/* ----------------------------------------------------------------------------- GSFramework Copyright 2001-2013 Emmanuel Julien. All Rights Reserved. ----------------------------------------------------------------------------- */ #ifndef __NBINDING_HELPERS__ #define __NBINDING_HELPERS__ #include "script_squirrel/cobject/uc_binding.h" #include "script_squirrel/cobject/cobject.h" #include "script_squirrel/cobject/vector_decl.h" #include "math/vector.h" #include "log/log.h" namespace GS { class MinMax; struct Color; struct Vector4; template struct Rect; namespace Script { /// Register a native closure in the vm. void sq_register(HSQUIRRELVM v, SQFUNCTION f, const char *fname, const SQChar *mask); /// Create a new class instance on the vm stack. bool CreateClassInstance(HSQUIRRELVM vm, const char *class_name, bool call = false); void PushColor(HSQUIRRELVM vm, const Color &c); void PushVector2(HSQUIRRELVM vm, const Vector2 &v); void GetVector2(HSQUIRRELVM vm, SQInteger idx, Vector2 &v); void PushVector(HSQUIRRELVM vm, const Vector4 &v, bool push_w = false); void GetVector(HSQUIRRELVM vm, SQInteger idx, Vector4 &v, bool get_w = false); void GetUV(HSQUIRRELVM vm, SQInteger idx, Vector2 &uv); void PushMinMax(HSQUIRRELVM vm, const MinMax &v); void GetMinMax(HSQUIRRELVM vm, SQInteger idx, MinMax &v); void PushRect(HSQUIRRELVM vm, const Rect &r); void GetRect(HSQUIRRELVM vm, SQInteger idx, Rect &r); void PushRect(HSQUIRRELVM vm, const Rect &r); void GetRect(HSQUIRRELVM vm, SQInteger idx, Rect &r); #define GetTableKey(_KEY_, _TYPE_GET_, _IDX_, _TO_)\ {\ sq_pushstring(vm, _KEY_, -1);\ sq_get(vm, (_IDX_) - 1);\ _TYPE_GET_(vm, -1, &_TO_);\ sq_pop(vm, 1);\ } #define SetTableKey(_KEY_, _TYPE_PUSH_, _IDX_, _V_)\ {\ sq_pushstring(vm, _KEY_, -1);\ _TYPE_PUSH_(vm, _V_);\ sq_set(vm, (_IDX_) - 2);\ } //------------------------------------------------------------------------------ #define __SQ_INVALIDATENATIVEREF(__PTR__) ((SquirrelVM *)sq_getforeignptr(vm))->InvalidateNativeReference(__PTR__); //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ #define __SQ_GETSTART(__ARGCOUNT__) \ int __sq_stackpos = -(__ARGCOUNT__), __sq_argcount = __ARGCOUNT__; #define __SQ_GETUPDATESTACK \ __sq_stackpos++; #define __SQ_GETEND \ sq_pop(vm, __sq_argcount); /* sq_pop(vm, __sq_argcount);\ if (sq_gettop(vm) != 1)\ return sq_throwerror(vm, "Internal binding error, stack configuration is invalid"); */ #define __SQ_STACKPOS __sq_stackpos #define __SQ_GETSAFEPTR(__VARNAME__, __TYPE__, __TAG__) \ __TYPE__ *__VARNAME__; if (!GS::Script::CObject::Get(vm, __sq_stackpos, (void **)&__VARNAME__, __TAG__)) return -1; if (!__VARNAME__) return sq_throwerror(vm, "Object is null"); __SQ_GETUPDATESTACK #define __SQ_GETSAFEPTRALLOWNULL(__VARNAME__, __TYPE__, __TAG__) \ __TYPE__ *__VARNAME__; if (!GS::Script::CObject::Get(vm, __sq_stackpos, (void **)&__VARNAME__, __TAG__)) return -1; __SQ_GETUPDATESTACK #define __SQ_GETCOBJECTBASE(__VARNAME__, __TYPE__, __TAGS__) \ __TYPE__ *__VARNAME__; if (!GS::Script::CObject::GetBase(vm, __sq_stackpos, (void **)&__VARNAME__, __TAGS__)) return -1; if (!__VARNAME__) return sq_throwerror(vm, "Object is null"); __SQ_GETUPDATESTACK #define __SQ_GETCOBJECTBASEALLOWNULL(__VARNAME__, __TYPE__, __TAGS__) \ __TYPE__ *__VARNAME__; if (!GS::Script::CObject::GetBase(vm, __sq_stackpos, (void **)&__VARNAME__, __TAGS__)) return -1; __SQ_GETUPDATESTACK #define __SQ_GETOBJECT(__VARNAME__) \ HSQOBJECT __VARNAME__; sq_getstackobj(vm, __sq_stackpos, &__VARNAME__); __SQ_GETUPDATESTACK #define __SQ_GETINT(__VARNAME__) \ SQInteger __VARNAME__; sq_getinteger(vm, __sq_stackpos, &__VARNAME__); __SQ_GETUPDATESTACK #define __SQ_GETFLOAT(__VARNAME__) \ SQFloat __VARNAME__; sq_getfloat(vm, __sq_stackpos, &__VARNAME__); __SQ_GETUPDATESTACK #define __SQ_GETBOOL(__VARNAME__) \ SQBool __VARNAME__; sq_getbool(vm, __sq_stackpos, &__VARNAME__); __SQ_GETUPDATESTACK #define __SQ_GETSTRING(__VARNAME__) \ const SQChar *__VARNAME__; sq_getstring(vm, __sq_stackpos, &__VARNAME__); __SQ_GETUPDATESTACK #define __SQ_GETCOLOR(__VARNAME__) \ GS::Color __VARNAME__; GetVector(vm, __sq_stackpos, __VARNAME__); __SQ_GETUPDATESTACK #define __SQ_GETVECTOR2(__VARNAME__) \ GS::Vector2 __VARNAME__; GetVector2(vm, __sq_stackpos, __VARNAME__); __SQ_GETUPDATESTACK #define __SQ_GETVECTORTO(__VECTOR__, __CONDITION__) \ if (__CONDITION__) GetVector(vm, __sq_stackpos, __VECTOR__); __SQ_GETUPDATESTACK #define __SQ_GETVECTORTOALWAYS(__VECTOR__) \ GetVector(vm, __sq_stackpos, __VECTOR__); __SQ_GETUPDATESTACK #define __SQ_GETUVTO(__UV__) \ GetUV(vm, __sq_stackpos, __UV__); __SQ_GETUPDATESTACK #define __SQ_GETRECT(__VARNAME__) \ GS::Rect __VARNAME__; GetRect(vm, __sq_stackpos, __VARNAME__); __SQ_GETUPDATESTACK #define __SQ_GETFRECT(__VARNAME__) \ GS::Rect __VARNAME__; GetRect(vm, __sq_stackpos, __VARNAME__); __SQ_GETUPDATESTACK #define __SQ_GETRECTTO(__RECT__) \ GetRect(vm, __sq_stackpos, __RECT__); __SQ_GETUPDATESTACK #define __SQ_GETSINGLE(__G) \ __SQ_GETSTART(1) __G __SQ_GETEND #define __SQ_RETURNSAFEPTR(Val, Tag) { GS::Script::CObject::Push(vm, Val, Tag); return 1; } #define __SQ_RETURNMANAGEDSAFEPTR(Val, Tag) { GS::Script::CObject::Push(vm, Val, Tag, true); return 1; } #define __SQ_RETURNMINMAX(Val) { PushMinMax(vm, Val); return 1; } #define __SQ_RETURNRECT(Val) { PushRect(vm, Val); return 1; } #define __SQ_RETURNCOLOR(Val) { PushColor(vm, Val); return 1; } #define __SQ_RETURNVECTOR2(Val) { PushVector2(vm, Val); return 1; } #define __SQ_RETURNVECTORW(Val) { PushVector(vm, Val, true); return 1; } #define __SQ_RETURNMINMAX(Val) { PushMinMax(vm, Val); return 1; } //------------------------------------------------------------------------------ // Wrap old accessors to the much faster OO ones. #ifndef _T #define _T #endif #define __SQ_GETMATRIX3(__VARNAME__) \ GS::Matrix3 __VARNAME__;\ { HSQUIRRELVM v = vm;\ _GetTypedParam(__mtx, __sq_stackpos, GS::Matrix3, Matrix3);\ __VARNAME__ = *__mtx;\ __SQ_GETUPDATESTACK } #define __SQ_GETMATRIX4(__VARNAME__) \ GS::Matrix4 __VARNAME__;\ { HSQUIRRELVM v = vm;\ _GetTypedParam(__mtx, __sq_stackpos, GS::Matrix4, Matrix4);\ __VARNAME__ = *__mtx;\ __SQ_GETUPDATESTACK } #define __SQ_RETURNMATRIX3(__V__) \ { StackHandler sa(vm);\ _SA_RETURN_OBJECT(new_Matrix3(vm, __V__)) } #define __SQ_RETURNMATRIX4(__V__) \ { StackHandler sa(vm);\ _SA_RETURN_OBJECT(new_Matrix4(vm, __V__)) } #define __SQ_GETVECTORW(__VARNAME__) \ GS::Vector4 __VARNAME__;\ { HSQUIRRELVM v = vm;\ _GetTypedParam(__vec, __sq_stackpos, GS::Vector4, Vector);\ __VARNAME__ = *__vec;\ __SQ_GETUPDATESTACK } #define __SQ_GETVECTOR(__VARNAME__) \ __SQ_GETVECTORW(__VARNAME__) \ __VARNAME__.w = 1; #define __SQ_RETURNVECTOR(Val) \ { StackHandler sa(vm);\ _SA_RETURN_OBJECT(new_Vector(vm, Val)) } //------------------------------------------------------------------------------ #define __SQ_RETURNINT(Val) { sq_pushinteger(vm, Val); return 1; } #define __SQ_RETURNFLOAT(Val) { sq_pushfloat(vm, Val); return 1; } #define __SQ_RETURNBOOL(Val) { sq_pushbool(vm, Val ? SQTrue : SQFalse); return 1; } #define __SQ_RETURNNULL { sq_pushnull(vm); return 1; } #define __SQ_RETURNSTRING(Val) { sq_pushstring(vm, Val, -1); return 1; } #define __SQ_RETURNOBJECT(Val) { sq_pushobject(vm, Val); return 1; } #define __SQ_RETURN return 0; #define __SQ_GETSINGLESAFEPTR(Name, Type, Tag) \ __SQ_GETSTART(1) \ __SQ_GETSAFEPTR(Name, Type, Tag) \ __SQ_GETEND #define __SQ_GETSINGLESAFEPTRALLOWNULL(Name, Type, Tag) \ __SQ_GETSTART(1) \ __SQ_GETSAFEPTRALLOWNULL(Name, Type, Tag) \ __SQ_GETEND //------------------------------------------------------------------------------ } // Script } // GS #endif // __NBINDING_HELPERS__