I copied the way that the const stuff was added in so if you add a file called SqPlusSmartPointer.h
#ifdef SQPLUS_SMARTPOINTER_ACCESSTYPE
#undef SQPLUS_SMARTPOINTER_ACCESSTYPE
enum VarAccessType {VAR_ACCESS_READ_WRITE=0,VAR_ACCESS_READ_ONLY=1<<0,VAR_ACCESS_CONSTANT=1<<1,VAR_ACCESS_STATIC=1<<2,VAR_ACCESS_SMARTPOINTER=1<<3};
#endif // #ifdef SQPLUS_SMARTPOINTER_ACCESSTYPE
#ifdef SQPLUS_SMARTPOINTER_REGISTER_VARIABLE
#undef SQPLUS_SMARTPOINTER_REGISTER_VARIABLE
// classType is the type of the member variable's containing class.
template<typename T>
void RegisterSmartInstanceVariable(SquirrelObject & so,SQUserPointer classType,T * var,const SQChar * scriptVarName,VarAccessType access=VAR_ACCESS_READ_WRITE) {
VarRef * pvr = createVarRef(so,scriptVarName);
void * offsetOrAddrOrConst = (void *)var; // var must be passed in as &obj->var, where obj = 0 (the address is the offset), or as static/global address.
*pvr = VarRef(offsetOrAddrOrConst,TypeInfo<T>(),classType,ClassType<T>::getCopyFunc(),sizeof(*var),access,TypeInfo<T>().typeName);
pvr->access |= VAR_ACCESS_SMARTPOINTER;
createInstanceSetGetHandlers(so);
} // RegisterInstanceVariable
#endif // #ifdef SQPLUS_SMARTPOINTER_REGISTER_VARIABLE
#ifdef SQPLUS_SMARTPOINTER_DISPATCH
#undef SQPLUS_SMARTPOINTER_DISPATCH
template<typename Callee,typename Pointee,typename Func>
class DirectCallSmartInstanceMemberFunction {
public:
static inline int Dispatch(HSQUIRRELVM v) {
StackHandler sa(v);
Callee * instance = (Callee *)sa.GetInstanceUp(1,0);
int paramCount = sa.GetParamCount();
Func * func = (Func *)sa.GetUserData(paramCount);
#ifdef SQ_USE_CLASS_INHERITANCE
SquirrelObject so(sa.GetObjectHandle(1)); // 'this'
SQUserPointer typetag; so.GetTypeTag(&typetag);
SQUserPointer calleeType = ClassType<Callee>::type();
if (typetag != calleeType) {
SquirrelObject typeTable = so.GetValue(SQ_CLASS_OBJECT_TABLE_NAME);
instance = (Callee *)typeTable.GetUserPointer(INT((size_t)ClassType<Callee>::type())); // <TODO> 64-bit compatible version.
if (!instance) {
return sq_throwerror(v,_T("Invalid Instance Type"));
} // if
} // if
#endif
Pointee * pointeeInstance = static_cast<Pointee*>(instance->get());
if(!pointeeInstance) {
return sq_throwerror(v,_T("SmartPointer Pointee NULL"));
}
return Call(*pointeeInstance,*func,v,2);
} // Dispatch
};
#endif // #ifdef SQPLUS_SMARTPOINTER_DISPATCH
#ifdef SQPLUS_SMARTPOINTER_DIRECT_CLOSURE
#undef SQPLUS_SMARTPOINTER_DIRECT_CLOSURE
template<typename Callee,typename Pointee,typename Func>
inline void sq_pushdirectsmartinstanceclosure(HSQUIRRELVM v,const Callee & callee,const Pointee & pointee,Func func,SQUnsignedInteger nupvalues) {
unsigned char * up = (unsigned char *)sq_newuserdata(v,sizeof(func)); // Also pushed on stack.
memcpy(up,&func,sizeof(func));
sq_newclosure(v,DirectCallSmartInstanceMemberFunction<Callee,Pointee,Func>::Dispatch,nupvalues+1);
} // sq_pushdirectinstanceclosure
#endif // #ifdef SQPLUS_SMARTPOINTER_DIRECT_CLOSURE
#ifdef SQPLUS_SMARTPOINTER_REGISTER_INSTANCE
#undef SQPLUS_SMARTPOINTER_REGISTER_INSTANCE
template<typename Callee, typename Pointee, typename Func>
inline void RegisterSmartInstance(HSQUIRRELVM v,HSQOBJECT hclass,Callee & callee,Pointee & pointee,Func func,const SQChar * name) {
sq_pushobject(v,hclass);
sq_pushstring(v,name,-1);
sq_pushdirectsmartinstanceclosure(v,callee,pointee,func,0);
sq_createslot(v,-3);
sq_poptop(v); // Remove hclass.
} // RegisterInstance
#endif // #ifdef SQPLUS_SMARTPOINTER_REGISTER_INSTANCE
#ifdef SQPLUS_SMARTPOINTER_CLASS_DEF
#undef SQPLUS_SMARTPOINTER_CLASS_DEF
// Register a smartpointer member function.
template<typename Pointee, typename Func>
SQClassDefBase & smartFunc(Func pfunc,const SQChar * name) {
RegisterSmartInstance(v,newClass.GetObjectHandle(),*(TClassType *)0,*(Pointee *)0,pfunc,name);
return *this;
} // func
// Register a member variable.
template<typename Pointee, typename VarType>
SQClassDefBase & smartVar(VarType Pointee::* pvar,const SQChar * name,VarAccessType access=VAR_ACCESS_READ_WRITE) {
struct CV {
VarType Pointee::* var;
} cv; // Cast Variable helper.
cv.var = pvar;
RegisterSmartInstanceVariable(newClass,ClassType<TClassType>::type(),*(VarType **)&cv,name,access);
return *this;
} // var
// Register a member variable as a UserPointer (read only).
template<typename Pointee, typename VarType>
SQClassDefBase & smartVarAsUserPointer(VarType Pointee::* pvar,const SQChar * name) {
struct CV {
VarType Pointee::* var;
} cv; // Cast Variable helper.
cv.var = pvar;
RegisterSmartInstanceVariable(newClass,ClassType<TClassType>::type(),*(SQAnything **)&cv,name,VAR_ACCESS_READ_ONLY);
return *this;
} // varAsUserPointer
#endif // #ifdef SQPLUS_SMARTPOINTER_CLASS_DEF
#ifdef SQPLUS_SMARTPOINTER_CPP_DECLARATION
#undef SQPLUS_SMARTPOINTER_CPP_DECLARATION
extern unsigned char* getSmartPointerPointee(unsigned char*);
#endif
#ifdef SQPLUS_SMARTPOINTER_INSTANCE_VARINFO
#undef SQPLUS_SMARTPOINTER_INSTANCE_VARINFO
if(vr->access & VAR_ACCESS_SMARTPOINTER) {
up = getSmartPointerPointee(up);
}
#endif // #ifdef SQPLUS_SMARTPOINTER_CPP_DECLARATION
In SqPlus.cpp at line 4 you need to add:
#ifdef SQPLUS_SUPPORT_SMART_POINTER
#define SQPLUS_SMARTPOINTER_CPP_DECLARATION
#include "SqPlusSmartPointer.h"
#endif
Then at line 60 add:
#ifdef SQPLUS_SUPPORT_SMART_POINTER
#define SQPLUS_SMARTPOINTER_INSTANCE_VARINFO
#include "SqPlusSmartPointer.h"
#endif
In SqPlus.h there are quite a few additions but not major ones which are:
line 78:
// === Uncomment to support smart pointer ===
#define SQPLUS_SUPPORT_SMART_POINTER
line 276:
#ifdef SQPLUS_SUPPORT_SMART_POINTER
#define SQPLUS_SMARTPOINTER_ACCESSTYPE
#include "SqPlusSmartPointer.h"
#else
enum VarAccessType {VAR_ACCESS_READ_WRITE=0,VAR_ACCESS_READ_ONLY=1<<0,VAR_ACCESS_CONSTANT=1<<1,VAR_ACCESS_STATIC=1<<2};
#endif
line 438:
#ifdef SQPLUS_SUPPORT_SMART_POINTER
#define SQPLUS_SMARTPOINTER_REGISTER_VARIABLE
#include "SqPlusSmartPointer.h"
#endif
line 1231:
#ifdef SQPLUS_SUPPORT_SMART_POINTER
#define SQPLUS_SMARTPOINTER_DISPATCH
#include "SqPlusSmartPointer.h"
#endif
and finally line 1295:
#ifdef SQPLUS_SUPPORT_SMART_POINTER
#define SQPLUS_SMARTPOINTER_DIRECT_CLOSURE
#include "SqPlusSmartPointer.h"
#endif
I think thats all but if that doesn't work I'll send you the files I've got. Doesn't handle constants or variable argument functions but they're pretty easy to add if needed. I don't actually have a sourceforge account at the mo but I'll set one up and send you the details.
Cheers,
James