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