28 #if !defined(_SCRAT_CLASS_H_)
29 #define _SCRAT_CLASS_H_
35 #include "sqratObject.h"
36 #include "sqratClassType.h"
37 #include "sqratMemberMethods.h"
38 #include "sqratAllocator.h"
55 template<
class C,
class A = DefaultAllocator<C> >
58 static SQInteger cleanup_hook(SQUserPointer p, SQInteger )
60 HSQUIRRELVM v = *(HSQUIRRELVM *) p;
61 ClassTypeData<C, void>* ptr =
static_cast<ClassTypeData<C, void>*
>(ClassType<C>::getClassTypeData(v));
63 ClassType<C>::deleteClassTypeData(v);
87 if(createClass && !ClassType<C>::hasClassTypeData(v)) {
88 ClassType<C>::getClassTypeData(v) =
new ClassTypeData<C, void>;
89 HSQOBJECT& classObj = ClassType<C>::ClassObject(v);
90 sq_resetobject(&classObj);
92 sq_newclass(vm,
false);
93 sq_getstackobj(vm, -1, &classObj);
94 sq_addref(vm, &classObj);
96 if (className.empty())
98 InitClass(string_to_wstring(
typeid(*this).name()));
100 InitClass(
typeid(*this).name());
102 else InitClass(className);
105 HSQUIRRELVM *p = (HSQUIRRELVM *) sq_newuserdata(v,
sizeof(v));
108 sq_setreleasehook(v, -1, cleanup_hook);
120 return ClassType<C>::ClassObject(vm);
130 return ClassType<C>::ClassObject(vm);
150 BindValue<V>(name, val,
true);
167 BindValue<V>(name, val,
false);
185 BindAccessor(name, &var,
sizeof(var), &sqDefaultGet<C, V>, ClassType<C>::GetTable(vm));
188 BindAccessor(name, &var,
sizeof(var), &sqDefaultSet<C, V>, ClassType<C>::SetTable(vm));
207 BindAccessor(name, &var,
sizeof(var), &sqStaticGet<C, V>, ClassType<C>::GetTable(vm));
210 BindAccessor(name, &var,
sizeof(var), &sqStaticSet<C, V>, ClassType<C>::SetTable(vm));
231 template<
class F1,
class F2>
232 Class&
Prop(
const SQChar* name, F1 getMethod, F2 setMethod) {
233 if(getMethod != NULL) {
235 BindAccessor(name, &getMethod,
sizeof(getMethod), SqMemberOverloadedFunc(getMethod), ClassType<C>::GetTable(vm));
238 if(setMethod != NULL) {
240 BindAccessor(name, &setMethod,
sizeof(setMethod), SqMemberOverloadedFunc(setMethod), ClassType<C>::SetTable(vm));
262 template<
class F1,
class F2>
264 if(getMethod != NULL) {
266 BindAccessor(name, &getMethod,
sizeof(getMethod), SqMemberGlobalOverloadedFunc(getMethod), ClassType<C>::GetTable(vm));
269 if(setMethod != NULL) {
271 BindAccessor(name, &setMethod,
sizeof(setMethod), SqMemberGlobalOverloadedFunc(setMethod), ClassType<C>::SetTable(vm));
294 BindAccessor(name, &getMethod,
sizeof(getMethod), SqMemberOverloadedFunc(getMethod), ClassType<C>::GetTable(vm));
316 BindAccessor(name, &getMethod,
sizeof(getMethod), SqMemberGlobalOverloadedFunc(getMethod), ClassType<C>::GetTable(vm));
334 BindFunc(name, &method,
sizeof(method), SqMemberFunc(method));
355 BindOverload(name, &method,
sizeof(method), SqMemberOverloadedFunc(method), SqOverloadFunc(method), SqGetArgCount(method));
372 BindFunc(name, &method,
sizeof(method), SqMemberGlobalFunc(method));
389 BindFunc(name, &method,
sizeof(method), SqGlobalFunc(method));
410 BindOverload(name, &method,
sizeof(method), SqMemberGlobalOverloadedFunc(method), SqOverloadFunc(method), SqGetArgCount(method) - 1);
431 BindOverload(name, &method,
sizeof(method), SqGlobalOverloadedFunc(method), SqOverloadFunc(method), SqGetArgCount(method));
449 sq_pushobject(vm, ClassType<C>::ClassObject(vm));
450 sq_pushstring(vm, name, -1);
451 sq_newclosure(vm, func, 0);
452 sq_newslot(vm, -3,
false);
468 sq_pushobject(vm, ClassType<C>::ClassObject(vm));
469 sq_pushstring(vm, name, -1);
470 #if !defined (SCRAT_NO_ERROR_CHECKING)
471 if(SQ_FAILED(sq_get(vm, -2))) {
475 SQObjectType value_type = sq_gettype(vm, -1);
476 if (value_type != OT_CLOSURE && value_type != OT_NATIVECLOSURE) {
483 sq_getstackobj(vm, -1, &funcObj);
484 Function ret(vm, ClassType<C>::ClassObject(vm), funcObj);
493 static SQInteger ClassWeakref(HSQUIRRELVM vm) {
498 static SQInteger ClassTypeof(HSQUIRRELVM vm) {
499 sq_pushstring(vm, ClassType<C>::ClassName(vm).c_str(), -1);
504 void InitClass(
const string& className) {
505 ClassType<C>::CopyFunc(vm) = &A::Copy;
506 ClassType<C>::ClassName(vm) = className;
507 ClassType<C>::BaseClass(vm) = NULL;
510 sq_pushobject(vm, ClassType<C>::ClassObject(vm));
513 sq_settypetag(vm, -1, ClassType<C>::getClassTypeData(vm));
516 sq_pushstring(vm,_SC(
"constructor"), -1);
517 sq_newclosure(vm, &A::New, 0);
518 sq_newslot(vm, -3,
false);
521 HSQOBJECT& setTable = ClassType<C>::SetTable(vm);
522 sq_resetobject(&setTable);
523 sq_pushstring(vm,_SC(
"__setTable"), -1);
525 sq_getstackobj(vm, -1, &setTable);
526 sq_addref(vm, &setTable);
527 sq_newslot(vm, -3,
true);
530 HSQOBJECT& getTable = ClassType<C>::GetTable(vm);
531 sq_resetobject(&getTable);
532 sq_pushstring(vm,_SC(
"__getTable"), -1);
534 sq_getstackobj(vm, -1, &getTable);
535 sq_addref(vm, &getTable);
536 sq_newslot(vm, -3,
true);
539 sq_pushstring(vm, _SC(
"_set"), -1);
540 sq_pushobject(vm, setTable);
541 sq_newclosure(vm, &sqVarSet, 1);
542 sq_newslot(vm, -3,
false);
545 sq_pushstring(vm, _SC(
"_get"), -1);
546 sq_pushobject(vm, getTable);
547 sq_newclosure(vm, &sqVarGet, 1);
548 sq_newslot(vm, -3,
false);
551 sq_pushstring(vm, _SC(
"weakref"), -1);
552 sq_newclosure(vm, &Class::ClassWeakref, 0);
553 sq_newslot(vm, -3,
false);
556 sq_pushstring(vm, _SC(
"_typeof"), -1);
557 sq_newclosure(vm, &Class::ClassTypeof, 0);
558 sq_newslot(vm, -3,
false);
565 inline void BindAccessor(
const SQChar* name,
void* var,
size_t varSize, SQFUNCTION func, HSQOBJECT table) {
567 sq_pushobject(vm, table);
568 sq_pushstring(vm, name, -1);
571 SQUserPointer varPtr = sq_newuserdata(vm, static_cast<SQUnsignedInteger>(varSize));
572 memcpy(varPtr, var, varSize);
575 sq_newclosure(vm, func, 1);
578 sq_newslot(vm, -3,
false);
586 Class& BindConstructor(SQFUNCTION method, SQInteger nParams,
const SQChar *name = 0){
587 SQFUNCTION overload = SqOverloadFunc(method);
588 bool alternative_global =
false;
590 name = _SC(
"constructor");
591 else alternative_global =
true;
592 string overloadName = SqOverloadName::Get(name, nParams);
594 if (!alternative_global )
597 sq_pushobject(vm, ClassType<C>::ClassObject(vm));
602 sq_pushroottable(vm);
606 sq_pushstring(vm, name, -1);
607 sq_pushstring(vm, name, -1);
608 sq_newclosure(vm, overload, 1);
609 sq_newslot(vm, -3,
false);
612 sq_pushstring(vm, overloadName.c_str(), -1);
613 sq_newclosure(vm, method, 0);
614 sq_setparamscheck(vm,nParams + 1,NULL);
615 sq_newslot(vm, -3,
false);
620 void setDefaultCtor()
622 ClassTypeDataBase *type_data = ClassType<C>::getClassTypeData(vm);
623 if (type_data->ctorCalled ==
false)
626 type_data->ctorCalled =
true;
642 return BindConstructor(A::template iNew<0>, 0, name);
658 return BindConstructor(A::template iNew<A1>,1, name);
672 template<
class A1,
class A2>
675 return BindConstructor(A::template iNew<A1,A2>,2, name);
690 template<
class A1,
class A2,
class A3>
693 return BindConstructor(A::template iNew<A1,A2,A3>,3, name);
709 template<
class A1,
class A2,
class A3,
class A4>
712 return BindConstructor(A::template iNew<A1,A2,A3,A4>,4, name);
729 template<
class A1,
class A2,
class A3,
class A4,
class A5>
732 return BindConstructor(A::template iNew<A1,A2,A3,A4,A5>,5, name);
750 template<
class A1,
class A2,
class A3,
class A4,
class A5,
class A6>
753 return BindConstructor(A::template iNew<A1,A2,A3,A4,A5,A6>,6, name);
772 template<
class A1,
class A2,
class A3,
class A4,
class A5,
class A6,
class A7>
775 return BindConstructor(A::template iNew<A1,A2,A3,A4,A5,A6,A7>,7, name);
795 template<
class A1,
class A2,
class A3,
class A4,
class A5,
class A6,
class A7,
class A8>
798 return BindConstructor(A::template iNew<A1,A2,A3,A4,A5,A6,A7,A8>,8, name);
819 template<
class A1,
class A2,
class A3,
class A4,
class A5,
class A6,
class A7,
class A8,
class A9>
822 return BindConstructor(A::template iNew<A1,A2,A3,A4,A5,A6,A7,A8,A9>,9, name);
842 template<
class C,
class B,
class A = DefaultAllocator<C> >
845 static SQInteger cleanup_hook(SQUserPointer p, SQInteger )
847 HSQUIRRELVM v = *(HSQUIRRELVM *) p;
848 ClassTypeData<C, B>* ptr =
static_cast<ClassTypeData<C, B>*
>(ClassType<C>::getClassTypeData(v));
850 ClassType<C>::deleteClassTypeData(v);
873 if(!ClassType<C>::hasClassTypeData(v)) {
874 ClassType<C>::getClassTypeData(v) =
new ClassTypeData<C, B>;
875 HSQOBJECT& classObj = ClassType<C>::ClassObject(v);
876 sq_resetobject(&classObj);
878 sq_pushobject(v, ClassType<B>::ClassObject(v));
879 sq_newclass(v,
true);
880 sq_getstackobj(v, -1, &classObj);
881 sq_addref(v, &classObj);
883 if (className.empty())
885 InitDerivedClass(v, string_to_wstring(
typeid(*this).name()));
887 InitDerivedClass(v,
typeid(*this).name());
889 else InitDerivedClass(v, className);
892 HSQUIRRELVM *p = (HSQUIRRELVM *) sq_newuserdata(v,
sizeof(v));
895 sq_setreleasehook(v, -1, cleanup_hook);
904 void InitDerivedClass(HSQUIRRELVM vm,
const string& className) {
905 ClassType<C>::CopyFunc(vm) = &A::Copy;
906 ClassType<C>::ClassName(vm) = className;
907 ClassType<C>::BaseClass(vm) = ClassType<B>::getClassTypeData(vm);
910 sq_pushobject(vm, ClassType<C>::ClassObject(vm));
913 sq_settypetag(vm, -1, ClassType<C>::getClassTypeData(vm));
915 sq_pushstring(vm,_SC(
"constructor"), -1);
916 sq_newclosure(vm, &A::New, 0);
917 sq_newslot(vm, -3,
false);
920 HSQOBJECT& setTable = ClassType<C>::SetTable(vm);
921 sq_resetobject(&setTable);
922 sq_pushobject(vm, ClassType<B>::SetTable(vm));
923 sq_pushstring(vm,_SC(
"__setTable"), -1);
926 sq_getstackobj(vm, -1, &setTable);
927 sq_addref(vm, &setTable);
928 sq_newslot(vm, -3,
true);
931 HSQOBJECT& getTable = ClassType<C>::GetTable(vm);
932 sq_resetobject(&getTable);
933 sq_pushobject(vm, ClassType<B>::GetTable(vm));
934 sq_pushstring(vm,_SC(
"__getTable"), -1);
937 sq_getstackobj(vm, -1, &getTable);
938 sq_addref(vm, &getTable);
939 sq_newslot(vm, -3,
true);
942 sq_pushstring(vm, _SC(
"_set"), -1);
943 sq_pushobject(vm, setTable);
944 sq_newclosure(vm, sqVarSet, 1);
945 sq_newslot(vm, -3,
false);
948 sq_pushstring(vm, _SC(
"_get"), -1);
949 sq_pushobject(vm, getTable);
950 sq_newclosure(vm, sqVarGet, 1);
951 sq_newslot(vm, -3,
false);
954 sq_pushstring(vm, _SC(
"weakref"), -1);
956 sq_newslot(vm, -3,
false);
959 sq_pushstring(vm, _SC(
"_typeof"), -1);
961 sq_newslot(vm, -3,
false);
Class & Ctor(const SQChar *name=0)
Definition: sqratClass.h:730
static HSQUIRRELVM Get()
Definition: sqratUtil.h:92
virtual HSQOBJECT GetObject() const
Definition: sqratClass.h:119
Class & GlobalFunc(const SQChar *name, F method)
Definition: sqratClass.h:371
Class & Ctor(const SQChar *name=0)
Definition: sqratClass.h:820
Class(HSQUIRRELVM v=DefaultVM::Get(), const string &className=string(), bool createClass=true)
Definition: sqratClass.h:86
Class & Prop(const SQChar *name, F1 getMethod, F2 setMethod)
Definition: sqratClass.h:232
Class & Ctor(const SQChar *name=0)
Definition: sqratClass.h:751
Class & GlobalProp(const SQChar *name, F1 getMethod, F2 setMethod)
Definition: sqratClass.h:263
Class & Ctor(const SQChar *name=0)
Definition: sqratClass.h:656
Class & StaticVar(const SQChar *name, V *var)
Definition: sqratClass.h:205
Function GetFunction(const SQChar *name)
Definition: sqratClass.h:466
Class & StaticOverload(const SQChar *name, F method)
Definition: sqratClass.h:430
Class & Ctor(const SQChar *name=0)
Definition: sqratClass.h:796
Class & Ctor(const SQChar *name=0)
Definition: sqratClass.h:773
Class & Prop(const SQChar *name, F getMethod)
Definition: sqratClass.h:292
Class & Overload(const SQChar *name, F method)
Definition: sqratClass.h:354
DerivedClass(HSQUIRRELVM v=DefaultVM::Get(), const string &className=string())
Definition: sqratClass.h:872
Definition: sqratClass.h:56
Class & GlobalProp(const SQChar *name, F getMethod)
Definition: sqratClass.h:314
Represents a function in Squirrel.
Definition: sqratFunction.h:40
Class & Func(const SQChar *name, F method)
Definition: sqratClass.h:333
Class & SetValue(const SQChar *name, const V &val)
Definition: sqratClass.h:166
Class & Ctor(const SQChar *name=0)
Definition: sqratClass.h:641
Class & StaticFunc(const SQChar *name, F method)
Definition: sqratClass.h:388
virtual HSQOBJECT & GetObject()
Definition: sqratClass.h:129
Class & GlobalOverload(const SQChar *name, F method)
Definition: sqratClass.h:409
Definition: sqratObject.h:48
Class & Ctor(const SQChar *name=0)
Definition: sqratClass.h:710
Class & Var(const SQChar *name, V C::*var)
Definition: sqratClass.h:183
Class & SetStaticValue(const SQChar *name, const V &val)
Definition: sqratClass.h:149
Class & SquirrelFunc(const SQChar *name, SQFUNCTION func)
Definition: sqratClass.h:448
Definition: sqratClass.h:843
Class & Ctor(const SQChar *name=0)
Definition: sqratClass.h:673
Class & Ctor(const SQChar *name=0)
Definition: sqratClass.h:691