/* ----------------------------------------------------------------------------- GSFramework Copyright 2001-2013 Emmanuel Julien. All Rights Reserved. ----------------------------------------------------------------------------- */ #ifndef __CU_BINDING_UTILS__ #define __CU_BINDING_UTILS__ #include "squirrel.h" #include "script_squirrel/cobject/squirrel_object.h" namespace GS { namespace Script { class CObject; } } struct ScriptClassMemberDecl { const SQChar *name; SQFUNCTION func; int params; const SQChar *typemask; }; struct SquirrelClassDecl { const SQChar *name; const SQChar *base; const ScriptClassMemberDecl *members; }; struct ScriptConstantDecl { const SQChar *name; SQObjectType type; union value { value(int v = 0) { i = v; } value(float v) { f = v; } value(const SQChar *v) { s = v; } float f; int i; const SQChar *s; } val; }; struct ScriptNamespaceDecl { const SQChar *name; const ScriptClassMemberDecl *members; const ScriptConstantDecl *constants; const ScriptClassMemberDecl *delegate; }; //------------------------------------------------------------------------------ #define case_ItemDerived \ case typetag_Camera: \ case typetag_Object: \ case typetag_Light: \ case typetag_Trigger: \ case typetag_Item: //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ #define _GetCObject(_CPP_CLASS, _TYPETAG, _VAR, _IDX) \ _CPP_CLASS *_VAR = NULL; \ { \ _GetParamAt(GS::Script::CObject, CObject, _IDX) \ if (self->type != _TYPETAG) \ return sa.ThrowError("Invalid type"); \ if (!self->native) \ return sa.ThrowError("Object is null"); \ _VAR = (_CPP_CLASS *)self->native; \ } #define _GetSelfNonNull \ _GetSelf(GS::Script::CObject, CObject); \ if (!self->native) \ return sa.ThrowError("Object is null"); //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ #define _BEGIN_CLASS(classname)\ SQInteger __##classname##__SCypeof(HSQUIRRELVM v)\ {\ sq_pushstring(v,_SC(#classname),-1);\ return 1;\ }\ struct ScriptClassMemberDecl __##classname##_members[] = {\ {_SC("_SCypeof"),__##classname##__SCypeof,1,NULL}, #define _BEGIN_NAMESPACE(xnamespace) struct ScriptClassMemberDecl __##xnamespace##_members[] = { #define _BEGIN_NAMESPACE_CONSTANTS(xnamespace) {NULL,NULL,NULL,NULL}}; \ struct ScriptConstantDecl __##xnamespace##_constants[] = { #define _BEGIN_DELEGATE(xnamespace) struct ScriptClassMemberDecl __##xnamespace##_delegate[] = { #define _DELEGATE(xnamespace) __##xnamespace##_delegate #define _END_DELEGATE(classname) {NULL,NULL,NULL,NULL}}; #define _CONSTANT(name,type,val) {_SC(#name),type,val}, #define _CONSTANT_IMPL(name,type) {_SC(#name),type,name}, #define _MEMBER_FUNCTION(classname,name,nparams,typemask) \ {_SC(#name),__##classname##_##name,nparams,typemask}, #define _END_NAMESPACE(classname,delegate) {NULL,OT_NULL,0}}; \ struct ScriptNamespaceDecl __##classname##_decl = { \ _SC(#classname), __##classname##_members,__##classname##_constants,delegate }; #define _END_CLASS(classname) {NULL,NULL,NULL,NULL}}; \ struct SquirrelClassDecl __##classname##_decl = { \ _SC(#classname), NULL, __##classname##_members }; #define _END_CLASS_INHERITANCE(classname,base) {NULL,NULL,NULL,NULL}}; \ struct SquirrelClassDecl __##classname##_decl = { \ _SC(#classname), _SC(#base), __##classname##_members }; #define _MEMBER_FUNCTION_IMPL(classname,name) \ SQInteger __##classname##_##name(HSQUIRRELVM v) \ { \ StackHandler sa(v); #define _END_IMPL } #define _INIT_STATIC_NAMESPACE(vm,classname) CreateStaticNamespace(vm,&__##classname##_decl); #define _INIT_CLASS(vm,classname)CreateClass(vm,&__##classname##_decl); #define _DECL_STATIC_NAMESPACE(xnamespace) extern struct ScriptNamespaceDecl __##xnamespace##_decl; #define _DECL_CLASS(classname) extern struct SquirrelClassDecl __##classname##_decl; #define _GetSelf(cppclass,scriptclass) \ cppclass *self = NULL; \ if (SQ_FAILED(sq_getinstanceup(v,1,(SQUserPointer*)&self,(SQUserPointer)&__##scriptclass##_decl))) \ return sq_throwerror(v,_SC("Invalid instance type"));\ if (!self)\ return sa.ThrowError("Internal failure"); #define _GetParamAt(cppclass,scriptclass,idx) \ cppclass *self = NULL; \ if (SQ_FAILED(sq_getinstanceup(v,idx,(SQUserPointer*)&self,(SQUserPointer)&__##scriptclass##_decl))) \ return sq_throwerror(v,_SC("Invalid instance type")); \ if (!self) \ return sa.ThrowError("Internal failure"); #define _CHECK_INST_PARAM_RAW(pname,idx,cppclass,scriptclass) \ cppclass *pname = NULL; \ if (SQ_FAILED(sq_getinstanceup(v,idx,(SQUserPointer*)&pname,(SQUserPointer)&__##scriptclass##_decl))) pname = NULL; //------------------------------------------------------------------------------ #define _GetTypedParam(pname,idx,cppclass,scriptclass) \ cppclass *pname = NULL; \ if (SQ_FAILED(sq_getinstanceup(v,idx,(SQUserPointer*)&pname,(SQUserPointer)&__##scriptclass##_decl))) \ return sq_throwerror(v,_SC("Invalid instance type")); #define _CHECK_INST_PARAM_COBJECT(__PARAM__, __IDX__, __CPPCLASS__) \ __CPPCLASS__ *__PARAM__ = NULL; \ { \ _GetTypedParam(c_object, __IDX__, GS::CObject, CObject) \ if (!c_object->c_object) \ return sq_throwerror(v, "C Object is null"); \ __PARAM__ = (__CPPCLASS__ *)c_object->c_object; \ } #define _CHECK_INST_PARAM_BREAK(pname,idx,cppclass,scriptclass) \ cppclass *pname = NULL; \ if (SQ_FAILED(sq_getinstanceup(v,idx,(SQUserPointer*)&pname,(SQUserPointer)&__##scriptclass##_decl))) \ break; //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ #define _CLASS_SCAG(classname) ((SQUserPointer)&__##classname##_decl) //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ #define _DECL_NATIVE_CONSTRUCTION(classname,cppclass)\ bool push_##classname(HSQUIRRELVM v, const cppclass &quat);\ SquirrelObject new_##classname(HSQUIRRELVM v, const cppclass &quat); //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ #define _IMPL_NATIVE_CONSTRUCTION(classname, cppclass)\ static SQInteger classname##_release_hook(SQUserPointer p, SQInteger size)\ {\ if (p)\ {\ cppclass *pv = (cppclass *)p;\ delete pv;\ }\ return 0;\ }\ bool push_##classname(HSQUIRRELVM vm, const cppclass &quat)\ {\ cppclass *newquat = new cppclass;\ *newquat = quat;\ if (!CreateNativeClassInstance(vm,#classname,newquat,classname##_release_hook))\ {\ delete newquat;\ return false;\ }\ return true;\ }\ ::SquirrelObject new_##classname(HSQUIRRELVM vm, const cppclass &quat)\ {\ ::SquirrelObject ret(vm);\ if (push_##classname(vm, quat))\ {\ ret.AttachToStackObject(-1);\ sq_pop(vm, 1);\ }\ return ret;\ }\ int construct_##classname(HSQUIRRELVM vm, cppclass *p)\ {\ sq_setinstanceup(vm, 1, p);\ sq_setreleasehook(vm, 1, classname##_release_hook);\ return 1;\ } //------------------------------------------------------------------------------ bool CreateStaticClass(HSQUIRRELVM v, SquirrelClassDecl *cd); bool CreateStaticNamespace(HSQUIRRELVM v, ScriptNamespaceDecl *sn); bool CreateClass(HSQUIRRELVM v, SquirrelClassDecl *cd); bool InitScriptClasses(HSQUIRRELVM v); bool CreateNativeClassInstance(HSQUIRRELVM v, const SQChar *classname, SQUserPointer ud, SQRELEASEHOOK hook); int refcounted_release_hook(SQUserPointer p, int size); int construct_RefCounted(void *p); //------------------------------------------------------------------------------ #define _SA_RETURN_OBJECT(__EXP__) { ::SquirrelObject o = __EXP__; return sa.Return(o); } #define _ReturnCObject(__OBJECT__, __TYPE__) { GS::Script::CObject::Push(v, __OBJECT__, __TYPE__); return 1; } //------------------------------------------------------------------------------ #endif // __CU_BINDING_UTILS__