关于squirrel语言与C++的自动绑定问题(2)
2016-03-20 20:29
471 查看
实现C++类自动绑定到Squirrel的核心类我是这样写的:
template<class T>struct SqModuleBase
{
struct BaseT
{
T* pObject;
bool flag_created;
};
static T* getHandle(HSQUIRRELVM v)
{
BaseT* handle;
if(SQ_FAILED(sq_getinstanceup(v,1,(SQUserPointer*)(&handle),0))) return NULL;
return handle->pObject;
}
static int _sq_get(HSQUIRRELVM v,const SQChar* &var,BaseT* &handle)
{
if(SQ_FAILED(sq_getinstanceup(v,1,(SQUserPointer*)(&handle),0)) || handle==NULL)
return 0;//表示获取对象失败,立即返回
if(SqGetVar(v,var))
{
if(strcmp(var,"this")==0)
{
sq_pushuserpointer(v,(SQUserPointer)handle->pObject);
return 1; //表示处理get成功,立即返回
}
return -1; //表示继续后续的处理
}
return 0; //表示获取参数失败,立即返回
}
template<class VAR2>
static int _sq_get2(HSQUIRRELVM v,const SQChar* &var,BaseT* &handle)
{
VAR2 var2;
if(SQ_FAILED(sq_getinstanceup(v,1,(SQUserPointer*)(&handle),0)) || handle==NULL)
return 0;//表示获取对象失败,立即返回
if(SqGetVar(v,var,var2))
{
return -1; //表示继续后续的处理
}
return 0; //表示获取参数失败,立即返回
}
static SQInteger _Sq2Constructor(HSQUIRRELVM v)
{
BaseT* handle=new BaseT;
handle->pObject=NULL;
handle->flag_created=false;
sq_setinstanceup(v,1,(SQUserPointer)(handle));
sq_setreleasehook(v,1,_queryobj_releasehook);
return 0;
}
static SQInteger _queryobj_releasehook(SQUserPointer p, SQInteger size)
{
BaseT* handle=(BaseT*)p;
if(handle!=NULL)
{
if(handle->flag_created) delete handle->pObject;
delete handle;
}
return 0;
}
static SQInteger _Sq2_is_null(HSQUIRRELVM v)
{
BaseT* handle;
if(SQ_FAILED(sq_getinstanceup(v,1,(SQUserPointer*)(&handle),0)))
{
sq_pushbool(v,SQTrue);
return 1;
}
if(handle->pObject==NULL)
sq_pushbool(v,SQTrue);
else
sq_pushbool(v,SQFalse);
return 1;
}
static SQInteger _Sq2_Use(HSQUIRRELVM v)
{
BaseT* handle;
if(SQ_FAILED(sq_getinstanceup(v,1,(SQUserPointer*)(&handle),0)))
return 0;
SQUserPointer p;
if(SqGetVar(v,p) && p!=NULL)
{
if(handle->flag_created) delete handle->pObject;
handle->pObject=(T*)p;
handle->flag_created=false;
}
return 0;
}
static SQInteger _Sq2_ThisPtr(HSQUIRRELVM v)
{
BaseT* handle;
if(SQ_FAILED(sq_getinstanceup(v,1,(SQUserPointer*)(&handle),0)))
return 0;
sq_pushuserpointer(v,(SQUserPointer)(handle->pObject));
return 1;
}
};
这是第一个类,我借鉴的是WTL的写法,这个类作为基础类实际上在C++内什么都没有存储,它的用处在后面体现
template<class T>struct SqModule:public SqModuleBase<T> //提供C++类的Squirrel封装
{
typedef typename SqModuleBase<T>::BaseT ModuleType;
static SQInteger Sq2_Create(HSQUIRRELVM v)
{
ModuleType* handle;
if(SQ_FAILED(sq_getinstanceup(v,1,(SQUserPointer*)(&handle),0))
|| handle==NULL) return 0;
if(handle->flag_created) delete handle->pObject;
handle->pObject=new T;
handle->flag_created=true;
return 0;
}
static void inject_base_function(const SQChar* name,HSQUIRRELVM v)
{
int top=sq_gettop(v);
sq_pushroottable(v);
sq_pushstring(v,name,-1);
sq_newclass(v,SQFalse);
sq_createslot(v,-3);
sq_settop(v,top);
register_func(v,name,SqModuleBase<T>::_Sq2Constructor,"constructor","x");
register_func(v,name,Sq2_Create,"create","x");
register_func(v,name,SqModuleBase<T>::_Sq2_Use,"use","xp");
register_func(v,name,SqModuleBase<T>::_Sq2_ThisPtr,"this_ptr","x");
register_func(v,name,SqModuleBase<T>::_Sq2_ThisPtr,"this","x");
register_func(v,name,SqModuleBase<T>::_Sq2_ThisPtr,"ptr","x");
register_func(v,name,SqModuleBase<T>::_Sq2_is_null,"is_null","x");
}
};
这是第二个类,同样,它在C++里也是什么都不存储,它继承了模板类SqModuleBase,这个关系有些绕来绕去的意思,但是通过这样的继承关系可以产生很多不同功能的SqModule类。
对于标准的C++类,我们以以下方式来定义一个新类
class Foo
{
privtae:
int x;
pubicd:
void set_x(int i){x=i;}
};
struct SqFoo:public SqModule<Foo>
{
};
SqFoo类包含了很多用于创建Squirrel对象的静态函数,它提供的create,this,use这几个基本的在squirrel中可以使用的方法
template<class T>struct SqModuleBase
{
struct BaseT
{
T* pObject;
bool flag_created;
};
static T* getHandle(HSQUIRRELVM v)
{
BaseT* handle;
if(SQ_FAILED(sq_getinstanceup(v,1,(SQUserPointer*)(&handle),0))) return NULL;
return handle->pObject;
}
static int _sq_get(HSQUIRRELVM v,const SQChar* &var,BaseT* &handle)
{
if(SQ_FAILED(sq_getinstanceup(v,1,(SQUserPointer*)(&handle),0)) || handle==NULL)
return 0;//表示获取对象失败,立即返回
if(SqGetVar(v,var))
{
if(strcmp(var,"this")==0)
{
sq_pushuserpointer(v,(SQUserPointer)handle->pObject);
return 1; //表示处理get成功,立即返回
}
return -1; //表示继续后续的处理
}
return 0; //表示获取参数失败,立即返回
}
template<class VAR2>
static int _sq_get2(HSQUIRRELVM v,const SQChar* &var,BaseT* &handle)
{
VAR2 var2;
if(SQ_FAILED(sq_getinstanceup(v,1,(SQUserPointer*)(&handle),0)) || handle==NULL)
return 0;//表示获取对象失败,立即返回
if(SqGetVar(v,var,var2))
{
return -1; //表示继续后续的处理
}
return 0; //表示获取参数失败,立即返回
}
static SQInteger _Sq2Constructor(HSQUIRRELVM v)
{
BaseT* handle=new BaseT;
handle->pObject=NULL;
handle->flag_created=false;
sq_setinstanceup(v,1,(SQUserPointer)(handle));
sq_setreleasehook(v,1,_queryobj_releasehook);
return 0;
}
static SQInteger _queryobj_releasehook(SQUserPointer p, SQInteger size)
{
BaseT* handle=(BaseT*)p;
if(handle!=NULL)
{
if(handle->flag_created) delete handle->pObject;
delete handle;
}
return 0;
}
static SQInteger _Sq2_is_null(HSQUIRRELVM v)
{
BaseT* handle;
if(SQ_FAILED(sq_getinstanceup(v,1,(SQUserPointer*)(&handle),0)))
{
sq_pushbool(v,SQTrue);
return 1;
}
if(handle->pObject==NULL)
sq_pushbool(v,SQTrue);
else
sq_pushbool(v,SQFalse);
return 1;
}
static SQInteger _Sq2_Use(HSQUIRRELVM v)
{
BaseT* handle;
if(SQ_FAILED(sq_getinstanceup(v,1,(SQUserPointer*)(&handle),0)))
return 0;
SQUserPointer p;
if(SqGetVar(v,p) && p!=NULL)
{
if(handle->flag_created) delete handle->pObject;
handle->pObject=(T*)p;
handle->flag_created=false;
}
return 0;
}
static SQInteger _Sq2_ThisPtr(HSQUIRRELVM v)
{
BaseT* handle;
if(SQ_FAILED(sq_getinstanceup(v,1,(SQUserPointer*)(&handle),0)))
return 0;
sq_pushuserpointer(v,(SQUserPointer)(handle->pObject));
return 1;
}
};
这是第一个类,我借鉴的是WTL的写法,这个类作为基础类实际上在C++内什么都没有存储,它的用处在后面体现
template<class T>struct SqModule:public SqModuleBase<T> //提供C++类的Squirrel封装
{
typedef typename SqModuleBase<T>::BaseT ModuleType;
static SQInteger Sq2_Create(HSQUIRRELVM v)
{
ModuleType* handle;
if(SQ_FAILED(sq_getinstanceup(v,1,(SQUserPointer*)(&handle),0))
|| handle==NULL) return 0;
if(handle->flag_created) delete handle->pObject;
handle->pObject=new T;
handle->flag_created=true;
return 0;
}
static void inject_base_function(const SQChar* name,HSQUIRRELVM v)
{
int top=sq_gettop(v);
sq_pushroottable(v);
sq_pushstring(v,name,-1);
sq_newclass(v,SQFalse);
sq_createslot(v,-3);
sq_settop(v,top);
register_func(v,name,SqModuleBase<T>::_Sq2Constructor,"constructor","x");
register_func(v,name,Sq2_Create,"create","x");
register_func(v,name,SqModuleBase<T>::_Sq2_Use,"use","xp");
register_func(v,name,SqModuleBase<T>::_Sq2_ThisPtr,"this_ptr","x");
register_func(v,name,SqModuleBase<T>::_Sq2_ThisPtr,"this","x");
register_func(v,name,SqModuleBase<T>::_Sq2_ThisPtr,"ptr","x");
register_func(v,name,SqModuleBase<T>::_Sq2_is_null,"is_null","x");
}
};
这是第二个类,同样,它在C++里也是什么都不存储,它继承了模板类SqModuleBase,这个关系有些绕来绕去的意思,但是通过这样的继承关系可以产生很多不同功能的SqModule类。
对于标准的C++类,我们以以下方式来定义一个新类
class Foo
{
privtae:
int x;
pubicd:
void set_x(int i){x=i;}
};
struct SqFoo:public SqModule<Foo>
{
};
SqFoo类包含了很多用于创建Squirrel对象的静态函数,它提供的create,this,use这几个基本的在squirrel中可以使用的方法
相关文章推荐