Directory Structure [step 1]: moving files
working on #672 NOTE: This commit can't be compiled!!
This commit is contained in:
Vendored
+292
@@ -0,0 +1,292 @@
|
||||
/**
|
||||
@file Pointer.h
|
||||
|
||||
@maintainer Morgan McGuire, http://graphics.cs.williams.edu
|
||||
|
||||
@created 2007-05-16
|
||||
@edited 2009-03-26
|
||||
|
||||
Copyright 2000-2009, Morgan McGuire.
|
||||
All rights reserved.
|
||||
*/
|
||||
#ifndef G3D_Pointer_h
|
||||
#define G3D_Pointer_h
|
||||
|
||||
#include "G3D/debugAssert.h"
|
||||
#include "G3D/ReferenceCount.h"
|
||||
|
||||
namespace G3D {
|
||||
|
||||
/**
|
||||
Acts like a pointer to a value of type ValueType (i.e.,
|
||||
ValueType*), but can operate through accessor methods as well as on
|
||||
a value in memory. This is useful for implementing scripting
|
||||
languages and other applications that need to connect existing APIs
|
||||
by reference.
|
||||
|
||||
Because the accessors require values to be passed by value (instead of by reference)
|
||||
this is primarily useful for objects whose memory size is small.
|
||||
|
||||
<pre>
|
||||
class Foo {
|
||||
public:
|
||||
void setEnabled(bool b);
|
||||
bool getEnabled() const;
|
||||
};
|
||||
|
||||
Foo f;
|
||||
bool b;
|
||||
|
||||
Pointer<bool> p1(&b);
|
||||
Pointer<bool> p2(&f, &Foo::getEnabled, &Foo::setEnabled);
|
||||
|
||||
*p1 = true;
|
||||
*p2 = false;
|
||||
*p2 = *p1; \/\/ Value assignment
|
||||
p2 = p1; \/\/ Pointer aliasing
|
||||
|
||||
\/\/ Or, equivalently:
|
||||
p1.setValue(true);
|
||||
p2.setValue(false);
|
||||
|
||||
p2.setValue(p1.getValue());
|
||||
p2 = p1;
|
||||
</pre>
|
||||
|
||||
<i>Note:</i> Because of the way that dereference is implemented, you cannot pass <code>*p</code> through a function
|
||||
that takes varargs (...), e.g., <code>printf("%d", *p)</code> will produce a compile-time error. Instead use
|
||||
<code>printf("%d",(bool)*p)</code> or <code>printf("%d", p.getValue())</code>.
|
||||
|
||||
*/
|
||||
template<class ValueType>
|
||||
class Pointer {
|
||||
private:
|
||||
|
||||
class Interface {
|
||||
public:
|
||||
virtual ~Interface() {};
|
||||
virtual void set(ValueType b) = 0;
|
||||
virtual ValueType get() const = 0;
|
||||
virtual Interface* clone() const = 0;
|
||||
virtual bool isNull() const = 0;
|
||||
};
|
||||
|
||||
class Memory : public Interface {
|
||||
private:
|
||||
|
||||
ValueType* value;
|
||||
|
||||
public:
|
||||
|
||||
Memory(ValueType* value) : value(value) {
|
||||
//debugAssert(value != NULL);
|
||||
}
|
||||
|
||||
virtual void set(ValueType v) {
|
||||
*value = v;
|
||||
}
|
||||
|
||||
virtual ValueType get() const {
|
||||
return *value;
|
||||
}
|
||||
|
||||
virtual Interface* clone() const {
|
||||
return new Memory(value);
|
||||
}
|
||||
|
||||
virtual bool isNull() const {
|
||||
return value == NULL;
|
||||
}
|
||||
};
|
||||
|
||||
template<class T, typename GetMethod, typename SetMethod>
|
||||
class Accessor : public Interface {
|
||||
private:
|
||||
|
||||
T* object;
|
||||
GetMethod getMethod;
|
||||
SetMethod setMethod;
|
||||
|
||||
public:
|
||||
|
||||
Accessor(T* object,
|
||||
GetMethod getMethod,
|
||||
SetMethod setMethod) : object(object), getMethod(getMethod), setMethod(setMethod) {
|
||||
debugAssert(object != NULL);
|
||||
}
|
||||
|
||||
virtual void set(ValueType v) {
|
||||
(object->*setMethod)(v);
|
||||
}
|
||||
|
||||
virtual ValueType get() const {
|
||||
return (object->*getMethod)();
|
||||
}
|
||||
|
||||
virtual Interface* clone() const {
|
||||
return new Accessor(object, getMethod, setMethod);
|
||||
}
|
||||
|
||||
virtual bool isNull() const {
|
||||
return object == NULL;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template<class T, typename GetMethod, typename SetMethod>
|
||||
class RefAccessor : public Interface {
|
||||
private:
|
||||
|
||||
ReferenceCountedPointer<T> object;
|
||||
GetMethod getMethod;
|
||||
SetMethod setMethod;
|
||||
|
||||
public:
|
||||
|
||||
RefAccessor(
|
||||
const ReferenceCountedPointer<T>& object,
|
||||
GetMethod getMethod,
|
||||
SetMethod setMethod) : object(object), getMethod(getMethod), setMethod(setMethod) {
|
||||
|
||||
debugAssert(object != NULL);
|
||||
}
|
||||
|
||||
virtual void set(ValueType v) {
|
||||
(object.pointer()->*setMethod)(v);
|
||||
}
|
||||
|
||||
virtual ValueType get() const {
|
||||
return (object.pointer()->*getMethod)();
|
||||
}
|
||||
|
||||
virtual Interface* clone() const {
|
||||
return new RefAccessor(object, getMethod, setMethod);
|
||||
}
|
||||
|
||||
virtual bool isNull() const {
|
||||
return object.isNull();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Interface* m_interface;
|
||||
|
||||
public:
|
||||
|
||||
Pointer() : m_interface(NULL) {};
|
||||
|
||||
/** Allows implicit cast from real pointer */
|
||||
Pointer(ValueType* v) : m_interface(new Memory(v)) {}
|
||||
|
||||
inline bool isNull() const {
|
||||
return (m_interface == NULL) || m_interface->isNull();
|
||||
}
|
||||
|
||||
// Assignment
|
||||
inline Pointer& operator=(const Pointer& r) {
|
||||
delete m_interface;
|
||||
if (r.m_interface != NULL) {
|
||||
m_interface = r.m_interface->clone();
|
||||
} else {
|
||||
m_interface = NULL;
|
||||
}
|
||||
return this[0];
|
||||
}
|
||||
|
||||
Pointer(const Pointer& p) : m_interface(NULL) {
|
||||
this[0] = p;
|
||||
}
|
||||
|
||||
template<class Class>
|
||||
Pointer(const ReferenceCountedPointer<Class>& object,
|
||||
ValueType (Class::*getMethod)() const,
|
||||
void (Class::*setMethod)(ValueType)) :
|
||||
m_interface(new RefAccessor<Class, ValueType (Class::*)() const, void (Class::*)(ValueType)>(object, getMethod, setMethod)) {}
|
||||
|
||||
template<class Class>
|
||||
Pointer(const ReferenceCountedPointer<Class>& object,
|
||||
const ValueType& (Class::*getMethod)() const,
|
||||
void (Class::*setMethod)(ValueType)) :
|
||||
m_interface(new RefAccessor<Class, const ValueType& (Class::*)() const, void (Class::*)(ValueType)>(object, getMethod, setMethod)) {}
|
||||
|
||||
template<class Class>
|
||||
Pointer(const ReferenceCountedPointer<Class>& object,
|
||||
ValueType (Class::*getMethod)() const,
|
||||
void (Class::*setMethod)(const ValueType&)) :
|
||||
m_interface(new RefAccessor<Class, ValueType (Class::*)() const, void (Class::*)(const ValueType&)>(object, getMethod, setMethod)) {}
|
||||
|
||||
template<class Class>
|
||||
Pointer(const ReferenceCountedPointer<Class>& object,
|
||||
const ValueType& (Class::*getMethod)() const,
|
||||
void (Class::*setMethod)(const ValueType&)) :
|
||||
m_interface(new RefAccessor<Class, const ValueType& (Class::*)() const, void (Class::*)(const ValueType&)>(object, getMethod, setMethod)) {}
|
||||
|
||||
template<class Class>
|
||||
Pointer(Class* object,
|
||||
const ValueType& (Class::*getMethod)() const,
|
||||
void (Class::*setMethod)(const ValueType&)) :
|
||||
m_interface(new Accessor<Class, const ValueType& (Class::*)() const, void (Class::*)(const ValueType&)>(object, getMethod, setMethod)) {}
|
||||
|
||||
template<class Class>
|
||||
Pointer(Class* object,
|
||||
ValueType (Class::*getMethod)() const,
|
||||
void (Class::*setMethod)(const ValueType&)) :
|
||||
m_interface(new Accessor<Class, ValueType (Class::*)() const, void (Class::*)(const ValueType&)>(object, getMethod, setMethod)) {}
|
||||
|
||||
template<class Class>
|
||||
Pointer(Class* object,
|
||||
const ValueType& (Class::*getMethod)() const,
|
||||
void (Class::*setMethod)(ValueType)) :
|
||||
m_interface(new Accessor<Class, const ValueType& (Class::*)() const, void (Class::*)(ValueType)>(object, getMethod, setMethod)) {}
|
||||
|
||||
template<class Class>
|
||||
Pointer(Class* object,
|
||||
ValueType (Class::*getMethod)() const,
|
||||
void (Class::*setMethod)(ValueType)) :
|
||||
m_interface(new Accessor<Class, ValueType (Class::*)() const, void (Class::*)(ValueType)>(object, getMethod, setMethod)) {}
|
||||
|
||||
~Pointer() {
|
||||
delete m_interface;
|
||||
}
|
||||
|
||||
inline const ValueType getValue() const {
|
||||
debugAssert(m_interface != NULL);
|
||||
return m_interface->get();
|
||||
}
|
||||
|
||||
inline void setValue(const ValueType& v) {
|
||||
debugAssert(m_interface != NULL);
|
||||
m_interface->set(v);
|
||||
}
|
||||
|
||||
class IndirectValue {
|
||||
private:
|
||||
|
||||
friend class Pointer;
|
||||
Pointer* pointer;
|
||||
IndirectValue(Pointer* p) : pointer(p) {}
|
||||
|
||||
public:
|
||||
|
||||
void operator=(const ValueType& v) {
|
||||
pointer->setValue(v);
|
||||
}
|
||||
|
||||
operator ValueType() const {
|
||||
return pointer->getValue();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
inline IndirectValue operator*() {
|
||||
return IndirectValue(this);
|
||||
}
|
||||
|
||||
inline const ValueType operator*() const {
|
||||
return getValue();
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user