1
0

It's a Squirrel!!

In SquirrelBindings.h use #define USE_SQUIRREL 1 to enable squirrel

git-svn-id: http://mc-server.googlecode.com/svn/trunk@76 0a769ca7-a7f5-676a-18bf-c427514a06d6
This commit is contained in:
faketruth 2011-11-08 01:25:01 +00:00
parent 0c3eda9b17
commit 8285a11a26
107 changed files with 23980 additions and 67 deletions

View File

@ -0,0 +1,26 @@
class SquirrelChatLog extends cPlugin__Squirrel
{
constructor()
{
base.constructor();
}
function Initialize()
{
::print("SquirrelChatLog initialize()");
this.SetName("SquirrelChatLog");
local PluginManager = cRoot.Get().GetPluginManager();
PluginManager.AddHook( this, PluginManager.E_PLUGIN_CHAT );
return true;
}
function OnChat( Message, Player )
{
::print(Player.GetName() + ": " + Message);
}
}
Plugin <- SquirrelChatLog();
cRoot.Get().GetPluginManager().AddPlugin( Plugin );

View File

@ -55,6 +55,7 @@
<IntrinsicFunctions>true</IntrinsicFunctions>
<AdditionalIncludeDirectories>..\jsoncpp-src-0.5.0\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>

View File

@ -17,10 +17,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WebServer", "WebServer.vcxp
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "JsonCpp", "JsonCpp.vcxproj", "{ADBF25B9-7192-4E54-B35E-8EC47CA5EF86}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Converter", "Converter.vcxproj", "{9AB1FB82-2148-40E4-919F-3B184B4593C8}"
ProjectSection(ProjectDependencies) = postProject
{F6F43A78-816D-4C37-A07B-68BED529273A} = {F6F43A78-816D-4C37-A07B-68BED529273A}
EndProjectSection
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "squirrel_3_0_1_stable", "squirrel_3_0_1_stable.vcxproj", "{4571CE2D-9E18-452F-90D6-94AE8E2406F4}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@ -76,12 +73,12 @@ Global
{ADBF25B9-7192-4E54-B35E-8EC47CA5EF86}.Release|Win32.ActiveCfg = Release|Win32
{ADBF25B9-7192-4E54-B35E-8EC47CA5EF86}.Release|Win32.Build.0 = Release|Win32
{ADBF25B9-7192-4E54-B35E-8EC47CA5EF86}.Release|x64.ActiveCfg = Release|Win32
{9AB1FB82-2148-40E4-919F-3B184B4593C8}.Debug|Win32.ActiveCfg = Debug|Win32
{9AB1FB82-2148-40E4-919F-3B184B4593C8}.Debug|Win32.Build.0 = Debug|Win32
{9AB1FB82-2148-40E4-919F-3B184B4593C8}.Debug|x64.ActiveCfg = Debug|Win32
{9AB1FB82-2148-40E4-919F-3B184B4593C8}.Release|Win32.ActiveCfg = Release|Win32
{9AB1FB82-2148-40E4-919F-3B184B4593C8}.Release|Win32.Build.0 = Release|Win32
{9AB1FB82-2148-40E4-919F-3B184B4593C8}.Release|x64.ActiveCfg = Release|Win32
{4571CE2D-9E18-452F-90D6-94AE8E2406F4}.Debug|Win32.ActiveCfg = Debug|Win32
{4571CE2D-9E18-452F-90D6-94AE8E2406F4}.Debug|Win32.Build.0 = Debug|Win32
{4571CE2D-9E18-452F-90D6-94AE8E2406F4}.Debug|x64.ActiveCfg = Debug|Win32
{4571CE2D-9E18-452F-90D6-94AE8E2406F4}.Release|Win32.ActiveCfg = Release|Win32
{4571CE2D-9E18-452F-90D6-94AE8E2406F4}.Release|Win32.Build.0 = Release|Win32
{4571CE2D-9E18-452F-90D6-94AE8E2406F4}.Release|x64.ActiveCfg = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

View File

@ -78,7 +78,7 @@
<ClCompile>
<AdditionalOptions>/ZI /D_DEBUG %(AdditionalOptions)</AdditionalOptions>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\tolua++-1.0.93\include;..\lua-5.1.4\src;..\zlib-1.2.5;..\mysql-connector\include;..\source\;..\pdcurs34\;..\jsoncpp-src-0.5.0\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>..\tolua++-1.0.93\include;..\lua-5.1.4\src;..\zlib-1.2.5;..\mysql-connector\include;..\source\;..\pdcurs34\;..\jsoncpp-src-0.5.0\include;..\squirrel_3_0_1_stable\include;..\squirrel_3_0_1_stable;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>false</MinimalRebuild>
<ExceptionHandling>Sync</ExceptionHandling>
@ -94,7 +94,7 @@
</ClCompile>
<Link>
<AdditionalOptions>/IGNORE:4078 %(AdditionalOptions)</AdditionalOptions>
<AdditionalDependencies>winmm.lib;ws2_32.lib;Psapi.lib;ZLib.lib;tolua++-1.0.93.lib;lua-5.1.4.lib;WebServer.lib;JsonCpp.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>winmm.lib;ws2_32.lib;Psapi.lib;ZLib.lib;tolua++-1.0.93.lib;lua-5.1.4.lib;WebServer.lib;JsonCpp.lib;squirrel_3_0_1_stable.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>../$(ProjectName)_debug.exe</OutputFile>
<AdditionalLibraryDirectories>VLD;./Debug/;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<IgnoreSpecificDefaultLibraries>%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
@ -145,10 +145,7 @@
<InlineFunctionExpansion>Default</InlineFunctionExpansion>
<IntrinsicFunctions>true</IntrinsicFunctions>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<WholeProgramOptimization>false</WholeProgramOptimization>
<AdditionalIncludeDirectories>..\tolua++-1.0.93\include;..\lua-5.1.4\src;..\zlib-1.2.5;..\mysql-connector\include;..\source\;..\pdcurs34\;..\jsoncpp-src-0.5.0\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ExceptionHandling>Sync</ExceptionHandling>
<AdditionalIncludeDirectories>..\tolua++-1.0.93\include;..\lua-5.1.4\src;..\zlib-1.2.5;..\mysql-connector\include;..\source\;..\pdcurs34\;..\jsoncpp-src-0.5.0\include;..\squirrel_3_0_1_stable\include;..\squirrel_3_0_1_stable;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<BasicRuntimeChecks>Default</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<BufferSecurityCheck>false</BufferSecurityCheck>
@ -161,10 +158,11 @@
<WarningLevel>Level4</WarningLevel>
<DebugInformationFormat>
</DebugInformationFormat>
<WholeProgramOptimization>true</WholeProgramOptimization>
</ClCompile>
<Link>
<AdditionalOptions>/IGNORE:4078 %(AdditionalOptions)</AdditionalOptions>
<AdditionalDependencies>winmm.lib;ws2_32.lib;Psapi.lib;ZLib.lib;tolua++-1.0.93.lib;lua-5.1.4.lib;WebServer.lib;JsonCpp.lib;libCMT.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>winmm.lib;ws2_32.lib;Psapi.lib;ZLib.lib;tolua++-1.0.93.lib;lua-5.1.4.lib;WebServer.lib;JsonCpp.lib;squirrel_3_0_1_stable.lib;LIBCMT.LIB;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>../$(ProjectName).exe</OutputFile>
<AdditionalLibraryDirectories>./Release/;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<IgnoreSpecificDefaultLibraries>LIBCMT;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
@ -350,6 +348,7 @@
<ClCompile Include="..\source\packets\cPacket_WindowClick.cpp" />
<ClCompile Include="..\source\packets\cPacket_WindowClose.cpp" />
<ClCompile Include="..\source\packets\cPacket_WindowOpen.cpp" />
<ClCompile Include="..\source\SquirrelBindings.cpp" />
<ClCompile Include="..\source\Vector3d.cpp" />
<ClCompile Include="..\source\Vector3f.cpp" />
<ClCompile Include="..\source\Vector3i.cpp" />
@ -498,6 +497,7 @@
<ClInclude Include="..\source\packets\cPacket_WindowClick.h" />
<ClInclude Include="..\source\packets\cPacket_WindowClose.h" />
<ClInclude Include="..\source\packets\cPacket_WindowOpen.h" />
<ClInclude Include="..\source\SquirrelBindings.h" />
<ClInclude Include="..\source\Vector3d.h" />
<ClInclude Include="..\source\Vector3f.h" />
<ClInclude Include="..\source\Vector3i.h" />

View File

@ -385,6 +385,9 @@
<Filter Include="cLavaSimulator">
<UniqueIdentifier>{b0401fd9-4021-4ab7-bf61-c8de112b4196}</UniqueIdentifier>
</Filter>
<Filter Include="LuaBindings\SquirrelBindings">
<UniqueIdentifier>{a71ee043-df55-4d42-a9aa-1643b40e1c22}</UniqueIdentifier>
</Filter>
<Filter Include="Packets\cPacket_Explosion">
<UniqueIdentifier>{0a6d025d-4fb8-4557-a348-004b819ea477}</UniqueIdentifier>
</Filter>
@ -781,6 +784,10 @@
<ClCompile Include="..\source\cLavaSimulator.cpp">
<Filter>cLavaSimulator</Filter>
</ClCompile>
<ClCompile Include="..\source\SquirrelBindings.cpp">
<Filter>LuaBindings\SquirrelBindings</Filter>
</ClCompile>
</ItemGroup>
<ClCompile Include="..\source\packets\cPacket_Explosion.cpp">
<Filter>Packets\cPacket_Explosion</Filter>
</ClCompile>
@ -1212,6 +1219,9 @@
<ClInclude Include="..\source\cLavaSimulator.h">
<Filter>cLavaSimulator</Filter>
</ClInclude>
<ClInclude Include="..\source\SquirrelBindings.h">
<Filter>LuaBindings\SquirrelBindings</Filter>
</ClInclude>
<ClInclude Include="..\source\packets\cPacket_Explosion.h">
<Filter>Packets\cPacket_Explosion</Filter>
</ClInclude>

View File

@ -98,6 +98,7 @@
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>

View File

@ -71,7 +71,6 @@
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
</ClCompile>
<Lib />
</ItemDefinitionGroup>
@ -94,7 +93,7 @@
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
</ClCompile>
<Lib>
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>

View File

@ -69,9 +69,9 @@
<Optimization>Disabled</Optimization>
<MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
</ClCompile>
<Lib />
</ItemDefinitionGroup>
@ -95,6 +95,7 @@
<FunctionLevelLinking>true</FunctionLevelLinking>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
</ClCompile>
<Lib>
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>

View File

@ -98,6 +98,7 @@
<FunctionLevelLinking>true</FunctionLevelLinking>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
</ClCompile>
<Lib>
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>

View File

@ -10,6 +10,7 @@ World=world_sexy
Plugin=Core
Plugin=Fire
Plugin=MagicCarpet
Squirrel=SquirrelChatLog
[HelpPlugin]
ShowPluginNames=1

View File

@ -1,6 +1,6 @@
/*
** Lua binding: AllToLua
** Generated automatically by tolua++-1.0.92 on 11/01/11 22:50:07.
** Generated automatically by tolua++-1.0.92 on 11/08/11 02:11:35.
*/
#ifndef __cplusplus
@ -6006,7 +6006,7 @@ static int tolua_AllToLua_cPluginManager_GetPlugin00(lua_State* tolua_S)
tolua_Error tolua_err;
if (
!tolua_isusertype(tolua_S,1,"cPluginManager",0,&tolua_err) ||
!tolua_iscppstring(tolua_S,2,0,&tolua_err) ||
!tolua_isstring(tolua_S,2,0,&tolua_err) ||
!tolua_isnoobj(tolua_S,3,&tolua_err)
)
goto tolua_lerror;
@ -6014,7 +6014,7 @@ static int tolua_AllToLua_cPluginManager_GetPlugin00(lua_State* tolua_S)
#endif
{
cPluginManager* self = (cPluginManager*) tolua_tousertype(tolua_S,1,0);
std::string a_Plugin = ((std::string) tolua_tocppstring(tolua_S,2,0));
const char* a_Plugin = ((const char*) tolua_tostring(tolua_S,2,0));
#ifndef TOLUA_RELEASE
if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetPlugin'", NULL);
#endif
@ -6545,7 +6545,7 @@ static int tolua_AllToLua_cPlugin_OnChat00(lua_State* tolua_S)
tolua_Error tolua_err;
if (
!tolua_isusertype(tolua_S,1,"cPlugin",0,&tolua_err) ||
!tolua_iscppstring(tolua_S,2,0,&tolua_err) ||
!tolua_isstring(tolua_S,2,0,&tolua_err) ||
!tolua_isusertype(tolua_S,3,"cPlayer",0,&tolua_err) ||
!tolua_isnoobj(tolua_S,4,&tolua_err)
)
@ -6554,7 +6554,7 @@ static int tolua_AllToLua_cPlugin_OnChat00(lua_State* tolua_S)
#endif
{
cPlugin* self = (cPlugin*) tolua_tousertype(tolua_S,1,0);
std::string a_Chat = ((std::string) tolua_tocppstring(tolua_S,2,0));
const char* a_Chat = ((const char*) tolua_tostring(tolua_S,2,0));
cPlayer* a_Player = ((cPlayer*) tolua_tousertype(tolua_S,3,0));
#ifndef TOLUA_RELEASE
if (!self) tolua_error(tolua_S,"invalid 'self' in function 'OnChat'", NULL);
@ -6797,8 +6797,8 @@ static int tolua_AllToLua_cPlugin_GetName00(lua_State* tolua_S)
if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetName'", NULL);
#endif
{
std::string tolua_ret = (std::string) self->GetName();
tolua_pushcppstring(tolua_S,(const char*)tolua_ret);
const char* tolua_ret = (const char*) self->GetName();
tolua_pushstring(tolua_S,(const char*)tolua_ret);
}
}
return 1;
@ -6818,7 +6818,7 @@ static int tolua_AllToLua_cPlugin_SetName00(lua_State* tolua_S)
tolua_Error tolua_err;
if (
!tolua_isusertype(tolua_S,1,"cPlugin",0,&tolua_err) ||
!tolua_iscppstring(tolua_S,2,0,&tolua_err) ||
!tolua_isstring(tolua_S,2,0,&tolua_err) ||
!tolua_isnoobj(tolua_S,3,&tolua_err)
)
goto tolua_lerror;
@ -6826,7 +6826,7 @@ static int tolua_AllToLua_cPlugin_SetName00(lua_State* tolua_S)
#endif
{
cPlugin* self = (cPlugin*) tolua_tousertype(tolua_S,1,0);
std::string a_Name = ((std::string) tolua_tocppstring(tolua_S,2,0));
const char* a_Name = ((const char*) tolua_tostring(tolua_S,2,0));
#ifndef TOLUA_RELEASE
if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetName'", NULL);
#endif
@ -7120,9 +7120,9 @@ public:
return ( bool ) cPlugin:: OnBlockDig(a_PacketData,a_Player,a_PickupItem);
};
};
bool OnChat( std::string a_Chat, cPlayer* a_Player) {
bool OnChat( const char* a_Chat, cPlayer* a_Player) {
if (push_method("OnChat", tolua_AllToLua_cPlugin_OnChat00)) {
tolua_pushcppstring(lua_state, (const char*)a_Chat);
tolua_pushstring(lua_state, (const char*)a_Chat);
tolua_pushusertype(lua_state, (void*)a_Player, "cPlayer");
ToluaBase::dbcall(lua_state, 3, 1);
bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0);
@ -7210,7 +7210,7 @@ public:
bool cPlugin__OnBlockDig( cPacket_BlockDig* a_PacketData, cPlayer* a_Player, cItem* a_PickupItem) {
return ( bool )cPlugin::OnBlockDig(a_PacketData,a_Player,a_PickupItem);
};
bool cPlugin__OnChat( std::string a_Chat, cPlayer* a_Player) {
bool cPlugin__OnChat( const char* a_Chat, cPlayer* a_Player) {
return ( bool )cPlugin::OnChat(a_Chat,a_Player);
};
bool cPlugin__OnLogin( cPacket_Login* a_PacketData) {
@ -7485,7 +7485,7 @@ static int tolua_AllToLua_Lua__cPlugin_cPlugin__OnChat00(lua_State* tolua_S)
tolua_Error tolua_err;
if (
!tolua_isusertype(tolua_S,1,"Lua__cPlugin",0,&tolua_err) ||
!tolua_iscppstring(tolua_S,2,0,&tolua_err) ||
!tolua_isstring(tolua_S,2,0,&tolua_err) ||
!tolua_isusertype(tolua_S,3,"cPlayer",0,&tolua_err) ||
!tolua_isnoobj(tolua_S,4,&tolua_err)
)
@ -7494,7 +7494,7 @@ static int tolua_AllToLua_Lua__cPlugin_cPlugin__OnChat00(lua_State* tolua_S)
#endif
{
Lua__cPlugin* self = (Lua__cPlugin*) tolua_tousertype(tolua_S,1,0);
std::string a_Chat = ((std::string) tolua_tocppstring(tolua_S,2,0));
const char* a_Chat = ((const char*) tolua_tostring(tolua_S,2,0));
cPlayer* a_Player = ((cPlayer*) tolua_tousertype(tolua_S,3,0));
#ifndef TOLUA_RELEASE
if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cPlugin__OnChat'", NULL);
@ -15097,7 +15097,22 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S)
tolua_constant(tolua_S,"E_BLOCK_LEAVES",E_BLOCK_LEAVES);
tolua_constant(tolua_S,"E_BLOCK_SPONGE",E_BLOCK_SPONGE);
tolua_constant(tolua_S,"E_BLOCK_GLASS",E_BLOCK_GLASS);
tolua_constant(tolua_S,"E_BLOCK_LAPIS_ORE",E_BLOCK_LAPIS_ORE);
tolua_constant(tolua_S,"E_BLOCK_LAPIS_BLOCK",E_BLOCK_LAPIS_BLOCK);
tolua_constant(tolua_S,"E_BLOCK_DISPENSER",E_BLOCK_DISPENSER);
tolua_constant(tolua_S,"E_BLOCK_SANDSTONE",E_BLOCK_SANDSTONE);
tolua_constant(tolua_S,"E_BLOCK_NOTE_BLOCK",E_BLOCK_NOTE_BLOCK);
tolua_constant(tolua_S,"E_BLOCK_BED",E_BLOCK_BED);
tolua_constant(tolua_S,"E_BLOCK_POWERED_RAIL",E_BLOCK_POWERED_RAIL);
tolua_constant(tolua_S,"E_BLOCK_DETECTOR_RAIL",E_BLOCK_DETECTOR_RAIL);
tolua_constant(tolua_S,"E_BLOCK_STICKY_PISTON",E_BLOCK_STICKY_PISTON);
tolua_constant(tolua_S,"E_BLOCK_COBWEB",E_BLOCK_COBWEB);
tolua_constant(tolua_S,"E_BLOCK_TALL_GRASS",E_BLOCK_TALL_GRASS);
tolua_constant(tolua_S,"E_BLOCK_DEAD_BUSH",E_BLOCK_DEAD_BUSH);
tolua_constant(tolua_S,"E_BLOCK_PISTON",E_BLOCK_PISTON);
tolua_constant(tolua_S,"E_BLOCK_PISTON_EXTENSION",E_BLOCK_PISTON_EXTENSION);
tolua_constant(tolua_S,"E_BLOCK_WHITE_CLOTH",E_BLOCK_WHITE_CLOTH);
tolua_constant(tolua_S,"E_BLOCK_PISTON_MOVED_BLOCK",E_BLOCK_PISTON_MOVED_BLOCK);
tolua_constant(tolua_S,"E_BLOCK_YELLOW_FLOWER",E_BLOCK_YELLOW_FLOWER);
tolua_constant(tolua_S,"E_BLOCK_RED_ROSE",E_BLOCK_RED_ROSE);
tolua_constant(tolua_S,"E_BLOCK_BROWN_MUSHROOM",E_BLOCK_BROWN_MUSHROOM);
@ -15136,14 +15151,18 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S)
tolua_constant(tolua_S,"E_BLOCK_WOODEN_PRESSURE_PLATE",E_BLOCK_WOODEN_PRESSURE_PLATE);
tolua_constant(tolua_S,"E_BLOCK_REDSTONE_ORE",E_BLOCK_REDSTONE_ORE);
tolua_constant(tolua_S,"E_BLOCK_REDSTONE_ORE_GLOWING",E_BLOCK_REDSTONE_ORE_GLOWING);
tolua_constant(tolua_S,"E_BLOCK_REDSTONE_TORCH_ON",E_BLOCK_REDSTONE_TORCH_ON);
tolua_constant(tolua_S,"E_BLOCK_REDSTONE_TORCH_OFF",E_BLOCK_REDSTONE_TORCH_OFF);
tolua_constant(tolua_S,"E_BLOCK_REDSTONE_TORCH_ON",E_BLOCK_REDSTONE_TORCH_ON);
tolua_constant(tolua_S,"E_BLOCK_STONE_BUTTON",E_BLOCK_STONE_BUTTON);
tolua_constant(tolua_S,"E_BLOCK_SNOW",E_BLOCK_SNOW);
tolua_constant(tolua_S,"E_BLOCK_ICE",E_BLOCK_ICE);
tolua_constant(tolua_S,"E_BLOCK_SNOW_BLOCK",E_BLOCK_SNOW_BLOCK);
tolua_constant(tolua_S,"E_BLOCK_CACTUS",E_BLOCK_CACTUS);
tolua_constant(tolua_S,"E_BLOCK_CLAY",E_BLOCK_CLAY);
tolua_constant(tolua_S,"E_BLOCK_REEDS",E_BLOCK_REEDS);
tolua_constant(tolua_S,"E_BLOCK_JUKEBOX",E_BLOCK_JUKEBOX);
tolua_constant(tolua_S,"E_BLOCK_FENCE",E_BLOCK_FENCE);
tolua_constant(tolua_S,"E_BLOCK_PUMPKIN",E_BLOCK_PUMPKIN);
tolua_constant(tolua_S,"E_BLOCK_BLOODSTONE",E_BLOCK_BLOODSTONE);
tolua_constant(tolua_S,"E_BLOCK_SOULSAND",E_BLOCK_SOULSAND);
tolua_constant(tolua_S,"E_BLOCK_GLOWSTONE",E_BLOCK_GLOWSTONE);
@ -15154,6 +15173,32 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S)
tolua_constant(tolua_S,"E_BLOCK_REDSTONE_REPEATER_ON",E_BLOCK_REDSTONE_REPEATER_ON);
tolua_constant(tolua_S,"E_BLOCK_LOCKED_CHEST",E_BLOCK_LOCKED_CHEST);
tolua_constant(tolua_S,"E_BLOCK_TRAPDOOR",E_BLOCK_TRAPDOOR);
tolua_constant(tolua_S,"E_BLOCK_SILVERFISH_EGG",E_BLOCK_SILVERFISH_EGG);
tolua_constant(tolua_S,"E_BLOCK_STONE_BRICKS",E_BLOCK_STONE_BRICKS);
tolua_constant(tolua_S,"E_BLOCK_HUGE_BROWN_MUSHROOM",E_BLOCK_HUGE_BROWN_MUSHROOM);
tolua_constant(tolua_S,"E_BLOCK_HUGE_RED_MUSHROOM",E_BLOCK_HUGE_RED_MUSHROOM);
tolua_constant(tolua_S,"E_BLOCK_IRON_BAR",E_BLOCK_IRON_BAR);
tolua_constant(tolua_S,"E_BLOCK_GLASS_PLANE",E_BLOCK_GLASS_PLANE);
tolua_constant(tolua_S,"E_BLOCK_MELON",E_BLOCK_MELON);
tolua_constant(tolua_S,"E_BLOCK_PUMPKIN_STEM",E_BLOCK_PUMPKIN_STEM);
tolua_constant(tolua_S,"E_BLOCK_MELON_STEM",E_BLOCK_MELON_STEM);
tolua_constant(tolua_S,"E_BLOCK_VINES",E_BLOCK_VINES);
tolua_constant(tolua_S,"E_BLOCK_FENCE_GATE",E_BLOCK_FENCE_GATE);
tolua_constant(tolua_S,"E_BLOCK_BRICK_STAIRS",E_BLOCK_BRICK_STAIRS);
tolua_constant(tolua_S,"E_BLOCK_STONE_BRICK_STAIRS",E_BLOCK_STONE_BRICK_STAIRS);
tolua_constant(tolua_S,"E_BLOCK_MYCELIUM",E_BLOCK_MYCELIUM);
tolua_constant(tolua_S,"E_BLOCK_LILY_PAD",E_BLOCK_LILY_PAD);
tolua_constant(tolua_S,"E_BLOCK_NETHER_BRICK",E_BLOCK_NETHER_BRICK);
tolua_constant(tolua_S,"E_BLOCK_NETHER_BRICK_FENCE",E_BLOCK_NETHER_BRICK_FENCE);
tolua_constant(tolua_S,"E_BLOCK_NETHER_BRICK_STAIRS",E_BLOCK_NETHER_BRICK_STAIRS);
tolua_constant(tolua_S,"E_BLOCK_NETHER_WART",E_BLOCK_NETHER_WART);
tolua_constant(tolua_S,"E_BLOCK_ENCHANTMENT_TABLE",E_BLOCK_ENCHANTMENT_TABLE);
tolua_constant(tolua_S,"E_BLOCK_BREWING_STAND",E_BLOCK_BREWING_STAND);
tolua_constant(tolua_S,"E_BLOCK_CAULDRON",E_BLOCK_CAULDRON);
tolua_constant(tolua_S,"E_BLOCK_END_PORTAL",E_BLOCK_END_PORTAL);
tolua_constant(tolua_S,"E_BLOCK_END_PORTAL_FRAME",E_BLOCK_END_PORTAL_FRAME);
tolua_constant(tolua_S,"E_BLOCK_END_STONE",E_BLOCK_END_STONE);
tolua_constant(tolua_S,"E_BLOCK_",E_BLOCK_);
tolua_constant(tolua_S,"E_ITEM_EMPTY",E_ITEM_EMPTY);
tolua_constant(tolua_S,"E_ITEM_STONE",E_ITEM_STONE);
tolua_constant(tolua_S,"E_ITEM_GRASS",E_ITEM_GRASS);
@ -15173,9 +15218,104 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S)
tolua_constant(tolua_S,"E_ITEM_COAL_ORE",E_ITEM_COAL_ORE);
tolua_constant(tolua_S,"E_ITEM_LOG",E_ITEM_LOG);
tolua_constant(tolua_S,"E_ITEM_LEAVES",E_ITEM_LEAVES);
tolua_constant(tolua_S,"E_ITEM_SPONGE",E_ITEM_SPONGE);
tolua_constant(tolua_S,"E_ITEM_GLASS",E_ITEM_GLASS);
tolua_constant(tolua_S,"E_ITEM_LAPIS_ORE",E_ITEM_LAPIS_ORE);
tolua_constant(tolua_S,"E_ITEM_LAPIS_BLOCK",E_ITEM_LAPIS_BLOCK);
tolua_constant(tolua_S,"E_ITEM_DISPENSER",E_ITEM_DISPENSER);
tolua_constant(tolua_S,"E_ITEM_SANDSTONE",E_ITEM_SANDSTONE);
tolua_constant(tolua_S,"E_ITEM_NOTE_ITEM",E_ITEM_NOTE_ITEM);
tolua_constant(tolua_S,"E_ITEM_POWERED_RAIL",E_ITEM_POWERED_RAIL);
tolua_constant(tolua_S,"E_ITEM_DETECTOR_RAIL",E_ITEM_DETECTOR_RAIL);
tolua_constant(tolua_S,"E_ITEM_STICKY_PISTON",E_ITEM_STICKY_PISTON);
tolua_constant(tolua_S,"E_ITEM_COBWEB",E_ITEM_COBWEB);
tolua_constant(tolua_S,"E_ITEM_TALL_GRASS",E_ITEM_TALL_GRASS);
tolua_constant(tolua_S,"E_ITEM_DEAD_BRUSH",E_ITEM_DEAD_BRUSH);
tolua_constant(tolua_S,"E_ITEM_PISTON",E_ITEM_PISTON);
tolua_constant(tolua_S,"E_ITEM_PISTON_EXTENSION",E_ITEM_PISTON_EXTENSION);
tolua_constant(tolua_S,"E_ITEM_WHITE_CLOTH",E_ITEM_WHITE_CLOTH);
tolua_constant(tolua_S,"E_ITEM_PISTON_MOVED_BLOCK",E_ITEM_PISTON_MOVED_BLOCK);
tolua_constant(tolua_S,"E_ITEM_YELLOW_FLOWER",E_ITEM_YELLOW_FLOWER);
tolua_constant(tolua_S,"E_ITEM_RED_ROSE",E_ITEM_RED_ROSE);
tolua_constant(tolua_S,"E_ITEM_BROWN_MUSHROOM",E_ITEM_BROWN_MUSHROOM);
tolua_constant(tolua_S,"E_ITEM_RED_MUSHROOM",E_ITEM_RED_MUSHROOM);
tolua_constant(tolua_S,"E_ITEM_GOLD_BLOCK",E_ITEM_GOLD_BLOCK);
tolua_constant(tolua_S,"E_ITEM_IRON_BLOCK",E_ITEM_IRON_BLOCK);
tolua_constant(tolua_S,"E_ITEM_DOUBLE_STEP",E_ITEM_DOUBLE_STEP);
tolua_constant(tolua_S,"E_ITEM_STEP",E_ITEM_STEP);
tolua_constant(tolua_S,"E_ITEM_BRICK",E_ITEM_BRICK);
tolua_constant(tolua_S,"E_ITEM_TNT",E_ITEM_TNT);
tolua_constant(tolua_S,"E_ITEM_BOOKCASE",E_ITEM_BOOKCASE);
tolua_constant(tolua_S,"E_ITEM_MOSSY_COBBLESTONE",E_ITEM_MOSSY_COBBLESTONE);
tolua_constant(tolua_S,"E_ITEM_OBSIDIAN",E_ITEM_OBSIDIAN);
tolua_constant(tolua_S,"E_ITEM_TORCH",E_ITEM_TORCH);
tolua_constant(tolua_S,"E_ITEM_FIRE",E_ITEM_FIRE);
tolua_constant(tolua_S,"E_ITEM_MOB_SPAWNER",E_ITEM_MOB_SPAWNER);
tolua_constant(tolua_S,"E_ITEM_WOODEN_STAIRS",E_ITEM_WOODEN_STAIRS);
tolua_constant(tolua_S,"E_ITEM_CHEST",E_ITEM_CHEST);
tolua_constant(tolua_S,"E_ITEM_REDSTONE_WIRE",E_ITEM_REDSTONE_WIRE);
tolua_constant(tolua_S,"E_ITEM_DIAMOND_ORE",E_ITEM_DIAMOND_ORE);
tolua_constant(tolua_S,"E_ITEM_DIAMOND_BLOCK",E_ITEM_DIAMOND_BLOCK);
tolua_constant(tolua_S,"E_ITEM_WORKBENCH",E_ITEM_WORKBENCH);
tolua_constant(tolua_S,"E_ITEM_CROPS",E_ITEM_CROPS);
tolua_constant(tolua_S,"E_ITEM_SOIL",E_ITEM_SOIL);
tolua_constant(tolua_S,"E_ITEM_FURNACE",E_ITEM_FURNACE);
tolua_constant(tolua_S,"E_ITEM_BURNING_FURNACE",E_ITEM_BURNING_FURNACE);
tolua_constant(tolua_S,"E_ITEM_SIGN_POST",E_ITEM_SIGN_POST);
tolua_constant(tolua_S,"E_ITEM_LADDER",E_ITEM_LADDER);
tolua_constant(tolua_S,"E_ITEM_MINECART_TRACKS",E_ITEM_MINECART_TRACKS);
tolua_constant(tolua_S,"E_ITEM_COBBLESTONE_STAIRS",E_ITEM_COBBLESTONE_STAIRS);
tolua_constant(tolua_S,"E_ITEM_WALLSIGN",E_ITEM_WALLSIGN);
tolua_constant(tolua_S,"E_ITEM_LEVER",E_ITEM_LEVER);
tolua_constant(tolua_S,"E_ITEM_STONE_PRESSURE_PLATE",E_ITEM_STONE_PRESSURE_PLATE);
tolua_constant(tolua_S,"E_ITEM_WOODEN_PRESSURE_PLATE",E_ITEM_WOODEN_PRESSURE_PLATE);
tolua_constant(tolua_S,"E_ITEM_REDSTONE_ORE",E_ITEM_REDSTONE_ORE);
tolua_constant(tolua_S,"E_ITEM_REDSTONE_ORE_GLOWING",E_ITEM_REDSTONE_ORE_GLOWING);
tolua_constant(tolua_S,"E_ITEM_REDSTONE_TORCH_ON",E_ITEM_REDSTONE_TORCH_ON);
tolua_constant(tolua_S,"E_ITEM_REDSTONE_TORCH_OFF",E_ITEM_REDSTONE_TORCH_OFF);
tolua_constant(tolua_S,"E_ITEM_STONE_BUTTON",E_ITEM_STONE_BUTTON);
tolua_constant(tolua_S,"E_ITEM_SNOW",E_ITEM_SNOW);
tolua_constant(tolua_S,"E_ITEM_ICE",E_ITEM_ICE);
tolua_constant(tolua_S,"E_ITEM_SNOW_BLOCK",E_ITEM_SNOW_BLOCK);
tolua_constant(tolua_S,"E_ITEM_CACTUS",E_ITEM_CACTUS);
tolua_constant(tolua_S,"E_ITEM_REEDS",E_ITEM_REEDS);
tolua_constant(tolua_S,"E_ITEM_JUKEBOX",E_ITEM_JUKEBOX);
tolua_constant(tolua_S,"E_ITEM_FENCE",E_ITEM_FENCE);
tolua_constant(tolua_S,"E_ITEM_PUMPKIN",E_ITEM_PUMPKIN);
tolua_constant(tolua_S,"E_ITEM_BLOODSTONE",E_ITEM_BLOODSTONE);
tolua_constant(tolua_S,"E_ITEM_SOULSAND",E_ITEM_SOULSAND);
tolua_constant(tolua_S,"E_ITEM_GLOWSTONE",E_ITEM_GLOWSTONE);
tolua_constant(tolua_S,"E_ITEM_PORT",E_ITEM_PORT);
tolua_constant(tolua_S,"E_ITEM_JACK_O_LANTERN",E_ITEM_JACK_O_LANTERN);
tolua_constant(tolua_S,"E_ITEM_REDSTONE_REPEATER_OFF",E_ITEM_REDSTONE_REPEATER_OFF);
tolua_constant(tolua_S,"E_ITEM_REDSTONE_REPEATER_ON",E_ITEM_REDSTONE_REPEATER_ON);
tolua_constant(tolua_S,"E_ITEM_LOCKED_CHEST",E_ITEM_LOCKED_CHEST);
tolua_constant(tolua_S,"E_ITEM_TRAPDOOR",E_ITEM_TRAPDOOR);
tolua_constant(tolua_S,"E_ITEM_SILVERFISH_EGG",E_ITEM_SILVERFISH_EGG);
tolua_constant(tolua_S,"E_ITEM_STONE_BRICKS",E_ITEM_STONE_BRICKS);
tolua_constant(tolua_S,"E_ITEM_HUGE_BROWN_MUSHROOM",E_ITEM_HUGE_BROWN_MUSHROOM);
tolua_constant(tolua_S,"E_ITEM_HUGE_RED_MUSHROOM",E_ITEM_HUGE_RED_MUSHROOM);
tolua_constant(tolua_S,"E_ITEM_IRON_BAR",E_ITEM_IRON_BAR);
tolua_constant(tolua_S,"E_ITEM_GLASS_PLANE",E_ITEM_GLASS_PLANE);
tolua_constant(tolua_S,"E_ITEM_MELON",E_ITEM_MELON);
tolua_constant(tolua_S,"E_ITEM_PUMPKIN_STEM",E_ITEM_PUMPKIN_STEM);
tolua_constant(tolua_S,"E_ITEM_MELON_STEM",E_ITEM_MELON_STEM);
tolua_constant(tolua_S,"E_ITEM_VINES",E_ITEM_VINES);
tolua_constant(tolua_S,"E_ITEM_FENCE_GATE",E_ITEM_FENCE_GATE);
tolua_constant(tolua_S,"E_ITEM_BRICK_STAIRS",E_ITEM_BRICK_STAIRS);
tolua_constant(tolua_S,"E_ITEM_STONE_BRICK_STAIRS",E_ITEM_STONE_BRICK_STAIRS);
tolua_constant(tolua_S,"E_ITEM_MYCELIUM",E_ITEM_MYCELIUM);
tolua_constant(tolua_S,"E_ITEM_LILY_PAD",E_ITEM_LILY_PAD);
tolua_constant(tolua_S,"E_ITEM_NETHER_BRICK",E_ITEM_NETHER_BRICK);
tolua_constant(tolua_S,"E_ITEM_NETHER_BRICK_FENCE",E_ITEM_NETHER_BRICK_FENCE);
tolua_constant(tolua_S,"E_ITEM_NETHER_BRICK_STAIRS",E_ITEM_NETHER_BRICK_STAIRS);
tolua_constant(tolua_S,"E_ITEM_ENCHANTMENT_TABLE",E_ITEM_ENCHANTMENT_TABLE);
tolua_constant(tolua_S,"E_ITEM_END_PORTAL",E_ITEM_END_PORTAL);
tolua_constant(tolua_S,"E_ITEM_END_PORTAL_FRAME",E_ITEM_END_PORTAL_FRAME);
tolua_constant(tolua_S,"E_ITEM_END_STONE",E_ITEM_END_STONE);
tolua_constant(tolua_S,"E_ITEM_IRON_SHOVEL",E_ITEM_IRON_SHOVEL);
tolua_constant(tolua_S,"E_ITEM_IRON_PICKAXE",E_ITEM_IRON_PICKAXE);
tolua_constant(tolua_S,"E_ITEM_IRON_AXE",E_ITEM_IRON_AXE);
tolua_constant(tolua_S,"E_ITEM_FLINT_AND_STEEL",E_ITEM_FLINT_AND_STEEL);
tolua_constant(tolua_S,"E_ITEM_APPLE",E_ITEM_APPLE);
tolua_constant(tolua_S,"E_ITEM_BOW",E_ITEM_BOW);
@ -15184,6 +15324,21 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S)
tolua_constant(tolua_S,"E_ITEM_DIAMOND",E_ITEM_DIAMOND);
tolua_constant(tolua_S,"E_ITEM_IRON",E_ITEM_IRON);
tolua_constant(tolua_S,"E_ITEM_GOLD",E_ITEM_GOLD);
tolua_constant(tolua_S,"E_ITEM_IRON_SWORD",E_ITEM_IRON_SWORD);
tolua_constant(tolua_S,"E_ITEM_WOODEN_SWORD",E_ITEM_WOODEN_SWORD);
tolua_constant(tolua_S,"E_ITEM_WOODEN_SHOVEL",E_ITEM_WOODEN_SHOVEL);
tolua_constant(tolua_S,"E_ITEM_WOODEN_PICKAXE",E_ITEM_WOODEN_PICKAXE);
tolua_constant(tolua_S,"E_ITEM_WOODEN_AXE",E_ITEM_WOODEN_AXE);
tolua_constant(tolua_S,"E_ITEM_STONE_SWORD",E_ITEM_STONE_SWORD);
tolua_constant(tolua_S,"E_ITEM_STONE_SHOVEL",E_ITEM_STONE_SHOVEL);
tolua_constant(tolua_S,"E_ITEM_STONE_PICKAXE",E_ITEM_STONE_PICKAXE);
tolua_constant(tolua_S,"E_ITEM_STONE_AXE",E_ITEM_STONE_AXE);
tolua_constant(tolua_S,"E_ITEM_DIAMOND_SWORD",E_ITEM_DIAMOND_SWORD);
tolua_constant(tolua_S,"E_ITEM_DIAMOND_SHOVEL",E_ITEM_DIAMOND_SHOVEL);
tolua_constant(tolua_S,"E_ITEM_DIAMOND_PICKAXE",E_ITEM_DIAMOND_PICKAXE);
tolua_constant(tolua_S,"E_ITEM_DIAMOND_AXE",E_ITEM_DIAMOND_AXE);
tolua_constant(tolua_S,"E_ITEM_STICK",E_ITEM_STICK);
tolua_constant(tolua_S,"E_ITEM_BOWL",E_ITEM_BOWL);
tolua_constant(tolua_S,"E_ITEM_MUSHROOM_SOUP",E_ITEM_MUSHROOM_SOUP);
tolua_constant(tolua_S,"E_ITEM_GOLD_SWORD",E_ITEM_GOLD_SWORD);
tolua_constant(tolua_S,"E_ITEM_GOLD_SHOVEL",E_ITEM_GOLD_SHOVEL);
@ -15191,12 +15346,61 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S)
tolua_constant(tolua_S,"E_ITEM_GOLD_AXE",E_ITEM_GOLD_AXE);
tolua_constant(tolua_S,"E_ITEM_STRING",E_ITEM_STRING);
tolua_constant(tolua_S,"E_ITEM_FEATHER",E_ITEM_FEATHER);
tolua_constant(tolua_S,"E_ITEM_GUNPOWDER",E_ITEM_GUNPOWDER);
tolua_constant(tolua_S,"E_ITEM_WOODEN_HOE",E_ITEM_WOODEN_HOE);
tolua_constant(tolua_S,"E_ITEM_STONE_HOE",E_ITEM_STONE_HOE);
tolua_constant(tolua_S,"E_ITEM_IRON_HOE",E_ITEM_IRON_HOE);
tolua_constant(tolua_S,"E_ITEM_DIAMOND_HOE",E_ITEM_DIAMOND_HOE);
tolua_constant(tolua_S,"E_ITEM_GOLD_HOE",E_ITEM_GOLD_HOE);
tolua_constant(tolua_S,"E_ITEM_SEEDS",E_ITEM_SEEDS);
tolua_constant(tolua_S,"E_ITEM_WHEAT",E_ITEM_WHEAT);
tolua_constant(tolua_S,"E_ITEM_BREAD",E_ITEM_BREAD);
tolua_constant(tolua_S,"E_ITEM_LEATHER_CAP",E_ITEM_LEATHER_CAP);
tolua_constant(tolua_S,"E_ITEM_LEATHER_TUNIC",E_ITEM_LEATHER_TUNIC);
tolua_constant(tolua_S,"E_ITEM_LEATHER_PANTS",E_ITEM_LEATHER_PANTS);
tolua_constant(tolua_S,"E_ITEM_LEATHER_BOOTS",E_ITEM_LEATHER_BOOTS);
tolua_constant(tolua_S,"E_ITEM_CHAIN_HELMET",E_ITEM_CHAIN_HELMET);
tolua_constant(tolua_S,"E_ITEM_CHAIN_CHESTPLATE",E_ITEM_CHAIN_CHESTPLATE);
tolua_constant(tolua_S,"E_ITEM_CHAIN_LEGGINGS",E_ITEM_CHAIN_LEGGINGS);
tolua_constant(tolua_S,"E_ITEM_CHAIN_BOOTS",E_ITEM_CHAIN_BOOTS);
tolua_constant(tolua_S,"E_ITEM_IRON_HELMET",E_ITEM_IRON_HELMET);
tolua_constant(tolua_S,"E_ITEM_IRON_CHESTPLATE",E_ITEM_IRON_CHESTPLATE);
tolua_constant(tolua_S,"E_ITEM_IRON_LEGGINGS",E_ITEM_IRON_LEGGINGS);
tolua_constant(tolua_S,"E_ITEM_IRON_BOOTS",E_ITEM_IRON_BOOTS);
tolua_constant(tolua_S,"E_ITEM_DIAMOND_HELMET",E_ITEM_DIAMOND_HELMET);
tolua_constant(tolua_S,"E_ITEM_DIAMOND_CHESTPLATE",E_ITEM_DIAMOND_CHESTPLATE);
tolua_constant(tolua_S,"E_ITEM_DIAMOND_LEGGINGS",E_ITEM_DIAMOND_LEGGINGS);
tolua_constant(tolua_S,"E_ITEM_DIAMOND_BOOTS",E_ITEM_DIAMOND_BOOTS);
tolua_constant(tolua_S,"E_ITEM_GOLD_HELMET",E_ITEM_GOLD_HELMET);
tolua_constant(tolua_S,"E_ITEM_GOLD_CHESTPLATE",E_ITEM_GOLD_CHESTPLATE);
tolua_constant(tolua_S,"E_ITEM_GOLD_LEGGINGS",E_ITEM_GOLD_LEGGINGS);
tolua_constant(tolua_S,"E_ITEM_GOLD_BOOTS",E_ITEM_GOLD_BOOTS);
tolua_constant(tolua_S,"E_ITEM_FLINT",E_ITEM_FLINT);
tolua_constant(tolua_S,"E_ITEM_RAW_MEAT",E_ITEM_RAW_MEAT);
tolua_constant(tolua_S,"E_ITEM_COOKED_MEAT",E_ITEM_COOKED_MEAT);
tolua_constant(tolua_S,"E_ITEM_PAINTINGS",E_ITEM_PAINTINGS);
tolua_constant(tolua_S,"E_ITEM_GOLDEN_APPLE",E_ITEM_GOLDEN_APPLE);
tolua_constant(tolua_S,"E_ITEM_SIGN",E_ITEM_SIGN);
tolua_constant(tolua_S,"E_ITEM_WOODEN_DOOR",E_ITEM_WOODEN_DOOR);
tolua_constant(tolua_S,"E_ITEM_BUCKET",E_ITEM_BUCKET);
tolua_constant(tolua_S,"E_ITEM_WATER_BUCKET",E_ITEM_WATER_BUCKET);
tolua_constant(tolua_S,"E_ITEM_LAVA_BUCKET",E_ITEM_LAVA_BUCKET);
tolua_constant(tolua_S,"E_ITEM_MINECART",E_ITEM_MINECART);
tolua_constant(tolua_S,"E_ITEM_SADDLE",E_ITEM_SADDLE);
tolua_constant(tolua_S,"E_ITEM_IRON_DOOR",E_ITEM_IRON_DOOR);
tolua_constant(tolua_S,"E_ITEM_REDSTONE_DUST",E_ITEM_REDSTONE_DUST);
tolua_constant(tolua_S,"E_ITEM_SNOWBALL",E_ITEM_SNOWBALL);
tolua_constant(tolua_S,"E_ITEM_BOAT",E_ITEM_BOAT);
tolua_constant(tolua_S,"E_ITEM_LEATHER",E_ITEM_LEATHER);
tolua_constant(tolua_S,"E_ITEM_MILK",E_ITEM_MILK);
tolua_constant(tolua_S,"E_ITEM_CLAY_BRICK",E_ITEM_CLAY_BRICK);
tolua_constant(tolua_S,"E_ITEM_CLAY",E_ITEM_CLAY);
tolua_constant(tolua_S,"E_ITEM_SUGAR_CANE",E_ITEM_SUGAR_CANE);
tolua_constant(tolua_S,"E_ITEM_PAPER",E_ITEM_PAPER);
tolua_constant(tolua_S,"E_ITEM_BOOK",E_ITEM_BOOK);
tolua_constant(tolua_S,"E_ITEM_SLIMEBALL",E_ITEM_SLIMEBALL);
tolua_constant(tolua_S,"E_ITEM_CHEST_MINECART",E_ITEM_CHEST_MINECART);
tolua_constant(tolua_S,"E_ITEM_FURNACE_MINECART",E_ITEM_FURNACE_MINECART);
tolua_constant(tolua_S,"E_ITEM_EGG",E_ITEM_EGG);
tolua_constant(tolua_S,"E_ITEM_COMPASS",E_ITEM_COMPASS);
tolua_constant(tolua_S,"E_ITEM_FISHING_ROD",E_ITEM_FISHING_ROD);
@ -15204,7 +15408,49 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S)
tolua_constant(tolua_S,"E_ITEM_GLOWSTONE_DUST",E_ITEM_GLOWSTONE_DUST);
tolua_constant(tolua_S,"E_ITEM_RAW_FISH",E_ITEM_RAW_FISH);
tolua_constant(tolua_S,"E_ITEM_COOKED_FISH",E_ITEM_COOKED_FISH);
tolua_constant(tolua_S,"E_ITEM_DYE",E_ITEM_DYE);
tolua_constant(tolua_S,"E_ITEM_BONE",E_ITEM_BONE);
tolua_constant(tolua_S,"E_ITEM_SUGAR",E_ITEM_SUGAR);
tolua_constant(tolua_S,"E_ITEM_CAKE",E_ITEM_CAKE);
tolua_constant(tolua_S,"E_ITEM_BED",E_ITEM_BED);
tolua_constant(tolua_S,"E_ITEM_REDSTONE_REPEATER",E_ITEM_REDSTONE_REPEATER);
tolua_constant(tolua_S,"E_ITEM_COOKIE",E_ITEM_COOKIE);
tolua_constant(tolua_S,"E_ITEM_MAP",E_ITEM_MAP);
tolua_constant(tolua_S,"E_ITEM_SHEARS",E_ITEM_SHEARS);
tolua_constant(tolua_S,"E_ITEM_MELON_SLICE",E_ITEM_MELON_SLICE);
tolua_constant(tolua_S,"E_ITEM_PUMPKIN_SEEDS",E_ITEM_PUMPKIN_SEEDS);
tolua_constant(tolua_S,"E_ITEM_MELON_SEEDS",E_ITEM_MELON_SEEDS);
tolua_constant(tolua_S,"E_ITEM_RAW_BEEF",E_ITEM_RAW_BEEF);
tolua_constant(tolua_S,"E_ITEM_STEAK",E_ITEM_STEAK);
tolua_constant(tolua_S,"E_ITEM_RAW_CHICKEN",E_ITEM_RAW_CHICKEN);
tolua_constant(tolua_S,"E_ITEM_COOKED_CHICKEN",E_ITEM_COOKED_CHICKEN);
tolua_constant(tolua_S,"E_ITEM_ROTTEN_FLESH",E_ITEM_ROTTEN_FLESH);
tolua_constant(tolua_S,"E_ITEM_ENDER_PEARL",E_ITEM_ENDER_PEARL);
tolua_constant(tolua_S,"E_ITEM_BLAZE_ROD",E_ITEM_BLAZE_ROD);
tolua_constant(tolua_S,"E_ITEM_GHAST_TEAR",E_ITEM_GHAST_TEAR);
tolua_constant(tolua_S,"E_ITEM_GOLD_NUGGET",E_ITEM_GOLD_NUGGET);
tolua_constant(tolua_S,"E_ITEM_NETHER_WART",E_ITEM_NETHER_WART);
tolua_constant(tolua_S,"E_ITEM_POTIONS",E_ITEM_POTIONS);
tolua_constant(tolua_S,"E_ITEM_GLASS_BOTTLE",E_ITEM_GLASS_BOTTLE);
tolua_constant(tolua_S,"E_ITEM_SPIDER_EYE",E_ITEM_SPIDER_EYE);
tolua_constant(tolua_S,"E_ITEM_FERMENTED_SPIDER_EYE",E_ITEM_FERMENTED_SPIDER_EYE);
tolua_constant(tolua_S,"E_ITEM_BLAZE_POWDER",E_ITEM_BLAZE_POWDER);
tolua_constant(tolua_S,"E_ITEM_MAGMA_CREAM",E_ITEM_MAGMA_CREAM);
tolua_constant(tolua_S,"E_ITEM_BREWING_STAND",E_ITEM_BREWING_STAND);
tolua_constant(tolua_S,"E_ITEM_CAULDRON",E_ITEM_CAULDRON);
tolua_constant(tolua_S,"E_ITEM_EYE_OF_ENDER",E_ITEM_EYE_OF_ENDER);
tolua_constant(tolua_S,"E_ITEM_GLISTERING_MELON",E_ITEM_GLISTERING_MELON);
tolua_constant(tolua_S,"E_ITEM_13_DISC",E_ITEM_13_DISC);
tolua_constant(tolua_S,"E_ITEM_CAT_DISC",E_ITEM_CAT_DISC);
tolua_constant(tolua_S,"E_ITEM_BLOCKS_DISC",E_ITEM_BLOCKS_DISC);
tolua_constant(tolua_S,"E_ITEM_CHIRP_DISC",E_ITEM_CHIRP_DISC);
tolua_constant(tolua_S,"E_ITEM_FAR_DISC",E_ITEM_FAR_DISC);
tolua_constant(tolua_S,"E_ITEM_MALL_DISC",E_ITEM_MALL_DISC);
tolua_constant(tolua_S,"E_ITEM_MELLOHI_DISC",E_ITEM_MELLOHI_DISC);
tolua_constant(tolua_S,"E_ITEM_STAL_DISC",E_ITEM_STAL_DISC);
tolua_constant(tolua_S,"E_ITEM_STRAD_DISC",E_ITEM_STRAD_DISC);
tolua_constant(tolua_S,"E_ITEM_WARD_DISC",E_ITEM_WARD_DISC);
tolua_constant(tolua_S,"E_ITEM_11_DISC",E_ITEM_11_DISC);
tolua_constant(tolua_S,"E_KEEP_ALIVE",E_KEEP_ALIVE);
tolua_constant(tolua_S,"E_LOGIN",E_LOGIN);
tolua_constant(tolua_S,"E_HANDSHAKE",E_HANDSHAKE);
@ -15241,6 +15487,11 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S)
tolua_constant(tolua_S,"E_MAP_CHUNK",E_MAP_CHUNK);
tolua_constant(tolua_S,"E_MULTI_BLOCK",E_MULTI_BLOCK);
tolua_constant(tolua_S,"E_BLOCK_CHANGE",E_BLOCK_CHANGE);
tolua_constant(tolua_S,"E_BLOCK_ACTION",E_BLOCK_ACTION);
tolua_constant(tolua_S,"E_EXPLOSION",E_EXPLOSION);
tolua_constant(tolua_S,"E_SOUND_EFFECT",E_SOUND_EFFECT);
tolua_constant(tolua_S,"E_NEW_INVALID_STATE",E_NEW_INVALID_STATE);
tolua_constant(tolua_S,"E_THUNDERBOLT",E_THUNDERBOLT);
tolua_constant(tolua_S,"E_WINDOW_OPEN",E_WINDOW_OPEN);
tolua_constant(tolua_S,"E_WINDOW_CLOSE",E_WINDOW_CLOSE);
tolua_constant(tolua_S,"E_WINDOW_CLICK",E_WINDOW_CLICK);

View File

@ -1,6 +1,6 @@
/*
** Lua binding: AllToLua
** Generated automatically by tolua++-1.0.92 on 11/01/11 22:50:07.
** Generated automatically by tolua++-1.0.92 on 11/08/11 02:11:36.
*/
/* Exported function */

136
source/SquirrelBindings.cpp Normal file
View File

@ -0,0 +1,136 @@
#include "SquirrelBindings.h"
#if USE_SQUIRREL
#pragma warning(disable:4100) // Getting A LOT of these warnings from SqPlus
#pragma warning(disable:4127)
#include "cMCLogger.h"
#include <sqplus/sqplus.h>
#include <sqplus/SquirrelObject.h>
#include <../squirrel/sqstate.h>
#include <../squirrel/sqvm.h>
#include <stdarg.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<typename T>
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<bool> 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<cPlugin__Squirrel>::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<bool>(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>("cEntity");
SqPlus::SQClassDefNoConstructor<cPawn, cEntity>("cPawn", "cEntity");
SqPlus::SQClassDefNoConstructor<cPlayer, cPawn>("cPlayer", "cPawn"). // All NoConstructor because they need a custom one
func(&cPlayer::GetName, "GetName");
SqPlus::SQClassDefNoConstructor<cPlugin>("cPlugin").
func(&cPlugin::SetName, "SetName").
func(&cPlugin::GetName, "GetName").
func(&cPlugin::GetVersion, "GetVersion").
func(&cPlugin::OnChat, "OnChat");
SqPlus::SQClassDef<cPlugin__Squirrel, cPlugin>("cPlugin__Squirrel", "cPlugin").
staticFunc(&cPlugin__Squirrel::constructor, "constructor");
SqPlus::SQClassDefNoConstructor<cRoot>("cRoot").
staticFunc(&cRoot::Get, "Get").
func(static_cast<cPluginManager* (__thiscall cRoot::*)(void)>(&cRoot::GetPluginManager), "GetPluginManager");
SqPlus::SQClassDefNoConstructor<cPluginManager>("cPluginManager").
overloadFunc<bool (cPluginManager::*)(cPlugin*)>(&cPluginManager::AddPlugin, "AddPlugin").
func(&cPluginManager::GetPlugin, "GetPlugin").
func(&cPluginManager::AddHook, "AddHook").
enumInt( cPluginManager::E_PLUGIN_CHAT, "E_PLUGIN_CHAT");
}
#endif

15
source/SquirrelBindings.h Normal file
View File

@ -0,0 +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

View File

@ -69,6 +69,7 @@
#ifndef _WIN32
#define sprintf_s(dst, size, format, ...) sprintf(dst, format, __VA_ARGS__ )
#include <stdlib.h> // rand()
#endif
#define AddPistonDir( x, y, z, dir, amount ) switch(dir) { case 0: (y)-=(amount); break; case 1: (y)+=(amount); break;\

View File

@ -5,6 +5,7 @@
cPlugin::cPlugin()
: m_Version( 0 )
, m_Language( E_CPP )
{
}
@ -44,7 +45,7 @@ bool cPlugin::OnDisconnect( std::string a_Reason, cPlayer* a_Player )
return false;
}
bool cPlugin::OnChat( std::string a_Chat, cPlayer* a_Player )
bool cPlugin::OnChat( const char* a_Chat, cPlayer* a_Player )
{
(void)a_Chat;
(void)a_Player;

View File

@ -41,7 +41,7 @@ public:
virtual bool OnDisconnect( std::string a_Reason, cPlayer* a_Player );
virtual bool OnBlockPlace( cPacket_BlockPlace* a_PacketData, cPlayer* a_Player );
virtual bool OnBlockDig( cPacket_BlockDig* a_PacketData, cPlayer* a_Player, cItem* a_PickupItem ) { (void)a_PacketData; (void)a_Player; (void)a_PickupItem; return false; }
virtual bool OnChat( std::string a_Chat, cPlayer* a_Player );
virtual bool OnChat( const char* a_Chat, cPlayer* a_Player );
virtual bool OnLogin( cPacket_Login* a_PacketData );
virtual void OnPlayerSpawn( cPlayer* a_Player );
virtual bool OnPlayerJoin( cPlayer* a_Player );
@ -50,8 +50,8 @@ public:
virtual bool OnKilled( cPawn* a_Killed, cEntity* a_Killer ) { (void)a_Killed; (void)a_Killer; return false; }
// Accessors
std::string GetName() const { return m_Name; }
void SetName( std::string a_Name ) { m_Name = a_Name; }
const char* GetName() const { return m_Name.c_str(); }
void SetName( const char* a_Name ) { m_Name = a_Name; }
int GetVersion() const { return m_Version; }
void SetVersion( int a_Version ) { m_Version = a_Version; }
@ -69,7 +69,19 @@ public:
void BindCommand( FuncCommandHandler* a_Function, std::string & a_Command ); // >> EXPORTED IN MANUALBINDINGS <<
const std::vector< CommandStruct > & GetCommands() const { return m_Commands; } // >> EXPORTED IN MANUALBINDINGS <<
/* This should not be exposed to scripting languages */
enum PluginLanguage
{
E_CPP,
E_LUA,
E_SQUIRREL,
};
PluginLanguage GetLanguage() { return m_Language; }
void SetLanguage( PluginLanguage a_Language ) { m_Language = a_Language; }
private:
PluginLanguage m_Language;
std::vector< CommandStruct > m_Commands;
std::string m_Name;
int m_Version;

View File

@ -6,10 +6,16 @@
#include "cItem.h"
#include "cRoot.h"
#include "cLuaCommandBinder.h"
#include "../iniFile/iniFile.h"
#include <string> //strcmp
#include <stdarg.h>
#include "../iniFile/iniFile.h"
#include "SquirrelBindings.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 <sqplus/sqplus.h>
#pragma warning(default:4100;default:4127;default:4510;default:4610;default:4244;default:4512)
#endif
extern std::vector<std::string> StringSplit(std::string str, std::string delim);
@ -39,6 +45,7 @@ cPluginManager::cPluginManager()
cPluginManager::~cPluginManager()
{
UnloadPluginsNow();
delete m_LuaCommandBinder;
delete m_pState;
}
@ -54,6 +61,16 @@ void cPluginManager::ReloadPluginsNow()
m_bReloadPlugins = false;
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() );
}
#endif
cIniFile IniFile("settings.ini");
if( IniFile.ReadFile() )
{
@ -64,10 +81,10 @@ void cPluginManager::ReloadPluginsNow()
for(unsigned int i = 0; i < NumPlugins; i++)
{
std::string ValueName = IniFile.GetValueName(KeyNum, i );
if( ValueName.compare("Plugin") == 0 )
{ // It's a plugin
if( ValueName.compare("Plugin") == 0 ) // It's a Lua plugin
{
std::string PluginFile = IniFile.GetValue(KeyNum, i );
if( PluginFile.compare("") != 0 )
if( !PluginFile.empty() )
{
// allow for comma separated plugin list
// degrades and works fine for the plugin
@ -82,6 +99,32 @@ void cPluginManager::ReloadPluginsNow()
}
}
}
#if USE_SQUIRREL
else if( ValueName.compare("Squirrel") == 0 ) // Squirrel plugin
{
std::string PluginFile = IniFile.GetValue(KeyNum, i );
if( !PluginFile.empty() )
{
LOGINFO("Loading Squirrel plugin: %s", PluginFile.c_str() );
try
{
SquirrelObject SquirrelScript = SquirrelVM::CompileScript( (std::string("Plugins/") + PluginFile + ".nut").c_str() );
try
{
SquirrelVM::RunScript( SquirrelScript );
}
catch (SquirrelError & e)
{
LOGERROR("Error: %s, %s\n", e.desc, "SquirrelVM::RunScript");
}
}
catch (SquirrelError & e)
{
LOGERROR("Error: %s, %s\n", e.desc, "SquirrelVM::CompileScript");
}
}
}
#endif
}
}
@ -98,6 +141,8 @@ void cPluginManager::ReloadPluginsNow()
{
LOG("WARNING: Can't find settings.ini, so can't load any plugins.");
}
LOG("--Done loading plugins--");
}
@ -291,11 +336,11 @@ bool cPluginManager::CallHook( PluginHook a_Hook, unsigned int a_NumArgs, ... )
return false;
}
cPlugin* cPluginManager::GetPlugin( std::string a_Plugin )
cPlugin* cPluginManager::GetPlugin( const char* a_Plugin )
{
for( PluginList::iterator itr = m_pState->Plugins.begin(); itr != m_pState->Plugins.end(); ++itr )
{
if( (*itr)->GetName().compare( a_Plugin ) == 0 )
if( std::string( (*itr)->GetName() ).compare( a_Plugin ) == 0 )
{
return *itr;
}
@ -328,6 +373,25 @@ void cPluginManager::UnloadPluginsNow()
{
RemovePlugin( *m_pState->Plugins.begin(), true );
}
//SquirrelVM::Shutdown(); // This breaks shit
}
void cPluginManager::RemoveHooks( cPlugin* a_Plugin )
{
m_pState->Hooks[ E_PLUGIN_TICK ].remove( a_Plugin );
m_pState->Hooks[ E_PLUGIN_CHAT ].remove( a_Plugin );
m_pState->Hooks[ E_PLUGIN_COLLECT_ITEM ].remove( a_Plugin );
m_pState->Hooks[ E_PLUGIN_BLOCK_DIG ].remove( a_Plugin );
m_pState->Hooks[ E_PLUGIN_BLOCK_PLACE ].remove( a_Plugin );
m_pState->Hooks[ E_PLUGIN_DISCONNECT ].remove( a_Plugin );
m_pState->Hooks[ E_PLUGIN_HANDSHAKE ].remove( a_Plugin );
m_pState->Hooks[ E_PLUGIN_LOGIN ].remove( a_Plugin );
m_pState->Hooks[ E_PLUGIN_PLAYER_SPAWN ].remove( a_Plugin );
m_pState->Hooks[ E_PLUGIN_PLAYER_JOIN ].remove( a_Plugin );
m_pState->Hooks[ E_PLUGIN_PLAYER_MOVE ].remove( a_Plugin );
m_pState->Hooks[ E_PLUGIN_TAKE_DAMAGE ].remove( a_Plugin );
m_pState->Hooks[ E_PLUGIN_KILLED ].remove( a_Plugin );
}
void cPluginManager::RemovePlugin( cPlugin* a_Plugin, bool a_bDelete /* = false */ )
@ -336,8 +400,10 @@ void cPluginManager::RemovePlugin( cPlugin* a_Plugin, bool a_bDelete /* = false
{
m_LuaCommandBinder->RemoveBindingsForPlugin( a_Plugin );
m_pState->Plugins.remove( a_Plugin );
RemoveHooks( a_Plugin );
a_Plugin->OnDisable();
delete a_Plugin;
if( a_Plugin->GetLanguage() != cPlugin::E_SQUIRREL ) // Squirrel needs to clean it up himself!
delete a_Plugin;
}
else
{
@ -356,11 +422,14 @@ bool cPluginManager::AddPlugin( cPlugin* a_Plugin )
m_pState->Plugins.push_back( a_Plugin );
return true;
}
RemoveHooks( a_Plugin ); // Undo any damage the Initialize() might have done
return false;
}
bool cPluginManager::AddPlugin( lua_State* a_LuaState, cPlugin* a_Plugin )
{
a_Plugin->SetLanguage( cPlugin::E_LUA );
cPlugin_Lua* LuaPlugin = GetLuaPlugin( a_LuaState );
if( LuaPlugin && a_Plugin->Initialize() )
{
@ -391,8 +460,8 @@ void cPluginManager::RemoveLuaPlugin( std::string a_FileName )
if( (*itr)->GetFileName() == a_FileName )
{
cPlugin_Lua* Plugin = *itr;
delete Plugin;
m_pState->LuaPlugins.remove( Plugin );
delete Plugin;
return;
}
}

View File

@ -34,7 +34,7 @@ public: //tolua_export
static cPluginManager * GetPluginManager(); //tolua_export
typedef std::list< cPlugin* > PluginList;
cPlugin* GetPlugin( std::string a_Plugin ); //tolua_export
cPlugin* GetPlugin( const char* a_Plugin ); //tolua_export
const PluginList & GetAllPlugins(); // >> EXPORTED IN MANUALBINDINGS <<
void ReloadPlugins(); //tolua_export
@ -47,6 +47,7 @@ public: //tolua_export
bool CallHook( PluginHook a_Hook, unsigned int a_NumArgs, ... );
void RemoveHooks( cPlugin* a_Plugin );
void RemovePlugin( cPlugin* a_Plugin, bool a_bDelete = false ); //tolua_export
void RemoveLuaPlugin( std::string a_FileName ); //tolua_export
cPlugin_Lua* GetLuaPlugin( lua_State* a_State ); //tolua_export

View File

@ -109,7 +109,7 @@ void cWebAdmin::Request_Handler(webserver::http_request* r)
const cPluginManager::PluginList & List = PM->GetAllPlugins();
for( cPluginManager::PluginList::const_iterator itr = List.begin(); itr != List.end(); ++itr )
{
Content += (*itr)->GetName() + "<br>";
Content += std::string( (*itr)->GetName() ) + "<br>";
}
Content += "</p>";
Content += "<h4>Players:</h4><p>";

View File

@ -9,6 +9,13 @@
#include <csignal> //std::signal
#include <stdlib.h> //exit()
#include "SquirrelBindings.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 <sqplus/sqplus.h>
#pragma warning(default:4100;default:4127;default:4510;default:4610;default:4244;default:4512)
#endif
void ShowCrashReport(int)
{
std::signal(SIGSEGV, SIG_DFL);
@ -43,6 +50,11 @@ int main( int argc, char **argv )
{
LOGERROR("Unknown exception!");
}
#if USE_SQUIRREL
SquirrelVM::Shutdown();
#endif
#ifdef _DEBUG
_CrtDumpMemoryLeaks();
#endif

View File

@ -0,0 +1,41 @@
Squirrel 3.0 stable
--------------------------------------------------------
What is in this distribution?
squirrel
static library implementing the compiler and interpreter of the language
sqstdlib
the standard utility libraries
sq
stand alone interpreter
doc
The manual
etc
a minimalistic embedding sample
samples
samples programs
HOW TO COMPILE
---------------------------------------------------------
GCC USERS
.........................................................
There is a very simple makefile that compiles all libraries and exes
from the root of the project run 'make'
for 32 bits systems
$ make
for 64 bits systems
$ make sq64
VISUAL C++ USERS
.........................................................
Open squirrel.dsw from the root project directory and build(dho!)

View File

@ -0,0 +1,21 @@
Copyright (c) 2003-2011 Alberto Demichelis
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
-----------------------------------------------------
END OF COPYRIGHT

View File

@ -0,0 +1,422 @@
***version 3.0.1 stable***
-added # as alternative symbol for "line comment"(mostly useful for shell scripts)
-added sq_throwobject() to throw an arbitrary object from the C API
-added alignement flag for userdata types, SQ_ALIGNMENT (thx Shigemasa)
-added rawset() and rawget() to class and instance default delegate
-changed bytecode format now ensures matching integer size and float size
-now inherited classes also inherit userdatasize
-added SQUIRREL_VERSION_NUMBER in squirrel.h and _versionnumber_ global symbol
-fixed sq_getmemberhandle
-fixed sq_getrefcount
-refactored some sqstdio code
-refactored some clone code
-refactored some stuff in the string lib
-added -s and -fno-exceptions in GCC makefile(better performance when using GCC)
***2011-03-13 ***
***version 3.0 stable***
-added sq_getcallee()
-sq_getfreevariable() also works for native closures
-minior optimizations
-removed several warning when compiling with GCC 4.x
-fixed some errors in the documentation
-fixed bug when using SQUSEDOUBLE and 32bits intengers
-fixed bug when invoking generators with closure.call() (thx huntercool)
***2010-12-19 ***
***version 3.0 release candidate 1(RC 1)***
-improved metamethods error handling
-added parameter 'isstatic' to _newmember metamethod(thx G.Meyer)
-added sq_getrefcount() to return number of refences from C++(thx G.Meyer)
***2010-11-07 ***
***version 3.0 beta 3***
-license changed to "MIT license"
-added sq_resurrectunreachable() and resurrectunreachable()
-added callee() built in function, returns the current running closure
-added thread.getstackinfos()
-added sq_objtouserpointer()
-added sq_newtableex()
-various refactoring and optimizations
-fixed several 64bits issues regarding integer to string conversions
-fixed some bugs when SQUSEDOUBLE is used in 32bits systems
***2010-08-18 ***
***version 3.0 beta 2.1***
-fixed bug in class constructor
-fixed bug in compound arith
***2010-08-12 ***
***version 3.0 beta 2***
-class methods can be added or replaced after the class as been instantiated
-JSON compliant table syntax, this is currently an experimental feature (thx atai)
-sq_getsize() now returns userdatasize for classes and instances
-now setroottable() and setconsttable() return the previous value of the respective table
-fixed bug in compound arith operators when used on a free variable (thx ellon)
-fixed some x64 minor bugs
-fixed minor bug in the compiler
-refactored some VM internals
-documented sq_getmemberhandle, sq_getbyhandle, sq_setbyhandle to set and get value from classes
***2009-11-15 ***
***version 3.0 beta 1***
-various refactoring and optimizations
-fixed bug in free variables (thx mokehehe)
-fixed bug in functions with default parameters (thx ara & Yexo)
-fixed bug in exception handling
-improved error propagation in _set and _get metamethods ( and 'throw null' for clean failure)
-added sq_getmemberhandle, sq_getbyhandle, sq_setbyhandle to set and get value from classes
***2009-06-30 ***
***version 3.0 alpha 2***
-added real free variables(thx Paul Ruizendaal)
-added refactored function call implementation and compiler(thx Paul Ruizendaal)
-added sq_getfunctioninfo
-added compile time flag SQUSEDOUBLE to use double precision floats
-added global slot _floatsize_ int the base lib to recognize single precision and double precision builds
-sq_wakeupvm can now resume the vm with an exception
-added sqstd_format
-now blobs can be cloned
-generators can now be instantiated by calling sq_call() or closure.call()
-fixed debughook bug
-fixed cooroutine error propagation
***2008-07-23 ***
***version 3.0 alpha 1***
-first branch from 2.x source tree
-added 'base' keyword
-removed 'delegate' keyword
-now compiled scripts are vararg functions
-added setdelegate() and getdelegate() table builtin methods
-added <=> 3 ways compare operator
-added lambda expression @(a,b) a + b
-added local function statement
-added array built-in map(),reduce(),apply(),filter() and find()
-generators hold only a weak reference of the enviroment object
-removed 'vargv' and 'vargc' keywords
-now var args are passed as an array called vargv(as a paramter)
-removed 'parent' keyword
-added class getbase() built in method
-instanceof doesn't throw an exception if the left expression is not a class
-lexical scoping for free variables(free variables are no longer in the second parameter list)
-sq_setprintfunc accept error func
-sq_geterrorfunc()
-added sq_arrayremove() and sq_arrayinsert()
-error() built in function(works like print but prints using the errorfunc)
-added native debug hook
***2008-02-17 ***
***version 2.2 stable***
-added _newslot metamethod in classes
-added enums added constants
-added sq_pushconsttable, sq_setconsttable
-added default param
-added octal literals(thx Dinosaur)
-fixed debug hook, 'calls' and 'returns' are properly notified in the same number.
-fixed a coroutine bug
***2007-07-29 ***
***version 2.1.2 stable***
-new behaviour for generators iteration using foreach
now when a generator is iterated by foreach the value returned by a 'return val' statement
will terminate the iteration but will not be returned as foreach iteration
-added sq_setclassudsize()
-added sq_clear()
-added table.clear(), array.clear()
-fixed sq_cmp() (thx jyuill)
-fixed minor bugs
***2006-08-21 ***
***version 2.1.1 stable***
-vm refactoring
-optimized internal function memory layout
-new global symbol _version_ (is the version string)
-code size optimization for float literals(on 32bits float builts)
-now the raw ref API(sq_addref etc...) is fully reentrant.
-fixed a bug in sq_getdelegate() now pushes null if the object doesn't have a delegate(thx MatzeB)
-improved C reference performances in NO_GARBAGE_COLLECTOR builds
-sq_getlocal() now enumerates also outer values.
-fixed regexp library for GCC users.
***2006-03-19 ***
***version 2.1 stable***
-added static class fields, new keyword static
-added 64bits architecture support
-added global slot _intsize_ int the base lib to recognize 32bits and 64bits builds
-added functions with fixed environment, closure.bindenv() built-in function
-all types except userdata and null implement the tostring() method
-string concatenation now invokes metamethod _tostring
-new metamethods for class objects _newmember and _inherited
-sq_call() sq_resume() sq_wakeupvm() have a new signature
-new C referencing implementation(scales more with the amount of references)
-refactored hash table
-new api functions sq_newslot(),sq_tobool(),sq_getbase(), sq_instanceof(), sq_bindenv()
-the api func sq_createslot was deprecated but still supported in form of C macro on top of sq_newslot
-sq_setreleasehook() now also works for classes
-stream.readstr() and stream.writestr() have been deprecated(this affects file and blob)
-fixed squirrel.h undeclared api calls
-fixed few minor bugs
-SQChar is now defined as wchar_t
-removed warning when building with -Wall -pedantic for GCC users
-added new std io function writeclosuretofile()
-added new std string functions strip(),rstrip(),lstrip() and split()
-regular expressions operators (+,*) now have more POSIX greedyness behaviour
-class constructors are now invoked as normal functions
***2005-10-02 ***
***version 2.0.5 stable***
-fixed some 64bits incompatibilities (thx sarge)
-fixed minor bug in the stdlib format() function (thx Rick)
-fixed a bug in dofile() that was preventing to compile empty files
-added new API sq_poptop() & sq_getfreevariable()
-some performance improvements
***2005-08-14 ***
***version 2.0.4 stable***
-weak references and related API calls
-added sq_objtobool()
-class instances memory policies improved(1 mem allocation for the whole instance)
-typetags are now declared as SQUserPointer instead of unsigned int
-first pass for 64bits compatibility
-fixed minor bug in the stdio stream
-fixed a bug in format()
-fixed bug in string.tointeger() and string.tofloat()
***2005-06-24 ***
***version 2.0.3 stable***
-dofile() and loadfile() in the iolib now can decode ASCII, UTF8 files UCS2 big-endian and little-endian
-sq_setparamscheck() : now typemesk can check for null
-added string escape sequence \xhhhh
-fixed some C++ standard incompatibilities
***2005-05-15 ***
***version 2.0.2 stable***
-performances improvements (expecially for GCC users)
-removed all dependencies from C++ exception handling
-various bugfixes
***2005-04-12 ***
***version 2.0.1 stable***
-various bugfixes
-sq_setparamscheck() now allows spaces in the typemask
***2005-04-03 ***
***version 2.0 stable***
-added API sq_gettypetag()
-added built-in function to the bool type(tointeger, tostring etc...)
***2005-02-27 ***
***version 2.0 release candidate 1(RC 1)***
-added API sq_reseterror()
-modified sq_release()
-now class instances can be cloned
-various bufixes
***2005-01-26 ***
***version 2.0 beta 1***
-added bool type
-class properties can be redefined in a derived class
-added ops *= /= and %=
-new syntax for class attributes declaration </ and /> instead of ( and )
-increased the max number of literals per function from 65535 to 16777215
-now free variables have proper lexical scoping
-added API sq_createinstance(), sq_pushbool(), sq_getbool()
-added built-in function type()
-added built-in function obj.rawin(key) in table,class and instance
-sq_rawget() and sq_rawset() now work also on classes and instances
-the VM no longer uses C++ exception handling (more suitable for embedded devices)
-various bufixes
***2004-12-21 ***
***version 2.0 alpha 2***
-globals scoping changed, now if :: is omitted the VM automatically falls back on the root table
-various bufixes
-added class level attributes
***2004-12-12 ***
***version 2.0 alpha 1***
-codebase branch from version 1.x
-added classes
-added functions with variable number of parameters(vargc & vargv and the ...)
-0 and 0.0 are now considered 'false' by all conditional statements(if,while,for,?,do-while)
-added new api functions sq_newclass() sq_setinstanceup() sq_getinstanceup() sq_getattributes() sq_setattributes()
-modified api sq_settypetag()
***2004-11-01 ***
***version 1.0 stable***
-fixed some minor bug
-improved operator 'delete' performances
-added scientific notation for float numbers( eg. 2.e16 or 2.e-2)
***2004-08-30 ***
***version 1.0 release candidate 2(RC 2)***
-fixed bug in the vm(thx Pierre Renaux)
-fixed bug in the optimizer(thx Pierre Renaux)
-fixed some bug in the documentation(thx JD)
-added new api functions for raw object handling
-removed nested multiline comments
-reduced memory footprint in C references
***2004-08-23 ***
***version 1.0 release candidate 1(RC 1)***
-fixed division by zero
-the 'in' operator and obj.rawget() do not query the default delegate anymore
-added function sq_getprintfunc()
-added new standard library 'auxlib'(implements default error handlers)
***2004-07-12 ***
***version 1.0 beta 4***
-fixed a bug in the integer.tochar() built-in method
-fixed unary minus operator
-fixed bug in dofile()
-fixed inconsistency between != and == operators(on float/integer comparison)
-added javascript style unsigned right shift operator '>>>'
-added array(size) constructor built-in function
-array.resize(size,[fill]) built-in function accepts an optional 'fill' value
-improved debug API, added sq_getclosureinfo() and sq_setnativeclosurename()
***2004-05-23 ***
***version 1.0 beta 3***
-minor vm bug fixes
-string allocation is now faster
-tables and array memory usage is now less conservative(they shrink)
-added regular expression routines in the standard library
-The 'c' expression now accepts only 1 character(thx irbrian)
-multiline strings <[ ]> have been substituted with C# style verbatim strings (eg. @"string")
-added new keyword 'parent' for accessing the delegate of tables and unserdata
-The metamethod '_clone' has been renamed '_cloned'
-the _delslot metamethod's behaviour and prototype have been changed
-new default function in the integer and float object 'tochar()'
-the built-in function chcode2string has been removed
-the default method [table].getdelegate() has been removed
-new api sq_rawdeleteslot()
-new table built-in method rawdelete(key)
-the dynamic mudule loading has been removed from the standard distribution
-some optimizations in the VM
***2004-04-21 ***
***version 1.0 beta 2***
-minor compiler/parser bug fixes
-sq_newclosure has a different prototype, the "paramscheck" of paramter has been moved to the new function sq_setparamscheck()
-sq_setparamscheck allows to add automatic parameters type checking in native closures
-sq_compile() lost the lineinfo parameter
-new api sq_enabledebuginfo() globally sets compiler's debug info generation
-added consistency check on bytecode serialization
-fixed += operator, now works on strings like +
-added global slot in the base lib _charsize_ to recognize unicode builds from ascii builds runtime
-added registry table
-new api call sq_pushregistrytable()
-added type tag to the userdata type sq_settypetag()
-sq_getuserdata now queries the userdata typetag
-the built in function collect_garbage() as been renamed collectgarbage() for consistency reasons
-new standard libraries(sqlibs are now obsolete)
***2004-02-20 ***
***version 1.0 beta 1***
-fixed a bug in the compiler (thanks Martin Kofler)
-fixed bug in the switch case statement
-fixed the _unm metamethod
-fixed minor bugs in the API
-fixed automatic stack resizing
-first beta version
first pass code clean up in the VM and base lib
first pass code coverege test has been done on VM and built-in lib
-new VM creation API sq_open() sq_close() (sq_newvm and sq_releasevm are now obsolete)
-new api allows to specifiy a "print" function to output text(sq_printfunc)
-added some small optimizations
-new cooperative multi-threading capabilities in the base library(coroutines), VMs are now a built in type("thread")
-new built in functions have been added for manipulating the new "thread" type
-friend virtual machines share the same root table, error handler and debug hook by default
-new compile time options
***2004-01-19 ***
***version 0.9 alpha***
-fixed a garbage collection bug
-fixed some API bugs(thanks to Joshua Jensen)
-fixed tail calls (in the version 0.8 the tail call optimization was erroneously disabled)
-new function parameters semantic, now passing a wrong number of parameters generates an exception
-native closures have now a built in parameter number checking
-sq_rawget and sq_rawset now work also on arrays
-sq_getsize now woks also on userdata
-the userdata release hook prototype is changed(now passes the size of the userdata)
-the lexer reader function now returns an integer instead of a char that allows better error checking on the input(thx Joshua Jensen)
-faster compiler
-try/catch blocks do not cause any runtime memory allocation anymore
***2003-12-06 ***
***version 0.8 alpha***
-fixed a bug that was preventing to have callable userdata throught the metamethod _call
-fixed a garbage collection bug
-fixed == operator now can compare correctly different types
-new built in method getstackinfos(level)
-improved line informations precision for the debug hook
-new api call sq_compilebuffer()
-new built-in api function compilestring()
-new syntactic sugar for function declarations inside tables
-the debug API has been finalized
***2003-11-17 ***
***version 0.7 alpha***
-fixed critical bug SQInteger the tail call system
-fixed bug in the continue statement code generation
-fixed func call param issue(thanks to Rewoonenco Andrew)
-added _delslot metamethod(thanks to Rewoonenco Andrew)
-new multiline string expression ( delimited by <[ and ]> )
-normal strings ("") do not allow embedded new line anymore
-reduced vm memory footprint(C refs are shared between friend VMs)
-new api method sq_deleteslot()
-new debug hook event 'r' is triggered when a function returns
***2003-11-04 ***
***version 0.6 alpha***
-fixed switch statement(was executing the default case after a break)
-sq_call() doesn't pop the closure (just the params)
-the vm execution can be suspended from the C API anytime (micro-threads)
-new api calls sq_suspendvm() sq_wakeupvm() sq_getvmstate() and sq_reservestack()
***2003-10-13 ***
***version 0.5 alpha***
-fixed some minor bug
-tested with non ASCII identifiers in unicode mode(I've tried chinese chars)
-added built-in function string.find()
-the built-in function array.sort() optionally accepts a cmp(a,b) function
-the debug hook function now has a new prototype debug_hook(event_type,sourcefile,line,functionname)
-fixed some debug info imprecision
***2003-10-01 ***
***version 0.4 alpha***
-faster VM
-sq_call will pop arguments and closure also in case of failure
-fixed a bug in sq_remove
-now the VM detects delegation cycles(and throws an exception)
-new operators ++ and --
-new operator ',' comma operator
-fixed some expression precedence issue
-fixed bug in sq_arraypop
***2003-09-15 ***
***version 0.3 alpha***
-fixed a bug in array::insert()
-optional Unicode core(define SQUNICODE or _UNICODE on Win32)
-sq_compiler uses a new reader function SQLEXREADFUNC
-the debug hook passes 'l' instead of 'line' for line callbacks
and 'c' instead of 'call' for call callbacks
-new array.extend() bulit-in function
-new API sq_clone()
***2003-09-10 ***
***version 0.2 pre-alpha***
-new completely reentrant VM (sq_open and sq_close are now obsolete)
-sq_newvm() has a new prototype
-allocators are now global and linked in the VM
-_newslot meta method added
-rawset creates a slot if doesn't exists
-the compiler error callback pass the vm handle(thanks Pierre Renaux)
-sq_setforeignptr() sq_getforeingptr() are now public
-sq_resume() now is possible to resume generators from C
-sq_getlasterror() retrieve the last thrown error
-improved docs
***2003-09-06 ***
***version 0.1 pre-alpha***
first release

View File

@ -0,0 +1,18 @@
SQUIRREL=.
MAKE=make
sq32:
cd squirrel; $(MAKE)
cd sqstdlib; $(MAKE)
cd sq; $(MAKE)
sqprof:
cd squirrel; $(MAKE) sqprof
cd sqstdlib; $(MAKE) sqprof
cd sq; $(MAKE) sqprof
sq64:
cd squirrel; $(MAKE) sq64
cd sqstdlib; $(MAKE) sq64
cd sq; $(MAKE) sq64

View File

@ -0,0 +1,23 @@
The programming language SQUIRREL 3.0 stable
--------------------------------------------------
The project has been compiled and run on Windows(x86 and x64) and
Linux(x86 and x64) and Solaris(x86 and x64).
Has been tested with the following compilers:
MS Visual C++ 6.0,7.0,7.1,8.0,9.0,10.0 (32 and 64bits)
MinGW gcc 3.2 (mingw special 20020817-1)
Cygnus gcc 3.2
Linux gcc 3.2.3
Linux gcc 4.0.0 (x86 & 64bits)
Solaris gcc 4.0.0 (x86 & 64bits)
Feedback and suggestions are appreciated
project page - http://www.squirrel-lang.org
community forums - http://forum.squirrel-lang.org
wiki - http://wiki.squirrel-lang.org
author - alberto@demichelis.net
END OF README

View File

@ -0,0 +1,16 @@
/* see copyright notice in squirrel.h */
#ifndef _SQSTD_AUXLIB_H_
#define _SQSTD_AUXLIB_H_
#ifdef __cplusplus
extern "C" {
#endif
SQUIRREL_API void sqstd_seterrorhandlers(HSQUIRRELVM v);
SQUIRREL_API void sqstd_printcallstack(HSQUIRRELVM v);
#ifdef __cplusplus
} /*extern "C"*/
#endif
#endif /* _SQSTD_AUXLIB_H_ */

View File

@ -0,0 +1,20 @@
/* see copyright notice in squirrel.h */
#ifndef _SQSTDBLOB_H_
#define _SQSTDBLOB_H_
#ifdef __cplusplus
extern "C" {
#endif
SQUIRREL_API SQUserPointer sqstd_createblob(HSQUIRRELVM v, SQInteger size);
SQUIRREL_API SQRESULT sqstd_getblob(HSQUIRRELVM v,SQInteger idx,SQUserPointer *ptr);
SQUIRREL_API SQInteger sqstd_getblobsize(HSQUIRRELVM v,SQInteger idx);
SQUIRREL_API SQRESULT sqstd_register_bloblib(HSQUIRRELVM v);
#ifdef __cplusplus
} /*extern "C"*/
#endif
#endif /*_SQSTDBLOB_H_*/

View File

@ -0,0 +1,53 @@
/* see copyright notice in squirrel.h */
#ifndef _SQSTDIO_H_
#define _SQSTDIO_H_
#ifdef __cplusplus
#define SQSTD_STREAM_TYPE_TAG 0x80000000
struct SQStream {
virtual SQInteger Read(void *buffer, SQInteger size) = 0;
virtual SQInteger Write(void *buffer, SQInteger size) = 0;
virtual SQInteger Flush() = 0;
virtual SQInteger Tell() = 0;
virtual SQInteger Len() = 0;
virtual SQInteger Seek(SQInteger offset, SQInteger origin) = 0;
virtual bool IsValid() = 0;
virtual bool EOS() = 0;
};
extern "C" {
#endif
#define SQ_SEEK_CUR 0
#define SQ_SEEK_END 1
#define SQ_SEEK_SET 2
typedef void* SQFILE;
SQUIRREL_API SQFILE sqstd_fopen(const SQChar *,const SQChar *);
SQUIRREL_API SQInteger sqstd_fread(SQUserPointer, SQInteger, SQInteger, SQFILE);
SQUIRREL_API SQInteger sqstd_fwrite(const SQUserPointer, SQInteger, SQInteger, SQFILE);
SQUIRREL_API SQInteger sqstd_fseek(SQFILE , SQInteger , SQInteger);
SQUIRREL_API SQInteger sqstd_ftell(SQFILE);
SQUIRREL_API SQInteger sqstd_fflush(SQFILE);
SQUIRREL_API SQInteger sqstd_fclose(SQFILE);
SQUIRREL_API SQInteger sqstd_feof(SQFILE);
SQUIRREL_API SQRESULT sqstd_createfile(HSQUIRRELVM v, SQFILE file,SQBool own);
SQUIRREL_API SQRESULT sqstd_getfile(HSQUIRRELVM v, SQInteger idx, SQFILE *file);
//compiler helpers
SQUIRREL_API SQRESULT sqstd_loadfile(HSQUIRRELVM v,const SQChar *filename,SQBool printerror);
SQUIRREL_API SQRESULT sqstd_dofile(HSQUIRRELVM v,const SQChar *filename,SQBool retval,SQBool printerror);
SQUIRREL_API SQRESULT sqstd_writeclosuretofile(HSQUIRRELVM v,const SQChar *filename);
SQUIRREL_API SQRESULT sqstd_register_iolib(HSQUIRRELVM v);
#ifdef __cplusplus
} /*extern "C"*/
#endif
#endif /*_SQSTDIO_H_*/

View File

@ -0,0 +1,15 @@
/* see copyright notice in squirrel.h */
#ifndef _SQSTD_MATH_H_
#define _SQSTD_MATH_H_
#ifdef __cplusplus
extern "C" {
#endif
SQUIRREL_API SQRESULT sqstd_register_mathlib(HSQUIRRELVM v);
#ifdef __cplusplus
} /*extern "C"*/
#endif
#endif /*_SQSTD_MATH_H_*/

View File

@ -0,0 +1,33 @@
/* see copyright notice in squirrel.h */
#ifndef _SQSTD_STRING_H_
#define _SQSTD_STRING_H_
#ifdef __cplusplus
extern "C" {
#endif
typedef unsigned int SQRexBool;
typedef struct SQRex SQRex;
typedef struct {
const SQChar *begin;
SQInteger len;
} SQRexMatch;
SQUIRREL_API SQRex *sqstd_rex_compile(const SQChar *pattern,const SQChar **error);
SQUIRREL_API void sqstd_rex_free(SQRex *exp);
SQUIRREL_API SQBool sqstd_rex_match(SQRex* exp,const SQChar* text);
SQUIRREL_API SQBool sqstd_rex_search(SQRex* exp,const SQChar* text, const SQChar** out_begin, const SQChar** out_end);
SQUIRREL_API SQBool sqstd_rex_searchrange(SQRex* exp,const SQChar* text_begin,const SQChar* text_end,const SQChar** out_begin, const SQChar** out_end);
SQUIRREL_API SQInteger sqstd_rex_getsubexpcount(SQRex* exp);
SQUIRREL_API SQBool sqstd_rex_getsubexp(SQRex* exp, SQInteger n, SQRexMatch *subexp);
SQUIRREL_API SQRESULT sqstd_format(HSQUIRRELVM v,SQInteger nformatstringidx,SQInteger *outlen,SQChar **output);
SQUIRREL_API SQRESULT sqstd_register_stringlib(HSQUIRRELVM v);
#ifdef __cplusplus
} /*extern "C"*/
#endif
#endif /*_SQSTD_STRING_H_*/

View File

@ -0,0 +1,15 @@
/* see copyright notice in squirrel.h */
#ifndef _SQSTD_SYSTEMLIB_H_
#define _SQSTD_SYSTEMLIB_H_
#ifdef __cplusplus
extern "C" {
#endif
SQUIRREL_API SQInteger sqstd_register_systemlib(HSQUIRRELVM v);
#ifdef __cplusplus
} /*extern "C"*/
#endif
#endif /* _SQSTD_SYSTEMLIB_H_ */

View File

@ -0,0 +1,500 @@
/*
Copyright (c) 2003-2011 Alberto Demichelis
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#ifndef _SQUIRREL_H_
#define _SQUIRREL_H_
#ifdef __cplusplus
extern "C" {
#endif
#ifndef SQUIRREL_API
#define SQUIRREL_API extern
#endif
#if (defined(_WIN64) || defined(_LP64))
#ifndef _SQ64
#define _SQ64
#endif
#endif
#ifdef _SQ64
#ifdef _MSC_VER
typedef __int64 SQInteger;
typedef unsigned __int64 SQUnsignedInteger;
typedef unsigned __int64 SQHash; /*should be the same size of a pointer*/
#else
typedef long long SQInteger;
typedef unsigned long long SQUnsignedInteger;
typedef unsigned long long SQHash; /*should be the same size of a pointer*/
#endif
typedef int SQInt32;
typedef unsigned int SQUnsignedInteger32;
#else
typedef int SQInteger;
typedef int SQInt32; /*must be 32 bits(also on 64bits processors)*/
typedef unsigned int SQUnsignedInteger32; /*must be 32 bits(also on 64bits processors)*/
typedef unsigned int SQUnsignedInteger;
typedef unsigned int SQHash; /*should be the same size of a pointer*/
#endif
#ifdef SQUSEDOUBLE
typedef double SQFloat;
#else
typedef float SQFloat;
#endif
#if defined(SQUSEDOUBLE) && !defined(_SQ64) || !defined(SQUSEDOUBLE) && defined(_SQ64)
#ifdef _MSC_VER
typedef __int64 SQRawObjectVal; //must be 64bits
#else
typedef long long SQRawObjectVal; //must be 64bits
#endif
#define SQ_OBJECT_RAWINIT() { _unVal.raw = 0; }
#else
typedef SQUnsignedInteger SQRawObjectVal; //is 32 bits on 32 bits builds and 64 bits otherwise
#define SQ_OBJECT_RAWINIT()
#endif
#ifndef SQ_ALIGNMENT // SQ_ALIGNMENT shall be less than or equal to SQ_MALLOC alignments, and its value shall be power of 2.
#if defined(SQUSEDOUBLE) || defined(_SQ64)
#define SQ_ALIGNMENT 8
#else
#define SQ_ALIGNMENT 4
#endif
#endif
typedef void* SQUserPointer;
typedef SQUnsignedInteger SQBool;
typedef SQInteger SQRESULT;
#define SQTrue (1)
#define SQFalse (0)
struct SQVM;
struct SQTable;
struct SQArray;
struct SQString;
struct SQClosure;
struct SQGenerator;
struct SQNativeClosure;
struct SQUserData;
struct SQFunctionProto;
struct SQRefCounted;
struct SQClass;
struct SQInstance;
struct SQDelegable;
struct SQOuter;
#ifdef _UNICODE
#define SQUNICODE
#endif
#ifdef SQUNICODE
#if (defined(_MSC_VER) && _MSC_VER >= 1400) // 1400 = VS8
#if !defined(_NATIVE_WCHAR_T_DEFINED) //this is if the compiler considers wchar_t as native type
#define wchar_t unsigned short
#endif
#else
typedef unsigned short wchar_t;
#endif
typedef wchar_t SQChar;
#define _SC(a) L##a
#define scstrcmp wcscmp
#define scsprintf swprintf
#define scstrlen wcslen
#define scstrtod wcstod
#ifdef _SQ64
#define scstrtol _wcstoi64
#else
#define scstrtol wcstol
#endif
#define scatoi _wtoi
#define scstrtoul wcstoul
#define scvsprintf vswprintf
#define scstrstr wcsstr
#define scisspace iswspace
#define scisdigit iswdigit
#define scisxdigit iswxdigit
#define scisalpha iswalpha
#define sciscntrl iswcntrl
#define scisalnum iswalnum
#define scprintf wprintf
#define MAX_CHAR 0xFFFF
#else
typedef char SQChar;
#define _SC(a) a
#define scstrcmp strcmp
#define scsprintf sprintf
#define scstrlen strlen
#define scstrtod strtod
#ifdef _SQ64
#ifdef _MSC_VER
#define scstrtol _strtoi64
#else
#define scstrtol strtoll
#endif
#else
#define scstrtol strtol
#endif
#define scatoi atoi
#define scstrtoul strtoul
#define scvsprintf vsprintf
#define scstrstr strstr
#define scisspace isspace
#define scisdigit isdigit
#define scisxdigit isxdigit
#define sciscntrl iscntrl
#define scisalpha isalpha
#define scisalnum isalnum
#define scprintf printf
#define MAX_CHAR 0xFF
#endif
#ifdef _SQ64
#define _PRINT_INT_PREC _SC("ll")
#define _PRINT_INT_FMT _SC("%lld")
#else
#define _PRINT_INT_FMT _SC("%d")
#endif
#define SQUIRREL_VERSION _SC("Squirrel 3.0.1 stable")
#define SQUIRREL_COPYRIGHT _SC("Copyright (C) 2003-2011 Alberto Demichelis")
#define SQUIRREL_AUTHOR _SC("Alberto Demichelis")
#define SQUIRREL_VERSION_NUMBER 301
#define SQ_VMSTATE_IDLE 0
#define SQ_VMSTATE_RUNNING 1
#define SQ_VMSTATE_SUSPENDED 2
#define SQUIRREL_EOB 0
#define SQ_BYTECODE_STREAM_TAG 0xFAFA
#define SQOBJECT_REF_COUNTED 0x08000000
#define SQOBJECT_NUMERIC 0x04000000
#define SQOBJECT_DELEGABLE 0x02000000
#define SQOBJECT_CANBEFALSE 0x01000000
#define SQ_MATCHTYPEMASKSTRING (-99999)
#define _RT_MASK 0x00FFFFFF
#define _RAW_TYPE(type) (type&_RT_MASK)
#define _RT_NULL 0x00000001
#define _RT_INTEGER 0x00000002
#define _RT_FLOAT 0x00000004
#define _RT_BOOL 0x00000008
#define _RT_STRING 0x00000010
#define _RT_TABLE 0x00000020
#define _RT_ARRAY 0x00000040
#define _RT_USERDATA 0x00000080
#define _RT_CLOSURE 0x00000100
#define _RT_NATIVECLOSURE 0x00000200
#define _RT_GENERATOR 0x00000400
#define _RT_USERPOINTER 0x00000800
#define _RT_THREAD 0x00001000
#define _RT_FUNCPROTO 0x00002000
#define _RT_CLASS 0x00004000
#define _RT_INSTANCE 0x00008000
#define _RT_WEAKREF 0x00010000
#define _RT_OUTER 0x00020000
typedef enum tagSQObjectType{
OT_NULL = (_RT_NULL|SQOBJECT_CANBEFALSE),
OT_INTEGER = (_RT_INTEGER|SQOBJECT_NUMERIC|SQOBJECT_CANBEFALSE),
OT_FLOAT = (_RT_FLOAT|SQOBJECT_NUMERIC|SQOBJECT_CANBEFALSE),
OT_BOOL = (_RT_BOOL|SQOBJECT_CANBEFALSE),
OT_STRING = (_RT_STRING|SQOBJECT_REF_COUNTED),
OT_TABLE = (_RT_TABLE|SQOBJECT_REF_COUNTED|SQOBJECT_DELEGABLE),
OT_ARRAY = (_RT_ARRAY|SQOBJECT_REF_COUNTED),
OT_USERDATA = (_RT_USERDATA|SQOBJECT_REF_COUNTED|SQOBJECT_DELEGABLE),
OT_CLOSURE = (_RT_CLOSURE|SQOBJECT_REF_COUNTED),
OT_NATIVECLOSURE = (_RT_NATIVECLOSURE|SQOBJECT_REF_COUNTED),
OT_GENERATOR = (_RT_GENERATOR|SQOBJECT_REF_COUNTED),
OT_USERPOINTER = _RT_USERPOINTER,
OT_THREAD = (_RT_THREAD|SQOBJECT_REF_COUNTED) ,
OT_FUNCPROTO = (_RT_FUNCPROTO|SQOBJECT_REF_COUNTED), //internal usage only
OT_CLASS = (_RT_CLASS|SQOBJECT_REF_COUNTED),
OT_INSTANCE = (_RT_INSTANCE|SQOBJECT_REF_COUNTED|SQOBJECT_DELEGABLE),
OT_WEAKREF = (_RT_WEAKREF|SQOBJECT_REF_COUNTED),
OT_OUTER = (_RT_OUTER|SQOBJECT_REF_COUNTED) //internal usage only
}SQObjectType;
#define ISREFCOUNTED(t) (t&SQOBJECT_REF_COUNTED)
typedef union tagSQObjectValue
{
struct SQTable *pTable;
struct SQArray *pArray;
struct SQClosure *pClosure;
struct SQOuter *pOuter;
struct SQGenerator *pGenerator;
struct SQNativeClosure *pNativeClosure;
struct SQString *pString;
struct SQUserData *pUserData;
SQInteger nInteger;
SQFloat fFloat;
SQUserPointer pUserPointer;
struct SQFunctionProto *pFunctionProto;
struct SQRefCounted *pRefCounted;
struct SQDelegable *pDelegable;
struct SQVM *pThread;
struct SQClass *pClass;
struct SQInstance *pInstance;
struct SQWeakRef *pWeakRef;
SQRawObjectVal raw;
}SQObjectValue;
typedef struct tagSQObject
{
SQObjectType _type;
SQObjectValue _unVal;
}SQObject;
typedef struct tagSQMemberHandle{
SQBool _static;
SQInteger _index;
}SQMemberHandle;
typedef struct tagSQStackInfos{
const SQChar* funcname;
const SQChar* source;
SQInteger line;
}SQStackInfos;
typedef struct SQVM* HSQUIRRELVM;
typedef SQObject HSQOBJECT;
typedef SQMemberHandle HSQMEMBERHANDLE;
typedef SQInteger (*SQFUNCTION)(HSQUIRRELVM);
typedef SQInteger (*SQRELEASEHOOK)(SQUserPointer,SQInteger size);
typedef void (*SQCOMPILERERROR)(HSQUIRRELVM,const SQChar * /*desc*/,const SQChar * /*source*/,SQInteger /*line*/,SQInteger /*column*/);
typedef void (*SQPRINTFUNCTION)(HSQUIRRELVM,const SQChar * ,...);
typedef void (*SQDEBUGHOOK)(HSQUIRRELVM /*v*/, SQInteger /*type*/, const SQChar * /*sourcename*/, SQInteger /*line*/, const SQChar * /*funcname*/);
typedef SQInteger (*SQWRITEFUNC)(SQUserPointer,SQUserPointer,SQInteger);
typedef SQInteger (*SQREADFUNC)(SQUserPointer,SQUserPointer,SQInteger);
typedef SQInteger (*SQLEXREADFUNC)(SQUserPointer);
typedef struct tagSQRegFunction{
const SQChar *name;
SQFUNCTION f;
SQInteger nparamscheck;
const SQChar *typemask;
}SQRegFunction;
typedef struct tagSQFunctionInfo {
SQUserPointer funcid;
const SQChar *name;
const SQChar *source;
}SQFunctionInfo;
/*vm*/
SQUIRREL_API HSQUIRRELVM sq_open(SQInteger initialstacksize);
SQUIRREL_API HSQUIRRELVM sq_newthread(HSQUIRRELVM friendvm, SQInteger initialstacksize);
SQUIRREL_API void sq_seterrorhandler(HSQUIRRELVM v);
SQUIRREL_API void sq_close(HSQUIRRELVM v);
SQUIRREL_API void sq_setforeignptr(HSQUIRRELVM v,SQUserPointer p);
SQUIRREL_API SQUserPointer sq_getforeignptr(HSQUIRRELVM v);
SQUIRREL_API void sq_setprintfunc(HSQUIRRELVM v, SQPRINTFUNCTION printfunc,SQPRINTFUNCTION errfunc);
SQUIRREL_API SQPRINTFUNCTION sq_getprintfunc(HSQUIRRELVM v);
SQUIRREL_API SQPRINTFUNCTION sq_geterrorfunc(HSQUIRRELVM v);
SQUIRREL_API SQRESULT sq_suspendvm(HSQUIRRELVM v);
SQUIRREL_API SQRESULT sq_wakeupvm(HSQUIRRELVM v,SQBool resumedret,SQBool retval,SQBool raiseerror,SQBool throwerror);
SQUIRREL_API SQInteger sq_getvmstate(HSQUIRRELVM v);
/*compiler*/
SQUIRREL_API SQRESULT sq_compile(HSQUIRRELVM v,SQLEXREADFUNC read,SQUserPointer p,const SQChar *sourcename,SQBool raiseerror);
SQUIRREL_API SQRESULT sq_compilebuffer(HSQUIRRELVM v,const SQChar *s,SQInteger size,const SQChar *sourcename,SQBool raiseerror);
SQUIRREL_API void sq_enabledebuginfo(HSQUIRRELVM v, SQBool enable);
SQUIRREL_API void sq_notifyallexceptions(HSQUIRRELVM v, SQBool enable);
SQUIRREL_API void sq_setcompilererrorhandler(HSQUIRRELVM v,SQCOMPILERERROR f);
/*stack operations*/
SQUIRREL_API void sq_push(HSQUIRRELVM v,SQInteger idx);
SQUIRREL_API void sq_pop(HSQUIRRELVM v,SQInteger nelemstopop);
SQUIRREL_API void sq_poptop(HSQUIRRELVM v);
SQUIRREL_API void sq_remove(HSQUIRRELVM v,SQInteger idx);
SQUIRREL_API SQInteger sq_gettop(HSQUIRRELVM v);
SQUIRREL_API void sq_settop(HSQUIRRELVM v,SQInteger newtop);
SQUIRREL_API SQRESULT sq_reservestack(HSQUIRRELVM v,SQInteger nsize);
SQUIRREL_API SQInteger sq_cmp(HSQUIRRELVM v);
SQUIRREL_API void sq_move(HSQUIRRELVM dest,HSQUIRRELVM src,SQInteger idx);
/*object creation handling*/
SQUIRREL_API SQUserPointer sq_newuserdata(HSQUIRRELVM v,SQUnsignedInteger size);
SQUIRREL_API void sq_newtable(HSQUIRRELVM v);
SQUIRREL_API void sq_newtableex(HSQUIRRELVM v,SQInteger initialcapacity);
SQUIRREL_API void sq_newarray(HSQUIRRELVM v,SQInteger size);
SQUIRREL_API void sq_newclosure(HSQUIRRELVM v,SQFUNCTION func,SQUnsignedInteger nfreevars);
SQUIRREL_API SQRESULT sq_setparamscheck(HSQUIRRELVM v,SQInteger nparamscheck,const SQChar *typemask);
SQUIRREL_API SQRESULT sq_bindenv(HSQUIRRELVM v,SQInteger idx);
SQUIRREL_API void sq_pushstring(HSQUIRRELVM v,const SQChar *s,SQInteger len);
SQUIRREL_API void sq_pushfloat(HSQUIRRELVM v,SQFloat f);
SQUIRREL_API void sq_pushinteger(HSQUIRRELVM v,SQInteger n);
SQUIRREL_API void sq_pushbool(HSQUIRRELVM v,SQBool b);
SQUIRREL_API void sq_pushuserpointer(HSQUIRRELVM v,SQUserPointer p);
SQUIRREL_API void sq_pushnull(HSQUIRRELVM v);
SQUIRREL_API SQObjectType sq_gettype(HSQUIRRELVM v,SQInteger idx);
SQUIRREL_API SQInteger sq_getsize(HSQUIRRELVM v,SQInteger idx);
SQUIRREL_API SQRESULT sq_getbase(HSQUIRRELVM v,SQInteger idx);
SQUIRREL_API SQBool sq_instanceof(HSQUIRRELVM v);
SQUIRREL_API SQRESULT sq_tostring(HSQUIRRELVM v,SQInteger idx);
SQUIRREL_API void sq_tobool(HSQUIRRELVM v, SQInteger idx, SQBool *b);
SQUIRREL_API SQRESULT sq_getstring(HSQUIRRELVM v,SQInteger idx,const SQChar **c);
SQUIRREL_API SQRESULT sq_getinteger(HSQUIRRELVM v,SQInteger idx,SQInteger *i);
SQUIRREL_API SQRESULT sq_getfloat(HSQUIRRELVM v,SQInteger idx,SQFloat *f);
SQUIRREL_API SQRESULT sq_getbool(HSQUIRRELVM v,SQInteger idx,SQBool *b);
SQUIRREL_API SQRESULT sq_getthread(HSQUIRRELVM v,SQInteger idx,HSQUIRRELVM *thread);
SQUIRREL_API SQRESULT sq_getuserpointer(HSQUIRRELVM v,SQInteger idx,SQUserPointer *p);
SQUIRREL_API SQRESULT sq_getuserdata(HSQUIRRELVM v,SQInteger idx,SQUserPointer *p,SQUserPointer *typetag);
SQUIRREL_API SQRESULT sq_settypetag(HSQUIRRELVM v,SQInteger idx,SQUserPointer typetag);
SQUIRREL_API SQRESULT sq_gettypetag(HSQUIRRELVM v,SQInteger idx,SQUserPointer *typetag);
SQUIRREL_API void sq_setreleasehook(HSQUIRRELVM v,SQInteger idx,SQRELEASEHOOK hook);
SQUIRREL_API SQChar *sq_getscratchpad(HSQUIRRELVM v,SQInteger minsize);
SQUIRREL_API SQRESULT sq_getfunctioninfo(HSQUIRRELVM v,SQInteger idx,SQFunctionInfo *fi);
SQUIRREL_API SQRESULT sq_getclosureinfo(HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger *nparams,SQUnsignedInteger *nfreevars);
SQUIRREL_API SQRESULT sq_setnativeclosurename(HSQUIRRELVM v,SQInteger idx,const SQChar *name);
SQUIRREL_API SQRESULT sq_setinstanceup(HSQUIRRELVM v, SQInteger idx, SQUserPointer p);
SQUIRREL_API SQRESULT sq_getinstanceup(HSQUIRRELVM v, SQInteger idx, SQUserPointer *p,SQUserPointer typetag);
SQUIRREL_API SQRESULT sq_setclassudsize(HSQUIRRELVM v, SQInteger idx, SQInteger udsize);
SQUIRREL_API SQRESULT sq_newclass(HSQUIRRELVM v,SQBool hasbase);
SQUIRREL_API SQRESULT sq_createinstance(HSQUIRRELVM v,SQInteger idx);
SQUIRREL_API SQRESULT sq_setattributes(HSQUIRRELVM v,SQInteger idx);
SQUIRREL_API SQRESULT sq_getattributes(HSQUIRRELVM v,SQInteger idx);
SQUIRREL_API SQRESULT sq_getclass(HSQUIRRELVM v,SQInteger idx);
SQUIRREL_API void sq_weakref(HSQUIRRELVM v,SQInteger idx);
SQUIRREL_API SQRESULT sq_getdefaultdelegate(HSQUIRRELVM v,SQObjectType t);
SQUIRREL_API SQRESULT sq_getmemberhandle(HSQUIRRELVM v,SQInteger idx,HSQMEMBERHANDLE *handle);
SQUIRREL_API SQRESULT sq_getbyhandle(HSQUIRRELVM v,SQInteger idx,HSQMEMBERHANDLE *handle);
SQUIRREL_API SQRESULT sq_setbyhandle(HSQUIRRELVM v,SQInteger idx,HSQMEMBERHANDLE *handle);
/*object manipulation*/
SQUIRREL_API void sq_pushroottable(HSQUIRRELVM v);
SQUIRREL_API void sq_pushregistrytable(HSQUIRRELVM v);
SQUIRREL_API void sq_pushconsttable(HSQUIRRELVM v);
SQUIRREL_API SQRESULT sq_setroottable(HSQUIRRELVM v);
SQUIRREL_API SQRESULT sq_setconsttable(HSQUIRRELVM v);
SQUIRREL_API SQRESULT sq_newslot(HSQUIRRELVM v, SQInteger idx, SQBool bstatic);
SQUIRREL_API SQRESULT sq_deleteslot(HSQUIRRELVM v,SQInteger idx,SQBool pushval);
SQUIRREL_API SQRESULT sq_set(HSQUIRRELVM v,SQInteger idx);
SQUIRREL_API SQRESULT sq_get(HSQUIRRELVM v,SQInteger idx);
SQUIRREL_API SQRESULT sq_rawget(HSQUIRRELVM v,SQInteger idx);
SQUIRREL_API SQRESULT sq_rawset(HSQUIRRELVM v,SQInteger idx);
SQUIRREL_API SQRESULT sq_rawdeleteslot(HSQUIRRELVM v,SQInteger idx,SQBool pushval);
SQUIRREL_API SQRESULT sq_arrayappend(HSQUIRRELVM v,SQInteger idx);
SQUIRREL_API SQRESULT sq_arraypop(HSQUIRRELVM v,SQInteger idx,SQBool pushval);
SQUIRREL_API SQRESULT sq_arrayresize(HSQUIRRELVM v,SQInteger idx,SQInteger newsize);
SQUIRREL_API SQRESULT sq_arrayreverse(HSQUIRRELVM v,SQInteger idx);
SQUIRREL_API SQRESULT sq_arrayremove(HSQUIRRELVM v,SQInteger idx,SQInteger itemidx);
SQUIRREL_API SQRESULT sq_arrayinsert(HSQUIRRELVM v,SQInteger idx,SQInteger destpos);
SQUIRREL_API SQRESULT sq_setdelegate(HSQUIRRELVM v,SQInteger idx);
SQUIRREL_API SQRESULT sq_getdelegate(HSQUIRRELVM v,SQInteger idx);
SQUIRREL_API SQRESULT sq_clone(HSQUIRRELVM v,SQInteger idx);
SQUIRREL_API SQRESULT sq_setfreevariable(HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger nval);
SQUIRREL_API SQRESULT sq_next(HSQUIRRELVM v,SQInteger idx);
SQUIRREL_API SQRESULT sq_getweakrefval(HSQUIRRELVM v,SQInteger idx);
SQUIRREL_API SQRESULT sq_clear(HSQUIRRELVM v,SQInteger idx);
/*calls*/
SQUIRREL_API SQRESULT sq_call(HSQUIRRELVM v,SQInteger params,SQBool retval,SQBool raiseerror);
SQUIRREL_API SQRESULT sq_resume(HSQUIRRELVM v,SQBool retval,SQBool raiseerror);
SQUIRREL_API const SQChar *sq_getlocal(HSQUIRRELVM v,SQUnsignedInteger level,SQUnsignedInteger idx);
SQUIRREL_API SQRESULT sq_getcallee(HSQUIRRELVM v);
SQUIRREL_API const SQChar *sq_getfreevariable(HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger nval);
SQUIRREL_API SQRESULT sq_throwerror(HSQUIRRELVM v,const SQChar *err);
SQUIRREL_API SQRESULT sq_throwobject(HSQUIRRELVM v);
SQUIRREL_API void sq_reseterror(HSQUIRRELVM v);
SQUIRREL_API void sq_getlasterror(HSQUIRRELVM v);
/*raw object handling*/
SQUIRREL_API SQRESULT sq_getstackobj(HSQUIRRELVM v,SQInteger idx,HSQOBJECT *po);
SQUIRREL_API void sq_pushobject(HSQUIRRELVM v,HSQOBJECT obj);
SQUIRREL_API void sq_addref(HSQUIRRELVM v,HSQOBJECT *po);
SQUIRREL_API SQBool sq_release(HSQUIRRELVM v,HSQOBJECT *po);
SQUIRREL_API SQUnsignedInteger sq_getrefcount(HSQUIRRELVM v,HSQOBJECT *po);
SQUIRREL_API void sq_resetobject(HSQOBJECT *po);
SQUIRREL_API const SQChar *sq_objtostring(const HSQOBJECT *o);
SQUIRREL_API SQBool sq_objtobool(const HSQOBJECT *o);
SQUIRREL_API SQInteger sq_objtointeger(const HSQOBJECT *o);
SQUIRREL_API SQFloat sq_objtofloat(const HSQOBJECT *o);
SQUIRREL_API SQUserPointer sq_objtouserpointer(const HSQOBJECT *o);
SQUIRREL_API SQRESULT sq_getobjtypetag(const HSQOBJECT *o,SQUserPointer * typetag);
/*GC*/
SQUIRREL_API SQInteger sq_collectgarbage(HSQUIRRELVM v);
SQUIRREL_API SQRESULT sq_resurrectunreachable(HSQUIRRELVM v);
/*serialization*/
SQUIRREL_API SQRESULT sq_writeclosure(HSQUIRRELVM vm,SQWRITEFUNC writef,SQUserPointer up);
SQUIRREL_API SQRESULT sq_readclosure(HSQUIRRELVM vm,SQREADFUNC readf,SQUserPointer up);
/*mem allocation*/
SQUIRREL_API void *sq_malloc(SQUnsignedInteger size);
SQUIRREL_API void *sq_realloc(void* p,SQUnsignedInteger oldsize,SQUnsignedInteger newsize);
SQUIRREL_API void sq_free(void *p,SQUnsignedInteger size);
/*debug*/
SQUIRREL_API SQRESULT sq_stackinfos(HSQUIRRELVM v,SQInteger level,SQStackInfos *si);
SQUIRREL_API void sq_setdebughook(HSQUIRRELVM v);
SQUIRREL_API void sq_setnativedebughook(HSQUIRRELVM v,SQDEBUGHOOK hook);
/*UTILITY MACRO*/
#define sq_isnumeric(o) ((o)._type&SQOBJECT_NUMERIC)
#define sq_istable(o) ((o)._type==OT_TABLE)
#define sq_isarray(o) ((o)._type==OT_ARRAY)
#define sq_isfunction(o) ((o)._type==OT_FUNCPROTO)
#define sq_isclosure(o) ((o)._type==OT_CLOSURE)
#define sq_isgenerator(o) ((o)._type==OT_GENERATOR)
#define sq_isnativeclosure(o) ((o)._type==OT_NATIVECLOSURE)
#define sq_isstring(o) ((o)._type==OT_STRING)
#define sq_isinteger(o) ((o)._type==OT_INTEGER)
#define sq_isfloat(o) ((o)._type==OT_FLOAT)
#define sq_isuserpointer(o) ((o)._type==OT_USERPOINTER)
#define sq_isuserdata(o) ((o)._type==OT_USERDATA)
#define sq_isthread(o) ((o)._type==OT_THREAD)
#define sq_isnull(o) ((o)._type==OT_NULL)
#define sq_isclass(o) ((o)._type==OT_CLASS)
#define sq_isinstance(o) ((o)._type==OT_INSTANCE)
#define sq_isbool(o) ((o)._type==OT_BOOL)
#define sq_isweakref(o) ((o)._type==OT_WEAKREF)
#define sq_type(o) ((o)._type)
/* deprecated */
#define sq_createslot(v,n) sq_newslot(v,n,SQFalse)
#define SQ_OK (0)
#define SQ_ERROR (-1)
#define SQ_FAILED(res) (res<0)
#define SQ_SUCCEEDED(res) (res>=0)
#ifdef __cplusplus
} /*extern "C"*/
#endif
#endif /*_SQUIRREL_H_*/

View File

@ -0,0 +1,18 @@
SQUIRREL= ..
OUT= $(SQUIRREL)/lib/libsqplus.a
INCDIRS= -I$(SQUIRREL)/include -I. -Iinclude
ALLSRCS = $(wildcard *.cpp)
WIN32SRCS = $(wildcard *Win32*)
SRCS = $(filter-out $(WIN32SRCS),$(ALLSRCS))
sqplus:
# g++ -fno-rtti -c $(SRCS) $(INCDIRS)
g++ -O3 -fno-rtti -Os -c $(SRCS) $(INCDIRS)
ar rc $(OUT) *.o
rm *.o
#g++ -O3 -fno-rtti -Os -c $(SRCS) $(INCDIRS)
#g++ -ggdb -fno-rtti -c $(SRCS) $(INCDIRS)

View File

@ -0,0 +1,382 @@
#include "sqplus.h"
#include <stdio.h>
#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)); // <TODO> 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<INT>::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<unsigned>::TypeID: {
unsigned * val = (unsigned *)data; // Address
if (val) {
*val = sa.GetInt(3);
return sa.Return(static_cast<INT>(*val));
} // if
break;
} // case
case TypeInfo<FLOAT>::TypeID: {
FLOAT * val = (FLOAT *)data; // Address
if (val) {
*val = sa.GetFloat(3);
return sa.Return(*val);
} // if
break;
} // case
case TypeInfo<bool>::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<SQUserPointer>::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<ScriptStringVarBase>::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<std::string>::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<INT>::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<unsigned>::TypeID: {
if (!(vr->m_access & VAR_ACCESS_CONSTANT)) {
unsigned * val = (unsigned *)data; // Address
if (val){
return sa.Return(static_cast<INT>(*val));
}
} else {
unsigned * val = (unsigned *)&data; // Constant value
return sa.Return(static_cast<INT>(*val));
} // if
break;
} // case
case TypeInfo<FLOAT>::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<bool>::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<SQUserPointer>::TypeID:
return sa.Return(data); // The address of member variable, not the variable itself.
case TypeInfo<ScriptStringVarBase>::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<const SQChar *>::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<std::string>::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

View File

@ -0,0 +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 <typename Callee>
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 <typename Callee,typename P1>
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<P1>(),v,index + 0)
);
Push(v,ret);
return 1;
}
template<typename Callee,typename P1,typename P2>
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<P1>(),v,index + 0),
Get(TypeWrapper<P2>(),v,index + 1)
);
Push(v,ret);
return 1;
}
template<typename Callee,typename P1,typename P2,typename P3>
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<P1>(),v,index + 0),
Get(TypeWrapper<P2>(),v,index + 1),
Get(TypeWrapper<P3>(),v,index + 2)
);
Push(v,ret);
return 1;
}
template<typename Callee,typename P1,typename P2,typename P3,typename P4>
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<P1>(),v,index + 0),
Get(TypeWrapper<P2>(),v,index + 1),
Get(TypeWrapper<P3>(),v,index + 2),
Get(TypeWrapper<P4>(),v,index + 3)
);
Push(v,ret);
return 1;
}
template<typename Callee,typename P1,typename P2,typename P3,typename P4,typename P5>
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<P1>(),v,index + 0),
Get(TypeWrapper<P2>(),v,index + 1),
Get(TypeWrapper<P3>(),v,index + 2),
Get(TypeWrapper<P4>(),v,index + 3),
Get(TypeWrapper<P5>(),v,index + 4)
);
Push(v,ret);
return 1;
}
template<typename Callee,typename P1,typename P2,typename P3,typename P4,typename P5,typename P6>
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<P1>(),v,index + 0),
Get(TypeWrapper<P2>(),v,index + 1),
Get(TypeWrapper<P3>(),v,index + 2),
Get(TypeWrapper<P4>(),v,index + 3),
Get(TypeWrapper<P5>(),v,index + 4),
Get(TypeWrapper<P6>(),v,index + 5)
);
Push(v,ret);
return 1;
}
template<typename Callee,typename P1,typename P2,typename P3,typename P4,typename P5,typename P6,typename P7>
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<P1>(),v,index + 0),
Get(TypeWrapper<P2>(),v,index + 1),
Get(TypeWrapper<P3>(),v,index + 2),
Get(TypeWrapper<P4>(),v,index + 3),
Get(TypeWrapper<P5>(),v,index + 4),
Get(TypeWrapper<P6>(),v,index + 5),
Get(TypeWrapper<P7>(),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<typename Callee>
static int Call(Callee & callee,void (CALL_QUAL Callee::*func)() CONST_QUAL, HSQUIRRELVM,int /*index*/) {
(callee.*func)();
return 0;
}
template<typename Callee,typename P1>
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<P1>(),v,index + 0)
);
return 0;
}
template<typename Callee,typename P1,typename P2>
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<P1>(),v,index + 0),
Get(TypeWrapper<P2>(),v,index + 1)
);
return 0;
}
template<typename Callee,typename P1,typename P2,typename P3>
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<P1>(),v,index + 0),
Get(TypeWrapper<P2>(),v,index + 1),
Get(TypeWrapper<P3>(),v,index + 2)
);
return 0;
}
template<typename Callee,typename P1,typename P2,typename P3,typename P4>
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<P1>(),v,index + 0),
Get(TypeWrapper<P2>(),v,index + 1),
Get(TypeWrapper<P3>(),v,index + 2),
Get(TypeWrapper<P4>(),v,index + 3)
);
return 0;
}
template<typename Callee,typename P1,typename P2,typename P3,typename P4,typename P5>
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<P1>(),v,index + 0),
Get(TypeWrapper<P2>(),v,index + 1),
Get(TypeWrapper<P3>(),v,index + 2),
Get(TypeWrapper<P4>(),v,index + 3),
Get(TypeWrapper<P5>(),v,index + 4)
);
return 0;
}
template<typename Callee,typename P1,typename P2,typename P3,typename P4,typename P5,typename P6>
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<P1>(),v,index + 0),
Get(TypeWrapper<P2>(),v,index + 1),
Get(TypeWrapper<P3>(),v,index + 2),
Get(TypeWrapper<P4>(),v,index + 3),
Get(TypeWrapper<P5>(),v,index + 4),
Get(TypeWrapper<P6>(),v,index + 5)
);
return 0;
}
template<typename Callee,typename P1,typename P2,typename P3,typename P4,typename P5,typename P6,typename P7>
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<P1>(),v,index + 0),
Get(TypeWrapper<P2>(),v,index + 1),
Get(TypeWrapper<P3>(),v,index + 2),
Get(TypeWrapper<P4>(),v,index + 3),
Get(TypeWrapper<P5>(),v,index + 4),
Get(TypeWrapper<P6>(),v,index + 5),
Get(TypeWrapper<P7>(),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<typename Callee,typename RT>
int Call(Callee & callee, RT (CALL_QUAL Callee::*func)() CONST_QUAL, HSQUIRRELVM v,int index) {
return ReturnSpecialization<RT>::Call(callee,func,v,index);
}
template<typename Callee,typename RT,typename P1>
int Call(Callee & callee,RT (CALL_QUAL Callee::*func)(P1) CONST_QUAL, HSQUIRRELVM v,int index) {
return ReturnSpecialization<RT>::Call(callee,func,v,index);
}
template<typename Callee,typename RT,typename P1,typename P2>
int Call(Callee & callee,RT (CALL_QUAL Callee::*func)(P1,P2) CONST_QUAL, HSQUIRRELVM v,int index) {
return ReturnSpecialization<RT>::Call(callee,func,v,index);
}
template<typename Callee,typename RT,typename P1,typename P2,typename P3>
int Call(Callee & callee,RT (CALL_QUAL Callee::*func)(P1,P2,P3) CONST_QUAL, HSQUIRRELVM v,int index) {
return ReturnSpecialization<RT>::Call(callee,func,v,index);
}
template<typename Callee,typename RT,typename P1,typename P2,typename P3,typename P4>
int Call(Callee & callee,RT (CALL_QUAL Callee::*func)(P1,P2,P3,P4) CONST_QUAL, HSQUIRRELVM v,int index) {
return ReturnSpecialization<RT>::Call(callee,func,v,index);
}
template<typename Callee,typename RT,typename P1,typename P2,typename P3,typename P4,typename P5>
int Call(Callee & callee,RT (CALL_QUAL Callee::*func)(P1,P2,P3,P4,P5) CONST_QUAL, HSQUIRRELVM v,int index) {
return ReturnSpecialization<RT>::Call(callee,func,v,index);
}
template<typename Callee,typename RT,typename P1,typename P2,typename P3,typename P4,typename P5,typename P6>
int Call(Callee & callee,RT (CALL_QUAL Callee::*func)(P1,P2,P3,P4,P5,P6) CONST_QUAL, HSQUIRRELVM v,int index) {
return ReturnSpecialization<RT>::Call(callee,func,v,index);
}
template<typename Callee,typename RT,typename P1,typename P2,typename P3,typename P4,typename P5,typename P6,typename P7>
int Call(Callee & callee,RT (CALL_QUAL Callee::*func)(P1,P2,P3,P4,P5,P6,P7) CONST_QUAL, HSQUIRRELVM v,int index) {
return ReturnSpecialization<RT>::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

View File

@ -0,0 +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<const TYPE &>,HSQUIRRELVM v,int idx) { return GetInstance<TYPE,false>(v,idx) != NULL; } \
inline const TYPE & Get(TypeWrapper<const TYPE &>,HSQUIRRELVM v,int idx) { return *GetInstance<TYPE,true>(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<const TYPE &>,HSQUIRRELVM v,int idx) { return GetInstance<TYPE,false>(v,idx) != NULL; } \
template<> inline const TYPE & Get(TypeWrapper<const TYPE &>,HSQUIRRELVM v,int idx) { return *GetInstance<TYPE,true>(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<typename VarType>
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<TClassType>::type(),*(VarType **)&cv,name,VarAccessType(access|VAR_ACCESS_STATIC));
return *this;
} // staticVar
#endif
// SqPlusConst.h

View File

@ -0,0 +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<bool>,HSQUIRRELVM v,int idx) { return sq_gettype(v,idx) == OT_BOOL; }
SQINLINE bool Match(TypeWrapper<bool>,HSQUIRRELVM v,int idx) { return true; } // All types can be cast to bool
SQINLINE bool Match(TypeWrapper<char>,HSQUIRRELVM v,int idx) { return sq_gettype(v,idx) == OT_INTEGER; }
SQINLINE bool Match(TypeWrapper<unsigned char>,HSQUIRRELVM v, int idx) { return sq_gettype(v,idx) == OT_INTEGER; }
SQINLINE bool Match(TypeWrapper<short>,HSQUIRRELVM v,int idx) { return sq_gettype(v,idx) == OT_INTEGER; }
SQINLINE bool Match(TypeWrapper<unsigned short>,HSQUIRRELVM v,int idx) { return sq_gettype(v,idx) == OT_INTEGER; }
SQINLINE bool Match(TypeWrapper<int>,HSQUIRRELVM v,int idx) { return sq_gettype(v,idx) == OT_INTEGER; }
SQINLINE bool Match(TypeWrapper<unsigned int>,HSQUIRRELVM v,int idx) { return sq_gettype(v,idx) == OT_INTEGER; }
SQINLINE bool Match(TypeWrapper<long>,HSQUIRRELVM v,int idx) { return sq_gettype(v,idx) == OT_INTEGER; }
SQINLINE bool Match(TypeWrapper<unsigned long>,HSQUIRRELVM v,int idx) { return sq_gettype(v,idx) == OT_INTEGER; }
SQINLINE bool Match(TypeWrapper<float>,HSQUIRRELVM v,int idx) { int type = sq_gettype(v,idx); return type == OT_FLOAT; }
SQINLINE bool Match(TypeWrapper<double>,HSQUIRRELVM v,int idx) { int type = sq_gettype(v,idx); return type == OT_FLOAT; }
SQINLINE bool Match(TypeWrapper<const SQChar *>,HSQUIRRELVM v,int idx) { return sq_gettype(v,idx) == OT_STRING; }
SQINLINE bool Match(TypeWrapper<SQChar *>,HSQUIRRELVM v,int idx) { return sq_gettype(v,idx) == OT_STRING; }
SQINLINE bool Match(TypeWrapper<HSQUIRRELVM>,HSQUIRRELVM v,int idx) { return true; } // See Get() for HSQUIRRELVM below (v is always present).
SQINLINE bool Match(TypeWrapper<void*>,HSQUIRRELVM v,int idx) { return sq_gettype(v,idx) == OT_USERPOINTER; }
SQINLINE bool Match(TypeWrapper<SquirrelObject>,HSQUIRRELVM v,int idx) { return true; } // See sq_getstackobj(): always returns true.
SQINLINE void Get(TypeWrapper<void>,HSQUIRRELVM v,int) {}
//SQINLINE bool Get(TypeWrapper<bool>,HSQUIRRELVM v,int idx) { SQBool b; SQPLUS_CHECK_GET(sq_getbool(v,idx,&b)); return b != 0; }
SQINLINE char Get(TypeWrapper<char>,HSQUIRRELVM v,int idx) { INT i; SQPLUS_CHECK_GET(sq_getinteger(v,idx,&i)); return static_cast<char>(i); }
SQINLINE unsigned char Get(TypeWrapper<unsigned char>,HSQUIRRELVM v,int idx) { INT i; SQPLUS_CHECK_GET(sq_getinteger(v,idx,&i)); return static_cast<unsigned char>(i); }
SQINLINE short Get(TypeWrapper<short>,HSQUIRRELVM v,int idx) { INT i; SQPLUS_CHECK_GET(sq_getinteger(v,idx,&i)); return static_cast<short>(i); }
SQINLINE unsigned short Get(TypeWrapper<unsigned short>,HSQUIRRELVM v,int idx) { INT i; SQPLUS_CHECK_GET(sq_getinteger(v,idx,&i)); return static_cast<unsigned short>(i); }
SQINLINE int Get(TypeWrapper<int>,HSQUIRRELVM v,int idx) { INT i; SQPLUS_CHECK_GET(sq_getinteger(v,idx,&i)); return i; }
SQINLINE unsigned int Get(TypeWrapper<unsigned int>,HSQUIRRELVM v,int idx) { INT i; SQPLUS_CHECK_GET(sq_getinteger(v,idx,&i)); return static_cast<unsigned int>(i); }
SQINLINE long Get(TypeWrapper<long>,HSQUIRRELVM v,int idx) { INT i; SQPLUS_CHECK_GET(sq_getinteger(v,idx,&i)); return static_cast<long>(i); }
SQINLINE unsigned long Get(TypeWrapper<unsigned long>,HSQUIRRELVM v,int idx) { INT i; SQPLUS_CHECK_GET(sq_getinteger(v,idx,&i)); return static_cast<unsigned long>(i); }
SQINLINE float Get(TypeWrapper<float>,HSQUIRRELVM v,int idx) { FLOAT f; SQPLUS_CHECK_GET(sq_getfloat(v,idx,&f)); return f; }
SQINLINE double Get(TypeWrapper<double>,HSQUIRRELVM v,int idx) { FLOAT f; SQPLUS_CHECK_GET(sq_getfloat(v,idx,&f)); return static_cast<double>(f); }
SQINLINE const SQChar * Get(TypeWrapper<const SQChar *>,HSQUIRRELVM v,int idx) { const SQChar * s; SQPLUS_CHECK_GET(sq_getstring(v,idx,&s)); return s; }
SQINLINE SquirrelNull Get(TypeWrapper<SquirrelNull>,HSQUIRRELVM v,int idx) { (void)v, (void)idx; return SquirrelNull(); }
SQINLINE void * Get(TypeWrapper<void *>,HSQUIRRELVM v,int idx) { SQUserPointer p; SQPLUS_CHECK_GET(sq_getuserpointer(v,idx,&p)); return p; }
SQINLINE HSQUIRRELVM Get(TypeWrapper<HSQUIRRELVM>,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<SquirrelObject>,HSQUIRRELVM v,int idx) { HSQOBJECT o; SQPLUS_CHECK_GET(sq_getstackobj(v,idx,&o)); return SquirrelObject(o); }
SQINLINE bool Get(TypeWrapper<bool>,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<const SQOtherChar *>,HSQUIRRELVM v,int idx) { return sq_gettype(v,idx) == OT_STRING; }
SQINLINE bool Match(TypeWrapper<SQOtherChar *>,HSQUIRRELVM v,int idx) { return sq_gettype(v,idx) == OT_STRING; }
/*SQINLINE SQOtherChar* Get(TypeWrapper<const SQOtherChar *>,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<const SQOtherChar *>,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<const std::string&>, HSQUIRRELVM v, int idx) { return sq_gettype(v,idx) == OT_STRING; }
SQINLINE std::string Get(TypeWrapper<const std::string&>,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<SQChar> sq_std_string;
SQINLINE void Push(HSQUIRRELVM v,const sq_std_string & value) { sq_pushstring(v,value.c_str(),-1); }
SQINLINE bool Match(TypeWrapper<const sq_std_string &>, HSQUIRRELVM v, int idx) { return sq_gettype(v,idx) == OT_STRING; }
SQINLINE sq_std_string Get(TypeWrapper<const sq_std_string &>,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<void>,HSQUIRRELVM v,int idx) { sq_pop(v,2); }
#endif // _SQPLUS_FUNCTION_CALL_IMPL_H_

View File

@ -0,0 +1,61 @@
#include "sqplus.h"
#include "SqPlusOCharBuf.h"
#include <wchar.h>
// 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

View File

@ -0,0 +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<class SQT, class SQOT, bool use_latin1>
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)<sizeof(SQOT) ){
// Converting wchar_t => 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<SQT,SQOT,use_latin1>& operator = (const SQT *ps){
Release();
Init( ps, false );
return *this;
}
SQCharBufImpl<SQT,SQOT,use_latin1>& operator = (const SQOT *ps){
Release();
Init( ps );
return *this;
}
// Move string from other here - Note: Empties the input argument (other)
SQCharBufImpl<SQT,SQOT,use_latin1>& operator = (const SQCharBufImpl<SQT,SQOT,use_latin1>& 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<SQOtherChar, SQChar, bool(SQPLUS_USE_LATIN1)> SQOthCharBuf;
typedef SQCharBufImpl<SQChar, SQOtherChar, bool(SQPLUS_USE_LATIN1)> SQDefCharBuf;
typedef SQCharBufImpl<wchar_t, char, bool(SQPLUS_USE_LATIN1)> SQWCharBuf;
typedef SQCharBufImpl<char, wchar_t, bool(SQPLUS_USE_LATIN1)> 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

View File

@ -0,0 +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<T> now
static inline int destruct(SQUserPointer up, SQInteger size) {
if (up) {
static_cast<T*>(up)->~T();
sq_free(up, size);
}
return 0;
}
static inline SQRELEASEHOOK &release(void) {
static SQRELEASEHOOK hook = ClassType<T>::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<typename Func> struct Arg;
#endif // SQPLUS_OVERLOAD_DECLARATION
#ifdef SQPLUS_OVERLOAD_IMPLEMENTATION
#undef SQPLUS_OVERLOAD_IMPLEMENTATION
private:
class SQFuncHolder {
private:
template<typename T>
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<T*>(up)) T;
array.SetUserPointer(index, up);
}
return *static_cast<T*>(up);
}
};
/*
storage of wrapped C++ functions
*/
typedef SQInteger(*WrappedFunction)(HSQUIRRELVM, bool, int);
typedef FlexArray<WrappedFunction> SQWrappedFuncArray;
typedef FlexArray<SQWrappedFuncArray> SQWrappedFuncArray2 ;
typedef FlexArray<SQWrappedFuncArray2> 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<typename Mfunc> struct MemberDispatcher {
static inline FlexArray<Mfunc> &mfunc(void) {
static FlexArray<Mfunc> mfunc;
return mfunc;
}
static inline SQInteger
dispatch(HSQUIRRELVM v, bool execute, int functionIndex) {
return execute ?
Call(*GetInstance<TClassType, true>(v, 1),
mfunc().get(functionIndex), v, 2) :
Arg<Mfunc>::argTypeDistance(v);
}
};
template<typename Sfunc> struct StaticDispatcher {
static inline FlexArray<Sfunc> &sfunc(void) {
static FlexArray<Sfunc> sfunc;
return sfunc;
}
static inline SQInteger
dispatch(HSQUIRRELVM v, bool execute, int functionIndex) {
return execute ?
Call(sfunc().get(functionIndex), v, 2) :
Arg<Sfunc>::argTypeDistance(v);
}
};
template<typename Cfunc> 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<Cfunc>::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<typename Mfunc> static inline void
addMemberFunc(int functionIndex, Mfunc mfunc) {
MemberHolder::funcs(functionIndex, Arg<Mfunc>::num()).push_back(
&MemberDispatcher<Mfunc>::dispatch
);
MemberDispatcher<Mfunc>::mfunc().set(functionIndex, mfunc);
}
template<typename Sfunc> static inline void
addStaticFunc(int functionIndex, Sfunc sfunc) {
StaticHolder::funcs(functionIndex, Arg<Sfunc>::num()).push_back(
&StaticDispatcher<Sfunc>::dispatch
);
StaticDispatcher<Sfunc>::sfunc().set(functionIndex, sfunc);
}
template<typename Cfunc> static inline void
addConstructor(Cfunc cfunc) {
ConstructorHolder::funcs(Arg<Cfunc>::num()).push_back(
&Constructor<Cfunc>::construct
);
Constructor<Cfunc>::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<int N>
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<typename Func>
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<TClassType,TClassBase> *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<TClassType,TClassBase> *def,
Func ofunc,
const SQChar *name) {
if (Arg<Func>::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<TClassType,TClassBase> *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<typename Cfunc>
static inline void addConstructor(SQClassDefBase<TClassType,TClassBase> *def,
Cfunc cfunc) {
SQFuncHolder::addConstructor(cfunc);
def->staticFuncVarArgs(constructorSwitcher, _SC("constructor"));
}
static inline void addGlobalFunc(SQClassDefBase<TClassType,TClassBase> *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<typename Mfunc>
SQClassDefBase<TClassType,TClassBase> &overloadFunc(Mfunc mfunc, const SQChar *n) {
SQOverloader<Mfunc>::addMemberFunc(this, mfunc, n);
return *this;
}
template<typename Ofunc>
SQClassDefBase<TClassType,TClassBase> &overloadOperator(Ofunc ofunc, const SQChar *n){
SQOverloader<Ofunc>::addOperatorFunc(this, ofunc, n);
return *this;
}
template<typename Sfunc>
SQClassDefBase<TClassType,TClassBase> &overloadStaticFunc(Sfunc sfunc,
const SQChar *n) {
SQOverloader<Sfunc>::addStaticFunc(this, sfunc, n);
return *this;
}
template<typename Cmetafunc>
SQClassDefBase<TClassType,TClassBase> &overloadConstructor(void) {
SQOverloader<Cmetafunc>::addConstructor(this, &Arg<Cmetafunc>::create);
return *this;
}
template<typename Cfunc>
SQClassDefBase<TClassType,TClassBase> &overloadConstructor(Cfunc cfunc) {
SQOverloader<Cfunc>::addConstructor(this, cfunc);
return *this;
}
template<typename Gfunc>
SQClassDefBase<TClassType,TClassBase> &overloadGlobalFunc(Gfunc gfunc,
const SQChar *n) {
SQOverloader<Gfunc>::addGlobalFunc(this, gfunc, n);
return *this;
}
#endif // SQPLUS_OVERLOAD_IMPLEMENTATION
#ifdef SQPLUS_OVERLOAD_FUNCTIONS
#undef SQPLUS_OVERLOAD_FUNCTIONS
struct GlobalFuncOverloader {};
static inline SQClassDefBase<GlobalFuncOverloader,SQNoBaseClass> &globalFuncOverloader(void)
{
static SQClassDefBase<GlobalFuncOverloader,SQNoBaseClass> fo(_SC("GlobalFuncOverloader"));
return fo;
}
template<typename Gfunc> void
OverloadGlobal(Gfunc gfunc, const SQChar *n)
{
globalFuncOverloader().overloadGlobalFunc(gfunc, n);
}
template<typename TYPE> struct CheckInstance {
template<typename T> struct unref {typedef T type;};
template<typename T> struct unref<T&> {typedef T type;};
template<typename T> struct unref<T*> {typedef T type;};
template<typename T> struct unref<const T&> {typedef T type;};
template<typename T> struct unref<const T*> {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<TYPE>(), v, index)) {
d = 0;
// Check instance type hierarchy
if (sq_type(o) == OT_INSTANCE) {
SQUserPointer dsttype =
ClassType<typename unref<TYPE>::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<typename T, typename R>
struct Arg<R(T::*)(void)> {
static inline int num(void) {return 0;}
static inline int argTypeDistance(HSQUIRRELVM) {
return 0;
}
};
template<typename T, typename R, typename A1>
struct Arg<R(T::*)(A1)> {
static inline int num(void) {return 1;}
static inline int argTypeDistance(HSQUIRRELVM v) {
return Arg<R(*)(A1)>::argTypeDistance(v);
}
};
template<typename T, typename R, typename A1, typename A2>
struct Arg<R(T::*)(A1, A2)> {
static inline int num(void) {return 2;}
static inline int argTypeDistance(HSQUIRRELVM v) {
return Arg<R(*)(A1, A2)>::argTypeDistance(v);
}
};
template<typename T, typename R, typename A1, typename A2, typename A3>
struct Arg<R(T::*)(A1, A2, A3)> {
static inline int num(void) {return 3;}
static inline int argTypeDistance(HSQUIRRELVM v) {
return Arg<R(*)(A1, A2, A3)>::argTypeDistance(v);
}
};
template<typename T, typename R, typename A1, typename A2, typename A3, typename A4>
struct Arg<R(T::*)(A1, A2, A3, A4)> {
static inline int num(void) {return 4;}
static inline int argTypeDistance(HSQUIRRELVM v) {
return Arg<R(*)(A1, A2, A3, A4)>::argTypeDistance(v);
}
};
template<typename T, typename R, typename A1, typename A2, typename A3, typename A4, typename A5>
struct Arg<R(T::*)(A1, A2, A3, A4, A5)> {
static inline int num(void) {return 5;}
static inline int argTypeDistance(HSQUIRRELVM v) {
return Arg<R(*)(A1, A2, A3, A4, A5)>::argTypeDistance(v);
}
};
template<typename T, typename R, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6>
struct Arg<R(T::*)(A1, A2, A3, A4, A5, A6)> {
static inline int num(void) {return 6;}
static inline int argTypeDistance(HSQUIRRELVM v) {
return Arg<R(*)(A1, A2, A3, A4, A5, A6)>::argTypeDistance(v);
}
};
template<typename T, typename R, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7>
struct Arg<R(T::*)(A1, A2, A3, A4, A5, A6, A7)> {
static inline int num(void) {return 7;}
static inline int argTypeDistance(HSQUIRRELVM v) {
return Arg<R(*)(A1, A2, A3, A4, A5, A6, A7)>::argTypeDistance(v);
}
};
#ifdef SQPLUS_CONST_OPT
template<typename T, typename R>
struct Arg<R(T::*)(void) const> {
static inline int num(void) {return 0;}
static inline int argTypeDistance(HSQUIRRELVM) {
return 0;
}
};
template<typename T, typename R, typename A1>
struct Arg<R(T::*)(A1) const> {
static inline int num(void) {return 1;}
static inline int argTypeDistance(HSQUIRRELVM v) {
return Arg<R(*)(A1)>::argTypeDistance(v);
}
};
template<typename T, typename R, typename A1, typename A2>
struct Arg<R(T::*)(A1, A2) const> {
static inline int num(void) {return 2;}
static inline int argTypeDistance(HSQUIRRELVM v) {
return Arg<R(*)(A1, A2)>::argTypeDistance(v);
}
};
template<typename T, typename R, typename A1, typename A2, typename A3>
struct Arg<R(T::*)(A1, A2, A3) const> {
static inline int num(void) {return 3;}
static inline int argTypeDistance(HSQUIRRELVM v) {
return Arg<R(*)(A1, A2, A3)>::argTypeDistance(v);
}
};
template<typename T, typename R, typename A1, typename A2, typename A3, typename A4>
struct Arg<R(T::*)(A1, A2, A3, A4) const> {
static inline int num(void) {return 4;}
static inline int argTypeDistance(HSQUIRRELVM v) {
return Arg<R(*)(A1, A2, A3, A4)>::argTypeDistance(v);
}
};
template<typename T, typename R, typename A1, typename A2, typename A3, typename A4, typename A5>
struct Arg<R(T::*)(A1, A2, A3, A4, A5) const> {
static inline int num(void) {return 5;}
static inline int argTypeDistance(HSQUIRRELVM v) {
return Arg<R(*)(A1, A2, A3, A4, A5)>::argTypeDistance(v);
}
};
template<typename T, typename R, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6>
struct Arg<R(T::*)(A1, A2, A3, A4, A5, A6) const> {
static inline int num(void) {return 6;}
static inline int argTypeDistance(HSQUIRRELVM v) {
return Arg<R(*)(A1, A2, A3, A4, A5, A6)>::argTypeDistance(v);
}
};
template<typename T, typename R, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7>
struct Arg<R(T::*)(A1, A2, A3, A4, A5, A6, A7) const> {
static inline int num(void) {return 7;}
static inline int argTypeDistance(HSQUIRRELVM v) {
return Arg<R(*)(A1, A2, A3, A4, A5, A6, A7)>::argTypeDistance(v);
}
};
#endif
static inline int classAllocationError(HSQUIRRELVM v) {
return sq_throwerror(v, _SC("Failed to allocate memory"));
}
template<typename R>
struct Arg<R(*)(void)> {
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<R*>(sq_malloc(sizeof(R)));
return r ?
PostConstruct<R>(v, new(r) R,
ClassType<R>::getReleaseHook()) :
classAllocationError(v);
}
};
template<typename R, typename A1>
struct Arg<R(*)(A1)> {
static inline int num(void) {return 1;}
static inline int argTypeDistance(HSQUIRRELVM v) {
int s, r;
r = 0;
s = CheckInstance<A1>::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<R*>(sq_malloc(sizeof(R)));
return r ?
PostConstruct<R>(v, new(r) R(a1),
ClassType<R>::getReleaseHook()) :
classAllocationError(v);
}
};
template<typename R, typename A1, typename A2>
struct Arg<R(*)(A1, A2)> {
static inline int num(void) {return 2;}
static inline int argTypeDistance(HSQUIRRELVM v) {
int s, r;
r = 0;
s = CheckInstance<A1>::distance(v, 2); if (s < 0) {return -1;} r += s;
s = CheckInstance<A2>::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<R*>(sq_malloc(sizeof(R)));
return r ?
PostConstruct<R>(v, new(r) R(a1, a2),
ClassType<R>::getReleaseHook()) :
classAllocationError(v);
}
};
template<typename R, typename A1, typename A2, typename A3>
struct Arg<R(*)(A1, A2, A3)> {
static inline int num(void) {return 3;}
static inline int argTypeDistance(HSQUIRRELVM v) {
int s, r;
r = 0;
s = CheckInstance<A1>::distance(v, 2); if (s < 0) {return -1;} r += s;
s = CheckInstance<A2>::distance(v, 3); if (s < 0) {return -1;} r += s;
s = CheckInstance<A3>::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<R*>(sq_malloc(sizeof(R)));
return r ?
PostConstruct<R>(v, new(r) R(a1, a2, a3),
ClassType<R>::getReleaseHook()) :
classAllocationError(v);
}
};
template<typename R, typename A1, typename A2, typename A3, typename A4>
struct Arg<R(*)(A1, A2, A3, A4)> {
static inline int num(void) {return 4;}
static inline int argTypeDistance(HSQUIRRELVM v) {
int s, r;
r = 0;
s = CheckInstance<A1>::distance(v, 2); if (s < 0) {return -1;} r += s;
s = CheckInstance<A2>::distance(v, 3); if (s < 0) {return -1;} r += s;
s = CheckInstance<A3>::distance(v, 4); if (s < 0) {return -1;} r += s;
s = CheckInstance<A4>::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<R*>(sq_malloc(sizeof(R)));
return r ?
PostConstruct<R>(v, new(r) R(a1, a2, a3, a4),
ClassType<R>::getReleaseHook()) :
classAllocationError(v);
}
};
template<typename R, typename A1, typename A2, typename A3, typename A4, typename A5>
struct Arg<R(*)(A1, A2, A3, A4, A5)> {
static inline int num(void) {return 5;}
static inline int argTypeDistance(HSQUIRRELVM v) {
int s, r;
r = 0;
s = CheckInstance<A1>::distance(v, 2); if (s < 0) {return -1;} r += s;
s = CheckInstance<A2>::distance(v, 3); if (s < 0) {return -1;} r += s;
s = CheckInstance<A3>::distance(v, 4); if (s < 0) {return -1;} r += s;
s = CheckInstance<A4>::distance(v, 5); if (s < 0) {return -1;} r += s;
s = CheckInstance<A5>::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<R*>(sq_malloc(sizeof(R)));
return r ?
PostConstruct<R>(v, new(r) R(a1, a2, a3, a4, a5),
ClassType<R>::getReleaseHook()) :
classAllocationError(v);
}
};
template<typename R, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6>
struct Arg<R(*)(A1, A2, A3, A4, A5, A6)> {
static inline int num(void) {return 6;}
static inline int argTypeDistance(HSQUIRRELVM v) {
int s, r;
r = 0;
s = CheckInstance<A1>::distance(v, 2); if (s < 0) {return -1;} r += s;
s = CheckInstance<A2>::distance(v, 3); if (s < 0) {return -1;} r += s;
s = CheckInstance<A3>::distance(v, 4); if (s < 0) {return -1;} r += s;
s = CheckInstance<A4>::distance(v, 5); if (s < 0) {return -1;} r += s;
s = CheckInstance<A5>::distance(v, 6); if (s < 0) {return -1;} r += s;
s = CheckInstance<A6>::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<R*>(sq_malloc(sizeof(R)));
return r ?
PostConstruct<R>(v, new(r) R(a1, a2, a3, a4, a5, a6),
ClassType<R>::getReleaseHook()) :
classAllocationError(v);
}
};
template<typename R, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7>
struct Arg<R(*)(A1, A2, A3, A4, A5, A6, A7)> {
static inline int num(void) {return 7;}
static inline int argTypeDistance(HSQUIRRELVM v) {
int s, r;
r = 0;
s = CheckInstance<A1>::distance(v, 2); if (s < 0) {return -1;} r += s;
s = CheckInstance<A2>::distance(v, 3); if (s < 0) {return -1;} r += s;
s = CheckInstance<A3>::distance(v, 4); if (s < 0) {return -1;} r += s;
s = CheckInstance<A4>::distance(v, 5); if (s < 0) {return -1;} r += s;
s = CheckInstance<A5>::distance(v, 6); if (s < 0) {return -1;} r += s;
s = CheckInstance<A6>::distance(v, 7); if (s < 0) {return -1;} r += s;
s = CheckInstance<A7>::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<R*>(sq_malloc(sizeof(R)));
return r ?
PostConstruct<R>(v, new(r) R(a1, a2, a3, a4, a5, a6, a7),
ClassType<R>::getReleaseHook()) :
classAllocationError(v);
}
};
#endif // SQPLUS_OVERLOAD_FUNCTIONS
// SqPlusOverload.h
// Local Variables:
// mode: c++
// End:

View File

@ -0,0 +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<SQChar> 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 <string>
#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

View File

@ -0,0 +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<typename T>
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<void*>(var);
*pvr = VarRef(offsetOrAddrOrConst,
TypeInfo<T>(),
classType,
ClassType<T>::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<typename Callee,typename Pointee,typename Func>
class DirectCallSmartInstanceMemberFunction {
public:
static inline int Dispatch(HSQUIRRELVM v) {
DirectCallInstanceFuncPicker<Callee, Func> p(v);
if (!p.instance || !p.func) {
sq_throwerror(v, _SC("Invalid Instance Type"));
}
Pointee *pointeeInstance = static_cast<Pointee*>(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<typename Callee,typename Pointee,typename Func>
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<Callee,Pointee,Func>::Dispatch,nupvalues+1);
} // sq_pushdirectinstanceclosure
#endif // #ifdef SQPLUS_SMARTPOINTER_DIRECT_CLOSURE
#ifdef SQPLUS_SMARTPOINTER_REGISTER_INSTANCE
#undef SQPLUS_SMARTPOINTER_REGISTER_INSTANCE
template<typename Callee, typename Pointee, typename Func>
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<typename Pointee, typename Func>
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<typename Pointee, typename VarType>
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<TClassType>::type(),*(VarType **)&cv,name,access);
return *this;
} // var
// Register a member variable as a UserPointer (read only).
template<typename Pointee, typename VarType>
SQClassDefBase & smartVarAsUserPointer(VarType Pointee::* pvar,const SQChar * name) {
struct CV {
VarType Pointee::* var;
} cv; // Cast Variable helper.
cv.var = pvar;
RegisterSmartInstanceVariable(newClass,ClassType<TClassType>::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<char*>(
getSmartPointerPointee(reinterpret_cast<unsigned char*>(up))
);
}
#endif // #ifdef SQPLUS_SMARTPOINTER_CPP_DECLARATION
// SqPlusSmartPointer.h

View File

@ -0,0 +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<class T>
struct sqTypeMask { };
// Return type not included in type mask, delegate to void case
// Base case, no arguments
template<typename RT>
struct sqTypeMask<RT(*)()> {
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<typename RT PTNC_##N> \
struct sqTypeMask<RT(*)(P_##N)> { \
static const SQChar *Get(){ \
static SQChar buf[10]; \
return strappchar(buf, (SQChar*)sqTypeMask<RT(*)(P_##M)>::Get(), \
(SQChar)TypeInfo<P##N>::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<typename Callee, typename RT PTNC_##N> \
struct sqTypeMask<RT(Callee::*)(P_##N) QUAL> { \
static const SQChar *Get(){ \
SQChar *buf = (SQChar*)sqTypeMask<RT(*)(P_##N)>::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<typename Callee, typename RT PTNC_##N> \
struct sqTypeMask<RT(__cdecl Callee::*)(P_##N) QUAL> { \
static const SQChar *Get(){ \
SQChar *buf = (SQChar*)sqTypeMask<RT(*)(P_##N)>::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

View File

@ -0,0 +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

View File

@ -0,0 +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

View File

@ -0,0 +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<SQUserPointer>(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

View File

@ -0,0 +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

View File

@ -0,0 +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);
}

View File

@ -0,0 +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 <windows.h>
#endif
#ifndef __IUnknown_INTERFACE_DEFINED__
#include <unknwn.h>
#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

View File

@ -0,0 +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 <assert.h>
#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()
{
//<<FIXME>>
return _o._unVal.nInteger?true:false;
}
void SquirrelObject::EndIteration()
{
sq_pop(SquirrelVM::_VM,2);
}

View File

@ -0,0 +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 <typename _ty>
SquirrelObject(const _ty & val) { sq_resetobject(&_o); Set((_ty &)val); } // Cast away const to avoid compiler SqPlus::Push() match issue.
template <typename _ty>
SquirrelObject(_ty & val) { sq_resetobject(&_o); Set(val); }
template <typename _ty>
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<typename T>
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<typename _ty>
_ty Get(void);
// Set any bound type to this SquirrelObject. Note that Squirrel's handling of references and pointers still holds here.
template<typename _ty>
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<typename _ty>
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_

View File

@ -0,0 +1,505 @@
#include <stdio.h>
#include <stdarg.h>
#include <assert.h>
#define _DEBUG_DUMP
#include "sqplus.h"
#include <sqstdio.h>
#include <sqstdmath.h>
#include <sqstdstring.h>
#include <sqstdaux.h>
#include <sqstdblob.h>
#include <sqstdsystem.h>
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 { // <TODO> 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

View File

@ -0,0 +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<typename T>
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_

View File

@ -0,0 +1,359 @@
2008-07-13 "SQUIRREL2_1_1_sqplus_snapshot_20080713"
* Released as a snapshot
2008-07-06 kawachi
* Removed testSqPlus2
2008-06-26 arst@users.sf.net
* SquirrelVM.cpp / SqPlusSetup.h
- Added a new define SQPLUS_SQUIRRELVM_WITH_SYSTEMLIB
(Juggernaut, http://squirrel-lang.org/forums/2585/ShowThread.aspx#2585)
- Added a new function:
SQClassDefBase::scriptVar(const SQChar* name, int ival,
SQBool static_var=SQFalse)
It allows for creating either static or ordinary Squirrel class
members from C++ source code. Versions for int/double/const
SQChar*.
- SquirrelObject::GetBase() - retrieve base class.
(Juggernaut, http://squirrel-lang.org/forums/2585/ShowThread.aspx#2585)
2008-06-14 Kazei
* Fixed memory leak in overloadConstructor
(http://squirrel-lang.org/forums/thread/2516.aspx)
2008-05-10 Neimod
* Fixed for typesafe scripting
(http://squirrel-lang.org/forums/thread/2478.aspx)
2008-05-08 arst@users.sf.net
* sqplus.h/.cpp
- SQ_USE_CLASS_INHERITANCE_SIMPLE is a new way of handling class
inheritence in SqPlus, relying on a template scheme (see ClassTypeBase
and ClassType<T>). It doesn't use any memory per instance and should
be a bit faster than previous scheme. SqClassDef has been given
a second template argument to account for this:
struct SQClassDef<MyClass, TheBaseClass> ...
- The name of the class (in SqClassDef) can be filled in by SqPlus now,
if Squirrel class name is same as C++ class name:
SQClasDef<Troll, Creature>("Troll", "Creature").func(...) =>
SQClasDef<Troll, Creature>().func(...)
- Code to handle class types (names, copy funcs, ID tag, ...) has been
collected in ClassTypeBase and ClassType<T>.
- A new macro to specify that classes should not be copied with default
C++ method: DECLARE_NONCOPY_TYPE(ClassThatCannotBeCopied).
- Reworked body of repetetive template functions, Moved to
SqPlusCallTemplates.h. Can be included with different qualifiers
(const, cdecl).
- Support for cdecl member functions (MSVC specific) through:
SQPLUS_ENABLE_CDECL_MEMBER_FUNCTIONS
cdecl functions are compatible across compilers, while thiscall
is not.
- Generic Push/Pop/Match handlers: SQPLUS_USE_GENERIC_HANDLERS
By default, Push/Get/Match handlers are for a single type. This
adds a fallback level, so that `hierarchy wide' handlers can
be used (define for base class and let all derived classes use
just that).
- For functions that return a pointer to a temporarary (such as
returning a SQDefCharBuf, a template mapper class:
Temporary<T>::type
was added. It can hold a temporary value while finishing a
SquirrelFunction call (before returning to C++).
- Suppressing horrible warnings from Visual C++ about sprintf and related
functions (_CRT_SECURE_NO_DEPRECATE).
* SquirrelVM.h/.cpp
- Changed SquirrelVM and SquirrelVMSys to make them hold a reference
on a SQVM so that ownership can be shared in a defined way.
- SquirrelVMSys can be used as before to swap the `active' VM.
Now it holds a ref to a VM so that a VM is closed automatically
when switched out and there are no refs to any longer. (To hold a
VM ref in the application, simply use an instance of SquirrelVMSys).
- NOTE: A VM created through sq_open() comes out with a reference
count of 1. A VM created with sq_newthread() arrives with a ref
count of 0. SquirrelVM will compensate for this.
- Possibility to store a `sandbox VM'. This VM is not allowed to
access functions / classes bound with SqPlus and so can run more
untrusted scripts.
- Hopefully these changes will not break current apps. (Note: creating
and keeping correct refs on SQVM involved some difficulties (with ref-
counting and garbage collected Squirrel). The scheme provided here is
(I hope) a working solution.)
* SquirrelObject.h/.cpp
- Added: operator = (HSQOBJECT)
- From forum: (http://squirrel-lang.org/forums/thread/2506.aspx)
(suggested by auron0)
- Added: operator == (const SquirrelObject& o)
- Added: CompareUserPointer(const SquirrelObject& o)
* SqPlusUTF8.h / .cpp
- New files for converting strings in arguments (UTF8 <-> wchar_t)
- Fix for conversion of UTF8 sequence of length 3+ bytes
2008-02-17 PallavNawani
* BindVariable of std::string
(http://squirrel-lang.org/forums/2370/ShowThread.aspx)
2007-10-14 "SQUIRREL2_1_1_sqplus_snapshot_20071014"
* Fixed const member function overloading by Tegan
(http://squirrel-lang.org/forums/thread/2160.aspx)
* Updates for missing inline in DECLARE_INSTANCE_TYPE_NAME
(http://squirrel-lang.org/forums/thread/2156.aspx)
* Fixed resolution in function overloading
(http://squirrel-lang.org/forums/thread/2179.aspx)
* Added support for operator overloading suggested by Tegan
(http://squirrel-lang.org/forums/thread/2160.aspx)
2007-09-27 "SQUIRREL2_1_1_sqplus_snapshot_20070927"
* Added ats's extensions :
http://squirrel-lang.org/forums/1/2153/ShowThread.aspx
- GCC_INLINE_WORKAROUND (problems with inline functions with gcc)
- Set/get for short/char members
- Get for const SQChar*
- DECLARE_ENUM_TYPE - Allows enums to be used as arguments
- Support for more customized Push handlers
- SQPLUS_DISABLE_COPY_INSTANCES (disabling automatic use of copy
constructors)
- Support for automatically generate TypeMasks (a template
solution) on function registration
2007-08-25 "SQUIRREL2_1_1_sqplus_snapshot_20070825"
* Added m0pey's smart pointer support :
http://squirrel-lang.org/forums/thread/1982.aspx
2007-01-07 "SQUIRREL2_1_1_sqplus_snapshot_20070701"
* Fixed `returning a pointer of a derived class' problem with gcc
(http://squirrel-lang.org/forums/thread/1875.aspx) based on
http://wiki.squirrel-lang.org/default.aspx/SquirrelWiki/SqPlusNativeCreatedInstancesWithCorrectAncestry.html
2007-06/02 "SQUIRREL2_1_1_sqplus_snapshot_20070602"
* Fix by Sebastien Frippiat:
http://squirrel-lang.org/forums/thread/507.aspx
2007-05-27 "SQUIRREL2_1_1_sqplus_snapshot_20070527"
* Added sqplus/SqPlusOverload.h for function overloading. See
testSqPlus2unit/test_FunctionOverloading.cpp.
2007-03-04 "SQUIRREL2_1_1_sqplus_snapshot_20070304"
* Fixed compilation problem on g++-3.4.4 (cygwin):
http://squirrel-lang.org/forums/thread/1753.aspx
2007-02-25 "SQUIRREL2_1_1_sqplus_snapshot_20070225"
* Fix by Kamaitati: http://squirrel-lang.org/forums/thread/1748.aspx
* Modified sqplu.h (SquirrelObject::Set<>()) for gcc
* Added testSqPlus2unit directory for unit testing
2006-10-09- "SQUIRREL2_1_1_sqplus_25"
* Fixed SqPlusConst.h:
http://squirrel-lang.org/forums/thread/1314.aspx, changed
SquirrelObject Get/Set to default to pass-by-reference, where
pass-by-copy requires extra parameter
2006-10-08 "SQUIRREL2_1_1_sqplus_24"
* Added SQClassDefNoConstructor<>:
http://wiki.squirrel-lang.org/default.aspx/SquirrelWiki/SqPlusWithoutAutoDefaultConstructor.html
(allows binding abstract base classes/pure-virtual-interfaces)
* Added "Squirrel Set/Get objects"
http://wiki.squirrel-lang.org/default.aspx/SquirrelWiki/SqPlusGetSetObjects.html
2006-09-30 "SQUIRREL2_1_1_sqplus_23"
* Fixed return type for sq_std_string Get()
2006-08-21 "SQUIRREL2_1_0_sqplus_22"
* Merged in Squirrel 2.1.1 Stable
2006-08-20 "SQUIRREL2_1_0_sqplus_21"
* Changed code order to be compatible with GCC 4.1.x.
* Added jflanglois' suggestion for std::basic_string<SQChar>
2006-06-27 "SQUIRREL2_1_0_sqplus_20"
* Added Katsuaki Kawachi's GetInstance()/Match() changes
(http://www.squirrel-lang.org/forums/962/ShowPost.aspx)
2006-02-06 "SQUIRREL2_1_0_sqplus_19"
* Added VS7.1 make/project files with 71 suffix: can be used
alongside VS8 without directory changes
* Added optional debug string argument to SquirrelVM::CompileBuffer()
2006-05-28 "SQUIRREL2_1_0_sqplus_18"
* Added Kamaitati's changes: bug fix, C++ style inheritance support,
null instance argument support
2006-04-25 "SQUIRREL2_1_0_sqplus_17"
* Changed SquirrelObject::GetInstanceUP() to return NULL and
clear internal error state on invalid instance type request
* Added SquirrelObject::GetTypeName(const "SQChar" * key),
SquirrelObject::GetTypeName("INT" key) and
SquirrelObject::GetTypeName().
* Added SQ_SUPPORT_INSTANCE_TYPE_INFO compile time option
* Added missing template arguments (7 argument case)
* Source changes to support VS7.1 and VS8 compilation (standard and
UNICODE builds)
* Added Code::Blocks project files