From d82e2449a0282232c6e6acd1a84514ee5332f4db Mon Sep 17 00:00:00 2001 From: "lapayo94@gmail.com" Date: Mon, 9 Jul 2012 15:53:17 +0000 Subject: Improved Squirrel Bindings Added AddCommand / BindCommand for Squirrel Plugins git-svn-id: http://mc-server.googlecode.com/svn/trunk@652 0a769ca7-a7f5-676a-18bf-c427514a06d6 --- squirrel_3_0_1_stable/_OLD_sqplus/sqplus.h | 2327 ---------------------------- 1 file changed, 2327 deletions(-) delete mode 100644 squirrel_3_0_1_stable/_OLD_sqplus/sqplus.h (limited to 'squirrel_3_0_1_stable/_OLD_sqplus/sqplus.h') diff --git a/squirrel_3_0_1_stable/_OLD_sqplus/sqplus.h b/squirrel_3_0_1_stable/_OLD_sqplus/sqplus.h deleted file mode 100644 index fff1633ed..000000000 --- a/squirrel_3_0_1_stable/_OLD_sqplus/sqplus.h +++ /dev/null @@ -1,2327 +0,0 @@ -// SqPlus.h -// Created by John Schultz 9/05/05, major update 10/05/05. -// Template function call design from LuaPlusCD by Joshua C. Jensen, -// inspired by luabind which was inspired by boost::python. -// Const argument, const member functions, and Mac OS-X changes by Simon Michelmore. -// DECLARE_INSTANCE_TYPE_NAME changes by Ben (Project5) from http://www.squirrel-lang.org/forums/. -// Added Kamaitati's changes 5/28/06. -// Free for any use. - -#ifndef _SQ_PLUS_H_ -#define _SQ_PLUS_H_ - -#include -#include - -#ifdef __APPLE__ - #include -#else - #include -#endif -#include -#include -#include // For INT_MAX on GCC - -#include "squirrel.h" // Include to get SQUNICODE setting from here -#ifndef _SC - #error No _SC macro - Usually defined in squirrel.h -#endif -// Provide a _sqT(...) macros also (same as _SC but easier to know its for Squirrel) -#ifndef _sqT - #define _sqT _SC -#endif - -// For backward compatibility, define _T if outside of Windows platform. -// (really, _SC() or _sqT() are better, since that leaves us free to run -// Squirrel in ASCII or wchar_t mode, regardless of the app being built). -#if !defined(_WIN32) && !defined(_WIN64) - #ifndef _T - #define _T _SC - #endif -#endif - - -// A comment about strings. We let squirrel.h determine whether to use -// char or wchar_t strings. So here we follow the define SQUNICODE. This -// opens up for using Unicode system calls on Windows while having the script -// engine in ASCII mode, or vice versa. To enable this, also the macro -// _SC("some string") is used instead of _T("some string"). -// -// To handle the case where function parameters are given in the opposite -// character mode (char if SQChar is wchar_t and vice versa), such strings -// can be converted on the fly to the other mode in the function call, if -// the define SQPLUS_AUTOCONVERT_OTHER_CHAR is set below. Buffers are -// allocated and kept around for the duration of the function call. The -// same applies to returned strings of the opposite type. - -#if defined(_MSC_VER) || defined(__BORLANDC__) - #include - #ifndef SQUNICODE - #define SCSNPRINTF _snprintf - #define SCPUTS puts - #else - #define SCSNPRINTF _snwprintf - #define SCPUTS _putws - #endif - #if defined(_MSC_VER) - #ifndef _CRT_SECURE_NO_DEPRECATE - #define _CRT_SECURE_NO_DEPRECATE // Disable warnings around various sprintf - #endif - #pragma warning(disable: 4996) // When above does not work - #endif -#else - #ifdef SQUNICODE - #define SCSNPRINTF _snwprintf - #define SCPUTS _putws - #include // for snprintf - #else - #define SCSNPRINTF snprintf - #include // for snprintf - #define SCPUTS puts - #endif -#endif - - -#ifndef _WINDEF_ - typedef int BOOL; - typedef int INT; - typedef float FLOAT; - #define TRUE 1 - #define FALSE 0 -#endif - -#if 1 -#define SQ_CALL_RAISE_ERROR SQTrue -#else -#define SQ_CALL_RAISE_ERROR SQFalse -#endif - -#include "SquirrelObject.h" -#include "SquirrelVM.h" -#include "SquirrelBindingsUtils.h" - -// All setup defines have moved to its own file -#include "SqPlusSetup.h" - -#ifdef SQPLUS_AUTOCONVERT_OTHER_CHAR -#define SQPLUS_AUTOCONVERT_MAX_INSTANCES 8 // In argument conversion, don't keep more than this alive -#include "SqPlusOCharBuf.h" -#endif - -#if defined(SQPLUS_SUPPORT_STD_STRING) && defined(SQUNICODE) - #ifdef _MSC_VER - #pragma message("std::string and SQChar as wchar_t is not compatible!") - #else - #warning std::string and SQChar as wchar_t is not compatible! - #endif -#endif - - -namespace SqPlus { - -template struct TypeWrapper {}; -struct SquirrelNull {}; -struct SQNoBaseClass {}; // For scripted classes with no base class (or no scripted base class) - -struct SQAnything { void * anything; }; // Needed for binding pointers to variables (cannot dereference void *). -typedef SQAnything * SQAnythingPtr; -typedef SQChar * SQCharPtr; - -// Helper struct to (sometimes) store a temporary return value as another type. -// Useful when returning const char* and other types that require temp allocation. -// For primitive types, it just maps onto itself. -template -struct Temporary { - typedef T type; -}; - -// References are tricky, but they should just be filtered out usually -template -struct SqAssignableRef { - SqAssignableRef( ) : m_pt(0) { } - void operator = (T& tr){ m_pt=&tr; } - operator T& () { return *m_pt; } - T *m_pt; -}; - -template -struct Temporary { - typedef SqAssignableRef type; -}; - - -// === Do not use directly: use one of the predefined sizes below === - -struct ScriptStringVarBase { - const unsigned char MaxLength; // Real length is MaxLength+1. - SQChar s[1]; - ScriptStringVarBase(int _MaxLength) : MaxLength(_MaxLength) {} - operator SQChar * () { return &s[0]; } - operator void * () { return (void *)&s[0]; } - const SQChar * operator = (const SQChar * _s) { - return safeStringCopy(s,_s,MaxLength); - } - // Special safe string copy where MaxLength is 1 less than true buffer length. - // strncpy() pads out nulls for the full length of the buffer specified by MaxLength. - static inline SQChar * safeStringCopy(SQChar * d,const SQChar * s,int MaxLength) { - int i=0; - while (s[i]) { - d[i] = s[i]; - i++; - if (i == MaxLength) break; - } // while - d[i] = 0; // Null terminate. - return d; - } // safeStringCopy -}; - -// === Do not use directly: use one of the predefined sizes below === - -template // MAXLENGTH is max printable characters (trailing NULL is accounted for in ScriptStringVarBase::s[1]). -struct ScriptStringVar : ScriptStringVarBase { - SQChar ps[MAXLENGTH]; - ScriptStringVar() : ScriptStringVarBase(MAXLENGTH) { - s[0] = 0; - } - ScriptStringVar(const SQChar * _s) : ScriptStringVarBase(MAXLENGTH) { - *this = _s; - } - const SQChar * operator = (const SQChar * _s) { - return safeStringCopy(s,_s,MaxLength); - } - const SQChar * operator = (const ScriptStringVar & _s) { - return safeStringCopy(s,_s.s,MaxLength); - } - bool operator == (const ScriptStringVar & _s) { - return _strcmp(s,_s.s) == 0; - } - bool compareCaseInsensitive(const ScriptStringVar & _s) { - return _stricmp(s,_s.s) == 0; - } -}; - -// === Fixed size strings for scripting === - -typedef ScriptStringVar<8> ScriptStringVar8; -typedef ScriptStringVar<16> ScriptStringVar16; -typedef ScriptStringVar<32> ScriptStringVar32; -typedef ScriptStringVar<64> ScriptStringVar64; -typedef ScriptStringVar<128> ScriptStringVar128; -typedef ScriptStringVar<256> ScriptStringVar256; - -// === Script Variable Types === - -enum ScriptVarType { - VAR_TYPE_NONE = -1, - VAR_TYPE_INT = 0, - VAR_TYPE_UINT, - VAR_TYPE_FLOAT, - VAR_TYPE_BOOL, - VAR_TYPE_CONST_STRING, - VAR_TYPE_STRING, - VAR_TYPE_USER_POINTER, - VAR_TYPE_INSTANCE, -#ifdef SQPLUS_SUPPORT_STD_STRING - VAR_TYPE_STD_STRING, -#endif -}; - -template -struct TypeInfo { - const SQChar * typeName; - enum {TypeID=VAR_TYPE_NONE, Size=0, TypeMask='?', IsInstance=0}; -}; - -// === Common Variable Types === - -template<> -struct TypeInfo { - const SQChar * typeName; - TypeInfo() : typeName(_SC("int")) {} - enum {TypeID=VAR_TYPE_INT,Size=sizeof(INT),TypeMask='i', IsInstance=0}; - operator ScriptVarType() { return ScriptVarType(TypeID); } -}; - -template<> -struct TypeInfo { - const SQChar * typeName; - TypeInfo() : typeName(_SC("uint")) {} - enum {TypeID=VAR_TYPE_UINT,Size=sizeof(unsigned), IsInstance=0}; - operator ScriptVarType() { return ScriptVarType(TypeID); } -}; - -template<> -struct TypeInfo { - const SQChar * typeName; - TypeInfo() : typeName(_SC("float")) {} - enum {TypeID=VAR_TYPE_FLOAT,Size=sizeof(FLOAT),TypeMask='f', IsInstance=0}; - operator ScriptVarType() { return ScriptVarType(TypeID); } -}; - -template<> -struct TypeInfo { - const SQChar * typeName; - TypeInfo() : typeName(_SC("bool")) {} - enum {TypeID=VAR_TYPE_BOOL,Size=sizeof(bool),TypeMask='b', IsInstance=0}; - operator ScriptVarType() { return ScriptVarType(TypeID); } -}; - -template<> -struct TypeInfo { - const SQChar * typeName; - TypeInfo() : typeName(_SC("short")) {} - enum {TypeID=VAR_TYPE_INT,Size=sizeof(short),TypeMask='i', IsInstance=0}; - operator ScriptVarType() { return ScriptVarType(TypeID); } -}; - -template<> -struct TypeInfo { - const SQChar * typeName; - TypeInfo() : typeName(_SC("char")) {} - enum {TypeID=VAR_TYPE_INT,Size=sizeof(char),TypeMask='i', IsInstance=0}; - operator ScriptVarType() { return ScriptVarType(TypeID); } -}; - -template<> -struct TypeInfo { - const SQChar * typeName; - TypeInfo() : typeName(_SC("SQUserPointer")) {} - enum {TypeID=VAR_TYPE_USER_POINTER,Size=sizeof(SQUserPointer),TypeMask='u', IsInstance=0}; - operator ScriptVarType() { return ScriptVarType(TypeID); } -}; - -template<> -struct TypeInfo { - const SQChar * typeName; - TypeInfo() : typeName(_SC("SQUserPointer")) {} - enum {TypeID=VAR_TYPE_USER_POINTER,Size=sizeof(SQUserPointer),TypeMask='u', IsInstance=0}; - operator ScriptVarType() { return ScriptVarType(TypeID); } -}; - -template<> -struct TypeInfo { - const SQChar * typeName; - TypeInfo() : typeName(0) {} - enum {TypeID=-1,Size=0,TypeMask=' ', IsInstance=0}; - operator ScriptVarType() { return ScriptVarType(TypeID); } -}; - -template<> -struct TypeInfo { - const SQChar * typeName; - TypeInfo() : typeName(_SC("const SQChar *")) {} - enum {TypeID=VAR_TYPE_CONST_STRING,Size=sizeof(const SQChar *),TypeMask='s', IsInstance=0}; - operator ScriptVarType() { return ScriptVarType(TypeID); } -}; - -#ifdef SQPLUS_AUTOCONVERT_OTHER_CHAR -template<> -struct TypeInfo { - const SQChar * typeName; - TypeInfo() : typeName(_SC("const SQOtherChar *")) {} - enum {TypeID=VAR_TYPE_CONST_STRING,Size=sizeof(const SQOtherChar *),TypeMask='s', IsInstance=0}; - operator ScriptVarType() { return ScriptVarType(TypeID); } -}; -template<> -struct Temporary { - typedef SQOthCharBuf type; -}; -template<> -struct Temporary { - typedef SQOthCharBuf type; -}; -#endif // SQPLUS_AUTOCONVERT_OTHER_CHAR - -// base case: raw pointer -template -struct TypeInfoPtrBase { - const SQChar * typeName; - TypeInfoPtrBase() : typeName(TypeInfo().typeName) {} - enum {TypeID=VAR_TYPE_USER_POINTER,Size=sizeof(T*),TypeMask='u'}; - operator ScriptVarType() { return ScriptVarType(TypeID); } -}; - -template -struct TypeInfoPtrBase : public TypeInfo { }; - -// Partial specialization for pointers (to access type without pointer / or instance typeinfo) -template -struct TypeInfo : public TypeInfoPtrBase::IsInstance> { }; - -// Same thing for references -template -struct TypeInfo : public TypeInfoPtrBase::IsInstance> { }; - -#ifdef SQPLUS_SUPPORT_STD_STRING -template<> -struct TypeInfo { - const SQChar *typeName; - TypeInfo() : typeName(_SC("std::string")) {} - enum {TypeID=SqPlus::VAR_TYPE_STD_STRING,Size=sizeof(std::string),TypeMask='s'}; - operator ScriptVarType() {return ScriptVarType(TypeID);} -}; -#endif - -template<> -struct TypeInfo { - const SQChar * typeName; - TypeInfo() : typeName(_SC("ScriptStringVarBase")) {} - enum {TypeID=VAR_TYPE_STRING,Size=sizeof(ScriptStringVarBase),TypeMask='s', IsInstance=0}; - operator ScriptVarType() { return ScriptVarType(TypeID); } -}; - -// === Fixed String Variants === - -template -struct TypeInfo > { - SQChar typeName[24]; - TypeInfo() { scsprintf(typeName,_SC("ScriptStringVar<%d>"),N); } - enum {TypeID=VAR_TYPE_STRING,Size=N*sizeof(ScriptStringVar),TypeMask='s', IsInstance=0}; - operator ScriptVarType() { return ScriptVarType(TypeID); } -}; - -#ifdef SQPLUS_SMARTPOINTER_OPT - #define SQPLUS_SMARTPOINTER_ACCESSTYPE - #include "SqPlusSmartPointer.h" -#else - enum VarAccessType {VAR_ACCESS_READ_WRITE=0,VAR_ACCESS_READ_ONLY=1<<0,VAR_ACCESS_CONSTANT=1<<1,VAR_ACCESS_STATIC=1<<2}; -#endif // SQPLUS_SMARTPOINTER_OPT - -// See VarRef and ClassType<> below: for instance assignment. -typedef void (*CopyVarFunc)(void * dst,void * src); - - -// === Class Type Helper class: returns an ID for each class type and provides base class pointer offset === - -struct ClassTypeBase { - ClassTypeBase() : m_pbase(0), m_name(0), m_offset(0), m_may_have_offset(-1) { } - // Many types cannot have offset, since "this" is the same for all base classes of - // an instance. Detect this, to avoid sum up base offsets all the time. - int MayHaveOffset( ) { - if( m_may_have_offset<0 ){ - if( m_offset ) m_may_have_offset = 1; - else m_may_have_offset = m_pbase ? m_pbase->MayHaveOffset() : 0; - } - return m_may_have_offset; - } - int GetOffsetTo( ClassTypeBase *pbase ){ - if( !m_pbase ) { /*printf("ClassTypeBase::getOffsetTo - Warning - Base type pointer is NULL!\n" );*/ return 0; } - return m_pbase==pbase ? m_offset : m_offset+m_pbase->GetOffsetTo(pbase); - } - virtual CopyVarFunc vgetCopyFunc(void) = 0; - virtual const SQChar* GetTypeName() = 0; - - ClassTypeBase *m_pbase; - const SQChar *m_name; // Name of type - int m_offset; // Adjustment of this pointer between this type and its base class - int m_may_have_offset; // Set to 0 for types that cannot possibly have offset -}; - -// This level handles instance copying in different ways -template -struct ClassTypeCopyImpl; - -// Helper struct to decide if type is copyable or not -template -struct IsCopyable { enum { value=true }; }; - -#define DECLARE_NONCOPY_TYPE_INTERN(TYPE) \ - template<> struct IsCopyable { enum { value=false }; }; - -// Macro to declare a type that should _not_ be copied using ordinary -// c++ copy expresssion: *(T*)pt1 = *(T*)pt2; -#define DECLARE_NONCOPY_TYPE(TYPE) namespace SqPlus { \ - template<> struct IsCopyable { enum { value=false }; }; \ -} - -// Base class to do copying in ordinary C++ way -template -struct ClassTypeCopyImpl : public ClassTypeBase { - static void copy(T * dst,T * src) { - *dst = *src; // This works types with copy ctor / assign operator - } // copy -}; - -// Base class to do copying with memcpy -template -struct ClassTypeCopyImpl : public ClassTypeBase { - static void copy(T * dst,T * src) { - memcpy(dst,src,sizeof(T)); // This works for raw data types - } // copy -}; - -// Base classes to do avoid copying altogether (void case) -template<> -struct ClassTypeCopyImpl : public ClassTypeBase { - static void copy(void * dst,void * src) { } // copy -}; - -template<> -struct ClassTypeCopyImpl : public ClassTypeBase { - static void copy(void * dst,void * src) { } // copy -}; - - -template -struct ClassType : public ClassTypeCopyImpl::value> { - typedef ClassTypeCopyImpl::value> ClassTypeBase; - ClassType( ) { this->m_name=stGetName(); } - - virtual CopyVarFunc vgetCopyFunc(void) { return (CopyVarFunc)&ClassTypeBase::copy; } - virtual const SQChar* GetTypeName(){ return this->m_name; } - - template - void SetBase(TypeWrapper) { - this->m_pbase = ClassType::Get(); - T* pt = reinterpret_cast(this); - this->m_offset = ((char*)pt)-((char*)static_cast(pt)); - } - static ClassType* Get(){ static ClassType st_ct; return &st_ct; } - static ClassTypeBase* type() { return Get(); } - static CopyVarFunc getCopyFunc(void) { return (CopyVarFunc)&ClassTypeBase::copy; } - static const SQChar* stGetName(){ return TypeInfo().typeName; } - - #ifdef SQPLUS_OVERLOAD_OPT - #define SQPLUS_OVERLOAD_RELEASE_HOOK - #include "SqPlusOverload.h" - #endif -}; - - -// === Variable references for script access === - -#define SQ_PLUS_TYPE_TABLE _SC("__SqTypes") - -struct VarRef { - // In this case 'offsetOrAddrOrConst' is simpler than using an anonymous union. - void * offsetOrAddrOrConst; // Instance member variable offset from 'this' pointer base (as size_t), or address if static variable (void *), or constant value. - ScriptVarType m_type; // Variable type (from enum above). - ClassTypeBase* instanceType; // Class type of the containing class instance (for member vars only). - ClassTypeBase* varType; // The class type of the variable itself - short m_size; // ATS: Use for short and char support. For debugging only (size of item when pointer to item is dereferenced). Could be used for variable max string buffer length. - short m_access; // VarAccessType. - - VarRef() : offsetOrAddrOrConst(0), m_type(VAR_TYPE_NONE), instanceType(0/*(SQUserPointer)-1*/), /*copyFunc(0),*/ m_size(0), m_access(VAR_ACCESS_READ_WRITE) {} - VarRef(void * _offsetOrAddrOrConst, ScriptVarType _type, ClassTypeBase* _instanceType, ClassTypeBase* _varType, int _size, VarAccessType _access) : - offsetOrAddrOrConst(_offsetOrAddrOrConst), m_type(_type), instanceType(_instanceType), varType(_varType), m_size(_size), m_access(_access) { -#ifdef SQ_SUPPORT_INSTANCE_TYPE_INFO - SquirrelObject typeTable = SquirrelVM::GetRootTable().GetValue(SQ_PLUS_TYPE_TABLE); - if (typeTable.IsNull()) { - typeTable = SquirrelVM::CreateTable(); - SquirrelObject root = SquirrelVM::GetRootTable(); - root.SetValue(SQ_PLUS_TYPE_TABLE,typeTable); - } // if - typeTable.SetValue(INT((size_t)varType),varType->GetTypeName()); -#endif // SQ_SUPPORT_INSTANCE_TYPE_INFO - } -}; - -typedef VarRef * VarRefPtr; - -// Internal use only. -inline void getVarNameTag(SQChar * buff,INT maxSize,const SQChar * scriptName) { -// assert(maxSize > 3); -#if 1 - SQChar * d = buff; - d[0] = '_'; - d[1] = 'v'; - d = &d[2]; - maxSize -= (2+1); // +1 = space for null. - int pos=0; - while (scriptName[pos] && pos < maxSize) { - d[pos] = scriptName[pos]; - pos++; - } // while - d[pos] = 0; // null terminate. -#else - SCSNPRINTF(buff,maxSize,_SC("_v%s"),scriptName); -#endif -} // getVarNameTag - -// Internal use only. -int setVarFunc(HSQUIRRELVM v); -int getVarFunc(HSQUIRRELVM v); -int setInstanceVarFunc(HSQUIRRELVM v); -int getInstanceVarFunc(HSQUIRRELVM v); - -// === BEGIN Helpers === - -inline void createTableSetGetHandlers(SquirrelObject & so) { - SquirrelObject delegate = so.GetDelegate(); - if (!delegate.Exists(_SC("_set"))) { - delegate = SquirrelVM::CreateTable(); - SquirrelVM::CreateFunction(delegate,setVarFunc,_SC("_set"),_SC("sn|b|s")); // String var name = number(int or float) or bool or string. - SquirrelVM::CreateFunction(delegate,getVarFunc,_SC("_get"),_SC("s")); // String var name. - so.SetDelegate(delegate); - } // if -} // createTableSetGetHandlers - -inline VarRefPtr createVarRef(SquirrelObject & so,const SQChar * scriptVarName) { - VarRefPtr pvr=0; - ScriptStringVar256 scriptVarTagName; getVarNameTag(scriptVarTagName,sizeof(scriptVarTagName),scriptVarName); - if (!so.GetUserData(scriptVarTagName,(SQUserPointer *)&pvr)) { - so.NewUserData(scriptVarTagName,sizeof(*pvr)); - if (!so.GetUserData(scriptVarTagName,(SQUserPointer *)&pvr)) throw SquirrelError(_SC("Could not create UserData.")); - } // if - return pvr; -} // createVarRef - -template -void validateConstantType(T constant) { - switch(TypeInfo()) { - case VAR_TYPE_INT: - case VAR_TYPE_FLOAT: - case VAR_TYPE_BOOL: - case VAR_TYPE_CONST_STRING: - break; - default: - throw SquirrelError(_SC("validateConstantType(): type must be INT, FLOAT, BOOL, or CONST CHAR *.")); - } // case -} // validateConstantType - -inline void createInstanceSetGetHandlers(SquirrelObject & so) { - if (!so.Exists(_SC("_set"))) { - SquirrelVM::CreateFunction(so,setInstanceVarFunc,_SC("_set"),_SC("sn|b|s|x")); // String var name = number(int or float) or bool or string or instance. - SquirrelVM::CreateFunction(so,getInstanceVarFunc,_SC("_get"),_SC("s")); // String var name. - } // if -} // createInstanceSetGetHandlers - -// === END Helpers === - - -// Provide an overridable way of copying / deleting objects -template -struct ObjectCloner { - static T* Clone(T* src){ return new T(src); } - static void Delete(T* dst){ if(dst) delete dst; } -}; - -// specialization for void type -//template<> inline void ClassType::copy(void *dst, void *src) {} -DECLARE_NONCOPY_TYPE_INTERN(void) - - -// === Bind a global or pre-allocated (not instance) class member variable or constant (for tables only (not classes)) === - -template -void BindVariable(SquirrelObject & so,T * var,const SQChar * scriptVarName,VarAccessType access=VAR_ACCESS_READ_WRITE) { - VarRefPtr pvr = createVarRef(so,scriptVarName); - *pvr = VarRef(var,TypeInfo(),NULL,ClassType::type(),sizeof(*var),access); - createTableSetGetHandlers(so); -} // BindVariable - -// === Bind a constant by value: INT, FLOAT, BOOL, or CONST CHAR * (for tables only (not classes)) === - -template -void BindConstant(SquirrelObject & so,T constant,const SQChar * scriptVarName) { - validateConstantType(constant); - VarRefPtr pvr = createVarRef(so,scriptVarName); - struct CV { - T var; - } cv; // Cast Variable helper. - cv.var = constant; - *pvr = VarRef(*(void **)&cv,TypeInfo(),NULL,ClassType::type(),sizeof(constant),VAR_ACCESS_CONSTANT); - createTableSetGetHandlers(so); -} // BindConstant - -template -void BindVariable(T * var,const SQChar * scriptVarName,VarAccessType access=VAR_ACCESS_READ_WRITE) { - SquirrelObject so = SquirrelVM::GetRootTable(); - BindVariable(so,var,scriptVarName,access); -} // BindVariable - -template -void BindConstant(T constant,const SQChar * scriptVarName) { - SquirrelObject so = SquirrelVM::GetRootTable(); - BindConstant(so,constant,scriptVarName); -} // BindConstant - -// === Register a class instance member variable or constant. var argument provides type and offset ( effectively &((ClassType *)0)->var ) === - -// classType is the type of the member variable's containing class. - template -void RegisterInstanceVariable(SquirrelObject & so,ClassTypeBase* classType,T * var,const SQChar * scriptVarName,VarAccessType access=VAR_ACCESS_READ_WRITE) { - VarRef * pvr = createVarRef(so,scriptVarName); - void * offsetOrAddrOrConst = (void *)var; // var must be passed in as &obj->var, where obj = 0 (the address is the offset), or as static/global address. - *pvr = VarRef(offsetOrAddrOrConst,TypeInfo(),classType,ClassType::type(),sizeof(*var),access); - createInstanceSetGetHandlers(so); -} // RegisterInstanceVariable - -#ifdef SQPLUS_SMARTPOINTER_OPT -#define SQPLUS_SMARTPOINTER_REGISTER_VARIABLE -#include "SqPlusSmartPointer.h" -#endif - -template -void RegisterInstanceConstant(SquirrelObject & so,ClassTypeBase *classType,T constant,const SQChar * scriptVarName) { - validateConstantType(constant); - VarRef * pvr = createVarRef(so,scriptVarName); - struct CV { - T var; - size_t pad; - } cv; // Cast Variable helper. - cv.var = constant; - *pvr = VarRef(*(void **)&cv,TypeInfo(),classType,ClassType::type(),sizeof(constant),VAR_ACCESS_CONSTANT); - createInstanceSetGetHandlers(so); -} // RegisterInstanceConstant - -////////////////////////////////////////////////////////////////////////// -/////////// BEGIN Generalized Class/Struct Instance Support ////////////// -////////////////////////////////////////////////////////////////////////// - -// Was previously in SqPlus namespace -//BOOL CreateNativeClassInstance(HSQUIRRELVM v,const SQChar * classname,SQUserPointer ud,SQRELEASEHOOK hook); // In SquirrelBindingUtils.cpp. - -// Create native class instance and leave on stack. -//BOOL CreateConstructNativeClassInstance(HSQUIRRELVM v,const SQChar * className); - -// Create new instance, copy 'classToCopy', and store result on stack. -template -inline BOOL CreateCopyInstance(HSQUIRRELVM v, const SQChar * className,const T & classToCopy) { -#ifndef SQPLUS_DISABLE_COPY_INSTANCES - if (!CreateConstructNativeClassInstance(v,className)) { - return FALSE; - } // if - SQUserPointer up=0; - sq_getinstanceup(v,-1,&up,ClassType::type()); - if (!up) return FALSE; - T * newClass = (T *)up; - *newClass = classToCopy; // Optimized version that uses the copy constructor. - return TRUE; -#else - return FALSE; -#endif -} // CreateCopyInstance - -// Create a new copy of type 'className' and copy 'classToCopy', return result via SquirrelObject. -template -inline SquirrelObject NewClassCopy(HSQUIRRELVM v, const SQChar * className,const T & classToCopy) { - if (CreateCopyInstance(v, className,classToCopy)) { - HSQOBJECT t; - sq_getstackobj(v,-1,&t); - SquirrelObject obj(t); - sq_poptop(v); - return obj; - } else { - throw SquirrelError(_SC("NewClassCopy(): could not create class")); - } // if - return SquirrelObject(); -} // NewClassCopy - -// Return a new class copy on the stack from a varArgs function call. -template -inline int ReturnCopy(HSQUIRRELVM v,const T & classToCopy) { - SquirrelObject so(NewClassCopy(v,GetTypeName(classToCopy),classToCopy)); - return StackHandler(v).Return(so); -} // ReturnCopy - -// Katsuaki Kawachi's GetInstance<> exception change. 6/27/06 jcs - -// Get an instance of type T from the stack at idx (for function calls). -template -T * GetInstance(HSQUIRRELVM v,SQInteger idx) { - SQUserPointer up=0; - if (SQ_FAILED(sq_getinstanceup(v,idx,&up,ClassType::type()))) { - up = 0; - } - if (ExceptionOnError) { // This code block should be compiled out when ExceptionOnError is false. In any case, the compiler should not generate a test condition (include or exclude the enclosed code block). - if (!up) { - throw SquirrelError(_SC("GetInstance: Invalid argument type")); - } - } // if - return (T *)up; -} // GetInstance - - -template void Push(HSQUIRRELVM v, T* pt); -template void Push(HSQUIRRELVM v, T& t); -template bool Match(TypeWrapper, HSQUIRRELVM v, int ix); -template bool Match(TypeWrapper, HSQUIRRELVM v, int ix); -template T &Get(TypeWrapper, HSQUIRRELVM v, int ix); -template T *Get(TypeWrapper, HSQUIRRELVM v, int ix); - - -#ifdef SQPLUS_USE_GENERIC_HANDLERS -// With template specialization, we get Push handlers per 'precise type match' -// This adds a fallback level after that, where we can delegate the work to -// wider C-style functions that can do something for a whole class hierarchy. -// (GenPush, GenGet, GenMatch). - -// This macro allows for a a last generic cast operation before giving control -// to one of GenPush/GenMatch/GenGet. -#ifndef SQPLUS_GEN_CAST - #define SQPLUS_GEN_CAST(TYPE,value) ((TYPE*)value) -#endif - -template void Push(HSQUIRRELVM v, T* pt){ GenPush(v,SQPLUS_GEN_CAST(T,pt)); } -template void Push(HSQUIRRELVM v, T& t){ GenPush(v,SQPLUS_GEN_CAST(T,&t)); } -template bool Match(TypeWrapper, HSQUIRRELVM v, int ix){ - if((ScriptVarType)TypeInfo::TypeID!=VAR_TYPE_NONE) - return GenMatch(SQPLUS_GEN_CAST(T*,0),TypeInfo().typeName,v,ix); - else return false; -} -template bool Match(TypeWrapper, HSQUIRRELVM v, int ix){ - if((ScriptVarType)TypeInfo::TypeID!=VAR_TYPE_NONE) - return GenMatch(SQPLUS_GEN_CAST(T*,0),TypeInfo().typeName,v,ix); - else return false; -} -template T &Get(TypeWrapper, HSQUIRRELVM v, int ix){ - if((ScriptVarType)TypeInfo::TypeID!=VAR_TYPE_NONE) - return *(T*)GenGet(SQPLUS_GEN_CAST(T*,0),TypeInfo().typeName,v,ix); - else return *SQPLUS_GEN_CAST(T,0); -} -template T *Get(TypeWrapper, HSQUIRRELVM v, int ix){ - if((ScriptVarType)TypeInfo::TypeID!=VAR_TYPE_NONE) - return (T*)GenGet(SQPLUS_GEN_CAST(T*,0),TypeInfo().typeName,v,ix); - else return NULL; -} -#endif // SQPLUS_USE_GENERIC_HANDLERS - - -// === BEGIN Function Call Handler Prototypes === - -void Push(HSQUIRRELVM v, char value); -void Push(HSQUIRRELVM v, unsigned char value); -void Push(HSQUIRRELVM v, short value); -void Push(HSQUIRRELVM v, unsigned short value); -void Push(HSQUIRRELVM v, int value); -void Push(HSQUIRRELVM v, unsigned int value); -void Push(HSQUIRRELVM v, long value); -void Push(HSQUIRRELVM v, unsigned long value); -void Push(HSQUIRRELVM v, double value); -void Push(HSQUIRRELVM v, float value); -void Push(HSQUIRRELVM v, const SQChar *value); -void Push(HSQUIRRELVM v, SQChar *value); -void Push(HSQUIRRELVM v, const SquirrelNull &); -void Push(HSQUIRRELVM v, SQFUNCTION value); -void Push(HSQUIRRELVM v, SQAnythingPtr value); // Cast to SQAnythingPtr instead of void * if USE_ARGUMENT_DEPENDANT_OVERLOADS can't be used by your compiler. -void Push(HSQUIRRELVM v, SquirrelObject &so); - -#define USE_ARGUMENT_DEPENDANT_OVERLOADS -#ifdef USE_ARGUMENT_DEPENDANT_OVERLOADS -#ifdef _MSC_VER -#pragma warning(disable:4675) // Disable warning: "resolved overload was found by argument-dependent lookup" when class/struct pointers are used as function arguments. -#endif -// === BEGIN Argument Dependent Overloads === -void Push(HSQUIRRELVM v, bool value); // Pass bool as int if USE_ARGUMENT_DEPENDANT_OVERLOADS can't be used by your compiler. -void Push(HSQUIRRELVM v, const void *value); // Pass SQAnythingPtr instead of void * " " -void Push(HSQUIRRELVM v, const SQUserPointer &value); -// === END Argument Dependent Overloads === -#endif - -#define SQPLUS_CHECK_GET(res) if (!SQ_SUCCEEDED(res)) throw SquirrelError(_SC("sq_get*() failed (type error)")) - -bool Match(TypeWrapper, HSQUIRRELVM v, int idx); -bool Match(TypeWrapper, HSQUIRRELVM v, int idx); -bool Match(TypeWrapper, HSQUIRRELVM v, int idx); -bool Match(TypeWrapper, HSQUIRRELVM v, int idx); -bool Match(TypeWrapper, HSQUIRRELVM v, int idx); -bool Match(TypeWrapper, HSQUIRRELVM v, int idx); -bool Match(TypeWrapper, HSQUIRRELVM v, int idx); -bool Match(TypeWrapper, HSQUIRRELVM v, int idx); -bool Match(TypeWrapper, HSQUIRRELVM v, int idx); -bool Match(TypeWrapper, HSQUIRRELVM v, int idx); -bool Match(TypeWrapper, HSQUIRRELVM v, int idx); -bool Match(TypeWrapper, HSQUIRRELVM v, int idx); -bool Match(TypeWrapper, HSQUIRRELVM v, int idx); -bool Match(TypeWrapper, HSQUIRRELVM v, int idx); // See Get() for HSQUIRRELVM below (v is always present). -bool Match(TypeWrapper, HSQUIRRELVM v, int idx); -bool Match(TypeWrapper, HSQUIRRELVM v, int idx); // See sq_getstackobj(): always returns true. - -void Get(TypeWrapper, HSQUIRRELVM v, int); -bool Get(TypeWrapper, HSQUIRRELVM v, int idx); -char Get(TypeWrapper, HSQUIRRELVM v, int idx); -unsigned char Get(TypeWrapper, HSQUIRRELVM v, int idx); -short Get(TypeWrapper, HSQUIRRELVM v, int idx); -unsigned short Get(TypeWrapper, HSQUIRRELVM v, int idx); -int Get(TypeWrapper, HSQUIRRELVM v, int idx); -unsigned int Get(TypeWrapper, HSQUIRRELVM v, int idx); -long Get(TypeWrapper, HSQUIRRELVM v, int idx); -unsigned long Get(TypeWrapper, HSQUIRRELVM v, int idx); -float Get(TypeWrapper, HSQUIRRELVM v, int idx); -double Get(TypeWrapper, HSQUIRRELVM v, int idx); -const SQChar *Get(TypeWrapper, HSQUIRRELVM v, int idx); -SquirrelNull Get(TypeWrapper, HSQUIRRELVM v, int idx); -void *Get(TypeWrapper, HSQUIRRELVM v, int idx); -HSQUIRRELVM Get(TypeWrapper, HSQUIRRELVM v, int /*idx*/); // sq_poptop(v): remove UserData from stack so GetParamCount() matches normal behavior. -SquirrelObject Get(TypeWrapper, HSQUIRRELVM v, int idx); - -#ifdef SQPLUS_AUTOCONVERT_OTHER_CHAR - void Push(HSQUIRRELVM v, const SQOtherChar *value); - void Push(HSQUIRRELVM v, SQOtherChar *value); - bool Match(TypeWrapper, HSQUIRRELVM v, int idx); - bool Match(TypeWrapper, HSQUIRRELVM v, int idx); - SQOthCharBuf Get(TypeWrapper, HSQUIRRELVM v, int idx); -#endif // SQPLUS_AUTOCONVERT_OTHER_CHAR - -#ifdef SQPLUS_SUPPORT_STD_STRING -void Push(HSQUIRRELVM v, const std::string& value); -bool Match(TypeWrapper, HSQUIRRELVM v, int idx); -std::string Get(TypeWrapper, HSQUIRRELVM v, int idx); -#endif - -// Added jflanglois suggestion, 8/20/06. jcs -#ifdef SQPLUS_SUPPORT_SQ_STD_STRING -typedef std::basic_string sq_std_string; -void Push(HSQUIRRELVM v,const sq_std_string & value); -bool Match(TypeWrapper, HSQUIRRELVM v, int idx); -sq_std_string Get(TypeWrapper, HSQUIRRELVM v, int idx); -#endif - -// Specialization to support void return type. -void GetRet(TypeWrapper, HSQUIRRELVM v,int idx); - -// GetRet() restores the stack for SquirrelFunction<>() calls. -// Hold on to a reference since return value might be temporary string/instance -template -inline RT GetRet(TypeWrapper,HSQUIRRELVM v,int idx) { - static SquirrelObject st_sq_ret; - static typename Temporary::type st_ret; - st_ret = Get(TypeWrapper(),v,idx); - st_sq_ret.AttachToStackObject(idx); - sq_pop(v,2); // restore stack after function call. - return st_ret; } - -#ifndef GCC_INLINE_WORKAROUND -# include "SqPlusFunctionCallImpl.h" -#endif // GCC_INLINE_WORKAROUND - -// === END Function Call Handlers === - - -// Helper, only implement function bodies -#define IMPLEMENT_ENUM_TYPE(TYPE) namespace SqPlus { \ - bool Match(TypeWrapper,HSQUIRRELVM v,int idx) { return Match(TypeWrapper(),v,idx); } \ - TYPE Get(TypeWrapper,HSQUIRRELVM v,int idx) { return (TYPE)Get(TypeWrapper(),v,idx); } \ - void Push(HSQUIRRELVM v,TYPE value) { sq_pushinteger(v,(int)value); } \ -} // nameSpace SqPlus - -// To register simple types (like enums) so they can be used as arguments -// (however, this does not handle enums as return values correctly, since -// we C++ gets problems with references to temporaries) -#define DECLARE_ENUM_TYPE(TYPE) IMPLEMENT_ENUM_TYPE(TYPE) \ -namespace SqPlus { \ - template<> struct TypeInfo : public TypeInfo { }; \ -} // nameSpace SqPlus - -// As above but use when function bodies should not be generated -// (for a header file). -#define PROTOS_ENUM_TYPE(TYPE) namespace SqPlus { \ - bool Match(TypeWrapper,HSQUIRRELVM v,int idx); \ - TYPE Get(TypeWrapper,HSQUIRRELVM v,int idx); \ - void Push(HSQUIRRELVM v,TYPE value); \ - template<> struct TypeInfo : public TypeInfo { }; \ -} // nameSpace SqPlus - - -// NAME and macro changes from Ben's (Project5) forum post. 2/26/06 jcs -// Kamaitati's NULL_INSTANCE support. 5/28/06 jcs - -// ATS: Splitting the macros in different parts to support custom Push implementation (covariant return type) - -#define DECLARE_INSTANCE_TYPEINFO_(TYPE,NAME) \ - inline const SQChar * GetTypeName(const TYPE & n) { return _SC(#NAME); } \ - template<> \ - struct TypeInfo { \ - const SQChar * typeName; \ - TypeInfo() : typeName( _SC(#NAME)) {} \ - enum {TypeID=VAR_TYPE_INSTANCE,Size=sizeof(TYPE),TypeMask='x', IsInstance=1}; \ - operator ScriptVarType() { return ScriptVarType(TypeID); } \ - }; - -#define DECLARE_INSTANCE_TYPEINFO(TYPE) namespace SqPlus { \ - DECLARE_INSTANCE_TYPEINFO_(TYPE,TYPE) \ -} // namespace SqPlus - -#define DECLARE_INSTANCE_TYPEINFO_NAME(TYPE,NAME) namespace SqPlus { \ - DECLARE_INSTANCE_TYPEINFO_(TYPE,NAME) \ -} // namespace SqPlus - - -#ifdef SQPLUS_SUPPORT_NULL_INSTANCES - -// Macro part shared by 'derived' macros -#define DECLARE_INSTANCE_TYPE_BASE_(TYPE,NAME) \ - DECLARE_INSTANCE_TYPEINFO_(TYPE,NAME) \ - template<> inline bool Match(TypeWrapper,HSQUIRRELVM v,int idx) { return GetInstance(v,idx) != NULL; } \ - template<> inline bool Match(TypeWrapper,HSQUIRRELVM v,int idx) { \ - return (sq_gettype(v,idx)==OT_NULL) || (GetInstance(v,idx) != NULL); } \ - template<> inline TYPE & Get(TypeWrapper,HSQUIRRELVM v,int idx) { return *GetInstance(v,idx); } \ - template<> inline TYPE * Get(TypeWrapper,HSQUIRRELVM v,int idx) { \ - if (sq_gettype(v,idx)==OT_NULL) return NULL; \ - return GetInstance(v,idx); } - -// Ordinary case -#define DECLARE_INSTANCE_TYPE_NAME_(TYPE,NAME) namespace SqPlus { \ - DECLARE_INSTANCE_TYPE_BASE_(TYPE,NAME) \ - template<> inline void Push(HSQUIRRELVM v,TYPE * value) { \ - if (!value) sq_pushnull(v); \ - else if (!CreateNativeClassInstance(v,GetTypeName(*value),value,0)) \ - throw SquirrelError( _SC( "Push(): could not create INSTANCE (check registration name)")); } \ - template<> inline void Push(HSQUIRRELVM v,TYPE & value) { if (!CreateCopyInstance(v,GetTypeName(value),value)) throw SquirrelError( _SC( "Push(): could not create INSTANCE copy (check registration name)")); } \ -} // nameSpace SqPlus - -// Allows for providing custom Push handlers (protos here, impl must be provided by app) -#define DECLARE_INSTANCE_TYPE_NAME_CUSTOM_(TYPE,NAME) namespace SqPlus { \ - DECLARE_INSTANCE_TYPE_BASE_(TYPE,NAME) \ - template<> void Push(HSQUIRRELVM v,TYPE * value); \ - template<> void Push(HSQUIRRELVM v,TYPE & value); \ -} // nameSpace SqPlus - - -#else - -#define DECLARE_INSTANCE_TYPE_NAME_(TYPE,NAME) namespace SqPlus { \ - DECLARE_INSTANCE_TYPEINFO_(TYPE,NAME) \ - template<> inline void Push(HSQUIRRELVM v,TYPE * value) { if (!CreateNativeClassInstance(v,GetTypeName(*value),value,0)) throw SquirrelError( _SC( "Push(): could not create INSTANCE (check registration name)")); } \ - template<> inline void Push(HSQUIRRELVM v,TYPE & value) { if (!CreateCopyInstance(v,GetTypeName(value),value)) throw SquirrelError( _SC( "Push(): could not create INSTANCE copy (check registration name)")); } \ - template<> inline bool Match(TypeWrapper,HSQUIRRELVM v,int idx) { return GetInstance(v,idx) != NULL; } \ - template<> inline bool Match(TypeWrapper,HSQUIRRELVM v,int idx) { return GetInstance(v,idx) != NULL; } \ - template<> inline TYPE & Get(TypeWrapper,HSQUIRRELVM v,int idx) { return *GetInstance(v,idx); } \ - template<> inline TYPE * Get(TypeWrapper,HSQUIRRELVM v,int idx) { return GetInstance(v,idx); } \ -} // nameSpace SqPlus - -#endif - -// TYPE or NAME below must match the string name used in SQClassDef<>, otherwise name lookup won't match and Squirrel will throw a "can't create instance" error. -#ifndef SQPLUS_CONST_OPT -#define DECLARE_INSTANCE_TYPE(TYPE) DECLARE_INSTANCE_TYPE_NAME_(TYPE,TYPE) -#define DECLARE_INSTANCE_TYPE_NAME(TYPE,NAME) DECLARE_INSTANCE_TYPE_NAME_(TYPE,NAME) -#define DECLARE_INSTANCE_TYPE_CUSTOM(TYPE) DECLARE_INSTANCE_TYPE_NAME_CUSTOM_(TYPE,TYPE) -#define DECLARE_INSTANCE_TYPE_NAME_CUSTOM(TYPE,NAME) DECLARE_INSTANCE_TYPE_NAME_CUSTOM_(TYPE,NAME) -#else -#define SQPLUS_DECLARE_INSTANCE_TYPE_CONST -#include "SqPlusConst.h" -#endif - -#ifdef SQPLUS_OVERLOAD_OPT -#define SQPLUS_OVERLOAD_DECLARATION -#include "SqPlusOverload.h" -#endif - -// Versions of above for types that aren't copy constructable -#define DECLARE_INSTANCE_TYPEINFO_NOCOPY(TYPE) \ - DECLARE_INSTANCE_TYPEINFO(TYPE) \ - DECLARE_NONCOPY_TYPE(TYPE) - -#define DECLARE_INSTANCE_TYPEINFO_NOCOPY_NAME(TYPE,NAME) namespace SqPlus { \ - DECLARE_INSTANCE_TYPEINFO_(TYPE,NAME) \ - DECLARE_NONCOPY_TYPE(TYPE) - -#define DECLARE_INSTANCE_TYPE_NOCOPY(TYPE) \ - DECLARE_INSTANCE_TYPE(TYPE) \ - DECLARE_NONCOPY_TYPE(TYPE) - -#define DECLARE_INSTANCE_TYPE_NOCOPY_NAME(TYPE,NAME) namespace SqPlus { \ - DECLARE_INSTANCE_TYPEINFO_(TYPE,NAME) \ - DECLARE_NONCOPY_TYPE(TYPE) - - -////////////////////////////////////////////////////////////////////////// -//////////// END Generalized Class/Struct Instance Support /////////////// -////////////////////////////////////////////////////////////////////////// - -#ifndef SQ_SKIP_ARG_ASSERT - #define sq_argassert(arg,_index_) if (!Match(TypeWrapper(),v,_index_)) return sq_throwerror(v,_SC("Incorrect function argument")) -#else - #define sq_argassert(arg,_index_) -#endif - -// === Return value variants === - -template -struct ReturnSpecialization { - - // === Standard Function calls === - - static int Call(RT (*func)(),HSQUIRRELVM v,int /*index*/) { - RT ret = func(); - Push(v,ret); - return 1; - } - - template - static int Call(RT (*func)(P1),HSQUIRRELVM v,int index) { - sq_argassert(1,index + 0); - RT ret = func( - Get(TypeWrapper(),v,index + 0) - ); - Push(v,ret); - return 1; - } - - template - static int Call(RT (*func)(P1,P2),HSQUIRRELVM v,int index) { - sq_argassert(1,index + 0); - sq_argassert(2,index + 1); - RT ret = func( - Get(TypeWrapper(),v,index + 0), - Get(TypeWrapper(),v,index + 1) - ); - Push(v,ret); - return 1; - } - - template - static int Call(RT (*func)(P1,P2,P3),HSQUIRRELVM v,int index) { - sq_argassert(1,index + 0); - sq_argassert(2,index + 1); - sq_argassert(3,index + 2); - RT ret = func( - Get(TypeWrapper(),v,index + 0), - Get(TypeWrapper(),v,index + 1), - Get(TypeWrapper(),v,index + 2) - ); - Push(v,ret); - return 1; - } - - template - static int Call(RT (*func)(P1,P2,P3,P4),HSQUIRRELVM v,int index) { - sq_argassert(1,index + 0); - sq_argassert(2,index + 1); - sq_argassert(3,index + 2); - sq_argassert(4,index + 3); - RT ret = func( - Get(TypeWrapper(),v,index + 0), - Get(TypeWrapper(),v,index + 1), - Get(TypeWrapper(),v,index + 2), - Get(TypeWrapper(),v,index + 3) - ); - Push(v,ret); - return 1; - } - - template - static int Call(RT (*func)(P1,P2,P3,P4,P5),HSQUIRRELVM v,int index) { - sq_argassert(1,index + 0); - sq_argassert(2,index + 1); - sq_argassert(3,index + 2); - sq_argassert(4,index + 3); - sq_argassert(5,index + 4); - RT ret = func( - Get(TypeWrapper(),v,index + 0), - Get(TypeWrapper(),v,index + 1), - Get(TypeWrapper(),v,index + 2), - Get(TypeWrapper(),v,index + 3), - Get(TypeWrapper(),v,index + 4) - ); - Push(v,ret); - return 1; - } - - template - static int Call(RT (*func)(P1,P2,P3,P4,P5,P6),HSQUIRRELVM v,int index) { - sq_argassert(1,index + 0); - sq_argassert(2,index + 1); - sq_argassert(3,index + 2); - sq_argassert(4,index + 3); - sq_argassert(5,index + 4); - sq_argassert(6,index + 5); - RT ret = func( - Get(TypeWrapper(),v,index + 0), - Get(TypeWrapper(),v,index + 1), - Get(TypeWrapper(),v,index + 2), - Get(TypeWrapper(),v,index + 3), - Get(TypeWrapper(),v,index + 4), - Get(TypeWrapper(),v,index + 5) - ); - Push(v,ret); - return 1; - } - - template - static int Call(RT (*func)(P1,P2,P3,P4,P5,P6,P7),HSQUIRRELVM v,int index) { - sq_argassert(1,index + 0); - sq_argassert(2,index + 1); - sq_argassert(3,index + 2); - sq_argassert(4,index + 3); - sq_argassert(5,index + 4); - sq_argassert(6,index + 5); - sq_argassert(7,index + 6); - RT ret = func( - Get(TypeWrapper(),v,index + 0), - Get(TypeWrapper(),v,index + 1), - Get(TypeWrapper(),v,index + 2), - Get(TypeWrapper(),v,index + 3), - Get(TypeWrapper(),v,index + 4), - Get(TypeWrapper(),v,index + 5), - Get(TypeWrapper(),v,index + 6) - ); - Push(v,ret); - return 1; - } - - // === Member Function calls === - - -#define SQPLUS_CALL_MFUNC_RET0 -#include "SqPlusCallTemplates.h" - -#ifdef SQPLUS_CONST_OPT -#define SQPLUS_CALL_MFUNC_RET0 -#include "SqPlusConst.h" -#endif -}; - -// === No return value variants === - -template<> -struct ReturnSpecialization { - - // === Standard function calls === - - static int Call(void (*func)(),HSQUIRRELVM v,int /*index*/) { - (void)v; - func(); - return 0; - } - - template - static int Call(void (*func)(P1),HSQUIRRELVM v,int index) { - sq_argassert(1,index + 0); - func( - Get(TypeWrapper(),v,index + 0) - ); - return 0; - } - - template - static int Call(void (*func)(P1,P2),HSQUIRRELVM v,int index) { - sq_argassert(1,index + 0); - sq_argassert(2,index + 1); - func( - Get(TypeWrapper(),v,index + 0), - Get(TypeWrapper(),v,index + 1) - ); - return 0; - } - - template - static int Call(void (*func)(P1,P2,P3),HSQUIRRELVM v,int index) { - sq_argassert(1,index + 0); - sq_argassert(2,index + 1); - sq_argassert(3,index + 2); - func( - Get(TypeWrapper(),v,index + 0), - Get(TypeWrapper(),v,index + 1), - Get(TypeWrapper(),v,index + 2) - ); - return 0; - } - - template - static int Call(void (*func)(P1,P2,P3,P4),HSQUIRRELVM v,int index) { - sq_argassert(1,index + 0); - sq_argassert(2,index + 1); - sq_argassert(3,index + 2); - sq_argassert(4,index + 3); - func( - Get(TypeWrapper(),v,index + 0), - Get(TypeWrapper(),v,index + 1), - Get(TypeWrapper(),v,index + 2), - Get(TypeWrapper(),v,index + 3) - ); - return 0; - } - - template - static int Call(void (*func)(P1,P2,P3,P4,P5),HSQUIRRELVM v,int index) { - sq_argassert(1,index + 0); - sq_argassert(2,index + 1); - sq_argassert(3,index + 2); - sq_argassert(4,index + 3); - sq_argassert(5,index + 4); - func( - Get(TypeWrapper(),v,index + 0), - Get(TypeWrapper(),v,index + 1), - Get(TypeWrapper(),v,index + 2), - Get(TypeWrapper(),v,index + 3), - Get(TypeWrapper(),v,index + 4) - ); - return 0; - } - - template - static int Call(void (*func)(P1,P2,P3,P4,P5,P6),HSQUIRRELVM v,int index) { - sq_argassert(1,index + 0); - sq_argassert(2,index + 1); - sq_argassert(3,index + 2); - sq_argassert(4,index + 3); - sq_argassert(5,index + 4); - sq_argassert(6,index + 5); - func( - Get(TypeWrapper(),v,index + 0), - Get(TypeWrapper(),v,index + 1), - Get(TypeWrapper(),v,index + 2), - Get(TypeWrapper(),v,index + 3), - Get(TypeWrapper(),v,index + 4), - Get(TypeWrapper(),v,index + 5) - ); - return 0; - } - - template - static int Call(void (*func)(P1,P2,P3,P4,P5,P6,P7),HSQUIRRELVM v,int index) { - sq_argassert(1,index + 0); - sq_argassert(2,index + 1); - sq_argassert(3,index + 2); - sq_argassert(4,index + 3); - sq_argassert(5,index + 4); - sq_argassert(6,index + 5); - sq_argassert(7,index + 6); - func( - Get(TypeWrapper(),v,index + 0), - Get(TypeWrapper(),v,index + 1), - Get(TypeWrapper(),v,index + 2), - Get(TypeWrapper(),v,index + 3), - Get(TypeWrapper(),v,index + 4), - Get(TypeWrapper(),v,index + 5), - Get(TypeWrapper(),v,index + 6) - ); - return 0; - } - - // === Member function calls === - - -#define SQPLUS_CALL_MFUNC_NORET -#include "SqPlusCallTemplates.h" - -#ifdef SQPLUS_CONST_OPT -#define SQPLUS_CALL_MFUNC_NORET -#include "SqPlusConst.h" -#endif - -}; - -// === STANDARD Function return value specialized call handlers === - -template -int Call(RT (*func)(),HSQUIRRELVM v,int index) { - return ReturnSpecialization::Call(func,v,index); -} - -template -int Call(RT (*func)(P1),HSQUIRRELVM v,int index) { - return ReturnSpecialization::Call(func,v,index); -} - -template -int Call(RT (*func)(P1,P2),HSQUIRRELVM v,int index) { - return ReturnSpecialization::Call(func,v,index); -} - -template -int Call(RT (*func)(P1,P2,P3),HSQUIRRELVM v,int index) { - return ReturnSpecialization::Call(func,v,index); -} - -template -int Call(RT (*func)(P1,P2,P3,P4),HSQUIRRELVM v,int index) { - return ReturnSpecialization::Call(func,v,index); -} - -template -int Call(RT (*func)(P1,P2,P3,P4,P5),HSQUIRRELVM v,int index) { - return ReturnSpecialization::Call(func,v,index); -} - -template -int Call(RT (*func)(P1,P2,P3,P4,P5,P6),HSQUIRRELVM v,int index) { - return ReturnSpecialization::Call(func,v,index); -} - -template -int Call(RT (*func)(P1,P2,P3,P4,P5,P6,P7),HSQUIRRELVM v,int index) { - return ReturnSpecialization::Call(func,v,index); -} - -// === MEMBER Function return value specialized call handlers === - - -#define SQPLUS_CALL_MFUNC_RET1 -#include "SqPlusCallTemplates.h" - -#ifdef SQPLUS_CONST_OPT -#define SQPLUS_CALL_MFUNC_RET1 -#include "SqPlusConst.h" -#endif - -// === Direct Call Standard Function handler === - -template -struct DirectCallFunction { - static inline int Dispatch(HSQUIRRELVM v) { -#ifdef SQPLUS_USE_SANDBOX_VM - if( v==SquirrelVM::GetSandboxVMPtr() ){ - return sq_throwerror(v, _SC("SqPlus: Cannot exec function from sandbox VM")); - } -#endif - StackHandler sa(v); - int paramCount = sa.GetParamCount(); - Func * func = (Func *)sa.GetUserData(paramCount); - return Call(*func,v,2); - } // Dispatch -}; - -// === Direct Call Member Function handler === - -template -class DirectCallMemberFunction { -public: - static inline int Dispatch(HSQUIRRELVM v) { -#ifdef SQPLUS_USE_SANDBOX_VM - if( v==SquirrelVM::GetSandboxVMPtr() ){ - return sq_throwerror(v, _SC("SqPlus: Cannot exec function from sandbox VM")); - } -#endif - StackHandler sa(v); - int paramCount = sa.GetParamCount(); - unsigned char * ud = (unsigned char *)sa.GetUserData(paramCount); - return Call(**(Callee**)ud,*(Func*)(ud + sizeof(Callee*)),v,2); - } // Dispatch -}; - -// === Direct Call Function handlers === - -#define SQ_CLASS_OBJECT_TABLE_NAME _SC("__ot") -#define SQ_CLASS_HIER_ARRAY _SC("__ca") - -template -struct DirectCallInstanceFuncPicker { - Callee *instance; - Func *func; - DirectCallInstanceFuncPicker(HSQUIRRELVM v) { -#ifdef SQPLUS_USE_SANDBOX_VM - if( v==SquirrelVM::GetSandboxVMPtr() ){ - instance = NULL; - func = NULL; - return; - } -#endif - StackHandler sa(v); - instance = static_cast(sa.GetInstanceUp(1, 0)); - const int paramCount = sa.GetParamCount(); - func = static_cast(sa.GetUserData(paramCount)); -#ifdef SQ_USE_CLASS_INHERITANCE - SquirrelObject so(sa.GetObjectHandle(1)); // 'this' - SQUserPointer typetag; so.GetTypeTag(&typetag); - SQUserPointer calleeType = ClassType::type(); - if (typetag != calleeType) { - SquirrelObject typeTable = so.GetValue(SQ_CLASS_OBJECT_TABLE_NAME); - instance = static_cast( - // 64-bit compatible version. - typeTable.GetUserPointer(INT((size_t)ClassType::type())) - ); - } -#elif defined(SQ_USE_CLASS_INHERITANCE_SIMPLE) - SquirrelObject so(sa.GetObjectHandle(1)); // 'this' - ClassTypeBase *instType; so.GetTypeTag((SQUserPointer*)&instType); - ClassTypeBase *calleeType = ClassType::type(); - if (instType!=calleeType && instType->MayHaveOffset() ) { - // instance type is nore derived than callee, adjust pointer - int offset = instType->GetOffsetTo(calleeType); - instance = (Callee*)((char*)instance-offset); - } -#endif - } -}; - -// === Direct Call Instance Member Function handler === -template -class DirectCallInstanceMemberFunction { -public: - static inline int Dispatch(HSQUIRRELVM v) { - DirectCallInstanceFuncPicker p(v); - return p.instance && p.func ? - Call(*(p.instance), *(p.func), v, 2) : - sq_throwerror(v, _SC("Invalid Instance Type")); - } -}; - -// === Direct Call Instance Global Function handler === -template -class DirectCallInstanceGlobalFunction { -public: - static inline int Dispatch(HSQUIRRELVM v) { - DirectCallInstanceFuncPicker p(v); - return p.func ? - Call(*(p.func), v, 1) : - sq_throwerror(v, _SC("Invalid Instance Type")); - } -}; - -// === Direct Call Instance Global Function Var Args handler === -template -class DirectCallInstanceGlobalFunctionVarArgs { -public: - static inline int Dispatch(HSQUIRRELVM v) { - DirectCallInstanceFuncPicker p(v); - return p.func && p.instance ? - (*p.func)(p.instance,v) : - sq_throwerror(v, _SC("Invalid Instance Type")); - } -}; - -// === Direct Call Instance Member Function Variable Argument handler === -template -class DirectCallInstanceMemberFunctionVarArgs { -public: - static inline int Dispatch(HSQUIRRELVM v) { - DirectCallInstanceFuncPicker p(v); - sq_poptop(v); // Remove UserData from stack: so sa.GetParamCount() returns actual param count. - return p.func && p.instance ? - (p.instance->*(*p.func))(v) : - sq_throwerror(v, _SC("Invalid Instance Type")); - } -}; - -#ifdef SQPLUS_SMARTPOINTER_OPT -#define SQPLUS_SMARTPOINTER_DISPATCH -#include "SqPlusSmartPointer.h" -#endif - - -// Code fragment useful for debugging new implementations. -#if 0 -HSQOBJECT ho = sa.GetObjectHandle(paramCount); -SquirrelObject so(ho); -SQObjectType sot = so.GetType(); -#endif - -#ifdef SQPLUS_ENABLE_AUTO_TYPEMASK - #include "SqPlusTypeMask.h" -#endif - -// === Standard function call === - -template -inline void sq_pushdirectclosure(HSQUIRRELVM v,Func func,SQUnsignedInteger nupvalues) { - SQUserPointer up = sq_newuserdata(v,sizeof(func)); // Also pushed on stack. - memcpy(up,&func,sizeof(func)); - sq_newclosure(v,DirectCallFunction::Dispatch,nupvalues+1); -#ifdef SQPLUS_ENABLE_AUTO_TYPEMASK - sq_setparamscheck(v,0,sqTypeMask::Get()); -#endif -} // sq_pushdirectclosure - -// === Fixed Class pointer call (always calls with object pointer that was registered) === - -template -inline void sq_pushdirectclosure(HSQUIRRELVM v,const Callee & callee,Func func,SQUnsignedInteger nupvalues) { - unsigned char * up = (unsigned char *)sq_newuserdata(v,sizeof(Callee*)+sizeof(func)); // Also pushed on stack. - const SQUserPointer pCallee = (SQUserPointer)&callee; - memcpy(up,&pCallee,sizeof(Callee*)); - memcpy(up + sizeof(Callee*),&func,sizeof(func)); - sq_newclosure(v,DirectCallMemberFunction::Dispatch,nupvalues+1); -#ifdef SQPLUS_ENABLE_AUTO_TYPEMASK - sq_setparamscheck(v,0,sqTypeMask::Get()); -#endif -} // sq_pushdirectclosure - -#ifdef SQPLUS_SMARTPOINTER_OPT -#define SQPLUS_SMARTPOINTER_DIRECT_CLOSURE -#include "SqPlusSmartPointer.h" -#endif - -// === Class Instance call: class pointer retrieved from script class instance === - -template -inline void sq_pushdirectinstanceclosure(HSQUIRRELVM v,const Callee & callee,Func func,SQUnsignedInteger nupvalues) { - unsigned char * up = (unsigned char *)sq_newuserdata(v,sizeof(func)); // Also pushed on stack. - memcpy(up,&func,sizeof(func)); - sq_newclosure(v,DirectCallInstanceMemberFunction::Dispatch,nupvalues+1); -#ifdef SQPLUS_ENABLE_AUTO_TYPEMASK - sq_setparamscheck(v,0,sqTypeMask::Get()); -#endif -} // sq_pushdirectinstanceclosure - -// === Global function using this: class pointer retrieved from script class instance === - -template -inline void sq_pushdirectinstanceclosureglobal(HSQUIRRELVM v,const Callee & callee,Func func,SQUnsignedInteger nupvalues) { - unsigned char * up = (unsigned char *)sq_newuserdata(v,sizeof(func)); // Also pushed on stack. - memcpy(up,&func,sizeof(func)); - // Could check that 1st arg of Func is a Callee - sq_newclosure(v,DirectCallInstanceGlobalFunction::Dispatch,nupvalues+1); -#ifdef SQPLUS_ENABLE_AUTO_TYPEMASK - SQChar *tm = (SQChar*)sqTypeMask::Get(); - if( tm ) { - // Censor out the 1st arg, since SqPlus adds that automatically - tm[1] = _SC('x'); //tm[0]; - tm++; - } - sq_setparamscheck(v,0,tm?tm:_SC("")); -#endif -} // sq_pushdirectinstanceclosureglobal - -// === Global function using this: class pointer retrieved from script class instance === - -template -inline void sq_pushdirectinstanceclosureglobalvarargs(HSQUIRRELVM v,const Callee & callee,Func func,SQUnsignedInteger nupvalues) { - unsigned char * up = (unsigned char *)sq_newuserdata(v,sizeof(func)); // Also pushed on stack. - memcpy(up,&func,sizeof(func)); - // Could check that 1st arg of Func is a Callee - sq_newclosure(v,DirectCallInstanceGlobalFunctionVarArgs::Dispatch,nupvalues+1); -#ifdef SQPLUS_ENABLE_AUTO_TYPEMASK - sq_setparamscheck(v,-1,_SC("x")); -#endif -} // sq_pushdirectinstanceclosureglobal - -// === Class Instance call: class pointer retrieved from script class instance (variable arguments) === - -template -inline void sq_pushdirectinstanceclosurevarargs(HSQUIRRELVM v,const Callee & callee,int (Callee::*func)(HSQUIRRELVM),SQUnsignedInteger nupvalues) { - unsigned char * up = (unsigned char *)sq_newuserdata(v,sizeof(func)); // Also pushed on stack. - memcpy(up,&func,sizeof(func)); - typedef int (Callee::*FuncType)(HSQUIRRELVM); - sq_newclosure(v,DirectCallInstanceMemberFunctionVarArgs::Dispatch,nupvalues+1); -} // sq_pushdirectinstanceclosurevarargs - -// === Register a STANDARD function (table or class on stack) === - -template -inline void Register(HSQUIRRELVM v,Func func,const SQChar * name) { - sq_pushstring(v,name,-1); - sq_pushdirectclosure(v,func,0); - sq_createslot(v,-3); // Stack is restored after this call (same state as before Register() call). -} // Register - -// === Register a MEMBER function (table or class on stack) === - -template -inline void Register(HSQUIRRELVM v,Callee & callee,Func func,const SQChar * name) { - sq_pushstring(v,name,-1); - sq_pushdirectclosure(v,callee,func,0); - sq_createslot(v,-3); // Stack is restored after this call (same state as before Register() call). -} // Register - -// === Register a STANDARD global function (root table) === - -template -inline void RegisterGlobal(HSQUIRRELVM v,Func func,const SQChar * name) { - sq_pushroottable(v); - Register(v,func,name); - sq_poptop(v); // Remove root table. -} // RegisterGlobal - -template -inline void RegisterGlobal(Func func,const SQChar * name) { - RegisterGlobal(SquirrelVM::GetVMPtr(),func,name); -} // RegisterGlobal - -// === Register a MEMBER global function (root table) === - -template -inline void RegisterGlobal(HSQUIRRELVM v,Callee & callee,Func func,const SQChar * name) { - sq_pushroottable(v); - Register(v,callee,func,name); - sq_poptop(v); // Remove root table. -} // RegisterGlobal - -template -inline void RegisterGlobal(Callee & callee,Func func,const SQChar * name) { - RegisterGlobal(SquirrelVM::GetVMPtr(),callee,func,name); -} // RegisterGlobal - -// === Register a STANDARD function (hso is table or class) === - -template -inline void Register(HSQUIRRELVM v,HSQOBJECT hso,Func func,const SQChar * name) { - sq_pushobject(v,hso); - Register(v,func,name); - sq_poptop(v); // Remove hso. -} // Register - -// === Register a MEMBER function (hso is table or class) === -// === Fixed Class pointer call (always calls with object pointer that was registered) === - -template -inline void Register(HSQUIRRELVM v,HSQOBJECT hso,Callee & callee,Func func,const SQChar * name) { - sq_pushobject(v,hso); - Register(v,callee,func,name); - sq_poptop(v); // Remove hso. -} // Register - -// === Register an INSTANCE MEMBER function === -// === Class Instance call: class pointer retrieved from script class instance === - -template -inline void RegisterInstance(HSQUIRRELVM v,HSQOBJECT hclass,Callee & callee,Func func,const SQChar * name) { - sq_pushobject(v,hclass); - sq_pushstring(v,name,-1); - sq_pushdirectinstanceclosure(v,callee,func,0); - sq_createslot(v,-3); - sq_poptop(v); // Remove hclass. -} // RegisterInstance - - -// === Register an INSTANCE GLOBAL MEMBER function === -// === Class Instance call: class pointer retrieved from script class instance === -// Allows embedding global func that takes Callee as 1st arg as a member func -template -inline void RegisterInstanceGlobalFunc(HSQUIRRELVM v,HSQOBJECT hclass,Callee & callee,Func func,const SQChar * name) { - sq_pushobject(v,hclass); - sq_pushstring(v,name,-1); - sq_pushdirectinstanceclosureglobal(v,callee,func,0); - sq_createslot(v,-3); - sq_poptop(v); // Remove hclass. -} // RegisterInstanceGlobaFunc - -// === Register an INSTANCE GLOBAL MEMBER WITH VAR ARGS function === -// === Class Instance call: class pointer retrieved from script class instance === -// Allows embedding global func that takes Callee as 1st arg as a member func -template -inline void RegisterInstanceGlobalFuncVarArgs(HSQUIRRELVM v,HSQOBJECT hclass,Callee & callee,Func func,const SQChar * name) { - sq_pushobject(v,hclass); - sq_pushstring(v,name,-1); - sq_pushdirectinstanceclosureglobalvarargs(v,callee,func,0); - sq_createslot(v,-3); - sq_poptop(v); // Remove hclass. -} // RegisterInstanceGlobaFunc - -#ifdef SQPLUS_SMARTPOINTER_OPT -#define SQPLUS_SMARTPOINTER_REGISTER_INSTANCE -#include "SqPlusSmartPointer.h" -#endif - -#ifdef _MSC_VER -#pragma warning(disable : 4995) // Deprecated _snprintf -#endif - -// === Register an INSTANCE MEMBER function Variable Arguments === -// typeMask: "*" means don't check parameters, typeMask=0 means function takes no arguments (and is type checked for that case). -// All the other Squirrel type-masks are passed normally. - -template -inline void RegisterInstanceVarArgs(HSQUIRRELVM v,HSQOBJECT hclass,Callee & callee,int (Callee::*func)(HSQUIRRELVM),const SQChar * name,const SQChar * typeMask=_SC("*")) { - sq_pushobject(v,hclass); - sq_pushstring(v,name,-1); - sq_pushdirectinstanceclosurevarargs(v,callee,func,0); - SQChar tm[64]; - SQChar * ptm = tm; - int numParams = SQ_MATCHTYPEMASKSTRING; - if (typeMask) { - if (typeMask[0] == '*') { - ptm = 0; // Variable args: don't check parameters. -// numParams = 0; // Clear SQ_MATCHTYPEMASKSTRING (does not mean match 0 params. See sq_setparamscheck()). - } else { - if (SCSNPRINTF(tm,sizeof(tm),_SC("x%s"),typeMask) < 0) { // Must be an instance. - throw SquirrelError(_SC("RegisterInstanceVarArgs: typeMask string too long.")); - } // if - } // if - } else { // Need to check object type on stack: table, class, instance, etc. -// _snprintf(tm,sizeof(tm),"x"); // instance. - tm[0] = 'x'; - tm[1] = 0; - } // if - if (ptm) { // If ptm == 0, don't check type. - sq_setparamscheck(v,numParams,ptm); // Determine arg count from type string. - } // if -#ifdef _DEBUG - sq_setnativeclosurename(v,-1,name); // For debugging only. -#endif - sq_createslot(v,-3); - sq_poptop(v); // Remove hclass. -} // RegisterInstanceVarArgs - -#ifdef _MSC_VER -#pragma warning(default : 4995) -#endif - -// === Call Squirrel Functions from C/C++ === -// No type checking is performed for Squirrel functions as Squirrel types are dynamic: -// Incoming types are passed unchanged to Squirrel functions. The parameter count is checked: an exception is thrown if mismatched. -// Return values must match the RT template argument type, else an exception can be thrown on return. - -template -struct SquirrelFunction { - HSQUIRRELVM v; - SquirrelObject object; // Table or class. - SquirrelObject func; - SquirrelFunction() : v(0) {} - SquirrelFunction(HSQUIRRELVM _v,const SquirrelObject & _object,const SquirrelObject & _func) : v(_v), object(_object), func(_func) {} - SquirrelFunction(const SquirrelObject & _object,const SquirrelObject & _func) : v(SquirrelVM::GetVMPtr()), object(_object), func(_func) {} - SquirrelFunction(const SquirrelObject & _object,const SQChar * name) { - v = SquirrelVM::GetVMPtr(); - object = _object; - func = object.GetValue(name); - } - SquirrelFunction(const SQChar * name) { - v = SquirrelVM::GetVMPtr(); - object = SquirrelVM::GetRootTable(); - func = object.GetValue(name); - } - - // Release references and reset internal objects to null. - void reset(void) { - func.Reset(); - object.Reset(); - } // Reset - -#define SQPLUS_CHECK_FNCALL(res) if (!SQ_SUCCEEDED(res)) throw SquirrelError(_SC("SquirrelFunction<> call failed")) - - RT operator()(void) { - sq_pushobject(v,func.GetObjectHandle()); - sq_pushobject(v,object.GetObjectHandle()); - SQPLUS_CHECK_FNCALL(sq_call(v,1,SQTrue,SQ_CALL_RAISE_ERROR)); - return GetRet(TypeWrapper(),v,-1); - } - - template - RT operator()(P1 p1) { - sq_pushobject(v,func.GetObjectHandle()); - sq_pushobject(v,object.GetObjectHandle()); - Push(v,p1); - SQPLUS_CHECK_FNCALL(sq_call(v,2,SQTrue,SQ_CALL_RAISE_ERROR)); - return GetRet(TypeWrapper(),v,-1); - } - - template - RT operator()(P1 p1,P2 p2) { - sq_pushobject(v,func.GetObjectHandle()); - sq_pushobject(v,object.GetObjectHandle()); - Push(v,p1); - Push(v,p2); - SQPLUS_CHECK_FNCALL(sq_call(v,3,SQTrue,SQ_CALL_RAISE_ERROR)); - return GetRet(TypeWrapper(),v,-1); - } - - template - RT operator()(P1 p1,P2 p2,P3 p3) { - sq_pushobject(v,func.GetObjectHandle()); - sq_pushobject(v,object.GetObjectHandle()); - Push(v,p1); - Push(v,p2); - Push(v,p3); - SQPLUS_CHECK_FNCALL(sq_call(v,4,SQTrue,SQ_CALL_RAISE_ERROR)); - return GetRet(TypeWrapper(),v,-1); - } - - template - RT operator()(P1 p1,P2 p2,P3 p3,P4 p4) { - sq_pushobject(v,func.GetObjectHandle()); - sq_pushobject(v,object.GetObjectHandle()); - Push(v,p1); - Push(v,p2); - Push(v,p3); - Push(v,p4); - SQPLUS_CHECK_FNCALL(sq_call(v,5,SQTrue,SQ_CALL_RAISE_ERROR)); - return GetRet(TypeWrapper(),v,-1); - } - - template - RT operator()(P1 p1,P2 p2,P3 p3,P4 p4,P5 p5) { - sq_pushobject(v,func.GetObjectHandle()); - sq_pushobject(v,object.GetObjectHandle()); - Push(v,p1); - Push(v,p2); - Push(v,p3); - Push(v,p4); - Push(v,p5); - SQPLUS_CHECK_FNCALL(sq_call(v,6,SQTrue,SQ_CALL_RAISE_ERROR)); - return GetRet(TypeWrapper(),v,-1); - } - - template - RT operator()(P1 p1,P2 p2,P3 p3,P4 p4,P5 p5,P6 p6) { - sq_pushobject(v,func.GetObjectHandle()); - sq_pushobject(v,object.GetObjectHandle()); - Push(v,p1); - Push(v,p2); - Push(v,p3); - Push(v,p4); - Push(v,p5); - Push(v,p6); - SQPLUS_CHECK_FNCALL(sq_call(v,7,SQTrue,SQ_CALL_RAISE_ERROR)); - return GetRet(TypeWrapper(),v,-1); - } - - template - RT operator()(P1 p1,P2 p2,P3 p3,P4 p4,P5 p5,P6 p6,P7 p7) { - sq_pushobject(v,func.GetObjectHandle()); - sq_pushobject(v,object.GetObjectHandle()); - Push(v,p1); - Push(v,p2); - Push(v,p3); - Push(v,p4); - Push(v,p5); - Push(v,p6); - Push(v,p7); - SQPLUS_CHECK_FNCALL(sq_call(v,8,SQTrue,SQ_CALL_RAISE_ERROR)); - return GetRet(TypeWrapper(),v,-1); - } - -}; - -// === Class/Struct registration === - -#define SQ_DELETE_CLASS(CLASSTYPE) if (up) { CLASSTYPE * self = (CLASSTYPE *)up; delete self;} return 0 -#define SQ_DECLARE_RELEASE(CLASSTYPE) \ - static int release(SQUserPointer up,SQInteger size) { \ - SQ_DELETE_CLASS(CLASSTYPE); \ - } - -template -struct ReleaseClassPtrPtr { - static int release(SQUserPointer up,SQInteger size) { - if (up) { - T ** self = (T **)up; - delete *self; - } // if - return 0; - } // release -}; - -template -struct ReleaseClassPtr { - static int release(SQUserPointer up,SQInteger size) { - if (up) { - T * self = (T *)up; - delete self; - } // if - return 0; - } // release -}; - -BOOL CreateClass(HSQUIRRELVM v,SquirrelObject & newClass,SQUserPointer classType,const SQChar * name,const SQChar * baseName=0); - - -template -inline void PopulateAncestry(HSQUIRRELVM v, - SquirrelObject &instance, - T *newClass) -{ - // 11/2/05: Create a new table for this instance. - SquirrelObject newObjectTable = SquirrelVM::CreateTable(); - // 64-bit compatible version. - newObjectTable.SetUserPointer(INT((size_t)ClassType::type()), newClass); - instance.SetValue(SQ_CLASS_OBJECT_TABLE_NAME, newObjectTable); - - SquirrelObject classHierArray = instance.GetValue(SQ_CLASS_HIER_ARRAY); - INT count = classHierArray.Len(); - - // This will be true when more than one C/C++ class is in the hierarchy. - if (count > 1) { - --count; // Skip the most-derived class. - for (INT i = 0; i < count; i++) { - // Kamaitati's changes for C++ inheritance support. jcs 5/28/06 - SquirrelObject so = classHierArray.GetValue(i); - sq_pushobject(v,so.GetObjectHandle()); - SQUserPointer typeTag; - sq_gettypetag(v,-1,&typeTag); - newObjectTable.SetUserPointer(INT(size_t(typeTag)),newClass); - sq_poptop(v); - } - } -} - - -// Call PostConstruct() at the end of custom constructors. -template -inline int PostConstruct(HSQUIRRELVM v, T *newClass, SQRELEASEHOOK hook) -{ -#ifdef SQ_USE_CLASS_INHERITANCE - StackHandler sa(v); - HSQOBJECT ho = sa.GetObjectHandle(1); // OT_INSTANCE - SquirrelObject instance(ho); - PopulateAncestry(v, instance, newClass); -#endif // SQ_USE_CLASS_INHERITANCE - - sq_setinstanceup(v, 1, newClass); - sq_setreleasehook(v, 1, hook); - return TRUE; -} // PostConstruct - -inline int PostConstructSimple(HSQUIRRELVM v, void *newClass, SQRELEASEHOOK hook){ - sq_setinstanceup(v, 1, newClass); - sq_setreleasehook(v, 1, hook); - return TRUE; -} // PostConstructSimple - - -template -struct ConstructReleaseClass { - static int construct(HSQUIRRELVM v) { - return PostConstruct(v,new T(),release); - } // construct - SQ_DECLARE_RELEASE(T) -}; - -# ifdef SQPLUS_ENABLE_TYPEOF -template -int sq_typeof(HSQUIRRELVM v) { - sq_pushstring(v,TypeInfo().typeName,-1); - return 1; -} -# endif - -// === Helper for RegisterClassType*() === -inline void setupClassHierarchy(SquirrelObject newClass) { - // New member vars cannot be added to instances (OT_INSTANCE): additions must occur on the defining class (OT_CLASS), before any instances are instantiated. - if (!newClass.Exists(SQ_CLASS_OBJECT_TABLE_NAME)) { // Will always get table from most-derived registered class. - SquirrelObject objectTable = SquirrelVM::CreateTable(); - newClass.SetValue(SQ_CLASS_OBJECT_TABLE_NAME,objectTable); // Constructors must add their 'this' pointer indexed by type to this table. See PostConstruct() above. - // 11/2/05: This table will behave as a static global for each instance unless overwritten during construction (see PostConstruct() above). - } // if - SquirrelObject classHierArray; - if (!newClass.Exists(SQ_CLASS_HIER_ARRAY)) { // Will always get table from most-derived registered class. - classHierArray = SquirrelVM::CreateArray(0); // The only constructor called will be the most-derived class: this array contains all classes in the hierarchy to be constructed. - newClass.SetValue(SQ_CLASS_HIER_ARRAY,classHierArray); - } else { - classHierArray = newClass.GetValue(SQ_CLASS_HIER_ARRAY); - } // if - classHierArray.ArrayAppend(newClass); // Add the class to the hierarchy array. The array values will be released and replaced with UserData to free created ancestor classes. -} // setupClassHierarchy - - -template -inline SquirrelObject RegisterClassType(HSQUIRRELVM v,const SQChar * scriptClassName,const SQChar * baseScriptClassName=0) { - int top = sq_gettop(v); - SquirrelObject newClass; - if (CreateClass(v,newClass,(SQUserPointer)ClassType::type(),scriptClassName,baseScriptClassName)) { - SquirrelVM::CreateFunction(newClass,&ConstructReleaseClass::construct,_SC("constructor")); -# ifdef SQ_USE_CLASS_INHERITANCE - setupClassHierarchy(newClass); -# endif -# ifdef SQPLUS_ENABLE_TYPEOF - SquirrelVM::CreateFunction(newClass,&sq_typeof,_SC("_typeof")); -# endif - } // if - sq_settop(v,top); - return newClass; -} // RegisterClassType - -template -inline SquirrelObject RegisterClassTypeNoConstructor(HSQUIRRELVM v,const SQChar * scriptClassName,const SQChar * baseScriptClassName=0) { - int top = sq_gettop(v); - SquirrelObject newClass; - if (CreateClass(v,newClass,(SQUserPointer)ClassType::type(),scriptClassName,baseScriptClassName)) { -# ifdef SQ_USE_CLASS_INHERITANCE - setupClassHierarchy(newClass); -# endif -# ifdef SQPLUS_ENABLE_TYPEOF - SquirrelVM::CreateFunction(newClass,&sq_typeof,_SC("_typeof")); -# endif - } // if - sq_settop(v,top); - return newClass; -} // RegisterClassTypeNoConstructor - - -// === Define and register a C++ class and its members for use with Squirrel === -// Constructors+destructors are automatically created. Custom constructors must use the -// standard SQFUNCTION signature if variable argument types are required (overloads). -// See testSqPlus2.cpp for examples. - -// Do not use SQClassDefBase<> directly, use SQClassDef<> or SQClassDefNoConstructor<>, below. -template -struct SQClassDefBase { - HSQUIRRELVM v; - const SQChar * name; - SquirrelObject newClass; - -#if defined(SQ_USE_CLASS_INHERITANCE) || defined(SQ_USE_CLASS_INHERITANCE_SIMPLE) - const SQChar * base; - // Optional base arg is the name of a base class to inherit from (must already be defined in the Squirrel VM). - SQClassDefBase(HSQUIRRELVM _v,const SQChar * _name=0,const SQChar * _base=0) : v(_v), name(_name), base(_base) {InitBase();} - // Optional base arg is the name of a base class to inherit from (must already be defined in the Squirrel VM). - SQClassDefBase(const SQChar * _name=0,const SQChar * _base=0) : v(SquirrelVM::GetVMPtr()), name(_name), base(_base) {InitBase(TypeWrapper());} - template - void InitBase(TypeWrapper){ /*assert(base);*/ ClassType::Get()->SetBase(TypeWrapper()); CheckInitDefaultNames(); } - void InitBase(TypeWrapper){ /*assert(!base);*/ CheckInitDefaultNames(); } - void CheckInitDefaultNames(){ if( !name ) name=TypeInfo().typeName; if( !base ) base=TypeInfo().typeName; } -#else - SQClassDefBase(HSQUIRRELVM _v,const SQChar * _name=0) : v(_v), name(_name) { CheckInitDefaultName(); } - SQClassDefBase(const SQChar * _name=0) : v(SquirrelVM::GetVMPtr()), name(_name) { CheckInitDefaultName(); } - void CheckInitDefaultName(){ if( !name ) name=TypeInfo().typeName; } -#endif - - // Register a member function. - template - SQClassDefBase & func(Func pfunc,const SQChar * name) { - RegisterInstance(v,newClass.GetObjectHandle(),*(TClassType *)0,pfunc,name); - return *this; - } // func - - // Register a global function as a member function (the global takes a Callee*/& as first arg). - template - SQClassDefBase & globMembFunc(Func pfunc,const SQChar * name) { - RegisterInstanceGlobalFunc(v,newClass.GetObjectHandle(),*(TClassType *)0,pfunc,name); - return *this; - } // globMemberFunc - - // Register a global function as a member function (the global takes a Callee*/& as first arg and SQVM* as 2nd). - template - SQClassDefBase & globMembFuncVarArgs(Func pfunc,const SQChar * name) { - RegisterInstanceGlobalFuncVarArgs(v,newClass.GetObjectHandle(),*(TClassType *)0,pfunc,name); - return *this; - } // globMemberFuncVarArgs - -#ifdef SQPLUS_SMARTPOINTER_OPT -#define SQPLUS_SMARTPOINTER_CLASS_DEF_FUNC -#include "SqPlusSmartPointer.h" -#endif - - // Register a variable-argument member function (supports variable+multiple return values). - // typeMask: "*" means don't check parameters, typeMask=0 means function takes no arguments (and is type checked for that case). - // All the other Squirrel type-masks are passed normally. - template - SQClassDefBase & funcVarArgs(Func pfunc,const SQChar * name,const SQChar * typeMask=_SC("*")) { - RegisterInstanceVarArgs(v,newClass.GetObjectHandle(),*(TClassType *)0,pfunc,name,typeMask); - return *this; - } // funcVarArgs - - // === BEGIN static-member+global function registration === - - // === This version is for static member functions only, such as custom constructors where 'this' is not yet valid === - // typeMask: "*" means don't check parameters, typeMask=0 means function takes no arguments (and is type checked for that case). - // All the other Squirrel type-masks are passed normally. - - template - SQClassDefBase & staticFuncVarArgs(Func pfunc,const SQChar * name,const SQChar * typeMask=_SC("*")) { - SquirrelVM::PushObject(newClass); - SquirrelVM::CreateFunction(pfunc,name,typeMask); - SquirrelVM::Pop(1); - return *this; - } // staticFuncVarArgs - - // Register a standard global function (effectively embedding a global function in TClassType's script namespace: does not need or use a 'this' pointer). - template - SQClassDefBase & staticFunc(Func pfunc,const SQChar * name) { - Register(v,newClass.GetObjectHandle(),pfunc,name); - return *this; - } // staticFunc - - // Register a function to a pre-allocated class/struct member function: will use callee's 'this' (effectively embedding a global function in TClassType's script namespace). - template - SQClassDefBase & staticFunc(Callee & callee,Func pfunc,const SQChar * name) { - Register(v,newClass.GetObjectHandle(),callee,pfunc,name); - return *this; - } // staticFunc - - // === END static+global function registration === - - // Register a member variable. - template - SQClassDefBase & var(VarType TClassType::* pvar,const SQChar * name,VarAccessType access=VAR_ACCESS_READ_WRITE) { - struct CV { - VarType TClassType::* var; - } cv; // Cast Variable helper. - cv.var = pvar; - RegisterInstanceVariable(newClass,ClassType::type(),*(VarType **)&cv,name,access); - return *this; - } // var - - // Register a member variable as a UserPointer (read only). - template - SQClassDefBase & varAsUserPointer(VarType TClassType::* pvar,const SQChar * name) { - struct CV { - VarType TClassType::* var; - } cv; // Cast Variable helper. - cv.var = pvar; - RegisterInstanceVariable(newClass,ClassType::type(),*(SQAnything **)&cv,name,VAR_ACCESS_READ_ONLY); - return *this; - } // varAsUserPointer - -#ifdef SQPLUS_SMARTPOINTER_OPT -#define SQPLUS_SMARTPOINTER_CLASS_DEF_VAR -#include "SqPlusSmartPointer.h" -#endif - - template - SQClassDefBase & staticVar(VarType * pvar,const SQChar * name,VarAccessType access=VAR_ACCESS_READ_WRITE) { - struct CV { - VarType * var; - } cv; // Cast Variable helper. - cv.var = pvar; - RegisterInstanceVariable(newClass,ClassType::type(),*(VarType **)&cv,name,VarAccessType(access|VAR_ACCESS_STATIC)); - return *this; - } // staticVar - -#ifdef SQPLUS_CONST_OPT -#define SQ_REG_CONST_STATIC_VAR -#include "SqPlusConst.h" -#endif - - // Member / static member script vars (ordinary Squirrel vars) - SQClassDefBase & scriptVar( const SQChar* name, int ival, SQBool static_var=SQFalse ) { - HSQUIRRELVM v = SquirrelVM::GetVMPtr(); - sq_pushobject(v,newClass.GetObjectHandle()); - sq_pushstring(v,name,-1); - sq_pushinteger(v,ival); - sq_newslot(v,-3,static_var); - sq_pop(v,1); - return *this; - } - - SQClassDefBase & scriptVar( const SQChar* name, double fval, SQBool static_var=SQFalse ) { - HSQUIRRELVM v = SquirrelVM::GetVMPtr(); - sq_pushobject(v,newClass.GetObjectHandle()); - sq_pushstring(v,name,-1); - sq_pushfloat(v,fval); - sq_newslot(v,-3,static_var); - sq_pop(v,1); - return *this; - } - - SQClassDefBase & scriptVar( const SQChar* name, const SQChar* sval, SQBool static_var=SQFalse ) { - HSQUIRRELVM v = SquirrelVM::GetVMPtr(); - sq_pushobject(v,newClass.GetObjectHandle()); - sq_pushstring(v,name,-1); - sq_pushstring(v,sval,-1); - sq_newslot(v,-3,static_var); - sq_pop(v,1); - return *this; - } - - // Register a constant (read-only in script, passed by value (only INT, FLOAT, or BOOL types)). - template - SQClassDefBase & constant(ConstantType constant,const SQChar * name) { - RegisterInstanceConstant(newClass,ClassType::type(),constant,name); - return *this; - } // constant - - // Register an enum as an integer (read-only in script). - SQClassDefBase & enumInt(int constant,const SQChar * name) { - RegisterInstanceConstant(newClass,ClassType::type(),constant,name); - return *this; - } // enumInt - -#ifdef SQPLUS_OVERLOAD_OPT -#define SQPLUS_OVERLOAD_IMPLEMENTATION -#include "SqPlusOverload.h" -#endif -}; - -#ifdef SQPLUS_OVERLOAD_OPT -#define SQPLUS_OVERLOAD_FUNCTIONS -#include "SqPlusOverload.h" -#endif - -template -struct SQClassDef : public SQClassDefBase { - -#if defined(SQ_USE_CLASS_INHERITANCE) || defined(SQ_USE_CLASS_INHERITANCE_SIMPLE) - // Optional base arg is the name of a base class to inherit from (must already be defined in the Squirrel VM). - SQClassDef(HSQUIRRELVM _v,const SQChar * _name=0,const SQChar * _base=0) : SQClassDefBase(_v,_name,_base) { - SQClassDefBase::newClass = - RegisterClassType( SQClassDefBase::v, - SQClassDefBase::name, - SQClassDefBase::base ); - } - // Optional base arg is the name of a base class to inherit from (must already be defined in the Squirrel VM). - SQClassDef(const SQChar * _name=0,const SQChar * _base=0) : SQClassDefBase(_name,_base) { - SQClassDefBase::newClass = - RegisterClassType< TClassType>( SQClassDefBase::v, - SQClassDefBase::name, - SQClassDefBase::base ); - } -#else - SQClassDef(HSQUIRRELVM _v,const SQChar * _name=0) : SQClassDefBase(_v,_name) { - SQClassDefBase::newClass = - RegisterClassType(SQClassDefBase::v, - SQClassDefBase::name ); - } - SQClassDef(const SQChar * _name=0) : SQClassDefBase(_name) { - SQClassDefBase::newClass = - RegisterClassType(SQClassDefBase::v, - SQClassDefBase::name ); - } -#endif -}; - -template -struct SQClassDefNoConstructor : public SQClassDefBase { -#if defined(SQ_USE_CLASS_INHERITANCE) || defined(SQ_USE_CLASS_INHERITANCE_SIMPLE) - // Optional base arg is the name of a base class to inherit from (must already be defined in the Squirrel VM). - SQClassDefNoConstructor(HSQUIRRELVM _v,const SQChar * _name=0,const SQChar * _base=0) : SQClassDefBase(_v,_name,_base) { - SQClassDefBase::newClass = RegisterClassTypeNoConstructor(SQClassDefBase::v,SQClassDefBase::name,SQClassDefBase::base); - } - // Optional base arg is the name of a base class to inherit from (must already be defined in the Squirrel VM). - SQClassDefNoConstructor(const SQChar * _name=0,const SQChar * _base=0) : SQClassDefBase(_name,_base) { - SQClassDefBase::newClass = RegisterClassTypeNoConstructor(SQClassDefBase::v,SQClassDefBase::name,SQClassDefBase::base); - } -#else - SQClassDefNoConstructor(HSQUIRRELVM _v,const SQChar * _name=0) : SQClassDefBase(_v,_name) { - SQClassDefBase::newClass = RegisterClassTypeNoConstructor(SQClassDefBase::v,SQClassDefBase::name); - } - SQClassDefNoConstructor(const SQChar * _name=0) : SQClassDefBase(_name) { - SQClassDefBase::newClass = RegisterClassTypeNoConstructor(SQClassDefBase::v,SQClassDefBase::name); - } -#endif -}; - - -// === Macros for old style registration. SQClassDef registration is now easier to use (SQ_DECLARE_CLASS() is not needed) === - -#define SQ_DECLARE_CLASS(CLASSNAME) \ -static int _##CLASSNAME##_release(SQUserPointer up,SQInteger size) { \ - if (up) { \ - CLASSNAME * self = (CLASSNAME *)up; \ - delete self; \ - } \ - return 0; \ -} \ -static int _##CLASSNAME##_constructor(HSQUIRRELVM v) { \ - CLASSNAME * pc = new CLASSNAME(); \ - sq_setinstanceup(v,1,pc); \ - sq_setreleasehook(v,1,_##CLASSNAME##_release); \ - return 1; \ -} - -#define SQ_REGISTER_CLASS(CLASSNAME) \ - RegisterClassType(SquirrelVM::GetVMPtr(),_SC(#CLASSNAME),_##CLASSNAME##_constructor) - -#define SQ_REGISTER_INSTANCE(NEWSQCLASS,CCLASS,FUNCNAME) \ - RegisterInstance(SquirrelVM::GetVMPtr(),NEWSQCLASS.GetObjectHandle(),*(CCLASS *)0,&CCLASS::FUNCNAME,_SC(#FUNCNAME)); - -#define SQ_REGISTER_INSTANCE_VARARGS(NEWSQCLASS,CCLASS,FUNCNAME) \ - RegisterInstanceVarArgs(SquirrelVM::GetVMPtr(),NEWSQCLASS.GetObjectHandle(),*(CCLASS *)0,&CCLASS::FUNCNAME,_SC(#FUNCNAME)); - -#define SQ_REGISTER_INSTANCE_VARIABLE(NEWSQCLASS,CCLASS,VARNAME) \ - RegisterInstanceVariable(NEWSQCLASS,&((CCLASS *)0)->VARNAME,_SC(#VARNAME)); - -#if defined(USE_ARGUMENT_DEPENDANT_OVERLOADS) && defined(_MSC_VER) -#pragma warning (default:4675) -#endif - -}; // namespace SqPlus - - -// === BEGIN code suggestion from the Wiki === - -// Get any bound type from this SquirrelObject. Note that Squirrel's -// handling of references and pointers still holds here. -template -inline _ty SquirrelObject::Get(void) { - sq_pushobject(SquirrelVM::_VM,GetObjectHandle()); - _ty val = SqPlus::Get(SqPlus::TypeWrapper<_ty>(),SquirrelVM::_VM,-1); - sq_poptop(SquirrelVM::_VM); - return val; -} - -// Set any bound type to this SquirrelObject. Note that Squirrel's -// handling of references and pointers still holds here. -template -inline SquirrelObject SquirrelObject::SetByValue(_ty val) { // classes/structs should be passed by ref (below) to avoid an extra copy. - SqPlus::Push(SquirrelVM::_VM,val); - AttachToStackObject(-1); - sq_poptop(SquirrelVM::_VM); - return *this; -} - -// Set any bound type to this SquirrelObject. Note that Squirrel's -// handling of references and pointers still holds here. -template -inline SquirrelObject &SquirrelObject::Set(_ty & val) { - SqPlus::Push(SquirrelVM::_VM,val); - AttachToStackObject(-1); - sq_poptop(SquirrelVM::_VM); - return *this; -} - -// === END code suggestion from the Wiki === - -#endif //_SQ_PLUS_H_ -- cgit v1.2.3