vcglib/wrap/glw/bookkeeping.h

583 lines
12 KiB
C++

#ifndef GLW_BOOKKEEPING_H
#define GLW_BOOKKEEPING_H
#include "./common.h"
namespace glw
{
class Context;
namespace detail
{
template <typename TObject>
class SharedObjectBase
{
friend class Context;
public:
typedef void BaseType;
typedef SharedObjectBase<TObject> ThisType;
typedef TObject ObjectType;
bool isNull(void) const
{
return (this->m_object == 0);
}
void setNull(void)
{
this->m_object = 0;
}
const ObjectType * object(void) const
{
return this->m_object;
}
ObjectType * object(void)
{
return this->m_object;
}
void ref(void)
{
this->m_refCount++;
}
void unref(void)
{
GLW_ASSERT(this->m_refCount > 0);
this->m_refCount--;
if (this->m_refCount == 0)
{
if (this->m_object != 0)
{
this->signalDestruction();
}
delete this;
}
}
protected:
Context * m_context;
ObjectType * m_object;
int m_refCount;
SharedObjectBase(Context * Context, ObjectType * Object)
: m_context (Context)
, m_object (Object)
, m_refCount (0)
{
GLW_ASSERT(this->m_context != 0);
GLW_ASSERT(this->m_object != 0);
}
private:
SharedObjectBase(const ThisType & other);
ThisType & operator = (const ThisType & other);
inline void signalDestruction(void);
};
template <typename TObject>
class SharedObject;
template <typename TObject, typename TObjectBase>
class SharedObjectTraits
{
public:
typedef void BaseType;
typedef SharedObjectTraits<TObject, TObjectBase> ThisType;
typedef TObject ObjectType;
typedef TObjectBase ObjectBaseType;
typedef SharedObject<ObjectBaseType> SharedObjectBaseType;
};
template <typename TObject>
class SharedObjectTraits<TObject, void>
{
public:
typedef void BaseType;
typedef SharedObjectTraits<TObject, void> ThisType;
typedef TObject ObjectType;
typedef void ObjectBaseType;
typedef SharedObjectBase<ObjectType> SharedObjectBaseType;
};
template <typename TObject>
class SharedObject : public SharedObjectTraits<TObject, typename TObject::BaseType>::SharedObjectBaseType
{
friend class Context;
public:
typedef typename SharedObjectTraits<TObject, typename TObject::BaseType>::SharedObjectBaseType BaseType;
typedef SharedObject<TObject> ThisType;
typedef TObject ObjectType;
const ObjectType * object(void) const
{
return static_cast<const ObjectType *>(BaseType::object());
}
ObjectType * object(void)
{
return static_cast<ObjectType *>(BaseType::object());
}
protected:
SharedObject(Context * Context, ObjectType * Object)
: BaseType(Context, Object)
{
;
}
private:
SharedObject(const ThisType & other);
ThisType & operator = (const ThisType & other);
};
template <typename TObject>
class SharedObjectBinding
{
friend class Context;
public:
typedef void BaseType;
typedef SharedObjectBinding<TObject> ThisType;
typedef TObject ObjectType;
typedef ObjectType UnsafeType;
~SharedObjectBinding(void)
{
this->detach();
}
bool isNull(void) const
{
if (this->m_shared == 0) return true;
return this->m_shared->isNull();
}
void setNull(void)
{
this->m_shared = 0;
}
const ObjectType * object(void) const
{
GLW_ASSERT(!this->isNull());
const ObjectType * obj = this->m_shared->object();
obj->setBinding(this->m_target, this->m_unit);
return obj;
}
ObjectType * object(void)
{
GLW_ASSERT(!this->isNull());
ObjectType * obj = this->m_shared->object();
obj->setBinding(this->m_target, this->m_unit);
return obj;
}
GLenum target(void) const
{
return this->m_target;
}
GLint unit(void) const
{
return this->m_unit;
}
void ref(void)
{
this->m_refCount++;
}
void unref(void)
{
GLW_ASSERT(this->m_refCount > 0);
this->m_refCount--;
if (this->m_refCount == 0)
{
delete this;
}
}
protected:
typedef SharedObject<ObjectType> SharedObjectType;
SharedObjectBinding(SharedObjectType * shared, GLenum target, GLint unit)
: m_shared (0)
, m_refCount (0)
, m_target (target)
, m_unit (unit)
{
this->attach(shared);
}
private:
SharedObjectType * m_shared;
int m_refCount;
GLenum m_target;
GLint m_unit;
SharedObjectBinding(const ThisType & other);
ThisType & operator = (const ThisType & other);
void attach(SharedObjectType * shared)
{
this->detach();
this->m_shared = shared;
if (this->m_shared != 0)
{
this->m_shared->ref();
}
}
void detach(void)
{
if (this->m_shared == 0) return;
this->m_shared->unref();
this->m_shared = 0;
}
};
template <typename TObject>
class SafeHandleBase
{
friend class Context;
public:
typedef void BaseType;
typedef SafeHandleBase<TObject> ThisType;
typedef TObject ObjectType;
typedef typename ObjectType::SafeType SafeType;
SafeHandleBase(void)
: m_shared(0)
{
;
}
SafeHandleBase(const ThisType & other)
: m_shared(0)
{
this->attach(other.shared());
}
~SafeHandleBase(void)
{
this->detach();
}
bool isNull(void) const
{
if (this->m_shared == 0) return true;
return this->m_shared->isNull();
}
void setNull(void)
{
this->detach();
}
const SafeType * operator -> (void) const
{
GLW_ASSERT(!this->isNull());
return this->m_shared->object();
}
SafeType * operator -> (void)
{
GLW_ASSERT(!this->isNull());
return this->m_shared->object();
}
ThisType & operator = (const ThisType & other)
{
this->attach(other.shared());
return (*this);
}
protected:
typedef SharedObject<ObjectType> SharedObjectType;
SafeHandleBase(SharedObjectType * shared)
: m_shared(0)
{
this->attach(shared);
}
const ObjectType * object(void) const
{
if (this->m_shared == 0) return 0;
return this->m_shared->object();
}
ObjectType * object(void)
{
if (this->m_shared == 0) return 0;
return this->m_shared->object();
}
SharedObjectType * shared(void) const
{
return this->m_shared;
}
private:
SharedObjectType * m_shared;
void attach(SharedObjectType * shared)
{
this->detach();
this->m_shared = shared;
if (this->m_shared != 0)
{
this->m_shared->ref();
}
}
void detach(void)
{
if (this->m_shared == 0) return;
this->m_shared->unref();
this->m_shared = 0;
}
};
template <typename TObject>
class SafeHandle;
template <typename TObject, typename TObjectBase>
class SafeHandleTraits
{
public:
typedef void BaseType;
typedef SafeHandleTraits<TObject, TObjectBase> ThisType;
typedef TObject ObjectType;
typedef TObjectBase ObjectBaseType;
typedef SafeHandle<ObjectBaseType> SafeHandleBaseType;
};
template <typename TObject>
class SafeHandleTraits<TObject, void>
{
public:
typedef void BaseType;
typedef SafeHandleTraits<TObject, void> ThisType;
typedef TObject ObjectType;
typedef void ObjectBaseType;
typedef SafeHandleBase<ObjectType> SafeHandleBaseType;
};
template <typename TObject>
class SafeHandle : public SafeHandleTraits<TObject, typename TObject::BaseType>::SafeHandleBaseType
{
friend class Context;
public:
typedef typename SafeHandleTraits<TObject, typename TObject::BaseType>::SafeHandleBaseType BaseType;
typedef SafeHandle<TObject> ThisType;
typedef TObject ObjectType;
typedef typename ObjectType::SafeType SafeType;
SafeHandle(void)
: BaseType()
{
;
}
SafeHandle(const ThisType & other)
: BaseType(other)
{
;
}
const SafeType * operator -> (void) const
{
return dynamic_cast<const SafeType *>(BaseType:: operator ->());
}
SafeType * operator -> (void)
{
return dynamic_cast<SafeType *>(BaseType:: operator ->());
}
/*
ThisType & operator = (const ThisType & other)
{
this->attach(other.shared());
return (*this);
}
*/
operator bool (void) const
{
return !this->isNull();
}
protected:
typedef SharedObject<ObjectType> SharedObjectType;
SafeHandle(SharedObjectType * shared)
: BaseType(shared)
{
;
}
const ObjectType * object(void) const
{
return static_cast<const ObjectType *>(BaseType::object());
}
ObjectType * object(void)
{
return static_cast<ObjectType *>(BaseType::object());
}
SharedObjectType * shared(void) const
{
return static_cast<SharedObjectType *>(BaseType::shared());
}
};
template <typename TObject>
class UnsafeHandle
{
friend class Context;
public:
typedef void BaseType;
typedef UnsafeHandle<TObject> ThisType;
typedef TObject ObjectType;
typedef ObjectType UnsafeType;
UnsafeHandle(void)
: m_shared(0)
{
;
}
UnsafeHandle(const ThisType & other)
: m_shared(0)
{
this->attach(other.shared());
}
~UnsafeHandle(void)
{
this->detach();
}
bool isNull(void) const
{
if (this->m_shared == 0) return true;
return this->m_shared->isNull();
}
void setNull(void)
{
this->detach();
}
const UnsafeType * operator -> (void) const
{
GLW_ASSERT(!this->isNull());
return this->m_shared->object();
}
UnsafeType * operator -> (void)
{
GLW_ASSERT(!this->isNull());
return this->m_shared->object();
}
ThisType & operator = (const ThisType & other)
{
this->attach(other.shared());
return (*this);
}
operator bool (void) const
{
return !this->isNull();
}
protected:
typedef SharedObjectBinding<ObjectType> SharedObjectBindingType;
UnsafeHandle(SharedObjectBindingType * shared)
: m_shared(0)
{
this->attach(shared);
}
const ObjectType * Object(void) const
{
if (this->m_shared == 0) return true;
return this->m_shared->object();
}
ObjectType * Object(void)
{
if (this->m_shared == 0) return true;
return this->m_shared->object();
}
private:
SharedObjectBindingType * m_shared;
void attach(SharedObjectBindingType * shared)
{
this->detach();
this->m_shared = shared;
if (this->m_shared != 0)
{
this->m_shared->ref();
}
}
void detach(void)
{
if (this->m_shared == 0) return;
this->m_shared->unref();
this->m_shared = 0;
}
SharedObjectBindingType * shared(void) const
{
return this->m_shared;
}
};
};
};
#endif // GLW_BOOKKEEPING_H