diff --git a/GNUmakefile b/GNUmakefile index 65945662a..6a83c3433 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -52,7 +52,10 @@ INCLUDE = -I.\ -IiniFile\ -Itolua++-1.0.93/include\ -Ijsoncpp-src-0.5.0/include\ - -Ijsoncpp-src-0.5.0/src/lib_json + -Ijsoncpp-src-0.5.0/src/lib_json\ + -Isquirrel_3_0_1_stable/include\ + -Isquirrel_3_0_1_stable\ + -Isquirrel_3_0_1_stable/sqrat # # Build MCServer diff --git a/Plugins/SquirrelChatLog.nut b/Plugins/SquirrelChatLog.nut index 586e8d6e2..df43c3fb3 100644 --- a/Plugins/SquirrelChatLog.nut +++ b/Plugins/SquirrelChatLog.nut @@ -1,26 +1,20 @@ -class SquirrelChatLog extends cPlugin__Squirrel +class SquirrelChatLog extends Plugin { - constructor() - { - base.constructor(); - } - + name = "SquirrelChatLogger"; + function Initialize() { ::print("SquirrelChatLog initialize()"); - this.SetName("SquirrelChatLog"); - local PluginManager = cRoot.Get().GetPluginManager(); - PluginManager.AddHook( this, PluginManager.E_PLUGIN_CHAT ); + this.AddHook(Hook.Chat); + return true; } function OnChat( Message, Player ) { + ::print("CHAT"); ::print(Player.GetName() + ": " + Message); + } } - - -Plugin <- SquirrelChatLog(); -cRoot.Get().GetPluginManager().AddPlugin( Plugin ); diff --git a/VC2010/MCServer.vcxproj b/VC2010/MCServer.vcxproj index 324c499f4..a75974183 100644 --- a/VC2010/MCServer.vcxproj +++ b/VC2010/MCServer.vcxproj @@ -99,7 +99,7 @@ /ZI /D_DEBUG %(AdditionalOptions) Disabled - ..\tolua++-1.0.93\include;..\lua-5.1.4\src;..\zlib-1.2.7;..\mysql-connector\include;..\source\;..\pdcurs34\;..\jsoncpp-src-0.5.0\include;..\squirrel_3_0_1_stable\include;..\squirrel_3_0_1_stable;%(AdditionalIncludeDirectories) + ..\tolua++-1.0.93\include;..\lua-5.1.4\src;..\zlib-1.2.7;..\mysql-connector\include;..\source\;..\pdcurs34\;..\jsoncpp-src-0.5.0\include;..\squirrel_3_0_1_stable\include;..\squirrel_3_0_1_stable;..\squirrel_3_0_1_stable\sqrat;%(AdditionalIncludeDirectories) WIN32;_DEBUG;_WINDOWS;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions) true Sync @@ -130,7 +130,7 @@ Disabled - ..\tolua++-1.0.93\include;..\lua-5.1.4\src;..\zlib-1.2.7;..\mysql-connector\include;..\source\;..\pdcurs34\;..\jsoncpp-src-0.5.0\include;..\squirrel_3_0_1_stable\include;..\squirrel_3_0_1_stable;%(AdditionalIncludeDirectories) + ..\tolua++-1.0.93\include;..\lua-5.1.4\src;..\zlib-1.2.7;..\mysql-connector\include;..\source\;..\pdcurs34\;..\jsoncpp-src-0.5.0\include;..\squirrel_3_0_1_stable\include;..\squirrel_3_0_1_stable;..\squirrel_3_0_1_stable\sqrat;%(AdditionalIncludeDirectories) WIN32;_DEBUG;_WINDOWS;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions) true Sync @@ -228,7 +228,7 @@ Default true Speed - ..\tolua++-1.0.93\include;..\lua-5.1.4\src;..\zlib-1.2.7;..\mysql-connector\include;..\source\;..\pdcurs34\;..\jsoncpp-src-0.5.0\include;..\squirrel_3_0_1_stable\include;..\squirrel_3_0_1_stable;%(AdditionalIncludeDirectories) + ..\tolua++-1.0.93\include;..\lua-5.1.4\src;..\zlib-1.2.7;..\mysql-connector\include;..\source\;..\pdcurs34\;..\jsoncpp-src-0.5.0\include;..\squirrel_3_0_1_stable\include;..\squirrel_3_0_1_stable;..\squirrel_3_0_1_stable\sqrat;%(AdditionalIncludeDirectories) Default MultiThreaded false @@ -306,6 +306,7 @@ + @@ -356,6 +357,7 @@ + @@ -472,7 +474,8 @@ - + + true NotUsing @@ -495,6 +498,7 @@ + @@ -522,6 +526,7 @@ + @@ -660,7 +665,10 @@ - + + + + @@ -706,4 +714,4 @@ - + \ No newline at end of file diff --git a/VC2010/MCServer.vcxproj.filters b/VC2010/MCServer.vcxproj.filters index 0a3e16992..1793d9b49 100644 --- a/VC2010/MCServer.vcxproj.filters +++ b/VC2010/MCServer.vcxproj.filters @@ -427,12 +427,15 @@ {4b3b7b43-8e8b-4823-b112-2259fdfff7d3} - - {833e49bd-848d-42de-ac60-6cd7656474e3} - {038cf4bd-108e-44e2-bdcb-9d48fb26676e} + + {43f91962-ebda-4195-aadc-921eca3c8356} + + + {833e49bd-848d-42de-ac60-6cd7656474e3} + @@ -799,9 +802,6 @@ Simulator\cSimulator\cFluidSimulator\cLavaSimulator - - LuaBindings\SquirrelBindings - Packets\cPacket_Explosion @@ -870,26 +870,26 @@ Packets - Generating + HandyStuff\Generating - Generating + HandyStuff\Generating - Generating + HandyStuff\Generating - Generating + HandyStuff\Generating - Generating + HandyStuff\Generating - Generating + HandyStuff\Generating - Generating + HandyStuff\Generating Storage @@ -904,6 +904,16 @@ Storage + + + LuaBindings\SquirrelBindings + + + cPlugin\cPlugin_Squirrel + + + LuaBindings\SquirrelBindings + @@ -1308,9 +1318,6 @@ Simulator\cSimulator\cFluidSimulator\cLavaSimulator - - LuaBindings\SquirrelBindings - Packets\cPacket_Explosion @@ -1380,25 +1387,25 @@ Packets - Generating + HandyStuff\Generating - Generating + HandyStuff\Generating - Generating + HandyStuff\Generating - Generating + HandyStuff\Generating - Generating + HandyStuff\Generating - Generating + HandyStuff\Generating - Generating + HandyStuff\Generating Storage @@ -1414,6 +1421,22 @@ + + + LuaBindings\SquirrelBindings + + + cPlugin\cPlugin_Squirrel + + + LuaBindings\SquirrelBindings + + + LuaBindings\SquirrelBindings + + + LuaBindings\SquirrelBindings + @@ -1430,4 +1453,4 @@ - + \ No newline at end of file diff --git a/VC2010/squirrel_3_0_1_stable.vcxproj b/VC2010/squirrel_3_0_1_stable.vcxproj index 92b9cc05b..b8136ec94 100644 --- a/VC2010/squirrel_3_0_1_stable.vcxproj +++ b/VC2010/squirrel_3_0_1_stable.vcxproj @@ -72,13 +72,6 @@ - - - - - - - @@ -101,21 +94,6 @@ - - - - - - - - - - - - - - - diff --git a/VC2010/squirrel_3_0_1_stable.vcxproj.filters b/VC2010/squirrel_3_0_1_stable.vcxproj.filters index 760a87547..a3e7f9767 100644 --- a/VC2010/squirrel_3_0_1_stable.vcxproj.filters +++ b/VC2010/squirrel_3_0_1_stable.vcxproj.filters @@ -7,9 +7,6 @@ {819d39f8-4859-48ad-b096-04f8d6811524} - - {d9a1c0d8-bd70-4686-9a3d-c35c9d3365e3} - @@ -72,27 +69,6 @@ sqstdlib - - sqplus - - - sqplus - - - sqplus - - - sqplus - - - sqplus - - - sqplus - - - sqplus - @@ -149,50 +125,5 @@ sqstdlib - - sqplus - - - sqplus - - - sqplus - - - sqplus - - - sqplus - - - sqplus - - - sqplus - - - sqplus - - - sqplus - - - sqplus - - - sqplus - - - sqplus - - - sqplus - - - sqplus - - - sqplus - \ No newline at end of file diff --git a/makefile_base b/makefile_base index 54a989d94..5560256da 100644 --- a/makefile_base +++ b/makefile_base @@ -25,7 +25,10 @@ INCLUDE = -I.\ -IiniFile\ -Itolua++-1.0.93/include\ -Ijsoncpp-src-0.5.0/include\ - -Ijsoncpp-src-0.5.0/src/lib_json + -Ijsoncpp-src-0.5.0/src/lib_json\ + -Isquirrel_3_0_1_stable/include\ + -Isquirrel_3_0_1_stable\ + -Isquirrel_3_0_1_stable/sqrat # @@ -66,6 +69,7 @@ MCServer : \ build/cReferenceManager.o\ build/Bindings.o\ build/BlockID.o\ + build/cBlockArea.o\ build/cBlockToPickup.o\ build/cChatColor.o\ build/cChestEntity.o\ @@ -115,10 +119,10 @@ MCServer : \ build/cWebAdmin.o\ build/cWebPlugin.o\ build/cWindow.o\ - build/LightingThread.o\ + build/LightingThread.o\ build/cRedstoneSimulator.o\ build/ChunkSender.o\ - build/cWorld.o\ + build/cWorld.o\ build/main.o\ build/ManualBindings.o\ build/Matrix4f.o\ @@ -253,7 +257,32 @@ MCServer : \ build/WSSAnvil.o\ build/FastNBT.o\ build/StringCompression.o\ + build/StringCompression.o\ + build/sqstdaux.o\ + build/sqstdblob.o\ + build/sqstdio.o\ + build/sqstdmath.o\ + build/sqstdrex.o\ + build/sqstdstream.o\ + build/sqstdstring.o\ + build/sqstdsystem.o\ + build/sqapi.o\ + build/sqbaselib.o\ + build/sqclass.o\ + build/sqcompiler.o\ + build/sqdebug.o\ + build/sqfuncstate.o\ + build/sqlexer.o\ + build/sqmem.o\ + build/sqobject.o\ + build/sqstate.o\ + build/sqtable.o\ + build/sqvm.o\ + build/squirrelbindings/SquirrelBindings.o\ + build/squirrelbindings/SquirrelFunctions.o\ + build/cPlugin_Squirrel.o\ build/CraftingRecipes.o + $(CC) $(LNK_OPTIONS) \ build/json_reader.o\ build/json_value.o\ @@ -288,6 +317,7 @@ MCServer : \ build/cReferenceManager.o\ build/Bindings.o\ build/BlockID.o\ + build/cBlockArea.o\ build/cBlockToPickup.o\ build/cChatColor.o\ build/cChestEntity.o\ @@ -476,6 +506,29 @@ MCServer : \ build/FastNBT.o\ build/StringCompression.o\ build/CraftingRecipes.o\ + build/sqstdaux.o\ + build/sqstdblob.o\ + build/sqstdio.o\ + build/sqstdmath.o\ + build/sqstdrex.o\ + build/sqstdstream.o\ + build/sqstdstring.o\ + build/sqstdsystem.o\ + build/sqapi.o\ + build/sqbaselib.o\ + build/sqclass.o\ + build/sqcompiler.o\ + build/sqdebug.o\ + build/sqfuncstate.o\ + build/sqlexer.o\ + build/sqmem.o\ + build/sqobject.o\ + build/sqstate.o\ + build/sqtable.o\ + build/sqvm.o\ + build/squirrelbindings/SquirrelBindings.o\ + build/squirrelbindings/SquirrelFunctions.o\ + build/cPlugin_Squirrel.o\ -o MCServer clean : @@ -696,6 +749,29 @@ clean : build/cIsThread.o\ build/cSocketThreads.o\ build/CraftingRecipes.o\ + build/sqstdaux.o\ + build/sqstdblob.o\ + build/sqstdio.o\ + build/sqstdmath.o\ + build/sqstdrex.o\ + build/sqstdstream.o\ + build/sqstdstring.o\ + build/sqstdsystem.o\ + build/sqapi.o\ + build/sqbaselib.o\ + build/sqclass.o\ + build/sqcompiler.o\ + build/sqdebug.o\ + build/sqfuncstate.o\ + build/sqlexer.o\ + build/sqmem.o\ + build/sqobject.o\ + build/sqstate.o\ + build/sqtable.o\ + build/sqvm.o\ + build/squirrelbindings/SquirrelBindings.o\ + build/squirrelbindings/SquirrelFunctions.o\ + build/cPlugin_Squirrel.o\ MCServer install : MCServer @@ -734,6 +810,9 @@ build/Bindings.o : source/Bindings.cpp build/BlockID.o : source/BlockID.cpp $(CC) $(CC_OPTIONS) source/BlockID.cpp -c $(INCLUDE) -o build/BlockID.o +build/cBlockArea.o : source/cBlockArea.cpp + $(CC) $(CC_OPTIONS) source/cBlockArea.cpp -c $(INCLUDE) -o build/cBlockArea.o + # Item # 6 -- cBlockToPickup -- build/cBlockToPickup.o : source/cBlockToPickup.cpp @@ -1602,7 +1681,58 @@ build/cRedstoneSimulator.o : source/cRedstoneSimulator.cpp build/CraftingRecipes.o : source/CraftingRecipes.cpp $(CC) $(CC_OPTIONS) source/CraftingRecipes.cpp -c $(INCLUDE) -o build/CraftingRecipes.o + + +build/squirrelbindings/SquirrelBindings.o : source/squirrelbindings/SquirrelBindings.cpp + $(CC) $(CC_OPTIONS) source/squirrelbindings/SquirrelBindings.cpp -c $(INCLUDE) -o build/squirrelbindings/SquirrelBindings.o + +build/squirrelbindings/SquirrelFunctions.o : source/squirrelbindings/SquirrelFunctions.cpp + $(CC) $(CC_OPTIONS) source/squirrelbindings/SquirrelFunctions.cpp -c $(INCLUDE) -o build/squirrelbindings/SquirrelFunctions.o + +build/cPlugin_Squirrel.o : source/cPlugin_Squirrel.cpp + $(CC) $(CC_OPTIONS) source/cPlugin_Squirrel.cpp -c $(INCLUDE) -o build/cPlugin_Squirrel.o + +build/sqstdaux.o : squirrel_3_0_1_stable/sqstdlib/sqstdaux.cpp + $(CC) $(CC_OPTIONS) squirrel_3_0_1_stable/sqstdlib/sqstdaux.cpp -c $(INCLUDE) -o build/sqstdaux.o +build/sqstdblob.o : squirrel_3_0_1_stable/sqstdlib/sqstdblob.cpp + $(CC) $(CC_OPTIONS) squirrel_3_0_1_stable/sqstdlib/sqstdblob.cpp -c $(INCLUDE) -o build/sqstdblob.o +build/sqstdio.o : squirrel_3_0_1_stable/sqstdlib/sqstdio.cpp + $(CC) $(CC_OPTIONS) squirrel_3_0_1_stable/sqstdlib/sqstdio.cpp -c $(INCLUDE) -o build/sqstdio.o +build/sqstdmath.o : squirrel_3_0_1_stable/sqstdlib/sqstdmath.cpp + $(CC) $(CC_OPTIONS) squirrel_3_0_1_stable/sqstdlib/sqstdmath.cpp -c $(INCLUDE) -o build/sqstdmath.o +build/sqstdrex.o : squirrel_3_0_1_stable/sqstdlib/sqstdrex.cpp + $(CC) $(CC_OPTIONS) squirrel_3_0_1_stable/sqstdlib/sqstdrex.cpp -c $(INCLUDE) -o build/sqstdrex.o +build/sqstdstream.o : squirrel_3_0_1_stable/sqstdlib/sqstdstream.cpp + $(CC) $(CC_OPTIONS) squirrel_3_0_1_stable/sqstdlib/sqstdstream.cpp -c $(INCLUDE) -o build/sqstdstream.o +build/sqstdstring.o : squirrel_3_0_1_stable/sqstdlib/sqstdstring.cpp + $(CC) $(CC_OPTIONS) squirrel_3_0_1_stable/sqstdlib/sqstdstring.cpp -c $(INCLUDE) -o build/sqstdstring.o +build/sqstdsystem.o : squirrel_3_0_1_stable/sqstdlib/sqstdsystem.cpp + $(CC) $(CC_OPTIONS) squirrel_3_0_1_stable/sqstdlib/sqstdsystem.cpp -c $(INCLUDE) -o build/sqstdsystem.o +build/sqapi.o : squirrel_3_0_1_stable/squirrel/sqapi.cpp + $(CC) $(CC_OPTIONS) squirrel_3_0_1_stable/squirrel/sqapi.cpp -c $(INCLUDE) -o build/sqapi.o +build/sqbaselib.o : squirrel_3_0_1_stable/squirrel/sqbaselib.cpp + $(CC) $(CC_OPTIONS) squirrel_3_0_1_stable/squirrel/sqbaselib.cpp -c $(INCLUDE) -o build/sqbaselib.o +build/sqclass.o : squirrel_3_0_1_stable/squirrel/sqclass.cpp + $(CC) $(CC_OPTIONS) squirrel_3_0_1_stable/squirrel/sqclass.cpp -c $(INCLUDE) -o build/sqclass.o +build/sqcompiler.o : squirrel_3_0_1_stable/squirrel/sqcompiler.cpp + $(CC) $(CC_OPTIONS) squirrel_3_0_1_stable/squirrel/sqcompiler.cpp -c $(INCLUDE) -o build/sqcompiler.o +build/sqdebug.o : squirrel_3_0_1_stable/squirrel/sqdebug.cpp + $(CC) $(CC_OPTIONS) squirrel_3_0_1_stable/squirrel/sqdebug.cpp -c $(INCLUDE) -o build/sqdebug.o +build/sqfuncstate.o : squirrel_3_0_1_stable/squirrel/sqfuncstate.cpp + $(CC) $(CC_OPTIONS) squirrel_3_0_1_stable/squirrel/sqfuncstate.cpp -c $(INCLUDE) -o build/sqfuncstate.o +build/sqlexer.o : squirrel_3_0_1_stable/squirrel/sqlexer.cpp + $(CC) $(CC_OPTIONS) squirrel_3_0_1_stable/squirrel/sqlexer.cpp -c $(INCLUDE) -o build/sqlexer.o +build/sqmem.o : squirrel_3_0_1_stable/squirrel/sqmem.cpp + $(CC) $(CC_OPTIONS) squirrel_3_0_1_stable/squirrel/sqmem.cpp -c $(INCLUDE) -o build/sqmem.o +build/sqobject.o : squirrel_3_0_1_stable/squirrel/sqobject.cpp + $(CC) $(CC_OPTIONS) squirrel_3_0_1_stable/squirrel/sqobject.cpp -c $(INCLUDE) -o build/sqobject.o +build/sqstate.o : squirrel_3_0_1_stable/squirrel/sqstate.cpp + $(CC) $(CC_OPTIONS) squirrel_3_0_1_stable/squirrel/sqstate.cpp -c $(INCLUDE) -o build/sqstate.o +build/sqtable.o : squirrel_3_0_1_stable/squirrel/sqtable.cpp + $(CC) $(CC_OPTIONS) squirrel_3_0_1_stable/squirrel/sqtable.cpp -c $(INCLUDE) -o build/sqtable.o +build/sqvm.o : squirrel_3_0_1_stable/squirrel/sqvm.cpp + $(CC) $(CC_OPTIONS) squirrel_3_0_1_stable/squirrel/sqvm.cpp -c $(INCLUDE) -o build/sqvm.o + # Template: copy and delete the "# "; insert filenames # build/.o : source/.cpp # $(CC) $(CC_OPTIONS) source/.cpp -c $(INCLUDE) -o build/.o - diff --git a/source/AllToLua.pkg b/source/AllToLua.pkg index b6ee64579..4e4cfb4b5 100644 --- a/source/AllToLua.pkg +++ b/source/AllToLua.pkg @@ -45,7 +45,7 @@ $cfile "cCuboid.h" $cfile "cMCLogger.h" $cfile "cTracer.h" $cfile "cGroup.h" -$cfile "BlockArea.h" +$cfile "cBlockArea.h" $cfile "packets/cPacket_Login.h" $cfile "packets/cPacket_BlockDig.h" $cfile "packets/cPacket_BlockPlace.h" diff --git a/source/Bindings.cpp b/source/Bindings.cpp index 485f37dc0..772013b25 100644 --- a/source/Bindings.cpp +++ b/source/Bindings.cpp @@ -1,6 +1,6 @@ /* ** Lua binding: AllToLua -** Generated automatically by tolua++-1.0.92 on 07/02/12 18:39:13. +** Generated automatically by tolua++-1.0.92 on 07/08/12 16:56:12. */ #ifndef __cplusplus @@ -54,7 +54,7 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S); #include "cMCLogger.h" #include "cTracer.h" #include "cGroup.h" -#include "BlockArea.h" +#include "cBlockArea.h" #include "packets/cPacket_Login.h" #include "packets/cPacket_BlockDig.h" #include "packets/cPacket_BlockPlace.h" diff --git a/source/Bindings.h b/source/Bindings.h index a47b5e463..097fe7e64 100644 --- a/source/Bindings.h +++ b/source/Bindings.h @@ -1,6 +1,6 @@ /* ** Lua binding: AllToLua -** Generated automatically by tolua++-1.0.92 on 07/02/12 18:39:13. +** Generated automatically by tolua++-1.0.92 on 07/08/12 16:56:13. */ /* Exported function */ diff --git a/source/SquirrelBindings.cpp b/source/_OLD_SquirrelBindings.cpp similarity index 94% rename from source/SquirrelBindings.cpp rename to source/_OLD_SquirrelBindings.cpp index d8f513370..532b19950 100644 --- a/source/SquirrelBindings.cpp +++ b/source/_OLD_SquirrelBindings.cpp @@ -1,140 +1,140 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "SquirrelBindings.h" -#if USE_SQUIRREL -#pragma warning(disable:4100) // Getting A LOT of these warnings from SqPlus -#pragma warning(disable:4127) - -#include -#include -#include <../squirrel/sqstate.h> -#include <../squirrel/sqvm.h> - -#include "cPlugin.h" -#include "cPluginManager.h" -#include "cRoot.h" -#include "cPlayer.h" - - - - - -bool SquirrelBindings::IsBound = false; - -bool IsTopClosure( HSQUIRRELVM v ) -{ - return ( v->_stack[0]._type == OT_CLOSURE ); -} - -class __Squirrel_Base_Class // All inheritable classes should extend this class, as it allows virtual functions to call Squirrel -{ -public: - template - static int ConstructAndDestruct(HSQUIRRELVM v, T* a_Instance, SQRELEASEHOOK a_ReleaseHook ) - { - LOG("ConstructAndDestruct()"); - - StackHandler sa(v); - HSQOBJECT ho = sa.GetObjectHandle(1); // OT_INSTANCE - SquirrelObject instance(ho); - SqPlus::PopulateAncestry(v, instance, a_Instance); - a_Instance->vm = v; - a_Instance->obj = instance; - - sq_setinstanceup(v, 1, a_Instance); - sq_setreleasehook(v, 1, a_ReleaseHook); - return TRUE; - } - - HSQUIRRELVM vm; - SquirrelObject obj; -}; - -class cPlugin__Squirrel : public cPlugin, public __Squirrel_Base_Class -{ -public: - cPlugin__Squirrel() { SetLanguage( cPlugin::E_SQUIRREL ); } - - bool Initialize() // This is a pure virtual function, so it NEEDS an implementation on the script side or it would be an illegal instance - { - SqPlus::SquirrelFunction InitFunc(obj, "Initialize"); - if( !InitFunc.func.IsNull() ) - return InitFunc(); - LOGWARN("cPlugin__Squirrel::Initialize() Pure virtual function called!"); // Spam some errorz to make it clear this function needs to be implemented - return false; - } - - static int constructor(HSQUIRRELVM v) { return ConstructAndDestruct( v, new cPlugin__Squirrel, SqPlus::ReleaseClassPtr::release ); } - - virtual bool OnChat( const char* a_Chat, cPlayer* a_Player ) - { - if( !IsTopClosure(vm) ) // Avoid recursion (TODO: FIXME: THIS NEEDS MORE RESEARCH!) - { //Called from C++ - return SqPlus::SquirrelFunction(obj, "OnChat")(a_Chat, a_Player); - } - else // Called from Squirrel - { - return cPlugin::OnChat(a_Chat, a_Player); - } - } -}; - -static void printFunc(HSQUIRRELVM v,const SQChar * s,...) -{ - (void)v; - va_list vl; - va_start(vl,s); - cMCLogger::GetInstance()->Log( s, vl ); - va_end(vl); -} - -DECLARE_INSTANCE_TYPE( cRoot ); -DECLARE_INSTANCE_TYPE( cPluginManager ); -DECLARE_ENUM_TYPE( cPluginManager::PluginHook ); -DECLARE_INSTANCE_TYPE( cPlugin ); -DECLARE_INSTANCE_TYPE( cPlugin__Squirrel ); - -DECLARE_INSTANCE_TYPE( cEntity ); -DECLARE_INSTANCE_TYPE( cPawn ); -DECLARE_INSTANCE_TYPE( cPlayer ); - -void SquirrelBindings::Bind( HSQUIRRELVM a_SquirrelVM ) -{ - IsBound = true; - - sq_setprintfunc(a_SquirrelVM, printFunc, printFunc); - - - SqPlus::SQClassDefNoConstructor("cEntity"); - SqPlus::SQClassDefNoConstructor("cPawn", "cEntity"); - SqPlus::SQClassDefNoConstructor("cPlayer", "cPawn"). // All NoConstructor because they need a custom one - func(&cPlayer::GetName, "GetName"); - - SqPlus::SQClassDefNoConstructor("cPlugin"). - func(&cPlugin::SetName, "SetName"). - func(&cPlugin::GetName, "GetName"). - func(&cPlugin::GetVersion, "GetVersion"). - func(&cPlugin::OnChat, "OnChat"); - - - SqPlus::SQClassDef("cPlugin__Squirrel", "cPlugin"). - staticFunc(&cPlugin__Squirrel::constructor, "constructor"); - - - SqPlus::SQClassDefNoConstructor("cRoot"). - staticFunc(&cRoot::Get, "Get"). - func(static_cast(&cRoot::GetPluginManager), "GetPluginManager"); - - - SqPlus::SQClassDefNoConstructor("cPluginManager"). - overloadFunc(&cPluginManager::AddPlugin, "AddPlugin"). - func(&cPluginManager::GetPlugin, "GetPlugin"). - func(&cPluginManager::AddHook, "AddHook"). - enumInt( cPluginManager::E_PLUGIN_CHAT, "E_PLUGIN_CHAT"); - - - -} - -#endif + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "SquirrelBindings.h" +#if USE_SQUIRREL +//#pragma warning(disable:4100) // Getting A LOT of these warnings from SqPlus +//#pragma warning(disable:4127) + +#include +#include +#include <../squirrel/sqstate.h> +#include <../squirrel/sqvm.h> + +#include "cPlugin.h" +#include "cPluginManager.h" +#include "cRoot.h" +#include "cPlayer.h" + + + + + +bool SquirrelBindings::IsBound = false; + +bool IsTopClosure( HSQUIRRELVM v ) +{ + return ( v->_stack[0]._type == OT_CLOSURE ); +} + +class __Squirrel_Base_Class // All inheritable classes should extend this class, as it allows virtual functions to call Squirrel +{ +public: + template + static int ConstructAndDestruct(HSQUIRRELVM v, T* a_Instance, SQRELEASEHOOK a_ReleaseHook ) + { + LOG("ConstructAndDestruct()"); + + StackHandler sa(v); + HSQOBJECT ho = sa.GetObjectHandle(1); // OT_INSTANCE + SquirrelObject instance(ho); + SqPlus::PopulateAncestry(v, instance, a_Instance); + a_Instance->vm = v; + a_Instance->obj = instance; + + sq_setinstanceup(v, 1, a_Instance); + sq_setreleasehook(v, 1, a_ReleaseHook); + return TRUE; + } + + HSQUIRRELVM vm; + SquirrelObject obj; +}; + +class cPlugin__Squirrel : public cPlugin, public __Squirrel_Base_Class +{ +public: + cPlugin__Squirrel() { SetLanguage( cPlugin::E_SQUIRREL ); } + + bool Initialize() // This is a pure virtual function, so it NEEDS an implementation on the script side or it would be an illegal instance + { + SqPlus::SquirrelFunction InitFunc(obj, "Initialize"); + if( !InitFunc.func.IsNull() ) + return InitFunc(); + LOGWARN("cPlugin__Squirrel::Initialize() Pure virtual function called!"); // Spam some errorz to make it clear this function needs to be implemented + return false; + } + + static int constructor(HSQUIRRELVM v) { return ConstructAndDestruct( v, new cPlugin__Squirrel, SqPlus::ReleaseClassPtr::release ); } + + virtual bool OnChat( const char* a_Chat, cPlayer* a_Player ) + { + if( !IsTopClosure(vm) ) // Avoid recursion (TODO: FIXME: THIS NEEDS MORE RESEARCH!) + { //Called from C++ + return SqPlus::SquirrelFunction(obj, "OnChat")(a_Chat, a_Player); + } + else // Called from Squirrel + { + return cPlugin::OnChat(a_Chat, a_Player); + } + } +}; + +static void printFunc(HSQUIRRELVM v,const SQChar * s,...) +{ + (void)v; + va_list vl; + va_start(vl,s); + cMCLogger::GetInstance()->Log( s, vl ); + va_end(vl); +} + +DECLARE_INSTANCE_TYPE( cRoot ); +DECLARE_INSTANCE_TYPE( cPluginManager ); +DECLARE_ENUM_TYPE( cPluginManager::PluginHook ); +DECLARE_INSTANCE_TYPE( cPlugin ); +DECLARE_INSTANCE_TYPE( cPlugin__Squirrel ); + +DECLARE_INSTANCE_TYPE( cEntity ); +DECLARE_INSTANCE_TYPE( cPawn ); +DECLARE_INSTANCE_TYPE( cPlayer ); + +void SquirrelBindings::Bind( HSQUIRRELVM a_SquirrelVM ) +{ + IsBound = true; + + sq_setprintfunc(a_SquirrelVM, printFunc, printFunc); + + + SqPlus::SQClassDefNoConstructor("cEntity"); + SqPlus::SQClassDefNoConstructor("cPawn", "cEntity"); + SqPlus::SQClassDefNoConstructor("cPlayer", "cPawn"). // All NoConstructor because they need a custom one + func(&cPlayer::GetName, "GetName"); + + SqPlus::SQClassDefNoConstructor("cPlugin"). + func(&cPlugin::SetName, "SetName"). + func(&cPlugin::GetName, "GetName"). + func(&cPlugin::GetVersion, "GetVersion"). + func(&cPlugin::OnChat, "OnChat"); + + + SqPlus::SQClassDef("cPlugin__Squirrel", "cPlugin"). + staticFunc(&cPlugin__Squirrel::constructor, "constructor"); + + + SqPlus::SQClassDefNoConstructor("cRoot"). + staticFunc(&cRoot::Get, "Get"). + func(static_cast(&cRoot::GetPluginManager), "GetPluginManager"); + + + SqPlus::SQClassDefNoConstructor("cPluginManager"). + overloadFunc(&cPluginManager::AddPlugin, "AddPlugin"). + func(&cPluginManager::GetPlugin, "GetPlugin"). + func(&cPluginManager::AddHook, "AddHook"). + enumInt( cPluginManager::E_PLUGIN_CHAT, "E_PLUGIN_CHAT"); + + + +} + +#endif diff --git a/source/SquirrelBindings.h b/source/_OLD_SquirrelBindings.h similarity index 80% rename from source/SquirrelBindings.h rename to source/_OLD_SquirrelBindings.h index 06a3df716..26f125746 100644 --- a/source/SquirrelBindings.h +++ b/source/_OLD_SquirrelBindings.h @@ -1,15 +1,15 @@ -#pragma once - -#define USE_SQUIRREL 0 - -#if USE_SQUIRREL - -struct SQVM; -class SquirrelBindings -{ -public: - static void Bind( SQVM* a_SquirrelVM ); - static bool IsBound; -}; - -#endif +#pragma once + +#define USE_SQUIRREL 1 + +#if USE_SQUIRREL + +struct SQVM; +class SquirrelBindings +{ +public: + static void Bind( SQVM* a_SquirrelVM ); + static bool IsBound; +}; + +#endif diff --git a/source/BlockArea.cpp b/source/cBlockArea.cpp similarity index 95% rename from source/BlockArea.cpp rename to source/cBlockArea.cpp index 7750b94fb..810503f04 100644 --- a/source/BlockArea.cpp +++ b/source/cBlockArea.cpp @@ -5,7 +5,7 @@ // The object also supports writing the blockdata back into cWorld, even into other coords #include "Globals.h" -#include "BlockArea.h" +#include "cBlockArea.h" #include "cWorld.h" diff --git a/source/BlockArea.h b/source/cBlockArea.h similarity index 100% rename from source/BlockArea.h rename to source/cBlockArea.h diff --git a/source/cChunk.cpp b/source/cChunk.cpp index cd94e3413..489af5cc9 100644 --- a/source/cChunk.cpp +++ b/source/cChunk.cpp @@ -27,7 +27,7 @@ #include "cBlockToPickup.h" #include "MersenneTwister.h" #include "cPlayer.h" -#include "BlockArea.h" +#include "cBlockArea.h" #include "cPluginManager.h" #include "packets/cPacket_DestroyEntity.h" diff --git a/source/cPluginManager.cpp b/source/cPluginManager.cpp index f152911e8..4cf21c850 100644 --- a/source/cPluginManager.cpp +++ b/source/cPluginManager.cpp @@ -5,6 +5,7 @@ #include "cPlugin.h" #include "cPlugin_Lua.h" #include "cPlugin_NewLua.h" +#include "cPlugin_Squirrel.h" #include "cWebAdmin.h" #include "cItem.h" #include "cRoot.h" @@ -12,10 +13,12 @@ #include "../iniFile/iniFile.h" #include "tolua++.h" -#include "SquirrelBindings.h" +#include "squirrelbindings/SquirrelBindings.h" +#include "squirrelbindings/SquirrelFunctions.h" + #if USE_SQUIRREL #pragma warning(disable:4100;disable:4127;disable:4510;disable:4610;disable:4244;disable:4512) // Getting A LOT of these warnings from SqPlus - #include + #pragma warning(default:4100;default:4127;default:4510;default:4610;default:4244;default:4512) #endif @@ -70,11 +73,8 @@ void cPluginManager::ReloadPluginsNow() UnloadPluginsNow(); #if USE_SQUIRREL - if( !SquirrelBindings::IsBound ) // Can only do this once apparently, or we're making ambiguous calls in the script - { - SquirrelVM::Init(); - SquirrelBindings::Bind( SquirrelVM::GetVMPtr() ); - } + CloseSquirrelVM(); + OpenSquirrelVM(); #endif // USE_SQUIRREL cIniFile IniFile("settings.ini"); @@ -129,26 +129,11 @@ void cPluginManager::ReloadPluginsNow() if( !PluginFile.empty() ) { LOGINFO("Loading Squirrel plugin: %s", PluginFile.c_str() ); - try - { - SquirrelObject SquirrelScript = SquirrelVM::CompileScript( (AString("Plugins/") + PluginFile + ".nut").c_str() ); - try - { - SquirrelVM::RunScript( SquirrelScript ); - } - catch (SquirrelError & e) - { - LOGERROR("SquirrelScript error: %s, %s\n", e.desc, "SquirrelVM::RunScript"); - } - } - catch (SquirrelError & e) - { - LOGERROR("SquirrelScript error: %s, %s\n", e.desc, "SquirrelVM::CompileScript"); - } + + this->AddPlugin(new cPlugin_Squirrel(PluginFile.c_str())); } } #endif // USE_SQUIRREL - } } @@ -195,7 +180,7 @@ bool cPluginManager::CallHook(PluginHook a_Hook, unsigned int a_NumArgs, ...) if (a_Hook == HOOK_CHAT) { if (a_NumArgs != 2) - { + { return false; } va_list argptr; @@ -221,6 +206,7 @@ bool cPluginManager::CallHook(PluginHook a_Hook, unsigned int a_NumArgs, ...) return true; } } + return false; } diff --git a/source/cPlugin_Squirrel.cpp b/source/cPlugin_Squirrel.cpp new file mode 100644 index 000000000..aa7f7f023 --- /dev/null +++ b/source/cPlugin_Squirrel.cpp @@ -0,0 +1,352 @@ +#include "Globals.h" +#include "cPlugin_Squirrel.h" +#include "squirrelbindings/SquirrelFunctions.h" +#include "squirrelbindings/SquirrelBindings.h" +#include "squirrelbindings/cSquirrelBaseClass.h" + + +cPlugin_Squirrel::cPlugin_Squirrel( const char* a_PluginName ) +{ + SetLanguage( cPlugin::E_SQUIRREL ); + m_PluginName = a_PluginName; +} + +cPlugin_Squirrel::~cPlugin_Squirrel() +{ + delete m_PluginName; + delete m_Plugin; +} + +bool cPlugin_Squirrel::Initialize() +{ + cCSLock Lock(m_CriticalSection); + + std::string PluginPath = std::string("Plugins/") + m_PluginName + ".nut"; + + Sqrat::Script script; + script.CompileFile(PluginPath); + if(script.IsNull()) + { + LOGERROR("Unable to run script \"%s\"", m_PluginName); + } + + try { + script.Run(); + + Sqrat::Function construct(Sqrat::RootTable(), m_PluginName); + + if(construct.IsNull()) + { + LOGERROR("Constructor for Plugin \"%s\" not found.", m_PluginName); + return false; + } + + Sqrat::Object obj = construct.Evaluate(); + + ((cSquirrelBaseClass *) obj.GetInstanceUP())->setInstance(this); + + m_Plugin = new SquirrelObject(obj); + + + Sqrat::Object PluginName = obj.GetSlot("name"); + if(!PluginName.IsNull()) + { + this->SetName(PluginName.Cast()); + } + + Sqrat::Function init = m_Plugin->GetFunction("Initialize"); + if(init.IsNull()) + { + LOGERROR("Can not initialize plugin \"%s\"", m_PluginName); + return false; + } + + return init.Evaluate(); + + } catch(Sqrat::Exception &e) + { + LOGERROR("Initialisation of \"%s\" failed: %s", m_PluginName, e.Message().c_str()); + return false; + } +} + + + + + +void cPlugin_Squirrel::OnDisable() +{ + cCSLock Lock(m_CriticalSection); + + m_Plugin->GetFunction("OnDisable").Execute(); +} + + + + + +void cPlugin_Squirrel::Tick(float a_Dt) +{ + cCSLock Lock( m_CriticalSection ); + + m_Plugin->GetFunction("OnTick").Execute(a_Dt); +} + + + + + +bool cPlugin_Squirrel::OnCollectItem( cPickup* a_Pickup, cPlayer* a_Player ) +{ + cCSLock Lock( m_CriticalSection ); + + return m_Plugin->GetFunction("OnCollectItem").Evaluate(a_Pickup, a_Player); +} + + + + + +bool cPlugin_Squirrel::OnDisconnect(const AString & a_Reason, cPlayer* a_Player ) +{ + cCSLock Lock( m_CriticalSection ); + + + return m_Plugin->GetFunction("OnDisconnect").Evaluate(a_Reason, a_Player); +} + + + + + +bool cPlugin_Squirrel::OnBlockPlace( cPacket_BlockPlace* a_PacketData, cPlayer* a_Player ) +{ + cCSLock Lock( m_CriticalSection ); + + return m_Plugin->GetFunction("OnBlockPlace").Evaluate(a_PacketData, a_Player); +} + + + + + +bool cPlugin_Squirrel::OnBlockDig( cPacket_BlockDig* a_PacketData, cPlayer* a_Player, cItem* a_PickupItem ) +{ + cCSLock Lock( m_CriticalSection ); + + return m_Plugin->GetFunction("OnBlockDig").Evaluate(a_PacketData, a_Player, a_PickupItem); +} + + + + + +bool cPlugin_Squirrel::OnChat( const char* a_Chat, cPlayer* a_Player ) +{ + cCSLock Lock( m_CriticalSection ); + + return m_Plugin->GetFunction("OnChat").Evaluate(a_Chat, a_Player); + +} + + + + + +bool cPlugin_Squirrel::OnLogin( cPacket_Login* a_PacketData ) +{ + cCSLock Lock( m_CriticalSection ); + + return m_Plugin->GetFunction("OnLogin").Evaluate(a_PacketData); +} + + + + + +void cPlugin_Squirrel::OnPlayerSpawn( cPlayer* a_Player ) +{ + cCSLock Lock( m_CriticalSection ); + + return m_Plugin->GetFunction("OnPlayerSpawn").Execute(a_Player); + +} + + + + + +bool cPlugin_Squirrel::OnPlayerJoin( cPlayer* a_Player ) +{ + cCSLock Lock( m_CriticalSection ); + + return m_Plugin->GetFunction("OnPlayerJoin").Evaluate(a_Player); +} + + + + + +void cPlugin_Squirrel::OnPlayerMove( cPlayer* a_Player ) +{ + cCSLock Lock( m_CriticalSection ); + + return m_Plugin->GetFunction("OnPlayerMove").Execute(a_Player); + +} + + + + + +void cPlugin_Squirrel::OnTakeDamage( cPawn* a_Pawn, TakeDamageInfo* a_TakeDamageInfo ) +{ + cCSLock Lock( m_CriticalSection ); + + return m_Plugin->GetFunction("OnTakeDamage")(a_Pawn, a_TakeDamageInfo); +} + + + + + +bool cPlugin_Squirrel::OnKilled( cPawn* a_Killed, cEntity* a_Killer ) +{ + cCSLock Lock( m_CriticalSection ); + + return m_Plugin->GetFunction("OnKilled").Evaluate(a_Killed, a_Killer); +} + + + + + +void cPlugin_Squirrel::OnChunkGenerated(cWorld * a_World, int a_ChunkX, int a_ChunkZ) +{ + cCSLock Lock(m_CriticalSection); + + return m_Plugin->GetFunction("OnChunkGenerated")(a_World, a_ChunkX, a_ChunkZ); +} + + + + + +bool cPlugin_Squirrel::OnChunkGenerating(cWorld * a_World, int a_ChunkX, int a_ChunkZ, cLuaChunk * a_pLuaChunk) +{ + cCSLock Lock(m_CriticalSection); + + return m_Plugin->GetFunction("OnChunkGenerating").Evaluate(a_World, a_ChunkX, a_ChunkZ, a_pLuaChunk); +} + + + + + +bool cPlugin_Squirrel::OnPreCrafting(const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe) +{ + cCSLock Lock(m_CriticalSection); + + return m_Plugin->GetFunction("OnPreCrafting").Evaluate((cPlayer *) a_Player, (cCraftingGrid *) a_Grid, a_Recipe); + +} + + + + + +bool cPlugin_Squirrel::OnCraftingNoRecipe(const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe) +{ + cCSLock Lock(m_CriticalSection); + + return m_Plugin->GetFunction("OnCraftingNoRecipe").Evaluate((cPlayer *) a_Player, (cCraftingGrid *) a_Grid, a_Recipe); +} + + + + + +bool cPlugin_Squirrel::OnPostCrafting(const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe) +{ + cCSLock Lock(m_CriticalSection); + + + return m_Plugin->GetFunction("OnPostCrafting").Evaluate((cPlayer *) a_Player, (cCraftingGrid *) a_Grid, a_Recipe); +} + + + + + +bool cPlugin_Squirrel::OnBlockToPickup( + BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, + const cPlayer * a_Player, const cItem & a_EquippedItem, cItems & a_Pickups +) +{ + cCSLock Lock(m_CriticalSection); + + + return m_Plugin->GetFunction("OnBlockToPickup").Evaluate(a_BlockType, a_BlockMeta, (cPlayer *) a_Player, a_EquippedItem, a_Pickups); + +} + + + + + +bool cPlugin_Squirrel::OnWeatherChanged(cWorld * a_World) +{ + cCSLock Lock(m_CriticalSection); + + + return m_Plugin->GetFunction("OnWeatherChanged").Evaluate(a_World); +} + + + + + +bool cPlugin_Squirrel::OnUpdatingSign( + cWorld * a_World, + int a_BlockX, int a_BlockY, int a_BlockZ, + AString & a_Line1, AString & a_Line2, AString & a_Line3, AString & a_Line4 +) +{ + cCSLock Lock(m_CriticalSection); + + + return m_Plugin->GetFunction("OnUpdatingSign") + .Evaluate( + a_World, + a_BlockX, + a_BlockY, + a_BlockZ, + a_Line1, + a_Line2, + a_Line3, + a_Line4 + ); +} + + + + + +bool cPlugin_Squirrel::OnUpdatedSign( + cWorld * a_World, + int a_BlockX, int a_BlockY, int a_BlockZ, + const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4 +) +{ + return m_Plugin->GetFunction("OnUpdatedSign") + .Evaluate( + a_World, + a_BlockX, + a_BlockY, + a_BlockZ, + a_Line1, + a_Line2, + a_Line3, + a_Line4 + ); +} diff --git a/source/cPlugin_Squirrel.h b/source/cPlugin_Squirrel.h new file mode 100644 index 000000000..cd05e117a --- /dev/null +++ b/source/cPlugin_Squirrel.h @@ -0,0 +1,42 @@ +#pragma once +#include "cPlugin.h" +#include +#include "squirrelbindings/SquirrelObject.h" + +class cPlugin_Squirrel : public cPlugin +{ +public: + cPlugin_Squirrel(const char* a_PluginName); + ~cPlugin_Squirrel(); + + void OnDisable(); + bool Initialize(); + + void Tick(float a_Dt); + + bool OnCollectItem (cPickup* a_Pickup, cPlayer* a_Player ) override; + bool OnDisconnect (const AString & a_Reason, cPlayer * a_Player ) override; + bool OnBlockPlace (cPacket_BlockPlace* a_PacketData, cPlayer* a_Player ) override; + bool OnBlockDig (cPacket_BlockDig* a_PacketData, cPlayer* a_Player, cItem* a_PickupItem ) override; + bool OnChat (const char* a_Chat, cPlayer* a_Player ) override; + bool OnLogin (cPacket_Login* a_PacketData ) override; + void OnPlayerSpawn (cPlayer* a_Player ) override; + bool OnPlayerJoin (cPlayer* a_Player ) override; + void OnPlayerMove (cPlayer* a_Player ) override; + void OnTakeDamage (cPawn* a_Pawn, TakeDamageInfo* a_TakeDamageInfo ) override; + bool OnKilled (cPawn* a_Killed, cEntity* a_Killer ) override; + void OnChunkGenerated (cWorld * a_World, int a_ChunkX, int a_ChunkZ) override; + bool OnChunkGenerating (cWorld * a_World, int a_ChunkX, int a_ChunkZ, cLuaChunk * a_pLuaChunk ) override; + bool OnPreCrafting (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe) override; + bool OnCraftingNoRecipe(const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe) override; + bool OnPostCrafting (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe) override; + bool OnBlockToPickup (BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, const cPlayer * a_Player, const cItem & a_EquippedItem, cItems & a_Pickups); + bool OnWeatherChanged (cWorld * a_World) override; + bool OnUpdatingSign (cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, AString & a_Line1, AString & a_Line2, AString & a_Line3, AString & a_Line4) override; + bool OnUpdatedSign (cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4) override; + +protected: + const char * m_PluginName; + cCriticalSection m_CriticalSection; + SquirrelObject *m_Plugin; +}; \ No newline at end of file diff --git a/source/cVine.h b/source/cVine.h index a99a98aca..d4bc99c1a 100644 --- a/source/cVine.h +++ b/source/cVine.h @@ -19,6 +19,5 @@ public: default: return 0xf; }; - return 0xf; } //tolua_export }; //tolua_export \ No newline at end of file diff --git a/source/main.cpp b/source/main.cpp index d379fdd17..03dea6f01 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -6,16 +6,17 @@ #include //std::exception #include //std::signal #include //exit() +#include "squirrelbindings/SquirrelFunctions.h" #ifdef _WIN32 #include #endif // _WIN32 -#include "SquirrelBindings.h" +#include "squirrelbindings/SquirrelBindings.h" #if USE_SQUIRREL #pragma warning(push) #pragma warning(disable:4100;disable:4127;disable:4510;disable:4610;disable:4244;disable:4512) // Getting A LOT of these warnings from SqPlus - #include + #pragma warning(pop) #endif @@ -189,7 +190,7 @@ int main( int argc, char **argv ) } #if USE_SQUIRREL - SquirrelVM::Shutdown(); + CloseSquirrelVM(); #endif #if defined(_MSC_VER) && defined(_DEBUG) && defined(ENABLE_LEAK_FINDER) diff --git a/source/squirrelbindings/SquirrelBindings.cpp b/source/squirrelbindings/SquirrelBindings.cpp new file mode 100644 index 000000000..27a82c306 --- /dev/null +++ b/source/squirrelbindings/SquirrelBindings.cpp @@ -0,0 +1,52 @@ +#include "Globals.h" +#include "SquirrelBindings.h" +#include "SquirrelFunctions.h" + +#include "cSquirrelBaseClass.h" + +#include "../cPlayer.h" + +using namespace Sqrat; + + + +void BindSquirrel(HSQUIRRELVM vm) +{ + RootTable() + .Bind("Plugin", Class() + .Func("AddHook", &cSquirrelBaseClass::AddHook) + ); + RootTable().Bind("cPlayer", Class() + .Func("GetName", &cPlayer::GetName) + ); + + + RootTable().Func("print", &sqPrint); + + + ConstTable().Enum("Hook", Enumeration() + .Const("Tick", cPluginManager::HOOK_TICK) + .Const("Chat", cPluginManager::HOOK_CHAT) + .Const("CollectItem", cPluginManager::HOOK_COLLECT_ITEM) + .Const("BlockDig", cPluginManager::HOOK_BLOCK_DIG) + .Const("BlockPlace", cPluginManager::HOOK_BLOCK_PLACE) + .Const("Disconnect", cPluginManager::HOOK_DISCONNECT) + .Const("Handshake", cPluginManager::HOOK_HANDSHAKE) + .Const("Login", cPluginManager::HOOK_LOGIN) + .Const("PlayerSpawn", cPluginManager::HOOK_PLAYER_SPAWN) + .Const("PlayerJoin", cPluginManager::HOOK_PLAYER_JOIN) + .Const("PlayerMove", cPluginManager::HOOK_PLAYER_MOVE) + .Const("TakeDamage", cPluginManager::HOOK_TAKE_DAMAGE) + .Const("Killed", cPluginManager::HOOK_KILLED) + .Const("ChunkGenerated", cPluginManager::HOOK_CHUNK_GENERATED) + .Const("ChunkGenerating", cPluginManager::HOOK_CHUNK_GENERATING) + .Const("BlockToDrops", cPluginManager::HOOK_BLOCK_TO_DROPS) + .Const("PreCrafting", cPluginManager::HOOK_PRE_CRAFTING) + .Const("CraftingNoRecipe", cPluginManager::HOOK_CRAFTING_NO_RECIPE) + .Const("PostCrafting", cPluginManager::HOOK_POST_CRAFTING) + .Const("BlockToPickup", cPluginManager::HOOK_BLOCK_TO_PICKUP) + .Const("WeatherChanged", cPluginManager::HOOK_WEATHER_CHANGED) + .Const("UpdatingSign", cPluginManager::HOOK_UPDATING_SIGN) + .Const("UpdatedSign", cPluginManager::HOOK_UPDATED_SIGN)); + +} \ No newline at end of file diff --git a/source/squirrelbindings/SquirrelBindings.h b/source/squirrelbindings/SquirrelBindings.h new file mode 100644 index 000000000..1b71f5e86 --- /dev/null +++ b/source/squirrelbindings/SquirrelBindings.h @@ -0,0 +1,13 @@ +#pragma once + + +#define USE_SQUIRREL 1 + +#if USE_SQUIRREL + +#include +#include + +void BindSquirrel(HSQUIRRELVM vm); + +#endif diff --git a/source/squirrelbindings/SquirrelFunctions.cpp b/source/squirrelbindings/SquirrelFunctions.cpp new file mode 100644 index 000000000..88871369d --- /dev/null +++ b/source/squirrelbindings/SquirrelFunctions.cpp @@ -0,0 +1,65 @@ + +#include "Globals.h" +#include "SquirrelFunctions.h" +#include "SquirrelBindings.h" + +static HSQUIRRELVM squirrelvm = NULL; + +SQInteger runtimeErrorHandler(HSQUIRRELVM a_VM) +{ + const SQChar *sErr = 0; + if(sq_gettop(a_VM) >= 1) + { + if(SQ_SUCCEEDED(sq_getstring(a_VM, 2, &sErr))) + { + LOGERROR("Squirrel Error: %s", sErr); + } + else + { + LOGERROR("Squirrel Error: Unknown Error"); + } + } + return 0; +} + +void compilerErrorHandler(HSQUIRRELVM v, + const SQChar* a_Desc, + const SQChar* a_Source, + SQInteger a_Line, + SQInteger a_Column) +{ + + LOGERROR("Squirrel Error: %s (%d:%d) %s", a_Source, a_Line, a_Column, a_Desc); +} + +HSQUIRRELVM OpenSquirrelVM() +{ + if(!squirrelvm) + { + squirrelvm = sq_open(1024); + Sqrat::DefaultVM::Set(squirrelvm); + + sq_newclosure(squirrelvm, runtimeErrorHandler, 0); + sq_seterrorhandler(squirrelvm); + + sq_setcompilererrorhandler(squirrelvm, compilerErrorHandler); + + BindSquirrel(squirrelvm); + } + return squirrelvm; +} + +void CloseSquirrelVM() +{ + if(squirrelvm) + { + sq_close(squirrelvm); + squirrelvm = NULL; + } +} + + +void sqPrint(SQChar * text) +{ + LOGINFO("%s", text); +} \ No newline at end of file diff --git a/source/squirrelbindings/SquirrelFunctions.h b/source/squirrelbindings/SquirrelFunctions.h new file mode 100644 index 000000000..0d08a726c --- /dev/null +++ b/source/squirrelbindings/SquirrelFunctions.h @@ -0,0 +1,6 @@ +#pragma once +#include +HSQUIRRELVM OpenSquirrelVM(); +void CloseSquirrelVM(); + +void sqPrint(SQChar * text); \ No newline at end of file diff --git a/source/squirrelbindings/SquirrelObject.h b/source/squirrelbindings/SquirrelObject.h new file mode 100644 index 000000000..1ac6fa105 --- /dev/null +++ b/source/squirrelbindings/SquirrelObject.h @@ -0,0 +1,24 @@ +#pragma once +#include + +class SquirrelObject +{ +public: + SquirrelObject(Sqrat::Object a_Obj) + { + m_SquirrelObject = a_Obj; + } + + Sqrat::Function GetFunction(const char *methodName) + { + if(m_SquirrelObject.IsNull()) + return Sqrat::Function(); + + Sqrat::Function method(m_SquirrelObject, methodName); + return method; + } + +protected: + Sqrat::Object m_SquirrelObject; + +}; \ No newline at end of file diff --git a/source/squirrelbindings/cSquirrelBaseClass.h b/source/squirrelbindings/cSquirrelBaseClass.h new file mode 100644 index 000000000..e06301555 --- /dev/null +++ b/source/squirrelbindings/cSquirrelBaseClass.h @@ -0,0 +1,29 @@ +#pragma once +#include "SquirrelBindings.h" +#include "../cPlugin_Squirrel.h" +#include "../cPluginManager.h" +#include "cRoot.h" + +//The baseclass for squirrel plugins +class cSquirrelBaseClass +{ +public: + cSquirrelBaseClass() + : m_Instance(0) + { + } + + void setInstance(cPlugin_Squirrel *a_Instance) + { + m_Instance = a_Instance; + } + + void AddHook(short a_Hook) + { + if(m_Instance) + cRoot::Get()->GetPluginManager()->AddHook(m_Instance, (cPluginManager::PluginHook) a_Hook); + } + +protected: + cPlugin_Squirrel *m_Instance; +}; \ No newline at end of file diff --git a/squirrel_3_0_1_stable/sqplus/Makefile b/squirrel_3_0_1_stable/_OLD_sqplus/Makefile similarity index 100% rename from squirrel_3_0_1_stable/sqplus/Makefile rename to squirrel_3_0_1_stable/_OLD_sqplus/Makefile diff --git a/squirrel_3_0_1_stable/sqplus/SqPlus.cpp b/squirrel_3_0_1_stable/_OLD_sqplus/SqPlus.cpp similarity index 96% rename from squirrel_3_0_1_stable/sqplus/SqPlus.cpp rename to squirrel_3_0_1_stable/_OLD_sqplus/SqPlus.cpp index a2eaacb72..3fdf99735 100644 --- a/squirrel_3_0_1_stable/sqplus/SqPlus.cpp +++ b/squirrel_3_0_1_stable/_OLD_sqplus/SqPlus.cpp @@ -1,382 +1,382 @@ -#include "sqplus.h" -#include - -#ifdef SQPLUS_SMARTPOINTER_OPT -#define SQPLUS_SMARTPOINTER_CPP_DECLARATION -#include "SqPlusSmartPointer.h" -#endif - -namespace SqPlus { - -static int getVarInfo(StackHandler & sa,VarRefPtr & vr) { - HSQOBJECT htable = sa.GetObjectHandle(1); - SquirrelObject table(htable); - const SQChar * el = sa.GetString(2); - ScriptStringVar256 varNameTag; - getVarNameTag(varNameTag,sizeof(varNameTag),el); - SQUserPointer data=0; - if (!table.RawGetUserData(varNameTag,&data)) { - return sa.ThrowError(_SC("getVarInfo: Could not retrieve UserData")); // Results in variable not being found error. - } - vr = (VarRefPtr)data; - return SQ_OK; -} // getVarInfo - -static int getInstanceVarInfo(StackHandler & sa,VarRefPtr & vr,SQUserPointer & data) { - HSQOBJECT ho = sa.GetObjectHandle(1); - SquirrelObject instance(ho); - const SQChar * el = sa.GetString(2); - ScriptStringVar256 varNameTag; - getVarNameTag(varNameTag,sizeof(varNameTag),el); - SQUserPointer ivrData=0; - if (!instance.RawGetUserData(varNameTag,&ivrData)) { - return sa.ThrowError(_SC("getInstanceVarInfo: Could not retrieve UserData")); // Results in variable not being found error. - } - vr = (VarRefPtr)ivrData; - - char * up; - if (!(vr->m_access & (VAR_ACCESS_STATIC|VAR_ACCESS_CONSTANT))) { - SQUserPointer typetag; - instance.GetTypeTag(&typetag); - -#if defined(SQ_USE_CLASS_INHERITANCE) - if (typetag != vr->instanceType) { - SquirrelObject typeTable = instance.GetValue(SQ_CLASS_OBJECT_TABLE_NAME); - up = (char *)typeTable.GetUserPointer(INT((size_t)vr->instanceType)); // 64-bit compatible version. - if (!up) { - throw SquirrelError(_SC("Invalid Instance Type")); - } - } else { - up = (char *)instance.GetInstanceUP(0); - } // if - -#elif defined(SQ_USE_CLASS_INHERITANCE_SIMPLE) - ClassTypeBase *ctb = (ClassTypeBase*)vr->instanceType; - up = (char *)instance.GetInstanceUP(0); - // Walk base classes until type tag match, adjust for inheritence offset - while(ctb && typetag!=ctb) { - up = (char*)up - ctb->m_offset; - ctb = ctb->m_pbase; - } - if (!ctb) { - throw SquirrelError(_SC("Invalid Instance Type")); - } -#else - up = (char *)instance.GetInstanceUP(0); -#endif - -#ifdef SQPLUS_SMARTPOINTER_OPT -#define SQPLUS_SMARTPOINTER_INSTANCE_VARINFO -#include "SqPlusSmartPointer.h" -#endif - - up += (size_t)vr->offsetOrAddrOrConst; // Offset - } else { - up = (char *)vr->offsetOrAddrOrConst; // Address - } // if - data = up; - return SQ_OK; -} // getInstanceVarInfo - - -// If not static/global, message can (and will) disappear before arriving at catch (G++) -static ScriptStringVar256 g_msg_throw; - -static int setVar(StackHandler & sa,VarRef * vr,void * data) { - if (vr->m_access & (VAR_ACCESS_READ_ONLY|VAR_ACCESS_CONSTANT)) { - const SQChar * el = sa.GetString(2); - SCSNPRINTF(g_msg_throw.s,sizeof(g_msg_throw),_SC("setVar(): Cannot write to constant: %s"),el); - throw SquirrelError(g_msg_throw.s); - } // if - switch (vr->m_type) { - case TypeInfo::TypeID: { - INT * val = (INT *)data; // Address - if (val) { - INT v = sa.GetInt(3); - // Support for different int sizes - switch( vr->m_size ) { - case 1: v = (*(char*)val = (char)v); break; - case 2: v = (*(short*)val = (short)v); break; -#ifdef _SQ64 - case 4: v = (*(int*)val = (int)v); break; -#endif - default: *val = v; - } - return sa.Return(v); - } // if - break; - } // case - case TypeInfo::TypeID: { - unsigned * val = (unsigned *)data; // Address - if (val) { - *val = sa.GetInt(3); - return sa.Return(static_cast(*val)); - } // if - break; - } // case - case TypeInfo::TypeID: { - FLOAT * val = (FLOAT *)data; // Address - if (val) { - *val = sa.GetFloat(3); - return sa.Return(*val); - } // if - break; - } // case - case TypeInfo::TypeID: { - bool * val = (bool *)data; // Address - if (val) { - *val = sa.GetBool(3) ? true : false; - return sa.Return(*val); - } // if - break; - } // case - case VAR_TYPE_INSTANCE: { - HSQUIRRELVM v = sa.GetVMPtr(); - SQUserPointer src = sa.GetInstanceUp(3,(SQUserPointer)vr->varType); // Effectively performs: ClassType<>::type() == ClassType<>(). - if (!src) { - throw SquirrelError(_SC("INSTANCE type assignment mismatch")); - } - vr->varType->vgetCopyFunc()(data,src); - return 0; - } - case TypeInfo::TypeID: { - const SQChar * el = sa.GetString(2); - SCSNPRINTF(g_msg_throw.s,sizeof(g_msg_throw),_SC("setVar(): Cannot write to an SQUserPointer: %s"),el); - throw SquirrelError(g_msg_throw.s); - } // case - case TypeInfo::TypeID: { - ScriptStringVarBase * val = (ScriptStringVarBase *)data; // Address - if (val) { - const SQChar * strVal = sa.GetString(3); - if (strVal) { - *val = strVal; - return sa.Return(val->s); - } // if - } // if - break; - } // case -#if defined(SQPLUS_SUPPORT_STD_STRING) && !defined(SQUNICODE) - case TypeInfo::TypeID: { - std::string *val = (std::string*)data; // Address - if (val) { - const SQChar *strVal = sa.GetString(3); - if (strVal) { - *val = strVal; - return sa.Return(val->c_str()); - } // if - } // if - break; - } // case -#endif - } // switch - return SQ_ERROR; -} // setVar - -static int getVar(StackHandler & sa,VarRef * vr,void * data) { - switch (vr->m_type) { - case TypeInfo::TypeID: { - if (!(vr->m_access & VAR_ACCESS_CONSTANT)) { - if (data) { - INT v; - // Support for different int sizes - switch( vr->m_size ){ - case 1: v = *(char*)data; break; - case 2: v = *(short*)data; break; -#ifdef _SQ64 - case 4: v = *(int*)data; break; -#endif - default: v = *(INT*)data; - } - return sa.Return(v); - } // if - } else { - INT * val = (INT *)&data; // Constant value - return sa.Return(*val); - } // if - break; - } // case - case TypeInfo::TypeID: { - if (!(vr->m_access & VAR_ACCESS_CONSTANT)) { - unsigned * val = (unsigned *)data; // Address - if (val){ - return sa.Return(static_cast(*val)); - } - } else { - unsigned * val = (unsigned *)&data; // Constant value - return sa.Return(static_cast(*val)); - } // if - break; - } // case - case TypeInfo::TypeID: { - if (!(vr->m_access & VAR_ACCESS_CONSTANT)) { - FLOAT * val = (FLOAT *)data; // Address - if (val) { - return sa.Return(*val); - } // if - } else { - FLOAT * val = (FLOAT *)&data; // Constant value - return sa.Return(*val); - } // if - break; - } // case - case TypeInfo::TypeID: { - if (!(vr->m_access & VAR_ACCESS_CONSTANT)) { - bool * val = (bool *)data; // Address - if (val) { - return sa.Return(*val); - } // if - } else { - bool * val = (bool *)&data; // Constant value - return sa.Return(*val); - } // if - break; - } // case - case VAR_TYPE_INSTANCE: - if (!CreateNativeClassInstance(sa.GetVMPtr(),vr->varType->GetTypeName(),data,0)) { // data = address. Allocates memory. - SCSNPRINTF(g_msg_throw.s,sizeof(g_msg_throw),_SC("getVar(): Could not create instance: %s"),vr->varType->GetTypeName()); - throw SquirrelError(g_msg_throw.s); - } // if - return 1; - case TypeInfo::TypeID: - return sa.Return(data); // The address of member variable, not the variable itself. - case TypeInfo::TypeID: { - if (!(vr->m_access & VAR_ACCESS_CONSTANT)) { - ScriptStringVarBase * val = (ScriptStringVarBase *)data; // Address - if (val) { - return sa.Return(val->s); - } // if - } else { - throw SquirrelError(_SC("getVar(): Invalid type+access: 'ScriptStringVarBase' with VAR_ACCESS_CONSTANT (use VAR_ACCESS_READ_ONLY instead)")); - } - break; - } // case - case TypeInfo::TypeID: { - if (!(vr->m_access & VAR_ACCESS_CONSTANT)) { - if( vr->m_access==VAR_ACCESS_READ_WRITE ) - throw SquirrelError(_SC("getVar(): Invalid type+access: 'const SQChar *' without VAR_ACCESS_CONSTANT")); - // It is OK to read from a SQChar* if requested - return sa.Return(*(const SQChar **)data); // Address - } else { - return sa.Return((const SQChar *)data); // Address - } - break; - } // case -#ifdef SQPLUS_SUPPORT_STD_STRING - case TypeInfo::TypeID: { - if (!(vr->m_access & VAR_ACCESS_CONSTANT)) { - std::string *val = (std::string *)data; // Address - if (val) { - return sa.Return(val->c_str()); - } - } else { - throw SquirrelError(_SC("getVar(): Invalid type+access: 'std::string' with VAR_ACCESS_CONSTANT (use VAR_ACCESS_READ_ONLY instead)")); - } - break; - } // case -#endif - } // switch - return SQ_ERROR; -} // getVar - -// === Global Vars === - -int setVarFunc(HSQUIRRELVM v) { - SquirrelVM::Init(v); // For handling multi-VM setting right - StackHandler sa(v); - if (sa.GetType(1) == OT_TABLE) { - VarRefPtr vr; - int res = getVarInfo(sa,vr); - if (res != SQ_OK) return res; - return setVar(sa,vr,vr->offsetOrAddrOrConst); - } // if - return SQ_ERROR; -} // setVarFunc - -int getVarFunc(HSQUIRRELVM v) { - SquirrelVM::Init(v); // For handling multi-VM setting right - StackHandler sa(v); - if (sa.GetType(1) == OT_TABLE) { - VarRefPtr vr; - int res = getVarInfo(sa,vr); - if (res != SQ_OK) return res; - return getVar(sa,vr,vr->offsetOrAddrOrConst); - } // if - return SQ_ERROR; -} // getVarFunc - -// === Instance Vars === - -int setInstanceVarFunc(HSQUIRRELVM v) { - SquirrelVM::Init(v); // For handling multi-VM setting right - StackHandler sa(v); - if (sa.GetType(1) == OT_INSTANCE) { - VarRefPtr vr; - void * data; - int res = getInstanceVarInfo(sa,vr,data); - if (res != SQ_OK) return res; - return setVar(sa,vr,data); - } // if - return SQ_ERROR; -} // setInstanceVarFunc - -int getInstanceVarFunc(HSQUIRRELVM v) { - SquirrelVM::Init(v); // For handling multi-VM setting right - StackHandler sa(v); - if (sa.GetType(1) == OT_INSTANCE) { - VarRefPtr vr; - void * data; - int res = getInstanceVarInfo(sa,vr,data); - if (res != SQ_OK) return res; - return getVar(sa,vr,data); - } // if - return SQ_ERROR; -} // getInstanceVarFunc - -// === Classes === - -BOOL CreateClass(HSQUIRRELVM v,SquirrelObject & newClass,SQUserPointer classType,const SQChar * name,const SQChar * baseName) { - int n = 0; - int oldtop = sq_gettop(v); - sq_pushroottable(v); - sq_pushstring(v,name,-1); - if (baseName) { - sq_pushstring(v,baseName,-1); - if (SQ_FAILED(sq_get(v,-3))) { // Make sure the base exists if specified by baseName. - sq_settop(v,oldtop); - return FALSE; - } // if - } // if - if (SQ_FAILED(sq_newclass(v,baseName ? 1 : 0))) { // Will inherit from base class on stack from sq_get() above. - sq_settop(v,oldtop); - return FALSE; - } // if - newClass.AttachToStackObject(-1); - sq_settypetag(v,-1,classType); - sq_createslot(v,-3); - sq_pop(v,1); - return TRUE; -} // CreateClass - -SquirrelObject RegisterClassType(HSQUIRRELVM v,const SQChar * scriptClassName,SQUserPointer classType,SQFUNCTION constructor) { - SquirrelVM::Init(v); // For handling multi-VM setting right - int top = sq_gettop(v); - SquirrelObject newClass; - if (CreateClass(v,newClass,classType,scriptClassName)) { - SquirrelVM::CreateFunction(newClass,constructor,_SC("constructor")); - } // if - sq_settop(v,top); - return newClass; -} // RegisterClassType - - -/////////////////////////////////////////////////////////////////////////// -// GCC sometimes has problems with finding inline functions at link time -// (that also have a template definition). To solve the problem, -// non-inlines goes here. -#ifdef GCC_INLINE_WORKAROUND -# include "SqPlusFunctionCallImpl.h" -#endif // GCC_INLINE_WORKAROUND -/////////////////////////////////////////////////////////////////////////// - -} // namespace SqPlus - +#include "sqplus.h" +#include + +#ifdef SQPLUS_SMARTPOINTER_OPT +#define SQPLUS_SMARTPOINTER_CPP_DECLARATION +#include "SqPlusSmartPointer.h" +#endif + +namespace SqPlus { + +static int getVarInfo(StackHandler & sa,VarRefPtr & vr) { + HSQOBJECT htable = sa.GetObjectHandle(1); + SquirrelObject table(htable); + const SQChar * el = sa.GetString(2); + ScriptStringVar256 varNameTag; + getVarNameTag(varNameTag,sizeof(varNameTag),el); + SQUserPointer data=0; + if (!table.RawGetUserData(varNameTag,&data)) { + return sa.ThrowError(_SC("getVarInfo: Could not retrieve UserData")); // Results in variable not being found error. + } + vr = (VarRefPtr)data; + return SQ_OK; +} // getVarInfo + +static int getInstanceVarInfo(StackHandler & sa,VarRefPtr & vr,SQUserPointer & data) { + HSQOBJECT ho = sa.GetObjectHandle(1); + SquirrelObject instance(ho); + const SQChar * el = sa.GetString(2); + ScriptStringVar256 varNameTag; + getVarNameTag(varNameTag,sizeof(varNameTag),el); + SQUserPointer ivrData=0; + if (!instance.RawGetUserData(varNameTag,&ivrData)) { + return sa.ThrowError(_SC("getInstanceVarInfo: Could not retrieve UserData")); // Results in variable not being found error. + } + vr = (VarRefPtr)ivrData; + + char * up; + if (!(vr->m_access & (VAR_ACCESS_STATIC|VAR_ACCESS_CONSTANT))) { + SQUserPointer typetag; + instance.GetTypeTag(&typetag); + +#if defined(SQ_USE_CLASS_INHERITANCE) + if (typetag != vr->instanceType) { + SquirrelObject typeTable = instance.GetValue(SQ_CLASS_OBJECT_TABLE_NAME); + up = (char *)typeTable.GetUserPointer(INT((size_t)vr->instanceType)); // 64-bit compatible version. + if (!up) { + throw SquirrelError(_SC("Invalid Instance Type")); + } + } else { + up = (char *)instance.GetInstanceUP(0); + } // if + +#elif defined(SQ_USE_CLASS_INHERITANCE_SIMPLE) + ClassTypeBase *ctb = (ClassTypeBase*)vr->instanceType; + up = (char *)instance.GetInstanceUP(0); + // Walk base classes until type tag match, adjust for inheritence offset + while(ctb && typetag!=ctb) { + up = (char*)up - ctb->m_offset; + ctb = ctb->m_pbase; + } + if (!ctb) { + throw SquirrelError(_SC("Invalid Instance Type")); + } +#else + up = (char *)instance.GetInstanceUP(0); +#endif + +#ifdef SQPLUS_SMARTPOINTER_OPT +#define SQPLUS_SMARTPOINTER_INSTANCE_VARINFO +#include "SqPlusSmartPointer.h" +#endif + + up += (size_t)vr->offsetOrAddrOrConst; // Offset + } else { + up = (char *)vr->offsetOrAddrOrConst; // Address + } // if + data = up; + return SQ_OK; +} // getInstanceVarInfo + + +// If not static/global, message can (and will) disappear before arriving at catch (G++) +static ScriptStringVar256 g_msg_throw; + +static int setVar(StackHandler & sa,VarRef * vr,void * data) { + if (vr->m_access & (VAR_ACCESS_READ_ONLY|VAR_ACCESS_CONSTANT)) { + const SQChar * el = sa.GetString(2); + SCSNPRINTF(g_msg_throw.s,sizeof(g_msg_throw),_SC("setVar(): Cannot write to constant: %s"),el); + throw SquirrelError(g_msg_throw.s); + } // if + switch (vr->m_type) { + case TypeInfo::TypeID: { + INT * val = (INT *)data; // Address + if (val) { + INT v = sa.GetInt(3); + // Support for different int sizes + switch( vr->m_size ) { + case 1: v = (*(char*)val = (char)v); break; + case 2: v = (*(short*)val = (short)v); break; +#ifdef _SQ64 + case 4: v = (*(int*)val = (int)v); break; +#endif + default: *val = v; + } + return sa.Return(v); + } // if + break; + } // case + case TypeInfo::TypeID: { + unsigned * val = (unsigned *)data; // Address + if (val) { + *val = sa.GetInt(3); + return sa.Return(static_cast(*val)); + } // if + break; + } // case + case TypeInfo::TypeID: { + FLOAT * val = (FLOAT *)data; // Address + if (val) { + *val = sa.GetFloat(3); + return sa.Return(*val); + } // if + break; + } // case + case TypeInfo::TypeID: { + bool * val = (bool *)data; // Address + if (val) { + *val = sa.GetBool(3) ? true : false; + return sa.Return(*val); + } // if + break; + } // case + case VAR_TYPE_INSTANCE: { + HSQUIRRELVM v = sa.GetVMPtr(); + SQUserPointer src = sa.GetInstanceUp(3,(SQUserPointer)vr->varType); // Effectively performs: ClassType<>::type() == ClassType<>(). + if (!src) { + throw SquirrelError(_SC("INSTANCE type assignment mismatch")); + } + vr->varType->vgetCopyFunc()(data,src); + return 0; + } + case TypeInfo::TypeID: { + const SQChar * el = sa.GetString(2); + SCSNPRINTF(g_msg_throw.s,sizeof(g_msg_throw),_SC("setVar(): Cannot write to an SQUserPointer: %s"),el); + throw SquirrelError(g_msg_throw.s); + } // case + case TypeInfo::TypeID: { + ScriptStringVarBase * val = (ScriptStringVarBase *)data; // Address + if (val) { + const SQChar * strVal = sa.GetString(3); + if (strVal) { + *val = strVal; + return sa.Return(val->s); + } // if + } // if + break; + } // case +#if defined(SQPLUS_SUPPORT_STD_STRING) && !defined(SQUNICODE) + case TypeInfo::TypeID: { + std::string *val = (std::string*)data; // Address + if (val) { + const SQChar *strVal = sa.GetString(3); + if (strVal) { + *val = strVal; + return sa.Return(val->c_str()); + } // if + } // if + break; + } // case +#endif + } // switch + return SQ_ERROR; +} // setVar + +static int getVar(StackHandler & sa,VarRef * vr,void * data) { + switch (vr->m_type) { + case TypeInfo::TypeID: { + if (!(vr->m_access & VAR_ACCESS_CONSTANT)) { + if (data) { + INT v; + // Support for different int sizes + switch( vr->m_size ){ + case 1: v = *(char*)data; break; + case 2: v = *(short*)data; break; +#ifdef _SQ64 + case 4: v = *(int*)data; break; +#endif + default: v = *(INT*)data; + } + return sa.Return(v); + } // if + } else { + INT * val = (INT *)&data; // Constant value + return sa.Return(*val); + } // if + break; + } // case + case TypeInfo::TypeID: { + if (!(vr->m_access & VAR_ACCESS_CONSTANT)) { + unsigned * val = (unsigned *)data; // Address + if (val){ + return sa.Return(static_cast(*val)); + } + } else { + unsigned * val = (unsigned *)&data; // Constant value + return sa.Return(static_cast(*val)); + } // if + break; + } // case + case TypeInfo::TypeID: { + if (!(vr->m_access & VAR_ACCESS_CONSTANT)) { + FLOAT * val = (FLOAT *)data; // Address + if (val) { + return sa.Return(*val); + } // if + } else { + FLOAT * val = (FLOAT *)&data; // Constant value + return sa.Return(*val); + } // if + break; + } // case + case TypeInfo::TypeID: { + if (!(vr->m_access & VAR_ACCESS_CONSTANT)) { + bool * val = (bool *)data; // Address + if (val) { + return sa.Return(*val); + } // if + } else { + bool * val = (bool *)&data; // Constant value + return sa.Return(*val); + } // if + break; + } // case + case VAR_TYPE_INSTANCE: + if (!CreateNativeClassInstance(sa.GetVMPtr(),vr->varType->GetTypeName(),data,0)) { // data = address. Allocates memory. + SCSNPRINTF(g_msg_throw.s,sizeof(g_msg_throw),_SC("getVar(): Could not create instance: %s"),vr->varType->GetTypeName()); + throw SquirrelError(g_msg_throw.s); + } // if + return 1; + case TypeInfo::TypeID: + return sa.Return(data); // The address of member variable, not the variable itself. + case TypeInfo::TypeID: { + if (!(vr->m_access & VAR_ACCESS_CONSTANT)) { + ScriptStringVarBase * val = (ScriptStringVarBase *)data; // Address + if (val) { + return sa.Return(val->s); + } // if + } else { + throw SquirrelError(_SC("getVar(): Invalid type+access: 'ScriptStringVarBase' with VAR_ACCESS_CONSTANT (use VAR_ACCESS_READ_ONLY instead)")); + } + break; + } // case + case TypeInfo::TypeID: { + if (!(vr->m_access & VAR_ACCESS_CONSTANT)) { + if( vr->m_access==VAR_ACCESS_READ_WRITE ) + throw SquirrelError(_SC("getVar(): Invalid type+access: 'const SQChar *' without VAR_ACCESS_CONSTANT")); + // It is OK to read from a SQChar* if requested + return sa.Return(*(const SQChar **)data); // Address + } else { + return sa.Return((const SQChar *)data); // Address + } + break; + } // case +#ifdef SQPLUS_SUPPORT_STD_STRING + case TypeInfo::TypeID: { + if (!(vr->m_access & VAR_ACCESS_CONSTANT)) { + std::string *val = (std::string *)data; // Address + if (val) { + return sa.Return(val->c_str()); + } + } else { + throw SquirrelError(_SC("getVar(): Invalid type+access: 'std::string' with VAR_ACCESS_CONSTANT (use VAR_ACCESS_READ_ONLY instead)")); + } + break; + } // case +#endif + } // switch + return SQ_ERROR; +} // getVar + +// === Global Vars === + +int setVarFunc(HSQUIRRELVM v) { + SquirrelVM::Init(v); // For handling multi-VM setting right + StackHandler sa(v); + if (sa.GetType(1) == OT_TABLE) { + VarRefPtr vr; + int res = getVarInfo(sa,vr); + if (res != SQ_OK) return res; + return setVar(sa,vr,vr->offsetOrAddrOrConst); + } // if + return SQ_ERROR; +} // setVarFunc + +int getVarFunc(HSQUIRRELVM v) { + SquirrelVM::Init(v); // For handling multi-VM setting right + StackHandler sa(v); + if (sa.GetType(1) == OT_TABLE) { + VarRefPtr vr; + int res = getVarInfo(sa,vr); + if (res != SQ_OK) return res; + return getVar(sa,vr,vr->offsetOrAddrOrConst); + } // if + return SQ_ERROR; +} // getVarFunc + +// === Instance Vars === + +int setInstanceVarFunc(HSQUIRRELVM v) { + SquirrelVM::Init(v); // For handling multi-VM setting right + StackHandler sa(v); + if (sa.GetType(1) == OT_INSTANCE) { + VarRefPtr vr; + void * data; + int res = getInstanceVarInfo(sa,vr,data); + if (res != SQ_OK) return res; + return setVar(sa,vr,data); + } // if + return SQ_ERROR; +} // setInstanceVarFunc + +int getInstanceVarFunc(HSQUIRRELVM v) { + SquirrelVM::Init(v); // For handling multi-VM setting right + StackHandler sa(v); + if (sa.GetType(1) == OT_INSTANCE) { + VarRefPtr vr; + void * data; + int res = getInstanceVarInfo(sa,vr,data); + if (res != SQ_OK) return res; + return getVar(sa,vr,data); + } // if + return SQ_ERROR; +} // getInstanceVarFunc + +// === Classes === + +BOOL CreateClass(HSQUIRRELVM v,SquirrelObject & newClass,SQUserPointer classType,const SQChar * name,const SQChar * baseName) { + int n = 0; + int oldtop = sq_gettop(v); + sq_pushroottable(v); + sq_pushstring(v,name,-1); + if (baseName) { + sq_pushstring(v,baseName,-1); + if (SQ_FAILED(sq_get(v,-3))) { // Make sure the base exists if specified by baseName. + sq_settop(v,oldtop); + return FALSE; + } // if + } // if + if (SQ_FAILED(sq_newclass(v,baseName ? 1 : 0))) { // Will inherit from base class on stack from sq_get() above. + sq_settop(v,oldtop); + return FALSE; + } // if + newClass.AttachToStackObject(-1); + sq_settypetag(v,-1,classType); + sq_createslot(v,-3); + sq_pop(v,1); + return TRUE; +} // CreateClass + +SquirrelObject RegisterClassType(HSQUIRRELVM v,const SQChar * scriptClassName,SQUserPointer classType,SQFUNCTION constructor) { + SquirrelVM::Init(v); // For handling multi-VM setting right + int top = sq_gettop(v); + SquirrelObject newClass; + if (CreateClass(v,newClass,classType,scriptClassName)) { + SquirrelVM::CreateFunction(newClass,constructor,_SC("constructor")); + } // if + sq_settop(v,top); + return newClass; +} // RegisterClassType + + +/////////////////////////////////////////////////////////////////////////// +// GCC sometimes has problems with finding inline functions at link time +// (that also have a template definition). To solve the problem, +// non-inlines goes here. +#ifdef GCC_INLINE_WORKAROUND +# include "SqPlusFunctionCallImpl.h" +#endif // GCC_INLINE_WORKAROUND +/////////////////////////////////////////////////////////////////////////// + +} // namespace SqPlus + diff --git a/squirrel_3_0_1_stable/sqplus/SqPlusCallTemplates.h b/squirrel_3_0_1_stable/_OLD_sqplus/SqPlusCallTemplates.h similarity index 97% rename from squirrel_3_0_1_stable/sqplus/SqPlusCallTemplates.h rename to squirrel_3_0_1_stable/_OLD_sqplus/SqPlusCallTemplates.h index 75e4887c5..4ebded1d3 100644 --- a/squirrel_3_0_1_stable/sqplus/SqPlusCallTemplates.h +++ b/squirrel_3_0_1_stable/_OLD_sqplus/SqPlusCallTemplates.h @@ -1,337 +1,337 @@ - -// This file is included multiple times, with varying options - No header guard. - -// Include this file to generate Call templates with or without these options: -// - SQPLUS_APPLY_CONST - const qualifier after functions signature (const func / member func) -// - SQPLUS_APPLY_CDECL - qualifier before class name (MSVC specific calling convention) - -#undef CONST_QUAL -#undef CALL_QUAL - -#ifdef SQPLUS_APPLY_CONST - #define CONST_QUAL const -#else - #define CONST_QUAL -#endif - -#ifdef SQPLUS_APPLY_CDECL - #define CALL_QUAL __cdecl -#else - #define CALL_QUAL -#endif - - -#ifdef SQPLUS_CALL_MFUNC_RET0 - - // Include this file again, with __cdecl also (Visual C++ specific) - #if defined(SQPLUS_ENABLE_CDECL_MEMBER_FUNCTIONS) && !defined(SQPLUS_APPLY_CDECL) - #define SQPLUS_APPLY_CDECL - #include "SqPlusCallTemplates.h" - #undef CALL_QUAL - #define CALL_QUAL - #endif - - template - static int Call(Callee & callee,RT (CALL_QUAL Callee::*func)() CONST_QUAL,HSQUIRRELVM v,int /*index*/) { - RT ret = (callee.*func)(); - Push(v,ret); - return 1; - } - - template - static int Call(Callee & callee,RT (CALL_QUAL Callee::*func)(P1) CONST_QUAL,HSQUIRRELVM v,int index) { - sq_argassert(1,index + 0); - RT ret = (callee.*func)( - Get(TypeWrapper(),v,index + 0) - ); - Push(v,ret); - return 1; - } - - template - static int Call(Callee & callee,RT (CALL_QUAL Callee::*func)(P1,P2) CONST_QUAL,HSQUIRRELVM v,int index) { - sq_argassert(1,index + 0); - sq_argassert(2,index + 1); - RT ret = (callee.*func)( - Get(TypeWrapper(),v,index + 0), - Get(TypeWrapper(),v,index + 1) - ); - Push(v,ret); - return 1; - } - - template - static int Call(Callee & callee,RT (CALL_QUAL Callee::*func)(P1,P2,P3) CONST_QUAL,HSQUIRRELVM v,int index) { - sq_argassert(1,index + 0); - sq_argassert(2,index + 1); - sq_argassert(3,index + 2); - RT ret = (callee.*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(Callee & callee,RT (CALL_QUAL Callee::*func)(P1,P2,P3,P4) CONST_QUAL,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 = (callee.*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(Callee & callee,RT (CALL_QUAL Callee::*func)(P1,P2,P3,P4,P5) CONST_QUAL,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 = (callee.*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(Callee & callee,RT (CALL_QUAL Callee::*func)(P1,P2,P3,P4,P5,P6) CONST_QUAL,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 = (callee.*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(Callee & callee,RT (CALL_QUAL Callee::*func)(P1,P2,P3,P4,P5,P6,P7) CONST_QUAL,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 = (callee.*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; - } -#undef SQPLUS_CALL_MFUNC_RET0 -#endif // SQPLUS_CALL_MFUNC_RET0 - - -#ifdef SQPLUS_CALL_MFUNC_NORET - - // Include this very same thing with __cdecl also - #if defined(SQPLUS_ENABLE_CDECL_MEMBER_FUNCTIONS) && !defined(SQPLUS_APPLY_CDECL) - #define SQPLUS_APPLY_CDECL - #include "SqPlusCallTemplates.h" - #undef CALL_QUAL - #define CALL_QUAL - #endif - - // === Member function calls === - - template - static int Call(Callee & callee,void (CALL_QUAL Callee::*func)() CONST_QUAL, HSQUIRRELVM,int /*index*/) { - (callee.*func)(); - return 0; - } - - template - static int Call(Callee & callee,void (CALL_QUAL Callee::*func)(P1) CONST_QUAL, HSQUIRRELVM v,int index) { - sq_argassert(1,index + 0); - (callee.*func)( - Get(TypeWrapper(),v,index + 0) - ); - return 0; - } - - template - static int Call(Callee & callee,void (CALL_QUAL Callee::*func)(P1,P2) CONST_QUAL, HSQUIRRELVM v,int index) { - sq_argassert(1,index + 0); - sq_argassert(2,index + 1); - (callee.*func)( - Get(TypeWrapper(),v,index + 0), - Get(TypeWrapper(),v,index + 1) - ); - return 0; - } - - template - static int Call(Callee & callee,void (CALL_QUAL Callee::*func)(P1,P2,P3) CONST_QUAL, HSQUIRRELVM v,int index) { - sq_argassert(1,index + 0); - sq_argassert(2,index + 1); - sq_argassert(3,index + 2); - (callee.*func)( - Get(TypeWrapper(),v,index + 0), - Get(TypeWrapper(),v,index + 1), - Get(TypeWrapper(),v,index + 2) - ); - return 0; - } - - template - static int Call(Callee & callee,void (CALL_QUAL Callee::*func)(P1,P2,P3,P4) CONST_QUAL, HSQUIRRELVM v,int index) { - sq_argassert(1,index + 0); - sq_argassert(2,index + 1); - sq_argassert(3,index + 2); - sq_argassert(4,index + 3); - (callee.*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(Callee & callee,void (CALL_QUAL Callee::*func)(P1,P2,P3,P4,P5) CONST_QUAL, 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); - (callee.*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(Callee & callee,void (CALL_QUAL Callee::*func)(P1,P2,P3,P4,P5,P6) CONST_QUAL, 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); - (callee.*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(Callee & callee,void (CALL_QUAL Callee::*func)(P1,P2,P3,P4,P5,P6,P7) CONST_QUAL, 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); - (callee.*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; - } -#undef SQPLUS_CALL_MFUNC_NORET -#endif // SQPLUS_CALL_MFUNC_NORET - - -#ifdef SQPLUS_CALL_MFUNC_RET1 - - // Include this very same thing with __cdecl also - #if defined(SQPLUS_ENABLE_CDECL_MEMBER_FUNCTIONS) && !defined(SQPLUS_APPLY_CDECL) - #define SQPLUS_APPLY_CDECL - #include "SqPlusCallTemplates.h" - #undef CALL_QUAL - #define CALL_QUAL - #endif - - template - int Call(Callee & callee, RT (CALL_QUAL Callee::*func)() CONST_QUAL, HSQUIRRELVM v,int index) { - return ReturnSpecialization::Call(callee,func,v,index); - } - - template - int Call(Callee & callee,RT (CALL_QUAL Callee::*func)(P1) CONST_QUAL, HSQUIRRELVM v,int index) { - return ReturnSpecialization::Call(callee,func,v,index); - } - - template - int Call(Callee & callee,RT (CALL_QUAL Callee::*func)(P1,P2) CONST_QUAL, HSQUIRRELVM v,int index) { - return ReturnSpecialization::Call(callee,func,v,index); - } - - template - int Call(Callee & callee,RT (CALL_QUAL Callee::*func)(P1,P2,P3) CONST_QUAL, HSQUIRRELVM v,int index) { - return ReturnSpecialization::Call(callee,func,v,index); - } - - template - int Call(Callee & callee,RT (CALL_QUAL Callee::*func)(P1,P2,P3,P4) CONST_QUAL, HSQUIRRELVM v,int index) { - return ReturnSpecialization::Call(callee,func,v,index); - } - - template - int Call(Callee & callee,RT (CALL_QUAL Callee::*func)(P1,P2,P3,P4,P5) CONST_QUAL, HSQUIRRELVM v,int index) { - return ReturnSpecialization::Call(callee,func,v,index); - } - - template - int Call(Callee & callee,RT (CALL_QUAL Callee::*func)(P1,P2,P3,P4,P5,P6) CONST_QUAL, HSQUIRRELVM v,int index) { - return ReturnSpecialization::Call(callee,func,v,index); - } - - template - int Call(Callee & callee,RT (CALL_QUAL Callee::*func)(P1,P2,P3,P4,P5,P6,P7) CONST_QUAL, HSQUIRRELVM v,int index) { - return ReturnSpecialization::Call(callee,func,v,index); - } - -#undef SQPLUS_CALL_MFUNC_RET1 -#endif // SQPLUS_CALL_MFUNC_RET1 - -// We will be reusing these symbols later -#undef SQPLUS_APPLY_CDECL -#undef SQPLUS_APPLY_CONST + +// This file is included multiple times, with varying options - No header guard. + +// Include this file to generate Call templates with or without these options: +// - SQPLUS_APPLY_CONST - const qualifier after functions signature (const func / member func) +// - SQPLUS_APPLY_CDECL - qualifier before class name (MSVC specific calling convention) + +#undef CONST_QUAL +#undef CALL_QUAL + +#ifdef SQPLUS_APPLY_CONST + #define CONST_QUAL const +#else + #define CONST_QUAL +#endif + +#ifdef SQPLUS_APPLY_CDECL + #define CALL_QUAL __cdecl +#else + #define CALL_QUAL +#endif + + +#ifdef SQPLUS_CALL_MFUNC_RET0 + + // Include this file again, with __cdecl also (Visual C++ specific) + #if defined(SQPLUS_ENABLE_CDECL_MEMBER_FUNCTIONS) && !defined(SQPLUS_APPLY_CDECL) + #define SQPLUS_APPLY_CDECL + #include "SqPlusCallTemplates.h" + #undef CALL_QUAL + #define CALL_QUAL + #endif + + template + static int Call(Callee & callee,RT (CALL_QUAL Callee::*func)() CONST_QUAL,HSQUIRRELVM v,int /*index*/) { + RT ret = (callee.*func)(); + Push(v,ret); + return 1; + } + + template + static int Call(Callee & callee,RT (CALL_QUAL Callee::*func)(P1) CONST_QUAL,HSQUIRRELVM v,int index) { + sq_argassert(1,index + 0); + RT ret = (callee.*func)( + Get(TypeWrapper(),v,index + 0) + ); + Push(v,ret); + return 1; + } + + template + static int Call(Callee & callee,RT (CALL_QUAL Callee::*func)(P1,P2) CONST_QUAL,HSQUIRRELVM v,int index) { + sq_argassert(1,index + 0); + sq_argassert(2,index + 1); + RT ret = (callee.*func)( + Get(TypeWrapper(),v,index + 0), + Get(TypeWrapper(),v,index + 1) + ); + Push(v,ret); + return 1; + } + + template + static int Call(Callee & callee,RT (CALL_QUAL Callee::*func)(P1,P2,P3) CONST_QUAL,HSQUIRRELVM v,int index) { + sq_argassert(1,index + 0); + sq_argassert(2,index + 1); + sq_argassert(3,index + 2); + RT ret = (callee.*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(Callee & callee,RT (CALL_QUAL Callee::*func)(P1,P2,P3,P4) CONST_QUAL,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 = (callee.*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(Callee & callee,RT (CALL_QUAL Callee::*func)(P1,P2,P3,P4,P5) CONST_QUAL,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 = (callee.*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(Callee & callee,RT (CALL_QUAL Callee::*func)(P1,P2,P3,P4,P5,P6) CONST_QUAL,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 = (callee.*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(Callee & callee,RT (CALL_QUAL Callee::*func)(P1,P2,P3,P4,P5,P6,P7) CONST_QUAL,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 = (callee.*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; + } +#undef SQPLUS_CALL_MFUNC_RET0 +#endif // SQPLUS_CALL_MFUNC_RET0 + + +#ifdef SQPLUS_CALL_MFUNC_NORET + + // Include this very same thing with __cdecl also + #if defined(SQPLUS_ENABLE_CDECL_MEMBER_FUNCTIONS) && !defined(SQPLUS_APPLY_CDECL) + #define SQPLUS_APPLY_CDECL + #include "SqPlusCallTemplates.h" + #undef CALL_QUAL + #define CALL_QUAL + #endif + + // === Member function calls === + + template + static int Call(Callee & callee,void (CALL_QUAL Callee::*func)() CONST_QUAL, HSQUIRRELVM,int /*index*/) { + (callee.*func)(); + return 0; + } + + template + static int Call(Callee & callee,void (CALL_QUAL Callee::*func)(P1) CONST_QUAL, HSQUIRRELVM v,int index) { + sq_argassert(1,index + 0); + (callee.*func)( + Get(TypeWrapper(),v,index + 0) + ); + return 0; + } + + template + static int Call(Callee & callee,void (CALL_QUAL Callee::*func)(P1,P2) CONST_QUAL, HSQUIRRELVM v,int index) { + sq_argassert(1,index + 0); + sq_argassert(2,index + 1); + (callee.*func)( + Get(TypeWrapper(),v,index + 0), + Get(TypeWrapper(),v,index + 1) + ); + return 0; + } + + template + static int Call(Callee & callee,void (CALL_QUAL Callee::*func)(P1,P2,P3) CONST_QUAL, HSQUIRRELVM v,int index) { + sq_argassert(1,index + 0); + sq_argassert(2,index + 1); + sq_argassert(3,index + 2); + (callee.*func)( + Get(TypeWrapper(),v,index + 0), + Get(TypeWrapper(),v,index + 1), + Get(TypeWrapper(),v,index + 2) + ); + return 0; + } + + template + static int Call(Callee & callee,void (CALL_QUAL Callee::*func)(P1,P2,P3,P4) CONST_QUAL, HSQUIRRELVM v,int index) { + sq_argassert(1,index + 0); + sq_argassert(2,index + 1); + sq_argassert(3,index + 2); + sq_argassert(4,index + 3); + (callee.*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(Callee & callee,void (CALL_QUAL Callee::*func)(P1,P2,P3,P4,P5) CONST_QUAL, 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); + (callee.*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(Callee & callee,void (CALL_QUAL Callee::*func)(P1,P2,P3,P4,P5,P6) CONST_QUAL, 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); + (callee.*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(Callee & callee,void (CALL_QUAL Callee::*func)(P1,P2,P3,P4,P5,P6,P7) CONST_QUAL, 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); + (callee.*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; + } +#undef SQPLUS_CALL_MFUNC_NORET +#endif // SQPLUS_CALL_MFUNC_NORET + + +#ifdef SQPLUS_CALL_MFUNC_RET1 + + // Include this very same thing with __cdecl also + #if defined(SQPLUS_ENABLE_CDECL_MEMBER_FUNCTIONS) && !defined(SQPLUS_APPLY_CDECL) + #define SQPLUS_APPLY_CDECL + #include "SqPlusCallTemplates.h" + #undef CALL_QUAL + #define CALL_QUAL + #endif + + template + int Call(Callee & callee, RT (CALL_QUAL Callee::*func)() CONST_QUAL, HSQUIRRELVM v,int index) { + return ReturnSpecialization::Call(callee,func,v,index); + } + + template + int Call(Callee & callee,RT (CALL_QUAL Callee::*func)(P1) CONST_QUAL, HSQUIRRELVM v,int index) { + return ReturnSpecialization::Call(callee,func,v,index); + } + + template + int Call(Callee & callee,RT (CALL_QUAL Callee::*func)(P1,P2) CONST_QUAL, HSQUIRRELVM v,int index) { + return ReturnSpecialization::Call(callee,func,v,index); + } + + template + int Call(Callee & callee,RT (CALL_QUAL Callee::*func)(P1,P2,P3) CONST_QUAL, HSQUIRRELVM v,int index) { + return ReturnSpecialization::Call(callee,func,v,index); + } + + template + int Call(Callee & callee,RT (CALL_QUAL Callee::*func)(P1,P2,P3,P4) CONST_QUAL, HSQUIRRELVM v,int index) { + return ReturnSpecialization::Call(callee,func,v,index); + } + + template + int Call(Callee & callee,RT (CALL_QUAL Callee::*func)(P1,P2,P3,P4,P5) CONST_QUAL, HSQUIRRELVM v,int index) { + return ReturnSpecialization::Call(callee,func,v,index); + } + + template + int Call(Callee & callee,RT (CALL_QUAL Callee::*func)(P1,P2,P3,P4,P5,P6) CONST_QUAL, HSQUIRRELVM v,int index) { + return ReturnSpecialization::Call(callee,func,v,index); + } + + template + int Call(Callee & callee,RT (CALL_QUAL Callee::*func)(P1,P2,P3,P4,P5,P6,P7) CONST_QUAL, HSQUIRRELVM v,int index) { + return ReturnSpecialization::Call(callee,func,v,index); + } + +#undef SQPLUS_CALL_MFUNC_RET1 +#endif // SQPLUS_CALL_MFUNC_RET1 + +// We will be reusing these symbols later +#undef SQPLUS_APPLY_CDECL +#undef SQPLUS_APPLY_CONST diff --git a/squirrel_3_0_1_stable/sqplus/SqPlusConst.h b/squirrel_3_0_1_stable/_OLD_sqplus/SqPlusConst.h similarity index 97% rename from squirrel_3_0_1_stable/sqplus/SqPlusConst.h rename to squirrel_3_0_1_stable/_OLD_sqplus/SqPlusConst.h index 0fd6b72ae..50fafc220 100644 --- a/squirrel_3_0_1_stable/sqplus/SqPlusConst.h +++ b/squirrel_3_0_1_stable/_OLD_sqplus/SqPlusConst.h @@ -1,74 +1,74 @@ -// SqPlusConst.h -// SqPlus constant type and constant member function support created by Simon Michelmore. -// Modular integration 11/14/05 jcs. - -#ifdef SQPLUS_DECLARE_INSTANCE_TYPE_CONST -#undef SQPLUS_DECLARE_INSTANCE_TYPE_CONST - -// Kamaitati's NULL_INSTANCE support. 5/28/06 jcs - -#ifdef SQPLUS_SUPPORT_NULL_INSTANCES - -#define DECLARE_INSTANCE_TYPE_NAME_CONST_BASE(TYPE,NAME) \ -inline bool Match(TypeWrapper,HSQUIRRELVM v,int idx) { return GetInstance(v,idx) != NULL; } \ -inline const TYPE & Get(TypeWrapper,HSQUIRRELVM v,int idx) { return *GetInstance(v,idx); } - -// Ordinary case -#define DECLARE_INSTANCE_TYPE_NAME_CONST(TYPE,NAME) \ - DECLARE_INSTANCE_TYPE_NAME_(TYPE,NAME) \ - namespace SqPlus { \ - DECLARE_INSTANCE_TYPE_NAME_CONST_BASE(TYPE,NAME) \ - template<> inline void Push(HSQUIRRELVM v,const TYPE * value) { \ - if (!value) sq_pushnull(v); \ - else if (!CreateNativeClassInstance(v,GetTypeName(*value),(TYPE*)value,0)) \ - throw SquirrelError(_SC("Push(): could not create INSTANCE (check registration name)")); } \ - template<> inline void Push(HSQUIRRELVM v,const TYPE & value) { if (!CreateCopyInstance(v,GetTypeName(value),value)) throw SquirrelError(_SC("Push(): could not create INSTANCE copy (check registration name)")); } \ - } // nameSpace SqPlus - -// Case for custom Push implementation (covariant return type) -#define DECLARE_INSTANCE_TYPE_NAME_CONST_CUSTOM(TYPE,NAME) \ - DECLARE_INSTANCE_TYPE_NAME_CUSTOM_(TYPE,NAME) \ - namespace SqPlus { \ - DECLARE_INSTANCE_TYPE_NAME_CONST_BASE(TYPE,NAME) \ - template<> void Push(HSQUIRRELVM v,const TYPE * value); \ - template<> void Push(HSQUIRRELVM v,const TYPE & value); \ - } // nameSpace SqPlus - - -#else - -#define DECLARE_INSTANCE_TYPE_NAME_CONST(TYPE,NAME) \ - DECLARE_INSTANCE_TYPE_NAME_(TYPE,NAME) \ - namespace SqPlus { \ - template<> inline void Push(HSQUIRRELVM v,const TYPE * value) { if (!CreateNativeClassInstance(v,GetTypeName(*value),(TYPE*)value,0)) throw SquirrelError(_SC("Push(): could not create INSTANCE (check registration name)")); } \ - template<> inline void Push(HSQUIRRELVM v,const 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 const TYPE & Get(TypeWrapper,HSQUIRRELVM v,int idx) { return *GetInstance(v,idx); } \ - } // nameSpace SqPlus - -#endif - -#define DECLARE_INSTANCE_TYPE(TYPE) DECLARE_INSTANCE_TYPE_NAME_CONST(TYPE,TYPE) -#define DECLARE_INSTANCE_TYPE_NAME(TYPE,NAME) DECLARE_INSTANCE_TYPE_NAME_CONST(TYPE,NAME) -#define DECLARE_INSTANCE_TYPE_CUSTOM(TYPE) DECLARE_INSTANCE_TYPE_NAME_CONST_CUSTOM(TYPE,TYPE) -#define DECLARE_INSTANCE_TYPE_NAME_CUSTOM(TYPE,NAME) DECLARE_INSTANCE_TYPE_NAME_CONST_CUSTOM(TYPE,NAME) -#endif - -#define SQPLUS_APPLY_CONST -#include "SqPlusCallTemplates.h" - - -#ifdef SQ_REG_CONST_STATIC_VAR -#undef SQ_REG_CONST_STATIC_VAR -template -SQClassDefBase & staticVar(const VarType * pvar,const SQChar * name,VarAccessType access=VAR_ACCESS_READ_ONLY) { - struct CV { - const VarType * var; - } cv; // Cast Variable helper. - cv.var = pvar; - RegisterInstanceVariable(newClass,ClassType::type(),*(VarType **)&cv,name,VarAccessType(access|VAR_ACCESS_STATIC)); - return *this; -} // staticVar -#endif - -// SqPlusConst.h +// SqPlusConst.h +// SqPlus constant type and constant member function support created by Simon Michelmore. +// Modular integration 11/14/05 jcs. + +#ifdef SQPLUS_DECLARE_INSTANCE_TYPE_CONST +#undef SQPLUS_DECLARE_INSTANCE_TYPE_CONST + +// Kamaitati's NULL_INSTANCE support. 5/28/06 jcs + +#ifdef SQPLUS_SUPPORT_NULL_INSTANCES + +#define DECLARE_INSTANCE_TYPE_NAME_CONST_BASE(TYPE,NAME) \ +inline bool Match(TypeWrapper,HSQUIRRELVM v,int idx) { return GetInstance(v,idx) != NULL; } \ +inline const TYPE & Get(TypeWrapper,HSQUIRRELVM v,int idx) { return *GetInstance(v,idx); } + +// Ordinary case +#define DECLARE_INSTANCE_TYPE_NAME_CONST(TYPE,NAME) \ + DECLARE_INSTANCE_TYPE_NAME_(TYPE,NAME) \ + namespace SqPlus { \ + DECLARE_INSTANCE_TYPE_NAME_CONST_BASE(TYPE,NAME) \ + template<> inline void Push(HSQUIRRELVM v,const TYPE * value) { \ + if (!value) sq_pushnull(v); \ + else if (!CreateNativeClassInstance(v,GetTypeName(*value),(TYPE*)value,0)) \ + throw SquirrelError(_SC("Push(): could not create INSTANCE (check registration name)")); } \ + template<> inline void Push(HSQUIRRELVM v,const TYPE & value) { if (!CreateCopyInstance(v,GetTypeName(value),value)) throw SquirrelError(_SC("Push(): could not create INSTANCE copy (check registration name)")); } \ + } // nameSpace SqPlus + +// Case for custom Push implementation (covariant return type) +#define DECLARE_INSTANCE_TYPE_NAME_CONST_CUSTOM(TYPE,NAME) \ + DECLARE_INSTANCE_TYPE_NAME_CUSTOM_(TYPE,NAME) \ + namespace SqPlus { \ + DECLARE_INSTANCE_TYPE_NAME_CONST_BASE(TYPE,NAME) \ + template<> void Push(HSQUIRRELVM v,const TYPE * value); \ + template<> void Push(HSQUIRRELVM v,const TYPE & value); \ + } // nameSpace SqPlus + + +#else + +#define DECLARE_INSTANCE_TYPE_NAME_CONST(TYPE,NAME) \ + DECLARE_INSTANCE_TYPE_NAME_(TYPE,NAME) \ + namespace SqPlus { \ + template<> inline void Push(HSQUIRRELVM v,const TYPE * value) { if (!CreateNativeClassInstance(v,GetTypeName(*value),(TYPE*)value,0)) throw SquirrelError(_SC("Push(): could not create INSTANCE (check registration name)")); } \ + template<> inline void Push(HSQUIRRELVM v,const 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 const TYPE & Get(TypeWrapper,HSQUIRRELVM v,int idx) { return *GetInstance(v,idx); } \ + } // nameSpace SqPlus + +#endif + +#define DECLARE_INSTANCE_TYPE(TYPE) DECLARE_INSTANCE_TYPE_NAME_CONST(TYPE,TYPE) +#define DECLARE_INSTANCE_TYPE_NAME(TYPE,NAME) DECLARE_INSTANCE_TYPE_NAME_CONST(TYPE,NAME) +#define DECLARE_INSTANCE_TYPE_CUSTOM(TYPE) DECLARE_INSTANCE_TYPE_NAME_CONST_CUSTOM(TYPE,TYPE) +#define DECLARE_INSTANCE_TYPE_NAME_CUSTOM(TYPE,NAME) DECLARE_INSTANCE_TYPE_NAME_CONST_CUSTOM(TYPE,NAME) +#endif + +#define SQPLUS_APPLY_CONST +#include "SqPlusCallTemplates.h" + + +#ifdef SQ_REG_CONST_STATIC_VAR +#undef SQ_REG_CONST_STATIC_VAR +template +SQClassDefBase & staticVar(const VarType * pvar,const SQChar * name,VarAccessType access=VAR_ACCESS_READ_ONLY) { + struct CV { + const VarType * var; + } cv; // Cast Variable helper. + cv.var = pvar; + RegisterInstanceVariable(newClass,ClassType::type(),*(VarType **)&cv,name,VarAccessType(access|VAR_ACCESS_STATIC)); + return *this; +} // staticVar +#endif + +// SqPlusConst.h diff --git a/squirrel_3_0_1_stable/sqplus/SqPlusFunctionCallImpl.h b/squirrel_3_0_1_stable/_OLD_sqplus/SqPlusFunctionCallImpl.h similarity index 98% rename from squirrel_3_0_1_stable/sqplus/SqPlusFunctionCallImpl.h rename to squirrel_3_0_1_stable/_OLD_sqplus/SqPlusFunctionCallImpl.h index c0752a7f3..8b54308d8 100644 --- a/squirrel_3_0_1_stable/sqplus/SqPlusFunctionCallImpl.h +++ b/squirrel_3_0_1_stable/_OLD_sqplus/SqPlusFunctionCallImpl.h @@ -1,114 +1,114 @@ -#ifndef _SQPLUS_FUNCTION_CALL_IMPL_H_ -#define _SQPLUS_FUNCTION_CALL_IMPL_H_ - -#ifdef GCC_INLINE_WORKAROUND -# define SQINLINE -#else -# define SQINLINE inline -#endif - -SQINLINE void Push(HSQUIRRELVM v,char value) { sq_pushinteger(v,value); } -SQINLINE void Push(HSQUIRRELVM v,unsigned char value) { sq_pushinteger(v,value); } -SQINLINE void Push(HSQUIRRELVM v,short value) { sq_pushinteger(v,value); } -SQINLINE void Push(HSQUIRRELVM v,unsigned short value) { sq_pushinteger(v,value); } -SQINLINE void Push(HSQUIRRELVM v,int value) { sq_pushinteger(v,value); } -SQINLINE void Push(HSQUIRRELVM v,unsigned int value) { sq_pushinteger(v,value); } -SQINLINE void Push(HSQUIRRELVM v,long value) { sq_pushinteger(v,value); } -SQINLINE void Push(HSQUIRRELVM v,unsigned long value) { sq_pushinteger(v,value); } -SQINLINE void Push(HSQUIRRELVM v,double value) { sq_pushfloat(v,(FLOAT)value); } -SQINLINE void Push(HSQUIRRELVM v,float value) { sq_pushfloat(v,(FLOAT)value); } -SQINLINE void Push(HSQUIRRELVM v,const SQChar * value) { sq_pushstring(v,value,-1); } -SQINLINE void Push(HSQUIRRELVM v,SQChar * value) { sq_pushstring(v,value,-1); } -SQINLINE void Push(HSQUIRRELVM v,const SquirrelNull &) { sq_pushnull(v); } -SQINLINE void Push(HSQUIRRELVM v,SQFUNCTION value) { sq_pushuserpointer(v,(void*)value); } -SQINLINE void Push(HSQUIRRELVM v,SQAnythingPtr value) { sq_pushuserpointer(v,(void*)value); } // Cast to SQAnythingPtr instead of void * if USE_ARGUMENT_DEPENDANT_OVERLOADS can't be used by your compiler. -SQINLINE void Push(HSQUIRRELVM v,SquirrelObject & so) { sq_pushobject(v,so.GetObjectHandle()); } - -#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 === -SQINLINE void Push(HSQUIRRELVM v,bool value) { sq_pushbool(v,value); } // Pass bool as int if USE_ARGUMENT_DEPENDANT_OVERLOADS can't be used by your compiler. -SQINLINE void Push(HSQUIRRELVM v,const void * value) { sq_pushuserpointer(v,(void*)value); } // Pass SQAnythingPtr instead of void * " " -SQINLINE void Push(HSQUIRRELVM v,const SQUserPointer & value) { sq_pushuserpointer(v,(void*)value); } -// === END Argument Dependent Overloads === -#endif - -#define SQPLUS_CHECK_GET(res) if (!SQ_SUCCEEDED(res)) throw SquirrelError(_SC("sq_get*() failed (type error)")) - -//SQINLINE bool Match(TypeWrapper,HSQUIRRELVM v,int idx) { return sq_gettype(v,idx) == OT_BOOL; } -SQINLINE bool Match(TypeWrapper,HSQUIRRELVM v,int idx) { return true; } // All types can be cast to bool -SQINLINE bool Match(TypeWrapper,HSQUIRRELVM v,int idx) { return sq_gettype(v,idx) == OT_INTEGER; } -SQINLINE bool Match(TypeWrapper,HSQUIRRELVM v, int idx) { return sq_gettype(v,idx) == OT_INTEGER; } -SQINLINE bool Match(TypeWrapper,HSQUIRRELVM v,int idx) { return sq_gettype(v,idx) == OT_INTEGER; } -SQINLINE bool Match(TypeWrapper,HSQUIRRELVM v,int idx) { return sq_gettype(v,idx) == OT_INTEGER; } -SQINLINE bool Match(TypeWrapper,HSQUIRRELVM v,int idx) { return sq_gettype(v,idx) == OT_INTEGER; } -SQINLINE bool Match(TypeWrapper,HSQUIRRELVM v,int idx) { return sq_gettype(v,idx) == OT_INTEGER; } -SQINLINE bool Match(TypeWrapper,HSQUIRRELVM v,int idx) { return sq_gettype(v,idx) == OT_INTEGER; } -SQINLINE bool Match(TypeWrapper,HSQUIRRELVM v,int idx) { return sq_gettype(v,idx) == OT_INTEGER; } -SQINLINE bool Match(TypeWrapper,HSQUIRRELVM v,int idx) { int type = sq_gettype(v,idx); return type == OT_FLOAT; } -SQINLINE bool Match(TypeWrapper,HSQUIRRELVM v,int idx) { int type = sq_gettype(v,idx); return type == OT_FLOAT; } -SQINLINE bool Match(TypeWrapper,HSQUIRRELVM v,int idx) { return sq_gettype(v,idx) == OT_STRING; } -SQINLINE bool Match(TypeWrapper,HSQUIRRELVM v,int idx) { return sq_gettype(v,idx) == OT_STRING; } -SQINLINE bool Match(TypeWrapper,HSQUIRRELVM v,int idx) { return true; } // See Get() for HSQUIRRELVM below (v is always present). -SQINLINE bool Match(TypeWrapper,HSQUIRRELVM v,int idx) { return sq_gettype(v,idx) == OT_USERPOINTER; } -SQINLINE bool Match(TypeWrapper,HSQUIRRELVM v,int idx) { return true; } // See sq_getstackobj(): always returns true. - -SQINLINE void Get(TypeWrapper,HSQUIRRELVM v,int) {} -//SQINLINE bool Get(TypeWrapper,HSQUIRRELVM v,int idx) { SQBool b; SQPLUS_CHECK_GET(sq_getbool(v,idx,&b)); return b != 0; } -SQINLINE char Get(TypeWrapper,HSQUIRRELVM v,int idx) { INT i; SQPLUS_CHECK_GET(sq_getinteger(v,idx,&i)); return static_cast(i); } -SQINLINE unsigned char Get(TypeWrapper,HSQUIRRELVM v,int idx) { INT i; SQPLUS_CHECK_GET(sq_getinteger(v,idx,&i)); return static_cast(i); } -SQINLINE short Get(TypeWrapper,HSQUIRRELVM v,int idx) { INT i; SQPLUS_CHECK_GET(sq_getinteger(v,idx,&i)); return static_cast(i); } -SQINLINE unsigned short Get(TypeWrapper,HSQUIRRELVM v,int idx) { INT i; SQPLUS_CHECK_GET(sq_getinteger(v,idx,&i)); return static_cast(i); } -SQINLINE int Get(TypeWrapper,HSQUIRRELVM v,int idx) { INT i; SQPLUS_CHECK_GET(sq_getinteger(v,idx,&i)); return i; } -SQINLINE unsigned int Get(TypeWrapper,HSQUIRRELVM v,int idx) { INT i; SQPLUS_CHECK_GET(sq_getinteger(v,idx,&i)); return static_cast(i); } -SQINLINE long Get(TypeWrapper,HSQUIRRELVM v,int idx) { INT i; SQPLUS_CHECK_GET(sq_getinteger(v,idx,&i)); return static_cast(i); } -SQINLINE unsigned long Get(TypeWrapper,HSQUIRRELVM v,int idx) { INT i; SQPLUS_CHECK_GET(sq_getinteger(v,idx,&i)); return static_cast(i); } -SQINLINE float Get(TypeWrapper,HSQUIRRELVM v,int idx) { FLOAT f; SQPLUS_CHECK_GET(sq_getfloat(v,idx,&f)); return f; } -SQINLINE double Get(TypeWrapper,HSQUIRRELVM v,int idx) { FLOAT f; SQPLUS_CHECK_GET(sq_getfloat(v,idx,&f)); return static_cast(f); } -SQINLINE const SQChar * Get(TypeWrapper,HSQUIRRELVM v,int idx) { const SQChar * s; SQPLUS_CHECK_GET(sq_getstring(v,idx,&s)); return s; } -SQINLINE SquirrelNull Get(TypeWrapper,HSQUIRRELVM v,int idx) { (void)v, (void)idx; return SquirrelNull(); } -SQINLINE void * Get(TypeWrapper,HSQUIRRELVM v,int idx) { SQUserPointer p; SQPLUS_CHECK_GET(sq_getuserpointer(v,idx,&p)); return p; } -SQINLINE HSQUIRRELVM Get(TypeWrapper,HSQUIRRELVM v,int /*idx*/) { sq_poptop(v); return v; } // sq_poptop(v): remove UserData from stack so GetParamCount() matches normal behavior. -SQINLINE SquirrelObject Get(TypeWrapper,HSQUIRRELVM v,int idx) { HSQOBJECT o; SQPLUS_CHECK_GET(sq_getstackobj(v,idx,&o)); return SquirrelObject(o); } - -SQINLINE bool Get(TypeWrapper,HSQUIRRELVM v,int idx){ - switch( sq_gettype(v,idx) ){ - case OT_NULL:{ return false; } - case OT_BOOL:{ SQBool b; SQPLUS_CHECK_GET(sq_getbool(v,idx,&b)); return b != 0; } - case OT_INTEGER:{ INT i; SQPLUS_CHECK_GET(sq_getinteger(v,idx,&i)); return i != 0; } - case OT_FLOAT:{ FLOAT f; SQPLUS_CHECK_GET(sq_getfloat(v,idx,&f)); return f != (FLOAT)0.0; } - default: return true; } } - -#ifdef SQPLUS_AUTOCONVERT_OTHER_CHAR -SQINLINE void Push(HSQUIRRELVM v, const SQOtherChar *value){ SQDefCharBuf cb(value); sq_pushstring(v,(const SQChar*)cb,-1); } -SQINLINE void Push(HSQUIRRELVM v, SQOtherChar *value){ SQDefCharBuf cb(value); sq_pushstring(v,(const SQChar*)cb,-1); } -SQINLINE bool Match(TypeWrapper,HSQUIRRELVM v,int idx) { return sq_gettype(v,idx) == OT_STRING; } -SQINLINE bool Match(TypeWrapper,HSQUIRRELVM v,int idx) { return sq_gettype(v,idx) == OT_STRING; } -/*SQINLINE SQOtherChar* Get(TypeWrapper,HSQUIRRELVM v,int idx) { - const SQChar *s; SQPLUS_CHECK_GET(sq_getstring(v,idx,&s)); - static SQOthCharBuf ocb[SQPLUS_AUTOCONVERT_MAX_INSTANCES]; static int st_buf_cnt; - return ocb[st_buf_cnt++%SQPLUS_AUTOCONVERT_MAX_INSTANCES].Set(s); }*/ -SQINLINE SQOthCharBuf Get(TypeWrapper,HSQUIRRELVM v,int idx) { const SQChar * s; SQPLUS_CHECK_GET(sq_getstring(v,idx,&s)); return SQOthCharBuf(s); } -#endif // SQPLUS_AUTOCONVERT_OTHER_CHAR - -#if defined(SQPLUS_SUPPORT_STD_STRING) && !defined(SQUNICODE) -SQINLINE void Push(HSQUIRRELVM v,const std::string& value) { sq_pushstring(v,value.c_str(),-1); } -SQINLINE bool Match(TypeWrapper, HSQUIRRELVM v, int idx) { return sq_gettype(v,idx) == OT_STRING; } -SQINLINE std::string Get(TypeWrapper,HSQUIRRELVM v,int idx) { const SQChar * s; SQPLUS_CHECK_GET(sq_getstring(v,idx,&s)); return std::string(s); } -#endif // defined(SQPLUS_SUPPORT_STD_STRING) && !defined(SQUNICODE) - -// Added jflanglois suggestion, 8/20/06. jcs -#ifdef SQPLUS_SUPPORT_SQ_STD_STRING -typedef std::basic_string sq_std_string; -SQINLINE void Push(HSQUIRRELVM v,const sq_std_string & value) { sq_pushstring(v,value.c_str(),-1); } -SQINLINE bool Match(TypeWrapper, HSQUIRRELVM v, int idx) { return sq_gettype(v,idx) == OT_STRING; } -SQINLINE sq_std_string Get(TypeWrapper,HSQUIRRELVM v,int idx) { const SQChar * s; SQPLUS_CHECK_GET(sq_getstring(v,idx,&s)); return sq_std_string(s); } -#endif - -// Specialization to support void return type. -SQINLINE void GetRet(TypeWrapper,HSQUIRRELVM v,int idx) { sq_pop(v,2); } - -#endif // _SQPLUS_FUNCTION_CALL_IMPL_H_ - +#ifndef _SQPLUS_FUNCTION_CALL_IMPL_H_ +#define _SQPLUS_FUNCTION_CALL_IMPL_H_ + +#ifdef GCC_INLINE_WORKAROUND +# define SQINLINE +#else +# define SQINLINE inline +#endif + +SQINLINE void Push(HSQUIRRELVM v,char value) { sq_pushinteger(v,value); } +SQINLINE void Push(HSQUIRRELVM v,unsigned char value) { sq_pushinteger(v,value); } +SQINLINE void Push(HSQUIRRELVM v,short value) { sq_pushinteger(v,value); } +SQINLINE void Push(HSQUIRRELVM v,unsigned short value) { sq_pushinteger(v,value); } +SQINLINE void Push(HSQUIRRELVM v,int value) { sq_pushinteger(v,value); } +SQINLINE void Push(HSQUIRRELVM v,unsigned int value) { sq_pushinteger(v,value); } +SQINLINE void Push(HSQUIRRELVM v,long value) { sq_pushinteger(v,value); } +SQINLINE void Push(HSQUIRRELVM v,unsigned long value) { sq_pushinteger(v,value); } +SQINLINE void Push(HSQUIRRELVM v,double value) { sq_pushfloat(v,(FLOAT)value); } +SQINLINE void Push(HSQUIRRELVM v,float value) { sq_pushfloat(v,(FLOAT)value); } +SQINLINE void Push(HSQUIRRELVM v,const SQChar * value) { sq_pushstring(v,value,-1); } +SQINLINE void Push(HSQUIRRELVM v,SQChar * value) { sq_pushstring(v,value,-1); } +SQINLINE void Push(HSQUIRRELVM v,const SquirrelNull &) { sq_pushnull(v); } +SQINLINE void Push(HSQUIRRELVM v,SQFUNCTION value) { sq_pushuserpointer(v,(void*)value); } +SQINLINE void Push(HSQUIRRELVM v,SQAnythingPtr value) { sq_pushuserpointer(v,(void*)value); } // Cast to SQAnythingPtr instead of void * if USE_ARGUMENT_DEPENDANT_OVERLOADS can't be used by your compiler. +SQINLINE void Push(HSQUIRRELVM v,SquirrelObject & so) { sq_pushobject(v,so.GetObjectHandle()); } + +#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 === +SQINLINE void Push(HSQUIRRELVM v,bool value) { sq_pushbool(v,value); } // Pass bool as int if USE_ARGUMENT_DEPENDANT_OVERLOADS can't be used by your compiler. +SQINLINE void Push(HSQUIRRELVM v,const void * value) { sq_pushuserpointer(v,(void*)value); } // Pass SQAnythingPtr instead of void * " " +SQINLINE void Push(HSQUIRRELVM v,const SQUserPointer & value) { sq_pushuserpointer(v,(void*)value); } +// === END Argument Dependent Overloads === +#endif + +#define SQPLUS_CHECK_GET(res) if (!SQ_SUCCEEDED(res)) throw SquirrelError(_SC("sq_get*() failed (type error)")) + +//SQINLINE bool Match(TypeWrapper,HSQUIRRELVM v,int idx) { return sq_gettype(v,idx) == OT_BOOL; } +SQINLINE bool Match(TypeWrapper,HSQUIRRELVM v,int idx) { return true; } // All types can be cast to bool +SQINLINE bool Match(TypeWrapper,HSQUIRRELVM v,int idx) { return sq_gettype(v,idx) == OT_INTEGER; } +SQINLINE bool Match(TypeWrapper,HSQUIRRELVM v, int idx) { return sq_gettype(v,idx) == OT_INTEGER; } +SQINLINE bool Match(TypeWrapper,HSQUIRRELVM v,int idx) { return sq_gettype(v,idx) == OT_INTEGER; } +SQINLINE bool Match(TypeWrapper,HSQUIRRELVM v,int idx) { return sq_gettype(v,idx) == OT_INTEGER; } +SQINLINE bool Match(TypeWrapper,HSQUIRRELVM v,int idx) { return sq_gettype(v,idx) == OT_INTEGER; } +SQINLINE bool Match(TypeWrapper,HSQUIRRELVM v,int idx) { return sq_gettype(v,idx) == OT_INTEGER; } +SQINLINE bool Match(TypeWrapper,HSQUIRRELVM v,int idx) { return sq_gettype(v,idx) == OT_INTEGER; } +SQINLINE bool Match(TypeWrapper,HSQUIRRELVM v,int idx) { return sq_gettype(v,idx) == OT_INTEGER; } +SQINLINE bool Match(TypeWrapper,HSQUIRRELVM v,int idx) { int type = sq_gettype(v,idx); return type == OT_FLOAT; } +SQINLINE bool Match(TypeWrapper,HSQUIRRELVM v,int idx) { int type = sq_gettype(v,idx); return type == OT_FLOAT; } +SQINLINE bool Match(TypeWrapper,HSQUIRRELVM v,int idx) { return sq_gettype(v,idx) == OT_STRING; } +SQINLINE bool Match(TypeWrapper,HSQUIRRELVM v,int idx) { return sq_gettype(v,idx) == OT_STRING; } +SQINLINE bool Match(TypeWrapper,HSQUIRRELVM v,int idx) { return true; } // See Get() for HSQUIRRELVM below (v is always present). +SQINLINE bool Match(TypeWrapper,HSQUIRRELVM v,int idx) { return sq_gettype(v,idx) == OT_USERPOINTER; } +SQINLINE bool Match(TypeWrapper,HSQUIRRELVM v,int idx) { return true; } // See sq_getstackobj(): always returns true. + +SQINLINE void Get(TypeWrapper,HSQUIRRELVM v,int) {} +//SQINLINE bool Get(TypeWrapper,HSQUIRRELVM v,int idx) { SQBool b; SQPLUS_CHECK_GET(sq_getbool(v,idx,&b)); return b != 0; } +SQINLINE char Get(TypeWrapper,HSQUIRRELVM v,int idx) { INT i; SQPLUS_CHECK_GET(sq_getinteger(v,idx,&i)); return static_cast(i); } +SQINLINE unsigned char Get(TypeWrapper,HSQUIRRELVM v,int idx) { INT i; SQPLUS_CHECK_GET(sq_getinteger(v,idx,&i)); return static_cast(i); } +SQINLINE short Get(TypeWrapper,HSQUIRRELVM v,int idx) { INT i; SQPLUS_CHECK_GET(sq_getinteger(v,idx,&i)); return static_cast(i); } +SQINLINE unsigned short Get(TypeWrapper,HSQUIRRELVM v,int idx) { INT i; SQPLUS_CHECK_GET(sq_getinteger(v,idx,&i)); return static_cast(i); } +SQINLINE int Get(TypeWrapper,HSQUIRRELVM v,int idx) { INT i; SQPLUS_CHECK_GET(sq_getinteger(v,idx,&i)); return i; } +SQINLINE unsigned int Get(TypeWrapper,HSQUIRRELVM v,int idx) { INT i; SQPLUS_CHECK_GET(sq_getinteger(v,idx,&i)); return static_cast(i); } +SQINLINE long Get(TypeWrapper,HSQUIRRELVM v,int idx) { INT i; SQPLUS_CHECK_GET(sq_getinteger(v,idx,&i)); return static_cast(i); } +SQINLINE unsigned long Get(TypeWrapper,HSQUIRRELVM v,int idx) { INT i; SQPLUS_CHECK_GET(sq_getinteger(v,idx,&i)); return static_cast(i); } +SQINLINE float Get(TypeWrapper,HSQUIRRELVM v,int idx) { FLOAT f; SQPLUS_CHECK_GET(sq_getfloat(v,idx,&f)); return f; } +SQINLINE double Get(TypeWrapper,HSQUIRRELVM v,int idx) { FLOAT f; SQPLUS_CHECK_GET(sq_getfloat(v,idx,&f)); return static_cast(f); } +SQINLINE const SQChar * Get(TypeWrapper,HSQUIRRELVM v,int idx) { const SQChar * s; SQPLUS_CHECK_GET(sq_getstring(v,idx,&s)); return s; } +SQINLINE SquirrelNull Get(TypeWrapper,HSQUIRRELVM v,int idx) { (void)v, (void)idx; return SquirrelNull(); } +SQINLINE void * Get(TypeWrapper,HSQUIRRELVM v,int idx) { SQUserPointer p; SQPLUS_CHECK_GET(sq_getuserpointer(v,idx,&p)); return p; } +SQINLINE HSQUIRRELVM Get(TypeWrapper,HSQUIRRELVM v,int /*idx*/) { sq_poptop(v); return v; } // sq_poptop(v): remove UserData from stack so GetParamCount() matches normal behavior. +SQINLINE SquirrelObject Get(TypeWrapper,HSQUIRRELVM v,int idx) { HSQOBJECT o; SQPLUS_CHECK_GET(sq_getstackobj(v,idx,&o)); return SquirrelObject(o); } + +SQINLINE bool Get(TypeWrapper,HSQUIRRELVM v,int idx){ + switch( sq_gettype(v,idx) ){ + case OT_NULL:{ return false; } + case OT_BOOL:{ SQBool b; SQPLUS_CHECK_GET(sq_getbool(v,idx,&b)); return b != 0; } + case OT_INTEGER:{ INT i; SQPLUS_CHECK_GET(sq_getinteger(v,idx,&i)); return i != 0; } + case OT_FLOAT:{ FLOAT f; SQPLUS_CHECK_GET(sq_getfloat(v,idx,&f)); return f != (FLOAT)0.0; } + default: return true; } } + +#ifdef SQPLUS_AUTOCONVERT_OTHER_CHAR +SQINLINE void Push(HSQUIRRELVM v, const SQOtherChar *value){ SQDefCharBuf cb(value); sq_pushstring(v,(const SQChar*)cb,-1); } +SQINLINE void Push(HSQUIRRELVM v, SQOtherChar *value){ SQDefCharBuf cb(value); sq_pushstring(v,(const SQChar*)cb,-1); } +SQINLINE bool Match(TypeWrapper,HSQUIRRELVM v,int idx) { return sq_gettype(v,idx) == OT_STRING; } +SQINLINE bool Match(TypeWrapper,HSQUIRRELVM v,int idx) { return sq_gettype(v,idx) == OT_STRING; } +/*SQINLINE SQOtherChar* Get(TypeWrapper,HSQUIRRELVM v,int idx) { + const SQChar *s; SQPLUS_CHECK_GET(sq_getstring(v,idx,&s)); + static SQOthCharBuf ocb[SQPLUS_AUTOCONVERT_MAX_INSTANCES]; static int st_buf_cnt; + return ocb[st_buf_cnt++%SQPLUS_AUTOCONVERT_MAX_INSTANCES].Set(s); }*/ +SQINLINE SQOthCharBuf Get(TypeWrapper,HSQUIRRELVM v,int idx) { const SQChar * s; SQPLUS_CHECK_GET(sq_getstring(v,idx,&s)); return SQOthCharBuf(s); } +#endif // SQPLUS_AUTOCONVERT_OTHER_CHAR + +#if defined(SQPLUS_SUPPORT_STD_STRING) && !defined(SQUNICODE) +SQINLINE void Push(HSQUIRRELVM v,const std::string& value) { sq_pushstring(v,value.c_str(),-1); } +SQINLINE bool Match(TypeWrapper, HSQUIRRELVM v, int idx) { return sq_gettype(v,idx) == OT_STRING; } +SQINLINE std::string Get(TypeWrapper,HSQUIRRELVM v,int idx) { const SQChar * s; SQPLUS_CHECK_GET(sq_getstring(v,idx,&s)); return std::string(s); } +#endif // defined(SQPLUS_SUPPORT_STD_STRING) && !defined(SQUNICODE) + +// Added jflanglois suggestion, 8/20/06. jcs +#ifdef SQPLUS_SUPPORT_SQ_STD_STRING +typedef std::basic_string sq_std_string; +SQINLINE void Push(HSQUIRRELVM v,const sq_std_string & value) { sq_pushstring(v,value.c_str(),-1); } +SQINLINE bool Match(TypeWrapper, HSQUIRRELVM v, int idx) { return sq_gettype(v,idx) == OT_STRING; } +SQINLINE sq_std_string Get(TypeWrapper,HSQUIRRELVM v,int idx) { const SQChar * s; SQPLUS_CHECK_GET(sq_getstring(v,idx,&s)); return sq_std_string(s); } +#endif + +// Specialization to support void return type. +SQINLINE void GetRet(TypeWrapper,HSQUIRRELVM v,int idx) { sq_pop(v,2); } + +#endif // _SQPLUS_FUNCTION_CALL_IMPL_H_ + diff --git a/squirrel_3_0_1_stable/sqplus/SqPlusOCharBuf.cpp b/squirrel_3_0_1_stable/_OLD_sqplus/SqPlusOCharBuf.cpp similarity index 97% rename from squirrel_3_0_1_stable/sqplus/SqPlusOCharBuf.cpp rename to squirrel_3_0_1_stable/_OLD_sqplus/SqPlusOCharBuf.cpp index 4a0bd2a9b..7c49c33db 100644 --- a/squirrel_3_0_1_stable/sqplus/SqPlusOCharBuf.cpp +++ b/squirrel_3_0_1_stable/_OLD_sqplus/SqPlusOCharBuf.cpp @@ -1,61 +1,61 @@ - -#include "sqplus.h" -#include "SqPlusOCharBuf.h" - -#include - -// Conversion functions, between char* string and wchar_t* strings. - -int ol_strlen(const wchar_t* pwc){ return (int)wcslen(pwc); } -int ol_buflen(const wchar_t* pwc){ return (int)wcslen(pwc); } -int ol_charlen(const wchar_t* pwc){ return 1; } -//int ol_charlen(const wchar_t pwc){ return 1; } -int ol_char(const wchar_t* pwc){ return (int)*pwc; } -bool ol_writechar(wchar_t*& pwc, int ch){ *pwc=(wchar_t)ch; pwc++; return true; } - -int ol_buflen(const char* pc){ return (int)strlen(pc); } - -#if SQPLUS_USE_LATIN1==1 - // Convert to 8-bit LATIN1 char set. The only thing to do is convert chars out of range to '?' - int ol_strlen(const char* pc){ return (int)strlen(pc); } - int ol_charlen(const char* pc){ return 1; } - //int ol_charlen(int pc){ return 1; } - int ol_char(const char* pc){ return (int)*(unsigned char*)pc; } - bool ol_writechar(char*& pc, int ch){ *pc=(char)(ch>255?'?':ch); pc++; return true; } -#else - #include "SqPlusUtf8.h" - // Convert to 8-Bit UTF8 encoding. Some more work here. - int ol_strlen(const char* pc){ return sqplus_utf8_strlen(pc); } - int ol_charlen(const char* pc){ return sqplus_utf8_len_first(pc); } - //int ol_charlen(int ch){ char buf[8]; return sqplus_wchar_to_utf8(buf,ch,8); } - int ol_char(const char* pc){ int chr=-1; sqplus_utf8_to_wchar(&chr,pc); return chr; } - bool ol_writechar(char*& pc, int ch) { - int l=sqplus_wchar_to_utf8(pc,ch,8); - if(l>0){ - pc += l; - return true; - } - else return false; - } -#endif - - -#ifdef SQUNICODE - // SQChar is wchar_t, convert to/from to either Latin1 or UTF8 - SQDefCharBuf CH2SQ( const char* ps ){ - return SQDefCharBuf(ps); - } - SQOthCharBuf SQ2CH( const wchar_t* pws ){ - return SQOthCharBuf(pws); - } -#else - // SQChar is char, convert to/from wchar_t - SQDefCharBuf WC2SQ( const wchar_t* pws ){ - return SQDefCharBuf(pws); - } - SQOthCharBuf SQ2WC( const char* ps ){ - return SQOthCharBuf(ps); - } -#endif - - + +#include "sqplus.h" +#include "SqPlusOCharBuf.h" + +#include + +// Conversion functions, between char* string and wchar_t* strings. + +int ol_strlen(const wchar_t* pwc){ return (int)wcslen(pwc); } +int ol_buflen(const wchar_t* pwc){ return (int)wcslen(pwc); } +int ol_charlen(const wchar_t* pwc){ return 1; } +//int ol_charlen(const wchar_t pwc){ return 1; } +int ol_char(const wchar_t* pwc){ return (int)*pwc; } +bool ol_writechar(wchar_t*& pwc, int ch){ *pwc=(wchar_t)ch; pwc++; return true; } + +int ol_buflen(const char* pc){ return (int)strlen(pc); } + +#if SQPLUS_USE_LATIN1==1 + // Convert to 8-bit LATIN1 char set. The only thing to do is convert chars out of range to '?' + int ol_strlen(const char* pc){ return (int)strlen(pc); } + int ol_charlen(const char* pc){ return 1; } + //int ol_charlen(int pc){ return 1; } + int ol_char(const char* pc){ return (int)*(unsigned char*)pc; } + bool ol_writechar(char*& pc, int ch){ *pc=(char)(ch>255?'?':ch); pc++; return true; } +#else + #include "SqPlusUtf8.h" + // Convert to 8-Bit UTF8 encoding. Some more work here. + int ol_strlen(const char* pc){ return sqplus_utf8_strlen(pc); } + int ol_charlen(const char* pc){ return sqplus_utf8_len_first(pc); } + //int ol_charlen(int ch){ char buf[8]; return sqplus_wchar_to_utf8(buf,ch,8); } + int ol_char(const char* pc){ int chr=-1; sqplus_utf8_to_wchar(&chr,pc); return chr; } + bool ol_writechar(char*& pc, int ch) { + int l=sqplus_wchar_to_utf8(pc,ch,8); + if(l>0){ + pc += l; + return true; + } + else return false; + } +#endif + + +#ifdef SQUNICODE + // SQChar is wchar_t, convert to/from to either Latin1 or UTF8 + SQDefCharBuf CH2SQ( const char* ps ){ + return SQDefCharBuf(ps); + } + SQOthCharBuf SQ2CH( const wchar_t* pws ){ + return SQOthCharBuf(pws); + } +#else + // SQChar is char, convert to/from wchar_t + SQDefCharBuf WC2SQ( const wchar_t* pws ){ + return SQDefCharBuf(pws); + } + SQOthCharBuf SQ2WC( const char* ps ){ + return SQOthCharBuf(ps); + } +#endif + + diff --git a/squirrel_3_0_1_stable/sqplus/SqPlusOCharBuf.h b/squirrel_3_0_1_stable/_OLD_sqplus/SqPlusOCharBuf.h similarity index 96% rename from squirrel_3_0_1_stable/sqplus/SqPlusOCharBuf.h rename to squirrel_3_0_1_stable/_OLD_sqplus/SqPlusOCharBuf.h index c27e7c803..24fe16b16 100644 --- a/squirrel_3_0_1_stable/sqplus/SqPlusOCharBuf.h +++ b/squirrel_3_0_1_stable/_OLD_sqplus/SqPlusOCharBuf.h @@ -1,193 +1,193 @@ - -#ifndef SQPLUS_OCHARBUF_H -#define SQPLUS_OCHARBUF_H - -// Conversion routines between different character encodings, to be used in -// Push/Get/Match handlers of SqPlus. It enables using both of char* and -// wchar_t* as function arguments. -// -// When converting from wchar_t to char, the choice is between using a Latin1 -// or a UTF8 representation in 8-bit mode. This is probably most useful if -// Squirrel is compiled in ANSI mode and the app uses some wchar_t strings -// (UNICODE mode on Win32). -// - -// A char is either -// - A Latin1 character (first code page, coincides with Unicode points 0..255) -// - Part of an UTF8 character -// -// Note: SQUTF8 requires Squirrel sources that have been patched for UTF8 strings -// internally (when converting function arguments). - -#ifndef SQUTF8 - // Default to Latin1 conversion - //#undef SQPLUS_USE_LATIN1 - #ifndef SQPLUS_USE_LATIN1 - #define SQPLUS_USE_LATIN1 1 - #endif -#else - // Using Squirrel with internal UTF8 string encoding - //#undef SQPLUS_USE_LATIN1 - #ifndef SQPLUS_USE_LATIN1 - #define SQPLUS_USE_LATIN1 0 - #endif -#endif - - -// The various ol_... functions sets up for a conversion scheme -// that can be used in both wchar_t => char and char => wchar_t. -int ol_strlen(const wchar_t* pwc); -int ol_buflen(const wchar_t* pwc); -int ol_charlen(const wchar_t* pwc); -int ol_char(const wchar_t* pwc); -bool ol_writechar(wchar_t*& pwc, int ch); - -int ol_strlen(const char* pc); -int ol_buflen(const char* pc); -int ol_charlen(const char* pc); -int ol_char(const char* pc); -bool ol_writechar(char*& pc, int ch); - -#ifdef SQUNICODE - // SQChar is wchar_t, convert to/from either Latin1 or UTF8 - typedef char SQOtherChar; -#else - // SQChar is char, convert to/from wchar_t - typedef wchar_t SQOtherChar; -#endif - - -// Buffer to hold a string and release it in destructor. -// SQT is input character type -// SQOT is the opposite type of SQChar -// If 'try_borrow' is set, it will not allocate a new buffer when no -// conversion is done, it will just keep the input pointer (beware). -template -struct SQCharBufImpl { - - // Allocate a buffer from string of same type - SQCharBufImpl(const SQT *poc=NULL, bool try_borrow=true ) : m_poc(0), m_own(false) { - Init( poc, try_borrow ); - } - - // This does conversion from other char type - SQCharBufImpl(const SQOT *ps, bool try_borrow=false ) : m_poc(0), m_own(false) { - Init( ps ); // Cannot borrow pointer when doing conversion - } - - void Init( const SQT *poc, bool try_borrow ){ - m_own = !try_borrow; - if( try_borrow ){ - m_poc = (SQT*)poc; - } - else { - int sl = poc ? ol_buflen(poc) : 0; - if( poc ){ - m_poc = poc ? new SQT[sl+1] : NULL; - if( m_poc ) memcpy( m_poc, poc, (sl+1)*sizeof(SQT) ); - } - else - m_poc = NULL; - } - } - - void Init( const SQOT *ps ){ - m_own = true; - if( ps ){ - int sl = ps ? ol_strlen(ps) : 0; // Length of string in characters (not bytes) - int scl = 0; // Length of converted string in char/wchar_t count - // How much storage needed? - if( !use_latin1 && sizeof(SQT) UTF8 - const SQOT *ps1 = ps; // It is wchar_t* here - SQT tmp_buf[8]; - SQT *ptmp; - while( *ps1 ){ - ptmp = tmp_buf; - if( ol_writechar(ptmp,*ps1++) ) - scl += ol_charlen(tmp_buf); - else - scl++; - } - } - else scl = sl; // Converting to wchar_t or Latin1, keep length - - m_poc = new SQT[scl+1]; - if( !m_poc ) return; - - // Convert - SQT *poc = m_poc; - while( *ps ){ - ol_writechar( poc, ol_char(ps) ); - ps += ol_charlen(ps); - } - *poc = 0; // Terminating zero - } - else - m_poc = NULL; - } - - ~SQCharBufImpl(){ Release(); } - - void Release( ){ - if(m_poc && m_own ) - delete [] m_poc; - m_poc = NULL; - } - - SQT* Set( const SQOT *ps ){ - Release( ); - Init( ps ); - return m_poc; - } - - operator SQT*() const { return m_poc; } - - SQCharBufImpl& operator = (const SQT *ps){ - Release(); - Init( ps, false ); - return *this; - } - - SQCharBufImpl& operator = (const SQOT *ps){ - Release(); - Init( ps ); - return *this; - } - - // Move string from other here - Note: Empties the input argument (other) - SQCharBufImpl& operator = (const SQCharBufImpl& other){ - Release(); - m_poc = other.m_poc; - m_own = other.m_own; - SQT **psqt = (SQT**)&other.m_poc; - *psqt = NULL; - return *this; - } - -protected: - SQT *m_poc; - bool m_own; -}; - -typedef SQCharBufImpl SQOthCharBuf; -typedef SQCharBufImpl SQDefCharBuf; -typedef SQCharBufImpl SQWCharBuf; -typedef SQCharBufImpl SQACharBuf; - -#ifdef SQUNICODE - // SQChar is wchar_t, convert to/from to either Latin1 or UTF8 - #define WC2SQ(s) s - #define SQ2WC(s) s - SQDefCharBuf CH2SQ( const char* ps ); - SQOthCharBuf SQ2CH( const wchar_t* pws ); -#else - // SQChar is char, convert to/from wchar_t - SQDefCharBuf WC2SQ( const wchar_t* pws ); - SQOthCharBuf SQ2WC( const char* pws ); - #define CH2SQ(s) s - #define SQ2CH(s) s -#endif - -#endif // SQPLUS_CHARBUF_H - + +#ifndef SQPLUS_OCHARBUF_H +#define SQPLUS_OCHARBUF_H + +// Conversion routines between different character encodings, to be used in +// Push/Get/Match handlers of SqPlus. It enables using both of char* and +// wchar_t* as function arguments. +// +// When converting from wchar_t to char, the choice is between using a Latin1 +// or a UTF8 representation in 8-bit mode. This is probably most useful if +// Squirrel is compiled in ANSI mode and the app uses some wchar_t strings +// (UNICODE mode on Win32). +// + +// A char is either +// - A Latin1 character (first code page, coincides with Unicode points 0..255) +// - Part of an UTF8 character +// +// Note: SQUTF8 requires Squirrel sources that have been patched for UTF8 strings +// internally (when converting function arguments). + +#ifndef SQUTF8 + // Default to Latin1 conversion + //#undef SQPLUS_USE_LATIN1 + #ifndef SQPLUS_USE_LATIN1 + #define SQPLUS_USE_LATIN1 1 + #endif +#else + // Using Squirrel with internal UTF8 string encoding + //#undef SQPLUS_USE_LATIN1 + #ifndef SQPLUS_USE_LATIN1 + #define SQPLUS_USE_LATIN1 0 + #endif +#endif + + +// The various ol_... functions sets up for a conversion scheme +// that can be used in both wchar_t => char and char => wchar_t. +int ol_strlen(const wchar_t* pwc); +int ol_buflen(const wchar_t* pwc); +int ol_charlen(const wchar_t* pwc); +int ol_char(const wchar_t* pwc); +bool ol_writechar(wchar_t*& pwc, int ch); + +int ol_strlen(const char* pc); +int ol_buflen(const char* pc); +int ol_charlen(const char* pc); +int ol_char(const char* pc); +bool ol_writechar(char*& pc, int ch); + +#ifdef SQUNICODE + // SQChar is wchar_t, convert to/from either Latin1 or UTF8 + typedef char SQOtherChar; +#else + // SQChar is char, convert to/from wchar_t + typedef wchar_t SQOtherChar; +#endif + + +// Buffer to hold a string and release it in destructor. +// SQT is input character type +// SQOT is the opposite type of SQChar +// If 'try_borrow' is set, it will not allocate a new buffer when no +// conversion is done, it will just keep the input pointer (beware). +template +struct SQCharBufImpl { + + // Allocate a buffer from string of same type + SQCharBufImpl(const SQT *poc=NULL, bool try_borrow=true ) : m_poc(0), m_own(false) { + Init( poc, try_borrow ); + } + + // This does conversion from other char type + SQCharBufImpl(const SQOT *ps, bool try_borrow=false ) : m_poc(0), m_own(false) { + Init( ps ); // Cannot borrow pointer when doing conversion + } + + void Init( const SQT *poc, bool try_borrow ){ + m_own = !try_borrow; + if( try_borrow ){ + m_poc = (SQT*)poc; + } + else { + int sl = poc ? ol_buflen(poc) : 0; + if( poc ){ + m_poc = poc ? new SQT[sl+1] : NULL; + if( m_poc ) memcpy( m_poc, poc, (sl+1)*sizeof(SQT) ); + } + else + m_poc = NULL; + } + } + + void Init( const SQOT *ps ){ + m_own = true; + if( ps ){ + int sl = ps ? ol_strlen(ps) : 0; // Length of string in characters (not bytes) + int scl = 0; // Length of converted string in char/wchar_t count + // How much storage needed? + if( !use_latin1 && sizeof(SQT) UTF8 + const SQOT *ps1 = ps; // It is wchar_t* here + SQT tmp_buf[8]; + SQT *ptmp; + while( *ps1 ){ + ptmp = tmp_buf; + if( ol_writechar(ptmp,*ps1++) ) + scl += ol_charlen(tmp_buf); + else + scl++; + } + } + else scl = sl; // Converting to wchar_t or Latin1, keep length + + m_poc = new SQT[scl+1]; + if( !m_poc ) return; + + // Convert + SQT *poc = m_poc; + while( *ps ){ + ol_writechar( poc, ol_char(ps) ); + ps += ol_charlen(ps); + } + *poc = 0; // Terminating zero + } + else + m_poc = NULL; + } + + ~SQCharBufImpl(){ Release(); } + + void Release( ){ + if(m_poc && m_own ) + delete [] m_poc; + m_poc = NULL; + } + + SQT* Set( const SQOT *ps ){ + Release( ); + Init( ps ); + return m_poc; + } + + operator SQT*() const { return m_poc; } + + SQCharBufImpl& operator = (const SQT *ps){ + Release(); + Init( ps, false ); + return *this; + } + + SQCharBufImpl& operator = (const SQOT *ps){ + Release(); + Init( ps ); + return *this; + } + + // Move string from other here - Note: Empties the input argument (other) + SQCharBufImpl& operator = (const SQCharBufImpl& other){ + Release(); + m_poc = other.m_poc; + m_own = other.m_own; + SQT **psqt = (SQT**)&other.m_poc; + *psqt = NULL; + return *this; + } + +protected: + SQT *m_poc; + bool m_own; +}; + +typedef SQCharBufImpl SQOthCharBuf; +typedef SQCharBufImpl SQDefCharBuf; +typedef SQCharBufImpl SQWCharBuf; +typedef SQCharBufImpl SQACharBuf; + +#ifdef SQUNICODE + // SQChar is wchar_t, convert to/from to either Latin1 or UTF8 + #define WC2SQ(s) s + #define SQ2WC(s) s + SQDefCharBuf CH2SQ( const char* ps ); + SQOthCharBuf SQ2CH( const wchar_t* pws ); +#else + // SQChar is char, convert to/from wchar_t + SQDefCharBuf WC2SQ( const wchar_t* pws ); + SQOthCharBuf SQ2WC( const char* pws ); + #define CH2SQ(s) s + #define SQ2CH(s) s +#endif + +#endif // SQPLUS_CHARBUF_H + diff --git a/squirrel_3_0_1_stable/sqplus/SqPlusOverload.h b/squirrel_3_0_1_stable/_OLD_sqplus/SqPlusOverload.h similarity index 97% rename from squirrel_3_0_1_stable/sqplus/SqPlusOverload.h rename to squirrel_3_0_1_stable/_OLD_sqplus/SqPlusOverload.h index e205de366..9668469ad 100644 --- a/squirrel_3_0_1_stable/sqplus/SqPlusOverload.h +++ b/squirrel_3_0_1_stable/_OLD_sqplus/SqPlusOverload.h @@ -1,819 +1,819 @@ -// SqPlusOverload.h -// SqPlus function overloading support created by Katsuaki Kawachi. -// -// Const member function fixed Tegan -// from http://squirrel-lang.org/forums/thread/2160.aspx - -#ifdef SQPLUS_OVERLOAD_RELEASE_HOOK -#undef SQPLUS_OVERLOAD_RELEASE_HOOK - - // These end up int ClassType now - static inline int destruct(SQUserPointer up, SQInteger size) { - if (up) { - static_cast(up)->~T(); - sq_free(up, size); - } - return 0; - } - - static inline SQRELEASEHOOK &release(void) { - static SQRELEASEHOOK hook = ClassType::destruct; - return hook; - } - - void releaseHook(SQRELEASEHOOK releaseHook) { - release() = releaseHook; - //return *this; - } - - static inline SQRELEASEHOOK &getReleaseHook(void) { - return release(); - } - -#endif // SQPLUS_OVERLOAD_RELEASE_HOOK - - -#ifdef SQPLUS_OVERLOAD_DECLARATION -#undef SQPLUS_OVERLOAD_DECLARATION - -template struct Arg; - -#endif // SQPLUS_OVERLOAD_DECLARATION - - -#ifdef SQPLUS_OVERLOAD_IMPLEMENTATION -#undef SQPLUS_OVERLOAD_IMPLEMENTATION -private: - class SQFuncHolder { - private: - template - class FlexArray { - protected: - SquirrelObject array; - public: - FlexArray(int size = 0) { - this->resize(size); - } - int size(void) const { - return array.Len(); - } - void resize(int newSize) { - if (this->size() == 0) { - array = SquirrelVM::CreateArray(newSize); - } else { - array.ArrayResize(newSize); - } - } - void push_back(const T &t) { - this->set(this->size(), t); - } - void set(int index, const T &t) { - get(index) = t; - } - T &get(int index) { - if (index >= array.Len()) { - resize(index + 1); - } - SQUserPointer up = array.GetUserPointer(index); - if (!up) { - up = sq_newuserdata(SquirrelVM::GetVMPtr(), sizeof(T)); - new(static_cast(up)) T; - array.SetUserPointer(index, up); - } - return *static_cast(up); - } - }; - /* - storage of wrapped C++ functions - */ - typedef SQInteger(*WrappedFunction)(HSQUIRRELVM, bool, int); - typedef FlexArray SQWrappedFuncArray; - typedef FlexArray SQWrappedFuncArray2 ; - typedef FlexArray SQWrappedFuncArray3 ; - - struct MemberHolder { - static SQWrappedFuncArray &funcs(int functionIndex, - int paramCount) { - static SQWrappedFuncArray3 funcs; - return funcs.get(paramCount).get(functionIndex); - } - }; - struct StaticHolder { - static SQWrappedFuncArray &funcs(int functionIndex, - int paramCount) { - static SQWrappedFuncArray3 funcs; - return funcs.get(paramCount).get(functionIndex); - } - }; - struct ConstructorHolder { - static SQWrappedFuncArray &funcs(int paramCount) { - static SQWrappedFuncArray2 funcs; - return funcs.get(paramCount); - } - }; - - /* - wrapper for C++ functions - */ - template struct MemberDispatcher { - static inline FlexArray &mfunc(void) { - static FlexArray mfunc; - return mfunc; - } - static inline SQInteger - dispatch(HSQUIRRELVM v, bool execute, int functionIndex) { - return execute ? - Call(*GetInstance(v, 1), - mfunc().get(functionIndex), v, 2) : - Arg::argTypeDistance(v); - } - }; - template struct StaticDispatcher { - static inline FlexArray &sfunc(void) { - static FlexArray sfunc; - return sfunc; - } - static inline SQInteger - dispatch(HSQUIRRELVM v, bool execute, int functionIndex) { - return execute ? - Call(sfunc().get(functionIndex), v, 2) : - Arg::argTypeDistance(v); - } - }; - template struct Constructor { - static inline Cfunc &cfunc(void) { - static Cfunc cfunc = 0; - return cfunc; - } - static inline SQInteger - construct(HSQUIRRELVM v, bool execute, int) { - return execute ? - Call(cfunc(), v, 2) : - Arg::argTypeDistance(v); - } - }; - - // search and call an overloaded function on runtime - static inline SQInteger - call(SQWrappedFuncArray &funcs, HSQUIRRELVM v, int functionIndex = 0) { - bool ambiguous = false; - int imin = -1; - int dmin = INT_MAX; - for (int i = 0, size = funcs.size(); i < size; ++i) { - // FIXME: to be refactored - const int d = (**funcs.get(i))(v, false, functionIndex); - if (d == 0) { // complete match - imin = i; - ambiguous = false; - goto SQPLUS_OVERLOAD_CALL_IMMEDIATE_EXECUTION; - } else if (0 < d && d < dmin) { - dmin = d; - imin = i; - ambiguous = false; - } else if (d == dmin) { - ambiguous = true; - } - } - - if (ambiguous) { - return sq_throwerror( - v, _SC("Call of overloaded function is ambiguous") - ); - } else if (imin == -1) { - return sq_throwerror( - v, _SC("No match for given arguments") - ); - } - - SQPLUS_OVERLOAD_CALL_IMMEDIATE_EXECUTION: - // FIXME: to be refactored - return (**funcs.get(imin))(v, true, functionIndex); - } - - public: - template static inline void - addMemberFunc(int functionIndex, Mfunc mfunc) { - MemberHolder::funcs(functionIndex, Arg::num()).push_back( - &MemberDispatcher::dispatch - ); - MemberDispatcher::mfunc().set(functionIndex, mfunc); - } - template static inline void - addStaticFunc(int functionIndex, Sfunc sfunc) { - StaticHolder::funcs(functionIndex, Arg::num()).push_back( - &StaticDispatcher::dispatch - ); - StaticDispatcher::sfunc().set(functionIndex, sfunc); - } - template static inline void - addConstructor(Cfunc cfunc) { - ConstructorHolder::funcs(Arg::num()).push_back( - &Constructor::construct - ); - Constructor::cfunc() = cfunc; - } - - static inline SQInteger - memberCall(int paramCount, HSQUIRRELVM v, int functionIndex) { - return call(MemberHolder::funcs(functionIndex, paramCount), - v, functionIndex); - } - static inline SQInteger - staticCall(int paramCount, HSQUIRRELVM v, int functionIndex) { - return call(StaticHolder::funcs(functionIndex, paramCount), - v, functionIndex); - } - static inline SQInteger - constructorCall(int paramCount, HSQUIRRELVM v, int) { - return call(ConstructorHolder::funcs(paramCount), v); - } - }; // class SQFuncHolder - - - struct FunctionNameEnumerator { - SquirrelObject names; - FunctionNameEnumerator(void) : names(SquirrelVM::CreateTable()) {} - int index(const SQChar *n) { - int i; - SquirrelObject v = names.GetValue(n); - if (v.IsNull()) { - i = names.Len(); - names.SetValue(n, i); - } else { - i = v.ToInteger(); - } - return i; - } - }; - - FunctionNameEnumerator overloadedMemberNames; - FunctionNameEnumerator overloadedStaticMemberNames; - - static SquirrelObject & - functionIndexHolders(HSQUIRRELVM v) { - static SquirrelObject indexHolders; - if (indexHolders.IsNull()) { - sq_newtable(v); - indexHolders.AttachToStackObject(-1); - sq_pop(v, 1); - } - return indexHolders; - } - - template - static SquirrelObject & - indexHolder(HSQUIRRELVM v) { - static SquirrelObject holder; - if (holder.IsNull()) { - sq_pushobject(v, functionIndexHolders(v).GetObjectHandle()); - sq_pushinteger(v, N); - if (SQ_OK == sq_rawget(v, -2)) { - holder.AttachToStackObject(-1); - sq_pop(v, 3); - } else { - sq_pushinteger(v, N); - sq_newtable(v); - holder.AttachToStackObject(-1); - sq_rawset(v, -3); - sq_pop(v, 1); - } - } - return holder; - } - - template - class SQOverloader { - private: - static inline SQInteger switcher(HSQUIRRELVM v, - int(*caller)(int, HSQUIRRELVM, int), - int fidx) { - return (*caller)(StackHandler(v).GetParamCount() - 1, - v, - fidx); - } - - static inline SQInteger memberSwitcher(HSQUIRRELVM v) { - SQInteger fidx; - sq_pushobject(v, indexHolder<0>(v).GetObjectHandle()); - sq_push(v, 0); // native closure - sq_rawget(v, -2); - sq_getinteger(v, -1, &fidx); - sq_pop(v, 2); - return switcher(v, SQFuncHolder::memberCall, fidx); - } - static inline SQInteger staticSwitcher(HSQUIRRELVM v) { - SQInteger fidx; - sq_pushobject(v, indexHolder<1>(v).GetObjectHandle()); - sq_push(v, 0); // native closure - sq_rawget(v, -2); - sq_getinteger(v, -1, &fidx); - sq_pop(v, 2); - return switcher(v, SQFuncHolder::staticCall, fidx); - } - static inline SQInteger constructorSwitcher(HSQUIRRELVM v) { - return switcher(v, SQFuncHolder::constructorCall, 0); - } - - public: - static inline void addMemberFunc(SQClassDefBase *def, - Func mfunc, - const SQChar *name) { - const int fidx = def->overloadedMemberNames.index(name); - SQFuncHolder::addMemberFunc(fidx, mfunc); - def->staticFuncVarArgs(memberSwitcher, name); - - HSQUIRRELVM v = def->v; - // get closure - sq_pushobject(v, def->newClass.GetObjectHandle()); - sq_pushstring(v, name, -1); - sq_rawget(v, -2); - // holder[closure] = fidx - sq_pushobject(v, indexHolder<0>(v).GetObjectHandle()); - sq_push(v, -2); - sq_pushinteger(v, fidx); - sq_rawset(v, -3); - // - sq_pop(v, 3); - } - - static inline void addOperatorFunc(SQClassDefBase *def, - Func ofunc, - const SQChar *name) { - if (Arg::num() != 1) { - //assert(false && - // "Cannot add this function as operator (argc != 1)"); - abort(); - } - SQChar proxy[256]; - scsprintf(proxy, _SC("overloaded%s"), name); - - addMemberFunc(def, ofunc, proxy); - - SQChar script[512]; - scsprintf(script, _SC("%s.%s<-function(o){return %s.%s(o);}"), - def->name, name, def->name, proxy); - SquirrelVM::RunScript(SquirrelVM::CompileBuffer(script)); - } - - static inline void addStaticFunc(SQClassDefBase *def, - Func sfunc, - const SQChar *name) { - const int fidx = def->overloadedStaticMemberNames.index(name); - SQFuncHolder::addStaticFunc(fidx, sfunc); - def->staticFuncVarArgs(staticSwitcher, name); - - HSQUIRRELVM v = def->v; - // get closure - sq_pushobject(v, def->newClass.GetObjectHandle()); - sq_pushstring(v, name, -1); - sq_rawget(v, -2); - - // holder[closure] = fidx - sq_pushobject(v, indexHolder<1>(v).GetObjectHandle()); - sq_push(v, -2); - sq_pushinteger(v, fidx); - sq_rawset(v, -3); - // - sq_pop(v, 3); - } - template - static inline void addConstructor(SQClassDefBase *def, - Cfunc cfunc) { - SQFuncHolder::addConstructor(cfunc); - def->staticFuncVarArgs(constructorSwitcher, _SC("constructor")); - } - static inline void addGlobalFunc(SQClassDefBase *def, - Func gfunc, - const SQChar *name) { - const int fidx = def->overloadedStaticMemberNames.index(name); - SQFuncHolder::addStaticFunc(fidx, gfunc); - SquirrelVM::CreateFunctionGlobal(staticSwitcher, name, _SC("*")); - - HSQUIRRELVM v = def->v; - // get closure - sq_pushroottable(v); - sq_pushstring(v, name, -1); - sq_rawget(v, -2); - - // holder[closure] = fidx - sq_pushobject(v, indexHolder<1>(v).GetObjectHandle()); - sq_push(v, -2); - sq_pushinteger(v, fidx); - sq_rawset(v, -3); - // - sq_pop(v, 3); - } - }; - -public: - template - SQClassDefBase &overloadFunc(Mfunc mfunc, const SQChar *n) { - SQOverloader::addMemberFunc(this, mfunc, n); - return *this; - } - template - SQClassDefBase &overloadOperator(Ofunc ofunc, const SQChar *n){ - SQOverloader::addOperatorFunc(this, ofunc, n); - return *this; - } - template - SQClassDefBase &overloadStaticFunc(Sfunc sfunc, - const SQChar *n) { - SQOverloader::addStaticFunc(this, sfunc, n); - return *this; - } - template - SQClassDefBase &overloadConstructor(void) { - SQOverloader::addConstructor(this, &Arg::create); - return *this; - } - template - SQClassDefBase &overloadConstructor(Cfunc cfunc) { - SQOverloader::addConstructor(this, cfunc); - return *this; - } - template - SQClassDefBase &overloadGlobalFunc(Gfunc gfunc, - const SQChar *n) { - SQOverloader::addGlobalFunc(this, gfunc, n); - return *this; - } - - -#endif // SQPLUS_OVERLOAD_IMPLEMENTATION - - - -#ifdef SQPLUS_OVERLOAD_FUNCTIONS -#undef SQPLUS_OVERLOAD_FUNCTIONS - -struct GlobalFuncOverloader {}; -static inline SQClassDefBase &globalFuncOverloader(void) -{ - static SQClassDefBase fo(_SC("GlobalFuncOverloader")); - return fo; -} - -template void -OverloadGlobal(Gfunc gfunc, const SQChar *n) -{ - globalFuncOverloader().overloadGlobalFunc(gfunc, n); -} - -template struct CheckInstance { - template struct unref {typedef T type;}; - template struct unref {typedef T type;}; - template struct unref {typedef T type;}; - template struct unref {typedef T type;}; - template struct unref {typedef T type;}; - - /* - d = -1 : not in hierarchy - d = 0 : same - d > 0 : similar (o is d-th subclass of TYPE) - */ - static inline int distance(HSQUIRRELVM v, int index) { - HSQOBJECT o; - sq_resetobject(&o); - sq_getstackobj(v, index, &o); - - const int top = sq_gettop(v); - sq_pushroottable(v); - - // Check plain object type - int d = -1; - if (Match(TypeWrapper(), v, index)) { - d = 0; - - // Check instance type hierarchy - if (sq_type(o) == OT_INSTANCE) { - SQUserPointer dsttype = - ClassType::type>::type(); - - SQUserPointer argtype; - for (sq_getclass(v, index); - sq_gettypetag(v, -1, &argtype) == SQ_OK; - sq_getbase(v, -1)) { - if (argtype == dsttype) { - goto SQPLUS_OVERLOAD_DISTANCE_IMMEDIATE_RETURN; - } - ++d; - } - d = -1; // no matching type found - } - } - SQPLUS_OVERLOAD_DISTANCE_IMMEDIATE_RETURN: - sq_settop(v, top); - return d; - } -}; - - -template -struct Arg { - static inline int num(void) {return 0;} - static inline int argTypeDistance(HSQUIRRELVM) { - return 0; - } -}; - -template -struct Arg { - static inline int num(void) {return 1;} - static inline int argTypeDistance(HSQUIRRELVM v) { - return Arg::argTypeDistance(v); - } -}; - -template -struct Arg { - static inline int num(void) {return 2;} - static inline int argTypeDistance(HSQUIRRELVM v) { - return Arg::argTypeDistance(v); - } -}; - -template -struct Arg { - static inline int num(void) {return 3;} - static inline int argTypeDistance(HSQUIRRELVM v) { - return Arg::argTypeDistance(v); - } -}; - -template -struct Arg { - static inline int num(void) {return 4;} - static inline int argTypeDistance(HSQUIRRELVM v) { - return Arg::argTypeDistance(v); - } -}; - -template -struct Arg { - static inline int num(void) {return 5;} - static inline int argTypeDistance(HSQUIRRELVM v) { - return Arg::argTypeDistance(v); - } -}; - -template -struct Arg { - static inline int num(void) {return 6;} - static inline int argTypeDistance(HSQUIRRELVM v) { - return Arg::argTypeDistance(v); - } -}; - -template -struct Arg { - static inline int num(void) {return 7;} - static inline int argTypeDistance(HSQUIRRELVM v) { - return Arg::argTypeDistance(v); - } -}; - -#ifdef SQPLUS_CONST_OPT -template -struct Arg { - static inline int num(void) {return 0;} - static inline int argTypeDistance(HSQUIRRELVM) { - return 0; - } -}; - -template -struct Arg { - static inline int num(void) {return 1;} - static inline int argTypeDistance(HSQUIRRELVM v) { - return Arg::argTypeDistance(v); - } -}; - -template -struct Arg { - static inline int num(void) {return 2;} - static inline int argTypeDistance(HSQUIRRELVM v) { - return Arg::argTypeDistance(v); - } -}; - -template -struct Arg { - static inline int num(void) {return 3;} - static inline int argTypeDistance(HSQUIRRELVM v) { - return Arg::argTypeDistance(v); - } -}; - -template -struct Arg { - static inline int num(void) {return 4;} - static inline int argTypeDistance(HSQUIRRELVM v) { - return Arg::argTypeDistance(v); - } -}; - -template -struct Arg { - static inline int num(void) {return 5;} - static inline int argTypeDistance(HSQUIRRELVM v) { - return Arg::argTypeDistance(v); - } -}; - -template -struct Arg { - static inline int num(void) {return 6;} - static inline int argTypeDistance(HSQUIRRELVM v) { - return Arg::argTypeDistance(v); - } -}; - -template -struct Arg { - static inline int num(void) {return 7;} - static inline int argTypeDistance(HSQUIRRELVM v) { - return Arg::argTypeDistance(v); - } -}; -#endif - -static inline int classAllocationError(HSQUIRRELVM v) { - return sq_throwerror(v, _SC("Failed to allocate memory")); -} - -template -struct Arg { - static inline int num(void) {return 0;} - static inline int argTypeDistance(HSQUIRRELVM) {return 0;} - static inline int create(void) { - HSQUIRRELVM v = SquirrelVM::GetVMPtr(); - R *r = static_cast(sq_malloc(sizeof(R))); - return r ? - PostConstruct(v, new(r) R, - ClassType::getReleaseHook()) : - classAllocationError(v); - } -}; - -template -struct Arg { - static inline int num(void) {return 1;} - static inline int argTypeDistance(HSQUIRRELVM v) { - int s, r; - r = 0; - s = CheckInstance::distance(v, 2); if (s < 0) {return -1;} r += s; - return r; - } - static inline int create(A1 a1) { - HSQUIRRELVM v = SquirrelVM::GetVMPtr(); - R *r = static_cast(sq_malloc(sizeof(R))); - return r ? - PostConstruct(v, new(r) R(a1), - ClassType::getReleaseHook()) : - classAllocationError(v); - } -}; - -template -struct Arg { - static inline int num(void) {return 2;} - static inline int argTypeDistance(HSQUIRRELVM v) { - int s, r; - r = 0; - s = CheckInstance::distance(v, 2); if (s < 0) {return -1;} r += s; - s = CheckInstance::distance(v, 3); if (s < 0) {return -1;} r += s; - return r; - } - static inline int create(A1 a1, A2 a2) { - HSQUIRRELVM v = SquirrelVM::GetVMPtr(); - R *r = static_cast(sq_malloc(sizeof(R))); - return r ? - PostConstruct(v, new(r) R(a1, a2), - ClassType::getReleaseHook()) : - classAllocationError(v); - } -}; - -template -struct Arg { - static inline int num(void) {return 3;} - static inline int argTypeDistance(HSQUIRRELVM v) { - int s, r; - r = 0; - s = CheckInstance::distance(v, 2); if (s < 0) {return -1;} r += s; - s = CheckInstance::distance(v, 3); if (s < 0) {return -1;} r += s; - s = CheckInstance::distance(v, 4); if (s < 0) {return -1;} r += s; - return r; - } - static inline int create(A1 a1, A2 a2, A3 a3) { - HSQUIRRELVM v = SquirrelVM::GetVMPtr(); - R *r = static_cast(sq_malloc(sizeof(R))); - return r ? - PostConstruct(v, new(r) R(a1, a2, a3), - ClassType::getReleaseHook()) : - classAllocationError(v); - } -}; - -template -struct Arg { - static inline int num(void) {return 4;} - static inline int argTypeDistance(HSQUIRRELVM v) { - int s, r; - r = 0; - s = CheckInstance::distance(v, 2); if (s < 0) {return -1;} r += s; - s = CheckInstance::distance(v, 3); if (s < 0) {return -1;} r += s; - s = CheckInstance::distance(v, 4); if (s < 0) {return -1;} r += s; - s = CheckInstance::distance(v, 5); if (s < 0) {return -1;} r += s; - return r; - } - static inline int create(A1 a1, A2 a2, A3 a3, A4 a4) { - HSQUIRRELVM v = SquirrelVM::GetVMPtr(); - R *r = static_cast(sq_malloc(sizeof(R))); - return r ? - PostConstruct(v, new(r) R(a1, a2, a3, a4), - ClassType::getReleaseHook()) : - classAllocationError(v); - } -}; - -template -struct Arg { - static inline int num(void) {return 5;} - static inline int argTypeDistance(HSQUIRRELVM v) { - int s, r; - r = 0; - s = CheckInstance::distance(v, 2); if (s < 0) {return -1;} r += s; - s = CheckInstance::distance(v, 3); if (s < 0) {return -1;} r += s; - s = CheckInstance::distance(v, 4); if (s < 0) {return -1;} r += s; - s = CheckInstance::distance(v, 5); if (s < 0) {return -1;} r += s; - s = CheckInstance::distance(v, 6); if (s < 0) {return -1;} r += s; - return r; - } - static inline int create(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) { - HSQUIRRELVM v = SquirrelVM::GetVMPtr(); - R *r = static_cast(sq_malloc(sizeof(R))); - return r ? - PostConstruct(v, new(r) R(a1, a2, a3, a4, a5), - ClassType::getReleaseHook()) : - classAllocationError(v); - } -}; - -template -struct Arg { - static inline int num(void) {return 6;} - static inline int argTypeDistance(HSQUIRRELVM v) { - int s, r; - r = 0; - s = CheckInstance::distance(v, 2); if (s < 0) {return -1;} r += s; - s = CheckInstance::distance(v, 3); if (s < 0) {return -1;} r += s; - s = CheckInstance::distance(v, 4); if (s < 0) {return -1;} r += s; - s = CheckInstance::distance(v, 5); if (s < 0) {return -1;} r += s; - s = CheckInstance::distance(v, 6); if (s < 0) {return -1;} r += s; - s = CheckInstance::distance(v, 7); if (s < 0) {return -1;} r += s; - return r; - } - static inline int create(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) { - HSQUIRRELVM v = SquirrelVM::GetVMPtr(); - R *r = static_cast(sq_malloc(sizeof(R))); - return r ? - PostConstruct(v, new(r) R(a1, a2, a3, a4, a5, a6), - ClassType::getReleaseHook()) : - classAllocationError(v); - } -}; - -template -struct Arg { - static inline int num(void) {return 7;} - static inline int argTypeDistance(HSQUIRRELVM v) { - int s, r; - r = 0; - s = CheckInstance::distance(v, 2); if (s < 0) {return -1;} r += s; - s = CheckInstance::distance(v, 3); if (s < 0) {return -1;} r += s; - s = CheckInstance::distance(v, 4); if (s < 0) {return -1;} r += s; - s = CheckInstance::distance(v, 5); if (s < 0) {return -1;} r += s; - s = CheckInstance::distance(v, 6); if (s < 0) {return -1;} r += s; - s = CheckInstance::distance(v, 7); if (s < 0) {return -1;} r += s; - s = CheckInstance::distance(v, 8); if (s < 0) {return -1;} r += s; - return r; - } - static inline int create(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) { - HSQUIRRELVM v = SquirrelVM::GetVMPtr(); - R *r = static_cast(sq_malloc(sizeof(R))); - return r ? - PostConstruct(v, new(r) R(a1, a2, a3, a4, a5, a6, a7), - ClassType::getReleaseHook()) : - classAllocationError(v); - } -}; -#endif // SQPLUS_OVERLOAD_FUNCTIONS - -// SqPlusOverload.h - -// Local Variables: -// mode: c++ -// End: +// SqPlusOverload.h +// SqPlus function overloading support created by Katsuaki Kawachi. +// +// Const member function fixed Tegan +// from http://squirrel-lang.org/forums/thread/2160.aspx + +#ifdef SQPLUS_OVERLOAD_RELEASE_HOOK +#undef SQPLUS_OVERLOAD_RELEASE_HOOK + + // These end up int ClassType now + static inline int destruct(SQUserPointer up, SQInteger size) { + if (up) { + static_cast(up)->~T(); + sq_free(up, size); + } + return 0; + } + + static inline SQRELEASEHOOK &release(void) { + static SQRELEASEHOOK hook = ClassType::destruct; + return hook; + } + + void releaseHook(SQRELEASEHOOK releaseHook) { + release() = releaseHook; + //return *this; + } + + static inline SQRELEASEHOOK &getReleaseHook(void) { + return release(); + } + +#endif // SQPLUS_OVERLOAD_RELEASE_HOOK + + +#ifdef SQPLUS_OVERLOAD_DECLARATION +#undef SQPLUS_OVERLOAD_DECLARATION + +template struct Arg; + +#endif // SQPLUS_OVERLOAD_DECLARATION + + +#ifdef SQPLUS_OVERLOAD_IMPLEMENTATION +#undef SQPLUS_OVERLOAD_IMPLEMENTATION +private: + class SQFuncHolder { + private: + template + class FlexArray { + protected: + SquirrelObject array; + public: + FlexArray(int size = 0) { + this->resize(size); + } + int size(void) const { + return array.Len(); + } + void resize(int newSize) { + if (this->size() == 0) { + array = SquirrelVM::CreateArray(newSize); + } else { + array.ArrayResize(newSize); + } + } + void push_back(const T &t) { + this->set(this->size(), t); + } + void set(int index, const T &t) { + get(index) = t; + } + T &get(int index) { + if (index >= array.Len()) { + resize(index + 1); + } + SQUserPointer up = array.GetUserPointer(index); + if (!up) { + up = sq_newuserdata(SquirrelVM::GetVMPtr(), sizeof(T)); + new(static_cast(up)) T; + array.SetUserPointer(index, up); + } + return *static_cast(up); + } + }; + /* + storage of wrapped C++ functions + */ + typedef SQInteger(*WrappedFunction)(HSQUIRRELVM, bool, int); + typedef FlexArray SQWrappedFuncArray; + typedef FlexArray SQWrappedFuncArray2 ; + typedef FlexArray SQWrappedFuncArray3 ; + + struct MemberHolder { + static SQWrappedFuncArray &funcs(int functionIndex, + int paramCount) { + static SQWrappedFuncArray3 funcs; + return funcs.get(paramCount).get(functionIndex); + } + }; + struct StaticHolder { + static SQWrappedFuncArray &funcs(int functionIndex, + int paramCount) { + static SQWrappedFuncArray3 funcs; + return funcs.get(paramCount).get(functionIndex); + } + }; + struct ConstructorHolder { + static SQWrappedFuncArray &funcs(int paramCount) { + static SQWrappedFuncArray2 funcs; + return funcs.get(paramCount); + } + }; + + /* + wrapper for C++ functions + */ + template struct MemberDispatcher { + static inline FlexArray &mfunc(void) { + static FlexArray mfunc; + return mfunc; + } + static inline SQInteger + dispatch(HSQUIRRELVM v, bool execute, int functionIndex) { + return execute ? + Call(*GetInstance(v, 1), + mfunc().get(functionIndex), v, 2) : + Arg::argTypeDistance(v); + } + }; + template struct StaticDispatcher { + static inline FlexArray &sfunc(void) { + static FlexArray sfunc; + return sfunc; + } + static inline SQInteger + dispatch(HSQUIRRELVM v, bool execute, int functionIndex) { + return execute ? + Call(sfunc().get(functionIndex), v, 2) : + Arg::argTypeDistance(v); + } + }; + template struct Constructor { + static inline Cfunc &cfunc(void) { + static Cfunc cfunc = 0; + return cfunc; + } + static inline SQInteger + construct(HSQUIRRELVM v, bool execute, int) { + return execute ? + Call(cfunc(), v, 2) : + Arg::argTypeDistance(v); + } + }; + + // search and call an overloaded function on runtime + static inline SQInteger + call(SQWrappedFuncArray &funcs, HSQUIRRELVM v, int functionIndex = 0) { + bool ambiguous = false; + int imin = -1; + int dmin = INT_MAX; + for (int i = 0, size = funcs.size(); i < size; ++i) { + // FIXME: to be refactored + const int d = (**funcs.get(i))(v, false, functionIndex); + if (d == 0) { // complete match + imin = i; + ambiguous = false; + goto SQPLUS_OVERLOAD_CALL_IMMEDIATE_EXECUTION; + } else if (0 < d && d < dmin) { + dmin = d; + imin = i; + ambiguous = false; + } else if (d == dmin) { + ambiguous = true; + } + } + + if (ambiguous) { + return sq_throwerror( + v, _SC("Call of overloaded function is ambiguous") + ); + } else if (imin == -1) { + return sq_throwerror( + v, _SC("No match for given arguments") + ); + } + + SQPLUS_OVERLOAD_CALL_IMMEDIATE_EXECUTION: + // FIXME: to be refactored + return (**funcs.get(imin))(v, true, functionIndex); + } + + public: + template static inline void + addMemberFunc(int functionIndex, Mfunc mfunc) { + MemberHolder::funcs(functionIndex, Arg::num()).push_back( + &MemberDispatcher::dispatch + ); + MemberDispatcher::mfunc().set(functionIndex, mfunc); + } + template static inline void + addStaticFunc(int functionIndex, Sfunc sfunc) { + StaticHolder::funcs(functionIndex, Arg::num()).push_back( + &StaticDispatcher::dispatch + ); + StaticDispatcher::sfunc().set(functionIndex, sfunc); + } + template static inline void + addConstructor(Cfunc cfunc) { + ConstructorHolder::funcs(Arg::num()).push_back( + &Constructor::construct + ); + Constructor::cfunc() = cfunc; + } + + static inline SQInteger + memberCall(int paramCount, HSQUIRRELVM v, int functionIndex) { + return call(MemberHolder::funcs(functionIndex, paramCount), + v, functionIndex); + } + static inline SQInteger + staticCall(int paramCount, HSQUIRRELVM v, int functionIndex) { + return call(StaticHolder::funcs(functionIndex, paramCount), + v, functionIndex); + } + static inline SQInteger + constructorCall(int paramCount, HSQUIRRELVM v, int) { + return call(ConstructorHolder::funcs(paramCount), v); + } + }; // class SQFuncHolder + + + struct FunctionNameEnumerator { + SquirrelObject names; + FunctionNameEnumerator(void) : names(SquirrelVM::CreateTable()) {} + int index(const SQChar *n) { + int i; + SquirrelObject v = names.GetValue(n); + if (v.IsNull()) { + i = names.Len(); + names.SetValue(n, i); + } else { + i = v.ToInteger(); + } + return i; + } + }; + + FunctionNameEnumerator overloadedMemberNames; + FunctionNameEnumerator overloadedStaticMemberNames; + + static SquirrelObject & + functionIndexHolders(HSQUIRRELVM v) { + static SquirrelObject indexHolders; + if (indexHolders.IsNull()) { + sq_newtable(v); + indexHolders.AttachToStackObject(-1); + sq_pop(v, 1); + } + return indexHolders; + } + + template + static SquirrelObject & + indexHolder(HSQUIRRELVM v) { + static SquirrelObject holder; + if (holder.IsNull()) { + sq_pushobject(v, functionIndexHolders(v).GetObjectHandle()); + sq_pushinteger(v, N); + if (SQ_OK == sq_rawget(v, -2)) { + holder.AttachToStackObject(-1); + sq_pop(v, 3); + } else { + sq_pushinteger(v, N); + sq_newtable(v); + holder.AttachToStackObject(-1); + sq_rawset(v, -3); + sq_pop(v, 1); + } + } + return holder; + } + + template + class SQOverloader { + private: + static inline SQInteger switcher(HSQUIRRELVM v, + int(*caller)(int, HSQUIRRELVM, int), + int fidx) { + return (*caller)(StackHandler(v).GetParamCount() - 1, + v, + fidx); + } + + static inline SQInteger memberSwitcher(HSQUIRRELVM v) { + SQInteger fidx; + sq_pushobject(v, indexHolder<0>(v).GetObjectHandle()); + sq_push(v, 0); // native closure + sq_rawget(v, -2); + sq_getinteger(v, -1, &fidx); + sq_pop(v, 2); + return switcher(v, SQFuncHolder::memberCall, fidx); + } + static inline SQInteger staticSwitcher(HSQUIRRELVM v) { + SQInteger fidx; + sq_pushobject(v, indexHolder<1>(v).GetObjectHandle()); + sq_push(v, 0); // native closure + sq_rawget(v, -2); + sq_getinteger(v, -1, &fidx); + sq_pop(v, 2); + return switcher(v, SQFuncHolder::staticCall, fidx); + } + static inline SQInteger constructorSwitcher(HSQUIRRELVM v) { + return switcher(v, SQFuncHolder::constructorCall, 0); + } + + public: + static inline void addMemberFunc(SQClassDefBase *def, + Func mfunc, + const SQChar *name) { + const int fidx = def->overloadedMemberNames.index(name); + SQFuncHolder::addMemberFunc(fidx, mfunc); + def->staticFuncVarArgs(memberSwitcher, name); + + HSQUIRRELVM v = def->v; + // get closure + sq_pushobject(v, def->newClass.GetObjectHandle()); + sq_pushstring(v, name, -1); + sq_rawget(v, -2); + // holder[closure] = fidx + sq_pushobject(v, indexHolder<0>(v).GetObjectHandle()); + sq_push(v, -2); + sq_pushinteger(v, fidx); + sq_rawset(v, -3); + // + sq_pop(v, 3); + } + + static inline void addOperatorFunc(SQClassDefBase *def, + Func ofunc, + const SQChar *name) { + if (Arg::num() != 1) { + //assert(false && + // "Cannot add this function as operator (argc != 1)"); + abort(); + } + SQChar proxy[256]; + scsprintf(proxy, _SC("overloaded%s"), name); + + addMemberFunc(def, ofunc, proxy); + + SQChar script[512]; + scsprintf(script, _SC("%s.%s<-function(o){return %s.%s(o);}"), + def->name, name, def->name, proxy); + SquirrelVM::RunScript(SquirrelVM::CompileBuffer(script)); + } + + static inline void addStaticFunc(SQClassDefBase *def, + Func sfunc, + const SQChar *name) { + const int fidx = def->overloadedStaticMemberNames.index(name); + SQFuncHolder::addStaticFunc(fidx, sfunc); + def->staticFuncVarArgs(staticSwitcher, name); + + HSQUIRRELVM v = def->v; + // get closure + sq_pushobject(v, def->newClass.GetObjectHandle()); + sq_pushstring(v, name, -1); + sq_rawget(v, -2); + + // holder[closure] = fidx + sq_pushobject(v, indexHolder<1>(v).GetObjectHandle()); + sq_push(v, -2); + sq_pushinteger(v, fidx); + sq_rawset(v, -3); + // + sq_pop(v, 3); + } + template + static inline void addConstructor(SQClassDefBase *def, + Cfunc cfunc) { + SQFuncHolder::addConstructor(cfunc); + def->staticFuncVarArgs(constructorSwitcher, _SC("constructor")); + } + static inline void addGlobalFunc(SQClassDefBase *def, + Func gfunc, + const SQChar *name) { + const int fidx = def->overloadedStaticMemberNames.index(name); + SQFuncHolder::addStaticFunc(fidx, gfunc); + SquirrelVM::CreateFunctionGlobal(staticSwitcher, name, _SC("*")); + + HSQUIRRELVM v = def->v; + // get closure + sq_pushroottable(v); + sq_pushstring(v, name, -1); + sq_rawget(v, -2); + + // holder[closure] = fidx + sq_pushobject(v, indexHolder<1>(v).GetObjectHandle()); + sq_push(v, -2); + sq_pushinteger(v, fidx); + sq_rawset(v, -3); + // + sq_pop(v, 3); + } + }; + +public: + template + SQClassDefBase &overloadFunc(Mfunc mfunc, const SQChar *n) { + SQOverloader::addMemberFunc(this, mfunc, n); + return *this; + } + template + SQClassDefBase &overloadOperator(Ofunc ofunc, const SQChar *n){ + SQOverloader::addOperatorFunc(this, ofunc, n); + return *this; + } + template + SQClassDefBase &overloadStaticFunc(Sfunc sfunc, + const SQChar *n) { + SQOverloader::addStaticFunc(this, sfunc, n); + return *this; + } + template + SQClassDefBase &overloadConstructor(void) { + SQOverloader::addConstructor(this, &Arg::create); + return *this; + } + template + SQClassDefBase &overloadConstructor(Cfunc cfunc) { + SQOverloader::addConstructor(this, cfunc); + return *this; + } + template + SQClassDefBase &overloadGlobalFunc(Gfunc gfunc, + const SQChar *n) { + SQOverloader::addGlobalFunc(this, gfunc, n); + return *this; + } + + +#endif // SQPLUS_OVERLOAD_IMPLEMENTATION + + + +#ifdef SQPLUS_OVERLOAD_FUNCTIONS +#undef SQPLUS_OVERLOAD_FUNCTIONS + +struct GlobalFuncOverloader {}; +static inline SQClassDefBase &globalFuncOverloader(void) +{ + static SQClassDefBase fo(_SC("GlobalFuncOverloader")); + return fo; +} + +template void +OverloadGlobal(Gfunc gfunc, const SQChar *n) +{ + globalFuncOverloader().overloadGlobalFunc(gfunc, n); +} + +template struct CheckInstance { + template struct unref {typedef T type;}; + template struct unref {typedef T type;}; + template struct unref {typedef T type;}; + template struct unref {typedef T type;}; + template struct unref {typedef T type;}; + + /* + d = -1 : not in hierarchy + d = 0 : same + d > 0 : similar (o is d-th subclass of TYPE) + */ + static inline int distance(HSQUIRRELVM v, int index) { + HSQOBJECT o; + sq_resetobject(&o); + sq_getstackobj(v, index, &o); + + const int top = sq_gettop(v); + sq_pushroottable(v); + + // Check plain object type + int d = -1; + if (Match(TypeWrapper(), v, index)) { + d = 0; + + // Check instance type hierarchy + if (sq_type(o) == OT_INSTANCE) { + SQUserPointer dsttype = + ClassType::type>::type(); + + SQUserPointer argtype; + for (sq_getclass(v, index); + sq_gettypetag(v, -1, &argtype) == SQ_OK; + sq_getbase(v, -1)) { + if (argtype == dsttype) { + goto SQPLUS_OVERLOAD_DISTANCE_IMMEDIATE_RETURN; + } + ++d; + } + d = -1; // no matching type found + } + } + SQPLUS_OVERLOAD_DISTANCE_IMMEDIATE_RETURN: + sq_settop(v, top); + return d; + } +}; + + +template +struct Arg { + static inline int num(void) {return 0;} + static inline int argTypeDistance(HSQUIRRELVM) { + return 0; + } +}; + +template +struct Arg { + static inline int num(void) {return 1;} + static inline int argTypeDistance(HSQUIRRELVM v) { + return Arg::argTypeDistance(v); + } +}; + +template +struct Arg { + static inline int num(void) {return 2;} + static inline int argTypeDistance(HSQUIRRELVM v) { + return Arg::argTypeDistance(v); + } +}; + +template +struct Arg { + static inline int num(void) {return 3;} + static inline int argTypeDistance(HSQUIRRELVM v) { + return Arg::argTypeDistance(v); + } +}; + +template +struct Arg { + static inline int num(void) {return 4;} + static inline int argTypeDistance(HSQUIRRELVM v) { + return Arg::argTypeDistance(v); + } +}; + +template +struct Arg { + static inline int num(void) {return 5;} + static inline int argTypeDistance(HSQUIRRELVM v) { + return Arg::argTypeDistance(v); + } +}; + +template +struct Arg { + static inline int num(void) {return 6;} + static inline int argTypeDistance(HSQUIRRELVM v) { + return Arg::argTypeDistance(v); + } +}; + +template +struct Arg { + static inline int num(void) {return 7;} + static inline int argTypeDistance(HSQUIRRELVM v) { + return Arg::argTypeDistance(v); + } +}; + +#ifdef SQPLUS_CONST_OPT +template +struct Arg { + static inline int num(void) {return 0;} + static inline int argTypeDistance(HSQUIRRELVM) { + return 0; + } +}; + +template +struct Arg { + static inline int num(void) {return 1;} + static inline int argTypeDistance(HSQUIRRELVM v) { + return Arg::argTypeDistance(v); + } +}; + +template +struct Arg { + static inline int num(void) {return 2;} + static inline int argTypeDistance(HSQUIRRELVM v) { + return Arg::argTypeDistance(v); + } +}; + +template +struct Arg { + static inline int num(void) {return 3;} + static inline int argTypeDistance(HSQUIRRELVM v) { + return Arg::argTypeDistance(v); + } +}; + +template +struct Arg { + static inline int num(void) {return 4;} + static inline int argTypeDistance(HSQUIRRELVM v) { + return Arg::argTypeDistance(v); + } +}; + +template +struct Arg { + static inline int num(void) {return 5;} + static inline int argTypeDistance(HSQUIRRELVM v) { + return Arg::argTypeDistance(v); + } +}; + +template +struct Arg { + static inline int num(void) {return 6;} + static inline int argTypeDistance(HSQUIRRELVM v) { + return Arg::argTypeDistance(v); + } +}; + +template +struct Arg { + static inline int num(void) {return 7;} + static inline int argTypeDistance(HSQUIRRELVM v) { + return Arg::argTypeDistance(v); + } +}; +#endif + +static inline int classAllocationError(HSQUIRRELVM v) { + return sq_throwerror(v, _SC("Failed to allocate memory")); +} + +template +struct Arg { + static inline int num(void) {return 0;} + static inline int argTypeDistance(HSQUIRRELVM) {return 0;} + static inline int create(void) { + HSQUIRRELVM v = SquirrelVM::GetVMPtr(); + R *r = static_cast(sq_malloc(sizeof(R))); + return r ? + PostConstruct(v, new(r) R, + ClassType::getReleaseHook()) : + classAllocationError(v); + } +}; + +template +struct Arg { + static inline int num(void) {return 1;} + static inline int argTypeDistance(HSQUIRRELVM v) { + int s, r; + r = 0; + s = CheckInstance::distance(v, 2); if (s < 0) {return -1;} r += s; + return r; + } + static inline int create(A1 a1) { + HSQUIRRELVM v = SquirrelVM::GetVMPtr(); + R *r = static_cast(sq_malloc(sizeof(R))); + return r ? + PostConstruct(v, new(r) R(a1), + ClassType::getReleaseHook()) : + classAllocationError(v); + } +}; + +template +struct Arg { + static inline int num(void) {return 2;} + static inline int argTypeDistance(HSQUIRRELVM v) { + int s, r; + r = 0; + s = CheckInstance::distance(v, 2); if (s < 0) {return -1;} r += s; + s = CheckInstance::distance(v, 3); if (s < 0) {return -1;} r += s; + return r; + } + static inline int create(A1 a1, A2 a2) { + HSQUIRRELVM v = SquirrelVM::GetVMPtr(); + R *r = static_cast(sq_malloc(sizeof(R))); + return r ? + PostConstruct(v, new(r) R(a1, a2), + ClassType::getReleaseHook()) : + classAllocationError(v); + } +}; + +template +struct Arg { + static inline int num(void) {return 3;} + static inline int argTypeDistance(HSQUIRRELVM v) { + int s, r; + r = 0; + s = CheckInstance::distance(v, 2); if (s < 0) {return -1;} r += s; + s = CheckInstance::distance(v, 3); if (s < 0) {return -1;} r += s; + s = CheckInstance::distance(v, 4); if (s < 0) {return -1;} r += s; + return r; + } + static inline int create(A1 a1, A2 a2, A3 a3) { + HSQUIRRELVM v = SquirrelVM::GetVMPtr(); + R *r = static_cast(sq_malloc(sizeof(R))); + return r ? + PostConstruct(v, new(r) R(a1, a2, a3), + ClassType::getReleaseHook()) : + classAllocationError(v); + } +}; + +template +struct Arg { + static inline int num(void) {return 4;} + static inline int argTypeDistance(HSQUIRRELVM v) { + int s, r; + r = 0; + s = CheckInstance::distance(v, 2); if (s < 0) {return -1;} r += s; + s = CheckInstance::distance(v, 3); if (s < 0) {return -1;} r += s; + s = CheckInstance::distance(v, 4); if (s < 0) {return -1;} r += s; + s = CheckInstance::distance(v, 5); if (s < 0) {return -1;} r += s; + return r; + } + static inline int create(A1 a1, A2 a2, A3 a3, A4 a4) { + HSQUIRRELVM v = SquirrelVM::GetVMPtr(); + R *r = static_cast(sq_malloc(sizeof(R))); + return r ? + PostConstruct(v, new(r) R(a1, a2, a3, a4), + ClassType::getReleaseHook()) : + classAllocationError(v); + } +}; + +template +struct Arg { + static inline int num(void) {return 5;} + static inline int argTypeDistance(HSQUIRRELVM v) { + int s, r; + r = 0; + s = CheckInstance::distance(v, 2); if (s < 0) {return -1;} r += s; + s = CheckInstance::distance(v, 3); if (s < 0) {return -1;} r += s; + s = CheckInstance::distance(v, 4); if (s < 0) {return -1;} r += s; + s = CheckInstance::distance(v, 5); if (s < 0) {return -1;} r += s; + s = CheckInstance::distance(v, 6); if (s < 0) {return -1;} r += s; + return r; + } + static inline int create(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) { + HSQUIRRELVM v = SquirrelVM::GetVMPtr(); + R *r = static_cast(sq_malloc(sizeof(R))); + return r ? + PostConstruct(v, new(r) R(a1, a2, a3, a4, a5), + ClassType::getReleaseHook()) : + classAllocationError(v); + } +}; + +template +struct Arg { + static inline int num(void) {return 6;} + static inline int argTypeDistance(HSQUIRRELVM v) { + int s, r; + r = 0; + s = CheckInstance::distance(v, 2); if (s < 0) {return -1;} r += s; + s = CheckInstance::distance(v, 3); if (s < 0) {return -1;} r += s; + s = CheckInstance::distance(v, 4); if (s < 0) {return -1;} r += s; + s = CheckInstance::distance(v, 5); if (s < 0) {return -1;} r += s; + s = CheckInstance::distance(v, 6); if (s < 0) {return -1;} r += s; + s = CheckInstance::distance(v, 7); if (s < 0) {return -1;} r += s; + return r; + } + static inline int create(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) { + HSQUIRRELVM v = SquirrelVM::GetVMPtr(); + R *r = static_cast(sq_malloc(sizeof(R))); + return r ? + PostConstruct(v, new(r) R(a1, a2, a3, a4, a5, a6), + ClassType::getReleaseHook()) : + classAllocationError(v); + } +}; + +template +struct Arg { + static inline int num(void) {return 7;} + static inline int argTypeDistance(HSQUIRRELVM v) { + int s, r; + r = 0; + s = CheckInstance::distance(v, 2); if (s < 0) {return -1;} r += s; + s = CheckInstance::distance(v, 3); if (s < 0) {return -1;} r += s; + s = CheckInstance::distance(v, 4); if (s < 0) {return -1;} r += s; + s = CheckInstance::distance(v, 5); if (s < 0) {return -1;} r += s; + s = CheckInstance::distance(v, 6); if (s < 0) {return -1;} r += s; + s = CheckInstance::distance(v, 7); if (s < 0) {return -1;} r += s; + s = CheckInstance::distance(v, 8); if (s < 0) {return -1;} r += s; + return r; + } + static inline int create(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) { + HSQUIRRELVM v = SquirrelVM::GetVMPtr(); + R *r = static_cast(sq_malloc(sizeof(R))); + return r ? + PostConstruct(v, new(r) R(a1, a2, a3, a4, a5, a6, a7), + ClassType::getReleaseHook()) : + classAllocationError(v); + } +}; +#endif // SQPLUS_OVERLOAD_FUNCTIONS + +// SqPlusOverload.h + +// Local Variables: +// mode: c++ +// End: diff --git a/squirrel_3_0_1_stable/sqplus/SqPlusSetup.h b/squirrel_3_0_1_stable/_OLD_sqplus/SqPlusSetup.h similarity index 97% rename from squirrel_3_0_1_stable/sqplus/SqPlusSetup.h rename to squirrel_3_0_1_stable/_OLD_sqplus/SqPlusSetup.h index 372e63f69..ca191459e 100644 --- a/squirrel_3_0_1_stable/sqplus/SqPlusSetup.h +++ b/squirrel_3_0_1_stable/_OLD_sqplus/SqPlusSetup.h @@ -1,129 +1,129 @@ -#ifndef SQPLUSSETUP_H -#define SQPLUSSETUP_H - -// Setup file for SqPlus. -// Comment / uncomment / define options below. - - -// Inheritance in Squirrel allows one class to inherit a base class's -// functions and variables. -// -// Variables are merged: if Derived has a var name 'val' and Base has -// a var of the same name, the resulting var 'val' will take Derived's -// initialization value. -// -// Functions are not merged, and can be called via Squirrel scoping rules. -// -// Define SQ_USE_CLASS_INHERITANCE to enable class inheritance support -// (requires slightly more memory and adds some CPU overhead). -// -// Can also be useful for debugging, as class type information is -// checked before dispatching instance function calls and before -// accessing instance member variables. -#define SQ_USE_CLASS_INHERITANCE - - -// This is a new C++ template based inheritence scheme that uses no -// additional memory per instance. To support offset between "this" -// pointer in base and derived class, use a second class in: -// SQClassDef< MyClass, MyBaseClass >. -// NOTE: For new code SQ_USE_CLASS_INHERITANCE_SIMPLE is more -// efficient than above method. -//#define SQ_USE_CLASS_INHERITANCE_SIMPLE - -// === Instance type info support === -#define SQ_SUPPORT_INSTANCE_TYPE_INFO - -// === Constant argument and constant member function support === -// Define SQPLUS_CONST_OPT before including SqPlus.h for constant -// argument + constant member function support. -#define SQPLUS_CONST_OPT - - -// === Uncomment to support smart pointer === -// Define SQPLUS_SMARTPOINTER_OPT before including SqPlus.h for -// smartpointer member function + variable support -//#define SQPLUS_SMARTPOINTER_OPT - - -// === Function overloading support === -#define SQPLUS_OVERLOAD_OPT - -// === Uncomment to support std::string === -// Requires that Squirrel is compiled with SQChar == char -//#define SQPLUS_SUPPORT_STD_STRING - -// === Uncomment to support typedef std::basic_string sq_std_string === -#define SQPLUS_SUPPORT_SQ_STD_STRING - -// === Uncomment to support NULL INSTANCE arguments === -#define SQPLUS_SUPPORT_NULL_INSTANCES - -// === Uncomment to disable copying of class instances === -// If classes being exposed have private or protected constructors -// one cannot do assign (=) in template functions. -//#define SQPLUS_DISABLE_COPY_INSTANCES - - -// === Auto generating typemasks for registered functions === -// This is useful when using Squirrel interactively -//#define SQPLUS_ENABLE_AUTO_TYPEMASK - -// === Uncomment to generate a typeof function for each class === -// This is mostly for displaying function help from inside a Squirrel prompt -//#define SQPLUS_ENABLE_TYPEOF - -// === Uncomment to skip sq_argassert() === -//#define SQ_SKIP_ARG_ASSERT - -// === GCC Inline template fix === -// Can solve problems when linking if GCC has problems with inline functions -//#define GCC_INLINE_WORKAROUND - - -// === MSVC cdecl member functions === -// Enable binding member functions with __cdecl calling convention under MSVC. -// Mostly useful when linking with binaries from other compilers. -#ifdef _MSC_VER -//#define SQPLUS_ENABLE_CDECL_MEMBER_FUNCTIONS -#endif - - -// === Generic Push/Pop/Match handlers === -// This enables using a 'fallback' set of Push/Get/Match that operates -// on class level (not on template level). This opens for handling all -// members of a certain class hierarchy using the same function -// GenPush/GenGet/GenMatch overrides (provided the hierarchy has some -// run-time type mechanism to use). They are used whenever an exact -// template match is not found. -//#define SQPLUS_USE_GENERIC_HANDLERS - - -// === Sandbox VM === -// This enables giving one VM the role of 'sandbox' VM where scripts -// of unknown origin may execute and not have access to any SqPlus -// registered functions. All normal VMs have full access to script -// functions, but the one given in SetSandboxVm() can only use std -// Squirrel functions. -//#define SQPLUS_USE_SANDBOX_VM - - -#if defined(SQPLUS_SUPPORT_STD_STRING) || defined(SQPLUS_SUPPORT_SQ_STD_STRING) -# include -#endif - - -// === Conversion of arguments from opposite char type ( char <=> wchar_t ) === -// Converts strings to opposite encoding in Push/Get handlers (UTF8 / Latin1) -#define SQPLUS_AUTOCONVERT_OTHER_CHAR - -// === Whether 8 bit chars are treated as Latin1(1) or UTF8(0) === -// (leave undefined for undefined for automatic handling) -#define SQPLUS_USE_LATIN1 1 - -// === Include system library bindings when creating VM:s in SquirrelVM::Init() === -// Define to bind to system lib when VM:s are created automatically in -// SquirrelVM::Init() -//#define SQPLUS_SQUIRRELVM_WITH_SYSTEMLIB - -#endif // SQPLUSSETUP_H +#ifndef SQPLUSSETUP_H +#define SQPLUSSETUP_H + +// Setup file for SqPlus. +// Comment / uncomment / define options below. + + +// Inheritance in Squirrel allows one class to inherit a base class's +// functions and variables. +// +// Variables are merged: if Derived has a var name 'val' and Base has +// a var of the same name, the resulting var 'val' will take Derived's +// initialization value. +// +// Functions are not merged, and can be called via Squirrel scoping rules. +// +// Define SQ_USE_CLASS_INHERITANCE to enable class inheritance support +// (requires slightly more memory and adds some CPU overhead). +// +// Can also be useful for debugging, as class type information is +// checked before dispatching instance function calls and before +// accessing instance member variables. +#define SQ_USE_CLASS_INHERITANCE + + +// This is a new C++ template based inheritence scheme that uses no +// additional memory per instance. To support offset between "this" +// pointer in base and derived class, use a second class in: +// SQClassDef< MyClass, MyBaseClass >. +// NOTE: For new code SQ_USE_CLASS_INHERITANCE_SIMPLE is more +// efficient than above method. +//#define SQ_USE_CLASS_INHERITANCE_SIMPLE + +// === Instance type info support === +#define SQ_SUPPORT_INSTANCE_TYPE_INFO + +// === Constant argument and constant member function support === +// Define SQPLUS_CONST_OPT before including SqPlus.h for constant +// argument + constant member function support. +#define SQPLUS_CONST_OPT + + +// === Uncomment to support smart pointer === +// Define SQPLUS_SMARTPOINTER_OPT before including SqPlus.h for +// smartpointer member function + variable support +//#define SQPLUS_SMARTPOINTER_OPT + + +// === Function overloading support === +#define SQPLUS_OVERLOAD_OPT + +// === Uncomment to support std::string === +// Requires that Squirrel is compiled with SQChar == char +//#define SQPLUS_SUPPORT_STD_STRING + +// === Uncomment to support typedef std::basic_string sq_std_string === +#define SQPLUS_SUPPORT_SQ_STD_STRING + +// === Uncomment to support NULL INSTANCE arguments === +#define SQPLUS_SUPPORT_NULL_INSTANCES + +// === Uncomment to disable copying of class instances === +// If classes being exposed have private or protected constructors +// one cannot do assign (=) in template functions. +//#define SQPLUS_DISABLE_COPY_INSTANCES + + +// === Auto generating typemasks for registered functions === +// This is useful when using Squirrel interactively +//#define SQPLUS_ENABLE_AUTO_TYPEMASK + +// === Uncomment to generate a typeof function for each class === +// This is mostly for displaying function help from inside a Squirrel prompt +//#define SQPLUS_ENABLE_TYPEOF + +// === Uncomment to skip sq_argassert() === +//#define SQ_SKIP_ARG_ASSERT + +// === GCC Inline template fix === +// Can solve problems when linking if GCC has problems with inline functions +//#define GCC_INLINE_WORKAROUND + + +// === MSVC cdecl member functions === +// Enable binding member functions with __cdecl calling convention under MSVC. +// Mostly useful when linking with binaries from other compilers. +#ifdef _MSC_VER +//#define SQPLUS_ENABLE_CDECL_MEMBER_FUNCTIONS +#endif + + +// === Generic Push/Pop/Match handlers === +// This enables using a 'fallback' set of Push/Get/Match that operates +// on class level (not on template level). This opens for handling all +// members of a certain class hierarchy using the same function +// GenPush/GenGet/GenMatch overrides (provided the hierarchy has some +// run-time type mechanism to use). They are used whenever an exact +// template match is not found. +//#define SQPLUS_USE_GENERIC_HANDLERS + + +// === Sandbox VM === +// This enables giving one VM the role of 'sandbox' VM where scripts +// of unknown origin may execute and not have access to any SqPlus +// registered functions. All normal VMs have full access to script +// functions, but the one given in SetSandboxVm() can only use std +// Squirrel functions. +//#define SQPLUS_USE_SANDBOX_VM + + +#if defined(SQPLUS_SUPPORT_STD_STRING) || defined(SQPLUS_SUPPORT_SQ_STD_STRING) +# include +#endif + + +// === Conversion of arguments from opposite char type ( char <=> wchar_t ) === +// Converts strings to opposite encoding in Push/Get handlers (UTF8 / Latin1) +#define SQPLUS_AUTOCONVERT_OTHER_CHAR + +// === Whether 8 bit chars are treated as Latin1(1) or UTF8(0) === +// (leave undefined for undefined for automatic handling) +#define SQPLUS_USE_LATIN1 1 + +// === Include system library bindings when creating VM:s in SquirrelVM::Init() === +// Define to bind to system lib when VM:s are created automatically in +// SquirrelVM::Init() +//#define SQPLUS_SQUIRRELVM_WITH_SYSTEMLIB + +#endif // SQPLUSSETUP_H diff --git a/squirrel_3_0_1_stable/sqplus/SqPlusSmartPointer.h b/squirrel_3_0_1_stable/_OLD_sqplus/SqPlusSmartPointer.h similarity index 97% rename from squirrel_3_0_1_stable/sqplus/SqPlusSmartPointer.h rename to squirrel_3_0_1_stable/_OLD_sqplus/SqPlusSmartPointer.h index 34996ffd8..5a6bacbf5 100644 --- a/squirrel_3_0_1_stable/sqplus/SqPlusSmartPointer.h +++ b/squirrel_3_0_1_stable/_OLD_sqplus/SqPlusSmartPointer.h @@ -1,141 +1,141 @@ -// SqPlusSmartPointer.h -// SqPlus smart pointer member function support created by James Whitworth. -// Modular integration 07/11/07 James Whitworth. -// you must define the function: -// unsigned char* getSmartPointerPointee(unsigned char*) { -// return &(MySmartPointer->pointee); -// } -// somewhere in your program so it can correctly lookup member variables on the class pointed to -// by your smart pointer. - -#ifdef SQPLUS_SMARTPOINTER_ACCESSTYPE -#undef SQPLUS_SMARTPOINTER_ACCESSTYPE -enum VarAccessType {VAR_ACCESS_READ_WRITE=0,VAR_ACCESS_READ_ONLY=1<<0,VAR_ACCESS_CONSTANT=1<<1,VAR_ACCESS_STATIC=1<<2,VAR_ACCESS_SMARTPOINTER=1<<3}; -#endif // #ifdef SQPLUS_SMARTPOINTER_ACCESSTYPE - -#ifdef SQPLUS_SMARTPOINTER_REGISTER_VARIABLE -#undef SQPLUS_SMARTPOINTER_REGISTER_VARIABLE -// classType is the type of the member variable's containing class. -template -void -RegisterSmartInstanceVariable(SquirrelObject & so, - ClassTypeBase *classType, - T *var, - const SQChar *scriptVarName, - VarAccessType access = VAR_ACCESS_READ_WRITE) -{ - VarRef *pvr = createVarRef(so,scriptVarName); - - // var must be passed in as &obj->var, where obj = 0 - // (the address is the offset), or as static/global address. - void *offsetOrAddrOrConst = static_cast(var); - *pvr = VarRef(offsetOrAddrOrConst, - TypeInfo(), - classType, - ClassType::type(), - sizeof(*var), - access); - pvr->m_access |= VAR_ACCESS_SMARTPOINTER; - createInstanceSetGetHandlers(so); -} -#endif // #ifdef SQPLUS_SMARTPOINTER_REGISTER_VARIABLE - -#ifdef SQPLUS_SMARTPOINTER_DISPATCH -#undef SQPLUS_SMARTPOINTER_DISPATCH -template -class DirectCallSmartInstanceMemberFunction { -public: - static inline int Dispatch(HSQUIRRELVM v) { - DirectCallInstanceFuncPicker p(v); - if (!p.instance || !p.func) { - sq_throwerror(v, _SC("Invalid Instance Type")); - } - Pointee *pointeeInstance = static_cast(p.instance->get()); - return - !pointeeInstance ? sq_throwerror(v, _SC("SmartPointer Pointee NULL")) : - Call(*pointeeInstance, *(p.func), v, 2); - } -}; -#endif // #ifdef SQPLUS_SMARTPOINTER_DISPATCH - -#ifdef SQPLUS_SMARTPOINTER_DIRECT_CLOSURE -#undef SQPLUS_SMARTPOINTER_DIRECT_CLOSURE - -template -inline void sq_pushdirectsmartinstanceclosure(HSQUIRRELVM v,const Callee & callee,const Pointee & pointee,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,DirectCallSmartInstanceMemberFunction::Dispatch,nupvalues+1); -} // sq_pushdirectinstanceclosure - -#endif // #ifdef SQPLUS_SMARTPOINTER_DIRECT_CLOSURE - -#ifdef SQPLUS_SMARTPOINTER_REGISTER_INSTANCE -#undef SQPLUS_SMARTPOINTER_REGISTER_INSTANCE - -template -inline void RegisterSmartInstance(HSQUIRRELVM v,HSQOBJECT hclass,Callee & callee,Pointee & pointee,Func func,const SQChar * name) { - sq_pushobject(v,hclass); - sq_pushstring(v,name,-1); - sq_pushdirectsmartinstanceclosure(v,callee,pointee,func,0); - sq_createslot(v,-3); - sq_poptop(v); // Remove hclass. -} // RegisterInstance - -#endif // #ifdef SQPLUS_SMARTPOINTER_REGISTER_INSTANCE - -#ifdef SQPLUS_SMARTPOINTER_CLASS_DEF_FUNC -#undef SQPLUS_SMARTPOINTER_CLASS_DEF_FUNC - - // Register a smartpointer member function. - template - SQClassDefBase & smartFunc(Func pfunc,const SQChar * name) { - RegisterSmartInstance(v,newClass.GetObjectHandle(),*(TClassType *)0,*(Pointee *)0,pfunc,name); - return *this; - } // func - -#endif // #ifdef SQPLUS_SMARTPOINTER_CLASS_DEF_FUNC - -#ifdef SQPLUS_SMARTPOINTER_CLASS_DEF_VAR -#undef SQPLUS_SMARTPOINTER_CLASS_DEF_VAR - - // Register a member variable. - template - SQClassDefBase & smartVar(VarType Pointee::* pvar,const SQChar * name,VarAccessType access=VAR_ACCESS_READ_WRITE) { - struct CV { - VarType Pointee::* var; - } cv; // Cast Variable helper. - cv.var = pvar; - RegisterSmartInstanceVariable(newClass,ClassType::type(),*(VarType **)&cv,name,access); - return *this; - } // var - - // Register a member variable as a UserPointer (read only). - template - SQClassDefBase & smartVarAsUserPointer(VarType Pointee::* pvar,const SQChar * name) { - struct CV { - VarType Pointee::* var; - } cv; // Cast Variable helper. - cv.var = pvar; - RegisterSmartInstanceVariable(newClass,ClassType::type(),*(SQAnything **)&cv,name,VAR_ACCESS_READ_ONLY); - return *this; - } // varAsUserPointer - -#endif // #ifdef SQPLUS_SMARTPOINTER_CLASS_DEF_VAR - - -#ifdef SQPLUS_SMARTPOINTER_CPP_DECLARATION -#undef SQPLUS_SMARTPOINTER_CPP_DECLARATION -extern unsigned char* getSmartPointerPointee(unsigned char*); -#endif - -#ifdef SQPLUS_SMARTPOINTER_INSTANCE_VARINFO -#undef SQPLUS_SMARTPOINTER_INSTANCE_VARINFO - if(vr->m_access & VAR_ACCESS_SMARTPOINTER) { - up = reinterpret_cast( - getSmartPointerPointee(reinterpret_cast(up)) - ); - } -#endif // #ifdef SQPLUS_SMARTPOINTER_CPP_DECLARATION - -// SqPlusSmartPointer.h +// SqPlusSmartPointer.h +// SqPlus smart pointer member function support created by James Whitworth. +// Modular integration 07/11/07 James Whitworth. +// you must define the function: +// unsigned char* getSmartPointerPointee(unsigned char*) { +// return &(MySmartPointer->pointee); +// } +// somewhere in your program so it can correctly lookup member variables on the class pointed to +// by your smart pointer. + +#ifdef SQPLUS_SMARTPOINTER_ACCESSTYPE +#undef SQPLUS_SMARTPOINTER_ACCESSTYPE +enum VarAccessType {VAR_ACCESS_READ_WRITE=0,VAR_ACCESS_READ_ONLY=1<<0,VAR_ACCESS_CONSTANT=1<<1,VAR_ACCESS_STATIC=1<<2,VAR_ACCESS_SMARTPOINTER=1<<3}; +#endif // #ifdef SQPLUS_SMARTPOINTER_ACCESSTYPE + +#ifdef SQPLUS_SMARTPOINTER_REGISTER_VARIABLE +#undef SQPLUS_SMARTPOINTER_REGISTER_VARIABLE +// classType is the type of the member variable's containing class. +template +void +RegisterSmartInstanceVariable(SquirrelObject & so, + ClassTypeBase *classType, + T *var, + const SQChar *scriptVarName, + VarAccessType access = VAR_ACCESS_READ_WRITE) +{ + VarRef *pvr = createVarRef(so,scriptVarName); + + // var must be passed in as &obj->var, where obj = 0 + // (the address is the offset), or as static/global address. + void *offsetOrAddrOrConst = static_cast(var); + *pvr = VarRef(offsetOrAddrOrConst, + TypeInfo(), + classType, + ClassType::type(), + sizeof(*var), + access); + pvr->m_access |= VAR_ACCESS_SMARTPOINTER; + createInstanceSetGetHandlers(so); +} +#endif // #ifdef SQPLUS_SMARTPOINTER_REGISTER_VARIABLE + +#ifdef SQPLUS_SMARTPOINTER_DISPATCH +#undef SQPLUS_SMARTPOINTER_DISPATCH +template +class DirectCallSmartInstanceMemberFunction { +public: + static inline int Dispatch(HSQUIRRELVM v) { + DirectCallInstanceFuncPicker p(v); + if (!p.instance || !p.func) { + sq_throwerror(v, _SC("Invalid Instance Type")); + } + Pointee *pointeeInstance = static_cast(p.instance->get()); + return + !pointeeInstance ? sq_throwerror(v, _SC("SmartPointer Pointee NULL")) : + Call(*pointeeInstance, *(p.func), v, 2); + } +}; +#endif // #ifdef SQPLUS_SMARTPOINTER_DISPATCH + +#ifdef SQPLUS_SMARTPOINTER_DIRECT_CLOSURE +#undef SQPLUS_SMARTPOINTER_DIRECT_CLOSURE + +template +inline void sq_pushdirectsmartinstanceclosure(HSQUIRRELVM v,const Callee & callee,const Pointee & pointee,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,DirectCallSmartInstanceMemberFunction::Dispatch,nupvalues+1); +} // sq_pushdirectinstanceclosure + +#endif // #ifdef SQPLUS_SMARTPOINTER_DIRECT_CLOSURE + +#ifdef SQPLUS_SMARTPOINTER_REGISTER_INSTANCE +#undef SQPLUS_SMARTPOINTER_REGISTER_INSTANCE + +template +inline void RegisterSmartInstance(HSQUIRRELVM v,HSQOBJECT hclass,Callee & callee,Pointee & pointee,Func func,const SQChar * name) { + sq_pushobject(v,hclass); + sq_pushstring(v,name,-1); + sq_pushdirectsmartinstanceclosure(v,callee,pointee,func,0); + sq_createslot(v,-3); + sq_poptop(v); // Remove hclass. +} // RegisterInstance + +#endif // #ifdef SQPLUS_SMARTPOINTER_REGISTER_INSTANCE + +#ifdef SQPLUS_SMARTPOINTER_CLASS_DEF_FUNC +#undef SQPLUS_SMARTPOINTER_CLASS_DEF_FUNC + + // Register a smartpointer member function. + template + SQClassDefBase & smartFunc(Func pfunc,const SQChar * name) { + RegisterSmartInstance(v,newClass.GetObjectHandle(),*(TClassType *)0,*(Pointee *)0,pfunc,name); + return *this; + } // func + +#endif // #ifdef SQPLUS_SMARTPOINTER_CLASS_DEF_FUNC + +#ifdef SQPLUS_SMARTPOINTER_CLASS_DEF_VAR +#undef SQPLUS_SMARTPOINTER_CLASS_DEF_VAR + + // Register a member variable. + template + SQClassDefBase & smartVar(VarType Pointee::* pvar,const SQChar * name,VarAccessType access=VAR_ACCESS_READ_WRITE) { + struct CV { + VarType Pointee::* var; + } cv; // Cast Variable helper. + cv.var = pvar; + RegisterSmartInstanceVariable(newClass,ClassType::type(),*(VarType **)&cv,name,access); + return *this; + } // var + + // Register a member variable as a UserPointer (read only). + template + SQClassDefBase & smartVarAsUserPointer(VarType Pointee::* pvar,const SQChar * name) { + struct CV { + VarType Pointee::* var; + } cv; // Cast Variable helper. + cv.var = pvar; + RegisterSmartInstanceVariable(newClass,ClassType::type(),*(SQAnything **)&cv,name,VAR_ACCESS_READ_ONLY); + return *this; + } // varAsUserPointer + +#endif // #ifdef SQPLUS_SMARTPOINTER_CLASS_DEF_VAR + + +#ifdef SQPLUS_SMARTPOINTER_CPP_DECLARATION +#undef SQPLUS_SMARTPOINTER_CPP_DECLARATION +extern unsigned char* getSmartPointerPointee(unsigned char*); +#endif + +#ifdef SQPLUS_SMARTPOINTER_INSTANCE_VARINFO +#undef SQPLUS_SMARTPOINTER_INSTANCE_VARINFO + if(vr->m_access & VAR_ACCESS_SMARTPOINTER) { + up = reinterpret_cast( + getSmartPointerPointee(reinterpret_cast(up)) + ); + } +#endif // #ifdef SQPLUS_SMARTPOINTER_CPP_DECLARATION + +// SqPlusSmartPointer.h diff --git a/squirrel_3_0_1_stable/sqplus/SqPlusTypeMask.h b/squirrel_3_0_1_stable/_OLD_sqplus/SqPlusTypeMask.h similarity index 96% rename from squirrel_3_0_1_stable/sqplus/SqPlusTypeMask.h rename to squirrel_3_0_1_stable/_OLD_sqplus/SqPlusTypeMask.h index 975a51a1f..50dc0c066 100644 --- a/squirrel_3_0_1_stable/sqplus/SqPlusTypeMask.h +++ b/squirrel_3_0_1_stable/_OLD_sqplus/SqPlusTypeMask.h @@ -1,169 +1,169 @@ - -// File to automatically generate a typemask for a function - -// Will generate type masks that accepts Instance pointer or null -#ifndef SQPLUS_ACCEPT_NULL_INSTANCE - #define SQPLUS_ACCEPT_NULL_INSTANCE -#endif - -// Macros to reduce typing: (P1), (P1,P2), (P1,P2,P3), ... -#define P_0 -#define P_1 P1 -#define P_2 P_1,P2 -#define P_3 P_2,P3 -#define P_4 P_3,P4 -#define P_5 P_4,P5 -#define P_6 P_5,P6 -#define P_7 P_6,P7 - -// Macros to reduce typing: (typename P1), (typename P1,typename P2), ... -#define PTN_0 -#define PTN_1 typename P1 -#define PTN_2 PTN_1,typename P2 -#define PTN_3 PTN_2,typename P3 -#define PTN_4 PTN_3,typename P4 -#define PTN_5 PTN_4,typename P5 -#define PTN_6 PTN_5,typename P6 -#define PTN_7 PTN_6,typename P7 - -// Include a comma first in list: ,typename P1,typename P2 -#define PTNC_0 -#define PTNC_1 ,PTN_1 -#define PTNC_2 ,PTN_2 -#define PTNC_3 ,PTN_3 -#define PTNC_4 ,PTN_4 -#define PTNC_5 ,PTN_5 -#define PTNC_6 ,PTN_6 -#define PTNC_7 ,PTN_7 - -#ifdef SQUNICODE -#define scstrcpy wcscpy -#else -#define scstrcpy strcpy -#endif - -inline const SQChar* strappchar(SQChar *buf, SQChar *in, SQChar ch){ - int l=scstrlen(in); - scstrcpy(buf,in); - buf[l] = ch; -#ifdef SQPLUS_ACCEPT_NULL_INSTANCE - if( ch=='x' ){ - buf[++l] = '|'; // Also accept NULL pointers - buf[++l] = 'o'; - } -#endif - buf[l+1] = 0; - return buf; -} - -template -struct sqTypeMask { }; - - -// Return type not included in type mask, delegate to void case - -// Base case, no arguments -template -struct sqTypeMask { - static const SQChar *Get(){ - static SQChar buf[64]; - //buf[0] = _SC('t'); - //buf[1] = 0; - //strcpy(buf,"t|x"); // Accept both instance and table, we don't use param anyway - buf[0] = _SC('.'); // Accept anything (not used) - buf[1] = 0; - return buf; - } -}; - -// Recursive case, peel of one arg at each level -#define DECLARE_RT_SQTYPEMASK(N,M) \ -template \ -struct sqTypeMask { \ - static const SQChar *Get(){ \ - static SQChar buf[10]; \ - return strappchar(buf, (SQChar*)sqTypeMask::Get(), \ - (SQChar)TypeInfo::TypeMask); \ - } \ -}; - -DECLARE_RT_SQTYPEMASK(1,0) -DECLARE_RT_SQTYPEMASK(2,1) -DECLARE_RT_SQTYPEMASK(3,2) -DECLARE_RT_SQTYPEMASK(4,3) -DECLARE_RT_SQTYPEMASK(5,4) -DECLARE_RT_SQTYPEMASK(6,5) -DECLARE_RT_SQTYPEMASK(7,6) - - -// Difference to above is that 1st param is instance instead of table - -#define DECLARE_RT_MEMBER_SQTYPEMASK(N,QUAL) \ -template \ -struct sqTypeMask { \ - static const SQChar *Get(){ \ - SQChar *buf = (SQChar*)sqTypeMask::Get(); \ - buf[0] = _SC('x'); \ - return buf; \ - } \ -}; - -// buf[1] = 0; \ - -DECLARE_RT_MEMBER_SQTYPEMASK(0,) -DECLARE_RT_MEMBER_SQTYPEMASK(1,) -DECLARE_RT_MEMBER_SQTYPEMASK(2,) -DECLARE_RT_MEMBER_SQTYPEMASK(3,) -DECLARE_RT_MEMBER_SQTYPEMASK(4,) -DECLARE_RT_MEMBER_SQTYPEMASK(5,) -DECLARE_RT_MEMBER_SQTYPEMASK(6,) -DECLARE_RT_MEMBER_SQTYPEMASK(7,) - -DECLARE_RT_MEMBER_SQTYPEMASK(0,const) -DECLARE_RT_MEMBER_SQTYPEMASK(1,const) -DECLARE_RT_MEMBER_SQTYPEMASK(2,const) -DECLARE_RT_MEMBER_SQTYPEMASK(3,const) -DECLARE_RT_MEMBER_SQTYPEMASK(4,const) -DECLARE_RT_MEMBER_SQTYPEMASK(5,const) -DECLARE_RT_MEMBER_SQTYPEMASK(6,const) -DECLARE_RT_MEMBER_SQTYPEMASK(7,const) - - -#ifdef _MSC_VER - -// Difference to above is we're using __cdecl calling convention here -// Only makes sense for MSVC where member functions can have different -// calling conventions (__cdecl or __thiscall) - -#define DECLARE_RT_MEMBER_SQTYPEMASK_CDECL(N,QUAL) \ -template \ -struct sqTypeMask { \ - static const SQChar *Get(){ \ - SQChar *buf = (SQChar*)sqTypeMask::Get(); \ - buf[0] = _SC('x'); \ - return buf; \ - } \ -}; - -// buf[1] = 0; \ - -DECLARE_RT_MEMBER_SQTYPEMASK_CDECL(0,) -DECLARE_RT_MEMBER_SQTYPEMASK_CDECL(1,) -DECLARE_RT_MEMBER_SQTYPEMASK_CDECL(2,) -DECLARE_RT_MEMBER_SQTYPEMASK_CDECL(3,) -DECLARE_RT_MEMBER_SQTYPEMASK_CDECL(4,) -DECLARE_RT_MEMBER_SQTYPEMASK_CDECL(5,) -DECLARE_RT_MEMBER_SQTYPEMASK_CDECL(6,) -DECLARE_RT_MEMBER_SQTYPEMASK_CDECL(7,) - -DECLARE_RT_MEMBER_SQTYPEMASK_CDECL(0,const) -DECLARE_RT_MEMBER_SQTYPEMASK_CDECL(1,const) -DECLARE_RT_MEMBER_SQTYPEMASK_CDECL(2,const) -DECLARE_RT_MEMBER_SQTYPEMASK_CDECL(3,const) -DECLARE_RT_MEMBER_SQTYPEMASK_CDECL(4,const) -DECLARE_RT_MEMBER_SQTYPEMASK_CDECL(5,const) -DECLARE_RT_MEMBER_SQTYPEMASK_CDECL(6,const) -DECLARE_RT_MEMBER_SQTYPEMASK_CDECL(7,const) - -#endif // _MSC_VER - + +// File to automatically generate a typemask for a function + +// Will generate type masks that accepts Instance pointer or null +#ifndef SQPLUS_ACCEPT_NULL_INSTANCE + #define SQPLUS_ACCEPT_NULL_INSTANCE +#endif + +// Macros to reduce typing: (P1), (P1,P2), (P1,P2,P3), ... +#define P_0 +#define P_1 P1 +#define P_2 P_1,P2 +#define P_3 P_2,P3 +#define P_4 P_3,P4 +#define P_5 P_4,P5 +#define P_6 P_5,P6 +#define P_7 P_6,P7 + +// Macros to reduce typing: (typename P1), (typename P1,typename P2), ... +#define PTN_0 +#define PTN_1 typename P1 +#define PTN_2 PTN_1,typename P2 +#define PTN_3 PTN_2,typename P3 +#define PTN_4 PTN_3,typename P4 +#define PTN_5 PTN_4,typename P5 +#define PTN_6 PTN_5,typename P6 +#define PTN_7 PTN_6,typename P7 + +// Include a comma first in list: ,typename P1,typename P2 +#define PTNC_0 +#define PTNC_1 ,PTN_1 +#define PTNC_2 ,PTN_2 +#define PTNC_3 ,PTN_3 +#define PTNC_4 ,PTN_4 +#define PTNC_5 ,PTN_5 +#define PTNC_6 ,PTN_6 +#define PTNC_7 ,PTN_7 + +#ifdef SQUNICODE +#define scstrcpy wcscpy +#else +#define scstrcpy strcpy +#endif + +inline const SQChar* strappchar(SQChar *buf, SQChar *in, SQChar ch){ + int l=scstrlen(in); + scstrcpy(buf,in); + buf[l] = ch; +#ifdef SQPLUS_ACCEPT_NULL_INSTANCE + if( ch=='x' ){ + buf[++l] = '|'; // Also accept NULL pointers + buf[++l] = 'o'; + } +#endif + buf[l+1] = 0; + return buf; +} + +template +struct sqTypeMask { }; + + +// Return type not included in type mask, delegate to void case + +// Base case, no arguments +template +struct sqTypeMask { + static const SQChar *Get(){ + static SQChar buf[64]; + //buf[0] = _SC('t'); + //buf[1] = 0; + //strcpy(buf,"t|x"); // Accept both instance and table, we don't use param anyway + buf[0] = _SC('.'); // Accept anything (not used) + buf[1] = 0; + return buf; + } +}; + +// Recursive case, peel of one arg at each level +#define DECLARE_RT_SQTYPEMASK(N,M) \ +template \ +struct sqTypeMask { \ + static const SQChar *Get(){ \ + static SQChar buf[10]; \ + return strappchar(buf, (SQChar*)sqTypeMask::Get(), \ + (SQChar)TypeInfo::TypeMask); \ + } \ +}; + +DECLARE_RT_SQTYPEMASK(1,0) +DECLARE_RT_SQTYPEMASK(2,1) +DECLARE_RT_SQTYPEMASK(3,2) +DECLARE_RT_SQTYPEMASK(4,3) +DECLARE_RT_SQTYPEMASK(5,4) +DECLARE_RT_SQTYPEMASK(6,5) +DECLARE_RT_SQTYPEMASK(7,6) + + +// Difference to above is that 1st param is instance instead of table + +#define DECLARE_RT_MEMBER_SQTYPEMASK(N,QUAL) \ +template \ +struct sqTypeMask { \ + static const SQChar *Get(){ \ + SQChar *buf = (SQChar*)sqTypeMask::Get(); \ + buf[0] = _SC('x'); \ + return buf; \ + } \ +}; + +// buf[1] = 0; \ + +DECLARE_RT_MEMBER_SQTYPEMASK(0,) +DECLARE_RT_MEMBER_SQTYPEMASK(1,) +DECLARE_RT_MEMBER_SQTYPEMASK(2,) +DECLARE_RT_MEMBER_SQTYPEMASK(3,) +DECLARE_RT_MEMBER_SQTYPEMASK(4,) +DECLARE_RT_MEMBER_SQTYPEMASK(5,) +DECLARE_RT_MEMBER_SQTYPEMASK(6,) +DECLARE_RT_MEMBER_SQTYPEMASK(7,) + +DECLARE_RT_MEMBER_SQTYPEMASK(0,const) +DECLARE_RT_MEMBER_SQTYPEMASK(1,const) +DECLARE_RT_MEMBER_SQTYPEMASK(2,const) +DECLARE_RT_MEMBER_SQTYPEMASK(3,const) +DECLARE_RT_MEMBER_SQTYPEMASK(4,const) +DECLARE_RT_MEMBER_SQTYPEMASK(5,const) +DECLARE_RT_MEMBER_SQTYPEMASK(6,const) +DECLARE_RT_MEMBER_SQTYPEMASK(7,const) + + +#ifdef _MSC_VER + +// Difference to above is we're using __cdecl calling convention here +// Only makes sense for MSVC where member functions can have different +// calling conventions (__cdecl or __thiscall) + +#define DECLARE_RT_MEMBER_SQTYPEMASK_CDECL(N,QUAL) \ +template \ +struct sqTypeMask { \ + static const SQChar *Get(){ \ + SQChar *buf = (SQChar*)sqTypeMask::Get(); \ + buf[0] = _SC('x'); \ + return buf; \ + } \ +}; + +// buf[1] = 0; \ + +DECLARE_RT_MEMBER_SQTYPEMASK_CDECL(0,) +DECLARE_RT_MEMBER_SQTYPEMASK_CDECL(1,) +DECLARE_RT_MEMBER_SQTYPEMASK_CDECL(2,) +DECLARE_RT_MEMBER_SQTYPEMASK_CDECL(3,) +DECLARE_RT_MEMBER_SQTYPEMASK_CDECL(4,) +DECLARE_RT_MEMBER_SQTYPEMASK_CDECL(5,) +DECLARE_RT_MEMBER_SQTYPEMASK_CDECL(6,) +DECLARE_RT_MEMBER_SQTYPEMASK_CDECL(7,) + +DECLARE_RT_MEMBER_SQTYPEMASK_CDECL(0,const) +DECLARE_RT_MEMBER_SQTYPEMASK_CDECL(1,const) +DECLARE_RT_MEMBER_SQTYPEMASK_CDECL(2,const) +DECLARE_RT_MEMBER_SQTYPEMASK_CDECL(3,const) +DECLARE_RT_MEMBER_SQTYPEMASK_CDECL(4,const) +DECLARE_RT_MEMBER_SQTYPEMASK_CDECL(5,const) +DECLARE_RT_MEMBER_SQTYPEMASK_CDECL(6,const) +DECLARE_RT_MEMBER_SQTYPEMASK_CDECL(7,const) + +#endif // _MSC_VER + diff --git a/squirrel_3_0_1_stable/sqplus/SqPlusUtf8.cpp b/squirrel_3_0_1_stable/_OLD_sqplus/SqPlusUtf8.cpp similarity index 96% rename from squirrel_3_0_1_stable/sqplus/SqPlusUtf8.cpp rename to squirrel_3_0_1_stable/_OLD_sqplus/SqPlusUtf8.cpp index 7505e9928..f5ee39ae5 100644 --- a/squirrel_3_0_1_stable/sqplus/SqPlusUtf8.cpp +++ b/squirrel_3_0_1_stable/_OLD_sqplus/SqPlusUtf8.cpp @@ -1,133 +1,133 @@ - -/////////////////////////////////////////////////////////////////////// -// Simple conversion routines, to, from UTF8 and full Unicode character -// (using int). -// - -// Only when needed -#if !defined(SQPLUS_USE_LATIN1) || SQPLUS_USE_LATIN1==0 - -static char g_utf8_length[256]; -static int g_did_init_length; - -void sqplus_init_utf8_lengths() { - // Fill in lengths in array above - for( int lb=0; lb<256; lb++ ){ - int l = -1; - if( !(lb&0x80) ) l=1; - else if( (lb&0xE0)==0xC0 ) l=2; - else if( (lb&0xF0)==0xE0 ) l=3; - else if( (lb&0xF8)==0xF0 ) l=4; - else if( (lb&0xFC)==0xF8 ) l=5; - else if( (lb&0xFE)==0xFC ) l=6; - g_utf8_length[lb] = l; - } - g_did_init_length = 1; -} - -// Length of a UTF8 encoded Unicode character -int sqplus_utf8_len(int lead_byte){ - if( !(lead_byte&0x80) ) return 1; // Special case, make faster - if( !g_did_init_length ) - sqplus_init_utf8_lengths(); - - return g_utf8_length[(unsigned char)lead_byte]; -} - -int sqplus_utf8_len_first(const char* pc){ - int lb = *(unsigned char*)pc; - if( !(lb&0x80) ) return 1; // Special case, make faster - if( !g_did_init_length ) - sqplus_init_utf8_lengths(); - - int l = g_utf8_length[(unsigned char)lb]; - if( l>0 ) return l; - - // Invalid UTF8 lead byte. Look for next valid character. - const char *pc1 = pc+1; - while( ((*pc1)&0xC0)==0x80 ) - pc1++; - return int(pc1 - pc); -} - - -// Length of a UTF8 encoded Unicode string (number of Unicode characters) -int sqplus_utf8_strlen(const char *str) { - if( !str ) return 0; - int l, tl=0; - while( *str ){ - l = sqplus_utf8_len_first(str); - str += l; - tl++; - } - return tl; -} - -// Convert one UTF8 encoded character to Unicode point -int sqplus_utf8_to_wchar(int *result, const char *string){ - int res=-1; - - // Assume argument pointers to be OK - unsigned char ch = *string; - int l = sqplus_utf8_len(ch); - - if( l<1 ) return -1; - int wc = l>1 ? (ch&(0x7F>>l)) : ch; - while( l>1 ){ - wc = (wc<<6) + (*++string & 0x3F); - l--; - } - *result = wc; - - return 0; -} - -// Convert one Unicode point to UTF8 encoded version. -// Checks if output fits in 1/4/6 bytes buffer. -int sqplus_wchar_to_utf8(char *s, int wc, int size){ - if( size<1 ) return -1; - if( (unsigned int)wc>=0x80000000 ) return -2; - - // Single byte case - if( wc<0x80 ){ - *s = (char)wc; - //*s = (char)wc&0x7F; - return 1; - } - if( size<4 ) return -3; - - // Two or more UTF8 bytes - int p = 1; // Index of last UTF8 byte - if( wc>0x7FF ){ // 11 bits - // Three or more UTF8 bytes - p++; // p>=2 - if( wc>0xFFFF ){ // 16 bits - // Four or more UTF8 bytes - p++; // p>=3 - if( wc>0x1FFFFF ){ // 21 bits - // Five or more UTF8 bytes - if( size<6 ) return -3; - p++; // p>=4 UTF8 bytes - if( wc>0x3FFFFFF ){ // 26 bits - // Six UTF8 bytes - p++; // p>=5 - if( (unsigned int)wc>(unsigned int)0x7FFFFFF ){ // 31 bits - // Would need 7 UTF8 bytes. Not supported. - return -10; - } - s[p-4] = 0x80 | ((wc>>24)&0x3F); // Bit 24..29 - } - s[p-3] = 0x80 | ((wc>>18)&0x3F); // Bit 18..23 - } - s[p-2] = 0x80 | ((wc>>12)&0x3F); // Bit 12..17 - } - s[p-1] = 0x80 | ((wc>>6)&0x3F); // Bit 6..11 - } - s[p] = 0x80 | (wc&0x3F); // Bit 0..5 - s[0] = (0xFC << (5-p)) | (wc>>(p*6)); - - return p+1; -} - -#endif // #if !defined(SQPLUS_USE_LATIN1) || SQPLUS_USE_LATIN1==0 - + +/////////////////////////////////////////////////////////////////////// +// Simple conversion routines, to, from UTF8 and full Unicode character +// (using int). +// + +// Only when needed +#if !defined(SQPLUS_USE_LATIN1) || SQPLUS_USE_LATIN1==0 + +static char g_utf8_length[256]; +static int g_did_init_length; + +void sqplus_init_utf8_lengths() { + // Fill in lengths in array above + for( int lb=0; lb<256; lb++ ){ + int l = -1; + if( !(lb&0x80) ) l=1; + else if( (lb&0xE0)==0xC0 ) l=2; + else if( (lb&0xF0)==0xE0 ) l=3; + else if( (lb&0xF8)==0xF0 ) l=4; + else if( (lb&0xFC)==0xF8 ) l=5; + else if( (lb&0xFE)==0xFC ) l=6; + g_utf8_length[lb] = l; + } + g_did_init_length = 1; +} + +// Length of a UTF8 encoded Unicode character +int sqplus_utf8_len(int lead_byte){ + if( !(lead_byte&0x80) ) return 1; // Special case, make faster + if( !g_did_init_length ) + sqplus_init_utf8_lengths(); + + return g_utf8_length[(unsigned char)lead_byte]; +} + +int sqplus_utf8_len_first(const char* pc){ + int lb = *(unsigned char*)pc; + if( !(lb&0x80) ) return 1; // Special case, make faster + if( !g_did_init_length ) + sqplus_init_utf8_lengths(); + + int l = g_utf8_length[(unsigned char)lb]; + if( l>0 ) return l; + + // Invalid UTF8 lead byte. Look for next valid character. + const char *pc1 = pc+1; + while( ((*pc1)&0xC0)==0x80 ) + pc1++; + return int(pc1 - pc); +} + + +// Length of a UTF8 encoded Unicode string (number of Unicode characters) +int sqplus_utf8_strlen(const char *str) { + if( !str ) return 0; + int l, tl=0; + while( *str ){ + l = sqplus_utf8_len_first(str); + str += l; + tl++; + } + return tl; +} + +// Convert one UTF8 encoded character to Unicode point +int sqplus_utf8_to_wchar(int *result, const char *string){ + int res=-1; + + // Assume argument pointers to be OK + unsigned char ch = *string; + int l = sqplus_utf8_len(ch); + + if( l<1 ) return -1; + int wc = l>1 ? (ch&(0x7F>>l)) : ch; + while( l>1 ){ + wc = (wc<<6) + (*++string & 0x3F); + l--; + } + *result = wc; + + return 0; +} + +// Convert one Unicode point to UTF8 encoded version. +// Checks if output fits in 1/4/6 bytes buffer. +int sqplus_wchar_to_utf8(char *s, int wc, int size){ + if( size<1 ) return -1; + if( (unsigned int)wc>=0x80000000 ) return -2; + + // Single byte case + if( wc<0x80 ){ + *s = (char)wc; + //*s = (char)wc&0x7F; + return 1; + } + if( size<4 ) return -3; + + // Two or more UTF8 bytes + int p = 1; // Index of last UTF8 byte + if( wc>0x7FF ){ // 11 bits + // Three or more UTF8 bytes + p++; // p>=2 + if( wc>0xFFFF ){ // 16 bits + // Four or more UTF8 bytes + p++; // p>=3 + if( wc>0x1FFFFF ){ // 21 bits + // Five or more UTF8 bytes + if( size<6 ) return -3; + p++; // p>=4 UTF8 bytes + if( wc>0x3FFFFFF ){ // 26 bits + // Six UTF8 bytes + p++; // p>=5 + if( (unsigned int)wc>(unsigned int)0x7FFFFFF ){ // 31 bits + // Would need 7 UTF8 bytes. Not supported. + return -10; + } + s[p-4] = 0x80 | ((wc>>24)&0x3F); // Bit 24..29 + } + s[p-3] = 0x80 | ((wc>>18)&0x3F); // Bit 18..23 + } + s[p-2] = 0x80 | ((wc>>12)&0x3F); // Bit 12..17 + } + s[p-1] = 0x80 | ((wc>>6)&0x3F); // Bit 6..11 + } + s[p] = 0x80 | (wc&0x3F); // Bit 0..5 + s[0] = (0xFC << (5-p)) | (wc>>(p*6)); + + return p+1; +} + +#endif // #if !defined(SQPLUS_USE_LATIN1) || SQPLUS_USE_LATIN1==0 + diff --git a/squirrel_3_0_1_stable/sqplus/SqPlusUtf8.h b/squirrel_3_0_1_stable/_OLD_sqplus/SqPlusUtf8.h similarity index 96% rename from squirrel_3_0_1_stable/sqplus/SqPlusUtf8.h rename to squirrel_3_0_1_stable/_OLD_sqplus/SqPlusUtf8.h index b0c14aa36..faefcb6c8 100644 --- a/squirrel_3_0_1_stable/sqplus/SqPlusUtf8.h +++ b/squirrel_3_0_1_stable/_OLD_sqplus/SqPlusUtf8.h @@ -1,15 +1,15 @@ -#ifndef SQPLUSUTF8_H -#define SQPLUSUTF8_H - -#if defined(SQUTF8) || SQPLUS_USE_LATIN1!=1 - -// Simple Unicode <-> UTF8 conversion routines -//int sqplus_utf8_len(char lead_byte); -int sqplus_utf8_len_first(const char *str); -int sqplus_utf8_strlen(const char *str); -int sqplus_utf8_to_wchar(int *result, const char *string); -int sqplus_wchar_to_utf8(char *s, int wc, int size); - -#endif // defined(SQUTF8) || SQPLUS_USE_LATIN1!=1 - -#endif // SQPLUSUTF8_H +#ifndef SQPLUSUTF8_H +#define SQPLUSUTF8_H + +#if defined(SQUTF8) || SQPLUS_USE_LATIN1!=1 + +// Simple Unicode <-> UTF8 conversion routines +//int sqplus_utf8_len(char lead_byte); +int sqplus_utf8_len_first(const char *str); +int sqplus_utf8_strlen(const char *str); +int sqplus_utf8_to_wchar(int *result, const char *string); +int sqplus_wchar_to_utf8(char *s, int wc, int size); + +#endif // defined(SQUTF8) || SQPLUS_USE_LATIN1!=1 + +#endif // SQPLUSUTF8_H diff --git a/squirrel_3_0_1_stable/sqplus/SquirrelBindingsUtils.cpp b/squirrel_3_0_1_stable/_OLD_sqplus/SquirrelBindingsUtils.cpp similarity index 96% rename from squirrel_3_0_1_stable/sqplus/SquirrelBindingsUtils.cpp rename to squirrel_3_0_1_stable/_OLD_sqplus/SquirrelBindingsUtils.cpp index cd337961c..81d1ef4fa 100644 --- a/squirrel_3_0_1_stable/sqplus/SquirrelBindingsUtils.cpp +++ b/squirrel_3_0_1_stable/_OLD_sqplus/SquirrelBindingsUtils.cpp @@ -1,161 +1,161 @@ -#include "sqplus.h" - -BOOL CreateStaticNamespace(HSQUIRRELVM v,ScriptNamespaceDecl *sn) -{ - int n = 0; - sq_pushroottable(v); - sq_pushstring(v,sn->name,-1); - sq_newtable(v); - const ScriptClassMemberDecl *members = sn->members; - const ScriptClassMemberDecl *m = NULL; - while(members[n].name) { - m = &members[n]; - sq_pushstring(v,m->name,-1); - sq_newclosure(v,m->func,0); - sq_setparamscheck(v,m->params,m->typemask); - sq_setnativeclosurename(v,-1,m->name); - sq_createslot(v,-3); - n++; - } - const ScriptConstantDecl *consts = sn->constants; - const ScriptConstantDecl *c = NULL; - n = 0; - while(consts[n].name) { - c = &consts[n]; - sq_pushstring(v,c->name,-1); - switch(c->type) { - case OT_STRING: sq_pushstring(v,c->val.s,-1);break; - case OT_INTEGER: sq_pushinteger(v,c->val.i);break; - case OT_FLOAT: sq_pushfloat(v,c->val.f);break; - } - sq_createslot(v,-3); - n++; - } - if(sn->delegate) { - const ScriptClassMemberDecl *members = sn->delegate; - const ScriptClassMemberDecl *m = NULL; - sq_newtable(v); - while(members[n].name) { - m = &members[n]; - sq_pushstring(v,m->name,-1); - sq_newclosure(v,m->func,0); - sq_setparamscheck(v,m->params,m->typemask); - sq_setnativeclosurename(v,-1,m->name); - sq_createslot(v,-3); - n++; - } - sq_setdelegate(v,-2); - } - sq_createslot(v,-3); - sq_pop(v,1); - - return TRUE; -} - -BOOL CreateClass(HSQUIRRELVM v,SquirrelClassDecl *cd) -{ - int n = 0; - int oldtop = sq_gettop(v); - sq_pushroottable(v); - sq_pushstring(v,cd->name,-1); - if(cd->base) { - sq_pushstring(v,cd->base,-1); - if(SQ_FAILED(sq_get(v,-3))) { // Make sure the base exists if specified by cd->base name. - sq_settop(v,oldtop); - return FALSE; - } - } - if(SQ_FAILED(sq_newclass(v,cd->base?1:0))) { // Will inherit from base class on stack from sq_get() above. - sq_settop(v,oldtop); - return FALSE; - } -// sq_settypetag(v,-1,(unsigned int)cd); -#ifdef _WIN32 -#pragma warning(disable : 4311) -#endif - sq_settypetag(v,-1,reinterpret_cast(cd)); - const ScriptClassMemberDecl *members = cd->members; - const ScriptClassMemberDecl *m = NULL; - if (members) { - while(members[n].name) { - m = &members[n]; - sq_pushstring(v,m->name,-1); - sq_newclosure(v,m->func,0); - sq_setparamscheck(v,m->params,m->typemask); - sq_setnativeclosurename(v,-1,m->name); - sq_createslot(v,-3); - n++; - } - } // if - sq_createslot(v,-3); - sq_pop(v,1); - return TRUE; -} - -BOOL CreateNativeClassInstance(HSQUIRRELVM v, - const SQChar *classname, - SQUserPointer ud, - SQRELEASEHOOK hook) -{ - // If we don't do this, SquirrelVM keeps an old pointer around and this - // will be used by SquirrelObject. That crashes when using several VMs. - SquirrelVM::Init( v ); - - int oldtop = sq_gettop(v); - sq_pushroottable(v); - sq_pushstring(v,classname,-1); - if(SQ_FAILED(sq_rawget(v,-2))){ //Get the class (created with sq_newclass()). - sq_settop(v,oldtop); - return FALSE; - } - //sq_pushroottable(v); - if(SQ_FAILED(sq_createinstance(v,-1))) { - sq_settop(v,oldtop); - return FALSE; - } - -#ifdef SQ_USE_CLASS_INHERITANCE - HSQOBJECT ho; - sq_getstackobj(v, -1, &ho); // OT_INSTANCE - SquirrelObject instance(ho); - SqPlus::PopulateAncestry(v, instance, ud); -#endif - - sq_remove(v,-3); //removes the root table - sq_remove(v,-2); //removes the class - if(SQ_FAILED(sq_setinstanceup(v,-1,ud))) { - sq_settop(v,oldtop); - return FALSE; - } - sq_setreleasehook(v,-1,hook); - return TRUE; -} - - - -// Create native class instance and leave on stack. -BOOL CreateConstructNativeClassInstance(HSQUIRRELVM v,const SQChar * className) { - int oldtop = sq_gettop(v); - sq_pushroottable(v); - sq_pushstring(v,className,-1); - if (SQ_FAILED(sq_rawget(v,-2))) { // Get the class (created with sq_newclass()). - sq_settop(v,oldtop); - return FALSE; - } // if -#if 0 - sq_remove(v,-3); // Remove the root table. - sq_push(v,1); // Push the 'this'. -#else // Kamaitati's change. 5/28/06 jcs. - sq_remove(v,-2); // Remove the root table. - sq_pushroottable(v); // Push the 'this'. -#endif - if (SQ_FAILED(sq_call(v,1,SQTrue,SQ_CALL_RAISE_ERROR))) { // Call ClassName(): creates new instance and calls constructor (instead of sq_createinstance() where constructor is not called). - sq_settop(v,oldtop); - return FALSE; - } // if - sq_remove(v,-2); // Remove the class. - // int newtop = sq_gettop(v); - return TRUE; -} // CreateConstructNativeClassInstance - - +#include "sqplus.h" + +BOOL CreateStaticNamespace(HSQUIRRELVM v,ScriptNamespaceDecl *sn) +{ + int n = 0; + sq_pushroottable(v); + sq_pushstring(v,sn->name,-1); + sq_newtable(v); + const ScriptClassMemberDecl *members = sn->members; + const ScriptClassMemberDecl *m = NULL; + while(members[n].name) { + m = &members[n]; + sq_pushstring(v,m->name,-1); + sq_newclosure(v,m->func,0); + sq_setparamscheck(v,m->params,m->typemask); + sq_setnativeclosurename(v,-1,m->name); + sq_createslot(v,-3); + n++; + } + const ScriptConstantDecl *consts = sn->constants; + const ScriptConstantDecl *c = NULL; + n = 0; + while(consts[n].name) { + c = &consts[n]; + sq_pushstring(v,c->name,-1); + switch(c->type) { + case OT_STRING: sq_pushstring(v,c->val.s,-1);break; + case OT_INTEGER: sq_pushinteger(v,c->val.i);break; + case OT_FLOAT: sq_pushfloat(v,c->val.f);break; + } + sq_createslot(v,-3); + n++; + } + if(sn->delegate) { + const ScriptClassMemberDecl *members = sn->delegate; + const ScriptClassMemberDecl *m = NULL; + sq_newtable(v); + while(members[n].name) { + m = &members[n]; + sq_pushstring(v,m->name,-1); + sq_newclosure(v,m->func,0); + sq_setparamscheck(v,m->params,m->typemask); + sq_setnativeclosurename(v,-1,m->name); + sq_createslot(v,-3); + n++; + } + sq_setdelegate(v,-2); + } + sq_createslot(v,-3); + sq_pop(v,1); + + return TRUE; +} + +BOOL CreateClass(HSQUIRRELVM v,SquirrelClassDecl *cd) +{ + int n = 0; + int oldtop = sq_gettop(v); + sq_pushroottable(v); + sq_pushstring(v,cd->name,-1); + if(cd->base) { + sq_pushstring(v,cd->base,-1); + if(SQ_FAILED(sq_get(v,-3))) { // Make sure the base exists if specified by cd->base name. + sq_settop(v,oldtop); + return FALSE; + } + } + if(SQ_FAILED(sq_newclass(v,cd->base?1:0))) { // Will inherit from base class on stack from sq_get() above. + sq_settop(v,oldtop); + return FALSE; + } +// sq_settypetag(v,-1,(unsigned int)cd); +#ifdef _WIN32 +#pragma warning(disable : 4311) +#endif + sq_settypetag(v,-1,reinterpret_cast(cd)); + const ScriptClassMemberDecl *members = cd->members; + const ScriptClassMemberDecl *m = NULL; + if (members) { + while(members[n].name) { + m = &members[n]; + sq_pushstring(v,m->name,-1); + sq_newclosure(v,m->func,0); + sq_setparamscheck(v,m->params,m->typemask); + sq_setnativeclosurename(v,-1,m->name); + sq_createslot(v,-3); + n++; + } + } // if + sq_createslot(v,-3); + sq_pop(v,1); + return TRUE; +} + +BOOL CreateNativeClassInstance(HSQUIRRELVM v, + const SQChar *classname, + SQUserPointer ud, + SQRELEASEHOOK hook) +{ + // If we don't do this, SquirrelVM keeps an old pointer around and this + // will be used by SquirrelObject. That crashes when using several VMs. + SquirrelVM::Init( v ); + + int oldtop = sq_gettop(v); + sq_pushroottable(v); + sq_pushstring(v,classname,-1); + if(SQ_FAILED(sq_rawget(v,-2))){ //Get the class (created with sq_newclass()). + sq_settop(v,oldtop); + return FALSE; + } + //sq_pushroottable(v); + if(SQ_FAILED(sq_createinstance(v,-1))) { + sq_settop(v,oldtop); + return FALSE; + } + +#ifdef SQ_USE_CLASS_INHERITANCE + HSQOBJECT ho; + sq_getstackobj(v, -1, &ho); // OT_INSTANCE + SquirrelObject instance(ho); + SqPlus::PopulateAncestry(v, instance, ud); +#endif + + sq_remove(v,-3); //removes the root table + sq_remove(v,-2); //removes the class + if(SQ_FAILED(sq_setinstanceup(v,-1,ud))) { + sq_settop(v,oldtop); + return FALSE; + } + sq_setreleasehook(v,-1,hook); + return TRUE; +} + + + +// Create native class instance and leave on stack. +BOOL CreateConstructNativeClassInstance(HSQUIRRELVM v,const SQChar * className) { + int oldtop = sq_gettop(v); + sq_pushroottable(v); + sq_pushstring(v,className,-1); + if (SQ_FAILED(sq_rawget(v,-2))) { // Get the class (created with sq_newclass()). + sq_settop(v,oldtop); + return FALSE; + } // if +#if 0 + sq_remove(v,-3); // Remove the root table. + sq_push(v,1); // Push the 'this'. +#else // Kamaitati's change. 5/28/06 jcs. + sq_remove(v,-2); // Remove the root table. + sq_pushroottable(v); // Push the 'this'. +#endif + if (SQ_FAILED(sq_call(v,1,SQTrue,SQ_CALL_RAISE_ERROR))) { // Call ClassName(): creates new instance and calls constructor (instead of sq_createinstance() where constructor is not called). + sq_settop(v,oldtop); + return FALSE; + } // if + sq_remove(v,-2); // Remove the class. + // int newtop = sq_gettop(v); + return TRUE; +} // CreateConstructNativeClassInstance + + diff --git a/squirrel_3_0_1_stable/sqplus/SquirrelBindingsUtils.h b/squirrel_3_0_1_stable/_OLD_sqplus/SquirrelBindingsUtils.h similarity index 97% rename from squirrel_3_0_1_stable/sqplus/SquirrelBindingsUtils.h rename to squirrel_3_0_1_stable/_OLD_sqplus/SquirrelBindingsUtils.h index 11ab4be54..5f727c263 100644 --- a/squirrel_3_0_1_stable/sqplus/SquirrelBindingsUtils.h +++ b/squirrel_3_0_1_stable/_OLD_sqplus/SquirrelBindingsUtils.h @@ -1,152 +1,152 @@ -#ifndef SQUIRREL_BINDINGS_UTILS_H -#define SQUIRREL_BINDINGS_UTILS_H - -struct ScriptClassMemberDecl { - const SQChar *name; - SQFUNCTION func; - int params; - const SQChar *typemask; -}; - -struct SquirrelClassDecl { - const SQChar *name; - const SQChar *base; - const ScriptClassMemberDecl *members; -}; - -struct ScriptConstantDecl { - const SQChar *name; - SQObjectType type; - union value { - value(float v){ f = v; } - value(int v){ i = v; } - value(long int v){ li = v; } - value(const SQChar *v){ s = v; } - float f; - int i; - long int li; - const SQChar *s; - } val; -}; - -struct ScriptNamespaceDecl { - const SQChar *name; - const ScriptClassMemberDecl *members; - const ScriptConstantDecl *constants; - const ScriptClassMemberDecl *delegate; -}; - -#define _BEGIN_CLASS(classname) \ - int __##classname##__typeof(HSQUIRRELVM v) \ - { \ - sq_pushstring(v,_SC(#classname),-1); \ - return 1; \ - } \ - struct ScriptClassMemberDecl __##classname##_members[] = { \ - {_SC("_typeof"),__##classname##__typeof,1,NULL}, - -#define _BEGIN_NAMESPACE(xnamespace) struct ScriptClassMemberDecl __##xnamespace##_members[] = { -#define _BEGIN_NAMESPACE_CONSTANTS(xnamespace) {NULL,NULL,0,NULL}}; \ - struct ScriptConstantDecl __##xnamespace##_constants[] = { - -#define _BEGIN_DELEGATE(xnamespace) struct ScriptClassMemberDecl __##xnamespace##_delegate[] = { -#define _DELEGATE(xnamespace) __##xnamespace##_delegate -#define _END_DELEGATE(classname) {NULL,NULL,NULL,NULL}}; - -#define _CONSTANT(name,type,val) {_SC(#name),type,val}, -#define _CONSTANT_IMPL(name,type) {_SC(#name),type,name}, - -#define _MEMBER_FUNCTION(classname,name,nparams,typemask) \ - {_SC(#name),__##classname##_##name,nparams,typemask}, - -#define _END_NAMESPACE(classname,delegate) {NULL,OT_NULL,0}}; \ -struct ScriptNamespaceDecl __##classname##_decl = { \ - _SC(#classname), __##classname##_members,__##classname##_constants,delegate }; - -#define _END_CLASS(classname) {NULL,NULL,0,NULL}}; \ -struct SquirrelClassDecl __##classname##_decl = { \ - _SC(#classname), NULL, __##classname##_members }; - - -#define _END_CLASS_INHERITANCE(classname,base) {NULL,NULL,NULL,NULL}}; \ -struct SquirrelClassDecl __##classname##_decl = { \ - _SC(#classname), _SC(#base), __##classname##_members }; - -#define _MEMBER_FUNCTION_IMPL(classname,name) \ - int __##classname##_##name(HSQUIRRELVM v) - -#define _INIT_STATIC_NAMESPACE(classname) CreateStaticNamespace(SquirrelVM::GetVMPtr(),&__##classname##_decl); -#define _INIT_CLASS(classname)CreateClass(SquirrelVM::GetVMPtr(),&__##classname##_decl); - -#define _DECL_STATIC_NAMESPACE(xnamespace) extern struct ScriptNamespaceDecl __##xnamespace##_decl; -#define _DECL_CLASS(classname) extern struct SquirrelClassDecl __##classname##_decl; - -#define _CHECK_SELF(cppclass,scriptclass) \ - cppclass *self = NULL; \ - if(SQ_FAILED(sq_getinstanceup(v,1,(SQUserPointer*)&self,(SQUserPointer)&__##scriptclass##_decl))) { \ - return sq_throwerror(v,_SC("invalid instance type"));\ - } - -#define _CHECK_INST_PARAM(pname,idx,cppclass,scriptclass) \ - cppclass *pname = NULL; \ - if(SQ_FAILED(sq_getinstanceup(v,idx,(SQUserPointer*)&pname,(SQUserPointer)&__##scriptclass##_decl))) { \ - return sq_throwerror(v,_SC("invalid instance type"));\ - } \ - -#define _CHECK_INST_PARAM_BREAK(pname,idx,cppclass,scriptclass) \ - cppclass *pname = NULL; \ - if(SQ_FAILED(sq_getinstanceup(v,idx,(SQUserPointer*)&pname,(SQUserPointer)&__##scriptclass##_decl))) { \ - break; \ - } \ - -#define _CLASS_TAG(classname) ((unsigned int)&__##classname##_decl) - - -#define _DECL_NATIVE_CONSTRUCTION(classname,cppclass) \ - BOOL push_##classname(cppclass &quat); \ - SquirrelObject new_##classname(cppclass &quat); - -#define _IMPL_NATIVE_CONSTRUCTION(classname,cppclass) \ -static int classname##_release_hook(SQUserPointer p, int size) \ -{ \ - if(p) { \ - cppclass *pv = (cppclass *)p; \ - delete pv; \ - } \ - return 0; \ -} \ -BOOL push_##classname(cppclass &quat) \ -{ \ - cppclass *newquat = new cppclass; \ - *newquat = quat; \ - if(!CreateNativeClassInstance(SquirrelVM::GetVMPtr(),_SC(#classname),newquat,classname##_release_hook)) { \ - delete newquat; \ - return FALSE; \ - } \ - return TRUE; \ -} \ -SquirrelObject new_##classname(cppclass &quat) \ -{ \ - SquirrelObject ret; \ - if(push_##classname(quat)) { \ - ret.AttachToStackObject(-1); \ - sq_pop(SquirrelVM::GetVMPtr(),1); \ - } \ - return ret; \ -} \ -int construct_##classname(cppclass *p) \ -{ \ - sq_setinstanceup(SquirrelVM::GetVMPtr(),1,p); \ - sq_setreleasehook(SquirrelVM::GetVMPtr(),1,classname##_release_hook); \ - return 1; \ -} - -BOOL CreateStaticClass(HSQUIRRELVM v,SquirrelClassDecl *cd); -BOOL CreateStaticNamespace(HSQUIRRELVM v,ScriptNamespaceDecl *sn); -BOOL CreateClass(HSQUIRRELVM v,SquirrelClassDecl *cd); -BOOL InitScriptClasses(HSQUIRRELVM v); -BOOL CreateNativeClassInstance(HSQUIRRELVM v,const SQChar *classname,SQUserPointer ud,SQRELEASEHOOK hook); -BOOL CreateConstructNativeClassInstance(HSQUIRRELVM v,const SQChar * className); - -#endif // SQUIRREL_BINDINGS_UTILS_H - +#ifndef SQUIRREL_BINDINGS_UTILS_H +#define SQUIRREL_BINDINGS_UTILS_H + +struct ScriptClassMemberDecl { + const SQChar *name; + SQFUNCTION func; + int params; + const SQChar *typemask; +}; + +struct SquirrelClassDecl { + const SQChar *name; + const SQChar *base; + const ScriptClassMemberDecl *members; +}; + +struct ScriptConstantDecl { + const SQChar *name; + SQObjectType type; + union value { + value(float v){ f = v; } + value(int v){ i = v; } + value(long int v){ li = v; } + value(const SQChar *v){ s = v; } + float f; + int i; + long int li; + const SQChar *s; + } val; +}; + +struct ScriptNamespaceDecl { + const SQChar *name; + const ScriptClassMemberDecl *members; + const ScriptConstantDecl *constants; + const ScriptClassMemberDecl *delegate; +}; + +#define _BEGIN_CLASS(classname) \ + int __##classname##__typeof(HSQUIRRELVM v) \ + { \ + sq_pushstring(v,_SC(#classname),-1); \ + return 1; \ + } \ + struct ScriptClassMemberDecl __##classname##_members[] = { \ + {_SC("_typeof"),__##classname##__typeof,1,NULL}, + +#define _BEGIN_NAMESPACE(xnamespace) struct ScriptClassMemberDecl __##xnamespace##_members[] = { +#define _BEGIN_NAMESPACE_CONSTANTS(xnamespace) {NULL,NULL,0,NULL}}; \ + struct ScriptConstantDecl __##xnamespace##_constants[] = { + +#define _BEGIN_DELEGATE(xnamespace) struct ScriptClassMemberDecl __##xnamespace##_delegate[] = { +#define _DELEGATE(xnamespace) __##xnamespace##_delegate +#define _END_DELEGATE(classname) {NULL,NULL,NULL,NULL}}; + +#define _CONSTANT(name,type,val) {_SC(#name),type,val}, +#define _CONSTANT_IMPL(name,type) {_SC(#name),type,name}, + +#define _MEMBER_FUNCTION(classname,name,nparams,typemask) \ + {_SC(#name),__##classname##_##name,nparams,typemask}, + +#define _END_NAMESPACE(classname,delegate) {NULL,OT_NULL,0}}; \ +struct ScriptNamespaceDecl __##classname##_decl = { \ + _SC(#classname), __##classname##_members,__##classname##_constants,delegate }; + +#define _END_CLASS(classname) {NULL,NULL,0,NULL}}; \ +struct SquirrelClassDecl __##classname##_decl = { \ + _SC(#classname), NULL, __##classname##_members }; + + +#define _END_CLASS_INHERITANCE(classname,base) {NULL,NULL,NULL,NULL}}; \ +struct SquirrelClassDecl __##classname##_decl = { \ + _SC(#classname), _SC(#base), __##classname##_members }; + +#define _MEMBER_FUNCTION_IMPL(classname,name) \ + int __##classname##_##name(HSQUIRRELVM v) + +#define _INIT_STATIC_NAMESPACE(classname) CreateStaticNamespace(SquirrelVM::GetVMPtr(),&__##classname##_decl); +#define _INIT_CLASS(classname)CreateClass(SquirrelVM::GetVMPtr(),&__##classname##_decl); + +#define _DECL_STATIC_NAMESPACE(xnamespace) extern struct ScriptNamespaceDecl __##xnamespace##_decl; +#define _DECL_CLASS(classname) extern struct SquirrelClassDecl __##classname##_decl; + +#define _CHECK_SELF(cppclass,scriptclass) \ + cppclass *self = NULL; \ + if(SQ_FAILED(sq_getinstanceup(v,1,(SQUserPointer*)&self,(SQUserPointer)&__##scriptclass##_decl))) { \ + return sq_throwerror(v,_SC("invalid instance type"));\ + } + +#define _CHECK_INST_PARAM(pname,idx,cppclass,scriptclass) \ + cppclass *pname = NULL; \ + if(SQ_FAILED(sq_getinstanceup(v,idx,(SQUserPointer*)&pname,(SQUserPointer)&__##scriptclass##_decl))) { \ + return sq_throwerror(v,_SC("invalid instance type"));\ + } \ + +#define _CHECK_INST_PARAM_BREAK(pname,idx,cppclass,scriptclass) \ + cppclass *pname = NULL; \ + if(SQ_FAILED(sq_getinstanceup(v,idx,(SQUserPointer*)&pname,(SQUserPointer)&__##scriptclass##_decl))) { \ + break; \ + } \ + +#define _CLASS_TAG(classname) ((unsigned int)&__##classname##_decl) + + +#define _DECL_NATIVE_CONSTRUCTION(classname,cppclass) \ + BOOL push_##classname(cppclass &quat); \ + SquirrelObject new_##classname(cppclass &quat); + +#define _IMPL_NATIVE_CONSTRUCTION(classname,cppclass) \ +static int classname##_release_hook(SQUserPointer p, int size) \ +{ \ + if(p) { \ + cppclass *pv = (cppclass *)p; \ + delete pv; \ + } \ + return 0; \ +} \ +BOOL push_##classname(cppclass &quat) \ +{ \ + cppclass *newquat = new cppclass; \ + *newquat = quat; \ + if(!CreateNativeClassInstance(SquirrelVM::GetVMPtr(),_SC(#classname),newquat,classname##_release_hook)) { \ + delete newquat; \ + return FALSE; \ + } \ + return TRUE; \ +} \ +SquirrelObject new_##classname(cppclass &quat) \ +{ \ + SquirrelObject ret; \ + if(push_##classname(quat)) { \ + ret.AttachToStackObject(-1); \ + sq_pop(SquirrelVM::GetVMPtr(),1); \ + } \ + return ret; \ +} \ +int construct_##classname(cppclass *p) \ +{ \ + sq_setinstanceup(SquirrelVM::GetVMPtr(),1,p); \ + sq_setreleasehook(SquirrelVM::GetVMPtr(),1,classname##_release_hook); \ + return 1; \ +} + +BOOL CreateStaticClass(HSQUIRRELVM v,SquirrelClassDecl *cd); +BOOL CreateStaticNamespace(HSQUIRRELVM v,ScriptNamespaceDecl *sn); +BOOL CreateClass(HSQUIRRELVM v,SquirrelClassDecl *cd); +BOOL InitScriptClasses(HSQUIRRELVM v); +BOOL CreateNativeClassInstance(HSQUIRRELVM v,const SQChar *classname,SQUserPointer ud,SQRELEASEHOOK hook); +BOOL CreateConstructNativeClassInstance(HSQUIRRELVM v,const SQChar * className); + +#endif // SQUIRREL_BINDINGS_UTILS_H + diff --git a/squirrel_3_0_1_stable/sqplus/SquirrelBindingsUtilsWin32.cpp b/squirrel_3_0_1_stable/_OLD_sqplus/SquirrelBindingsUtilsWin32.cpp similarity index 96% rename from squirrel_3_0_1_stable/sqplus/SquirrelBindingsUtilsWin32.cpp rename to squirrel_3_0_1_stable/_OLD_sqplus/SquirrelBindingsUtilsWin32.cpp index dd3f850ca..448c49f25 100644 --- a/squirrel_3_0_1_stable/sqplus/SquirrelBindingsUtilsWin32.cpp +++ b/squirrel_3_0_1_stable/_OLD_sqplus/SquirrelBindingsUtilsWin32.cpp @@ -1,31 +1,31 @@ -#include "sqplus.h" - -//#include "SquirrelObject.h" -//#include "SquirrelVM.h" -#include "SquirrelBindingsUtilsWin32.h" - -int refcounted_release_hook(SQUserPointer p, int size) -{ - IUnknown *pRC = (IUnknown*)p; - pRC->Release(); - return 0; -} - -static BOOL __CreateRefCountedInstance(HSQUIRRELVM v,const SQChar *classname,IUnknown *pRC,SQRELEASEHOOK hook) -{ - if(!CreateNativeClassInstance(v,classname,pRC,hook)) return FALSE; - return TRUE; -} - -int construct_RefCounted(IUnknown *p) -{ - sq_setinstanceup(SquirrelVM::GetVMPtr(),1,p); - sq_setreleasehook(SquirrelVM::GetVMPtr(),1,refcounted_release_hook); - return 1; -} - - -BOOL CreateRefCountedInstance(HSQUIRRELVM v,const SQChar *classname,IUnknown *pRC) -{ - return __CreateRefCountedInstance(v,classname,pRC,refcounted_release_hook); -} +#include "sqplus.h" + +//#include "SquirrelObject.h" +//#include "SquirrelVM.h" +#include "SquirrelBindingsUtilsWin32.h" + +int refcounted_release_hook(SQUserPointer p, int size) +{ + IUnknown *pRC = (IUnknown*)p; + pRC->Release(); + return 0; +} + +static BOOL __CreateRefCountedInstance(HSQUIRRELVM v,const SQChar *classname,IUnknown *pRC,SQRELEASEHOOK hook) +{ + if(!CreateNativeClassInstance(v,classname,pRC,hook)) return FALSE; + return TRUE; +} + +int construct_RefCounted(IUnknown *p) +{ + sq_setinstanceup(SquirrelVM::GetVMPtr(),1,p); + sq_setreleasehook(SquirrelVM::GetVMPtr(),1,refcounted_release_hook); + return 1; +} + + +BOOL CreateRefCountedInstance(HSQUIRRELVM v,const SQChar *classname,IUnknown *pRC) +{ + return __CreateRefCountedInstance(v,classname,pRC,refcounted_release_hook); +} diff --git a/squirrel_3_0_1_stable/sqplus/SquirrelBindingsUtilsWin32.h b/squirrel_3_0_1_stable/_OLD_sqplus/SquirrelBindingsUtilsWin32.h similarity index 96% rename from squirrel_3_0_1_stable/sqplus/SquirrelBindingsUtilsWin32.h rename to squirrel_3_0_1_stable/_OLD_sqplus/SquirrelBindingsUtilsWin32.h index 3f3358422..0acd05147 100644 --- a/squirrel_3_0_1_stable/sqplus/SquirrelBindingsUtilsWin32.h +++ b/squirrel_3_0_1_stable/_OLD_sqplus/SquirrelBindingsUtilsWin32.h @@ -1,41 +1,41 @@ -#ifndef SQUIRREL_BINDINGS_UTILS_WIN32_H -#define SQUIRREL_BINDINGS_UTILS_WIN32_H - -#ifndef _INC_WINDOWS -#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers -// Windows Header Files: -#include -#endif -#ifndef __IUnknown_INTERFACE_DEFINED__ -#include -#endif - -#ifndef SQUIRREL_BINDINGS_UTILS_H -#include "SquirrelBindingsUtils.h" -#endif - -#define _DECLARE_REFCOUNTED_NEW(cppclass,classname) \ - SquirrelObject new_##classname(cppclass *ptr) { \ - if(CreateRefCountedInstance(SquirrelVM::GetVMPtr(),_SC(#classname),ptr)) { \ - HSQOBJECT o; \ - sq_getstackobj(SquirrelVM::GetVMPtr(),-1,&o); \ - SquirrelObject tmp = o; \ - sq_pop(SquirrelVM::GetVMPtr(),1); \ - return tmp; \ - } \ - return SquirrelObject() ; \ - } - -#define _RETURN_REFCOUNTED_INSTANCE(classname,ptr) \ - if(!CreateRefCountedInstance(SquirrelVM::GetVMPtr(),_SC(#classname),ptr)) { \ - return sa.ThrowError(_SC("cannot create the class instance")); \ - } \ - return 1; - -BOOL CreateRefCountedInstance(HSQUIRRELVM v,const SQChar *classname,IUnknown *pRC); -BOOL CreateRefCountedInstanceChached(HSQUIRRELVM v,const SQChar *classname,IUnknown *pRC); -int refcounted_release_hook(SQUserPointer p, int size); -int construct_RefCounted(IUnknown *p); - -#endif // SQUIRREL_BINDINGS_UTILS_WIN32_H - +#ifndef SQUIRREL_BINDINGS_UTILS_WIN32_H +#define SQUIRREL_BINDINGS_UTILS_WIN32_H + +#ifndef _INC_WINDOWS +#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers +// Windows Header Files: +#include +#endif +#ifndef __IUnknown_INTERFACE_DEFINED__ +#include +#endif + +#ifndef SQUIRREL_BINDINGS_UTILS_H +#include "SquirrelBindingsUtils.h" +#endif + +#define _DECLARE_REFCOUNTED_NEW(cppclass,classname) \ + SquirrelObject new_##classname(cppclass *ptr) { \ + if(CreateRefCountedInstance(SquirrelVM::GetVMPtr(),_SC(#classname),ptr)) { \ + HSQOBJECT o; \ + sq_getstackobj(SquirrelVM::GetVMPtr(),-1,&o); \ + SquirrelObject tmp = o; \ + sq_pop(SquirrelVM::GetVMPtr(),1); \ + return tmp; \ + } \ + return SquirrelObject() ; \ + } + +#define _RETURN_REFCOUNTED_INSTANCE(classname,ptr) \ + if(!CreateRefCountedInstance(SquirrelVM::GetVMPtr(),_SC(#classname),ptr)) { \ + return sa.ThrowError(_SC("cannot create the class instance")); \ + } \ + return 1; + +BOOL CreateRefCountedInstance(HSQUIRRELVM v,const SQChar *classname,IUnknown *pRC); +BOOL CreateRefCountedInstanceChached(HSQUIRRELVM v,const SQChar *classname,IUnknown *pRC); +int refcounted_release_hook(SQUserPointer p, int size); +int construct_RefCounted(IUnknown *p); + +#endif // SQUIRREL_BINDINGS_UTILS_WIN32_H + diff --git a/squirrel_3_0_1_stable/sqplus/SquirrelObject.cpp b/squirrel_3_0_1_stable/_OLD_sqplus/SquirrelObject.cpp similarity index 95% rename from squirrel_3_0_1_stable/sqplus/SquirrelObject.cpp rename to squirrel_3_0_1_stable/_OLD_sqplus/SquirrelObject.cpp index 58d43bbed..90ffead80 100644 --- a/squirrel_3_0_1_stable/sqplus/SquirrelObject.cpp +++ b/squirrel_3_0_1_stable/_OLD_sqplus/SquirrelObject.cpp @@ -1,702 +1,702 @@ -#include "sqplus.h" - -SquirrelObject::SquirrelObject(void) -{ - sq_resetobject(&_o); -} - -SquirrelObject::~SquirrelObject() -{ - Reset(); -} - -SquirrelObject::SquirrelObject(const SquirrelObject &o) -{ - _o = o._o; - sq_addref(SquirrelVM::_VM,&_o); -} - -SquirrelObject::SquirrelObject(HSQOBJECT o) -{ - _o = o; - sq_addref(SquirrelVM::_VM,&_o); -} - -void SquirrelObject::Reset(void) { - if(SquirrelVM::_VM) - sq_release(SquirrelVM::_VM,&_o); - else if( _o._type!=OT_NULL && _o._unVal.pRefCounted ) - printf( "SquirrelObject::~SquirrelObject - Cannot release\n" ); - sq_resetobject(&_o); -} // SquirrelObject::Reset - -SquirrelObject SquirrelObject::Clone() -{ - SquirrelObject ret; - if(GetType() == OT_TABLE || GetType() == OT_ARRAY) - { - sq_pushobject(SquirrelVM::_VM,_o); - sq_clone(SquirrelVM::_VM,-1); - ret.AttachToStackObject(-1); - sq_pop(SquirrelVM::_VM,2); - } - return ret; - -} - -SquirrelObject & SquirrelObject::operator =(const SquirrelObject &o) -{ - //HSQOBJECT t; - //t = o._o; - //sq_addref(SquirrelVM::_VM,&t); - sq_addref(SquirrelVM::_VM, (HSQOBJECT*)&o._o); - sq_release(SquirrelVM::_VM,&_o); - //_o = t; - _o = o._o; - return *this; -} - -SquirrelObject & SquirrelObject::operator =(HSQOBJECT ho) -{ - sq_addref(SquirrelVM::_VM,&ho); - sq_release(SquirrelVM::_VM,&_o); - _o = ho; - return *this; -} - -SquirrelObject & SquirrelObject::operator =(int n) -{ - sq_pushinteger(SquirrelVM::_VM,n); - AttachToStackObject(-1); - sq_pop(SquirrelVM::_VM,1); - return *this; -} - -#include -#include "../squirrel/sqstate.h" -#include "../squirrel/sqvm.h" - -SquirrelObject & SquirrelObject::operator =(HSQUIRRELVM v) -{ - if( v && SquirrelVM::_VM ){ - SquirrelVM::_VM->Push(v); - AttachToStackObject(-1); - sq_poptop(SquirrelVM::_VM); - } - else Reset(); - return *this; -} - -bool SquirrelObject::operator == (const SquirrelObject &o) -{ - bool cmp = false; - HSQUIRRELVM v = SquirrelVM::GetVMPtr(); - int oldtop = sq_gettop(v); - - sq_pushobject(v, GetObjectHandle()); - sq_pushobject(v, o.GetObjectHandle()); - if(sq_cmp(v) == 0) - cmp = true; - - sq_settop(v, oldtop); - return cmp; -} - -bool SquirrelObject::CompareUserPointer( const SquirrelObject &o ) -{ - if( _o._type == o.GetObjectHandle()._type ) - if( _o._unVal.pUserPointer == o.GetObjectHandle()._unVal.pUserPointer ) - return true; - - return false; -} - -void SquirrelObject::ArrayAppend(const SquirrelObject &o) -{ - if(sq_isarray(_o)) { - sq_pushobject(SquirrelVM::_VM,_o); - sq_pushobject(SquirrelVM::_VM,o._o); - sq_arrayappend(SquirrelVM::_VM,-2); - sq_pop(SquirrelVM::_VM,1); - } -} - -void SquirrelObject::AttachToStackObject(int idx) -{ - HSQOBJECT t; - sq_getstackobj(SquirrelVM::_VM,idx,&t); - sq_addref(SquirrelVM::_VM,&t); - sq_release(SquirrelVM::_VM,&_o); - _o = t; -} - -BOOL SquirrelObject::SetDelegate(SquirrelObject &obj) -{ - if(obj.GetType() == OT_TABLE || - obj.GetType() == OT_NULL) { - switch(_o._type) { - case OT_USERDATA: - case OT_TABLE: - sq_pushobject(SquirrelVM::_VM,_o); - sq_pushobject(SquirrelVM::_VM,obj._o); - if(SQ_SUCCEEDED(sq_setdelegate(SquirrelVM::_VM,-2))) { - sq_pop(SquirrelVM::_VM,1); - return TRUE; - } - sq_pop(SquirrelVM::_VM,1); - break; - } - } - return FALSE; -} - -SquirrelObject SquirrelObject::GetDelegate() -{ - SquirrelObject ret; - if(_o._type == OT_TABLE || _o._type == OT_USERDATA) - { - int top = sq_gettop(SquirrelVM::_VM); - sq_pushobject(SquirrelVM::_VM,_o); - sq_getdelegate(SquirrelVM::_VM,-1); - ret.AttachToStackObject(-1); - sq_settop(SquirrelVM::_VM,top); -// sq_pop(SquirrelVM::_VM,2); - } - return ret; -} - -BOOL SquirrelObject::IsNull() const -{ - return sq_isnull(_o); -} - -BOOL SquirrelObject::IsNumeric() const -{ - return sq_isnumeric(_o); -} - -int SquirrelObject::Len() const -{ - int ret = 0; - if(sq_isarray(_o) || sq_istable(_o) || sq_isstring(_o)) { - sq_pushobject(SquirrelVM::_VM,_o); - ret = sq_getsize(SquirrelVM::_VM,-1); - sq_pop(SquirrelVM::_VM,1); - } - return ret; -} - -#define _SETVALUE_INT_BEGIN \ - BOOL ret = FALSE; \ - int top = sq_gettop(SquirrelVM::_VM); \ - sq_pushobject(SquirrelVM::_VM,_o); \ - sq_pushinteger(SquirrelVM::_VM,key); - -#define _SETVALUE_INT_END \ - if(SQ_SUCCEEDED(sq_rawset(SquirrelVM::_VM,-3))) { \ - ret = TRUE; \ - } \ - sq_settop(SquirrelVM::_VM,top); \ - return ret; - -BOOL SquirrelObject::SetValue(INT key,const SquirrelObject &val) -{ - _SETVALUE_INT_BEGIN - sq_pushobject(SquirrelVM::_VM,val._o); - _SETVALUE_INT_END -} - -BOOL SquirrelObject::SetValue(INT key,INT n) -{ - _SETVALUE_INT_BEGIN - sq_pushinteger(SquirrelVM::_VM,n); - _SETVALUE_INT_END -} - -BOOL SquirrelObject::SetValue(INT key,FLOAT f) -{ - _SETVALUE_INT_BEGIN - sq_pushfloat(SquirrelVM::_VM,f); - _SETVALUE_INT_END -} - -BOOL SquirrelObject::SetValue(INT key,const SQChar *s) -{ - _SETVALUE_INT_BEGIN - sq_pushstring(SquirrelVM::_VM,s,-1); - _SETVALUE_INT_END -} - -BOOL SquirrelObject::SetValue(INT key,bool b) -{ - _SETVALUE_INT_BEGIN - sq_pushbool(SquirrelVM::_VM,b); - _SETVALUE_INT_END -} - -BOOL SquirrelObject::SetValue(const SquirrelObject &key,const SquirrelObject &val) -{ - BOOL ret = FALSE; - int top = sq_gettop(SquirrelVM::_VM); - sq_pushobject(SquirrelVM::_VM,_o); - sq_pushobject(SquirrelVM::_VM,key._o); - sq_pushobject(SquirrelVM::_VM,val._o); - if(SQ_SUCCEEDED(sq_rawset(SquirrelVM::_VM,-3))) { - ret = TRUE; - } - sq_settop(SquirrelVM::_VM,top); - return ret; -} - -#define _SETVALUE_STR_BEGIN \ - BOOL ret = FALSE; \ - int top = sq_gettop(SquirrelVM::_VM); \ - sq_pushobject(SquirrelVM::_VM,_o); \ - sq_pushstring(SquirrelVM::_VM,key,-1); - -#define _SETVALUE_STR_END \ - if(SQ_SUCCEEDED(sq_rawset(SquirrelVM::_VM,-3))) { \ - ret = TRUE; \ - } \ - sq_settop(SquirrelVM::_VM,top); \ - return ret; - -BOOL SquirrelObject::SetValue(const SQChar *key,const SquirrelObject &val) -{ - _SETVALUE_STR_BEGIN - sq_pushobject(SquirrelVM::_VM,val._o); - _SETVALUE_STR_END -} - -BOOL SquirrelObject::SetValue(const SQChar *key,INT n) -{ - _SETVALUE_STR_BEGIN - sq_pushinteger(SquirrelVM::_VM,n); - _SETVALUE_STR_END -} - -BOOL SquirrelObject::SetValue(const SQChar *key,FLOAT f) -{ - _SETVALUE_STR_BEGIN - sq_pushfloat(SquirrelVM::_VM,f); - _SETVALUE_STR_END -} - -BOOL SquirrelObject::SetValue(const SQChar *key,const SQChar *s) -{ - _SETVALUE_STR_BEGIN - sq_pushstring(SquirrelVM::_VM,s,-1); - _SETVALUE_STR_END -} - -BOOL SquirrelObject::SetValue(const SQChar *key,bool b) -{ - _SETVALUE_STR_BEGIN - sq_pushbool(SquirrelVM::_VM,b); - _SETVALUE_STR_END -} - -// === BEGIN User Pointer, User Data === - -BOOL SquirrelObject::SetUserPointer(const SQChar * key,SQUserPointer up) { - _SETVALUE_STR_BEGIN - sq_pushuserpointer(SquirrelVM::_VM,up); - _SETVALUE_STR_END -} // SquirrelObject::SetUserPointer - -SQUserPointer SquirrelObject::GetUserPointer(const SQChar * key) { - SQUserPointer ret = NULL; - if (GetSlot(key)) { - sq_getuserpointer(SquirrelVM::_VM,-1,&ret); - sq_pop(SquirrelVM::_VM,1); - } // if - sq_pop(SquirrelVM::_VM,1); - return ret; -} // SquirrelObject::GetUserPointer - -BOOL SquirrelObject::SetUserPointer(INT key,SQUserPointer up) { - _SETVALUE_INT_BEGIN - sq_pushuserpointer(SquirrelVM::_VM,up); - _SETVALUE_INT_END -} // SquirrelObject::SetUserPointer - -SQUserPointer SquirrelObject::GetUserPointer(INT key) { - SQUserPointer ret = NULL; - if (GetSlot(key)) { - sq_getuserpointer(SquirrelVM::_VM,-1,&ret); - sq_pop(SquirrelVM::_VM,1); - } // if - sq_pop(SquirrelVM::_VM,1); - return ret; -} // SquirrelObject::GetUserPointer - -// === User Data === - -BOOL SquirrelObject::NewUserData(const SQChar * key,INT size,SQUserPointer * typetag) { - _SETVALUE_STR_BEGIN - sq_newuserdata(SquirrelVM::_VM,size); - if (typetag) { - sq_settypetag(SquirrelVM::_VM,-1,typetag); - } // if - _SETVALUE_STR_END -} // SquirrelObject::NewUserData - -BOOL SquirrelObject::GetUserData(const SQChar * key,SQUserPointer * data,SQUserPointer * typetag) { - BOOL ret = false; - if (GetSlot(key)) { - sq_getuserdata(SquirrelVM::_VM,-1,data,typetag); - sq_pop(SquirrelVM::_VM,1); - ret = true; - } // if - sq_pop(SquirrelVM::_VM,1); - return ret; -} // SquirrelObject::GetUserData - -BOOL SquirrelObject::RawGetUserData(const SQChar * key,SQUserPointer * data,SQUserPointer * typetag) { - BOOL ret = false; - if (RawGetSlot(key)) { - sq_getuserdata(SquirrelVM::_VM,-1,data,typetag); - sq_pop(SquirrelVM::_VM,1); - ret = true; - } // if - sq_pop(SquirrelVM::_VM,1); - return ret; -} // SquirrelObject::RawGetUserData - -// === END User Pointer === - -// === BEGIN Arrays === - -BOOL SquirrelObject::ArrayResize(INT newSize) { -// int top = sq_gettop(SquirrelVM::_VM); - sq_pushobject(SquirrelVM::_VM,GetObjectHandle()); - BOOL res = sq_arrayresize(SquirrelVM::_VM,-1,newSize) == SQ_OK; - sq_pop(SquirrelVM::_VM,1); -// sq_settop(SquirrelVM::_VM,top); - return res; -} // SquirrelObject::ArrayResize - -BOOL SquirrelObject::ArrayExtend(INT amount) { - int newLen = Len()+amount; - return ArrayResize(newLen); -} // SquirrelObject::ArrayExtend - -BOOL SquirrelObject::ArrayReverse(void) { - sq_pushobject(SquirrelVM::_VM,GetObjectHandle()); - BOOL res = sq_arrayreverse(SquirrelVM::_VM,-1) == SQ_OK; - sq_pop(SquirrelVM::_VM,1); - return res; -} // SquirrelObject::ArrayReverse - -SquirrelObject SquirrelObject::ArrayPop(SQBool returnPoppedVal) { - SquirrelObject ret; - int top = sq_gettop(SquirrelVM::_VM); - sq_pushobject(SquirrelVM::_VM,GetObjectHandle()); - if (sq_arraypop(SquirrelVM::_VM,-1,returnPoppedVal) == SQ_OK) { - if (returnPoppedVal) { - ret.AttachToStackObject(-1); - } // if - } // if - sq_settop(SquirrelVM::_VM,top); - return ret; -} // SquirrelObject::ArrayPop - -// === END Arrays === - -SQObjectType SquirrelObject::GetType() -{ - return _o._type; -} - -BOOL SquirrelObject::GetSlot(INT key) const -{ - sq_pushobject(SquirrelVM::_VM,_o); - sq_pushinteger(SquirrelVM::_VM,key); - if(SQ_SUCCEEDED(sq_get(SquirrelVM::_VM,-2))) { - return TRUE; - } - - return FALSE; -} - - -SquirrelObject SquirrelObject::GetValue(INT key)const -{ - SquirrelObject ret; - if(GetSlot(key)) { - ret.AttachToStackObject(-1); - sq_pop(SquirrelVM::_VM,1); - } - sq_pop(SquirrelVM::_VM,1); - return ret; -} - -FLOAT SquirrelObject::GetFloat(INT key) const -{ - FLOAT ret = 0.0f; - if(GetSlot(key)) { - sq_getfloat(SquirrelVM::_VM,-1,&ret); - sq_pop(SquirrelVM::_VM,1); - } - sq_pop(SquirrelVM::_VM,1); - return ret; -} - -INT SquirrelObject::GetInt(INT key) const -{ - INT ret = 0; - if(GetSlot(key)) { - sq_getinteger(SquirrelVM::_VM,-1,&ret); - sq_pop(SquirrelVM::_VM,1); - } - sq_pop(SquirrelVM::_VM,1); - return ret; -} - -const SQChar *SquirrelObject::GetString(INT key) const -{ - const SQChar *ret = NULL; - if(GetSlot(key)) { - sq_getstring(SquirrelVM::_VM,-1,&ret); - sq_pop(SquirrelVM::_VM,1); - } - sq_pop(SquirrelVM::_VM,1); - return ret; -} - -bool SquirrelObject::GetBool(INT key) const -{ - SQBool ret = FALSE; - if(GetSlot(key)) { - sq_getbool(SquirrelVM::_VM,-1,&ret); - sq_pop(SquirrelVM::_VM,1); - } - sq_pop(SquirrelVM::_VM,1); - return ret?true:false; -} - -BOOL SquirrelObject::Exists(const SQChar *key) const -{ - if(GetSlot(key)) { - sq_pop(SquirrelVM::_VM,2); - return TRUE; - } else { - sq_pop(SquirrelVM::_VM,1); - return FALSE; - } -} -//////////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////// - -BOOL SquirrelObject::GetSlot(const SQChar *name) const -{ - sq_pushobject(SquirrelVM::_VM,_o); - sq_pushstring(SquirrelVM::_VM,name,-1); - if(SQ_SUCCEEDED(sq_get(SquirrelVM::_VM,-2))) { - return TRUE; - } - - return FALSE; -} - -BOOL SquirrelObject::RawGetSlot(const SQChar *name) const { - sq_pushobject(SquirrelVM::_VM,_o); - sq_pushstring(SquirrelVM::_VM,name,-1); - if(SQ_SUCCEEDED(sq_rawget(SquirrelVM::_VM,-2))) { - return TRUE; - } - return FALSE; -} // SquirrelObject::RawGetSlot - -SquirrelObject SquirrelObject::GetValue(const SQChar *key)const -{ - SquirrelObject ret; - if(GetSlot(key)) { - ret.AttachToStackObject(-1); - sq_pop(SquirrelVM::_VM,1); - } - sq_pop(SquirrelVM::_VM,1); - return ret; -} - -FLOAT SquirrelObject::GetFloat(const SQChar *key) const -{ - FLOAT ret = 0.0f; - if(GetSlot(key)) { - sq_getfloat(SquirrelVM::_VM,-1,&ret); - sq_pop(SquirrelVM::_VM,1); - } - sq_pop(SquirrelVM::_VM,1); - return ret; -} - -INT SquirrelObject::GetInt(const SQChar *key) const -{ - INT ret = 0; - if(GetSlot(key)) { - sq_getinteger(SquirrelVM::_VM,-1,&ret); - sq_pop(SquirrelVM::_VM,1); - } - sq_pop(SquirrelVM::_VM,1); - return ret; -} - -const SQChar *SquirrelObject::GetString(const SQChar *key) const -{ - const SQChar *ret = NULL; - if(GetSlot(key)) { - sq_getstring(SquirrelVM::_VM,-1,&ret); - sq_pop(SquirrelVM::_VM,1); - } - sq_pop(SquirrelVM::_VM,1); - return ret; -} - -bool SquirrelObject::GetBool(const SQChar *key) const -{ - SQBool ret = FALSE; - if(GetSlot(key)) { - sq_getbool(SquirrelVM::_VM,-1,&ret); - sq_pop(SquirrelVM::_VM,1); - } - sq_pop(SquirrelVM::_VM,1); - return ret?true:false; -} - -SQUserPointer SquirrelObject::GetInstanceUP(SQUserPointer tag) const -{ - SQUserPointer up; - sq_pushobject(SquirrelVM::_VM,_o); - if (SQ_FAILED(sq_getinstanceup(SquirrelVM::_VM,-1,(SQUserPointer*)&up,tag))) { - sq_reseterror(SquirrelVM::_VM); - up = NULL; - } // if - sq_pop(SquirrelVM::_VM,1); - return up; -} - -BOOL SquirrelObject::SetInstanceUP(SQUserPointer up) -{ - if(!sq_isinstance(_o)) return FALSE; - sq_pushobject(SquirrelVM::_VM,_o); - sq_setinstanceup(SquirrelVM::_VM,-1,up); - sq_pop(SquirrelVM::_VM,1); - return TRUE; -} - -SquirrelObject SquirrelObject::GetAttributes(const SQChar *key) -{ - SquirrelObject ret; - int top = sq_gettop(SquirrelVM::_VM); - sq_pushobject(SquirrelVM::_VM,_o); - if(key) - sq_pushstring(SquirrelVM::_VM,key,-1); - else - sq_pushnull(SquirrelVM::_VM); - if(SQ_SUCCEEDED(sq_getattributes(SquirrelVM::_VM,-2))) { - ret.AttachToStackObject(-1); - } - sq_settop(SquirrelVM::_VM,top); - return ret; -} - -BOOL SquirrelObject::BeginIteration() -{ - if(!sq_istable(_o) && !sq_isarray(_o) && !sq_isclass(_o)) - return FALSE; - sq_pushobject(SquirrelVM::_VM,_o); - sq_pushnull(SquirrelVM::_VM); - return TRUE; -} - -BOOL SquirrelObject::Next(SquirrelObject &key,SquirrelObject &val) -{ - if(SQ_SUCCEEDED(sq_next(SquirrelVM::_VM,-2))) { - key.AttachToStackObject(-2); - val.AttachToStackObject(-1); - sq_pop(SquirrelVM::_VM,2); - return TRUE; - } - return FALSE; -} - -BOOL SquirrelObject::GetTypeTag(SQUserPointer * typeTag) { - if (SQ_SUCCEEDED(sq_getobjtypetag(&_o,typeTag))) { - return TRUE; - } // if - return FALSE; -} // SquirrelObject::GetTypeTag - -const SQChar * SquirrelObject::GetTypeName(const SQChar * key) { -#if 1 - // This version will work even if SQ_SUPPORT_INSTANCE_TYPE_INFO is not enabled. - SqPlus::ScriptStringVar256 varNameTag; - SqPlus::getVarNameTag(varNameTag,sizeof(varNameTag),key); - SQUserPointer data=0; - if (!RawGetUserData(varNameTag,&data)) { - return NULL; - } // if - SqPlus::VarRefPtr vr = (SqPlus::VarRefPtr)data; - return vr->varType->GetTypeName(); -#else // This version will only work if SQ_SUPPORT_INSTANCE_TYPE_INFO is enabled. - SquirrelObject so = GetValue(key); - if (so.IsNull()) return NULL; - return so.GetTypeName(); -#endif -} // SquirrelObject::GetTypeName - -const SQChar * SquirrelObject::GetTypeName(INT key) { - SquirrelObject so = GetValue(key); - if (so.IsNull()) return NULL; - return so.GetTypeName(); -} // SquirrelObject::GetTypeName - -const SQChar * SquirrelObject::GetTypeName(void) { - SQUserPointer typeTag=NULL; - if (SQ_SUCCEEDED(sq_getobjtypetag(&_o,&typeTag))) { - SquirrelObject typeTable = SquirrelVM::GetRootTable().GetValue(SQ_PLUS_TYPE_TABLE); - if (typeTable.IsNull()) { - return NULL; // Not compiled with SQ_SUPPORT_INSTANCE_TYPE_INFO enabled. - } // if - return typeTable.GetString(INT((size_t)typeTag)); - } // if - return NULL; -} // SquirrelObject::GetTypeName - -SquirrelObject SquirrelObject::GetBase(void) -{ - SquirrelObject ret; - sq_pushobject(SquirrelVM::_VM,_o); - sq_getbase(SquirrelVM::_VM,-1); - ret.AttachToStackObject(-1); - sq_pop(SquirrelVM::_VM,2); - - return ret; -} - -const SQChar* SquirrelObject::ToString() -{ - return sq_objtostring(&_o); -} - -SQInteger SquirrelObject::ToInteger() -{ - return sq_objtointeger(&_o); -} - -SQFloat SquirrelObject::ToFloat() -{ - return sq_objtofloat(&_o); -} - -bool SquirrelObject::ToBool() -{ - //<> - return _o._unVal.nInteger?true:false; -} - -void SquirrelObject::EndIteration() -{ - sq_pop(SquirrelVM::_VM,2); -} - +#include "sqplus.h" + +SquirrelObject::SquirrelObject(void) +{ + sq_resetobject(&_o); +} + +SquirrelObject::~SquirrelObject() +{ + Reset(); +} + +SquirrelObject::SquirrelObject(const SquirrelObject &o) +{ + _o = o._o; + sq_addref(SquirrelVM::_VM,&_o); +} + +SquirrelObject::SquirrelObject(HSQOBJECT o) +{ + _o = o; + sq_addref(SquirrelVM::_VM,&_o); +} + +void SquirrelObject::Reset(void) { + if(SquirrelVM::_VM) + sq_release(SquirrelVM::_VM,&_o); + else if( _o._type!=OT_NULL && _o._unVal.pRefCounted ) + printf( "SquirrelObject::~SquirrelObject - Cannot release\n" ); + sq_resetobject(&_o); +} // SquirrelObject::Reset + +SquirrelObject SquirrelObject::Clone() +{ + SquirrelObject ret; + if(GetType() == OT_TABLE || GetType() == OT_ARRAY) + { + sq_pushobject(SquirrelVM::_VM,_o); + sq_clone(SquirrelVM::_VM,-1); + ret.AttachToStackObject(-1); + sq_pop(SquirrelVM::_VM,2); + } + return ret; + +} + +SquirrelObject & SquirrelObject::operator =(const SquirrelObject &o) +{ + //HSQOBJECT t; + //t = o._o; + //sq_addref(SquirrelVM::_VM,&t); + sq_addref(SquirrelVM::_VM, (HSQOBJECT*)&o._o); + sq_release(SquirrelVM::_VM,&_o); + //_o = t; + _o = o._o; + return *this; +} + +SquirrelObject & SquirrelObject::operator =(HSQOBJECT ho) +{ + sq_addref(SquirrelVM::_VM,&ho); + sq_release(SquirrelVM::_VM,&_o); + _o = ho; + return *this; +} + +SquirrelObject & SquirrelObject::operator =(int n) +{ + sq_pushinteger(SquirrelVM::_VM,n); + AttachToStackObject(-1); + sq_pop(SquirrelVM::_VM,1); + return *this; +} + +#include +#include "../squirrel/sqstate.h" +#include "../squirrel/sqvm.h" + +SquirrelObject & SquirrelObject::operator =(HSQUIRRELVM v) +{ + if( v && SquirrelVM::_VM ){ + SquirrelVM::_VM->Push(v); + AttachToStackObject(-1); + sq_poptop(SquirrelVM::_VM); + } + else Reset(); + return *this; +} + +bool SquirrelObject::operator == (const SquirrelObject &o) +{ + bool cmp = false; + HSQUIRRELVM v = SquirrelVM::GetVMPtr(); + int oldtop = sq_gettop(v); + + sq_pushobject(v, GetObjectHandle()); + sq_pushobject(v, o.GetObjectHandle()); + if(sq_cmp(v) == 0) + cmp = true; + + sq_settop(v, oldtop); + return cmp; +} + +bool SquirrelObject::CompareUserPointer( const SquirrelObject &o ) +{ + if( _o._type == o.GetObjectHandle()._type ) + if( _o._unVal.pUserPointer == o.GetObjectHandle()._unVal.pUserPointer ) + return true; + + return false; +} + +void SquirrelObject::ArrayAppend(const SquirrelObject &o) +{ + if(sq_isarray(_o)) { + sq_pushobject(SquirrelVM::_VM,_o); + sq_pushobject(SquirrelVM::_VM,o._o); + sq_arrayappend(SquirrelVM::_VM,-2); + sq_pop(SquirrelVM::_VM,1); + } +} + +void SquirrelObject::AttachToStackObject(int idx) +{ + HSQOBJECT t; + sq_getstackobj(SquirrelVM::_VM,idx,&t); + sq_addref(SquirrelVM::_VM,&t); + sq_release(SquirrelVM::_VM,&_o); + _o = t; +} + +BOOL SquirrelObject::SetDelegate(SquirrelObject &obj) +{ + if(obj.GetType() == OT_TABLE || + obj.GetType() == OT_NULL) { + switch(_o._type) { + case OT_USERDATA: + case OT_TABLE: + sq_pushobject(SquirrelVM::_VM,_o); + sq_pushobject(SquirrelVM::_VM,obj._o); + if(SQ_SUCCEEDED(sq_setdelegate(SquirrelVM::_VM,-2))) { + sq_pop(SquirrelVM::_VM,1); + return TRUE; + } + sq_pop(SquirrelVM::_VM,1); + break; + } + } + return FALSE; +} + +SquirrelObject SquirrelObject::GetDelegate() +{ + SquirrelObject ret; + if(_o._type == OT_TABLE || _o._type == OT_USERDATA) + { + int top = sq_gettop(SquirrelVM::_VM); + sq_pushobject(SquirrelVM::_VM,_o); + sq_getdelegate(SquirrelVM::_VM,-1); + ret.AttachToStackObject(-1); + sq_settop(SquirrelVM::_VM,top); +// sq_pop(SquirrelVM::_VM,2); + } + return ret; +} + +BOOL SquirrelObject::IsNull() const +{ + return sq_isnull(_o); +} + +BOOL SquirrelObject::IsNumeric() const +{ + return sq_isnumeric(_o); +} + +int SquirrelObject::Len() const +{ + int ret = 0; + if(sq_isarray(_o) || sq_istable(_o) || sq_isstring(_o)) { + sq_pushobject(SquirrelVM::_VM,_o); + ret = sq_getsize(SquirrelVM::_VM,-1); + sq_pop(SquirrelVM::_VM,1); + } + return ret; +} + +#define _SETVALUE_INT_BEGIN \ + BOOL ret = FALSE; \ + int top = sq_gettop(SquirrelVM::_VM); \ + sq_pushobject(SquirrelVM::_VM,_o); \ + sq_pushinteger(SquirrelVM::_VM,key); + +#define _SETVALUE_INT_END \ + if(SQ_SUCCEEDED(sq_rawset(SquirrelVM::_VM,-3))) { \ + ret = TRUE; \ + } \ + sq_settop(SquirrelVM::_VM,top); \ + return ret; + +BOOL SquirrelObject::SetValue(INT key,const SquirrelObject &val) +{ + _SETVALUE_INT_BEGIN + sq_pushobject(SquirrelVM::_VM,val._o); + _SETVALUE_INT_END +} + +BOOL SquirrelObject::SetValue(INT key,INT n) +{ + _SETVALUE_INT_BEGIN + sq_pushinteger(SquirrelVM::_VM,n); + _SETVALUE_INT_END +} + +BOOL SquirrelObject::SetValue(INT key,FLOAT f) +{ + _SETVALUE_INT_BEGIN + sq_pushfloat(SquirrelVM::_VM,f); + _SETVALUE_INT_END +} + +BOOL SquirrelObject::SetValue(INT key,const SQChar *s) +{ + _SETVALUE_INT_BEGIN + sq_pushstring(SquirrelVM::_VM,s,-1); + _SETVALUE_INT_END +} + +BOOL SquirrelObject::SetValue(INT key,bool b) +{ + _SETVALUE_INT_BEGIN + sq_pushbool(SquirrelVM::_VM,b); + _SETVALUE_INT_END +} + +BOOL SquirrelObject::SetValue(const SquirrelObject &key,const SquirrelObject &val) +{ + BOOL ret = FALSE; + int top = sq_gettop(SquirrelVM::_VM); + sq_pushobject(SquirrelVM::_VM,_o); + sq_pushobject(SquirrelVM::_VM,key._o); + sq_pushobject(SquirrelVM::_VM,val._o); + if(SQ_SUCCEEDED(sq_rawset(SquirrelVM::_VM,-3))) { + ret = TRUE; + } + sq_settop(SquirrelVM::_VM,top); + return ret; +} + +#define _SETVALUE_STR_BEGIN \ + BOOL ret = FALSE; \ + int top = sq_gettop(SquirrelVM::_VM); \ + sq_pushobject(SquirrelVM::_VM,_o); \ + sq_pushstring(SquirrelVM::_VM,key,-1); + +#define _SETVALUE_STR_END \ + if(SQ_SUCCEEDED(sq_rawset(SquirrelVM::_VM,-3))) { \ + ret = TRUE; \ + } \ + sq_settop(SquirrelVM::_VM,top); \ + return ret; + +BOOL SquirrelObject::SetValue(const SQChar *key,const SquirrelObject &val) +{ + _SETVALUE_STR_BEGIN + sq_pushobject(SquirrelVM::_VM,val._o); + _SETVALUE_STR_END +} + +BOOL SquirrelObject::SetValue(const SQChar *key,INT n) +{ + _SETVALUE_STR_BEGIN + sq_pushinteger(SquirrelVM::_VM,n); + _SETVALUE_STR_END +} + +BOOL SquirrelObject::SetValue(const SQChar *key,FLOAT f) +{ + _SETVALUE_STR_BEGIN + sq_pushfloat(SquirrelVM::_VM,f); + _SETVALUE_STR_END +} + +BOOL SquirrelObject::SetValue(const SQChar *key,const SQChar *s) +{ + _SETVALUE_STR_BEGIN + sq_pushstring(SquirrelVM::_VM,s,-1); + _SETVALUE_STR_END +} + +BOOL SquirrelObject::SetValue(const SQChar *key,bool b) +{ + _SETVALUE_STR_BEGIN + sq_pushbool(SquirrelVM::_VM,b); + _SETVALUE_STR_END +} + +// === BEGIN User Pointer, User Data === + +BOOL SquirrelObject::SetUserPointer(const SQChar * key,SQUserPointer up) { + _SETVALUE_STR_BEGIN + sq_pushuserpointer(SquirrelVM::_VM,up); + _SETVALUE_STR_END +} // SquirrelObject::SetUserPointer + +SQUserPointer SquirrelObject::GetUserPointer(const SQChar * key) { + SQUserPointer ret = NULL; + if (GetSlot(key)) { + sq_getuserpointer(SquirrelVM::_VM,-1,&ret); + sq_pop(SquirrelVM::_VM,1); + } // if + sq_pop(SquirrelVM::_VM,1); + return ret; +} // SquirrelObject::GetUserPointer + +BOOL SquirrelObject::SetUserPointer(INT key,SQUserPointer up) { + _SETVALUE_INT_BEGIN + sq_pushuserpointer(SquirrelVM::_VM,up); + _SETVALUE_INT_END +} // SquirrelObject::SetUserPointer + +SQUserPointer SquirrelObject::GetUserPointer(INT key) { + SQUserPointer ret = NULL; + if (GetSlot(key)) { + sq_getuserpointer(SquirrelVM::_VM,-1,&ret); + sq_pop(SquirrelVM::_VM,1); + } // if + sq_pop(SquirrelVM::_VM,1); + return ret; +} // SquirrelObject::GetUserPointer + +// === User Data === + +BOOL SquirrelObject::NewUserData(const SQChar * key,INT size,SQUserPointer * typetag) { + _SETVALUE_STR_BEGIN + sq_newuserdata(SquirrelVM::_VM,size); + if (typetag) { + sq_settypetag(SquirrelVM::_VM,-1,typetag); + } // if + _SETVALUE_STR_END +} // SquirrelObject::NewUserData + +BOOL SquirrelObject::GetUserData(const SQChar * key,SQUserPointer * data,SQUserPointer * typetag) { + BOOL ret = false; + if (GetSlot(key)) { + sq_getuserdata(SquirrelVM::_VM,-1,data,typetag); + sq_pop(SquirrelVM::_VM,1); + ret = true; + } // if + sq_pop(SquirrelVM::_VM,1); + return ret; +} // SquirrelObject::GetUserData + +BOOL SquirrelObject::RawGetUserData(const SQChar * key,SQUserPointer * data,SQUserPointer * typetag) { + BOOL ret = false; + if (RawGetSlot(key)) { + sq_getuserdata(SquirrelVM::_VM,-1,data,typetag); + sq_pop(SquirrelVM::_VM,1); + ret = true; + } // if + sq_pop(SquirrelVM::_VM,1); + return ret; +} // SquirrelObject::RawGetUserData + +// === END User Pointer === + +// === BEGIN Arrays === + +BOOL SquirrelObject::ArrayResize(INT newSize) { +// int top = sq_gettop(SquirrelVM::_VM); + sq_pushobject(SquirrelVM::_VM,GetObjectHandle()); + BOOL res = sq_arrayresize(SquirrelVM::_VM,-1,newSize) == SQ_OK; + sq_pop(SquirrelVM::_VM,1); +// sq_settop(SquirrelVM::_VM,top); + return res; +} // SquirrelObject::ArrayResize + +BOOL SquirrelObject::ArrayExtend(INT amount) { + int newLen = Len()+amount; + return ArrayResize(newLen); +} // SquirrelObject::ArrayExtend + +BOOL SquirrelObject::ArrayReverse(void) { + sq_pushobject(SquirrelVM::_VM,GetObjectHandle()); + BOOL res = sq_arrayreverse(SquirrelVM::_VM,-1) == SQ_OK; + sq_pop(SquirrelVM::_VM,1); + return res; +} // SquirrelObject::ArrayReverse + +SquirrelObject SquirrelObject::ArrayPop(SQBool returnPoppedVal) { + SquirrelObject ret; + int top = sq_gettop(SquirrelVM::_VM); + sq_pushobject(SquirrelVM::_VM,GetObjectHandle()); + if (sq_arraypop(SquirrelVM::_VM,-1,returnPoppedVal) == SQ_OK) { + if (returnPoppedVal) { + ret.AttachToStackObject(-1); + } // if + } // if + sq_settop(SquirrelVM::_VM,top); + return ret; +} // SquirrelObject::ArrayPop + +// === END Arrays === + +SQObjectType SquirrelObject::GetType() +{ + return _o._type; +} + +BOOL SquirrelObject::GetSlot(INT key) const +{ + sq_pushobject(SquirrelVM::_VM,_o); + sq_pushinteger(SquirrelVM::_VM,key); + if(SQ_SUCCEEDED(sq_get(SquirrelVM::_VM,-2))) { + return TRUE; + } + + return FALSE; +} + + +SquirrelObject SquirrelObject::GetValue(INT key)const +{ + SquirrelObject ret; + if(GetSlot(key)) { + ret.AttachToStackObject(-1); + sq_pop(SquirrelVM::_VM,1); + } + sq_pop(SquirrelVM::_VM,1); + return ret; +} + +FLOAT SquirrelObject::GetFloat(INT key) const +{ + FLOAT ret = 0.0f; + if(GetSlot(key)) { + sq_getfloat(SquirrelVM::_VM,-1,&ret); + sq_pop(SquirrelVM::_VM,1); + } + sq_pop(SquirrelVM::_VM,1); + return ret; +} + +INT SquirrelObject::GetInt(INT key) const +{ + INT ret = 0; + if(GetSlot(key)) { + sq_getinteger(SquirrelVM::_VM,-1,&ret); + sq_pop(SquirrelVM::_VM,1); + } + sq_pop(SquirrelVM::_VM,1); + return ret; +} + +const SQChar *SquirrelObject::GetString(INT key) const +{ + const SQChar *ret = NULL; + if(GetSlot(key)) { + sq_getstring(SquirrelVM::_VM,-1,&ret); + sq_pop(SquirrelVM::_VM,1); + } + sq_pop(SquirrelVM::_VM,1); + return ret; +} + +bool SquirrelObject::GetBool(INT key) const +{ + SQBool ret = FALSE; + if(GetSlot(key)) { + sq_getbool(SquirrelVM::_VM,-1,&ret); + sq_pop(SquirrelVM::_VM,1); + } + sq_pop(SquirrelVM::_VM,1); + return ret?true:false; +} + +BOOL SquirrelObject::Exists(const SQChar *key) const +{ + if(GetSlot(key)) { + sq_pop(SquirrelVM::_VM,2); + return TRUE; + } else { + sq_pop(SquirrelVM::_VM,1); + return FALSE; + } +} +//////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// + +BOOL SquirrelObject::GetSlot(const SQChar *name) const +{ + sq_pushobject(SquirrelVM::_VM,_o); + sq_pushstring(SquirrelVM::_VM,name,-1); + if(SQ_SUCCEEDED(sq_get(SquirrelVM::_VM,-2))) { + return TRUE; + } + + return FALSE; +} + +BOOL SquirrelObject::RawGetSlot(const SQChar *name) const { + sq_pushobject(SquirrelVM::_VM,_o); + sq_pushstring(SquirrelVM::_VM,name,-1); + if(SQ_SUCCEEDED(sq_rawget(SquirrelVM::_VM,-2))) { + return TRUE; + } + return FALSE; +} // SquirrelObject::RawGetSlot + +SquirrelObject SquirrelObject::GetValue(const SQChar *key)const +{ + SquirrelObject ret; + if(GetSlot(key)) { + ret.AttachToStackObject(-1); + sq_pop(SquirrelVM::_VM,1); + } + sq_pop(SquirrelVM::_VM,1); + return ret; +} + +FLOAT SquirrelObject::GetFloat(const SQChar *key) const +{ + FLOAT ret = 0.0f; + if(GetSlot(key)) { + sq_getfloat(SquirrelVM::_VM,-1,&ret); + sq_pop(SquirrelVM::_VM,1); + } + sq_pop(SquirrelVM::_VM,1); + return ret; +} + +INT SquirrelObject::GetInt(const SQChar *key) const +{ + INT ret = 0; + if(GetSlot(key)) { + sq_getinteger(SquirrelVM::_VM,-1,&ret); + sq_pop(SquirrelVM::_VM,1); + } + sq_pop(SquirrelVM::_VM,1); + return ret; +} + +const SQChar *SquirrelObject::GetString(const SQChar *key) const +{ + const SQChar *ret = NULL; + if(GetSlot(key)) { + sq_getstring(SquirrelVM::_VM,-1,&ret); + sq_pop(SquirrelVM::_VM,1); + } + sq_pop(SquirrelVM::_VM,1); + return ret; +} + +bool SquirrelObject::GetBool(const SQChar *key) const +{ + SQBool ret = FALSE; + if(GetSlot(key)) { + sq_getbool(SquirrelVM::_VM,-1,&ret); + sq_pop(SquirrelVM::_VM,1); + } + sq_pop(SquirrelVM::_VM,1); + return ret?true:false; +} + +SQUserPointer SquirrelObject::GetInstanceUP(SQUserPointer tag) const +{ + SQUserPointer up; + sq_pushobject(SquirrelVM::_VM,_o); + if (SQ_FAILED(sq_getinstanceup(SquirrelVM::_VM,-1,(SQUserPointer*)&up,tag))) { + sq_reseterror(SquirrelVM::_VM); + up = NULL; + } // if + sq_pop(SquirrelVM::_VM,1); + return up; +} + +BOOL SquirrelObject::SetInstanceUP(SQUserPointer up) +{ + if(!sq_isinstance(_o)) return FALSE; + sq_pushobject(SquirrelVM::_VM,_o); + sq_setinstanceup(SquirrelVM::_VM,-1,up); + sq_pop(SquirrelVM::_VM,1); + return TRUE; +} + +SquirrelObject SquirrelObject::GetAttributes(const SQChar *key) +{ + SquirrelObject ret; + int top = sq_gettop(SquirrelVM::_VM); + sq_pushobject(SquirrelVM::_VM,_o); + if(key) + sq_pushstring(SquirrelVM::_VM,key,-1); + else + sq_pushnull(SquirrelVM::_VM); + if(SQ_SUCCEEDED(sq_getattributes(SquirrelVM::_VM,-2))) { + ret.AttachToStackObject(-1); + } + sq_settop(SquirrelVM::_VM,top); + return ret; +} + +BOOL SquirrelObject::BeginIteration() +{ + if(!sq_istable(_o) && !sq_isarray(_o) && !sq_isclass(_o)) + return FALSE; + sq_pushobject(SquirrelVM::_VM,_o); + sq_pushnull(SquirrelVM::_VM); + return TRUE; +} + +BOOL SquirrelObject::Next(SquirrelObject &key,SquirrelObject &val) +{ + if(SQ_SUCCEEDED(sq_next(SquirrelVM::_VM,-2))) { + key.AttachToStackObject(-2); + val.AttachToStackObject(-1); + sq_pop(SquirrelVM::_VM,2); + return TRUE; + } + return FALSE; +} + +BOOL SquirrelObject::GetTypeTag(SQUserPointer * typeTag) { + if (SQ_SUCCEEDED(sq_getobjtypetag(&_o,typeTag))) { + return TRUE; + } // if + return FALSE; +} // SquirrelObject::GetTypeTag + +const SQChar * SquirrelObject::GetTypeName(const SQChar * key) { +#if 1 + // This version will work even if SQ_SUPPORT_INSTANCE_TYPE_INFO is not enabled. + SqPlus::ScriptStringVar256 varNameTag; + SqPlus::getVarNameTag(varNameTag,sizeof(varNameTag),key); + SQUserPointer data=0; + if (!RawGetUserData(varNameTag,&data)) { + return NULL; + } // if + SqPlus::VarRefPtr vr = (SqPlus::VarRefPtr)data; + return vr->varType->GetTypeName(); +#else // This version will only work if SQ_SUPPORT_INSTANCE_TYPE_INFO is enabled. + SquirrelObject so = GetValue(key); + if (so.IsNull()) return NULL; + return so.GetTypeName(); +#endif +} // SquirrelObject::GetTypeName + +const SQChar * SquirrelObject::GetTypeName(INT key) { + SquirrelObject so = GetValue(key); + if (so.IsNull()) return NULL; + return so.GetTypeName(); +} // SquirrelObject::GetTypeName + +const SQChar * SquirrelObject::GetTypeName(void) { + SQUserPointer typeTag=NULL; + if (SQ_SUCCEEDED(sq_getobjtypetag(&_o,&typeTag))) { + SquirrelObject typeTable = SquirrelVM::GetRootTable().GetValue(SQ_PLUS_TYPE_TABLE); + if (typeTable.IsNull()) { + return NULL; // Not compiled with SQ_SUPPORT_INSTANCE_TYPE_INFO enabled. + } // if + return typeTable.GetString(INT((size_t)typeTag)); + } // if + return NULL; +} // SquirrelObject::GetTypeName + +SquirrelObject SquirrelObject::GetBase(void) +{ + SquirrelObject ret; + sq_pushobject(SquirrelVM::_VM,_o); + sq_getbase(SquirrelVM::_VM,-1); + ret.AttachToStackObject(-1); + sq_pop(SquirrelVM::_VM,2); + + return ret; +} + +const SQChar* SquirrelObject::ToString() +{ + return sq_objtostring(&_o); +} + +SQInteger SquirrelObject::ToInteger() +{ + return sq_objtointeger(&_o); +} + +SQFloat SquirrelObject::ToFloat() +{ + return sq_objtofloat(&_o); +} + +bool SquirrelObject::ToBool() +{ + //<> + return _o._unVal.nInteger?true:false; +} + +void SquirrelObject::EndIteration() +{ + sq_pop(SquirrelVM::_VM,2); +} + diff --git a/squirrel_3_0_1_stable/sqplus/SquirrelObject.h b/squirrel_3_0_1_stable/_OLD_sqplus/SquirrelObject.h similarity index 96% rename from squirrel_3_0_1_stable/sqplus/SquirrelObject.h rename to squirrel_3_0_1_stable/_OLD_sqplus/SquirrelObject.h index 647410a74..8824c3dea 100644 --- a/squirrel_3_0_1_stable/sqplus/SquirrelObject.h +++ b/squirrel_3_0_1_stable/_OLD_sqplus/SquirrelObject.h @@ -1,256 +1,256 @@ -#ifndef _SQUIRREL_OBJECT_H_ -#define _SQUIRREL_OBJECT_H_ - -class SquirrelObject -{ - friend class SquirrelVM; - -public: - SquirrelObject(); - virtual ~SquirrelObject(); - SquirrelObject(const SquirrelObject & o); - SquirrelObject(HSQOBJECT o); - -#if 1 - template - SquirrelObject(const _ty & val) { sq_resetobject(&_o); Set((_ty &)val); } // Cast away const to avoid compiler SqPlus::Push() match issue. - template - SquirrelObject(_ty & val) { sq_resetobject(&_o); Set(val); } - template - SquirrelObject(_ty * val) { sq_resetobject(&_o); SetByValue(val); } // Set() would also be OK here. SetByValue() to save potential compiler overhead. -#endif - - SquirrelObject & operator = (HSQOBJECT ho); - SquirrelObject & operator = (const SquirrelObject &o); - SquirrelObject & operator = (int n); - SquirrelObject & operator = (HSQUIRRELVM v); - - operator HSQOBJECT& (){ return _o; } - bool operator ==(const SquirrelObject& o); - bool CompareUserPointer(const SquirrelObject& o); - - void AttachToStackObject(int idx); - void Reset(void); // Release (any) reference and reset _o. - SquirrelObject Clone(); - BOOL SetValue(const SquirrelObject &key,const SquirrelObject &val); - - BOOL SetValue(SQInteger key,const SquirrelObject &val); - BOOL SetValue(INT key,bool b); // Compiler treats SQBool as INT. - BOOL SetValue(INT key,INT n); - BOOL SetValue(INT key,FLOAT f); - BOOL SetValue(INT key,const SQChar *s); - - BOOL SetValue(const SQChar *key,const SquirrelObject &val); - BOOL SetValue(const SQChar *key,bool b); - BOOL SetValue(const SQChar *key,INT n); - BOOL SetValue(const SQChar *key,FLOAT f); - BOOL SetValue(const SQChar *key,const SQChar *s); - - BOOL SetUserPointer(const SQChar * key,SQUserPointer up); - SQUserPointer GetUserPointer(const SQChar * key); - BOOL SetUserPointer(INT key,SQUserPointer up); - SQUserPointer GetUserPointer(INT key); - - BOOL NewUserData(const SQChar * key,INT size,SQUserPointer * typetag=0); - BOOL GetUserData(const SQChar * key,SQUserPointer * data,SQUserPointer * typetag=0); - BOOL RawGetUserData(const SQChar * key,SQUserPointer * data,SQUserPointer * typetag=0); - - // === BEGIN Arrays === - - BOOL ArrayResize(INT newSize); - BOOL ArrayExtend(INT amount); - BOOL ArrayReverse(void); - SquirrelObject ArrayPop(SQBool returnPoppedVal=SQTrue); - - void ArrayAppend(const SquirrelObject &o); - - template - BOOL ArrayAppend(T item); - - // === END Arrays === - - BOOL SetInstanceUP(SQUserPointer up); - BOOL IsNull() const; - int IsNumeric() const; - int Len() const; - BOOL SetDelegate(SquirrelObject &obj); - SquirrelObject GetDelegate(); - const SQChar* ToString(); - bool ToBool(); - SQInteger ToInteger(); - SQFloat ToFloat(); - SQUserPointer GetInstanceUP(SQUserPointer tag) const; - SquirrelObject GetValue(const SQChar *key) const; - BOOL Exists(const SQChar *key) const; - FLOAT GetFloat(const SQChar *key) const; - INT GetInt(const SQChar *key) const; - const SQChar *GetString(const SQChar *key) const; - bool GetBool(const SQChar *key) const; - SquirrelObject GetValue(INT key) const; - FLOAT GetFloat(INT key) const; - INT GetInt(INT key) const; - const SQChar *GetString(INT key) const; - bool GetBool(INT key) const; - SquirrelObject GetAttributes(const SQChar *key = NULL); - SQObjectType GetType(); - HSQOBJECT & GetObjectHandle() const {return *(HSQOBJECT*)&_o;} - BOOL BeginIteration(); - BOOL Next(SquirrelObject &key,SquirrelObject &value); - void EndIteration(); - - BOOL GetTypeTag(SQUserPointer * typeTag); - - // === Get the type name of item/object through string key in a table or class. Returns NULL if the type name is not set (not an SqPlus registered type). - const SQChar * GetTypeName(const SQChar * key); - // === Get the type name of item/object through INT key in a table or class. Returns NULL if the type name is not set (not an SqPlus registered type). - const SQChar * GetTypeName(INT key); - // === Get the type name of this object, else return NULL if not an SqPlus registered type. - const SQChar * GetTypeName(void); - - // === Return base class of object using sq_getbase() === - SquirrelObject GetBase(); - - // === 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 - _ty Get(void); - - // Set any bound type to this SquirrelObject. Note that Squirrel's handling of references and pointers still holds here. - template - SquirrelObject SetByValue(_ty val); // classes/structs should be passed by ref (below) to avoid an extra copy. - - // Set any bound type to this SquirrelObject. Note that Squirrel's handling of references and pointers still holds here. - template - SquirrelObject &Set(_ty & val); - - // === END code suggestion from the Wiki === - -private: - BOOL GetSlot(const SQChar *name) const; - BOOL RawGetSlot(const SQChar *name) const; - BOOL GetSlot(INT key) const; - HSQOBJECT _o; -}; - -struct StackHandler { - StackHandler(HSQUIRRELVM v) { - _top = sq_gettop(v); - this->v = v; - } - SQFloat GetFloat(int idx) { - SQFloat x = 0.0f; - if(idx > 0 && idx <= _top) { - sq_getfloat(v,idx,&x); - } - return x; - } - SQInteger GetInt(int idx) { - SQInteger x = 0; - if(idx > 0 && idx <= _top) { - sq_getinteger(v,idx,&x); - } - return x; - } - HSQOBJECT GetObjectHandle(int idx) { - HSQOBJECT x; - if(idx > 0 && idx <= _top) { - sq_resetobject(&x); - sq_getstackobj(v,idx,&x); - } - return x; - } - const SQChar *GetString(int idx) - { - const SQChar *x = NULL; - if(idx > 0 && idx <= _top) { - sq_getstring(v,idx,&x); - } - return x; - } - SQUserPointer GetUserPointer(int idx) - { - SQUserPointer x = 0; - if(idx > 0 && idx <= _top) { - sq_getuserpointer(v,idx,&x); - } - return x; - } - SQUserPointer GetInstanceUp(int idx,SQUserPointer tag) - { - SQUserPointer self; - if(SQ_FAILED(sq_getinstanceup(v,idx,(SQUserPointer*)&self,tag))) - return NULL; - return self; - } - SQUserPointer GetUserData(int idx,SQUserPointer tag=0) - { - SQUserPointer otag; - SQUserPointer up; - if(idx > 0 && idx <= _top) { - if(SQ_SUCCEEDED(sq_getuserdata(v,idx,&up,&otag))) { - if(tag == otag) - return up; - } - } - return NULL; - } - BOOL GetBool(int idx) - { - SQBool ret; - if(idx > 0 && idx <= _top) { - if(SQ_SUCCEEDED(sq_getbool(v,idx,&ret))) - return ret; - } - return FALSE; - } - int GetType(int idx) - { - if(idx > 0 && idx <= _top) { - return sq_gettype(v,idx); - } - return -1; - } - - int GetParamCount() { - return _top; - } - int Return(const SQChar *s) - { - sq_pushstring(v,s,-1); - return 1; - } - int Return(FLOAT f) - { - sq_pushfloat(v,f); - return 1; - } - int Return(INT i) - { - sq_pushinteger(v,i); - return 1; - } - int Return(bool b) - { - sq_pushbool(v,b); - return 1; - } - int Return(SQUserPointer p) { - sq_pushuserpointer(v,p); - return 1; - } - int Return(SquirrelObject &o) - { - sq_pushobject(v,o.GetObjectHandle()); - return 1; - } - int Return() { return 0; } - int ThrowError(const SQChar *error) { - return sq_throwerror(v,error); - } - HSQUIRRELVM GetVMPtr() { return v; } -private: - int _top; - HSQUIRRELVM v; -}; - -#endif //_SQUIRREL_OBJECT_H_ +#ifndef _SQUIRREL_OBJECT_H_ +#define _SQUIRREL_OBJECT_H_ + +class SquirrelObject +{ + friend class SquirrelVM; + +public: + SquirrelObject(); + virtual ~SquirrelObject(); + SquirrelObject(const SquirrelObject & o); + SquirrelObject(HSQOBJECT o); + +#if 1 + template + SquirrelObject(const _ty & val) { sq_resetobject(&_o); Set((_ty &)val); } // Cast away const to avoid compiler SqPlus::Push() match issue. + template + SquirrelObject(_ty & val) { sq_resetobject(&_o); Set(val); } + template + SquirrelObject(_ty * val) { sq_resetobject(&_o); SetByValue(val); } // Set() would also be OK here. SetByValue() to save potential compiler overhead. +#endif + + SquirrelObject & operator = (HSQOBJECT ho); + SquirrelObject & operator = (const SquirrelObject &o); + SquirrelObject & operator = (int n); + SquirrelObject & operator = (HSQUIRRELVM v); + + operator HSQOBJECT& (){ return _o; } + bool operator ==(const SquirrelObject& o); + bool CompareUserPointer(const SquirrelObject& o); + + void AttachToStackObject(int idx); + void Reset(void); // Release (any) reference and reset _o. + SquirrelObject Clone(); + BOOL SetValue(const SquirrelObject &key,const SquirrelObject &val); + + BOOL SetValue(SQInteger key,const SquirrelObject &val); + BOOL SetValue(INT key,bool b); // Compiler treats SQBool as INT. + BOOL SetValue(INT key,INT n); + BOOL SetValue(INT key,FLOAT f); + BOOL SetValue(INT key,const SQChar *s); + + BOOL SetValue(const SQChar *key,const SquirrelObject &val); + BOOL SetValue(const SQChar *key,bool b); + BOOL SetValue(const SQChar *key,INT n); + BOOL SetValue(const SQChar *key,FLOAT f); + BOOL SetValue(const SQChar *key,const SQChar *s); + + BOOL SetUserPointer(const SQChar * key,SQUserPointer up); + SQUserPointer GetUserPointer(const SQChar * key); + BOOL SetUserPointer(INT key,SQUserPointer up); + SQUserPointer GetUserPointer(INT key); + + BOOL NewUserData(const SQChar * key,INT size,SQUserPointer * typetag=0); + BOOL GetUserData(const SQChar * key,SQUserPointer * data,SQUserPointer * typetag=0); + BOOL RawGetUserData(const SQChar * key,SQUserPointer * data,SQUserPointer * typetag=0); + + // === BEGIN Arrays === + + BOOL ArrayResize(INT newSize); + BOOL ArrayExtend(INT amount); + BOOL ArrayReverse(void); + SquirrelObject ArrayPop(SQBool returnPoppedVal=SQTrue); + + void ArrayAppend(const SquirrelObject &o); + + template + BOOL ArrayAppend(T item); + + // === END Arrays === + + BOOL SetInstanceUP(SQUserPointer up); + BOOL IsNull() const; + int IsNumeric() const; + int Len() const; + BOOL SetDelegate(SquirrelObject &obj); + SquirrelObject GetDelegate(); + const SQChar* ToString(); + bool ToBool(); + SQInteger ToInteger(); + SQFloat ToFloat(); + SQUserPointer GetInstanceUP(SQUserPointer tag) const; + SquirrelObject GetValue(const SQChar *key) const; + BOOL Exists(const SQChar *key) const; + FLOAT GetFloat(const SQChar *key) const; + INT GetInt(const SQChar *key) const; + const SQChar *GetString(const SQChar *key) const; + bool GetBool(const SQChar *key) const; + SquirrelObject GetValue(INT key) const; + FLOAT GetFloat(INT key) const; + INT GetInt(INT key) const; + const SQChar *GetString(INT key) const; + bool GetBool(INT key) const; + SquirrelObject GetAttributes(const SQChar *key = NULL); + SQObjectType GetType(); + HSQOBJECT & GetObjectHandle() const {return *(HSQOBJECT*)&_o;} + BOOL BeginIteration(); + BOOL Next(SquirrelObject &key,SquirrelObject &value); + void EndIteration(); + + BOOL GetTypeTag(SQUserPointer * typeTag); + + // === Get the type name of item/object through string key in a table or class. Returns NULL if the type name is not set (not an SqPlus registered type). + const SQChar * GetTypeName(const SQChar * key); + // === Get the type name of item/object through INT key in a table or class. Returns NULL if the type name is not set (not an SqPlus registered type). + const SQChar * GetTypeName(INT key); + // === Get the type name of this object, else return NULL if not an SqPlus registered type. + const SQChar * GetTypeName(void); + + // === Return base class of object using sq_getbase() === + SquirrelObject GetBase(); + + // === 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 + _ty Get(void); + + // Set any bound type to this SquirrelObject. Note that Squirrel's handling of references and pointers still holds here. + template + SquirrelObject SetByValue(_ty val); // classes/structs should be passed by ref (below) to avoid an extra copy. + + // Set any bound type to this SquirrelObject. Note that Squirrel's handling of references and pointers still holds here. + template + SquirrelObject &Set(_ty & val); + + // === END code suggestion from the Wiki === + +private: + BOOL GetSlot(const SQChar *name) const; + BOOL RawGetSlot(const SQChar *name) const; + BOOL GetSlot(INT key) const; + HSQOBJECT _o; +}; + +struct StackHandler { + StackHandler(HSQUIRRELVM v) { + _top = sq_gettop(v); + this->v = v; + } + SQFloat GetFloat(int idx) { + SQFloat x = 0.0f; + if(idx > 0 && idx <= _top) { + sq_getfloat(v,idx,&x); + } + return x; + } + SQInteger GetInt(int idx) { + SQInteger x = 0; + if(idx > 0 && idx <= _top) { + sq_getinteger(v,idx,&x); + } + return x; + } + HSQOBJECT GetObjectHandle(int idx) { + HSQOBJECT x; + if(idx > 0 && idx <= _top) { + sq_resetobject(&x); + sq_getstackobj(v,idx,&x); + } + return x; + } + const SQChar *GetString(int idx) + { + const SQChar *x = NULL; + if(idx > 0 && idx <= _top) { + sq_getstring(v,idx,&x); + } + return x; + } + SQUserPointer GetUserPointer(int idx) + { + SQUserPointer x = 0; + if(idx > 0 && idx <= _top) { + sq_getuserpointer(v,idx,&x); + } + return x; + } + SQUserPointer GetInstanceUp(int idx,SQUserPointer tag) + { + SQUserPointer self; + if(SQ_FAILED(sq_getinstanceup(v,idx,(SQUserPointer*)&self,tag))) + return NULL; + return self; + } + SQUserPointer GetUserData(int idx,SQUserPointer tag=0) + { + SQUserPointer otag; + SQUserPointer up; + if(idx > 0 && idx <= _top) { + if(SQ_SUCCEEDED(sq_getuserdata(v,idx,&up,&otag))) { + if(tag == otag) + return up; + } + } + return NULL; + } + BOOL GetBool(int idx) + { + SQBool ret; + if(idx > 0 && idx <= _top) { + if(SQ_SUCCEEDED(sq_getbool(v,idx,&ret))) + return ret; + } + return FALSE; + } + int GetType(int idx) + { + if(idx > 0 && idx <= _top) { + return sq_gettype(v,idx); + } + return -1; + } + + int GetParamCount() { + return _top; + } + int Return(const SQChar *s) + { + sq_pushstring(v,s,-1); + return 1; + } + int Return(FLOAT f) + { + sq_pushfloat(v,f); + return 1; + } + int Return(INT i) + { + sq_pushinteger(v,i); + return 1; + } + int Return(bool b) + { + sq_pushbool(v,b); + return 1; + } + int Return(SQUserPointer p) { + sq_pushuserpointer(v,p); + return 1; + } + int Return(SquirrelObject &o) + { + sq_pushobject(v,o.GetObjectHandle()); + return 1; + } + int Return() { return 0; } + int ThrowError(const SQChar *error) { + return sq_throwerror(v,error); + } + HSQUIRRELVM GetVMPtr() { return v; } +private: + int _top; + HSQUIRRELVM v; +}; + +#endif //_SQUIRREL_OBJECT_H_ diff --git a/squirrel_3_0_1_stable/sqplus/SquirrelVM.cpp b/squirrel_3_0_1_stable/_OLD_sqplus/SquirrelVM.cpp similarity index 96% rename from squirrel_3_0_1_stable/sqplus/SquirrelVM.cpp rename to squirrel_3_0_1_stable/_OLD_sqplus/SquirrelVM.cpp index 2d506d700..12b84dbe5 100644 --- a/squirrel_3_0_1_stable/sqplus/SquirrelVM.cpp +++ b/squirrel_3_0_1_stable/_OLD_sqplus/SquirrelVM.cpp @@ -1,505 +1,505 @@ -#include -#include -#include - -#define _DEBUG_DUMP - -#include "sqplus.h" - -#include -#include -#include -#include -#include -#include - - -HSQUIRRELVM SquirrelVM::_VM; -bool SquirrelVM::_no_vm_ref; -int SquirrelVM::_CallState = -1; -SquirrelObject* SquirrelVM::_root; -HSQUIRRELVM SquirrelVM::_sandboxVM; -SquirrelObject SquirrelVM::_vm; - - -// Helper struct to keep track of all SQSharedState:s created by SquirrelVM. -#include "../squirrel/sqpcheader.h" -#include "../squirrel/sqvm.h" -struct SQSharedStateNode { - SQSharedStateNode( SQSharedState* ps ); - ~SQSharedStateNode( ); - SQSharedState* m_ps; - SQSharedStateNode* m_nxt; -}; - -// Linked list of shared states -static SQSharedStateNode* g_sqss_fst; - -SQSharedStateNode::SQSharedStateNode( SQSharedState* ps ) : m_ps(ps), m_nxt(g_sqss_fst) { - g_sqss_fst = this; -} - -SQSharedStateNode::~SQSharedStateNode() { - if(m_ps) sq_delete(m_ps,SQSharedState); - delete m_nxt; -} - -static struct SquirrelVM_ModConstr { - ~SquirrelVM_ModConstr(){ - // Delete any shared states we created - delete g_sqss_fst; - g_sqss_fst = NULL; - } -} g_squirrelvm_mod_constr; - - - -SquirrelError::SquirrelError() -{ - const SQChar *s; - sq_getlasterror(SquirrelVM::_VM); - sq_getstring(SquirrelVM::_VM,-1,&s); - if(s) { - desc = s; - } - else { - desc = _SC("unknown error"); - } -} - - -SquirrelVMSys::~SquirrelVMSys() { - // Must take care to release object with the 'ref' VM - PushRefVM( _vm.GetObjectHandle()._unVal.pThread ); - _vm.Reset(); - PopRefVM(); -} - -void SquirrelVMSys::Set( HSQUIRRELVM v ){ - // Must take care to release object with the 'ref' VM - PushRefVM( v ); - _vm = v; - PopRefVM( ); -} - -void SquirrelVMSys::Set( const SquirrelObject& ov ){ - assert( ov.GetObjectHandle()._type==OT_THREAD ); - // Must take care to release object with the 'ref' VM - PushRefVM( ov.GetObjectHandle()._unVal.pThread ); - _vm = ov; - PopRefVM( ); -} - -SquirrelVMSys::operator HSQUIRRELVM () const { - // Avoid const madness - SquirrelObject *pvm = (SquirrelObject*)&_vm; - assert( pvm->GetObjectHandle()._type==OT_THREAD ); - return pvm->GetObjectHandle()._unVal.pThread; -} - - -// When doing a SquirrelObject assignment, a reference using the current -// VM is done. -HSQUIRRELVM g_VM_pushed; -void SquirrelVMSys::PushRefVM( HSQUIRRELVM v ){ - assert( !g_VM_pushed ); - g_VM_pushed = SquirrelVM::_VM; - SquirrelVM::_VM = v; -} - -void SquirrelVMSys::PopRefVM( ){ - SquirrelVM::_VM = g_VM_pushed; - g_VM_pushed = NULL; -} - - -bool SquirrelVM::Init( HSQUIRRELVM v ){ - if( v && v==_VM ) - return true; - - // Do we have a previous state? - Release( ); - - bool created_new = false; - if( !v ){ - // Create a new VM - a root VM with new SharedState. - v = sq_open(1024); - if( !v ) return false; - // Store the associated shared state in a linked list. The state will only - // be destroyed at app shutdown. Often that is fine, but if using many - // VM:s briefly, this allocation is not optimal. - new SQSharedStateNode( _ss(v) ); - created_new = true; - sq_setprintfunc(v,SquirrelVM::PrintFunc, SquirrelVM::PrintFunc); - sq_pushroottable(v); - sqstd_register_iolib(v); - sqstd_register_bloblib(v); - sqstd_register_mathlib(v); - sqstd_register_stringlib(v); -#ifdef SQPLUS_SQUIRRELVM_WITH_SYSTEMLIB - sqstd_register_systemlib(v); -#endif - sqstd_seterrorhandlers(v); - //TODO error handler, compiler error handler - sq_pop(v,1); - } - - // After this we hold a ref - _no_vm_ref = false; - _VM = v; - _vm = v; - - // In the case where Squirrel is ref counted we currently - // hold two references to the VM (since it is created with - // a ref count of 1). In the GC case, it is outside of the - // chain of valid objects, so it is not referenced. Compensate - // in ref counted case. - if( created_new ) - DropVMRefIfRefCounted( v ); - - return true; -} - -bool SquirrelVM::InitNoRef( HSQUIRRELVM v ){ - if( v && v==_VM ) - return true; - - // Do we have a previous state? - Release( ); - - // Set pointer to this VM, without referencing it - _no_vm_ref = true; - _VM = v; - - return true; -} - -/* -void SquirrelVM::Init( HSQUIRRELVM v ) -{ - if( v && v==_VM ) { - return; - } - - // Do we have a previous state? - Release(); - - if( !v ){ - // Create a new VM and own it - _VM = sq_open(1024); - sq_setprintfunc(_VM,SquirrelVM::PrintFunc); - sq_pushroottable(_VM); - sqstd_register_iolib(_VM); - sqstd_register_bloblib(_VM); - sqstd_register_mathlib(_VM); - sqstd_register_stringlib(_VM); - sqstd_seterrorhandlers(_VM); - //TODO error handler, compiler error handler - sq_pop(_VM,1); - } - else { - _VM = v; - } - // After this we hold a ref - _vm = _VM; -} -*/ - -void SquirrelVM::Release() { - // Release root table object if we have one - if( _root ){ - delete _root; - _root = NULL; - } - - // Release our ref on VM - if we should - if( !_no_vm_ref ) - _vm.Reset(); - - _VM = NULL; -} - -void SquirrelVM::DropVMRefIfRefCounted( HSQUIRRELVM v ){ -#ifdef NO_GARBAGE_COLLECTOR - if( v ){ - SQObject t; - t._unVal.pThread = v; - t._type = OT_THREAD; - sq_release( v, &t ); - } -#endif -} - -BOOL SquirrelVM::Update() -{ - //update remote debugger - return TRUE; -} - -void SquirrelVM::PrintFunc(HSQUIRRELVM v,const SQChar* s,...) -{ - static SQChar temp[2048]; - va_list vl; - va_start(vl, s); - scvsprintf( temp,s, vl); - SCPUTS(temp); - va_end(vl); -} - -SquirrelObject SquirrelVM::CompileScript(const SQChar *s) -{ - SquirrelObject ret; - if(SQ_SUCCEEDED(sqstd_loadfile(_VM,s,1))) { - ret.AttachToStackObject(-1); - sq_pop(_VM,1); - return ret; - } - throw SquirrelError(); -} - -SquirrelObject SquirrelVM::CompileBuffer(const SQChar *s,const SQChar * debugInfo) -{ - SquirrelObject ret; - if(SQ_SUCCEEDED(sq_compilebuffer(_VM,s,(int)scstrlen(s)*sizeof(SQChar),debugInfo,1))) { - ret.AttachToStackObject(-1); - sq_pop(_VM,1); - return ret; - } - throw SquirrelError(); -} - -SquirrelObject SquirrelVM::RunScript(const SquirrelObject &o,SquirrelObject *_this) -{ - SquirrelObject ret; - sq_pushobject(_VM,o._o); - if(_this) { - sq_pushobject(_VM,_this->_o); - } - else { - sq_pushroottable(_VM); - } - if(SQ_SUCCEEDED(sq_call(_VM,1,SQTrue,SQ_CALL_RAISE_ERROR))) { - ret.AttachToStackObject(-1); - sq_pop(_VM,2); - return ret; - } - sq_pop(_VM,1); - throw SquirrelError(); - -} - - -BOOL SquirrelVM::BeginCall(const SquirrelObject &func) -{ - if(_CallState != -1) - return FALSE; - _CallState = 1; - sq_pushobject(_VM,func._o); - sq_pushroottable(_VM); - return TRUE; -} - -BOOL SquirrelVM::BeginCall(const SquirrelObject &func,SquirrelObject &_this) -{ - if(_CallState != -1) - throw SquirrelError(_SC("call already initialized")); - _CallState = 1; - sq_pushobject(_VM,func._o); - sq_pushobject(_VM,_this._o); - return TRUE; -} - -#define _CHECK_CALL_STATE \ - if(_CallState == -1) \ - throw SquirrelError(_SC("call not initialized")); - -void SquirrelVM::PushParam(const SquirrelObject &o) -{ - _CHECK_CALL_STATE - sq_pushobject(_VM,o._o); - _CallState++; -} - -void SquirrelVM::PushParam(const SQChar *s) -{ - _CHECK_CALL_STATE - sq_pushstring(_VM,s,-1); - _CallState++; -} - -void SquirrelVM::PushParam(SQInteger n) -{ - _CHECK_CALL_STATE - sq_pushinteger(_VM,n); - _CallState++; -} - -void SquirrelVM::PushParam(SQFloat f) -{ - _CHECK_CALL_STATE - sq_pushfloat(_VM,f); - _CallState++; -} - -void SquirrelVM::PushParamNull() -{ - _CHECK_CALL_STATE - sq_pushnull(_VM); - _CallState++; -} - -void SquirrelVM::PushParam(SQUserPointer up) -{ - _CHECK_CALL_STATE - sq_pushuserpointer(_VM,up); - _CallState++; -} - -SquirrelObject SquirrelVM::EndCall() -{ - SquirrelObject ret; - if(_CallState >= 0) { - int oldtop = sq_gettop(_VM); - int nparams = _CallState; - _CallState = -1; - if(SQ_SUCCEEDED(sq_call(_VM,nparams,SQTrue,SQ_CALL_RAISE_ERROR))) { - ret.AttachToStackObject(-1); - sq_pop(_VM,2); - }else { - sq_settop(_VM,oldtop-(nparams+1)); - throw SquirrelError(); - } - - } - return ret; -} - -SquirrelObject SquirrelVM::CreateInstance(SquirrelObject &oclass) -{ - SquirrelObject ret; - int oldtop = sq_gettop(_VM); - sq_pushobject(_VM,oclass._o); - if(SQ_FAILED(sq_createinstance(_VM,-1))) { - sq_settop(_VM,oldtop); - throw SquirrelError(); - } - ret.AttachToStackObject(-1); - sq_pop(_VM,2); - return ret; -} - -SquirrelObject SquirrelVM::CreateTable() -{ - SquirrelObject ret; - sq_newtable(_VM); - ret.AttachToStackObject(-1); - sq_pop(_VM,1); - return ret; -} - -SquirrelObject SquirrelVM::CreateString(const SQChar *s) -{ - SquirrelObject ret; - sq_pushstring(_VM,s,-1); - ret.AttachToStackObject(-1); - sq_pop(_VM,1); - return ret; -} - - -SquirrelObject SquirrelVM::CreateArray(int size) -{ - SquirrelObject ret; - sq_newarray(_VM,size); - ret.AttachToStackObject(-1); - sq_pop(_VM,1); - return ret; -} - -SquirrelObject SquirrelVM::CreateFunction(SQFUNCTION func) -{ - SquirrelObject ret; - sq_newclosure(_VM,func,0); - ret.AttachToStackObject(-1); - sq_pop(_VM,1); - return ret; -} - -SquirrelObject SquirrelVM::CreateUserData(int size) { - SquirrelObject ret; - sq_newuserdata(_VM,size); - ret.AttachToStackObject(-1); - sq_pop(_VM,1); - return ret; -} - -const SquirrelObject &SquirrelVM::GetRootTable() -{ - if( !_root ){ - sq_pushroottable(_VM); - _root = new SquirrelObject(); - _root->AttachToStackObject(-1); - sq_pop(_VM,1); - } - return *_root; -} - -void SquirrelVM::PushRootTable(void) { - sq_pushroottable(_VM); -} // SquirrelVM::PushRootTable - -// Creates a function in the table or class currently on the stack. -//void CreateFunction(HSQUIRRELVM v,const SQChar * scriptFuncName,SQFUNCTION func,int numParams=0,const SQChar * typeMask=0) { -SquirrelObject SquirrelVM::CreateFunction(SQFUNCTION func,const SQChar * scriptFuncName,const SQChar * typeMask) { - sq_pushstring(_VM,scriptFuncName,-1); - sq_newclosure(_VM,func,0); - SquirrelObject ret; - ret.AttachToStackObject(-1); - 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("t|y|x%s"),typeMask) < 0) { -// sq_throwerror(_VM,_SC("CreateFunction: typeMask string too long.")); - throw SquirrelError(_SC("CreateFunction: typeMask string too long.")); - } // if - } // if - } else { // Need to check object type on stack: table, class, instance, etc. - SCSNPRINTF(tm,sizeof(tm),_SC("%s"),_SC("t|y|x")); // table, class, instance. -// tm[0] = 't'; -// tm[1] = 0; - } // if -#if 0 - sq_setparamscheck(_VM,numParams+1,ptm); // Parameters are table+args (thus, the +1). -#else - if (ptm) { - sq_setparamscheck(_VM,numParams,ptm); // Determine arg count from type string. - } // if -#endif -#ifdef _DEBUG - sq_setnativeclosurename(_VM,-1,scriptFuncName); // For debugging only. -#endif - sq_createslot(_VM,-3); // Create slot in table or class (assigning function to slot at scriptNameFunc). - return ret; -} // SquirrelVM::CreateFunction - -SquirrelObject SquirrelVM::CreateFunction(SquirrelObject & so,SQFUNCTION func,const SQChar * scriptFuncName,const SQChar * typeMask) { - PushObject(so); - SquirrelObject ret = CreateFunction(func,scriptFuncName,typeMask); - Pop(1); - return ret; -} // SquirrelVM::CreateFunction - -// Create a Global function on the root table. -//void CreateFunctionGlobal(HSQUIRRELVM v,const SQChar * scriptFuncName,SQFUNCTION func,int numParams=0,const SQChar * typeMask=0) { -SquirrelObject SquirrelVM::CreateFunctionGlobal(SQFUNCTION func,const SQChar * scriptFuncName,const SQChar * typeMask) { - PushRootTable(); // Push root table. - // CreateFunction(scriptFuncName,func,numParams,typeMask); - SquirrelObject ret = CreateFunction(func,scriptFuncName,typeMask); - Pop(1); // Pop root table. - return ret; -} // SquirrelVM::CreateFunctionGlobal +#include +#include +#include + +#define _DEBUG_DUMP + +#include "sqplus.h" + +#include +#include +#include +#include +#include +#include + + +HSQUIRRELVM SquirrelVM::_VM; +bool SquirrelVM::_no_vm_ref; +int SquirrelVM::_CallState = -1; +SquirrelObject* SquirrelVM::_root; +HSQUIRRELVM SquirrelVM::_sandboxVM; +SquirrelObject SquirrelVM::_vm; + + +// Helper struct to keep track of all SQSharedState:s created by SquirrelVM. +#include "../squirrel/sqpcheader.h" +#include "../squirrel/sqvm.h" +struct SQSharedStateNode { + SQSharedStateNode( SQSharedState* ps ); + ~SQSharedStateNode( ); + SQSharedState* m_ps; + SQSharedStateNode* m_nxt; +}; + +// Linked list of shared states +static SQSharedStateNode* g_sqss_fst; + +SQSharedStateNode::SQSharedStateNode( SQSharedState* ps ) : m_ps(ps), m_nxt(g_sqss_fst) { + g_sqss_fst = this; +} + +SQSharedStateNode::~SQSharedStateNode() { + if(m_ps) sq_delete(m_ps,SQSharedState); + delete m_nxt; +} + +static struct SquirrelVM_ModConstr { + ~SquirrelVM_ModConstr(){ + // Delete any shared states we created + delete g_sqss_fst; + g_sqss_fst = NULL; + } +} g_squirrelvm_mod_constr; + + + +SquirrelError::SquirrelError() +{ + const SQChar *s; + sq_getlasterror(SquirrelVM::_VM); + sq_getstring(SquirrelVM::_VM,-1,&s); + if(s) { + desc = s; + } + else { + desc = _SC("unknown error"); + } +} + + +SquirrelVMSys::~SquirrelVMSys() { + // Must take care to release object with the 'ref' VM + PushRefVM( _vm.GetObjectHandle()._unVal.pThread ); + _vm.Reset(); + PopRefVM(); +} + +void SquirrelVMSys::Set( HSQUIRRELVM v ){ + // Must take care to release object with the 'ref' VM + PushRefVM( v ); + _vm = v; + PopRefVM( ); +} + +void SquirrelVMSys::Set( const SquirrelObject& ov ){ + assert( ov.GetObjectHandle()._type==OT_THREAD ); + // Must take care to release object with the 'ref' VM + PushRefVM( ov.GetObjectHandle()._unVal.pThread ); + _vm = ov; + PopRefVM( ); +} + +SquirrelVMSys::operator HSQUIRRELVM () const { + // Avoid const madness + SquirrelObject *pvm = (SquirrelObject*)&_vm; + assert( pvm->GetObjectHandle()._type==OT_THREAD ); + return pvm->GetObjectHandle()._unVal.pThread; +} + + +// When doing a SquirrelObject assignment, a reference using the current +// VM is done. +HSQUIRRELVM g_VM_pushed; +void SquirrelVMSys::PushRefVM( HSQUIRRELVM v ){ + assert( !g_VM_pushed ); + g_VM_pushed = SquirrelVM::_VM; + SquirrelVM::_VM = v; +} + +void SquirrelVMSys::PopRefVM( ){ + SquirrelVM::_VM = g_VM_pushed; + g_VM_pushed = NULL; +} + + +bool SquirrelVM::Init( HSQUIRRELVM v ){ + if( v && v==_VM ) + return true; + + // Do we have a previous state? + Release( ); + + bool created_new = false; + if( !v ){ + // Create a new VM - a root VM with new SharedState. + v = sq_open(1024); + if( !v ) return false; + // Store the associated shared state in a linked list. The state will only + // be destroyed at app shutdown. Often that is fine, but if using many + // VM:s briefly, this allocation is not optimal. + new SQSharedStateNode( _ss(v) ); + created_new = true; + sq_setprintfunc(v,SquirrelVM::PrintFunc, SquirrelVM::PrintFunc); + sq_pushroottable(v); + sqstd_register_iolib(v); + sqstd_register_bloblib(v); + sqstd_register_mathlib(v); + sqstd_register_stringlib(v); +#ifdef SQPLUS_SQUIRRELVM_WITH_SYSTEMLIB + sqstd_register_systemlib(v); +#endif + sqstd_seterrorhandlers(v); + //TODO error handler, compiler error handler + sq_pop(v,1); + } + + // After this we hold a ref + _no_vm_ref = false; + _VM = v; + _vm = v; + + // In the case where Squirrel is ref counted we currently + // hold two references to the VM (since it is created with + // a ref count of 1). In the GC case, it is outside of the + // chain of valid objects, so it is not referenced. Compensate + // in ref counted case. + if( created_new ) + DropVMRefIfRefCounted( v ); + + return true; +} + +bool SquirrelVM::InitNoRef( HSQUIRRELVM v ){ + if( v && v==_VM ) + return true; + + // Do we have a previous state? + Release( ); + + // Set pointer to this VM, without referencing it + _no_vm_ref = true; + _VM = v; + + return true; +} + +/* +void SquirrelVM::Init( HSQUIRRELVM v ) +{ + if( v && v==_VM ) { + return; + } + + // Do we have a previous state? + Release(); + + if( !v ){ + // Create a new VM and own it + _VM = sq_open(1024); + sq_setprintfunc(_VM,SquirrelVM::PrintFunc); + sq_pushroottable(_VM); + sqstd_register_iolib(_VM); + sqstd_register_bloblib(_VM); + sqstd_register_mathlib(_VM); + sqstd_register_stringlib(_VM); + sqstd_seterrorhandlers(_VM); + //TODO error handler, compiler error handler + sq_pop(_VM,1); + } + else { + _VM = v; + } + // After this we hold a ref + _vm = _VM; +} +*/ + +void SquirrelVM::Release() { + // Release root table object if we have one + if( _root ){ + delete _root; + _root = NULL; + } + + // Release our ref on VM - if we should + if( !_no_vm_ref ) + _vm.Reset(); + + _VM = NULL; +} + +void SquirrelVM::DropVMRefIfRefCounted( HSQUIRRELVM v ){ +#ifdef NO_GARBAGE_COLLECTOR + if( v ){ + SQObject t; + t._unVal.pThread = v; + t._type = OT_THREAD; + sq_release( v, &t ); + } +#endif +} + +BOOL SquirrelVM::Update() +{ + //update remote debugger + return TRUE; +} + +void SquirrelVM::PrintFunc(HSQUIRRELVM v,const SQChar* s,...) +{ + static SQChar temp[2048]; + va_list vl; + va_start(vl, s); + scvsprintf( temp,s, vl); + SCPUTS(temp); + va_end(vl); +} + +SquirrelObject SquirrelVM::CompileScript(const SQChar *s) +{ + SquirrelObject ret; + if(SQ_SUCCEEDED(sqstd_loadfile(_VM,s,1))) { + ret.AttachToStackObject(-1); + sq_pop(_VM,1); + return ret; + } + throw SquirrelError(); +} + +SquirrelObject SquirrelVM::CompileBuffer(const SQChar *s,const SQChar * debugInfo) +{ + SquirrelObject ret; + if(SQ_SUCCEEDED(sq_compilebuffer(_VM,s,(int)scstrlen(s)*sizeof(SQChar),debugInfo,1))) { + ret.AttachToStackObject(-1); + sq_pop(_VM,1); + return ret; + } + throw SquirrelError(); +} + +SquirrelObject SquirrelVM::RunScript(const SquirrelObject &o,SquirrelObject *_this) +{ + SquirrelObject ret; + sq_pushobject(_VM,o._o); + if(_this) { + sq_pushobject(_VM,_this->_o); + } + else { + sq_pushroottable(_VM); + } + if(SQ_SUCCEEDED(sq_call(_VM,1,SQTrue,SQ_CALL_RAISE_ERROR))) { + ret.AttachToStackObject(-1); + sq_pop(_VM,2); + return ret; + } + sq_pop(_VM,1); + throw SquirrelError(); + +} + + +BOOL SquirrelVM::BeginCall(const SquirrelObject &func) +{ + if(_CallState != -1) + return FALSE; + _CallState = 1; + sq_pushobject(_VM,func._o); + sq_pushroottable(_VM); + return TRUE; +} + +BOOL SquirrelVM::BeginCall(const SquirrelObject &func,SquirrelObject &_this) +{ + if(_CallState != -1) + throw SquirrelError(_SC("call already initialized")); + _CallState = 1; + sq_pushobject(_VM,func._o); + sq_pushobject(_VM,_this._o); + return TRUE; +} + +#define _CHECK_CALL_STATE \ + if(_CallState == -1) \ + throw SquirrelError(_SC("call not initialized")); + +void SquirrelVM::PushParam(const SquirrelObject &o) +{ + _CHECK_CALL_STATE + sq_pushobject(_VM,o._o); + _CallState++; +} + +void SquirrelVM::PushParam(const SQChar *s) +{ + _CHECK_CALL_STATE + sq_pushstring(_VM,s,-1); + _CallState++; +} + +void SquirrelVM::PushParam(SQInteger n) +{ + _CHECK_CALL_STATE + sq_pushinteger(_VM,n); + _CallState++; +} + +void SquirrelVM::PushParam(SQFloat f) +{ + _CHECK_CALL_STATE + sq_pushfloat(_VM,f); + _CallState++; +} + +void SquirrelVM::PushParamNull() +{ + _CHECK_CALL_STATE + sq_pushnull(_VM); + _CallState++; +} + +void SquirrelVM::PushParam(SQUserPointer up) +{ + _CHECK_CALL_STATE + sq_pushuserpointer(_VM,up); + _CallState++; +} + +SquirrelObject SquirrelVM::EndCall() +{ + SquirrelObject ret; + if(_CallState >= 0) { + int oldtop = sq_gettop(_VM); + int nparams = _CallState; + _CallState = -1; + if(SQ_SUCCEEDED(sq_call(_VM,nparams,SQTrue,SQ_CALL_RAISE_ERROR))) { + ret.AttachToStackObject(-1); + sq_pop(_VM,2); + }else { + sq_settop(_VM,oldtop-(nparams+1)); + throw SquirrelError(); + } + + } + return ret; +} + +SquirrelObject SquirrelVM::CreateInstance(SquirrelObject &oclass) +{ + SquirrelObject ret; + int oldtop = sq_gettop(_VM); + sq_pushobject(_VM,oclass._o); + if(SQ_FAILED(sq_createinstance(_VM,-1))) { + sq_settop(_VM,oldtop); + throw SquirrelError(); + } + ret.AttachToStackObject(-1); + sq_pop(_VM,2); + return ret; +} + +SquirrelObject SquirrelVM::CreateTable() +{ + SquirrelObject ret; + sq_newtable(_VM); + ret.AttachToStackObject(-1); + sq_pop(_VM,1); + return ret; +} + +SquirrelObject SquirrelVM::CreateString(const SQChar *s) +{ + SquirrelObject ret; + sq_pushstring(_VM,s,-1); + ret.AttachToStackObject(-1); + sq_pop(_VM,1); + return ret; +} + + +SquirrelObject SquirrelVM::CreateArray(int size) +{ + SquirrelObject ret; + sq_newarray(_VM,size); + ret.AttachToStackObject(-1); + sq_pop(_VM,1); + return ret; +} + +SquirrelObject SquirrelVM::CreateFunction(SQFUNCTION func) +{ + SquirrelObject ret; + sq_newclosure(_VM,func,0); + ret.AttachToStackObject(-1); + sq_pop(_VM,1); + return ret; +} + +SquirrelObject SquirrelVM::CreateUserData(int size) { + SquirrelObject ret; + sq_newuserdata(_VM,size); + ret.AttachToStackObject(-1); + sq_pop(_VM,1); + return ret; +} + +const SquirrelObject &SquirrelVM::GetRootTable() +{ + if( !_root ){ + sq_pushroottable(_VM); + _root = new SquirrelObject(); + _root->AttachToStackObject(-1); + sq_pop(_VM,1); + } + return *_root; +} + +void SquirrelVM::PushRootTable(void) { + sq_pushroottable(_VM); +} // SquirrelVM::PushRootTable + +// Creates a function in the table or class currently on the stack. +//void CreateFunction(HSQUIRRELVM v,const SQChar * scriptFuncName,SQFUNCTION func,int numParams=0,const SQChar * typeMask=0) { +SquirrelObject SquirrelVM::CreateFunction(SQFUNCTION func,const SQChar * scriptFuncName,const SQChar * typeMask) { + sq_pushstring(_VM,scriptFuncName,-1); + sq_newclosure(_VM,func,0); + SquirrelObject ret; + ret.AttachToStackObject(-1); + 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("t|y|x%s"),typeMask) < 0) { +// sq_throwerror(_VM,_SC("CreateFunction: typeMask string too long.")); + throw SquirrelError(_SC("CreateFunction: typeMask string too long.")); + } // if + } // if + } else { // Need to check object type on stack: table, class, instance, etc. + SCSNPRINTF(tm,sizeof(tm),_SC("%s"),_SC("t|y|x")); // table, class, instance. +// tm[0] = 't'; +// tm[1] = 0; + } // if +#if 0 + sq_setparamscheck(_VM,numParams+1,ptm); // Parameters are table+args (thus, the +1). +#else + if (ptm) { + sq_setparamscheck(_VM,numParams,ptm); // Determine arg count from type string. + } // if +#endif +#ifdef _DEBUG + sq_setnativeclosurename(_VM,-1,scriptFuncName); // For debugging only. +#endif + sq_createslot(_VM,-3); // Create slot in table or class (assigning function to slot at scriptNameFunc). + return ret; +} // SquirrelVM::CreateFunction + +SquirrelObject SquirrelVM::CreateFunction(SquirrelObject & so,SQFUNCTION func,const SQChar * scriptFuncName,const SQChar * typeMask) { + PushObject(so); + SquirrelObject ret = CreateFunction(func,scriptFuncName,typeMask); + Pop(1); + return ret; +} // SquirrelVM::CreateFunction + +// Create a Global function on the root table. +//void CreateFunctionGlobal(HSQUIRRELVM v,const SQChar * scriptFuncName,SQFUNCTION func,int numParams=0,const SQChar * typeMask=0) { +SquirrelObject SquirrelVM::CreateFunctionGlobal(SQFUNCTION func,const SQChar * scriptFuncName,const SQChar * typeMask) { + PushRootTable(); // Push root table. + // CreateFunction(scriptFuncName,func,numParams,typeMask); + SquirrelObject ret = CreateFunction(func,scriptFuncName,typeMask); + Pop(1); // Pop root table. + return ret; +} // SquirrelVM::CreateFunctionGlobal diff --git a/squirrel_3_0_1_stable/sqplus/SquirrelVM.h b/squirrel_3_0_1_stable/_OLD_sqplus/SquirrelVM.h similarity index 97% rename from squirrel_3_0_1_stable/sqplus/SquirrelVM.h rename to squirrel_3_0_1_stable/_OLD_sqplus/SquirrelVM.h index ee66a2b76..70c4f2a36 100644 --- a/squirrel_3_0_1_stable/sqplus/SquirrelVM.h +++ b/squirrel_3_0_1_stable/_OLD_sqplus/SquirrelVM.h @@ -1,179 +1,179 @@ -#ifndef _SQUIRREL_VM_H_ -#define _SQUIRREL_VM_H_ - -#include "SquirrelObject.h" - -struct SquirrelError { - SquirrelError(); - SquirrelError(const SQChar* s):desc(s){} - const SQChar *desc; -}; - -// This class can hold a reference to a SquirrelVM. It keeps a Squirrel ref -// to the VM to protect it from being deleted while held. -struct SquirrelVMSys { - SquirrelVMSys() { } - ~SquirrelVMSys(); - - void Set( HSQUIRRELVM v ); - void Set( const SquirrelObject& ov ); - void Reset( ){ _vm.Reset(); } - - SquirrelVMSys& operator = (HSQUIRRELVM v){ Set(v); return *this; } - operator HSQUIRRELVM () const; - -protected: - void PushRefVM(HSQUIRRELVM v); - void PopRefVM(); - SquirrelObject _vm; - friend class SquirrelVM; -}; - -// Notes on creating / destroying SquirrelVM:s: -// -// VM:s created through sq_open are special since they create a new -// SQSharedState. That shared state is later shared by any new thread -// or friend VM. sq_close can be used for closing VM:s created through -// sq_open (but not for friend VMs). -// -// Using squirrel references in SquirrelVMSys and SquirrelVM, one must -// make sure that these are all reset if one calls sq_close manually. -// -// When there are no more references to a VM, it is destroyed automatically, -// but the shared state is not! For VM:s created by SquirrelVM, it keeps -// a list of shared states it has created and will destroy them all on -// app shutdown. - -class SquirrelVM { - friend class SquirrelObject; - friend struct SquirrelError; - friend struct SquirrelVMSys; - -public: - // If a VM is passed as arg here, Init will not alter it. Otherwise - // a new VM is created and initialized. A squirrel reference is kept - // while it is the current VM. - static bool Init( HSQUIRRELVM v=NULL ); - - // Initialize with an externally created VM, without adding a ref - // on it. NOTE: This may not be compatible with Set/GetVMSys as - // we're just working with raw pointers here. - static bool InitNoRef( HSQUIRRELVM v ); - static BOOL IsInitialized(){return _VM == NULL?FALSE:TRUE;} - - static void Release(); // Release ref on VM and reset VM pointer - static void Shutdown(){ Release(); } - static void AppFinalShutdown(); // Call when finally shutting down app - - static BOOL Update(); //debugger and maybe GC later - - static SquirrelObject CompileScript(const SQChar *s); - static SquirrelObject CompileBuffer(const SQChar *s,const SQChar * debugInfo=_SC("console_buffer")); - static SquirrelObject RunScript(const SquirrelObject &o,SquirrelObject *_this = NULL); - - static void PrintFunc(HSQUIRRELVM v,const SQChar* s,...); - - static BOOL BeginCall(const SquirrelObject &func); - static BOOL BeginCall(const SquirrelObject &func,SquirrelObject &_this); - - static void PushParam(const SquirrelObject &o); - static void PushParam(const SQChar *s); - static void PushParam(SQInteger n); - static void PushParam(SQFloat f); - static void PushParam(SQUserPointer up); - static void PushParamNull(); - - static SquirrelObject EndCall(); - static SquirrelObject CreateString(const SQChar *s); - static SquirrelObject CreateTable(); - static SquirrelObject CreateArray(int size); - static SquirrelObject CreateInstance(SquirrelObject &oclass); // oclass is an existing class. Create an 'instance' (OT_INSTANCE) of oclass. - static SquirrelObject CreateFunction(SQFUNCTION func); - static SquirrelObject CreateUserData(int size); - - static const SquirrelObject &GetRootTable(); - static HSQUIRRELVM GetVMPtr() { return _VM; } - - // The sandbox VM ptr is one which cannot access functions bound with - // SqPlus. It is suitable for running non-trusted scripts that can only - // access basic functionality. - static void SetSandboxVMPtr(HSQUIRRELVM v) { - _sandboxVM = v; - } // SetSandboxVMPtr - - static HSQUIRRELVM GetSandboxVMPtr() { - return _sandboxVM; - } // GetSandboxVMPtr - - static void GetVMSys(SquirrelVMSys & vmSys) { - vmSys.Set( _vm ); - } // GetVMSys - - static void SetVMSys(const SquirrelVMSys & vmSys) { - Release(); - HSQUIRRELVM v = (HSQUIRRELVM)vmSys; - if( v ) - Init( v ); - } // SetVMSys - - static void PushValue(INT val) { - sq_pushinteger(_VM,val); - } // PushValue - static void PushValue(FLOAT val) { - sq_pushfloat(_VM,val); - } // PushValue - static void PushValue(bool val) { // Compiler treats SQBool as INT. - sq_pushbool(_VM,val); - } // PushValue - static void PushValue(SQChar * val) { - sq_pushstring(_VM,val,-1); - } // PushValue - static void PushValue(SQUserPointer val) { - sq_pushuserpointer(_VM,val); - } // PushValue - static void PushValue(const SQChar * val) { - sq_pushstring(_VM,val,-1); - } // PushValue - static void PushObject(SquirrelObject & so) { - sq_pushobject(_VM,so._o); - } // PushObject - static void Pop(SQInteger nelemstopop) { - sq_pop(_VM,nelemstopop); - } // Pop - - static void PushRootTable(void); - - // Create/bind a function on the table currently on the stack. - static SquirrelObject CreateFunction(SQFUNCTION func,const SQChar * scriptFuncName,const SQChar * typeMask=0); - // Create/bind a function on the table so. typeMask: standard Squirrel types plus: no typemask means no args, "*" means any type of args. - static SquirrelObject CreateFunction(SquirrelObject & so,SQFUNCTION func,const SQChar * scriptFuncName,const SQChar * typeMask=0); - // Create/bind a function to the root table. typeMask: standard Squirrel types plus: no typemask means no args, "*" means any type of args. - static SquirrelObject CreateFunctionGlobal(SQFUNCTION func,const SQChar * scriptFuncName,const SQChar * typeMask=0); - - // This is a helper to correct a difference in referncing new VM:s in - // ref counted versus garbage collected modes. NOTE: Only use after creating - // a VM with: 1 - sq_open() 2 - Creating a ref to the VM (SquirrelObject) - static void DropVMRefIfRefCounted( HSQUIRRELVM v ); - - -private: - static SquirrelObject _vm; // This is a Squirrel reference to the VM - static HSQUIRRELVM _VM; // The raw C++ pointer - static bool _no_vm_ref; // Set if we only keep the raw C++ pointer and no ref - static int _CallState; - static SquirrelObject * _root; // Cached root table if non NULL - static HSQUIRRELVM _sandboxVM; // The sandbox VM (that cannot use bound functions) -}; - - -template -inline BOOL SquirrelObject::ArrayAppend(T item) { - sq_pushobject(SquirrelVM::_VM,GetObjectHandle()); - SquirrelVM::PushValue(item); - BOOL res = sq_arrayappend(SquirrelVM::_VM,-2) == SQ_OK; - sq_pop(SquirrelVM::_VM,1); - return res; -} // ArrayAppend - -#endif //_SQUIRREL_VM_H_ - +#ifndef _SQUIRREL_VM_H_ +#define _SQUIRREL_VM_H_ + +#include "SquirrelObject.h" + +struct SquirrelError { + SquirrelError(); + SquirrelError(const SQChar* s):desc(s){} + const SQChar *desc; +}; + +// This class can hold a reference to a SquirrelVM. It keeps a Squirrel ref +// to the VM to protect it from being deleted while held. +struct SquirrelVMSys { + SquirrelVMSys() { } + ~SquirrelVMSys(); + + void Set( HSQUIRRELVM v ); + void Set( const SquirrelObject& ov ); + void Reset( ){ _vm.Reset(); } + + SquirrelVMSys& operator = (HSQUIRRELVM v){ Set(v); return *this; } + operator HSQUIRRELVM () const; + +protected: + void PushRefVM(HSQUIRRELVM v); + void PopRefVM(); + SquirrelObject _vm; + friend class SquirrelVM; +}; + +// Notes on creating / destroying SquirrelVM:s: +// +// VM:s created through sq_open are special since they create a new +// SQSharedState. That shared state is later shared by any new thread +// or friend VM. sq_close can be used for closing VM:s created through +// sq_open (but not for friend VMs). +// +// Using squirrel references in SquirrelVMSys and SquirrelVM, one must +// make sure that these are all reset if one calls sq_close manually. +// +// When there are no more references to a VM, it is destroyed automatically, +// but the shared state is not! For VM:s created by SquirrelVM, it keeps +// a list of shared states it has created and will destroy them all on +// app shutdown. + +class SquirrelVM { + friend class SquirrelObject; + friend struct SquirrelError; + friend struct SquirrelVMSys; + +public: + // If a VM is passed as arg here, Init will not alter it. Otherwise + // a new VM is created and initialized. A squirrel reference is kept + // while it is the current VM. + static bool Init( HSQUIRRELVM v=NULL ); + + // Initialize with an externally created VM, without adding a ref + // on it. NOTE: This may not be compatible with Set/GetVMSys as + // we're just working with raw pointers here. + static bool InitNoRef( HSQUIRRELVM v ); + static BOOL IsInitialized(){return _VM == NULL?FALSE:TRUE;} + + static void Release(); // Release ref on VM and reset VM pointer + static void Shutdown(){ Release(); } + static void AppFinalShutdown(); // Call when finally shutting down app + + static BOOL Update(); //debugger and maybe GC later + + static SquirrelObject CompileScript(const SQChar *s); + static SquirrelObject CompileBuffer(const SQChar *s,const SQChar * debugInfo=_SC("console_buffer")); + static SquirrelObject RunScript(const SquirrelObject &o,SquirrelObject *_this = NULL); + + static void PrintFunc(HSQUIRRELVM v,const SQChar* s,...); + + static BOOL BeginCall(const SquirrelObject &func); + static BOOL BeginCall(const SquirrelObject &func,SquirrelObject &_this); + + static void PushParam(const SquirrelObject &o); + static void PushParam(const SQChar *s); + static void PushParam(SQInteger n); + static void PushParam(SQFloat f); + static void PushParam(SQUserPointer up); + static void PushParamNull(); + + static SquirrelObject EndCall(); + static SquirrelObject CreateString(const SQChar *s); + static SquirrelObject CreateTable(); + static SquirrelObject CreateArray(int size); + static SquirrelObject CreateInstance(SquirrelObject &oclass); // oclass is an existing class. Create an 'instance' (OT_INSTANCE) of oclass. + static SquirrelObject CreateFunction(SQFUNCTION func); + static SquirrelObject CreateUserData(int size); + + static const SquirrelObject &GetRootTable(); + static HSQUIRRELVM GetVMPtr() { return _VM; } + + // The sandbox VM ptr is one which cannot access functions bound with + // SqPlus. It is suitable for running non-trusted scripts that can only + // access basic functionality. + static void SetSandboxVMPtr(HSQUIRRELVM v) { + _sandboxVM = v; + } // SetSandboxVMPtr + + static HSQUIRRELVM GetSandboxVMPtr() { + return _sandboxVM; + } // GetSandboxVMPtr + + static void GetVMSys(SquirrelVMSys & vmSys) { + vmSys.Set( _vm ); + } // GetVMSys + + static void SetVMSys(const SquirrelVMSys & vmSys) { + Release(); + HSQUIRRELVM v = (HSQUIRRELVM)vmSys; + if( v ) + Init( v ); + } // SetVMSys + + static void PushValue(INT val) { + sq_pushinteger(_VM,val); + } // PushValue + static void PushValue(FLOAT val) { + sq_pushfloat(_VM,val); + } // PushValue + static void PushValue(bool val) { // Compiler treats SQBool as INT. + sq_pushbool(_VM,val); + } // PushValue + static void PushValue(SQChar * val) { + sq_pushstring(_VM,val,-1); + } // PushValue + static void PushValue(SQUserPointer val) { + sq_pushuserpointer(_VM,val); + } // PushValue + static void PushValue(const SQChar * val) { + sq_pushstring(_VM,val,-1); + } // PushValue + static void PushObject(SquirrelObject & so) { + sq_pushobject(_VM,so._o); + } // PushObject + static void Pop(SQInteger nelemstopop) { + sq_pop(_VM,nelemstopop); + } // Pop + + static void PushRootTable(void); + + // Create/bind a function on the table currently on the stack. + static SquirrelObject CreateFunction(SQFUNCTION func,const SQChar * scriptFuncName,const SQChar * typeMask=0); + // Create/bind a function on the table so. typeMask: standard Squirrel types plus: no typemask means no args, "*" means any type of args. + static SquirrelObject CreateFunction(SquirrelObject & so,SQFUNCTION func,const SQChar * scriptFuncName,const SQChar * typeMask=0); + // Create/bind a function to the root table. typeMask: standard Squirrel types plus: no typemask means no args, "*" means any type of args. + static SquirrelObject CreateFunctionGlobal(SQFUNCTION func,const SQChar * scriptFuncName,const SQChar * typeMask=0); + + // This is a helper to correct a difference in referncing new VM:s in + // ref counted versus garbage collected modes. NOTE: Only use after creating + // a VM with: 1 - sq_open() 2 - Creating a ref to the VM (SquirrelObject) + static void DropVMRefIfRefCounted( HSQUIRRELVM v ); + + +private: + static SquirrelObject _vm; // This is a Squirrel reference to the VM + static HSQUIRRELVM _VM; // The raw C++ pointer + static bool _no_vm_ref; // Set if we only keep the raw C++ pointer and no ref + static int _CallState; + static SquirrelObject * _root; // Cached root table if non NULL + static HSQUIRRELVM _sandboxVM; // The sandbox VM (that cannot use bound functions) +}; + + +template +inline BOOL SquirrelObject::ArrayAppend(T item) { + sq_pushobject(SquirrelVM::_VM,GetObjectHandle()); + SquirrelVM::PushValue(item); + BOOL res = sq_arrayappend(SquirrelVM::_VM,-2) == SQ_OK; + sq_pop(SquirrelVM::_VM,1); + return res; +} // ArrayAppend + +#endif //_SQUIRREL_VM_H_ + diff --git a/squirrel_3_0_1_stable/sqplus/changes.txt b/squirrel_3_0_1_stable/_OLD_sqplus/changes.txt similarity index 100% rename from squirrel_3_0_1_stable/sqplus/changes.txt rename to squirrel_3_0_1_stable/_OLD_sqplus/changes.txt diff --git a/squirrel_3_0_1_stable/sqplus/sqplus.cbp b/squirrel_3_0_1_stable/_OLD_sqplus/sqplus.cbp similarity index 100% rename from squirrel_3_0_1_stable/sqplus/sqplus.cbp rename to squirrel_3_0_1_stable/_OLD_sqplus/sqplus.cbp diff --git a/squirrel_3_0_1_stable/sqplus/sqplus.h b/squirrel_3_0_1_stable/_OLD_sqplus/sqplus.h similarity index 97% rename from squirrel_3_0_1_stable/sqplus/sqplus.h rename to squirrel_3_0_1_stable/_OLD_sqplus/sqplus.h index 6116d50ec..fff1633ed 100644 --- a/squirrel_3_0_1_stable/sqplus/sqplus.h +++ b/squirrel_3_0_1_stable/_OLD_sqplus/sqplus.h @@ -1,2327 +1,2327 @@ -// 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_ +// 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_ diff --git a/squirrel_3_0_1_stable/sqplus/sqplus.vcproj b/squirrel_3_0_1_stable/_OLD_sqplus/sqplus.vcproj similarity index 100% rename from squirrel_3_0_1_stable/sqplus/sqplus.vcproj rename to squirrel_3_0_1_stable/_OLD_sqplus/sqplus.vcproj diff --git a/squirrel_3_0_1_stable/sqplus/sqplus.vcxproj b/squirrel_3_0_1_stable/_OLD_sqplus/sqplus.vcxproj similarity index 100% rename from squirrel_3_0_1_stable/sqplus/sqplus.vcxproj rename to squirrel_3_0_1_stable/_OLD_sqplus/sqplus.vcxproj diff --git a/squirrel_3_0_1_stable/sqplus/sqplus.vcxproj.filters b/squirrel_3_0_1_stable/_OLD_sqplus/sqplus.vcxproj.filters similarity index 100% rename from squirrel_3_0_1_stable/sqplus/sqplus.vcxproj.filters rename to squirrel_3_0_1_stable/_OLD_sqplus/sqplus.vcxproj.filters diff --git a/squirrel_3_0_1_stable/sqplus/sqplus.vcxproj.user b/squirrel_3_0_1_stable/_OLD_sqplus/sqplus.vcxproj.user similarity index 100% rename from squirrel_3_0_1_stable/sqplus/sqplus.vcxproj.user rename to squirrel_3_0_1_stable/_OLD_sqplus/sqplus.vcxproj.user diff --git a/squirrel_3_0_1_stable/sqplus/sqplus71.vcproj b/squirrel_3_0_1_stable/_OLD_sqplus/sqplus71.vcproj similarity index 100% rename from squirrel_3_0_1_stable/sqplus/sqplus71.vcproj rename to squirrel_3_0_1_stable/_OLD_sqplus/sqplus71.vcproj diff --git a/squirrel_3_0_1_stable/sqplus/sqplusWin32.h b/squirrel_3_0_1_stable/_OLD_sqplus/sqplusWin32.h similarity index 78% rename from squirrel_3_0_1_stable/sqplus/sqplusWin32.h rename to squirrel_3_0_1_stable/_OLD_sqplus/sqplusWin32.h index bf46fd6cf..98741bcfe 100644 --- a/squirrel_3_0_1_stable/sqplus/sqplusWin32.h +++ b/squirrel_3_0_1_stable/_OLD_sqplus/sqplusWin32.h @@ -1,7 +1,7 @@ -#ifndef _SQ_PLUS_WIN32_H_ -#define _SQ_PLUS_WIN32_H_ - -#include "sqplus.h" -#include "SquirrelBindingsUtilsWin32.h" - +#ifndef _SQ_PLUS_WIN32_H_ +#define _SQ_PLUS_WIN32_H_ + +#include "sqplus.h" +#include "SquirrelBindingsUtilsWin32.h" + #endif //_SQ_PLUS_WIN32_H_ \ No newline at end of file diff --git a/squirrel_3_0_1_stable/sqrat/sqmodule.h b/squirrel_3_0_1_stable/sqrat/sqmodule.h new file mode 100644 index 000000000..7f1670eb1 --- /dev/null +++ b/squirrel_3_0_1_stable/sqrat/sqmodule.h @@ -0,0 +1,199 @@ +// +// SqModule: API used to communicate with and register squirrel modules +// + +// +// Copyright (c) 2009 Brandon Jones +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would be +// appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, and must not be +// misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source +// distribution. +// + +#if !defined(_SQ_MODULE_H_) +#define _SQ_MODULE_H_ + +#include "squirrel.h" + +#ifdef __cplusplus +extern "C" { +#endif + + /* HSQAPI */ + /* + Allows modules to interface with squirrel's C api without linking to the squirrel library + If new functions are added to the Squirrel API, they should be added here too + */ + typedef struct { + /*vm*/ + HSQUIRRELVM (*open)(SQInteger initialstacksize); + HSQUIRRELVM (*newthread)(HSQUIRRELVM friendvm, SQInteger initialstacksize); + void (*seterrorhandler)(HSQUIRRELVM v); + void (*close)(HSQUIRRELVM v); + void (*setforeignptr)(HSQUIRRELVM v,SQUserPointer p); + SQUserPointer (*getforeignptr)(HSQUIRRELVM v); +#if SQUIRREL_VERSION_NUMBER >= 300 + void (*setprintfunc)(HSQUIRRELVM v, SQPRINTFUNCTION printfunc, SQPRINTFUNCTION); +#else + void (*setprintfunc)(HSQUIRRELVM v, SQPRINTFUNCTION printfunc); +#endif + SQPRINTFUNCTION (*getprintfunc)(HSQUIRRELVM v); + SQRESULT (*suspendvm)(HSQUIRRELVM v); + SQRESULT (*wakeupvm)(HSQUIRRELVM v,SQBool resumedret,SQBool retval,SQBool raiseerror,SQBool throwerror); + SQInteger (*getvmstate)(HSQUIRRELVM v); + + /*compiler*/ + SQRESULT (*compile)(HSQUIRRELVM v,SQLEXREADFUNC read,SQUserPointer p,const SQChar *sourcename,SQBool raiseerror); + SQRESULT (*compilebuffer)(HSQUIRRELVM v,const SQChar *s,SQInteger size,const SQChar *sourcename,SQBool raiseerror); + void (*enabledebuginfo)(HSQUIRRELVM v, SQBool enable); + void (*notifyallexceptions)(HSQUIRRELVM v, SQBool enable); + void (*setcompilererrorhandler)(HSQUIRRELVM v,SQCOMPILERERROR f); + + /*stack operations*/ + void (*push)(HSQUIRRELVM v,SQInteger idx); + void (*pop)(HSQUIRRELVM v,SQInteger nelemstopop); + void (*poptop)(HSQUIRRELVM v); + void (*remove)(HSQUIRRELVM v,SQInteger idx); + SQInteger (*gettop)(HSQUIRRELVM v); + void (*settop)(HSQUIRRELVM v,SQInteger newtop); +#if SQUIRREL_VERSION_NUMBER >= 300 + SQRESULT (*reservestack)(HSQUIRRELVM v,SQInteger nsize); +#else + void (*reservestack)(HSQUIRRELVM v,SQInteger nsize); +#endif + SQInteger (*cmp)(HSQUIRRELVM v); + void (*move)(HSQUIRRELVM dest,HSQUIRRELVM src,SQInteger idx); + + /*object creation handling*/ + SQUserPointer (*newuserdata)(HSQUIRRELVM v,SQUnsignedInteger size); + void (*newtable)(HSQUIRRELVM v); + void (*newarray)(HSQUIRRELVM v,SQInteger size); + void (*newclosure)(HSQUIRRELVM v,SQFUNCTION func,SQUnsignedInteger nfreevars); + SQRESULT (*setparamscheck)(HSQUIRRELVM v,SQInteger nparamscheck,const SQChar *typemask); + SQRESULT (*bindenv)(HSQUIRRELVM v,SQInteger idx); + void (*pushstring)(HSQUIRRELVM v,const SQChar *s,SQInteger len); + void (*pushfloat)(HSQUIRRELVM v,SQFloat f); + void (*pushinteger)(HSQUIRRELVM v,SQInteger n); + void (*pushbool)(HSQUIRRELVM v,SQBool b); + void (*pushuserpointer)(HSQUIRRELVM v,SQUserPointer p); + void (*pushnull)(HSQUIRRELVM v); + SQObjectType (*gettype)(HSQUIRRELVM v,SQInteger idx); + SQInteger (*getsize)(HSQUIRRELVM v,SQInteger idx); + SQRESULT (*getbase)(HSQUIRRELVM v,SQInteger idx); + SQBool (*instanceof)(HSQUIRRELVM v); +#if SQUIRREL_VERSION_NUMBER >= 300 + SQRESULT (*tostring)(HSQUIRRELVM v,SQInteger idx); +#else + void (*tostring)(HSQUIRRELVM v,SQInteger idx); +#endif + void (*tobool)(HSQUIRRELVM v, SQInteger idx, SQBool *b); + SQRESULT (*getstring)(HSQUIRRELVM v,SQInteger idx,const SQChar **c); + SQRESULT (*getinteger)(HSQUIRRELVM v,SQInteger idx,SQInteger *i); + SQRESULT (*getfloat)(HSQUIRRELVM v,SQInteger idx,SQFloat *f); + SQRESULT (*getbool)(HSQUIRRELVM v,SQInteger idx,SQBool *b); + SQRESULT (*getthread)(HSQUIRRELVM v,SQInteger idx,HSQUIRRELVM *thread); + SQRESULT (*getuserpointer)(HSQUIRRELVM v,SQInteger idx,SQUserPointer *p); + SQRESULT (*getuserdata)(HSQUIRRELVM v,SQInteger idx,SQUserPointer *p,SQUserPointer *typetag); + SQRESULT (*settypetag)(HSQUIRRELVM v,SQInteger idx,SQUserPointer typetag); + SQRESULT (*gettypetag)(HSQUIRRELVM v,SQInteger idx,SQUserPointer *typetag); + void (*setreleasehook)(HSQUIRRELVM v,SQInteger idx,SQRELEASEHOOK hook); + SQChar* (*getscratchpad)(HSQUIRRELVM v,SQInteger minsize); + SQRESULT (*getclosureinfo)(HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger *nparams,SQUnsignedInteger *nfreevars); + SQRESULT (*setnativeclosurename)(HSQUIRRELVM v,SQInteger idx,const SQChar *name); + SQRESULT (*setinstanceup)(HSQUIRRELVM v, SQInteger idx, SQUserPointer p); + SQRESULT (*getinstanceup)(HSQUIRRELVM v, SQInteger idx, SQUserPointer *p,SQUserPointer typetag); + SQRESULT (*setclassudsize)(HSQUIRRELVM v, SQInteger idx, SQInteger udsize); + SQRESULT (*newclass)(HSQUIRRELVM v,SQBool hasbase); + SQRESULT (*createinstance)(HSQUIRRELVM v,SQInteger idx); + SQRESULT (*setattributes)(HSQUIRRELVM v,SQInteger idx); + SQRESULT (*getattributes)(HSQUIRRELVM v,SQInteger idx); + SQRESULT (*getclass)(HSQUIRRELVM v,SQInteger idx); + void (*weakref)(HSQUIRRELVM v,SQInteger idx); + SQRESULT (*getdefaultdelegate)(HSQUIRRELVM v,SQObjectType t); + + /*object manipulation*/ + void (*pushroottable)(HSQUIRRELVM v); + void (*pushregistrytable)(HSQUIRRELVM v); + void (*pushconsttable)(HSQUIRRELVM v); + SQRESULT (*setroottable)(HSQUIRRELVM v); + SQRESULT (*setconsttable)(HSQUIRRELVM v); + SQRESULT (*newslot)(HSQUIRRELVM v, SQInteger idx, SQBool bstatic); + SQRESULT (*deleteslot)(HSQUIRRELVM v,SQInteger idx,SQBool pushval); + SQRESULT (*set)(HSQUIRRELVM v,SQInteger idx); + SQRESULT (*get)(HSQUIRRELVM v,SQInteger idx); + SQRESULT (*rawget)(HSQUIRRELVM v,SQInteger idx); + SQRESULT (*rawset)(HSQUIRRELVM v,SQInteger idx); + SQRESULT (*rawdeleteslot)(HSQUIRRELVM v,SQInteger idx,SQBool pushval); + SQRESULT (*arrayappend)(HSQUIRRELVM v,SQInteger idx); + SQRESULT (*arraypop)(HSQUIRRELVM v,SQInteger idx,SQBool pushval); + SQRESULT (*arrayresize)(HSQUIRRELVM v,SQInteger idx,SQInteger newsize); + SQRESULT (*arrayreverse)(HSQUIRRELVM v,SQInteger idx); + SQRESULT (*arrayremove)(HSQUIRRELVM v,SQInteger idx,SQInteger itemidx); + SQRESULT (*arrayinsert)(HSQUIRRELVM v,SQInteger idx,SQInteger destpos); + SQRESULT (*setdelegate)(HSQUIRRELVM v,SQInteger idx); + SQRESULT (*getdelegate)(HSQUIRRELVM v,SQInteger idx); + SQRESULT (*clone)(HSQUIRRELVM v,SQInteger idx); + SQRESULT (*setfreevariable)(HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger nval); + SQRESULT (*next)(HSQUIRRELVM v,SQInteger idx); + SQRESULT (*getweakrefval)(HSQUIRRELVM v,SQInteger idx); + SQRESULT (*clear)(HSQUIRRELVM v,SQInteger idx); + + /*calls*/ + SQRESULT (*call)(HSQUIRRELVM v,SQInteger params,SQBool retval,SQBool raiseerror); + SQRESULT (*resume)(HSQUIRRELVM v,SQBool retval,SQBool raiseerror); + const SQChar* (*getlocal)(HSQUIRRELVM v,SQUnsignedInteger level,SQUnsignedInteger idx); + const SQChar* (*getfreevariable)(HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger nval); + SQRESULT (*throwerror)(HSQUIRRELVM v,const SQChar *err); + void (*reseterror)(HSQUIRRELVM v); + void (*getlasterror)(HSQUIRRELVM v); + + /*raw object handling*/ + SQRESULT (*getstackobj)(HSQUIRRELVM v,SQInteger idx,HSQOBJECT *po); + void (*pushobject)(HSQUIRRELVM v,HSQOBJECT obj); + void (*addref)(HSQUIRRELVM v,HSQOBJECT *po); + SQBool (*release)(HSQUIRRELVM v,HSQOBJECT *po); + void (*resetobject)(HSQOBJECT *po); + const SQChar* (*objtostring)(const HSQOBJECT *o); + SQBool (*objtobool)(const HSQOBJECT *o); + SQInteger (*objtointeger)(const HSQOBJECT *o); + SQFloat (*objtofloat)(const HSQOBJECT *o); + SQRESULT (*getobjtypetag)(const HSQOBJECT *o,SQUserPointer * typetag); + + /*GC*/ + SQInteger (*collectgarbage)(HSQUIRRELVM v); + + /*serialization*/ + SQRESULT (*writeclosure)(HSQUIRRELVM vm,SQWRITEFUNC writef,SQUserPointer up); + SQRESULT (*readclosure)(HSQUIRRELVM vm,SQREADFUNC readf,SQUserPointer up); + + /*mem allocation*/ + void* (*malloc)(SQUnsignedInteger size); + void* (*realloc)(void* p,SQUnsignedInteger oldsize,SQUnsignedInteger newsize); + void (*free)(void *p,SQUnsignedInteger size); + + /*debug*/ + SQRESULT (*stackinfos)(HSQUIRRELVM v,SQInteger level,SQStackInfos *si); + void (*setdebughook)(HSQUIRRELVM v); + } sq_api; + typedef sq_api* HSQAPI; + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*_SQ_MODULE_H_*/ diff --git a/squirrel_3_0_1_stable/sqrat/sqrat.h b/squirrel_3_0_1_stable/sqrat/sqrat.h new file mode 100644 index 000000000..70159cdb1 --- /dev/null +++ b/squirrel_3_0_1_stable/sqrat/sqrat.h @@ -0,0 +1,41 @@ +// +// Sqrat: Squirrel C++ Binding Utility +// + +// +// Copyright (c) 2009 Brandon Jones +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would be +// appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, and must not be +// misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source +// distribution. +// + +#if !defined(_SCRAT_MAIN_H_) +#define _SCRAT_MAIN_H_ + +#include + +#include "sqrat/sqratTable.h" +#include "sqrat/sqratClass.h" +#include "sqrat/sqratFunction.h" +#include "sqrat/sqratConst.h" +#include "sqrat/sqratUtil.h" +#include "sqrat/sqratScript.h" +#include "sqrat/sqratArray.h" + +#endif diff --git a/squirrel_3_0_1_stable/sqrat/sqrat/sqratAllocator.h b/squirrel_3_0_1_stable/sqrat/sqrat/sqratAllocator.h new file mode 100644 index 000000000..3fa7b707d --- /dev/null +++ b/squirrel_3_0_1_stable/sqrat/sqrat/sqratAllocator.h @@ -0,0 +1,134 @@ +// +// SqratAllocator: Custom Class Allocation/Deallocation +// + +// +// Copyright (c) 2009 Brandon Jones +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would be +// appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, and must not be +// misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source +// distribution. +// + +#if !defined(_SCRAT_ALLOCATOR_H_) +#define _SCRAT_ALLOCATOR_H_ + +#include +#include + +#include "sqratObject.h" + +namespace Sqrat { + +// +// DefaultAllocator +// + +template +class DefaultAllocator { +public: + static SQInteger New(HSQUIRRELVM vm) { + C* instance = new C(); + sq_setinstanceup(vm, 1, instance); + sq_setreleasehook(vm, 1, &Delete); + return 0; + } + + static SQInteger Copy(HSQUIRRELVM vm, SQInteger idx, const void* value) { + C* instance = new C(*static_cast(value)); + sq_setinstanceup(vm, idx, instance); + sq_setreleasehook(vm, idx, &Delete); + return 0; + } + + static SQInteger Delete(SQUserPointer ptr, SQInteger size) { + C* instance = reinterpret_cast(ptr); + delete instance; + return 0; + } +}; + +// +// NoConstructorAllocator +// + +class NoConstructor { +public: + static SQInteger New(HSQUIRRELVM) { + return 0; + } + static SQInteger Copy(HSQUIRRELVM, SQInteger, const void*) { + return 0; + } + static SQInteger Delete(SQUserPointer, SQInteger) { + return 0; + } +}; + +// +// CopyOnly +// + +template +class CopyOnly { +public: + static SQInteger New(HSQUIRRELVM) { + return 0; + } + static SQInteger Copy(HSQUIRRELVM vm, SQInteger idx, const void* value) { + C* instance = new C(*static_cast(value)); + sq_setinstanceup(vm, idx, instance); + sq_setreleasehook(vm, idx, &Delete); + return 0; + } + static SQInteger Delete(SQUserPointer ptr, SQInteger size) { + void* instance = reinterpret_cast(ptr); + delete instance; + return 0; + } +}; + + +// +// NoCopy +// + +template +class NoCopy { +public: + static SQInteger New(HSQUIRRELVM vm) { + C* instance = new C(); + sq_setinstanceup(vm, 1, instance); + sq_setreleasehook(vm, 1, &Delete); + return 0; + } + + static SQInteger Copy(HSQUIRRELVM vm, SQInteger idx, const void* value) { + return 0; + } + + static SQInteger Delete(SQUserPointer ptr, SQInteger size) { + C* instance = reinterpret_cast(ptr); + delete instance; + return 0; + } +}; + +} + +#endif diff --git a/squirrel_3_0_1_stable/sqrat/sqrat/sqratArray.h b/squirrel_3_0_1_stable/sqrat/sqrat/sqratArray.h new file mode 100644 index 000000000..67bf4f4b6 --- /dev/null +++ b/squirrel_3_0_1_stable/sqrat/sqrat/sqratArray.h @@ -0,0 +1,210 @@ + +// +// SqratArray: Array Binding +// + +// +// Copyright 2011 Alston Chen +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would be +// appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, and must not be +// misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source +// distribution. +// + + +#if !defined(_SCRAT_ARRAY_H_) +#define _SCRAT_ARRAY_H_ + +#include +#include + +#include "sqratObject.h" +#include "sqratFunction.h" +#include "sqratGlobalMethods.h" + +namespace Sqrat { + + class ArrayBase : public Object { + public: + ArrayBase(HSQUIRRELVM v = DefaultVM::Get()) : Object(v, true) { + } + + ArrayBase(const Object& obj) : Object(obj) { + } + + // Bind a Table or Class to the Array (Can be used to facilitate Namespaces) + // Note: Bind cannot be called "inline" like other functions because it introduces order-of-initialization bugs. + void Bind(const SQInteger index, Object& obj) { + sq_pushobject(vm, GetObject()); + sq_pushinteger(vm, index); + sq_pushobject(vm, obj.GetObject()); + sq_set(vm, -3); + sq_pop(vm,1); // pop array + } + + // Bind a raw Squirrel closure to the Array + ArrayBase& SquirrelFunc(const SQInteger index, SQFUNCTION func) { + sq_pushobject(vm, GetObject()); + sq_pushinteger(vm, index); + sq_newclosure(vm, func, 0); + sq_set(vm, -3); + sq_pop(vm,1); // pop array + return *this; + } + + // + // Variable Binding + // + + template + ArrayBase& SetValue(const SQInteger index, const V& val) { + sq_pushobject(vm, GetObject()); + sq_pushinteger(vm, index); + PushVar(vm, val); + sq_set(vm, -3); + sq_pop(vm,1); // pop array + return *this; + } + + template + ArrayBase& SetInstance(const SQInteger index, V* val) { + BindInstance(index, false); + return *this; + } + + template + ArrayBase& Func(const SQInteger index, F method) { + BindFunc(index, &method, sizeof(method), SqGlobalFunc(method)); + return *this; + } + + //template + //ArrayBase& Overload(const SQChar* name, F method) { + // BindOverload(name, &method, sizeof(method), SqGlobalFunc(method), SqOverloadFunc(method), SqGetArgCount(method)); + // return *this; + //} + + // + // Function Calls + // + + Function GetFunction(const SQInteger index) { + HSQOBJECT funcObj; + sq_pushobject(vm, GetObject()); + sq_pushinteger(vm, index); + if(SQ_FAILED(sq_get(vm, -2))) { + sq_pushnull(vm); + } + sq_getstackobj(vm, -1, &funcObj); + Function ret(vm, GetObject(), funcObj); + sq_pop(vm, 2); + + return ret; + } + + // + // Array manipulation + // + + template + ArrayBase& Append(const V& val) { + sq_pushobject(vm, GetObject()); + PushVar(vm, val); + sq_arrayappend(vm, -2); + sq_pop(vm,1); // pop array + return *this; + } + + template + ArrayBase& Append(V* val) { + sq_pushobject(vm, GetObject()); + PushVar(vm, val); + sq_arrayappend(vm, -2); + sq_pop(vm,1); // pop array + return *this; + } + + template + ArrayBase& Insert(const SQInteger destpos, const V& val) { + sq_pushobject(vm, GetObject()); + PushVar(vm, val); + sq_arrayinsert(vm, -2, destpos); + sq_pop(vm,1); // pop array + return *this; + } + + template + ArrayBase& Insert(const SQInteger destpos, V* val) { + sq_pushobject(vm, GetObject()); + PushVar(vm, val); + sq_arrayinsert(vm, -2, destpos); + sq_pop(vm,1); // pop array + return *this; + } + + Object Pop() { + HSQOBJECT slotObj; + sq_pushobject(vm, GetObject()); + if(SQ_FAILED(sq_arraypop(vm, -1, true))) { + sq_pop(vm, 1); + return Object(); // Return a NULL object + } else { + sq_getstackobj(vm, -1, &slotObj); + Object ret(slotObj, vm); + sq_pop(vm, 2); + return ret; + } + } + + ArrayBase& Remove(const SQInteger itemidx) { + sq_pushobject(vm, GetObject()); + sq_arrayremove(vm, -1, itemidx); + sq_pop(vm,1); // pop array + return *this; + } + + ArrayBase& Resize(const SQInteger newsize) { + sq_pushobject(vm, GetObject()); + sq_arrayresize(vm, -1, newsize); + sq_pop(vm,1); // pop array + return *this; + } + + ArrayBase& Reverse() { + sq_pushobject(vm, GetObject()); + sq_arrayreverse(vm, -1); + sq_pop(vm,1); // pop array + return *this; + } + }; + + class Array : public ArrayBase { + public: + Array(HSQUIRRELVM v = DefaultVM::Get(), const SQInteger size = 0) : ArrayBase(v) { + sq_newarray(vm, size); + sq_getstackobj(vm,-1,&obj); + sq_addref(vm, &obj); + sq_pop(vm,1); + } + + Array(const Object& obj) : ArrayBase(obj) { + } + }; +} + +#endif diff --git a/squirrel_3_0_1_stable/sqrat/sqrat/sqratClass.h b/squirrel_3_0_1_stable/sqrat/sqrat/sqratClass.h new file mode 100644 index 000000000..7c0302458 --- /dev/null +++ b/squirrel_3_0_1_stable/sqrat/sqrat/sqratClass.h @@ -0,0 +1,415 @@ + +// +// SqratClass: Class Binding +// + +// +// Copyright (c) 2009 Brandon Jones +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would be +// appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, and must not be +// misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source +// distribution. +// + +#if !defined(_SCRAT_CLASS_H_) +#define _SCRAT_CLASS_H_ + +#include +#include + +#include "sqratObject.h" +#include "sqratClassType.h" +#include "sqratMemberMethods.h" +#include "sqratAllocator.h" + +namespace Sqrat +{ + +/** + @tparam C class type to expose + @tparam A allocator to use when instantiating and destroying class instances in Squirrel + + @remarks + DefaultAllocator is used if no allocator is specified. This should be sufficent for most classes + but if specific behavior is desired it can be overridden. If the class should not be instantiated from + Squirrel the NoConstructor allocator may be used. +*/ +/// Exposes a C++ class to Squirrel +template > +class Class : public Object +{ +public: + /** + @param v Squirrel virtual machine to bind to + */ + /// Constructor + Class(HSQUIRRELVM v = DefaultVM::Get(), bool createClass = true) : Object(v, false) { + if(createClass && !ClassType::Initialized(v)) { + HSQOBJECT& classObj = ClassType::ClassObject(v); + sq_resetobject(&classObj); + + sq_newclass(vm, false); + sq_getstackobj(vm, -1, &classObj); + sq_addref(vm, &classObj); // must addref before the pop! + sq_pop(vm, 1); + + InitClass(); + ClassType::Initialized(v) = true; + } + } + + ~Class() { + /*ClassType::deleteClassTypeData(vm);*/ + /* it seems the original design by Tojo was that ClassType objects are static + so they presist with the lifetime of the program; so we cannot delete the + ClassType object here */ + } + + /// Get the Squirrel Object for this Class (const) + virtual HSQOBJECT GetObject() const { + return ClassType::ClassObject(vm); + } + + /// Get the Squirrel Object for this Class (ref) + virtual HSQOBJECT& GetObject() { + return ClassType::ClassObject(vm); + } + +public: + // + // Variable Binding + // + + /** + @param name name of the static slot + @param var value to assign + */ + /// Assign a static class slot a value + template + Class& SetStaticValue(const SQChar* name, const V& val) { + BindValue(name, val, true); + return *this; + } + + /** + @param name name of the slot + @param var value to assign + */ + /// Assign a class slot a value + template + Class& SetValue(const SQChar* name, const V& val) { + BindValue(name, val, false); + return *this; + } + + /** + @param name name of the variable as it will appear in Squirrel + @param var variable to bind + */ + /// Bind a class variable + template + Class& Var(const SQChar* name, V C::* var) { + // Add the getter + BindAccessor(name, &var, sizeof(var), &sqDefaultGet, ClassType::GetTable(vm)); + + // Add the setter + BindAccessor(name, &var, sizeof(var), &sqDefaultSet, ClassType::SetTable(vm)); + + return *this; + } + + /// Bind a class property (variable accessed via a setter and getter) + template + Class& Prop(const SQChar* name, V (C::*getMethod)() const, void (C::*setMethod)(const V&)) { + if(getMethod != NULL) { + // Add the getter + BindAccessor(name, &getMethod, sizeof(getMethod), SqMemberFunc(getMethod), ClassType::GetTable(vm)); + } + + if(setMethod != NULL) { + // Add the setter + BindAccessor(name, &setMethod, sizeof(setMethod), SqMemberFunc(setMethod), ClassType::SetTable(vm)); + } + + return *this; + } + + /// Bind a class property (variable accessed via a setter and getter) + template + Class& Prop(const SQChar* name, V (C::*getMethod)(), void (C::*setMethod)(V)) { + if(getMethod != NULL) { + // Add the getter + BindAccessor(name, &getMethod, sizeof(getMethod), SqMemberFunc(getMethod), ClassType::GetTable(vm)); + } + + if(setMethod != NULL) { + // Add the setter + BindAccessor(name, &setMethod, sizeof(setMethod), SqMemberFunc(setMethod), ClassType::SetTable(vm)); + } + + return *this; + } + + /// Bind a read only class property (variable accessed via a getter) + template + Class& Prop(const SQChar* name, V (C::*getMethod)() const) { + // Add the getter + BindAccessor(name, &getMethod, sizeof(getMethod), SqMemberFunc(getMethod), ClassType::GetTable(vm)); + + return *this; + } + + /// Bind a read only class property (variable accessed via a getter) + template + Class& Prop(const SQChar* name, V (C::*getMethod)()) { + // Add the getter + BindAccessor(name, &getMethod, sizeof(getMethod), SqMemberFunc(getMethod), ClassType::GetTable(vm)); + + return *this; + } + + // TODO: Handle static instance vars + + // + // Function Binding + // + + template + Class& Func(const SQChar* name, F method) { + BindFunc(name, &method, sizeof(method), SqMemberFunc(method)); + return *this; + } + + template + Class& Overload(const SQChar* name, F method) { + BindOverload(name, &method, sizeof(method), SqMemberFunc(method), SqOverloadFunc(method), SqGetArgCount(method)); + return *this; + } + + template + Class& GlobalFunc(const SQChar* name, F method) { + BindFunc(name, &method, sizeof(method), SqMemberGlobalFunc(method)); + return *this; + } + + template + Class& StaticFunc(const SQChar* name, F method) { + BindFunc(name, &method, sizeof(method), SqGlobalFunc(method)); + return *this; + } + + template + Class& SquirrelFunc(const SQChar* name, SQFUNCTION func) { + sq_pushobject(vm, ClassType::ClassObject(vm)); + sq_pushstring(vm, name, -1); + sq_newclosure(vm, func, 0); + sq_newslot(vm, -3, false); + sq_pop(vm, 1); // pop table + + return *this; + } + + // + // Function Calls + // + + Function GetFunction(const SQChar* name) { + HSQOBJECT funcObj; + sq_pushobject(vm, ClassType::ClassObject(vm)); + sq_pushstring(vm, name, -1); + if(SQ_FAILED(sq_get(vm, -2))) { + sq_pushnull(vm); + } + sq_getstackobj(vm, -1, &funcObj); + sq_pop(vm, 2); + + return Function(vm, ClassType::ClassObject(vm), funcObj); + } + +protected: + static SQInteger ClassWeakref(HSQUIRRELVM vm) { + sq_weakref(vm, -1); + return 1; + } + + // Initialize the required data structure for the class + void InitClass() { + ClassType::CopyFunc(vm) = &A::Copy; + + // push the class + sq_pushobject(vm, ClassType::ClassObject(vm)); + + // add the default constructor + sq_pushstring(vm,_SC("constructor"), -1); + sq_newclosure(vm, &A::New, 0); + sq_newslot(vm, -3, false); + + // add the set table (static) + HSQOBJECT& setTable = ClassType::SetTable(vm); + sq_resetobject(&setTable); + sq_pushstring(vm,_SC("__setTable"), -1); + sq_newtable(vm); + sq_getstackobj(vm, -1, &setTable); + sq_addref(vm, &setTable); + sq_newslot(vm, -3, true); + + // add the get table (static) + HSQOBJECT& getTable = ClassType::GetTable(vm); + sq_resetobject(&getTable); + sq_pushstring(vm,_SC("__getTable"), -1); + sq_newtable(vm); + sq_getstackobj(vm, -1, &getTable); + sq_addref(vm, &getTable); + sq_newslot(vm, -3, true); + + // override _set + sq_pushstring(vm, _SC("_set"), -1); + sq_pushobject(vm, setTable); // Push the set table as a free variable + sq_newclosure(vm, &sqVarSet, 1); + sq_newslot(vm, -3, false); + + // override _get + sq_pushstring(vm, _SC("_get"), -1); + sq_pushobject(vm, getTable); // Push the get table as a free variable + sq_newclosure(vm, &sqVarGet, 1); + sq_newslot(vm, -3, false); + + // add weakref (apparently not provided by default) + sq_pushstring(vm, _SC("weakref"), -1); + sq_newclosure(vm, &Class::ClassWeakref, 0); + sq_newslot(vm, -3, false); + + // pop the class + sq_pop(vm, 1); + } + + // Helper function used to bind getters and setters + inline void BindAccessor(const SQChar* name, void* var, size_t varSize, SQFUNCTION func, HSQOBJECT table) { + // Push the get or set table + sq_pushobject(vm, table); + sq_pushstring(vm, name, -1); + + // Push the variable offset as a free variable + SQUserPointer varPtr = sq_newuserdata(vm, static_cast(varSize)); + memcpy(varPtr, var, varSize); + + // Create the accessor function + sq_newclosure(vm, func, 1); + + // Add the accessor to the table + sq_newslot(vm, -3, false); + + // Pop get/set table + sq_pop(vm, 1); + } + +}; + +/** + @tparam C class type to expose + @tparam B base class type (must already be bound) + @tparam A allocator to use when instantiating and destroying class instances in Squirrel + + @remarks + DefaultAllocator is used if no allocator is specified. This should be sufficent for most classes + but if specific behavior is desired it can be overridden. If the class should not be instantiated from + Squirrel the NoConstructor allocator may be used. + + @remarks + Classes in Squirrel are single-inheritance only, and as such Sqrat only allows for single inheritance as well +*/ +/// Exposes a C++ class with a base class to Squirrel +template > +class DerivedClass : public Class +{ +public: + DerivedClass(HSQUIRRELVM v = DefaultVM::Get()) : Class(v, false) { + if(!ClassType::Initialized(v)) { + HSQOBJECT& classObj = ClassType::ClassObject(v); + sq_resetobject(&classObj); + + sq_pushobject(v, ClassType::ClassObject(v)); + sq_newclass(v, true); + sq_getstackobj(v, -1, &classObj); + sq_addref(v, &classObj); // must addref before the pop! + sq_pop(v, 1); + + InitDerivedClass(v); + ClassType::Initialized(v) = true; + } + } + +protected: + void InitDerivedClass(HSQUIRRELVM vm) { + ClassType::CopyFunc(vm) = &A::Copy; + + // push the class + sq_pushobject(vm, ClassType::ClassObject(vm)); + + // add the default constructor + sq_pushstring(vm,_SC("constructor"), -1); + sq_newclosure(vm, &A::New, 0); + sq_newslot(vm, -3, false); + + // clone the base classes set table (static) + HSQOBJECT& setTable = ClassType::SetTable(vm); + sq_resetobject(&setTable); + sq_pushobject(vm, ClassType::SetTable(vm)); + sq_pushstring(vm,_SC("__setTable"), -1); + sq_clone(vm, -2); + sq_remove(vm, -3); + sq_getstackobj(vm, -1, &setTable); + sq_addref(vm, &setTable); + sq_newslot(vm, -3, true); + + // clone the base classes get table (static) + HSQOBJECT& getTable = ClassType::GetTable(vm); + sq_resetobject(&getTable); + sq_pushobject(vm, ClassType::GetTable(vm)); + sq_pushstring(vm,_SC("__getTable"), -1); + sq_clone(vm, -2); + sq_remove(vm, -3); + sq_getstackobj(vm, -1, &getTable); + sq_addref(vm, &getTable); + sq_newslot(vm, -3, true); + + // override _set + sq_pushstring(vm, _SC("_set"), -1); + sq_pushobject(vm, setTable); // Push the set table as a free variable + sq_newclosure(vm, sqVarSet, 1); + sq_newslot(vm, -3, false); + + // override _get + sq_pushstring(vm, _SC("_get"), -1); + sq_pushobject(vm, getTable); // Push the get table as a free variable + sq_newclosure(vm, sqVarGet, 1); + sq_newslot(vm, -3, false); + + // add weakref (apparently not provided by default) + sq_pushstring(vm, _SC("weakref"), -1); + sq_newclosure(vm, &Class::ClassWeakref, 0); + sq_newslot(vm, -3, false); + + // pop the class + sq_pop(vm, 1); + } +}; + +} + +#endif diff --git a/squirrel_3_0_1_stable/sqrat/sqrat/sqratClassType.h b/squirrel_3_0_1_stable/sqrat/sqrat/sqratClassType.h new file mode 100644 index 000000000..35dfcc447 --- /dev/null +++ b/squirrel_3_0_1_stable/sqrat/sqrat/sqratClassType.h @@ -0,0 +1,126 @@ + +// +// SqratClassType: Type Translators +// + +// +// Copyright (c) 2009 Brandon Jones +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would be +// appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, and must not be +// misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source +// distribution. +// + +#if !defined(_SCRAT_CLASSTYPE_H_) +#define _SCRAT_CLASSTYPE_H_ + +#include +#include + +namespace Sqrat +{ + +// +// ClassType +// + +// Get the Copy Function for this Class +typedef SQInteger (*COPYFUNC)(HSQUIRRELVM, SQInteger, const void*); + +struct ClassTypeData { + bool initialized; + HSQOBJECT classObj; + HSQOBJECT getTable; + HSQOBJECT setTable; + COPYFUNC copyFunc; + ClassTypeData(): initialized(false) {} +}; + +template +struct ClassType { + + static std::map< HSQUIRRELVM, ClassTypeData > s_classTypeDataMap; + + static inline ClassTypeData& getClassTypeData(HSQUIRRELVM vm) { + //TODO: use mutex to lock s_classTypeDataMap in multithreaded environment + return s_classTypeDataMap[vm]; + } + + static inline bool hasClassTypeData(HSQUIRRELVM vm) { + //TODO: use mutex to lock s_classTypeDataMap in multithreaded environment + return (s_classTypeDataMap.find(vm) != s_classTypeDataMap.end()); + } + + static inline void deleteClassTypeData(HSQUIRRELVM vm) { + //TODO: use mutex to lock s_classTypeDataMap in multithreaded environment + std::map< HSQUIRRELVM, ClassTypeData >::iterator it = s_classTypeDataMap.find(vm); + if(it != s_classTypeDataMap.end()) { + s_classTypeDataMap.erase(it); + } + } + + // Get the Squirrel Object for this Class + static inline HSQOBJECT& ClassObject(HSQUIRRELVM vm) { + return getClassTypeData(vm).classObj; + } + + // Get the Get Table for this Class + static inline HSQOBJECT& GetTable(HSQUIRRELVM vm) { + return getClassTypeData(vm).getTable; + } + + // Get the Set Table for this Class + static inline HSQOBJECT& SetTable(HSQUIRRELVM vm) { + return getClassTypeData(vm).setTable; + } + + static inline COPYFUNC& CopyFunc(HSQUIRRELVM vm) { + return getClassTypeData(vm).copyFunc; + } + + static inline bool& Initialized(HSQUIRRELVM vm) { + return getClassTypeData(vm).initialized; + } + + static void PushInstance(HSQUIRRELVM vm, C* ptr) { + sq_pushobject(vm, ClassObject(vm)); + sq_createinstance(vm, -1); + sq_remove(vm, -2); + sq_setinstanceup(vm, -1, ptr); + } + + static void PushInstanceCopy(HSQUIRRELVM vm, C& value) { + sq_pushobject(vm, ClassObject(vm)); + sq_createinstance(vm, -1); + sq_remove(vm, -2); + CopyFunc(vm)(vm, -1, &value); + } + + static C* GetInstance(HSQUIRRELVM vm, SQInteger idx) { + C* ptr = NULL; + sq_getinstanceup(vm, idx, (SQUserPointer*)&ptr, NULL); + return ptr; + } +}; + +template +std::map< HSQUIRRELVM, ClassTypeData > ClassType::s_classTypeDataMap; + +} + +#endif diff --git a/squirrel_3_0_1_stable/sqrat/sqrat/sqratConst.h b/squirrel_3_0_1_stable/sqrat/sqrat/sqratConst.h new file mode 100644 index 000000000..9a52b1fed --- /dev/null +++ b/squirrel_3_0_1_stable/sqrat/sqrat/sqratConst.h @@ -0,0 +1,120 @@ +// +// SqratConst: Constant and Enumeration Binding +// + +// +// Copyright (c) 2009 Brandon Jones +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would be +// appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, and must not be +// misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source +// distribution. +// + +#if !defined(_SCRAT_CONST_H_) +#define _SCRAT_CONST_H_ + +#include +#include + +#include "sqratObject.h" + +namespace Sqrat { + +// +// Enumerations +// + +class Enumeration : public Object { +public: + Enumeration(HSQUIRRELVM v = DefaultVM::Get(), bool createTable = true) : Object(v, false) { + if(createTable) { + sq_newtable(vm); + sq_getstackobj(vm,-1,&obj); + sq_addref(vm, &obj); + sq_pop(vm,1); + } + } + + // + // Bind Constants + // + + virtual Enumeration& Const(const SQChar* name, const int val) { + BindValue(name, val, false); + return *this; + } + + virtual Enumeration& Const(const SQChar* name, const float val) { + BindValue(name, val, false); + return *this; + } + + virtual Enumeration& Const(const SQChar* name, const SQChar* val) { + BindValue(name, val, false); + return *this; + } + +}; + +// +// Constants +// + +class ConstTable : public Enumeration { +public: + ConstTable(HSQUIRRELVM v = DefaultVM::Get()) : Enumeration(v, false) { + sq_pushconsttable(vm); + sq_getstackobj(vm,-1, &obj); + sq_pop(v,1); // No addref needed, since the consttable is always around + } + + // + // Bind Constants + // + + virtual ConstTable& Const(const SQChar* name, const int val) { + Enumeration::Const(name, val); + return *this; + } + + virtual ConstTable& Const(const SQChar* name, const float val) { + Enumeration::Const(name, val); + return *this; + } + + virtual ConstTable& Const(const SQChar* name, const SQChar* val) { + Enumeration::Const(name, val); + return *this; + } + + // + // Bind Enumerations + // + + ConstTable& Enum(const SQChar* name, Enumeration& en) { + sq_pushobject(vm, GetObject()); + sq_pushstring(vm, name, -1); + sq_pushobject(vm, en.GetObject()); + sq_newslot(vm, -3, false); + sq_pop(vm,1); // pop table + return *this; + } +}; +} + +#endif diff --git a/squirrel_3_0_1_stable/sqrat/sqrat/sqratFunction.h b/squirrel_3_0_1_stable/sqrat/sqrat/sqratFunction.h new file mode 100644 index 000000000..e9eda966e --- /dev/null +++ b/squirrel_3_0_1_stable/sqrat/sqrat/sqratFunction.h @@ -0,0 +1,751 @@ +// +// SqObject: Referenced Squirrel Object Wrapper +// + +// +// Copyright (c) 2009 Brandon Jones +// Copyirght 2011 Li-Cheng (Andy) Tai +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would be +// appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, and must not be +// misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source +// distribution. +// + +#if !defined(_SCRAT_SQFUNC_H_) +#define _SCRAT_SQFUNC_H_ + +#include +#include "sqratObject.h" + +namespace Sqrat { + +class Function { + friend class TableBase; + friend class Table; + friend class ArrayBase; + friend struct Var; +private: + HSQUIRRELVM vm; + HSQOBJECT env, obj; + + Function(HSQUIRRELVM v, HSQOBJECT e, HSQOBJECT o) : vm(v), env(e), obj(o) { + sq_addref(vm, &env); + sq_addref(vm, &obj); + } + +public: + Function() { + sq_resetobject(&env); + sq_resetobject(&obj); + } + + Function(const Function& sf) : vm(sf.vm), env(sf.env), obj(sf.obj) { + sq_addref(vm, &env); + sq_addref(vm, &obj); + } + + Function(const Object& e, const SQChar* slot) : vm(e.GetVM()), env(e.GetObject()) { + sq_addref(vm, &env); + Object so = e.GetSlot(slot); + obj = so.GetObject(); + sq_addref(vm, &obj); + } + + ~Function() { + Release(); + } + + Function& operator=(const Function& sf) { + Release(); + vm = sf.vm; + env = sf.env; + obj = sf.obj; + sq_addref(vm, &env); + sq_addref(vm, &obj); + return *this; + } + + bool IsNull() { + return sq_isnull(obj); + } + + HSQOBJECT& GetEnv() { + return env; + } + + HSQOBJECT& GetFunc() { + return obj; + } + + HSQUIRRELVM& GetVM() { + return vm; + } + + void Release() { + if(!IsNull()) { + sq_release(vm, &env); + sq_release(vm, &obj); + sq_resetobject(&env); + sq_resetobject(&obj); + } + } + + template + R Evaluate() { + sq_pushobject(vm, obj); + sq_pushobject(vm, env); + + sq_call(vm, 1, true, ErrorHandling::IsEnabled()); + R ret = Var(vm, -1).value; + sq_pop(vm, 2); + return ret; + } + + template + R Evaluate(A1 a1) { + sq_pushobject(vm, obj); + sq_pushobject(vm, env); + + PushVar(vm, a1); + + sq_call(vm, 2, true, ErrorHandling::IsEnabled()); + Var ret(vm, -1); + sq_pop(vm, 2); + return ret.value; + } + + template + R Evaluate(A1 a1, A2 a2) { + sq_pushobject(vm, obj); + sq_pushobject(vm, env); + + PushVar(vm, a1); + PushVar(vm, a2); + + sq_call(vm, 3, true, ErrorHandling::IsEnabled()); + R ret = Var(vm, -1).value; + sq_pop(vm, 2); + return ret; + } + + template + R Evaluate(A1 a1, A2 a2, A3 a3) { + sq_pushobject(vm, obj); + sq_pushobject(vm, env); + + PushVar(vm, a1); + PushVar(vm, a2); + PushVar(vm, a3); + + sq_call(vm, 4, true, ErrorHandling::IsEnabled()); + R ret = Var(vm, -1).value; + sq_pop(vm, 2); + return ret; + } + + template + R Evaluate(A1 a1, A2 a2, A3 a3, A4 a4) { + sq_pushobject(vm, obj); + sq_pushobject(vm, env); + + PushVar(vm, a1); + PushVar(vm, a2); + PushVar(vm, a3); + PushVar(vm, a4); + + sq_call(vm, 5, true, ErrorHandling::IsEnabled()); + R ret = Var(vm, -1).value; + sq_pop(vm, 2); + return ret; + } + + + template + R Evaluate(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) { + sq_pushobject(vm, obj); + sq_pushobject(vm, env); + + PushVar(vm, a1); + PushVar(vm, a2); + PushVar(vm, a3); + PushVar(vm, a4); + PushVar(vm, a5); + + sq_call(vm, 6, true, ErrorHandling::IsEnabled()); + R ret = Var(vm, -1).value; + sq_pop(vm, 2); + return ret; + } + + template + R Evaluate(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) { + sq_pushobject(vm, obj); + sq_pushobject(vm, env); + + PushVar(vm, a1); + PushVar(vm, a2); + PushVar(vm, a3); + PushVar(vm, a4); + PushVar(vm, a5); + PushVar(vm, a6); + + sq_call(vm, 7, true, ErrorHandling::IsEnabled()); + R ret = Var(vm, -1).value; + sq_pop(vm, 2); + return ret; + } + + template + R Evaluate(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) { + sq_pushobject(vm, obj); + sq_pushobject(vm, env); + + PushVar(vm, a1); + PushVar(vm, a2); + PushVar(vm, a3); + PushVar(vm, a4); + PushVar(vm, a5); + PushVar(vm, a6); + PushVar(vm, a7); + + sq_call(vm, 8, true, ErrorHandling::IsEnabled()); + R ret = Var(vm, -1).value; + sq_pop(vm, 2); + return ret; + } + + template + R Evaluate(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) { + sq_pushobject(vm, obj); + sq_pushobject(vm, env); + + PushVar(vm, a1); + PushVar(vm, a2); + PushVar(vm, a3); + PushVar(vm, a4); + PushVar(vm, a5); + PushVar(vm, a6); + PushVar(vm, a7); + PushVar(vm, a8); + + sq_call(vm, 9, true, ErrorHandling::IsEnabled()); + R ret = Var(vm, -1).value; + sq_pop(vm, 2); + return ret; + } + + template + R Evaluate(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9) { + sq_pushobject(vm, obj); + sq_pushobject(vm, env); + + PushVar(vm, a1); + PushVar(vm, a2); + PushVar(vm, a3); + PushVar(vm, a4); + PushVar(vm, a5); + PushVar(vm, a6); + PushVar(vm, a7); + PushVar(vm, a8); + PushVar(vm, a9); + + sq_call(vm, 10, true, ErrorHandling::IsEnabled()); + R ret = Var(vm, -1).value; + sq_pop(vm, 2); + return ret; + } + + template + R Evaluate(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10) { + sq_pushobject(vm, obj); + sq_pushobject(vm, env); + + PushVar(vm, a1); + PushVar(vm, a2); + PushVar(vm, a3); + PushVar(vm, a4); + PushVar(vm, a5); + PushVar(vm, a6); + PushVar(vm, a7); + PushVar(vm, a8); + PushVar(vm, a9); + PushVar(vm, a10); + + sq_call(vm, 11, true, ErrorHandling::IsEnabled()); + R ret = Var(vm, -1).value; + sq_pop(vm, 2); + return ret; + } + + template + R Evaluate(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10, A11 a11) { + sq_pushobject(vm, obj); + sq_pushobject(vm, env); + + PushVar(vm, a1); + PushVar(vm, a2); + PushVar(vm, a3); + PushVar(vm, a4); + PushVar(vm, a5); + PushVar(vm, a6); + PushVar(vm, a7); + PushVar(vm, a8); + PushVar(vm, a9); + PushVar(vm, a10); + PushVar(vm, a11); + + sq_call(vm, 12, true, ErrorHandling::IsEnabled()); + R ret = Var(vm, -1).value; + sq_pop(vm, 2); + return ret; + } + + template + R Evaluate(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10, A11 a11, A12 a12) { + sq_pushobject(vm, obj); + sq_pushobject(vm, env); + + PushVar(vm, a1); + PushVar(vm, a2); + PushVar(vm, a3); + PushVar(vm, a4); + PushVar(vm, a5); + PushVar(vm, a6); + PushVar(vm, a7); + PushVar(vm, a8); + PushVar(vm, a9); + PushVar(vm, a10); + PushVar(vm, a11); + PushVar(vm, a12); + + sq_call(vm, 13, true, ErrorHandling::IsEnabled()); + R ret = Var(vm, -1).value; + sq_pop(vm, 2); + return ret; + } + + template + R Evaluate(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10, A11 a11, A12 a12, A13 a13) { + sq_pushobject(vm, obj); + sq_pushobject(vm, env); + + PushVar(vm, a1); + PushVar(vm, a2); + PushVar(vm, a3); + PushVar(vm, a4); + PushVar(vm, a5); + PushVar(vm, a6); + PushVar(vm, a7); + PushVar(vm, a8); + PushVar(vm, a9); + PushVar(vm, a10); + PushVar(vm, a11); + PushVar(vm, a12); + PushVar(vm, a13); + + sq_call(vm, 14, true, ErrorHandling::IsEnabled()); + R ret = Var(vm, -1).value; + sq_pop(vm, 2); + return ret; + } + + template + R Evaluate(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10, A11 a11, A12 a12, A13 a13, A14 a14) { + sq_pushobject(vm, obj); + sq_pushobject(vm, env); + + PushVar(vm, a1); + PushVar(vm, a2); + PushVar(vm, a3); + PushVar(vm, a4); + PushVar(vm, a5); + PushVar(vm, a6); + PushVar(vm, a7); + PushVar(vm, a8); + PushVar(vm, a9); + PushVar(vm, a10); + PushVar(vm, a11); + PushVar(vm, a12); + PushVar(vm, a13); + PushVar(vm, a14); + + sq_call(vm, 15, true, ErrorHandling::IsEnabled()); + R ret = Var(vm, -1).value; + sq_pop(vm, 2); + return ret; + } + + // + // void returns + // + + void Execute() { + sq_pushobject(vm, obj); + sq_pushobject(vm, env); + + sq_call(vm, 1, false, ErrorHandling::IsEnabled()); + sq_pop(vm, 1); + } + + template + void Execute(A1 a1) { + sq_pushobject(vm, obj); + sq_pushobject(vm, env); + + PushVar(vm, a1); + + sq_call(vm, 2, false, ErrorHandling::IsEnabled()); + sq_pop(vm, 1); + } + + template + void Execute(A1 a1, A2 a2) { + sq_pushobject(vm, obj); + sq_pushobject(vm, env); + + PushVar(vm, a1); + PushVar(vm, a2); + + sq_call(vm, 3, false, ErrorHandling::IsEnabled()); + sq_pop(vm, 1); + } + + template + void Execute(A1 a1, A2 a2, A3 a3) { + sq_pushobject(vm, obj); + sq_pushobject(vm, env); + + PushVar(vm, a1); + PushVar(vm, a2); + PushVar(vm, a3); + + sq_call(vm, 4, false, ErrorHandling::IsEnabled()); + sq_pop(vm, 1); + } + + template + void Execute(A1 a1, A2 a2, A3 a3, A4 a4) { + sq_pushobject(vm, obj); + sq_pushobject(vm, env); + + PushVar(vm, a1); + PushVar(vm, a2); + PushVar(vm, a3); + PushVar(vm, a4); + + sq_call(vm, 5, false, ErrorHandling::IsEnabled()); + sq_pop(vm, 1); + } + + + template + void Execute(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) { + sq_pushobject(vm, obj); + sq_pushobject(vm, env); + + PushVar(vm, a1); + PushVar(vm, a2); + PushVar(vm, a3); + PushVar(vm, a4); + PushVar(vm, a5); + + sq_call(vm, 6, false, ErrorHandling::IsEnabled()); + sq_pop(vm, 1); + } + + template + void Execute(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) { + sq_pushobject(vm, obj); + sq_pushobject(vm, env); + + PushVar(vm, a1); + PushVar(vm, a2); + PushVar(vm, a3); + PushVar(vm, a4); + PushVar(vm, a5); + PushVar(vm, a6); + + sq_call(vm, 7, false, ErrorHandling::IsEnabled()); + sq_pop(vm, 1); + } + + template + void Execute(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) { + sq_pushobject(vm, obj); + sq_pushobject(vm, env); + + PushVar(vm, a1); + PushVar(vm, a2); + PushVar(vm, a3); + PushVar(vm, a4); + PushVar(vm, a5); + PushVar(vm, a6); + PushVar(vm, a7); + + sq_call(vm, 8, false, ErrorHandling::IsEnabled()); + sq_pop(vm, 1); + } + + template + void Execute(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) { + sq_pushobject(vm, obj); + sq_pushobject(vm, env); + + PushVar(vm, a1); + PushVar(vm, a2); + PushVar(vm, a3); + PushVar(vm, a4); + PushVar(vm, a5); + PushVar(vm, a6); + PushVar(vm, a7); + PushVar(vm, a8); + + sq_call(vm, 9, false, ErrorHandling::IsEnabled()); + sq_pop(vm, 1); + } + + template + void Execute(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9) { + sq_pushobject(vm, obj); + sq_pushobject(vm, env); + + PushVar(vm, a1); + PushVar(vm, a2); + PushVar(vm, a3); + PushVar(vm, a4); + PushVar(vm, a5); + PushVar(vm, a6); + PushVar(vm, a7); + PushVar(vm, a8); + PushVar(vm, a9); + + sq_call(vm, 10, false, ErrorHandling::IsEnabled()); + sq_pop(vm, 1); + } + + template + void Execute(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10) { + sq_pushobject(vm, obj); + sq_pushobject(vm, env); + + PushVar(vm, a1); + PushVar(vm, a2); + PushVar(vm, a3); + PushVar(vm, a4); + PushVar(vm, a5); + PushVar(vm, a6); + PushVar(vm, a7); + PushVar(vm, a8); + PushVar(vm, a9); + PushVar(vm, a10); + + sq_call(vm, 11, false, ErrorHandling::IsEnabled()); + sq_pop(vm, 1); + } + + template + void Execute(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10, A11 a11) { + sq_pushobject(vm, obj); + sq_pushobject(vm, env); + + PushVar(vm, a1); + PushVar(vm, a2); + PushVar(vm, a3); + PushVar(vm, a4); + PushVar(vm, a5); + PushVar(vm, a6); + PushVar(vm, a7); + PushVar(vm, a8); + PushVar(vm, a9); + PushVar(vm, a10); + PushVar(vm, a11); + + sq_call(vm, 12, false, ErrorHandling::IsEnabled()); + sq_pop(vm, 1); + } + + template + void Execute(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10, A11 a11, A12 a12) { + sq_pushobject(vm, obj); + sq_pushobject(vm, env); + + PushVar(vm, a1); + PushVar(vm, a2); + PushVar(vm, a3); + PushVar(vm, a4); + PushVar(vm, a5); + PushVar(vm, a6); + PushVar(vm, a7); + PushVar(vm, a8); + PushVar(vm, a9); + PushVar(vm, a10); + PushVar(vm, a11); + PushVar(vm, a12); + + sq_call(vm, 13, false, ErrorHandling::IsEnabled()); + sq_pop(vm, 1); + } + + template + void Execute(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10, A11 a11, A12 a12, A13 a13) { + sq_pushobject(vm, obj); + sq_pushobject(vm, env); + + PushVar(vm, a1); + PushVar(vm, a2); + PushVar(vm, a3); + PushVar(vm, a4); + PushVar(vm, a5); + PushVar(vm, a6); + PushVar(vm, a7); + PushVar(vm, a8); + PushVar(vm, a9); + PushVar(vm, a10); + PushVar(vm, a11); + PushVar(vm, a12); + PushVar(vm, a13); + + sq_call(vm, 14, false, ErrorHandling::IsEnabled()); + sq_pop(vm, 1); + } + + template + void Execute(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10, A11 a11, A12 a12, A13 a13, A14 a14) { + sq_pushobject(vm, obj); + sq_pushobject(vm, env); + + PushVar(vm, a1); + PushVar(vm, a2); + PushVar(vm, a3); + PushVar(vm, a4); + PushVar(vm, a5); + PushVar(vm, a6); + PushVar(vm, a7); + PushVar(vm, a8); + PushVar(vm, a9); + PushVar(vm, a10); + PushVar(vm, a11); + PushVar(vm, a12); + PushVar(vm, a13); + PushVar(vm, a14); + + sq_call(vm, 15, false, ErrorHandling::IsEnabled()); + sq_pop(vm, 1); + } + + // + // Operator overloads for ease of use (calls Execute) + // + + void operator()() { + Execute(); + } + + template + void operator()(A1 a1) { + Execute(a1); + } + + template + void operator()(A1 a1, A2 a2) { + Execute(a1, a2); + } + + template + void operator()(A1 a1, A2 a2, A3 a3) { + Execute(a1, a2, a3); + } + + template + void operator()(A1 a1, A2 a2, A3 a3, A4 a4) { + Execute(a1, a2, a3, a4); + } + + + template + void operator()(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) { + Execute(a1, a2, a3, a4, a5); + } + + template + void operator()(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) { + Execute(a1, a2, a3, a4, a5, a6); + } + + template + void operator()(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) { + Execute(a1, a2, a3, a4, a5, a6, a7); + } + + template + void operator()(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) { + Execute(a1, a2, a3, a4, a5, a6, a7, a8); + } + + template + void operator()(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9) { + Execute(a1, a2, a3, a4, a5, a6, a7, a8, a9); + } + + template + void operator()(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10) { + Execute(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10); + } + + template + void operator()(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10, A11 a11) { + Execute(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11); + } + + template + void operator()(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10, A11 a11, A12 a12) { + Execute(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12); + } + + template + void operator()(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10, A11 a11, A12 a12, A13 a13) { + Execute(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13); + } + + template + void operator()(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10, A11 a11, A12 a12, A13 a13, A14 a14) { + Execute(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14); + } +}; + +// +// Overridden Getter/Setter +// + +template<> +struct Var { + Function value; + Var(HSQUIRRELVM vm, SQInteger idx) { + HSQOBJECT sqEnv; + HSQOBJECT sqValue; + sq_getstackobj(vm, 1, &sqEnv); + sq_getstackobj(vm, idx, &sqValue); + value = Function(vm, sqEnv, sqValue); + } + static void push(HSQUIRRELVM vm, Function& value) { + sq_pushobject(vm, value.GetFunc()); + } +}; +} + +#endif diff --git a/squirrel_3_0_1_stable/sqrat/sqrat/sqratGlobalMethods.h b/squirrel_3_0_1_stable/sqrat/sqrat/sqratGlobalMethods.h new file mode 100644 index 000000000..c58a8ad3d --- /dev/null +++ b/squirrel_3_0_1_stable/sqrat/sqrat/sqratGlobalMethods.h @@ -0,0 +1,835 @@ +// +// SqratGlobalMethods: Global Methods +// + +// +// Copyright (c) 2009 Brandon Jones +// Copyirght 2011 Li-Cheng (Andy) Tai +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would be +// appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, and must not be +// misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source +// distribution. +// + +#if !defined(_SCRAT_GLOBAL_METHODS_H_) +#define _SCRAT_GLOBAL_METHODS_H_ + +#include +#include "sqratTypes.h" + +namespace Sqrat { + +// +// Squirrel Global Functions +// + +template +class SqGlobal { +public: + // Arg Count 0 + static SQInteger Func0(HSQUIRRELVM vm) { + typedef R (*M)(); + M* method; + sq_getuserdata(vm, -1, (SQUserPointer*)&method, NULL); + + R ret = (*method)(); + + PushVar(vm, ret); + return 1; + } + + + // Arg Count 1 + template + static SQInteger Func1(HSQUIRRELVM vm) { + typedef R (*M)(A1); + M* method; + sq_getuserdata(vm, -1, (SQUserPointer*)&method, NULL); + + R ret = (*method)( + Var(vm, startIdx).value + ); + + PushVar(vm, ret); + return 1; + } + + // Arg Count 2 + template + static SQInteger Func2(HSQUIRRELVM vm) { + typedef R (*M)(A1, A2); + M* method; + sq_getuserdata(vm, -1, (SQUserPointer*)&method, NULL); + + R ret = (*method)( + Var(vm, startIdx).value, + Var(vm, startIdx + 1).value + ); + + PushVar(vm, ret); + return 1; + } + + // Arg Count 3 + template + static SQInteger Func3(HSQUIRRELVM vm) { + typedef R (*M)(A1, A2, A3); + M* method; + sq_getuserdata(vm, -1, (SQUserPointer*)&method, NULL); + + R ret = (*method)( + Var(vm, startIdx).value, + Var(vm, startIdx + 1).value, + Var(vm, startIdx + 2).value + ); + + PushVar(vm, ret); + return 1; + } + + // Arg Count 4 + template + static SQInteger Func4(HSQUIRRELVM vm) { + typedef R (*M)(A1, A2, A3, A4); + M* method; + sq_getuserdata(vm, -1, (SQUserPointer*)&method, NULL); + + R ret = (*method)( + Var(vm, startIdx).value, + Var(vm, startIdx + 1).value, + Var(vm, startIdx + 2).value, + Var(vm, startIdx + 3).value + ); + + PushVar(vm, ret); + return 1; + } + + // Arg Count 5 + template + static SQInteger Func5(HSQUIRRELVM vm) { + typedef R (*M)(A1, A2, A3, A4, A5); + M* method; + sq_getuserdata(vm, -1, (SQUserPointer*)&method, NULL); + + R ret = (*method)( + Var(vm, startIdx).value, + Var(vm, startIdx + 1).value, + Var(vm, startIdx + 2).value, + Var(vm, startIdx + 3).value, + Var(vm, startIdx + 4).value + ); + + PushVar(vm, ret); + return 1; + } + + // Arg Count 6 + template + static SQInteger Func6(HSQUIRRELVM vm) { + typedef R (*M)(A1, A2, A3, A4, A5, A6); + M* method; + sq_getuserdata(vm, -1, (SQUserPointer*)&method, NULL); + + R ret = (*method)( + Var(vm, startIdx).value, + Var(vm, startIdx + 1).value, + Var(vm, startIdx + 2).value, + Var(vm, startIdx + 3).value, + Var(vm, startIdx + 4).value, + Var(vm, startIdx + 5).value + ); + + PushVar(vm, ret); + return 1; + } + + // Arg Count 7 + template + static SQInteger Func7(HSQUIRRELVM vm) { + typedef R (*M)(A1, A2, A3, A4, A5, A6, A7); + M* method; + sq_getuserdata(vm, -1, (SQUserPointer*)&method, NULL); + + R ret = (*method)( + Var(vm, startIdx).value, + Var(vm, startIdx + 1).value, + Var(vm, startIdx + 2).value, + Var(vm, startIdx + 3).value, + Var(vm, startIdx + 4).value, + Var(vm, startIdx + 5).value, + Var(vm, startIdx + 6).value + ); + + PushVar(vm, ret); + return 1; + } + + // Arg Count 8 + template + static SQInteger Func8(HSQUIRRELVM vm) { + typedef R (*M)(A1, A2, A3, A4, A5, A6, A7, A8); + M* method; + sq_getuserdata(vm, -1, (SQUserPointer*)&method, NULL); + + R ret = (*method)( + Var(vm, startIdx).value, + Var(vm, startIdx + 1).value, + Var(vm, startIdx + 2).value, + Var(vm, startIdx + 3).value, + Var(vm, startIdx + 4).value, + Var(vm, startIdx + 5).value, + Var(vm, startIdx + 6).value, + Var(vm, startIdx + 7).value + ); + + PushVar(vm, ret); + return 1; + } + + // Arg Count 9 + template + static SQInteger Func9(HSQUIRRELVM vm) { + typedef R (*M)(A1, A2, A3, A4, A5, A6, A7, A8, A9); + M* method; + sq_getuserdata(vm, -1, (SQUserPointer*)&method, NULL); + + R ret = (*method)( + Var(vm, startIdx).value, + Var(vm, startIdx + 1).value, + Var(vm, startIdx + 2).value, + Var(vm, startIdx + 3).value, + Var(vm, startIdx + 4).value, + Var(vm, startIdx + 5).value, + Var(vm, startIdx + 6).value, + Var(vm, startIdx + 7).value, + Var(vm, startIdx + 8).value + ); + + PushVar(vm, ret); + return 1; + } + + // Arg Count 10 + template + static SQInteger Func10(HSQUIRRELVM vm) { + typedef R (*M)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10); + M* method; + sq_getuserdata(vm, -1, (SQUserPointer*)&method, NULL); + + R ret = (*method)( + Var(vm, startIdx).value, + Var(vm, startIdx + 1).value, + Var(vm, startIdx + 2).value, + Var(vm, startIdx + 3).value, + Var(vm, startIdx + 4).value, + Var(vm, startIdx + 5).value, + Var(vm, startIdx + 6).value, + Var(vm, startIdx + 7).value, + Var(vm, startIdx + 8).value, + Var(vm, startIdx + 9).value + ); + + PushVar(vm, ret); + return 1; + } + + // Arg Count 11 + template + static SQInteger Func11(HSQUIRRELVM vm) { + typedef R (*M)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11); + M* method; + sq_getuserdata(vm, -1, (SQUserPointer*)&method, NULL); + + R ret = (*method)( + Var(vm, startIdx).value, + Var(vm, startIdx + 1).value, + Var(vm, startIdx + 2).value, + Var(vm, startIdx + 3).value, + Var(vm, startIdx + 4).value, + Var(vm, startIdx + 5).value, + Var(vm, startIdx + 6).value, + Var(vm, startIdx + 7).value, + Var(vm, startIdx + 8).value, + Var(vm, startIdx + 9).value, + Var(vm, startIdx + 10).value + ); + + PushVar(vm, ret); + return 1; + } + + // Arg Count 12 + template + static SQInteger Func12(HSQUIRRELVM vm) { + typedef R (*M)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12); + M* method; + sq_getuserdata(vm, -1, (SQUserPointer*)&method, NULL); + + R ret = (*method)( + Var(vm, startIdx).value, + Var(vm, startIdx + 1).value, + Var(vm, startIdx + 2).value, + Var(vm, startIdx + 3).value, + Var(vm, startIdx + 4).value, + Var(vm, startIdx + 5).value, + Var(vm, startIdx + 6).value, + Var(vm, startIdx + 7).value, + Var(vm, startIdx + 8).value, + Var(vm, startIdx + 9).value, + Var(vm, startIdx + 10).value, + Var(vm, startIdx + 11).value + ); + + PushVar(vm, ret); + return 1; + } + + // Arg Count 13 + template + static SQInteger Func13(HSQUIRRELVM vm) { + typedef R (*M)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13); + M* method; + sq_getuserdata(vm, -1, (SQUserPointer*)&method, NULL); + + R ret = (*method)( + Var(vm, startIdx).value, + Var(vm, startIdx + 1).value, + Var(vm, startIdx + 2).value, + Var(vm, startIdx + 3).value, + Var(vm, startIdx + 4).value, + Var(vm, startIdx + 5).value, + Var(vm, startIdx + 6).value, + Var(vm, startIdx + 7).value, + Var(vm, startIdx + 8).value, + Var(vm, startIdx + 9).value, + Var(vm, startIdx + 10).value, + Var(vm, startIdx + 11).value, + Var(vm, startIdx + 12).value + ); + + PushVar(vm, ret); + return 1; + } + + // Arg Count 14 + template + static SQInteger Func14(HSQUIRRELVM vm) { + typedef R (*M)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14); + M* method; + sq_getuserdata(vm, -1, (SQUserPointer*)&method, NULL); + + R ret = (*method)( + Var(vm, startIdx).value, + Var(vm, startIdx + 1).value, + Var(vm, startIdx + 2).value, + Var(vm, startIdx + 3).value, + Var(vm, startIdx + 4).value, + Var(vm, startIdx + 5).value, + Var(vm, startIdx + 6).value, + Var(vm, startIdx + 7).value, + Var(vm, startIdx + 8).value, + Var(vm, startIdx + 9).value, + Var(vm, startIdx + 10).value, + Var(vm, startIdx + 11).value, + Var(vm, startIdx + 12).value, + Var(vm, startIdx + 13).value + ); + + PushVar(vm, ret); + return 1; + } +}; + +// +// void return specialization +// + +template <> +class SqGlobal { +public: + // Arg Count 0 + static SQInteger Func0(HSQUIRRELVM vm) { + typedef void (*M)(); + M* method; + sq_getuserdata(vm, -1, (SQUserPointer*)&method, NULL); + (*method)(); + return 0; + } + + // Arg Count 1 + template + static SQInteger Func1(HSQUIRRELVM vm) { + typedef void (*M)(A1); + M* method; + sq_getuserdata(vm, -1, (SQUserPointer*)&method, NULL); + + (*method)( + Var(vm, startIdx).value + ); + return 0; + } + + // Arg Count 2 + template + static SQInteger Func2(HSQUIRRELVM vm) { + typedef void (*M)(A1, A2); + M* method; + sq_getuserdata(vm, -1, (SQUserPointer*)&method, NULL); + + (*method)( + Var(vm, startIdx).value, + Var(vm, startIdx + 1).value + ); + return 0; + } + + // Arg Count 3 + template + static SQInteger Func3(HSQUIRRELVM vm) { + typedef void (*M)(A1, A2, A3); + M* method; + sq_getuserdata(vm, -1, (SQUserPointer*)&method, NULL); + + (*method)( + Var(vm, startIdx).value, + Var(vm, startIdx + 1).value, + Var(vm, startIdx + 2).value + ); + return 0; + } + + // Arg Count 4 + template + static SQInteger Func4(HSQUIRRELVM vm) { + typedef void (*M)(A1, A2, A3, A4); + M* method; + sq_getuserdata(vm, -1, (SQUserPointer*)&method, NULL); + + (*method)( + Var(vm, startIdx).value, + Var(vm, startIdx + 1).value, + Var(vm, startIdx + 2).value, + Var(vm, startIdx + 3).value + ); + return 0; + } + + // Arg Count 5 + template + static SQInteger Func5(HSQUIRRELVM vm) { + typedef void (*M)(A1, A2, A3, A4, A5); + M* method; + sq_getuserdata(vm, -1, (SQUserPointer*)&method, NULL); + + (*method)( + Var(vm, startIdx).value, + Var(vm, startIdx + 1).value, + Var(vm, startIdx + 2).value, + Var(vm, startIdx + 3).value, + Var(vm, startIdx + 4).value + ); + return 0; + } + + // Arg Count 6 + template + static SQInteger Func6(HSQUIRRELVM vm) { + typedef void (*M)(A1, A2, A3, A4, A5, A6); + M* method; + sq_getuserdata(vm, -1, (SQUserPointer*)&method, NULL); + + (*method)( + Var(vm, startIdx).value, + Var(vm, startIdx + 1).value, + Var(vm, startIdx + 2).value, + Var(vm, startIdx + 3).value, + Var(vm, startIdx + 4).value, + Var(vm, startIdx + 5).value + ); + return 0; + } + + // Arg Count 7 + template + static SQInteger Func7(HSQUIRRELVM vm) { + typedef void (*M)(A1, A2, A3, A4, A5, A6, A7); + M* method; + sq_getuserdata(vm, -1, (SQUserPointer*)&method, NULL); + + (*method)( + Var(vm, startIdx).value, + Var(vm, startIdx + 1).value, + Var(vm, startIdx + 2).value, + Var(vm, startIdx + 3).value, + Var(vm, startIdx + 4).value, + Var(vm, startIdx + 5).value, + Var(vm, startIdx + 6).value + ); + return 0; + } + + // Arg Count 8 + template + static SQInteger Func8(HSQUIRRELVM vm) { + typedef void (*M)(A1, A2, A3, A4, A5, A6, A7, A8); + M* method; + sq_getuserdata(vm, -1, (SQUserPointer*)&method, NULL); + + (*method)( + Var(vm, startIdx).value, + Var(vm, startIdx + 1).value, + Var(vm, startIdx + 2).value, + Var(vm, startIdx + 3).value, + Var(vm, startIdx + 4).value, + Var(vm, startIdx + 5).value, + Var(vm, startIdx + 6).value, + Var(vm, startIdx + 7).value + ); + return 0; + } + + // Arg Count 9 + template + static SQInteger Func9(HSQUIRRELVM vm) { + typedef void (*M)(A1, A2, A3, A4, A5, A6, A7, A8, A9); + M* method; + sq_getuserdata(vm, -1, (SQUserPointer*)&method, NULL); + + (*method)( + Var(vm, startIdx).value, + Var(vm, startIdx + 1).value, + Var(vm, startIdx + 2).value, + Var(vm, startIdx + 3).value, + Var(vm, startIdx + 4).value, + Var(vm, startIdx + 5).value, + Var(vm, startIdx + 6).value, + Var(vm, startIdx + 7).value, + Var(vm, startIdx + 8).value + ); + return 0; + } + + // Arg Count 10 + template + static SQInteger Func10(HSQUIRRELVM vm) { + typedef void (*M)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10); + M* method; + sq_getuserdata(vm, -1, (SQUserPointer*)&method, NULL); + + (*method)( + Var(vm, startIdx).value, + Var(vm, startIdx + 1).value, + Var(vm, startIdx + 2).value, + Var(vm, startIdx + 3).value, + Var(vm, startIdx + 4).value, + Var(vm, startIdx + 5).value, + Var(vm, startIdx + 6).value, + Var(vm, startIdx + 7).value, + Var(vm, startIdx + 8).value, + Var(vm, startIdx + 9).value + ); + return 0; + } + + // Arg Count 11 + template + static SQInteger Func11(HSQUIRRELVM vm) { + typedef void (*M)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11); + M* method; + sq_getuserdata(vm, -1, (SQUserPointer*)&method, NULL); + + (*method)( + Var(vm, startIdx).value, + Var(vm, startIdx + 1).value, + Var(vm, startIdx + 2).value, + Var(vm, startIdx + 3).value, + Var(vm, startIdx + 4).value, + Var(vm, startIdx + 5).value, + Var(vm, startIdx + 6).value, + Var(vm, startIdx + 7).value, + Var(vm, startIdx + 8).value, + Var(vm, startIdx + 9).value, + Var(vm, startIdx + 10).value + ); + return 0; + } + + // Arg Count 12 + template + static SQInteger Func12(HSQUIRRELVM vm) { + typedef void (*M)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12); + M* method; + sq_getuserdata(vm, -1, (SQUserPointer*)&method, NULL); + + (*method)( + Var(vm, startIdx).value, + Var(vm, startIdx + 1).value, + Var(vm, startIdx + 2).value, + Var(vm, startIdx + 3).value, + Var(vm, startIdx + 4).value, + Var(vm, startIdx + 5).value, + Var(vm, startIdx + 6).value, + Var(vm, startIdx + 7).value, + Var(vm, startIdx + 8).value, + Var(vm, startIdx + 9).value, + Var(vm, startIdx + 10).value, + Var(vm, startIdx + 11).value + ); + return 0; + } + + // Arg Count 13 + template + static SQInteger Func13(HSQUIRRELVM vm) { + typedef void (*M)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13); + M* method; + sq_getuserdata(vm, -1, (SQUserPointer*)&method, NULL); + + (*method)( + Var(vm, startIdx).value, + Var(vm, startIdx + 1).value, + Var(vm, startIdx + 2).value, + Var(vm, startIdx + 3).value, + Var(vm, startIdx + 4).value, + Var(vm, startIdx + 5).value, + Var(vm, startIdx + 6).value, + Var(vm, startIdx + 7).value, + Var(vm, startIdx + 8).value, + Var(vm, startIdx + 9).value, + Var(vm, startIdx + 10).value, + Var(vm, startIdx + 11).value, + Var(vm, startIdx + 12).value + ); + return 0; + } + + // Arg Count 14 + template + static SQInteger Func14(HSQUIRRELVM vm) { + typedef void (*M)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14); + M* method; + sq_getuserdata(vm, -1, (SQUserPointer*)&method, NULL); + + (*method)( + Var(vm, startIdx).value, + Var(vm, startIdx + 1).value, + Var(vm, startIdx + 2).value, + Var(vm, startIdx + 3).value, + Var(vm, startIdx + 4).value, + Var(vm, startIdx + 5).value, + Var(vm, startIdx + 6).value, + Var(vm, startIdx + 7).value, + Var(vm, startIdx + 8).value, + Var(vm, startIdx + 9).value, + Var(vm, startIdx + 10).value, + Var(vm, startIdx + 11).value, + Var(vm, startIdx + 12).value, + Var(vm, startIdx + 13).value + ); + return 0; + } +}; + + +// +// Global Function Resolvers +// + +// Arg Count 0 +template +SQFUNCTION SqGlobalFunc(R (*method)()) { + return &SqGlobal::Func0; +} + +// Arg Count 1 +template +SQFUNCTION SqGlobalFunc(R (*method)(A1)) { + return &SqGlobal::template Func1; +} + +// Arg Count 2 +template +SQFUNCTION SqGlobalFunc(R (*method)(A1, A2)) { + return &SqGlobal::template Func2; +} + +// Arg Count 3 +template +SQFUNCTION SqGlobalFunc(R (*method)(A1, A2, A3)) { + return &SqGlobal::template Func3; +} + +// Arg Count 4 +template +SQFUNCTION SqGlobalFunc(R (*method)(A1, A2, A3, A4)) { + return &SqGlobal::template Func4; +} + +// Arg Count 5 +template +SQFUNCTION SqGlobalFunc(R (*method)(A1, A2, A3, A4, A5)) { + return &SqGlobal::template Func5; +} + +// Arg Count 6 +template +SQFUNCTION SqGlobalFunc(R (*method)(A1, A2, A3, A4, A5, A6)) { + return &SqGlobal::template Func6; +} + +// Arg Count 7 +template +SQFUNCTION SqGlobalFunc(R (*method)(A1, A2, A3, A4, A5, A6, A7)) { + return &SqGlobal::template Func7; +} + +// Arg Count 8 +template +SQFUNCTION SqGlobalFunc(R (*method)(A1, A2, A3, A4, A5, A6, A7, A8)) { + return &SqGlobal::template Func8; +} + +// Arg Count 9 +template +SQFUNCTION SqGlobalFunc(R (*method)(A1, A2, A3, A4, A5, A6, A7, A8, A9)) { + return &SqGlobal::template Func9; +} + +// Arg Count 10 +template +SQFUNCTION SqGlobalFunc(R (*method)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10)) { + return &SqGlobal::template Func10; +} + +// Arg Count 11 +template +SQFUNCTION SqGlobalFunc(R (*method)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11)) { + return &SqGlobal::template Func11; +} + +// Arg Count 12 +template +SQFUNCTION SqGlobalFunc(R (*method)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12)) { + return &SqGlobal::template Func12; +} + +// Arg Count 13 +template +SQFUNCTION SqGlobalFunc(R (*method)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13)) { + return &SqGlobal::template Func13; +} + +// Arg Count 14 +template +SQFUNCTION SqGlobalFunc(R (*method)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14)) { + return &SqGlobal::template Func14; +} + +// +// Member Global Function Resolvers +// + +// Arg Count 1 +template +SQFUNCTION SqMemberGlobalFunc(R (*method)(A1)) { + return &SqGlobal::template Func1; +} + +// Arg Count 2 +template +SQFUNCTION SqMemberGlobalFunc(R (*method)(A1, A2)) { + return &SqGlobal::template Func2; +} + +// Arg Count 3 +template +SQFUNCTION SqMemberGlobalFunc(R (*method)(A1, A2, A3)) { + return &SqGlobal::template Func3; +} + +// Arg Count 4 +template +SQFUNCTION SqMemberGlobalFunc(R (*method)(A1, A2, A3, A4)) { + return &SqGlobal::template Func4; +} + +// Arg Count 5 +template +SQFUNCTION SqMemberGlobalFunc(R (*method)(A1, A2, A3, A4, A5)) { + return &SqGlobal::template Func5; +} + +// Arg Count 6 +template +SQFUNCTION SqMemberGlobalFunc(R (*method)(A1, A2, A3, A4, A5, A6)) { + return &SqGlobal::template Func6; +} + +// Arg Count 7 +template +SQFUNCTION SqMemberGlobalFunc(R (*method)(A1, A2, A3, A4, A5, A6, A7)) { + return &SqGlobal::template Func7; +} + +// Arg Count 8 +template +SQFUNCTION SqMemberGlobalFunc(R (*method)(A1, A2, A3, A4, A5, A6, A7, A8)) { + return &SqGlobal::template Func8; +} + +// Arg Count 9 +template +SQFUNCTION SqMemberGlobalFunc(R (*method)(A1, A2, A3, A4, A5, A6, A7, A8, A9)) { + return &SqGlobal::template Func9; +} + +// Arg Count 10 +template +SQFUNCTION SqMemberGlobalFunc(R (*method)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10)) { + return &SqGlobal::template Func10; +} + +// Arg Count 11 +template +SQFUNCTION SqMemberGlobalFunc(R (*method)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11)) { + return &SqGlobal::template Func11; +} + +// Arg Count 12 +template +SQFUNCTION SqMemberGlobalFunc(R (*method)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12)) { + return &SqGlobal::template Func12; +} + +// Arg Count 13 +template +SQFUNCTION SqMemberGlobalFunc(R (*method)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13)) { + return &SqGlobal::template Func13; +} + +// Arg Count 14 +template +SQFUNCTION SqMemberGlobalFunc(R (*method)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14)) { + return &SqGlobal::template Func14; +} + + +} + +#endif diff --git a/squirrel_3_0_1_stable/sqrat/sqrat/sqratMemberMethods.h b/squirrel_3_0_1_stable/sqrat/sqrat/sqratMemberMethods.h new file mode 100644 index 000000000..ebfa7c085 --- /dev/null +++ b/squirrel_3_0_1_stable/sqrat/sqrat/sqratMemberMethods.h @@ -0,0 +1,1706 @@ +// +// SqratMemberMethods: Member Methods +// + +// +// Copyright (c) 2009 Brandon Jones +// Copyright 2011 Li-Cheng (Andy) Tai +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would be +// appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, and must not be +// misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source +// distribution. +// + +#if !defined(_SCRAT_MEMBER_METHODS_H_) +#define _SCRAT_MEMBER_METHODS_H_ + +#include +#include "sqratTypes.h" + +namespace Sqrat { + +// +// Squirrel Global Functions +// + +template +class SqMember { +public: + // Arg Count 0 + static SQInteger Func0(HSQUIRRELVM vm) { + typedef R (C::*M)(); + M* methodPtr; + sq_getuserdata(vm, -1, (SQUserPointer*)&methodPtr, NULL); + M method = *methodPtr; + + C* ptr = NULL; + sq_getinstanceup(vm, 1, (SQUserPointer*)&ptr, NULL); + + R ret = (ptr->*method)(); + + PushVar(vm, ret); + return 1; + } + + static SQInteger Func0C(HSQUIRRELVM vm) { + typedef R (C::*M)() const; + M* methodPtr; + sq_getuserdata(vm, -1, (SQUserPointer*)&methodPtr, NULL); + M method = *methodPtr; + + C* ptr = NULL; + sq_getinstanceup(vm, 1, (SQUserPointer*)&ptr, NULL); + + R ret = (ptr->*method)(); + + PushVar(vm, ret); + return 1; + } + + // Arg Count 1 + template + static SQInteger Func1(HSQUIRRELVM vm) { + typedef R (C::*M)(A1); + M* methodPtr; + sq_getuserdata(vm, -1, (SQUserPointer*)&methodPtr, NULL); + M method = *methodPtr; + + C* ptr = NULL; + sq_getinstanceup(vm, 1, (SQUserPointer*)&ptr, NULL); + + R ret = (ptr->*method)( + Var(vm, 2).value + ); + + PushVar(vm, ret); + return 1; + } + + template + static SQInteger Func1C(HSQUIRRELVM vm) { + typedef R (C::*M)(A1) const; + M* methodPtr; + sq_getuserdata(vm, -1, (SQUserPointer*)&methodPtr, NULL); + M method = *methodPtr; + + C* ptr = NULL; + sq_getinstanceup(vm, 1, (SQUserPointer*)&ptr, NULL); + + R ret = (ptr->*method)( + Var(vm, 2).value + ); + + PushVar(vm, ret); + return 1; + } + + // Arg Count 2 + template + static SQInteger Func2(HSQUIRRELVM vm) { + typedef R (C::*M)(A1, A2); + M* methodPtr; + sq_getuserdata(vm, -1, (SQUserPointer*)&methodPtr, NULL); + M method = *methodPtr; + + C* ptr = NULL; + sq_getinstanceup(vm, 1, (SQUserPointer*)&ptr, NULL); + + R ret = (ptr->*method)( + Var(vm, 2).value, + Var(vm, 3).value + ); + + PushVar(vm, ret); + return 1; + } + + template + static SQInteger Func2C(HSQUIRRELVM vm) { + typedef R (C::*M)(A1, A2) const; + M* methodPtr; + sq_getuserdata(vm, -1, (SQUserPointer*)&methodPtr, NULL); + M method = *methodPtr; + + C* ptr = NULL; + sq_getinstanceup(vm, 1, (SQUserPointer*)&ptr, NULL); + + R ret = (ptr->*method)( + Var(vm, 2).value, + Var(vm, 3).value + ); + + PushVar(vm, ret); + return 1; + } + + // Arg Count 3 + template + static SQInteger Func3(HSQUIRRELVM vm) { + typedef R (C::*M)(A1, A2, A3); + M* methodPtr; + sq_getuserdata(vm, -1, (SQUserPointer*)&methodPtr, NULL); + M method = *methodPtr; + + C* ptr = NULL; + sq_getinstanceup(vm, 1, (SQUserPointer*)&ptr, NULL); + + R ret = (ptr->*method)( + Var(vm, 2).value, + Var(vm, 3).value, + Var(vm, 4).value + ); + + PushVar(vm, ret); + return 1; + } + + template + static SQInteger Func3C(HSQUIRRELVM vm) { + typedef R (C::*M)(A1, A2, A3) const; + M* methodPtr; + sq_getuserdata(vm, -1, (SQUserPointer*)&methodPtr, NULL); + M method = *methodPtr; + + C* ptr = NULL; + sq_getinstanceup(vm, 1, (SQUserPointer*)&ptr, NULL); + + R ret = (ptr->*method)( + Var(vm, 2).value, + Var(vm, 3).value, + Var(vm, 4).value + ); + + PushVar(vm, ret); + return 1; + } + + // Arg Count 4 + template + static SQInteger Func4(HSQUIRRELVM vm) { + typedef R (C::*M)(A1, A2, A3, A4); + M* methodPtr; + sq_getuserdata(vm, -1, (SQUserPointer*)&methodPtr, NULL); + M method = *methodPtr; + + C* ptr = NULL; + sq_getinstanceup(vm, 1, (SQUserPointer*)&ptr, NULL); + + R ret = (ptr->*method)( + Var(vm, 2).value, + Var(vm, 3).value, + Var(vm, 4).value, + Var(vm, 5).value + ); + + PushVar(vm, ret); + return 1; + } + + template + static SQInteger Func4C(HSQUIRRELVM vm) { + typedef R (C::*M)(A1, A2, A3, A4) const; + M* methodPtr; + sq_getuserdata(vm, -1, (SQUserPointer*)&methodPtr, NULL); + M method = *methodPtr; + + C* ptr = NULL; + sq_getinstanceup(vm, 1, (SQUserPointer*)&ptr, NULL); + + R ret = (ptr->*method)( + Var(vm, 2).value, + Var(vm, 3).value, + Var(vm, 4).value, + Var(vm, 5).value + ); + + PushVar(vm, ret); + return 1; + } + + // Arg Count 5 + template + static SQInteger Func5(HSQUIRRELVM vm) { + typedef R (C::*M)(A1, A2, A3, A4, A5); + M* methodPtr; + sq_getuserdata(vm, -1, (SQUserPointer*)&methodPtr, NULL); + M method = *methodPtr; + + C* ptr = NULL; + sq_getinstanceup(vm, 1, (SQUserPointer*)&ptr, NULL); + + R ret = (ptr->*method)( + Var(vm, 2).value, + Var(vm, 3).value, + Var(vm, 4).value, + Var(vm, 5).value, + Var(vm, 6).value + ); + + PushVar(vm, ret); + return 1; + } + + template + static SQInteger Func5C(HSQUIRRELVM vm) { + typedef R (C::*M)(A1, A2, A3, A4, A5) const; + M* methodPtr; + sq_getuserdata(vm, -1, (SQUserPointer*)&methodPtr, NULL); + M method = *methodPtr; + + C* ptr = NULL; + sq_getinstanceup(vm, 1, (SQUserPointer*)&ptr, NULL); + + R ret = (ptr->*method)( + Var(vm, 2).value, + Var(vm, 3).value, + Var(vm, 4).value, + Var(vm, 5).value, + Var(vm, 6).value + ); + + PushVar(vm, ret); + return 1; + } + + // Arg Count 6 + template + static SQInteger Func6(HSQUIRRELVM vm) { + typedef R (C::*M)(A1, A2, A3, A4, A5, A6); + M* methodPtr; + sq_getuserdata(vm, -1, (SQUserPointer*)&methodPtr, NULL); + M method = *methodPtr; + + C* ptr = NULL; + sq_getinstanceup(vm, 1, (SQUserPointer*)&ptr, NULL); + + R ret = (ptr->*method)( + Var(vm, 2).value, + Var(vm, 3).value, + Var(vm, 4).value, + Var(vm, 5).value, + Var(vm, 6).value, + Var(vm, 7).value + ); + + PushVar(vm, ret); + return 1; + } + + template + static SQInteger Func6C(HSQUIRRELVM vm) { + typedef R (C::*M)(A1, A2, A3, A4, A5, A6) const; + M* methodPtr; + sq_getuserdata(vm, -1, (SQUserPointer*)&methodPtr, NULL); + M method = *methodPtr; + + C* ptr = NULL; + sq_getinstanceup(vm, 1, (SQUserPointer*)&ptr, NULL); + + R ret = (ptr->*method)( + Var(vm, 2).value, + Var(vm, 3).value, + Var(vm, 4).value, + Var(vm, 5).value, + Var(vm, 6).value, + Var(vm, 7).value + ); + + PushVar(vm, ret); + return 1; + } + + // Arg Count 7 + template + static SQInteger Func7(HSQUIRRELVM vm) { + typedef R (C::*M)(A1, A2, A3, A4, A5, A6, A7); + M* methodPtr; + sq_getuserdata(vm, -1, (SQUserPointer*)&methodPtr, NULL); + M method = *methodPtr; + + C* ptr = NULL; + sq_getinstanceup(vm, 1, (SQUserPointer*)&ptr, NULL); + + R ret = (ptr->*method)( + Var(vm, 2).value, + Var(vm, 3).value, + Var(vm, 4).value, + Var(vm, 5).value, + Var(vm, 6).value, + Var(vm, 7).value, + Var(vm, 8).value + ); + + PushVar(vm, ret); + return 1; + } + + template + static SQInteger Func7C(HSQUIRRELVM vm) { + typedef R (C::*M)(A1, A2, A3, A4, A5, A6, A7) const; + M* methodPtr; + sq_getuserdata(vm, -1, (SQUserPointer*)&methodPtr, NULL); + M method = *methodPtr; + + C* ptr = NULL; + sq_getinstanceup(vm, 1, (SQUserPointer*)&ptr, NULL); + + R ret = (ptr->*method)( + Var(vm, 2).value, + Var(vm, 3).value, + Var(vm, 4).value, + Var(vm, 5).value, + Var(vm, 6).value, + Var(vm, 7).value, + Var(vm, 8).value + ); + + PushVar(vm, ret); + return 1; + } + + // Arg Count 8 + template + static SQInteger Func8(HSQUIRRELVM vm) { + typedef R (C::*M)(A1, A2, A3, A4, A5, A6, A7, A8); + M* methodPtr; + sq_getuserdata(vm, -1, (SQUserPointer*)&methodPtr, NULL); + M method = *methodPtr; + + C* ptr = NULL; + sq_getinstanceup(vm, 1, (SQUserPointer*)&ptr, NULL); + + R ret = (ptr->*method)( + Var(vm, 2).value, + Var(vm, 3).value, + Var(vm, 4).value, + Var(vm, 5).value, + Var(vm, 6).value, + Var(vm, 7).value, + Var(vm, 8).value, + Var(vm, 9).value + ); + + PushVar(vm, ret); + return 1; + } + + template + static SQInteger Func8C(HSQUIRRELVM vm) { + typedef R (C::*M)(A1, A2, A3, A4, A5, A6, A7, A8) const; + M* methodPtr; + sq_getuserdata(vm, -1, (SQUserPointer*)&methodPtr, NULL); + M method = *methodPtr; + + C* ptr = NULL; + sq_getinstanceup(vm, 1, (SQUserPointer*)&ptr, NULL); + + R ret = (ptr->*method)( + Var(vm, 2).value, + Var(vm, 3).value, + Var(vm, 4).value, + Var(vm, 5).value, + Var(vm, 6).value, + Var(vm, 7).value, + Var(vm, 8).value, + Var(vm, 9).value + ); + + PushVar(vm, ret); + return 1; + } + + // Arg Count 9 + template + static SQInteger Func9(HSQUIRRELVM vm) { + typedef R (C::*M)(A1, A2, A3, A4, A5, A6, A7, A8, A9); + M* methodPtr; + sq_getuserdata(vm, -1, (SQUserPointer*)&methodPtr, NULL); + M method = *methodPtr; + + C* ptr = NULL; + sq_getinstanceup(vm, 1, (SQUserPointer*)&ptr, NULL); + + R ret = (ptr->*method)( + Var(vm, 2).value, + Var(vm, 3).value, + Var(vm, 4).value, + Var(vm, 5).value, + Var(vm, 6).value, + Var(vm, 7).value, + Var(vm, 8).value, + Var(vm, 9).value, + Var(vm, 10).value + ); + + PushVar(vm, ret); + return 1; + } + + template + static SQInteger Func9C(HSQUIRRELVM vm) { + typedef R (C::*M)(A1, A2, A3, A4, A5, A6, A7, A8, A9) const; + M* methodPtr; + sq_getuserdata(vm, -1, (SQUserPointer*)&methodPtr, NULL); + M method = *methodPtr; + + C* ptr = NULL; + sq_getinstanceup(vm, 1, (SQUserPointer*)&ptr, NULL); + + R ret = (ptr->*method)( + Var(vm, 2).value, + Var(vm, 3).value, + Var(vm, 4).value, + Var(vm, 5).value, + Var(vm, 6).value, + Var(vm, 7).value, + Var(vm, 8).value, + Var(vm, 9).value, + Var(vm, 10).value + ); + + PushVar(vm, ret); + return 1; + } + + + // Arg Count 10 + template + static SQInteger Func10(HSQUIRRELVM vm) { + typedef R (C::*M)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10); + M* methodPtr; + sq_getuserdata(vm, -1, (SQUserPointer*)&methodPtr, NULL); + M method = *methodPtr; + + C* ptr = NULL; + sq_getinstanceup(vm, 1, (SQUserPointer*)&ptr, NULL); + + R ret = (ptr->*method)( + Var(vm, 2).value, + Var(vm, 3).value, + Var(vm, 4).value, + Var(vm, 5).value, + Var(vm, 6).value, + Var(vm, 7).value, + Var(vm, 8).value, + Var(vm, 9).value, + Var(vm, 10).value, + Var(vm, 11).value + ); + + PushVar(vm, ret); + return 1; + } + + template + static SQInteger Func10C(HSQUIRRELVM vm) { + typedef R (C::*M)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10) const; + M* methodPtr; + sq_getuserdata(vm, -1, (SQUserPointer*)&methodPtr, NULL); + M method = *methodPtr; + + C* ptr = NULL; + sq_getinstanceup(vm, 1, (SQUserPointer*)&ptr, NULL); + + R ret = (ptr->*method)( + Var(vm, 2).value, + Var(vm, 3).value, + Var(vm, 4).value, + Var(vm, 5).value, + Var(vm, 6).value, + Var(vm, 7).value, + Var(vm, 8).value, + Var(vm, 9).value, + Var(vm, 10).value, + Var(vm, 11).value + ); + + PushVar(vm, ret); + return 1; + } + + + // Arg Count 11 + template + static SQInteger Func11(HSQUIRRELVM vm) { + typedef R (C::*M)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11); + M* methodPtr; + sq_getuserdata(vm, -1, (SQUserPointer*)&methodPtr, NULL); + M method = *methodPtr; + + C* ptr = NULL; + sq_getinstanceup(vm, 1, (SQUserPointer*)&ptr, NULL); + + R ret = (ptr->*method)( + Var(vm, 2).value, + Var(vm, 3).value, + Var(vm, 4).value, + Var(vm, 5).value, + Var(vm, 6).value, + Var(vm, 7).value, + Var(vm, 8).value, + Var(vm, 9).value, + Var(vm, 10).value, + Var(vm, 11).value, + Var(vm, 12).value + ); + + PushVar(vm, ret); + return 1; + } + + template + static SQInteger Func11C(HSQUIRRELVM vm) { + typedef R (C::*M)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11) const; + M* methodPtr; + sq_getuserdata(vm, -1, (SQUserPointer*)&methodPtr, NULL); + M method = *methodPtr; + + C* ptr = NULL; + sq_getinstanceup(vm, 1, (SQUserPointer*)&ptr, NULL); + + R ret = (ptr->*method)( + Var(vm, 2).value, + Var(vm, 3).value, + Var(vm, 4).value, + Var(vm, 5).value, + Var(vm, 6).value, + Var(vm, 7).value, + Var(vm, 8).value, + Var(vm, 9).value, + Var(vm, 10).value, + Var(vm, 11).value, + Var(vm, 12).value + ); + + PushVar(vm, ret); + return 1; + } + + + // Arg Count 12 + template + static SQInteger Func12(HSQUIRRELVM vm) { + typedef R (C::*M)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12); + M* methodPtr; + sq_getuserdata(vm, -1, (SQUserPointer*)&methodPtr, NULL); + M method = *methodPtr; + + C* ptr = NULL; + sq_getinstanceup(vm, 1, (SQUserPointer*)&ptr, NULL); + + R ret = (ptr->*method)( + Var(vm, 2).value, + Var(vm, 3).value, + Var(vm, 4).value, + Var(vm, 5).value, + Var(vm, 6).value, + Var(vm, 7).value, + Var(vm, 8).value, + Var(vm, 9).value, + Var(vm, 10).value, + Var(vm, 11).value, + Var(vm, 12).value, + Var(vm, 13).value + ); + + PushVar(vm, ret); + return 1; + } + + template + static SQInteger Func12C(HSQUIRRELVM vm) { + typedef R (C::*M)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12) const; + M* methodPtr; + sq_getuserdata(vm, -1, (SQUserPointer*)&methodPtr, NULL); + M method = *methodPtr; + + C* ptr = NULL; + sq_getinstanceup(vm, 1, (SQUserPointer*)&ptr, NULL); + + R ret = (ptr->*method)( + Var(vm, 2).value, + Var(vm, 3).value, + Var(vm, 4).value, + Var(vm, 5).value, + Var(vm, 6).value, + Var(vm, 7).value, + Var(vm, 8).value, + Var(vm, 9).value, + Var(vm, 10).value, + Var(vm, 11).value, + Var(vm, 12).value, + Var(vm, 13).value + ); + + PushVar(vm, ret); + return 1; + } + + // Arg Count 13 + template + static SQInteger Func13(HSQUIRRELVM vm) { + typedef R (C::*M)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13); + M* methodPtr; + sq_getuserdata(vm, -1, (SQUserPointer*)&methodPtr, NULL); + M method = *methodPtr; + + C* ptr = NULL; + sq_getinstanceup(vm, 1, (SQUserPointer*)&ptr, NULL); + + R ret = (ptr->*method)( + Var(vm, 2).value, + Var(vm, 3).value, + Var(vm, 4).value, + Var(vm, 5).value, + Var(vm, 6).value, + Var(vm, 7).value, + Var(vm, 8).value, + Var(vm, 9).value, + Var(vm, 10).value, + Var(vm, 11).value, + Var(vm, 12).value, + Var(vm, 13).value, + Var(vm, 14).value + ); + + PushVar(vm, ret); + return 1; + } + + template + static SQInteger Func13C(HSQUIRRELVM vm) { + typedef R (C::*M)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13) const; + M* methodPtr; + sq_getuserdata(vm, -1, (SQUserPointer*)&methodPtr, NULL); + M method = *methodPtr; + + C* ptr = NULL; + sq_getinstanceup(vm, 1, (SQUserPointer*)&ptr, NULL); + + R ret = (ptr->*method)( + Var(vm, 2).value, + Var(vm, 3).value, + Var(vm, 4).value, + Var(vm, 5).value, + Var(vm, 6).value, + Var(vm, 7).value, + Var(vm, 8).value, + Var(vm, 9).value, + Var(vm, 10).value, + Var(vm, 11).value, + Var(vm, 12).value, + Var(vm, 13).value, + Var(vm, 14).value + ); + + PushVar(vm, ret); + return 1; + } + + // Arg Count 14 + template + static SQInteger Func14(HSQUIRRELVM vm) { + typedef R (C::*M)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14); + M* methodPtr; + sq_getuserdata(vm, -1, (SQUserPointer*)&methodPtr, NULL); + M method = *methodPtr; + + C* ptr = NULL; + sq_getinstanceup(vm, 1, (SQUserPointer*)&ptr, NULL); + + R ret = (ptr->*method)( + Var(vm, 2).value, + Var(vm, 3).value, + Var(vm, 4).value, + Var(vm, 5).value, + Var(vm, 6).value, + Var(vm, 7).value, + Var(vm, 8).value, + Var(vm, 9).value, + Var(vm, 10).value, + Var(vm, 11).value, + Var(vm, 12).value, + Var(vm, 13).value, + Var(vm, 14).value, + Var(vm, 15).value + ); + + PushVar(vm, ret); + return 1; + } + + template + static SQInteger Func14C(HSQUIRRELVM vm) { + typedef R (C::*M)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14) const; + M* methodPtr; + sq_getuserdata(vm, -1, (SQUserPointer*)&methodPtr, NULL); + M method = *methodPtr; + + C* ptr = NULL; + sq_getinstanceup(vm, 1, (SQUserPointer*)&ptr, NULL); + + R ret = (ptr->*method)( + Var(vm, 2).value, + Var(vm, 3).value, + Var(vm, 4).value, + Var(vm, 5).value, + Var(vm, 6).value, + Var(vm, 7).value, + Var(vm, 8).value, + Var(vm, 9).value, + Var(vm, 10).value, + Var(vm, 11).value, + Var(vm, 12).value, + Var(vm, 13).value, + Var(vm, 14).value, + Var(vm, 15).value + ); + + PushVar(vm, ret); + return 1; + } +}; + +// +// void return specialization +// + +template +class SqMember { +public: + // Arg Count 0 + static SQInteger Func0(HSQUIRRELVM vm) { + typedef void (C::*M)(); + M* methodPtr; + sq_getuserdata(vm, -1, (SQUserPointer*)&methodPtr, NULL); + M method = *methodPtr; + + C* ptr = NULL; + sq_getinstanceup(vm, 1, (SQUserPointer*)&ptr, NULL); + + (ptr->*method)(); + return 0; + } + + static SQInteger Func0C(HSQUIRRELVM vm) { + typedef void (C::*M)() const; + M* methodPtr; + sq_getuserdata(vm, -1, (SQUserPointer*)&methodPtr, NULL); + M method = *methodPtr; + + C* ptr = NULL; + sq_getinstanceup(vm, 1, (SQUserPointer*)&ptr, NULL); + + (ptr->*method)(); + return 0; + } + + // Arg Count 1 + template + static SQInteger Func1(HSQUIRRELVM vm) { + typedef void (C::*M)(A1); + M* methodPtr; + sq_getuserdata(vm, -1, (SQUserPointer*)&methodPtr, NULL); + M method = *methodPtr; + + C* ptr = NULL; + sq_getinstanceup(vm, 1, (SQUserPointer*)&ptr, NULL); + + (ptr->*method)( + Var(vm, 2).value + ); + return 0; + } + + template + static SQInteger Func1C(HSQUIRRELVM vm) { + typedef void (C::*M)(A1) const; + M* methodPtr; + sq_getuserdata(vm, -1, (SQUserPointer*)&methodPtr, NULL); + M method = *methodPtr; + + C* ptr = NULL; + sq_getinstanceup(vm, 1, (SQUserPointer*)&ptr, NULL); + + (ptr->*method)( + Var(vm, 2).value + ); + return 0; + } + + // Arg Count 2 + template + static SQInteger Func2(HSQUIRRELVM vm) { + typedef void (C::*M)(A1, A2); + M* methodPtr; + sq_getuserdata(vm, -1, (SQUserPointer*)&methodPtr, NULL); + M method = *methodPtr; + + C* ptr = NULL; + sq_getinstanceup(vm, 1, (SQUserPointer*)&ptr, NULL); + + (ptr->*method)( + Var(vm, 2).value, + Var(vm, 3).value + ); + return 0; + } + + template + static SQInteger Func2C(HSQUIRRELVM vm) { + typedef void (C::*M)(A1, A2) const; + M* methodPtr; + sq_getuserdata(vm, -1, (SQUserPointer*)&methodPtr, NULL); + M method = *methodPtr; + + C* ptr = NULL; + sq_getinstanceup(vm, 1, (SQUserPointer*)&ptr, NULL); + + (ptr->*method)( + Var(vm, 2).value, + Var(vm, 3).value + ); + return 0; + } + + // Arg Count 3 + template + static SQInteger Func3(HSQUIRRELVM vm) { + typedef void (C::*M)(A1, A2, A3); + M* methodPtr; + sq_getuserdata(vm, -1, (SQUserPointer*)&methodPtr, NULL); + M method = *methodPtr; + + C* ptr = NULL; + sq_getinstanceup(vm, 1, (SQUserPointer*)&ptr, NULL); + + (ptr->*method)( + Var(vm, 2).value, + Var(vm, 3).value, + Var(vm, 4).value + ); + return 0; + } + + template + static SQInteger Func3C(HSQUIRRELVM vm) { + typedef void (C::*M)(A1, A2, A3) const; + M* methodPtr; + sq_getuserdata(vm, -1, (SQUserPointer*)&methodPtr, NULL); + M method = *methodPtr; + + C* ptr = NULL; + sq_getinstanceup(vm, 1, (SQUserPointer*)&ptr, NULL); + + (ptr->*method)( + Var(vm, 2).value, + Var(vm, 3).value, + Var(vm, 4).value + ); + return 0; + } + + // Arg Count 4 + template + static SQInteger Func4(HSQUIRRELVM vm) { + typedef void (C::*M)(A1, A2, A3, A4); + M* methodPtr; + sq_getuserdata(vm, -1, (SQUserPointer*)&methodPtr, NULL); + M method = *methodPtr; + + C* ptr = NULL; + sq_getinstanceup(vm, 1, (SQUserPointer*)&ptr, NULL); + + (ptr->*method)( + Var(vm, 2).value, + Var(vm, 3).value, + Var(vm, 4).value, + Var(vm, 5).value + ); + return 0; + } + + template + static SQInteger Func4C(HSQUIRRELVM vm) { + typedef void (C::*M)(A1, A2, A3, A4) const; + M* methodPtr; + sq_getuserdata(vm, -1, (SQUserPointer*)&methodPtr, NULL); + M method = *methodPtr; + + C* ptr = NULL; + sq_getinstanceup(vm, 1, (SQUserPointer*)&ptr, NULL); + + (ptr->*method)( + Var(vm, 2).value, + Var(vm, 3).value, + Var(vm, 4).value, + Var(vm, 5).value + ); + return 0; + } + + // Arg Count 5 + template + static SQInteger Func5(HSQUIRRELVM vm) { + typedef void (C::*M)(A1, A2, A3, A4, A5); + M* methodPtr; + sq_getuserdata(vm, -1, (SQUserPointer*)&methodPtr, NULL); + M method = *methodPtr; + + C* ptr = NULL; + sq_getinstanceup(vm, 1, (SQUserPointer*)&ptr, NULL); + + (ptr->*method)( + Var(vm, 2).value, + Var(vm, 3).value, + Var(vm, 4).value, + Var(vm, 5).value, + Var(vm, 6).value + ); + return 0; + } + + template + static SQInteger Func5C(HSQUIRRELVM vm) { + typedef void (C::*M)(A1, A2, A3, A4, A5) const; + M* methodPtr; + sq_getuserdata(vm, -1, (SQUserPointer*)&methodPtr, NULL); + M method = *methodPtr; + + C* ptr = NULL; + sq_getinstanceup(vm, 1, (SQUserPointer*)&ptr, NULL); + + (ptr->*method)( + Var(vm, 2).value, + Var(vm, 3).value, + Var(vm, 4).value, + Var(vm, 5).value, + Var(vm, 6).value + ); + return 0; + } + + // Arg Count 6 + template + static SQInteger Func6(HSQUIRRELVM vm) { + typedef void (C::*M)(A1, A2, A3, A4, A5, A6); + M* methodPtr; + sq_getuserdata(vm, -1, (SQUserPointer*)&methodPtr, NULL); + M method = *methodPtr; + + C* ptr = NULL; + sq_getinstanceup(vm, 1, (SQUserPointer*)&ptr, NULL); + + (ptr->*method)( + Var(vm, 2).value, + Var(vm, 3).value, + Var(vm, 4).value, + Var(vm, 5).value, + Var(vm, 6).value, + Var(vm, 7).value + ); + return 0; + } + + template + static SQInteger Func6C(HSQUIRRELVM vm) { + typedef void (C::*M)(A1, A2, A3, A4, A5, A6) const; + M* methodPtr; + sq_getuserdata(vm, -1, (SQUserPointer*)&methodPtr, NULL); + M method = *methodPtr; + + C* ptr = NULL; + sq_getinstanceup(vm, 1, (SQUserPointer*)&ptr, NULL); + + (ptr->*method)( + Var(vm, 2).value, + Var(vm, 3).value, + Var(vm, 4).value, + Var(vm, 5).value, + Var(vm, 6).value, + Var(vm, 7).value + ); + return 0; + } + + // Arg Count 7 + template + static SQInteger Func7(HSQUIRRELVM vm) { + typedef void (C::*M)(A1, A2, A3, A4, A5, A6, A7); + M* methodPtr; + sq_getuserdata(vm, -1, (SQUserPointer*)&methodPtr, NULL); + M method = *methodPtr; + + C* ptr = NULL; + sq_getinstanceup(vm, 1, (SQUserPointer*)&ptr, NULL); + + (ptr->*method)( + Var(vm, 2).value, + Var(vm, 3).value, + Var(vm, 4).value, + Var(vm, 5).value, + Var(vm, 6).value, + Var(vm, 7).value, + Var(vm, 8).value + ); + return 0; + } + + template + static SQInteger Func7C(HSQUIRRELVM vm) { + typedef void (C::*M)(A1, A2, A3, A4, A5, A6, A7) const; + M* methodPtr; + sq_getuserdata(vm, -1, (SQUserPointer*)&methodPtr, NULL); + M method = *methodPtr; + + C* ptr = NULL; + sq_getinstanceup(vm, 1, (SQUserPointer*)&ptr, NULL); + + (ptr->*method)( + Var(vm, 2).value, + Var(vm, 3).value, + Var(vm, 4).value, + Var(vm, 5).value, + Var(vm, 6).value, + Var(vm, 7).value, + Var(vm, 8).value + ); + return 0; + } + + // Arg Count 8 + template + static SQInteger Func8(HSQUIRRELVM vm) { + typedef void (C::*M)(A1, A2, A3, A4, A5, A6, A7, A8); + M* methodPtr; + sq_getuserdata(vm, -1, (SQUserPointer*)&methodPtr, NULL); + M method = *methodPtr; + + C* ptr = NULL; + sq_getinstanceup(vm, 1, (SQUserPointer*)&ptr, NULL); + + (ptr->*method)( + Var(vm, 2).value, + Var(vm, 3).value, + Var(vm, 4).value, + Var(vm, 5).value, + Var(vm, 6).value, + Var(vm, 7).value, + Var(vm, 8).value, + Var(vm, 9).value + ); + return 0; + } + + template + static SQInteger Func8C(HSQUIRRELVM vm) { + typedef void (C::*M)(A1, A2, A3, A4, A5, A6, A7, A8) const; + M* methodPtr; + sq_getuserdata(vm, -1, (SQUserPointer*)&methodPtr, NULL); + M method = *methodPtr; + + C* ptr = NULL; + sq_getinstanceup(vm, 1, (SQUserPointer*)&ptr, NULL); + + (ptr->*method)( + Var(vm, 2).value, + Var(vm, 3).value, + Var(vm, 4).value, + Var(vm, 5).value, + Var(vm, 6).value, + Var(vm, 7).value, + Var(vm, 8).value, + Var(vm, 9).value + ); + return 0; + } + + // Arg Count 9 + template + static SQInteger Func9(HSQUIRRELVM vm) { + typedef void (C::*M)(A1, A2, A3, A4, A5, A6, A7, A8, A9); + M* methodPtr; + sq_getuserdata(vm, -1, (SQUserPointer*)&methodPtr, NULL); + M method = *methodPtr; + + C* ptr = NULL; + sq_getinstanceup(vm, 1, (SQUserPointer*)&ptr, NULL); + + (ptr->*method)( + Var(vm, 2).value, + Var(vm, 3).value, + Var(vm, 4).value, + Var(vm, 5).value, + Var(vm, 6).value, + Var(vm, 7).value, + Var(vm, 8).value, + Var(vm, 9).value, + Var(vm, 10).value + ); + return 0; + } + + template + static SQInteger Func9C(HSQUIRRELVM vm) { + typedef void (C::*M)(A1, A2, A3, A4, A5, A6, A7, A8, A9) const; + M* methodPtr; + sq_getuserdata(vm, -1, (SQUserPointer*)&methodPtr, NULL); + M method = *methodPtr; + + C* ptr = NULL; + sq_getinstanceup(vm, 1, (SQUserPointer*)&ptr, NULL); + + (ptr->*method)( + Var(vm, 2).value, + Var(vm, 3).value, + Var(vm, 4).value, + Var(vm, 5).value, + Var(vm, 6).value, + Var(vm, 7).value, + Var(vm, 8).value, + Var(vm, 9).value, + Var(vm, 10).value + ); + return 0; + } + + // Arg Count 10 + template + static SQInteger Func10(HSQUIRRELVM vm) { + typedef void (C::*M)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10); + M* methodPtr; + sq_getuserdata(vm, -1, (SQUserPointer*)&methodPtr, NULL); + M method = *methodPtr; + + C* ptr = NULL; + sq_getinstanceup(vm, 1, (SQUserPointer*)&ptr, NULL); + + (ptr->*method)( + Var(vm, 2).value, + Var(vm, 3).value, + Var(vm, 4).value, + Var(vm, 5).value, + Var(vm, 6).value, + Var(vm, 7).value, + Var(vm, 8).value, + Var(vm, 9).value, + Var(vm, 10).value, + Var(vm, 11).value + ); + return 0; + } + + template + static SQInteger Func10C(HSQUIRRELVM vm) { + typedef void (C::*M)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10) const; + M* methodPtr; + sq_getuserdata(vm, -1, (SQUserPointer*)&methodPtr, NULL); + M method = *methodPtr; + + C* ptr = NULL; + sq_getinstanceup(vm, 1, (SQUserPointer*)&ptr, NULL); + + (ptr->*method)( + Var(vm, 2).value, + Var(vm, 3).value, + Var(vm, 4).value, + Var(vm, 5).value, + Var(vm, 6).value, + Var(vm, 7).value, + Var(vm, 8).value, + Var(vm, 9).value, + Var(vm, 10).value, + Var(vm, 11).value + ); + return 0; + } + + // Arg Count 11 + template + static SQInteger Func11(HSQUIRRELVM vm) { + typedef void (C::*M)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11); + M* methodPtr; + sq_getuserdata(vm, -1, (SQUserPointer*)&methodPtr, NULL); + M method = *methodPtr; + + C* ptr = NULL; + sq_getinstanceup(vm, 1, (SQUserPointer*)&ptr, NULL); + + (ptr->*method)( + Var(vm, 2).value, + Var(vm, 3).value, + Var(vm, 4).value, + Var(vm, 5).value, + Var(vm, 6).value, + Var(vm, 7).value, + Var(vm, 8).value, + Var(vm, 9).value, + Var(vm, 10).value, + Var(vm, 11).value, + Var(vm, 12).value + ); + return 0; + } + + template + static SQInteger Func11C(HSQUIRRELVM vm) { + typedef void (C::*M)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11) const; + M* methodPtr; + sq_getuserdata(vm, -1, (SQUserPointer*)&methodPtr, NULL); + M method = *methodPtr; + + C* ptr = NULL; + sq_getinstanceup(vm, 1, (SQUserPointer*)&ptr, NULL); + + (ptr->*method)( + Var(vm, 2).value, + Var(vm, 3).value, + Var(vm, 4).value, + Var(vm, 5).value, + Var(vm, 6).value, + Var(vm, 7).value, + Var(vm, 8).value, + Var(vm, 9).value, + Var(vm, 10).value, + Var(vm, 11).value, + Var(vm, 12).value + ); + return 0; + } + + // Arg Count 12 + template + static SQInteger Func12(HSQUIRRELVM vm) { + typedef void (C::*M)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12); + M* methodPtr; + sq_getuserdata(vm, -1, (SQUserPointer*)&methodPtr, NULL); + M method = *methodPtr; + + C* ptr = NULL; + sq_getinstanceup(vm, 1, (SQUserPointer*)&ptr, NULL); + + (ptr->*method)( + Var(vm, 2).value, + Var(vm, 3).value, + Var(vm, 4).value, + Var(vm, 5).value, + Var(vm, 6).value, + Var(vm, 7).value, + Var(vm, 8).value, + Var(vm, 9).value, + Var(vm, 10).value, + Var(vm, 11).value, + Var(vm, 12).value, + Var(vm, 13).value + ); + return 0; + } + + template + static SQInteger Func12C(HSQUIRRELVM vm) { + typedef void (C::*M)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12) const; + M* methodPtr; + sq_getuserdata(vm, -1, (SQUserPointer*)&methodPtr, NULL); + M method = *methodPtr; + + C* ptr = NULL; + sq_getinstanceup(vm, 1, (SQUserPointer*)&ptr, NULL); + + (ptr->*method)( + Var(vm, 2).value, + Var(vm, 3).value, + Var(vm, 4).value, + Var(vm, 5).value, + Var(vm, 6).value, + Var(vm, 7).value, + Var(vm, 8).value, + Var(vm, 9).value, + Var(vm, 10).value, + Var(vm, 11).value, + Var(vm, 12).value, + Var(vm, 13).value + ); + return 0; + } + + // Arg Count 13 + template + static SQInteger Func13(HSQUIRRELVM vm) { + typedef void (C::*M)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13); + M* methodPtr; + sq_getuserdata(vm, -1, (SQUserPointer*)&methodPtr, NULL); + M method = *methodPtr; + + C* ptr = NULL; + sq_getinstanceup(vm, 1, (SQUserPointer*)&ptr, NULL); + + (ptr->*method)( + Var(vm, 2).value, + Var(vm, 3).value, + Var(vm, 4).value, + Var(vm, 5).value, + Var(vm, 6).value, + Var(vm, 7).value, + Var(vm, 8).value, + Var(vm, 9).value, + Var(vm, 10).value, + Var(vm, 11).value, + Var(vm, 12).value, + Var(vm, 13).value, + Var(vm, 14).value + ); + return 0; + } + + template + static SQInteger Func13C(HSQUIRRELVM vm) { + typedef void (C::*M)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13) const; + M* methodPtr; + sq_getuserdata(vm, -1, (SQUserPointer*)&methodPtr, NULL); + M method = *methodPtr; + + C* ptr = NULL; + sq_getinstanceup(vm, 1, (SQUserPointer*)&ptr, NULL); + + (ptr->*method)( + Var(vm, 2).value, + Var(vm, 3).value, + Var(vm, 4).value, + Var(vm, 5).value, + Var(vm, 6).value, + Var(vm, 7).value, + Var(vm, 8).value, + Var(vm, 9).value, + Var(vm, 10).value, + Var(vm, 11).value, + Var(vm, 12).value, + Var(vm, 13).value, + Var(vm, 14).value + ); + return 0; + } + + // Arg Count 14 + template + static SQInteger Func14(HSQUIRRELVM vm) { + typedef void (C::*M)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14); + M* methodPtr; + sq_getuserdata(vm, -1, (SQUserPointer*)&methodPtr, NULL); + M method = *methodPtr; + + C* ptr = NULL; + sq_getinstanceup(vm, 1, (SQUserPointer*)&ptr, NULL); + + (ptr->*method)( + Var(vm, 2).value, + Var(vm, 3).value, + Var(vm, 4).value, + Var(vm, 5).value, + Var(vm, 6).value, + Var(vm, 7).value, + Var(vm, 8).value, + Var(vm, 9).value, + Var(vm, 10).value, + Var(vm, 11).value, + Var(vm, 12).value, + Var(vm, 13).value, + Var(vm, 14).value, + Var(vm, 15).value + ); + return 0; + } + + template + static SQInteger Func14C(HSQUIRRELVM vm) { + typedef void (C::*M)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14) const; + M* methodPtr; + sq_getuserdata(vm, -1, (SQUserPointer*)&methodPtr, NULL); + M method = *methodPtr; + + C* ptr = NULL; + sq_getinstanceup(vm, 1, (SQUserPointer*)&ptr, NULL); + + (ptr->*method)( + Var(vm, 2).value, + Var(vm, 3).value, + Var(vm, 4).value, + Var(vm, 5).value, + Var(vm, 6).value, + Var(vm, 7).value, + Var(vm, 8).value, + Var(vm, 9).value, + Var(vm, 10).value, + Var(vm, 11).value, + Var(vm, 12).value, + Var(vm, 13).value, + Var(vm, 14).value, + Var(vm, 15).value + ); + return 0; + } + +}; + + +// +// Member Function Resolvers +// + +// Arg Count 0 +template +inline SQFUNCTION SqMemberFunc(R (C::*method)()) { + return &SqMember::Func0; +} + +template +inline SQFUNCTION SqMemberFunc(R (C::*method)() const) { + return &SqMember::Func0C; +} + +// Arg Count 1 +template +inline SQFUNCTION SqMemberFunc(R (C::*method)(A1)) { + return &SqMember::template Func1; +} + +template +inline SQFUNCTION SqMemberFunc(R (C::*method)(A1) const) { + return &SqMember::template Func1C; +} + +// Arg Count 2 +template +inline SQFUNCTION SqMemberFunc(R (C::*method)(A1, A2)) { + return &SqMember::template Func2; +} + +template +inline SQFUNCTION SqMemberFunc(R (C::*method)(A1, A2) const) { + return &SqMember::template Func2C; +} + +// Arg Count 3 +template +inline SQFUNCTION SqMemberFunc(R (C::*method)(A1, A2, A3)) { + return &SqMember::template Func3; +} + +template +inline SQFUNCTION SqMemberFunc(R (C::*method)(A1, A2, A3) const) { + return &SqMember::template Func3C; +} + +// Arg Count 4 +template +inline SQFUNCTION SqMemberFunc(R (C::*method)(A1, A2, A3, A4)) { + return &SqMember::template Func4; +} + +template +inline SQFUNCTION SqMemberFunc(R (C::*method)(A1, A2, A3, A4) const) { + return &SqMember::template Func4C; +} + +// Arg Count 5 +template +inline SQFUNCTION SqMemberFunc(R (C::*method)(A1, A2, A3, A4, A5)) { + return &SqMember::template Func5; +} + +template +inline SQFUNCTION SqMemberFunc(R (C::*method)(A1, A2, A3, A4, A5) const) { + return &SqMember::template Func5C; +} + +// Arg Count 6 +template +inline SQFUNCTION SqMemberFunc(R (C::*method)(A1, A2, A3, A4, A5, A6)) { + return &SqMember::template Func6; +} + +template +inline SQFUNCTION SqMemberFunc(R (C::*method)(A1, A2, A3, A4, A5, A6) const) { + return &SqMember::template Func6C; +} + +// Arg Count 7 +template +inline SQFUNCTION SqMemberFunc(R (C::*method)(A1, A2, A3, A4, A5, A6, A7)) { + return &SqMember::template Func7; +} + +template +inline SQFUNCTION SqMemberFunc(R (C::*method)(A1, A2, A3, A4, A5, A6, A7) const) { + return &SqMember::template Func7C; +} + +// Arg Count 8 +template +inline SQFUNCTION SqMemberFunc(R (C::*method)(A1, A2, A3, A4, A5, A6, A7, A8)) { + return &SqMember::template Func8; +} + +template +inline SQFUNCTION SqMemberFunc(R (C::*method)(A1, A2, A3, A4, A5, A6, A7, A8) const) { + return &SqMember::template Func8C; +} + +// Arg Count 9 +template +inline SQFUNCTION SqMemberFunc(R (C::*method)(A1, A2, A3, A4, A5, A6, A7, A8, A9)) { + return &SqMember::template Func9; +} + +template +inline SQFUNCTION SqMemberFunc(R (C::*method)(A1, A2, A3, A4, A5, A6, A7, A8, A9) const) { + return &SqMember::template Func9C; +} + +// Arg Count 10 +template +inline SQFUNCTION SqMemberFunc(R (C::*method)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10)) { + return &SqMember::template Func10; +} + +template +inline SQFUNCTION SqMemberFunc(R (C::*method)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10) const) { + return &SqMember::template Func10C; +} +// Arg Count 11 +template +inline SQFUNCTION SqMemberFunc(R (C::*method)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11)) { + return &SqMember::template Func11; +} + +template +inline SQFUNCTION SqMemberFunc(R (C::*method)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11) const) { + return &SqMember::template Func11C; +} +// Arg Count 12 +template +inline SQFUNCTION SqMemberFunc(R (C::*method)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12)) { + return &SqMember::template Func12; +} + +template +inline SQFUNCTION SqMemberFunc(R (C::*method)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12) const) { + return &SqMember::template Func12C; +} +// Arg Count 13 +template +inline SQFUNCTION SqMemberFunc(R (C::*method)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13)) { + return &SqMember::template Func13; +} + +template +inline SQFUNCTION SqMemberFunc(R (C::*method)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13) const) { + return &SqMember::template Func13C; +} +// Arg Count 14 +template +inline SQFUNCTION SqMemberFunc(R (C::*method)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14)) { + return &SqMember::template Func14; +} + +template +inline SQFUNCTION SqMemberFunc(R (C::*method)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14) const) { + return &SqMember::template Func14C; +} + + +// +// Variable Get +// + +template +inline SQInteger sqDefaultGet(HSQUIRRELVM vm) { + C* ptr = NULL; + sq_getinstanceup(vm, 1, (SQUserPointer*)&ptr, NULL); + + typedef V C::*M; + M* memberPtr = NULL; + sq_getuserdata(vm, -1, (SQUserPointer*)&memberPtr, NULL); // Get Member... + M member = *memberPtr; + + PushVar(vm, ptr->*member); + + return 1; +} + +inline SQInteger sqVarGet(HSQUIRRELVM vm) { + // Find the get method in the get table + sq_push(vm, 2); + if (SQ_FAILED( sq_get(vm,-2) )) { +#if (SQUIRREL_VERSION_NUMBER >= 200) && (SQUIRREL_VERSION_NUMBER < 300) // Squirrel 2.x + return sq_throwerror(vm,_SC("Member Variable not found")); +#else // Squirrel 3.x + sq_pushnull(vm); + return sq_throwobject(vm); +#endif + } + + // push 'this' + sq_push(vm, 1); + + // Call the getter + sq_call(vm, 1, true, ErrorHandling::IsEnabled()); + return 1; +} + +// +// Variable Set +// + +template +inline SQInteger sqDefaultSet(HSQUIRRELVM vm) { + C* ptr = NULL; + sq_getinstanceup(vm, 1, (SQUserPointer*)&ptr, NULL); + + typedef V C::*M; + M* memberPtr = NULL; + sq_getuserdata(vm, -1, (SQUserPointer*)&memberPtr, NULL); // Get Member... + M member = *memberPtr; + + ptr->*member = Var(vm, 2).value; + return 0; +} + +inline SQInteger sqVarSet(HSQUIRRELVM vm) { + // Find the set method in the set table + sq_push(vm, 2); + if (SQ_FAILED( sq_get(vm,-2) )) { +#if (SQUIRREL_VERSION_NUMBER >= 200) && (SQUIRREL_VERSION_NUMBER < 300) // Squirrel 2.x + return sq_throwerror(vm,_SC("Member Variable not found")); +#else // Squirrel 3.x + sq_pushnull(vm); + return sq_throwobject(vm); +#endif + } + + // push 'this' + sq_push(vm, 1); + sq_push(vm, 3); + + // Call the setter + sq_call(vm, 2, false, ErrorHandling::IsEnabled()); + + return 0; +} +} + +#endif diff --git a/squirrel_3_0_1_stable/sqrat/sqrat/sqratObject.h b/squirrel_3_0_1_stable/sqrat/sqrat/sqratObject.h new file mode 100644 index 000000000..a1cac9126 --- /dev/null +++ b/squirrel_3_0_1_stable/sqrat/sqrat/sqratObject.h @@ -0,0 +1,310 @@ +// +// SqratObject: Referenced Squirrel Object Wrapper +// + +// +// Copyright (c) 2009 Brandon Jones +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would be +// appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, and must not be +// misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source +// distribution. +// + +#if !defined(_SCRAT_OBJECT_H_) +#define _SCRAT_OBJECT_H_ + +#include +#include +#include "sqratTypes.h" +#include "sqratOverloadMethods.h" +#include "sqratUtil.h" + +namespace Sqrat { + +class Object { +protected: + HSQUIRRELVM vm; + HSQOBJECT obj; + bool release; + + Object(HSQUIRRELVM v, bool releaseOnDestroy = true) : vm(v), release(releaseOnDestroy) { + sq_resetobject(&obj); + } + +public: + Object() : vm(0), release(true) { + sq_resetobject(&obj); + } + + Object(const Object& so) : vm(so.vm), obj(so.obj), release(so.release) { + sq_addref(vm, &obj); + } + + Object(HSQOBJECT o, HSQUIRRELVM v = DefaultVM::Get()) : vm(v), obj(o), release(true) { + sq_addref(vm, &obj); + } + + template + Object(T* instance, HSQUIRRELVM v = DefaultVM::Get()) : vm(v), release(true) { + ClassType::PushInstance(vm, instance); + sq_getstackobj(vm, -1, &obj); + sq_addref(vm, &obj); + } + + virtual ~Object() { + if(release) { + Release(); + } + } + + Object& operator=(const Object& so) { + if(release) { + Release(); + } + vm = so.vm; + obj = so.obj; + release = so.release; + sq_addref(vm, &GetObject()); + return *this; + } + + HSQUIRRELVM& GetVM() { + return vm; + } + + HSQUIRRELVM GetVM() const { + return vm; + } + + SQObjectType GetType() const { + return GetObject()._type; + } + + bool IsNull() const { + return sq_isnull(GetObject()); + } + + virtual HSQOBJECT GetObject() const { + return obj; + } + + virtual HSQOBJECT& GetObject() { + return obj; + } + + operator HSQOBJECT&() { + return GetObject(); + } + + void Release() { + sq_release(vm, &obj); + } + + SQUserPointer GetInstanceUP(SQUserPointer tag = NULL) const { + SQUserPointer up; + sq_pushobject(vm, GetObject()); + sq_getinstanceup(vm, -1, &up, tag); + sq_pop(vm, 1); + return up; + } + + Object GetSlot(const SQChar* slot) const { + HSQOBJECT slotObj; + sq_pushobject(vm, GetObject()); + sq_pushstring(vm, slot, -1); + if(SQ_FAILED(sq_get(vm, -2))) { + sq_pop(vm, 1); + return Object(vm); // Return a NULL object + } else { + sq_getstackobj(vm, -1, &slotObj); + Object ret(slotObj, vm); // must addref before the pop! + sq_pop(vm, 2); + return ret; + } + } + + template + T Cast() const { + sq_pushobject(vm, GetObject()); + T ret = Var(vm, -1).value; + sq_pop(vm, 1); + return ret; + } + + Object GetSlot(SQInteger index) const { + HSQOBJECT slotObj; + sq_pushobject(vm, GetObject()); + sq_pushinteger(vm, index); + if(SQ_FAILED(sq_get(vm, -2))) { + sq_pop(vm, 1); + return Object(vm); // Return a NULL object + } else { + sq_getstackobj(vm, -1, &slotObj); + Object ret(slotObj, vm); // must addref before the pop! + sq_pop(vm, 2); + return ret; + } + } + + template + inline Object operator[](T slot) + { + return GetSlot(slot); + } + + + SQInteger GetSize() const { + sq_pushobject(vm, GetObject()); + SQInteger ret = sq_getsize(vm, -1); + sq_pop(vm, 1); + return ret; + } + +protected: + // Bind a function and it's associated Squirrel closure to the object + inline void BindFunc(const SQChar* name, void* method, size_t methodSize, SQFUNCTION func, bool staticVar = false) { + sq_pushobject(vm, GetObject()); + sq_pushstring(vm, name, -1); + + SQUserPointer methodPtr = sq_newuserdata(vm, static_cast(methodSize)); + memcpy(methodPtr, method, methodSize); + + sq_newclosure(vm, func, 1); + sq_newslot(vm, -3, staticVar); + sq_pop(vm,1); // pop table + } + + inline void BindFunc(const SQInteger index, void* method, size_t methodSize, SQFUNCTION func, bool staticVar = false) { + sq_pushobject(vm, GetObject()); + sq_pushinteger(vm, index); + + SQUserPointer methodPtr = sq_newuserdata(vm, static_cast(methodSize)); + memcpy(methodPtr, method, methodSize); + + sq_newclosure(vm, func, 1); + sq_newslot(vm, -3, staticVar); + sq_pop(vm,1); // pop table + } + + + // Bind a function and it's associated Squirrel closure to the object + inline void BindOverload(const SQChar* name, void* method, size_t methodSize, SQFUNCTION func, SQFUNCTION overload, int argCount, bool staticVar = false) { + string overloadName = SqOverloadName::Get(name, argCount); + + sq_pushobject(vm, GetObject()); + + // Bind overload handler + sq_pushstring(vm, name, -1); + sq_pushstring(vm, name, -1); // function name is passed as a free variable + sq_newclosure(vm, overload, 1); + sq_newslot(vm, -3, staticVar); + + // Bind overloaded function + sq_pushstring(vm, overloadName.c_str(), -1); + SQUserPointer methodPtr = sq_newuserdata(vm, static_cast(methodSize)); + memcpy(methodPtr, method, methodSize); + sq_newclosure(vm, func, 1); + sq_newslot(vm, -3, staticVar); + + sq_pop(vm,1); // pop table + } + + // Set the value of a variable on the object. Changes to values set this way are not reciprocated + template + inline void BindValue(const SQChar* name, const V& val, bool staticVar = false) { + sq_pushobject(vm, GetObject()); + sq_pushstring(vm, name, -1); + PushVar(vm, val); + sq_newslot(vm, -3, staticVar); + sq_pop(vm,1); // pop table + } + template + inline void BindValue(const SQInteger index, const V& val, bool staticVar = false) { + sq_pushobject(vm, GetObject()); + sq_pushinteger(vm, index); + PushVar(vm, val); + sq_newslot(vm, -3, staticVar); + sq_pop(vm,1); // pop table + } + + // Set the value of an instance on the object. Changes to values set this way are reciprocated back to the source instance + template + inline void BindInstance(const SQChar* name, V* val, bool staticVar = false) { + sq_pushobject(vm, GetObject()); + sq_pushstring(vm, name, -1); + PushVar(vm, val); + sq_newslot(vm, -3, staticVar); + sq_pop(vm,1); // pop table + } + template + inline void BindInstance(const SQInteger index, V* val, bool staticVar = false) { + sq_pushobject(vm, GetObject()); + sq_pushinteger(vm, index); + PushVar(vm, val); + sq_newslot(vm, -3, staticVar); + sq_pop(vm,1); // pop table + } +}; + + +// +// Overridden Getter/Setter +// + +template<> +struct Var { + Object value; + Var(HSQUIRRELVM vm, SQInteger idx) { + HSQOBJECT sqValue; + sq_getstackobj(vm, idx, &sqValue); + value = Object(sqValue, vm); + } + static void push(HSQUIRRELVM vm, Object& value) { + sq_pushobject(vm, value.GetObject()); + } +}; + +template<> +struct Var { + Object value; + Var(HSQUIRRELVM vm, SQInteger idx) { + HSQOBJECT sqValue; + sq_getstackobj(vm, idx, &sqValue); + value = Object(sqValue, vm); + } + static void push(HSQUIRRELVM vm, Object& value) { + sq_pushobject(vm, value.GetObject()); + } +}; + +template<> +struct Var { + Object value; + Var(HSQUIRRELVM vm, SQInteger idx) { + HSQOBJECT sqValue; + sq_getstackobj(vm, idx, &sqValue); + value = Object(sqValue, vm); + } + static void push(HSQUIRRELVM vm, Object& value) { + sq_pushobject(vm, value.GetObject()); + } +}; + +} + +#endif diff --git a/squirrel_3_0_1_stable/sqrat/sqrat/sqratOverloadMethods.h b/squirrel_3_0_1_stable/sqrat/sqrat/sqratOverloadMethods.h new file mode 100644 index 000000000..47a40acba --- /dev/null +++ b/squirrel_3_0_1_stable/sqrat/sqrat/sqratOverloadMethods.h @@ -0,0 +1,485 @@ +// +// SqratGlobalMethods: Global Methods +// + +// +// Copyright (c) 2009 Brandon Jones +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would be +// appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, and must not be +// misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source +// distribution. +// + +#if !defined(_SQRAT_OVERLOAD_METHODS_H_) +#define _SQRAT_OVERLOAD_METHODS_H_ + +#include +#include +#include +#include "sqratTypes.h" +#include "sqratUtil.h" + +namespace Sqrat { + +// +// Overload name generator +// +class SqOverloadName { +public: + static string Get(const SQChar* name, int args) { + std::basic_stringstream overloadName; + overloadName << _SC("__sqrat_ol_ ") << name << _SC("_") << args; + + return overloadName.str(); + } +}; + +// +// Squirrel Overload Functions +// + +template +class SqOverload { +public: + static SQInteger Func(HSQUIRRELVM vm) { + // Get the arg count + int argCount = sq_gettop(vm) - 2; + + const SQChar* funcName; + sq_getstring(vm, -1, &funcName); // get the function name (free variable) + + string overloadName = SqOverloadName::Get(funcName, argCount); + + sq_pushstring(vm, overloadName.c_str(), -1); + if(SQ_FAILED(sq_get(vm, 1))) { // Lookup the proper overload + return sq_throwerror(vm, "No overload matching this argument list found");// How to best appropriately error? + } + + // Push the args again + for(int i = 1; i <= argCount + 1; ++i) { + sq_push(vm, i); + } + + sq_call(vm, argCount + 1, true, ErrorHandling::IsEnabled()); + + return 1; + } +}; + +// +// void return specialization +// + +template <> +class SqOverload { +public: + static SQInteger Func(HSQUIRRELVM vm) { + // Get the arg count + int argCount = sq_gettop(vm) - 2; + + const SQChar* funcName; + sq_getstring(vm, -1, &funcName); // get the function name (free variable) + + string overloadName = SqOverloadName::Get(funcName, argCount); + + sq_pushstring(vm, overloadName.c_str(), -1); + if(SQ_FAILED(sq_get(vm, 1))) { // Lookup the proper overload + return sq_throwerror(vm, "No overload matching this argument list found");// How to best appropriately error? + } + + // Push the args again + for(int i = 1; i <= argCount + 1; ++i) { + sq_push(vm, i); + } + + sq_call(vm, argCount + 1, false, ErrorHandling::IsEnabled()); + + return 0; + } +}; + +// +// Overload handler resolver +// + +template +inline SQFUNCTION SqOverloadFunc(R (*method)) { + return &SqOverload::Func; +} + +template +inline SQFUNCTION SqOverloadFunc(R (C::*method)) { + return &SqOverload::Func; +} + +template +inline SQFUNCTION SqOverloadFunc(R (C::*method)() const ) { + return &SqOverload::Func; +} + +template +inline SQFUNCTION SqOverloadFunc(R (C::*method)(A1) const ) { + return &SqOverload::Func; +} + +template +inline SQFUNCTION SqOverloadFunc(R (C::*method)(A1, A2) const ) { + return &SqOverload::Func; +} + +template +inline SQFUNCTION SqOverloadFunc(R (C::*method)(A1, A2, A3) const ) { + return &SqOverload::Func; +} + +template +inline SQFUNCTION SqOverloadFunc(R (C::*method)(A1, A2, A3, A4) const ) { + return &SqOverload::Func; +} + +template +inline SQFUNCTION SqOverloadFunc(R (C::*method)(A1, A2, A3, A4, A5) const ) { + return &SqOverload::Func; +} + +template +inline SQFUNCTION SqOverloadFunc(R (C::*method)(A1, A2, A3, A4, A5, A6) const ) { + return &SqOverload::Func; +} + +template +inline SQFUNCTION SqOverloadFunc(R (C::*method)(A1, A2, A3, A4, A5, A6, A7) const ) { + return &SqOverload::Func; +} + +template +inline SQFUNCTION SqOverloadFunc(R (C::*method)(A1, A2, A3, A4, A5, A6, A7, A8) const ) { + return &SqOverload::Func; +} + +template +inline SQFUNCTION SqOverloadFunc(R (C::*method)(A1, A2, A3, A4, A5, A6, A7, A8, A9) const ) { + return &SqOverload::Func; +} + +template +inline SQFUNCTION SqOverloadFunc(R (C::*method)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10) const ) { + return &SqOverload::Func; +} + +template +inline SQFUNCTION SqOverloadFunc(R (C::*method)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11) const ) { + return &SqOverload::Func; +} + +template +inline SQFUNCTION SqOverloadFunc(R (C::*method)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12) const ) { + return &SqOverload::Func; +} + +template +inline SQFUNCTION SqOverloadFunc(R (C::*method)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13) const ) { + return &SqOverload::Func; +} + +template +inline SQFUNCTION SqOverloadFunc(R (C::*method)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14) const ) { + return &SqOverload::Func; +} + +// +// Query argument count +// + +// Arg Count 0 +template +inline int SqGetArgCount(R (*method)()) { + return 0; +} + +// Arg Count 1 +template +inline int SqGetArgCount(R (*method)(A1)) { + return 1; +} + +// Arg Count 2 +template +inline int SqGetArgCount(R (*method)(A1, A2)) { + return 2; +} + +// Arg Count 3 +template +inline int SqGetArgCount(R (*method)(A1, A2, A3)) { + return 3; +} + +// Arg Count 4 +template +inline int SqGetArgCount(R (*method)(A1, A2, A3, A4)) { + return 4; +} + +// Arg Count 5 +template +inline int SqGetArgCount(R (*method)(A1, A2, A3, A4, A5)) { + return 5; +} + +// Arg Count 6 +template +inline int SqGetArgCount(R (*method)(A1, A2, A3, A4, A5, A6)) { + return 6; +} + +// Arg Count 7 +template +inline int SqGetArgCount(R (*method)(A1, A2, A3, A4, A5, A6, A7)) { + return 7; +} + +// Arg Count 8 +template +inline int SqGetArgCount(R (*method)(A1, A2, A3, A4, A5, A6, A7, A8)) { + return 8; +} + +// Arg Count 9 +template +inline int SqGetArgCount(R (*method)(A1, A2, A3, A4, A5, A6, A7, A8, A9)) { + return 9; +} + +// Arg Count 10 +template +inline int SqGetArgCount(R (*method)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10)) { + return 10; +} + +// Arg Count 11 +template +inline int SqGetArgCount(R (*method)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11)) { + return 11; +} + +// Arg Count 12 +template +inline int SqGetArgCount(R (*method)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12)) { + return 12; +} + +// Arg Count 13 +template +inline int SqGetArgCount(R (*method)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13)) { + return 13; +} + +// Arg Count 14 +template +inline int SqGetArgCount(R (*method)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14)) { + return 14; +} + +// +// Query member function argument count +// + +// Arg Count 0 +template +inline int SqGetArgCount(R (C::*method)()) { + return 0; +} + +// Arg Count 1 +template +inline int SqGetArgCount(R (C::*method)(A1)) { + return 1; +} + +// Arg Count 2 +template +inline int SqGetArgCount(R (C::*method)(A1, A2)) { + return 2; +} + +// Arg Count 3 +template +inline int SqGetArgCount(R (C::*method)(A1, A2, A3)) { + return 3; +} + +// Arg Count 4 +template +inline int SqGetArgCount(R (C::*method)(A1, A2, A3, A4)) { + return 4; +} + +// Arg Count 5 +template +inline int SqGetArgCount(R (C::*method)(A1, A2, A3, A4, A5)) { + return 5; +} + +// Arg Count 6 +template +inline int SqGetArgCount(R (C::*method)(A1, A2, A3, A4, A5, A6)) { + return 6; +} + +// Arg Count 7 +template +inline int SqGetArgCount(R (C::*method)(A1, A2, A3, A4, A5, A6, A7)) { + return 7; +} + +// Arg Count 8 +template +inline int SqGetArgCount(R (C::*method)(A1, A2, A3, A4, A5, A6, A7, A8)) { + return 8; +} + +// Arg Count 9 +template +inline int SqGetArgCount(R (C::*method)(A1, A2, A3, A4, A5, A6, A7, A8, A9)) { + return 9; +} + +// Arg Count 10 +template +inline int SqGetArgCount(R (C::*method)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10)) { + return 10; +} + +// Arg Count 11 +template +inline int SqGetArgCount(R (C::*method)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11)) { + return 11; +} + +// Arg Count 12 +template +inline int SqGetArgCount(R (C::*method)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12)) { + return 12; +} + +// Arg Count 13 +template +inline int SqGetArgCount(R (C::*method)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13)) { + return 13; +} + +// Arg Count 14 +template +inline int SqGetArgCount(R (C::*method)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14)) { + return 14; +} + +// +// Query const member function argument count +// + +// Arg Count 0 +template +inline int SqGetArgCount(R (C::*method)() const) { + return 0; +} + +// Arg Count 1 +template +inline int SqGetArgCount(R (C::*method)(A1) const) { + return 1; +} + +// Arg Count 2 +template +inline int SqGetArgCount(R (C::*method)(A1, A2) const) { + return 2; +} + +// Arg Count 3 +template +inline int SqGetArgCount(R (C::*method)(A1, A2, A3) const) { + return 3; +} + +// Arg Count 4 +template +inline int SqGetArgCount(R (C::*method)(A1, A2, A3, A4) const) { + return 4; +} + +// Arg Count 5 +template +inline int SqGetArgCount(R (C::*method)(A1, A2, A3, A4, A5) const) { + return 5; +} + +// Arg Count 6 +template +inline int SqGetArgCount(R (C::*method)(A1, A2, A3, A4, A5, A6) const) { + return 6; +} + +// Arg Count 7 +template +inline int SqGetArgCount(R (C::*method)(A1, A2, A3, A4, A5, A6, A7) const) { + return 7; +} + +// Arg Count 8 +template +inline int SqGetArgCount(R (C::*method)(A1, A2, A3, A4, A5, A6, A7, A8) const) { + return 8; +} + +// Arg Count 9 +template +inline int SqGetArgCount(R (C::*method)(A1, A2, A3, A4, A5, A6, A7, A8, A9) const) { + return 9; +} + +// Arg Count 10 +template +inline int SqGetArgCount(R (C::*method)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10) const) { + return 10; +} +// Arg Count 11 +template +inline int SqGetArgCount(R (C::*method)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11) const) { + return 11; +} +// Arg Count 12 +template +inline int SqGetArgCount(R (C::*method)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12) const) { + return 12; +} +// Arg Count 13 +template +inline int SqGetArgCount(R (C::*method)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13) const) { + return 13; +} +// Arg Count 14 +template +inline int SqGetArgCount(R (C::*method)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14) const) { + return 14; +} + +} + +#endif diff --git a/squirrel_3_0_1_stable/sqrat/sqrat/sqratScript.h b/squirrel_3_0_1_stable/sqrat/sqrat/sqratScript.h new file mode 100644 index 000000000..4ef07e309 --- /dev/null +++ b/squirrel_3_0_1_stable/sqrat/sqrat/sqratScript.h @@ -0,0 +1,141 @@ +// +// SqratScript: Script Compilation and Execution +// + +// +// Copyright (c) 2009 Brandon Jones +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would be +// appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, and must not be +// misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source +// distribution. +// + +#if !defined(_SCRAT_SCRIPT_H_) +#define _SCRAT_SCRIPT_H_ + +#include +#include +#include + +#include "sqratObject.h" + +namespace Sqrat { + +class Script : public Object { +public: + Script(HSQUIRRELVM v = DefaultVM::Get()) : Object(v, false) { + } + + ~Script() + { + if(!sq_isnull(obj)) { + sq_release(vm, &obj); + } + } + void CompileString(const string& script) { + if(!sq_isnull(obj)) { + sq_release(vm, &obj); + } + if(SQ_FAILED(sq_compilebuffer(vm, script.c_str(), static_cast(script.size() * sizeof(SQChar)), _SC(""), true))) { + throw Exception(LastErrorString(vm)); + } + sq_getstackobj(vm,-1,&obj); + sq_addref(vm, &obj); + sq_pop(vm, 1); + } + + bool CompileString(const string& script, string& errMsg) { + if(!sq_isnull(obj)) { + sq_release(vm, &obj); + } + if(SQ_FAILED(sq_compilebuffer(vm, script.c_str(), static_cast(script.size() * sizeof(SQChar)), _SC(""), true))) { + errMsg = LastErrorString(vm); + return false; + } + sq_getstackobj(vm,-1,&obj); + sq_addref(vm, &obj); + sq_pop(vm, 1); + return true; + } + + void CompileFile(const string& path) { + if(!sq_isnull(obj)) { + sq_release(vm, &obj); + } + if(SQ_FAILED(sqstd_loadfile(vm, path.c_str(), true))) { + throw Exception(LastErrorString(vm)); + } + sq_getstackobj(vm,-1,&obj); + sq_addref(vm, &obj); + sq_pop(vm, 1); + } + + bool CompileFile(const string& path, string& errMsg) { + if(!sq_isnull(obj)) { + sq_release(vm, &obj); + } + if(SQ_FAILED(sqstd_loadfile(vm, path.c_str(), true))) { + errMsg = LastErrorString(vm); + return false; + } + sq_getstackobj(vm,-1,&obj); + sq_addref(vm, &obj); + sq_pop(vm, 1); + return true; + } + + void Run() { + if(!sq_isnull(obj)) { + SQRESULT result; + sq_pushobject(vm, obj); + sq_pushroottable(vm); + result = sq_call(vm, 1, false, true); + sq_pop(vm, 1); + if(SQ_FAILED(result)) { + throw Exception(LastErrorString(vm)); + } + } + } + + bool Run(string& errMsg) { + if(!sq_isnull(obj)) { + SQRESULT result; + sq_pushobject(vm, obj); + sq_pushroottable(vm); + result = sq_call(vm, 1, false, true); + sq_pop(vm, 1); + if(SQ_FAILED(result)) { + errMsg = LastErrorString(vm); + return false; + } + } + return true; + } + + + void WriteCompiledFile(const string& path) { + if(!sq_isnull(obj)) { + sq_pushobject(vm, obj); + sqstd_writeclosuretofile(vm, path.c_str()); + //sq_pop(vm, 1); // needed? + } + } +}; +} + +#endif diff --git a/squirrel_3_0_1_stable/sqrat/sqrat/sqratTable.h b/squirrel_3_0_1_stable/sqrat/sqrat/sqratTable.h new file mode 100644 index 000000000..df3d4cda7 --- /dev/null +++ b/squirrel_3_0_1_stable/sqrat/sqrat/sqratTable.h @@ -0,0 +1,162 @@ +// +// SqratTable: Table Binding +// + +// +// Copyright (c) 2009 Brandon Jones +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would be +// appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, and must not be +// misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source +// distribution. +// + +#if !defined(_SCRAT_TABLE_H_) +#define _SCRAT_TABLE_H_ + +#include +#include + +#include "sqratObject.h" +#include "sqratFunction.h" +#include "sqratGlobalMethods.h" + +namespace Sqrat { + +class TableBase : public Object { +public: + TableBase(HSQUIRRELVM v = DefaultVM::Get()) : Object(v, true) { + } + + TableBase(const Object& obj) : Object(obj) { + } + + // Bind a Table or Class to the Table (Can be used to facilitate Namespaces) + // Note: Bind cannot be called "inline" like other functions because it introduces order-of-initialization bugs. + void Bind(const SQChar* name, Object& obj) { + sq_pushobject(vm, GetObject()); + sq_pushstring(vm, name, -1); + sq_pushobject(vm, obj.GetObject()); + sq_newslot(vm, -3, false); + sq_pop(vm,1); // pop table + } + + // Bind a raw Squirrel closure to the Table + TableBase& SquirrelFunc(const SQChar* name, SQFUNCTION func) { + sq_pushobject(vm, GetObject()); + sq_pushstring(vm, name, -1); + sq_newclosure(vm, func, 0); + sq_newslot(vm, -3, false); + sq_pop(vm,1); // pop table + + return *this; + } + + // + // Variable Binding + // + + template + TableBase& SetValue(const SQChar* name, const V& val) { + BindValue(name, val, false); + return *this; + } + template + TableBase& SetValue(const SQInteger index, const V& val) { + BindValue(index, val, false); + return *this; + } + + template + TableBase& SetInstance(const SQChar* name, V* val) { + BindInstance(name, val, false); + return *this; + } + + template + TableBase& Func(const SQChar* name, F method) { + BindFunc(name, &method, sizeof(method), SqGlobalFunc(method)); + return *this; + } + + template + TableBase& Overload(const SQChar* name, F method) { + BindOverload(name, &method, sizeof(method), SqGlobalFunc(method), SqOverloadFunc(method), SqGetArgCount(method)); + return *this; + } + + // + // Function Calls + // + + Function GetFunction(const SQChar* name) { + HSQOBJECT funcObj; + sq_pushobject(vm, GetObject()); + sq_pushstring(vm, name, -1); + if(SQ_FAILED(sq_get(vm, -2))) { + sq_pushnull(vm); + } + sq_getstackobj(vm, -1, &funcObj); + Function ret(vm, GetObject(), funcObj); // must addref before the pop! + + sq_pop(vm, 2); + + return ret; + } + Function GetFunction(const SQInteger index) { + HSQOBJECT funcObj; + sq_pushobject(vm, GetObject()); + sq_pushinteger(vm, index); + if(SQ_FAILED(sq_get(vm, -2))) { + sq_pushnull(vm); + } + sq_getstackobj(vm, -1, &funcObj); + Function ret(vm, GetObject(), funcObj); + sq_pop(vm, 2); + + return ret; + } +}; + +class Table : public TableBase { +public: + Table(HSQUIRRELVM v = DefaultVM::Get()) : TableBase(v) { + sq_newtable(vm); + sq_getstackobj(vm,-1,&obj); + sq_addref(vm, &obj); + sq_pop(vm,1); + } + Table(const Object& obj) : TableBase(obj) { + } +}; + +// +// Root Table +// + +class RootTable : public TableBase { +public: + RootTable(HSQUIRRELVM v = DefaultVM::Get()) : TableBase(v) { + sq_pushroottable(vm); + sq_getstackobj(vm,-1,&obj); + sq_addref(vm, &obj); + sq_pop(v,1); // pop root table + } +}; +} + +#endif diff --git a/squirrel_3_0_1_stable/sqrat/sqrat/sqratTypes.h b/squirrel_3_0_1_stable/sqrat/sqrat/sqratTypes.h new file mode 100644 index 000000000..09c9a7192 --- /dev/null +++ b/squirrel_3_0_1_stable/sqrat/sqrat/sqratTypes.h @@ -0,0 +1,341 @@ +// +// SqratTypes: Type Translators +// + +// +// Copyright (c) 2009 Brandon Jones +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would be +// appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, and must not be +// misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source +// distribution. +// + +#if !defined(_SCRAT_TYPES_H_) +#define _SCRAT_TYPES_H_ + +#include +#include + +#include "sqratClassType.h" + +namespace Sqrat { + +// +// Variable Accessors +// + +// Generic classes +template +struct Var { + T value; + Var(HSQUIRRELVM vm, SQInteger idx) { + value = *ClassType::GetInstance(vm, idx); + } + static void push(HSQUIRRELVM vm, T value) { + ClassType::PushInstanceCopy(vm, value); + } +}; + +template +struct Var { + T value; + Var(HSQUIRRELVM vm, SQInteger idx) { + value = *ClassType::GetInstance(vm, idx); + } + static void push(HSQUIRRELVM vm, T value) { + ClassType::PushInstanceCopy(vm, value); + } +}; + +template +struct Var { + T* value; + Var(HSQUIRRELVM vm, SQInteger idx) { + value = ClassType::GetInstance(vm, idx); + } + static void push(HSQUIRRELVM vm, T* value) { + ClassType::PushInstance(vm, value); + } +}; + +template +struct Var { + T value; + Var(HSQUIRRELVM vm, SQInteger idx) { + value = *ClassType::GetInstance(vm, idx); + } + static void push(HSQUIRRELVM vm, T value) { + ClassType::PushInstanceCopy(vm, value); + } +}; + +template +struct Var { + T* value; + Var(HSQUIRRELVM vm, SQInteger idx) { + value = ClassType::GetInstance(vm, idx); + } + static void push(HSQUIRRELVM vm, T* value) { + ClassType::PushInstance(vm, value); + } +}; + +// Integer Types +#define SCRAT_INTEGER( type ) \ + template<> \ + struct Var { \ + type value; \ + Var(HSQUIRRELVM vm, SQInteger idx) { \ + SQInteger sqValue; \ + sq_getinteger(vm, idx, &sqValue); \ + value = static_cast(sqValue); \ + } \ + static void push(HSQUIRRELVM vm, type& value) { \ + sq_pushinteger(vm, static_cast(value)); \ + } \ + };\ + \ + template<> \ + struct Var { \ + type value; \ + Var(HSQUIRRELVM vm, SQInteger idx) { \ + SQInteger sqValue; \ + sq_getinteger(vm, idx, &sqValue); \ + value = static_cast(sqValue); \ + } \ + static void push(HSQUIRRELVM vm, const type& value) { \ + sq_pushinteger(vm, static_cast(value)); \ + } \ + }; \ + \ + template<> \ + struct Var { \ + type value; \ + Var(HSQUIRRELVM vm, SQInteger idx) { \ + SQInteger sqValue; \ + sq_getinteger(vm, idx, &sqValue); \ + value = static_cast(sqValue); \ + } \ + static void push(HSQUIRRELVM vm, const type& value) { \ + sq_pushinteger(vm, static_cast(value)); \ + } \ + }; + +SCRAT_INTEGER(unsigned int) +SCRAT_INTEGER(signed int) +SCRAT_INTEGER(unsigned long) +SCRAT_INTEGER(signed long) +SCRAT_INTEGER(unsigned short) +SCRAT_INTEGER(signed short) + +#if defined(__int64) +SCRAT_INTEGER(unsigned __int64) +SCRAT_INTEGER(signed __int64) +#endif + +// Float Types +#define SCRAT_FLOAT( type ) \ + template<> \ + struct Var { \ + type value; \ + Var(HSQUIRRELVM vm, SQInteger idx) { \ + SQFloat sqValue; \ + sq_getfloat(vm, idx, &sqValue); \ + value = static_cast(sqValue); \ + } \ + static void push(HSQUIRRELVM vm, type& value) { \ + sq_pushfloat(vm, static_cast(value)); \ + } \ + }; \ + \ + template<> \ + struct Var { \ + type value; \ + Var(HSQUIRRELVM vm, SQInteger idx) { \ + SQFloat sqValue; \ + sq_getfloat(vm, idx, &sqValue); \ + value = static_cast(sqValue); \ + } \ + static void push(HSQUIRRELVM vm, const type& value) { \ + sq_pushfloat(vm, static_cast(value)); \ + } \ + }; \ + template<> \ + struct Var { \ + type value; \ + Var(HSQUIRRELVM vm, SQInteger idx) { \ + SQFloat sqValue; \ + sq_getfloat(vm, idx, &sqValue); \ + value = static_cast(sqValue); \ + } \ + static void push(HSQUIRRELVM vm, const type& value) { \ + sq_pushfloat(vm, static_cast(value)); \ + } \ + }; + +SCRAT_FLOAT(float) +SCRAT_FLOAT(double) + +// Boolean Types +template<> +struct Var { + bool value; + Var(HSQUIRRELVM vm, SQInteger idx) { + SQBool sqValue; + sq_tobool(vm, idx, &sqValue); + value = (sqValue != 0); + } + static void push(HSQUIRRELVM vm, bool& value) { + sq_pushbool(vm, static_cast(value)); + } +}; + +template<> +struct Var { + bool value; + Var(HSQUIRRELVM vm, SQInteger idx) { + SQBool sqValue; + sq_tobool(vm, idx, &sqValue); + value = (sqValue != 0); + } + static void push(HSQUIRRELVM vm, const bool& value) { + sq_pushbool(vm, static_cast(value)); + } +}; + +template<> +struct Var { + bool value; + Var(HSQUIRRELVM vm, SQInteger idx) { + SQBool sqValue; + sq_tobool(vm, idx, &sqValue); + value = (sqValue != 0); + } + static void push(HSQUIRRELVM vm, const bool& value) { + sq_pushbool(vm, static_cast(value)); + } +}; + +// String Types +typedef std::basic_string string; + +template<> +struct Var { + SQChar* value; + HSQOBJECT obj;/* hold a reference to the object holding value during the Var struct lifetime*/ + HSQUIRRELVM v; + Var(HSQUIRRELVM vm, SQInteger idx) { + sq_tostring(vm, idx); + sq_getstackobj(vm, -1, &obj); + sq_getstring(vm, -1, (const SQChar**)&value); + sq_addref(vm, &obj); + sq_pop(vm,1); + v = vm; + } + ~Var() + { + if(v && !sq_isnull(obj)) { + sq_release(v, &obj); + } + } + static void push(HSQUIRRELVM vm, SQChar* value) { + sq_pushstring(vm, value, -1); + } +}; + +template<> +struct Var { + const SQChar* value; + HSQOBJECT obj; /* hold a reference to the object holding value during the Var struct lifetime*/ + HSQUIRRELVM v; + Var(HSQUIRRELVM vm, SQInteger idx) { + sq_tostring(vm, idx); + sq_getstackobj(vm, -1, &obj); + sq_getstring(vm, -1, &value); + sq_addref(vm, &obj); + sq_pop(vm,1); + v = vm; + } + ~Var() + { + if(v && !sq_isnull(obj)) { + sq_release(v, &obj); + } + } + static void push(HSQUIRRELVM vm, const SQChar* value) { + sq_pushstring(vm, value, -1); + } +}; + +template<> +struct Var { + string value; + Var(HSQUIRRELVM vm, SQInteger idx) { + const SQChar* ret; + sq_tostring(vm, idx); + sq_getstring(vm, -1, &ret); + value = string(ret); + sq_pop(vm,1); + } + static void push(HSQUIRRELVM vm, string value) { + sq_pushstring(vm, value.c_str(), -1); + } +}; + +template<> +struct Var { + string value; + Var(HSQUIRRELVM vm, SQInteger idx) { + const SQChar* ret; + sq_tostring(vm, idx); + sq_getstring(vm, -1, &ret); + value = string(ret); + sq_pop(vm,1); + } + static void push(HSQUIRRELVM vm, string value) { + sq_pushstring(vm, value.c_str(), -1); + } +}; + +template<> +struct Var { + string value; + Var(HSQUIRRELVM vm, SQInteger idx) { + const SQChar* ret; + sq_tostring(vm, idx); + sq_getstring(vm, -1, &ret); + value = string(ret); + sq_pop(vm,1); + } + static void push(HSQUIRRELVM vm, string value) { + sq_pushstring(vm, value.c_str(), -1); + } +}; + +// +// Variable Accessors +// + +// Push +template +inline void PushVar(HSQUIRRELVM vm, T value) { + Var::push(vm, value); +} +} + +#endif diff --git a/squirrel_3_0_1_stable/sqrat/sqrat/sqratUtil.h b/squirrel_3_0_1_stable/sqrat/sqrat/sqratUtil.h new file mode 100644 index 000000000..991e2f524 --- /dev/null +++ b/squirrel_3_0_1_stable/sqrat/sqrat/sqratUtil.h @@ -0,0 +1,94 @@ +// +// SqratUtil: Squirrel Utilities +// + +// +// Copyright (c) 2009 Brandon Jones +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would be +// appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, and must not be +// misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source +// distribution. +// + +#if !defined(_SCRAT_UTIL_H_) +#define _SCRAT_UTIL_H_ + +#include +#include + +#include "sqratTypes.h" + +namespace Sqrat { + +class DefaultVM { +private: + static HSQUIRRELVM& staticVm() { + static HSQUIRRELVM vm; + return vm; + } +public: + static HSQUIRRELVM Get() { + return staticVm(); + } + static void Set(HSQUIRRELVM vm) { + staticVm() = vm; + } +}; + +class ErrorHandling { +private: + static bool& errorHandling() { + static bool eh = true; + return eh; + } +public: + static bool IsEnabled() { + return errorHandling(); + } + static void Enable(bool enable) { + errorHandling() = enable; + } +}; + +class Exception { +public: + Exception(const string& msg) : message(msg) {} + Exception(const Exception& ex) : message(ex.message) {} + + const string Message() const { + return message; + } + +private: + string message; +}; + +inline string LastErrorString( HSQUIRRELVM vm ) { + const SQChar* sqErr; + sq_getlasterror(vm); + if(sq_gettype(vm, -1) == OT_NULL) { + return string(); + } + sq_tostring(vm, -1); + sq_getstring(vm, -1, &sqErr); + return string(sqErr); +} + +} + +#endif diff --git a/squirrel_3_0_1_stable/sqrat/sqrat/sqratVM.h b/squirrel_3_0_1_stable/sqrat/sqrat/sqratVM.h new file mode 100644 index 000000000..48a909300 --- /dev/null +++ b/squirrel_3_0_1_stable/sqrat/sqrat/sqratVM.h @@ -0,0 +1,255 @@ +// wrapper for the Squirrel VM under Sqrat +// +// Copyright (c) 2011 Alston Chen +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would be +// appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, and must not be +// misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source +// distribution. +// +// + +#if !defined(_SCRAT_VM_H_) +#define _SCRAT_VM_H_ + +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include + +namespace Sqrat { + +class SqratVM +{ +private: + static std::map ms_sqratVMs; + static void s_addVM(HSQUIRRELVM vm, SqratVM* sqratvm); + static void s_deleteVM(HSQUIRRELVM vm); + static SqratVM* s_getVM(HSQUIRRELVM vm); + + HSQUIRRELVM m_vm; + Sqrat::RootTable* m_rootTable; + Sqrat::Script* m_script; + Sqrat::string m_lastErrorMsg; + +private: + static void printFunc(HSQUIRRELVM v, const SQChar *s, ...); + static SQInteger runtimeErrorHandler(HSQUIRRELVM v); + static void compilerErrorHandler(HSQUIRRELVM v, + const SQChar* desc, + const SQChar* source, + SQInteger line, + SQInteger column); +public: + enum ERROR_STATE + { + NO_ERROR, COMPILE_ERROR, RUNTIME_ERROR + }; + + SqratVM(int initialStackSize = 1024); + ~SqratVM(); + + HSQUIRRELVM getVM() { return m_vm; } + Sqrat::RootTable& getRootTable() { return *m_rootTable; } + Sqrat::Script& getScript() { return *m_script; } + + Sqrat::string getLastErrorMsg() { return m_lastErrorMsg; } + void setLastErrorMsg(const Sqrat::string& str) { m_lastErrorMsg = str; } + + void setPrintFunc(SQPRINTFUNCTION printFunc, SQPRINTFUNCTION errFunc); + void setErrorHandler(SQFUNCTION runErr, SQCOMPILERERROR comErr); + + ERROR_STATE doString(const Sqrat::string& str); + ERROR_STATE doFile(const Sqrat::string& file); +}; + + + + +#ifdef SQUNICODE + #define scvprintf vwprintf +#else + #define scvprintf vprintf +#endif + + +std::map SqratVM::ms_sqratVMs; + +void SqratVM::s_addVM(HSQUIRRELVM vm, SqratVM* sqratvm) +{ + //TODO: use mutex to lock ms_sqratVMs + ms_sqratVMs.insert(std::make_pair(vm, sqratvm)); +} +void SqratVM::s_deleteVM(HSQUIRRELVM vm) +{ + //TODO: use mutex to lock ms_sqratVMs + ms_sqratVMs.erase(vm); +} +SqratVM* SqratVM::s_getVM(HSQUIRRELVM vm) +{ + //TODO: use mutex to lock ms_sqratVMs + return ms_sqratVMs[vm]; +} + +void SqratVM::printFunc(HSQUIRRELVM v, const SQChar *s, ...) +{ + va_list vl; + va_start(vl, s); + scvprintf(s, vl); + va_end(vl); +} + +SQInteger SqratVM::runtimeErrorHandler(HSQUIRRELVM v) +{ + const SQChar *sErr = 0; + if(sq_gettop(v) >= 1) + { + Sqrat::string& errStr = s_getVM(v)->m_lastErrorMsg; + + if(SQ_SUCCEEDED(sq_getstring(v, 2, &sErr))) + { + //scprintf(_SC("RuntimeError: %s\n"), sErr); + //errStr = _SC("RuntimeError: ") + sErr; + errStr = sErr; + } + else + { + //scprintf(_SC("An Unknown RuntimeError Occured.\n")); + errStr = _SC("An Unknown RuntimeError Occured."); + } + } + return 0; +} + +void SqratVM::compilerErrorHandler(HSQUIRRELVM v, + const SQChar* desc, + const SQChar* source, + SQInteger line, + SQInteger column) +{ + //scprintf(_SC("%s(%d:%d): %s\n"), source, line, column, desc); + + SQChar buf[512]; + scsprintf(buf, _SC("%s(%d:%d): %s"), source, line, column, desc); + s_getVM(v)->m_lastErrorMsg = buf; +} + +SqratVM::SqratVM(int initialStackSize /* = 1024 */) + : m_vm(sq_open(initialStackSize)) + , m_rootTable(new Sqrat::RootTable(m_vm)) + , m_script(new Sqrat::Script(m_vm)) + , m_lastErrorMsg() +{ + s_addVM(m_vm, this); + + //register std libs + sq_pushroottable(m_vm); + sqstd_register_iolib(m_vm); + sqstd_register_bloblib(m_vm); + sqstd_register_mathlib(m_vm); + sqstd_register_systemlib(m_vm); + sqstd_register_stringlib(m_vm); + sq_pop(m_vm, 1); + + setPrintFunc(printFunc, printFunc); + setErrorHandler(runtimeErrorHandler, compilerErrorHandler); +} + +SqratVM::~SqratVM() +{ + s_deleteVM(m_vm); + + delete m_script; + delete m_rootTable; + sq_close(m_vm); +} + +void SqratVM::setPrintFunc(SQPRINTFUNCTION printFunc, SQPRINTFUNCTION errFunc) +{ + sq_setprintfunc(m_vm, printFunc, errFunc); +} + +void SqratVM::setErrorHandler(SQFUNCTION runErr, SQCOMPILERERROR comErr) +{ + sq_newclosure(m_vm, runErr, 0); + sq_seterrorhandler(m_vm); + + sq_setcompilererrorhandler(m_vm, comErr); +} + +SqratVM::ERROR_STATE SqratVM::doString(const Sqrat::string& str) +{ + Sqrat::string msg; + m_lastErrorMsg.clear(); + + if(!m_script->CompileString(str, msg)) + { + if(m_lastErrorMsg.empty()) + { + m_lastErrorMsg = msg; + } + return COMPILE_ERROR; + } + + if(!m_script->Run(msg)) + { + if(m_lastErrorMsg.empty()) + { + m_lastErrorMsg = msg; + } + return RUNTIME_ERROR; + } + + return NO_ERROR; +} + +SqratVM::ERROR_STATE SqratVM::doFile(const Sqrat::string& file) +{ + Sqrat::string msg; + m_lastErrorMsg.clear(); + + if(!m_script->CompileFile(file, msg)) + { + if(m_lastErrorMsg.empty()) + { + m_lastErrorMsg = msg; + } + return COMPILE_ERROR; + } + + if(!m_script->Run(msg)) + { + if(m_lastErrorMsg.empty()) + { + m_lastErrorMsg = msg; + } + return RUNTIME_ERROR; + } + + return NO_ERROR; +} +} + +#endif diff --git a/squirrel_3_0_1_stable/sqrat/sqratimport.h b/squirrel_3_0_1_stable/sqrat/sqratimport.h new file mode 100644 index 000000000..fcf294edd --- /dev/null +++ b/squirrel_3_0_1_stable/sqrat/sqratimport.h @@ -0,0 +1,45 @@ +// +// SqImport: Supports importing of squirrel modules +// + +// +// Copyright (c) 2009 Brandon Jones +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would be +// appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, and must not be +// misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source +// distribution. +// + +#if !defined(_SQ_IMPORT_H_) +#define _SQ_IMPORT_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + + SQUIRREL_API SQRESULT sqrat_import(HSQUIRRELVM v); + + SQUIRREL_API SQRESULT sqrat_register_importlib(HSQUIRRELVM v); + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*_SQ_IMPORT_H_*/