1 #ifndef SQUIRREL_BINDINGS_UTILS_H 2 #define SQUIRREL_BINDINGS_UTILS_H 3 4 struct ScriptClassMemberDecl { 5 const SQChar *name; 6 SQFUNCTION func; 7 SQInteger params; 8 const SQChar *typemask; 9 }; 10 11 struct SquirrelClassDecl { 12 const SQChar *name; 13 const SQChar *base; 14 const ScriptClassMemberDecl *members; 15 }; 16 17 struct ScriptConstantDecl { 18 const SQChar *name; 19 SQObjectType type; 20 union value { value(float v)21 value(float v){ f = v; } value(int v)22 value(int v){ i = v; } value(long int v)23 value(long int v){ li = v; } value(const SQChar * v)24 value(const SQChar *v){ s = v; } 25 float f; 26 int i; 27 long int li; 28 const SQChar *s; 29 } val; 30 }; 31 32 struct ScriptNamespaceDecl { 33 const SQChar *name; 34 const ScriptClassMemberDecl *members; 35 const ScriptConstantDecl *constants; 36 const ScriptClassMemberDecl *delegate; 37 }; 38 39 #define _BEGIN_CLASS(classname) \ 40 SQInteger __##classname##__typeof(HSQUIRRELVM v) \ 41 { \ 42 sq_pushstring(v,sqT(#classname),-1); \ 43 return 1; \ 44 } \ 45 struct ScriptClassMemberDecl __##classname##_members[] = { \ 46 {sqT("_typeof"),__##classname##__typeof,1,NULL}, 47 48 #define _BEGIN_NAMESPACE(xnamespace) struct ScriptClassMemberDecl __##xnamespace##_members[] = { 49 #define _BEGIN_NAMESPACE_CONSTANTS(xnamespace) {NULL,NULL,0,NULL}}; \ 50 struct ScriptConstantDecl __##xnamespace##_constants[] = { 51 52 #define _BEGIN_DELEGATE(xnamespace) struct ScriptClassMemberDecl __##xnamespace##_delegate[] = { 53 #define _DELEGATE(xnamespace) __##xnamespace##_delegate 54 #define _END_DELEGATE(classname) {NULL,NULL,NULL,NULL}}; 55 56 #define _CONSTANT(name,type,val) {sqT(#name),type,val}, 57 #define _CONSTANT_IMPL(name,type) {sqT(#name),type,name}, 58 59 #define _MEMBER_FUNCTION(classname,name,nparams,typemask) \ 60 {sqT(#name),__##classname##_##name,nparams,typemask}, 61 62 #define _END_NAMESPACE(classname,delegate) {NULL,OT_NULL,0}}; \ 63 struct ScriptNamespaceDecl __##classname##_decl = { \ 64 sqT(#classname), __##classname##_members,__##classname##_constants,delegate }; 65 66 #define _END_CLASS(classname) {NULL,NULL,0,NULL}}; \ 67 struct SquirrelClassDecl __##classname##_decl = { \ 68 sqT(#classname), NULL, __##classname##_members }; 69 70 71 #define _END_CLASS_INHERITANCE(classname,base) {NULL,NULL,NULL,NULL}}; \ 72 struct SquirrelClassDecl __##classname##_decl = { \ 73 sqT(#classname), sqT(#base), __##classname##_members }; 74 75 #define _MEMBER_FUNCTION_IMPL(classname,name) \ 76 SQInteger __##classname##_##name(HSQUIRRELVM v) 77 78 #define _INIT_STATIC_NAMESPACE(classname) CreateStaticNamespace(SquirrelVM::GetVMPtr(),&__##classname##_decl); 79 #define _INIT_CLASS(classname)CreateClass(SquirrelVM::GetVMPtr(),&__##classname##_decl); 80 81 #define _DECL_STATIC_NAMESPACE(xnamespace) extern struct ScriptNamespaceDecl __##xnamespace##_decl; 82 #define _DECL_CLASS(classname) extern struct SquirrelClassDecl __##classname##_decl; 83 84 #define _CHECK_SELF(cppclass,scriptclass) \ 85 cppclass *self = NULL; \ 86 if(SQ_FAILED(sq_getinstanceup(v,1,(SQUserPointer*)&self,(SQUserPointer)&__##scriptclass##_decl))) { \ 87 return sq_throwerror(v,sqT("invalid instance type"));\ 88 } 89 90 #define _CHECK_INST_PARAM(pname,idx,cppclass,scriptclass) \ 91 cppclass *pname = NULL; \ 92 if(SQ_FAILED(sq_getinstanceup(v,idx,(SQUserPointer*)&pname,(SQUserPointer)&__##scriptclass##_decl))) { \ 93 return sq_throwerror(v,sqT("invalid instance type"));\ 94 } \ 95 96 #define _CHECK_INST_PARAM_BREAK(pname,idx,cppclass,scriptclass) \ 97 cppclass *pname = NULL; \ 98 if(SQ_FAILED(sq_getinstanceup(v,idx,(SQUserPointer*)&pname,(SQUserPointer)&__##scriptclass##_decl))) { \ 99 break; \ 100 } \ 101 102 #define _CLASS_TAG(classname) ((unsigned int)&__##classname##_decl) 103 104 105 #define _DECL_NATIVE_CONSTRUCTION(classname,cppclass) \ 106 BOOL_T push_##classname(cppclass &quat); \ 107 SquirrelObject new_##classname(cppclass &quat); 108 109 #define _IMPL_NATIVE_CONSTRUCTION(classname,cppclass) \ 110 static SQInteger classname##_release_hook(SQUserPointer p, SQInteger size) \ 111 { \ 112 if(p) { \ 113 cppclass *pv = (cppclass *)p; \ 114 delete pv; \ 115 } \ 116 return 0; \ 117 } \ 118 BOOL_T push_##classname(cppclass &quat) \ 119 { \ 120 cppclass *newquat = new cppclass; \ 121 *newquat = quat; \ 122 if(!CreateNativeClassInstance(SquirrelVM::GetVMPtr(),sqT(#classname),newquat,classname##_release_hook)) { \ 123 delete newquat; \ 124 return FALSE; \ 125 } \ 126 return TRUE; \ 127 } \ 128 SquirrelObject new_##classname(cppclass &quat) \ 129 { \ 130 SquirrelObject ret; \ 131 if(push_##classname(quat)) { \ 132 ret.AttachToStackObject(-1); \ 133 sq_pop(SquirrelVM::GetVMPtr(),1); \ 134 } \ 135 return ret; \ 136 } \ 137 SQInteger construct_##classname(cppclass *p) \ 138 { \ 139 sq_setinstanceup(SquirrelVM::GetVMPtr(),1,p); \ 140 sq_setreleasehook(SquirrelVM::GetVMPtr(),1,classname##_release_hook); \ 141 return 1; \ 142 } 143 144 BOOL_T CreateStaticClass(HSQUIRRELVM v,SquirrelClassDecl *cd); 145 BOOL_T CreateStaticNamespace(HSQUIRRELVM v,ScriptNamespaceDecl *sn); 146 BOOL_T CreateClass(HSQUIRRELVM v,SquirrelClassDecl *cd); 147 BOOL_T InitScriptClasses(HSQUIRRELVM v); 148 BOOL_T CreateNativeClassInstance(HSQUIRRELVM v,const SQChar *classname,SQUserPointer ud,SQRELEASEHOOK hook); 149 150 #endif // SQUIRREL_BINDINGS_UTILS_H 151 152