240 lines
8.0 KiB
C++
240 lines
8.0 KiB
C++
/* -----------------------------------------------------------------------------
|
|
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__
|