From 4dafefe46a72ba47468b13d011f8299055081b0f Mon Sep 17 00:00:00 2001 From: chai Date: Fri, 22 Oct 2021 23:59:54 +0800 Subject: *LuaBind --- Documents/Lua.xlsx | Bin 8758 -> 96510 bytes Editor/EditorApplication.cpp | 3 +- Editor/EditorApplication.h | 2 +- Editor/GUI/ContainerWindow.cpp | 3 +- Editor/GUI/EditorWindows.h | 4 +- Editor/GUI/GUIWindow.cpp | 7 +- Editor/Scripting/Editor/EditorApplication.bind.cpp | 2 +- .../Scripting/EditorGUI/ContainerWindow.bind.cpp | 2 +- Editor/Scripting/EditorGUI/GUIWindow.bind.cpp | 14 +- Projects/VisualStudio/Editor/Editor.vcxproj | 6 + .../VisualStudio/Editor/Editor.vcxproj.filters | 21 + Projects/VisualStudio/Runtime/Runtime.vcxproj | 497 ++++++++-------- .../VisualStudio/Runtime/Runtime.vcxproj.filters | 652 +++++++++------------ .../Libraries/GameLab/Engine/Math/Euler.lua | 11 - Resources/Editor.exe | Bin 0 -> 855040 bytes Runtime/Lua/LuaBind/LuaBindClass.cpp | 2 + Runtime/Lua/LuaBind/LuaBindClass.hpp | 150 ++--- Runtime/Lua/LuaBind/LuaBindHelper.cpp | 0 Runtime/Lua/LuaBind/LuaBindHelper.h | 16 + Runtime/Lua/LuaBind/LuaBindMemberRef.h | 2 - Runtime/Lua/LuaBind/LuaBindRef.cpp | 72 ++- Runtime/Lua/LuaBind/LuaBindRef.h | 21 +- Runtime/Lua/LuaBind/LuaBindRefTable.cpp | 34 +- Runtime/Lua/LuaBind/LuaBindRefTable.h | 15 +- Runtime/Lua/LuaBind/LuaBindState.h | 43 +- Runtime/Lua/LuaBind/LuaBindUtility.h | 14 +- Runtime/Lua/LuaBind/LuaBindVM.cpp | 40 +- Runtime/Lua/LuaBind/LuaBindVM.h | 19 +- Runtime/Lua/LuaBind/signal/bind.h | 510 ++++++++++++++++ Runtime/Lua/LuaBind/signal/remove_from_container.h | 32 + Runtime/Lua/LuaBind/signal/signal.h | 451 ++++++++++++++ Runtime/Lua/LuaBind/signal/slot.h | 203 +++++++ 32 files changed, 1955 insertions(+), 893 deletions(-) delete mode 100644 Resources/DefaultContent/Libraries/GameLab/Engine/Math/Euler.lua create mode 100644 Resources/Editor.exe create mode 100644 Runtime/Lua/LuaBind/LuaBindHelper.cpp create mode 100644 Runtime/Lua/LuaBind/LuaBindHelper.h create mode 100644 Runtime/Lua/LuaBind/signal/bind.h create mode 100644 Runtime/Lua/LuaBind/signal/remove_from_container.h create mode 100644 Runtime/Lua/LuaBind/signal/signal.h create mode 100644 Runtime/Lua/LuaBind/signal/slot.h diff --git a/Documents/Lua.xlsx b/Documents/Lua.xlsx index 33d6bec..a73900b 100644 Binary files a/Documents/Lua.xlsx and b/Documents/Lua.xlsx differ diff --git a/Editor/EditorApplication.cpp b/Editor/EditorApplication.cpp index 2f2d1e3..f9a6fa0 100644 --- a/Editor/EditorApplication.cpp +++ b/Editor/EditorApplication.cpp @@ -4,7 +4,8 @@ static bool s_Created; -EditorApplication::EditorApplication() +EditorApplication::EditorApplication(LuaBind::VM* vm) + : LuaBind::NativeClass(vm) { Assert(!s_Created); } diff --git a/Editor/EditorApplication.h b/Editor/EditorApplication.h index 9109a1f..25661a1 100644 --- a/Editor/EditorApplication.h +++ b/Editor/EditorApplication.h @@ -10,7 +10,7 @@ class EditorApplication : public LuaBind::NativeClass { public: - EditorApplication(); + EditorApplication(LuaBind::VM* vm); ~EditorApplication(); void PullMessage(); diff --git a/Editor/GUI/ContainerWindow.cpp b/Editor/GUI/ContainerWindow.cpp index ee42635..2aca239 100644 --- a/Editor/GUI/ContainerWindow.cpp +++ b/Editor/GUI/ContainerWindow.cpp @@ -177,7 +177,8 @@ LRESULT CALLBACK ContainerWindow::ContainerWndProc(HWND hWnd, UINT message, WPAR return flag; } -ContainerWindow::ContainerWindow() +ContainerWindow::ContainerWindow(LuaBind::VM* vm) + : LuaBind::NativeClass(vm) { } diff --git a/Editor/GUI/EditorWindows.h b/Editor/GUI/EditorWindows.h index 58a37fb..d9805a0 100644 --- a/Editor/GUI/EditorWindows.h +++ b/Editor/GUI/EditorWindows.h @@ -53,7 +53,7 @@ public: kShowAuxWindow = 5, // Popup windows like the color picker, gradient editor, etc. Drawn with black background on Mac }; - ContainerWindow(); + ContainerWindow(LuaBind::VM* vm); ~ContainerWindow(); void Init(Rectf size, int showMode, const Vector2f& minSize, const Vector2f& maxSize, std::string name = ""); @@ -134,6 +134,8 @@ public: static LRESULT CALLBACK GUIViewWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); static void RepaintAll(); + GUIWindow(LuaBind::VM* vm); + void Init(std::string name = ""); void DoPaint(); void SetContainerWindow(ContainerWindow* wnd); diff --git a/Editor/GUI/GUIWindow.cpp b/Editor/GUI/GUIWindow.cpp index 0502b21..8918ad3 100644 --- a/Editor/GUI/GUIWindow.cpp +++ b/Editor/GUI/GUIWindow.cpp @@ -174,6 +174,12 @@ void GUIWindow::RepaintAll() //////////////////////////////////////////////////////////// +GUIWindow::GUIWindow(LuaBind::VM* vm) + : LuaBind::NativeClass(vm) + , m_Instance(vm, Ref::STRONG_REF) +{ +} + void GUIWindow::ProcessEventMessages(UINT message, WPARAM wParam, LPARAM lParam) { @@ -226,7 +232,6 @@ void GUIWindow::Init(std::string name) log_error("Failed to setup rendering context"); log_info("Created GUIWindow " /*+ (long)this*/); - } bool GUIWindow::SetRenderContext() diff --git a/Editor/Scripting/Editor/EditorApplication.bind.cpp b/Editor/Scripting/Editor/EditorApplication.bind.cpp index 672bdcd..c6ea9f7 100644 --- a/Editor/Scripting/Editor/EditorApplication.bind.cpp +++ b/Editor/Scripting/Editor/EditorApplication.bind.cpp @@ -16,7 +16,7 @@ LUA_BIND_POSTPROCESS(EditorApplication) LUA_BIND_IMPL_METHOD(EditorApplication, EditorApplication::_New) { LUA_BIND_PREPARE(L, EditorApplication); - EditorApplication* app = new EditorApplication(); + EditorApplication* app = new EditorApplication(state.GetVM()); app->PushUserdata(state); return 1; } diff --git a/Editor/Scripting/EditorGUI/ContainerWindow.bind.cpp b/Editor/Scripting/EditorGUI/ContainerWindow.bind.cpp index 75d28aa..ce0efc8 100644 --- a/Editor/Scripting/EditorGUI/ContainerWindow.bind.cpp +++ b/Editor/Scripting/EditorGUI/ContainerWindow.bind.cpp @@ -54,7 +54,7 @@ LUA_BIND_IMPL_METHOD(ContainerWindow, ContainerWindow::_New) LUA_BIND_STATE(L, ContainerWindow); LUA_BIND_CHECK(L, "TNTT"); - ContainerWindow* wnd = new ContainerWindow(); + ContainerWindow* wnd = new ContainerWindow(state.GetVM()); Rectf rect = state.GetValue(state, Rectf()); int showMode = state.GetValue(2, 0); diff --git a/Editor/Scripting/EditorGUI/GUIWindow.bind.cpp b/Editor/Scripting/EditorGUI/GUIWindow.bind.cpp index 78ea635..075bce5 100644 --- a/Editor/Scripting/EditorGUI/GUIWindow.bind.cpp +++ b/Editor/Scripting/EditorGUI/GUIWindow.bind.cpp @@ -7,8 +7,7 @@ LUA_BIND_REGISTRY(GUIWindow) { "Focus", _Focus }, { "SetContainerWindow", _SetContainerWindow }, { "SetPosition", _SetPosition }, - { "New", _New }, - { "__gc", _GC } + { "New", _New } ); } @@ -16,13 +15,6 @@ LUA_BIND_POSTPROCESS(GUIWindow) { } -LUA_BIND_IMPL_METHOD(GUIWindow, _GC) -{ - LUA_BIND_PREPARE(L, GUIWindow); - - return 0; -} - LUA_BIND_IMPL_METHOD(GUIWindow, _DoPaint) { LUA_BIND_PREPARE(L, GUIWindow); @@ -64,8 +56,8 @@ LUA_BIND_IMPL_METHOD(GUIWindow, _SetPosition) LUA_BIND_IMPL_METHOD(GUIWindow, _New) { LUA_BIND_PREPARE(L, GUIWindow); - GUIWindow* wnd = new GUIWindow(); - wnd->PushUserdata(state); + GUIWindow* wnd = new GUIWindow(state.GetVM()); wnd->Init(); + wnd->PushUserdata(state); return 1; } \ No newline at end of file diff --git a/Projects/VisualStudio/Editor/Editor.vcxproj b/Projects/VisualStudio/Editor/Editor.vcxproj index 5bcaf94..7304a6a 100644 --- a/Projects/VisualStudio/Editor/Editor.vcxproj +++ b/Projects/VisualStudio/Editor/Editor.vcxproj @@ -176,6 +176,7 @@ + @@ -216,6 +217,7 @@ + @@ -224,6 +226,10 @@ + + + + diff --git a/Projects/VisualStudio/Editor/Editor.vcxproj.filters b/Projects/VisualStudio/Editor/Editor.vcxproj.filters index e60fc65..9ae1dba 100644 --- a/Projects/VisualStudio/Editor/Editor.vcxproj.filters +++ b/Projects/VisualStudio/Editor/Editor.vcxproj.filters @@ -85,6 +85,9 @@ {47032dd6-dca2-478f-b594-d08c0b22e119} + + {86d0c80c-7c35-425d-87c8-0529ef352650} + @@ -231,6 +234,9 @@ Runtime\Graphics + + Runtime\Lua\LuaBind + @@ -371,6 +377,21 @@ Runtime\Graphics + + Runtime\Lua\LuaBind\signal + + + Runtime\Lua\LuaBind\signal + + + Runtime\Lua\LuaBind\signal + + + Runtime\Lua\LuaBind\signal + + + Runtime\Lua\LuaBind + diff --git a/Projects/VisualStudio/Runtime/Runtime.vcxproj b/Projects/VisualStudio/Runtime/Runtime.vcxproj index 2d56bfd..36c49d6 100644 --- a/Projects/VisualStudio/Runtime/Runtime.vcxproj +++ b/Projects/VisualStudio/Runtime/Runtime.vcxproj @@ -1,263 +1,236 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - Debug - x64 - - - Release - x64 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {12759f92-73f9-48bc-8808-9fe709dcd134} - - - {9b542e6d-8677-4ad6-9a69-4650103906c5} - - - {12b7b0f8-6581-4321-9627-3ee601100463} - - - - - - - - 15.0 - {4C26BDCC-CA08-4C43-8EFF-B62A204D5FBD} - Runtime - 10.0.17763.0 - - - - Application - true - v141 - MultiByte - - - Application - false - v141 - true - MultiByte - - - Application - true - v141 - MultiByte - - - Application - false - v141 - true - MultiByte - - - - - - - - - - - - - - - - - - - - - $(SolutionDir)..\..\Build - - - $(SolutionDir)..\..\Build - - - $(SolutionDir)..\..\Build - - - $(SolutionDir)..\..\Build - - - - Level3 - Disabled - true - true - $(SolutionDir)..\..\ThirdParty\;$(SolutionDir)..\..\ThirdParty\SDL2\include;%(AdditionalIncludeDirectories) - - - Console - - - - - Level3 - Disabled - true - true - $(SolutionDir)..\..\ThirdParty\;$(SolutionDir)..\..\ThirdParty\SDL2\include;%(AdditionalIncludeDirectories) - - - Console - - - - - Level3 - MaxSpeed - true - true - true - true - $(SolutionDir)..\..\ThirdParty\;$(SolutionDir)..\..\ThirdParty\SDL2\include;%(AdditionalIncludeDirectories) - - - Console - true - true - - - - - Level3 - MaxSpeed - true - true - true - true - $(SolutionDir)..\..\ThirdParty\;$(SolutionDir)..\..\ThirdParty\SDL2\include;%(AdditionalIncludeDirectories) - - - Console - true - true - - - - - + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {12759f92-73f9-48bc-8808-9fe709dcd134} + + + {9b542e6d-8677-4ad6-9a69-4650103906c5} + + + {12b7b0f8-6581-4321-9627-3ee601100463} + + + + 15.0 + {4C26BDCC-CA08-4C43-8EFF-B62A204D5FBD} + Runtime + 10.0.17763.0 + + + + Application + true + v141 + MultiByte + + + Application + false + v141 + true + MultiByte + + + Application + true + v141 + MultiByte + + + Application + false + v141 + true + MultiByte + + + + + + + + + + + + + + + + + + + + + $(SolutionDir)..\..\Build + + + $(SolutionDir)..\..\Build + + + $(SolutionDir)..\..\Build + + + $(SolutionDir)..\..\Build + + + + Level3 + Disabled + true + true + $(SolutionDir)..\..\ThirdParty\;$(SolutionDir)..\..\ThirdParty\SDL2\include;%(AdditionalIncludeDirectories) + + + Console + + + + + Level3 + Disabled + true + true + $(SolutionDir)..\..\ThirdParty\;$(SolutionDir)..\..\ThirdParty\SDL2\include;%(AdditionalIncludeDirectories) + + + Console + + + + + Level3 + MaxSpeed + true + true + true + true + $(SolutionDir)..\..\ThirdParty\;$(SolutionDir)..\..\ThirdParty\SDL2\include;%(AdditionalIncludeDirectories) + + + Console + true + true + + + + + Level3 + MaxSpeed + true + true + true + true + $(SolutionDir)..\..\ThirdParty\;$(SolutionDir)..\..\ThirdParty\SDL2\include;%(AdditionalIncludeDirectories) + + + Console + true + true + + + + + \ No newline at end of file diff --git a/Projects/VisualStudio/Runtime/Runtime.vcxproj.filters b/Projects/VisualStudio/Runtime/Runtime.vcxproj.filters index 86744e8..fb980a8 100644 --- a/Projects/VisualStudio/Runtime/Runtime.vcxproj.filters +++ b/Projects/VisualStudio/Runtime/Runtime.vcxproj.filters @@ -1,367 +1,287 @@ - - - - - {e789ad2d-945c-482e-8316-1dd0ccdfc465} - - - {9ad1872a-2d30-43f7-be83-f30d53e57970} - - - {c7bba1da-cea1-43fa-b344-17a3d4abc615} - - - {d0c5cd2c-bc7a-437a-86ce-903b6891c0dd} - - - {93deee15-5efc-4231-ab54-56f471ab701f} - - - {088f2ab7-cbf6-4338-b43a-652fde8d0b4b} - - - {ec69ceaf-4fa8-4296-827e-fd4c537ec5ea} - - - {bfc9838c-ddde-4d86-8da3-4ccebd976cde} - - - {f15a5d95-54d1-49e5-bcdf-2759f0afc5c4} - - - {5bbfbd7d-379a-43e9-b05a-8f97b7f3fa3a} - - - {e53ba507-aa27-4d67-9da4-42752bc84dc8} - - - {158d8348-2b65-4ff1-b313-ba9f7bcfde32} - - - {fb970ccc-e9aa-4f61-854c-0b852503a375} - - - {4478c64f-e27a-4be6-a189-8d99e0fc6b15} - - - {c865b35b-5537-4757-927d-7476009f4de2} - - - {a354c650-8493-41a2-81e5-205495beb0e5} - - - {e53b1cb1-9d81-47a0-8d40-566d4fd0ef80} - - - - - Utilities - - - Utilities - - - Graphics - - - Mesh - - - Mesh - - - Threads - - - Threads - - - Threads - - - Mesh - - - Profiler - - - Utilities - - - Graphics - - - Graphics - - - Math - - - Graphics - - - Mesh - - - Math - - - Graphics - - - Input - - - Graphics - - - Graphics - - - Graphics - - - Utilities - - - Utilities - - - FileSystem - - - Utilities - - - Utilities - - - Graphics - - - FileSystem - - - Graphics - - - Mesh - - - Graphics - - - Utilities - - - Graphics - - - Graphics - - - Math - - - Shaders - - - Shaders - - - Shaders - - - Utilities - - - Profiler - - - Mesh - - - Graphics - - - Physics - - - ImGUI - - - ImGUI - - - - LuaBind - - - LuaBind - - - LuaBind - - - LuaBind - - - LuaBind - - - LuaBind - - - LuaBind - - - LuaBind - - - LuaBind - - - LuaBind - - - LuaBind - - - LuaBind - - - LuaBind - - - LuaBind - - - - - Mesh - - - Threads - - - Threads - - - Graphics - - - Math - - - Graphics\Scripting - - - Graphics - - - Graphics - - - Graphics - - - Math - - - Graphics - - - Physics\Scripting - - - Input - - - Graphics - - - Graphics - - - Graphics\Scripting - - - Graphics - - - FileSystem - - - Utilities - - - Utilities - - - Graphics - - - FileSystem - - - Graphics - - - Graphics\Scripting - - - Mesh - - - Graphics - - - Shaders - - - Graphics - - - ImGUI - - - ImGUI - - - - LuaBind - - - LuaBind - - - LuaBind - - - LuaBind - - - LuaBind - - - LuaBind - - - LuaBind - - - LuaBind - - - LuaBind - - - - - LuaBind - - - LuaBind - - + + + + + {e789ad2d-945c-482e-8316-1dd0ccdfc465} + + + {9ad1872a-2d30-43f7-be83-f30d53e57970} + + + {c7bba1da-cea1-43fa-b344-17a3d4abc615} + + + {d0c5cd2c-bc7a-437a-86ce-903b6891c0dd} + + + {93deee15-5efc-4231-ab54-56f471ab701f} + + + {088f2ab7-cbf6-4338-b43a-652fde8d0b4b} + + + {ec69ceaf-4fa8-4296-827e-fd4c537ec5ea} + + + {bfc9838c-ddde-4d86-8da3-4ccebd976cde} + + + {f15a5d95-54d1-49e5-bcdf-2759f0afc5c4} + + + {5bbfbd7d-379a-43e9-b05a-8f97b7f3fa3a} + + + {e53ba507-aa27-4d67-9da4-42752bc84dc8} + + + {158d8348-2b65-4ff1-b313-ba9f7bcfde32} + + + {fb970ccc-e9aa-4f61-854c-0b852503a375} + + + {4478c64f-e27a-4be6-a189-8d99e0fc6b15} + + + {c865b35b-5537-4757-927d-7476009f4de2} + + + {e53b1cb1-9d81-47a0-8d40-566d4fd0ef80} + + + + + Utilities + + + Utilities + + + Graphics + + + Mesh + + + Mesh + + + Threads + + + Threads + + + Threads + + + Mesh + + + Profiler + + + Utilities + + + Graphics + + + Graphics + + + Math + + + Graphics + + + Mesh + + + Math + + + Graphics + + + Input + + + Graphics + + + Graphics + + + Graphics + + + Utilities + + + Utilities + + + FileSystem + + + Utilities + + + Utilities + + + Graphics + + + FileSystem + + + Graphics + + + Mesh + + + Graphics + + + Utilities + + + Graphics + + + Graphics + + + Math + + + Shaders + + + Shaders + + + Shaders + + + Utilities + + + Profiler + + + Mesh + + + Graphics + + + Physics + + + ImGUI + + + ImGUI + + + + + + Mesh + + + Threads + + + Threads + + + Graphics + + + Math + + + Graphics\Scripting + + + Graphics + + + Graphics + + + Graphics + + + Math + + + Graphics + + + Physics\Scripting + + + Input + + + Graphics + + + Graphics + + + Graphics\Scripting + + + Graphics + + + FileSystem + + + Utilities + + + Utilities + + + Graphics + + + FileSystem + + + Graphics + + + Graphics\Scripting + + + Mesh + + + Graphics + + + Shaders + + + Graphics + + + ImGUI + + + ImGUI + + + \ No newline at end of file diff --git a/Resources/DefaultContent/Libraries/GameLab/Engine/Math/Euler.lua b/Resources/DefaultContent/Libraries/GameLab/Engine/Math/Euler.lua deleted file mode 100644 index 1f2ed78..0000000 --- a/Resources/DefaultContent/Libraries/GameLab/Engine/Math/Euler.lua +++ /dev/null @@ -1,11 +0,0 @@ -local Euler = GameLab.Class("Euler", "GameLab.Engine.Math") - -Euler.Ctor = function (self, x, y, z) - self.x = x or 0 - self.y = y or 0 - self.z = z or 0 -end - - - -return Euler \ No newline at end of file diff --git a/Resources/Editor.exe b/Resources/Editor.exe new file mode 100644 index 0000000..7d4ab9d Binary files /dev/null and b/Resources/Editor.exe differ diff --git a/Runtime/Lua/LuaBind/LuaBindClass.cpp b/Runtime/Lua/LuaBind/LuaBindClass.cpp index 7fd603c..9c67475 100644 --- a/Runtime/Lua/LuaBind/LuaBindClass.cpp +++ b/Runtime/Lua/LuaBind/LuaBindClass.cpp @@ -5,6 +5,8 @@ namespace LuaBind { + UIDGenerator gClassIDGenerator; + #if LUA_BIND_ENABLE_PLAIN_CLASS int PlainClass::registry(lua_State* L) diff --git a/Runtime/Lua/LuaBind/LuaBindClass.hpp b/Runtime/Lua/LuaBind/LuaBindClass.hpp index 154a4ce..f0fdf43 100644 --- a/Runtime/Lua/LuaBind/LuaBindClass.hpp +++ b/Runtime/Lua/LuaBind/LuaBindClass.hpp @@ -2,25 +2,24 @@ #define __LUA_BIND_CLASS_H__ #include "LuaBindConfig.h" - -#if LUA_BIND_PROFILER #include -#endif - +#include #include - #include "LuaBindRef.h" #include "LuaBindMemberRef.h" #include "LuaBindCFunctions.h" #include "LuaBindWatchDog.h" #include "LuaBindUtility.h" +#include "LuaBindHelper.h" namespace LuaBind { - class VM; - // +#define CLASS_NONE_ID (-1) + + extern UIDGenerator gClassIDGenerator; + // Ðé»ùÀ࣬ΪÁËʵÏÖ¶à̬¡£ÐèÒª·ÃÎÊÏÂÃæÕâЩ½Ó¿ÚµÄÍⲿ»ùÀàÐèÒªÐé¼Ì³Ð´ËÀ֮࣬ºóÔÙÅÉÉúÁ´Öоͻá // µ÷ÓöÔӦʵÌåµÄ·½·¨¡£×¢Òâ¼Ì³Ð´ËÀàʱ²»ÄÜʵÏÖÏÂÃæµÄ·½·¨£¬ÊµÏÖÔÚNativeClassÖУ¬ÊµÏÖ»á // µ¼Ö¶þÒåÐÔ¡£ @@ -28,24 +27,19 @@ namespace LuaBind // ÒÀ¾ÝEffective C++Ìõ¿î40£¬Èç¹ûÔÚ±ØÐëʹÓÃvirtual base»ùÀàÇé¿öÏ£¬Ó¦¸Ã¾¡¿ÉÄܱÜÃâÏòÆäÖзŠ// ÖÃÊý¾Ý³ÉÔ±£¬¹æ±ÜÊý¾Ý³ÉÔ±³õʼ»¯Ôì³ÉµÄһЩÒþÐÔÎÊÌâ¡£ÒÀ¾ÝÕâÒ»µã£¬vpb»ùÀà¸ü¼Ó½Ó½üC#ºÍJavaÖÐ // µÄInterface¡£ËùÒÔ£¬ÔÚÕâÀï°ÑÀàÓÃI¿ªÍ·±êʶÕâÊÇÒ»¸ö½Ó¿Ú¡£ - // class Object { public: Object() {}; virtual ~Object() {}; - // // ³ÉÔ±ÒýÓùÜÀí£¬ÔÚʵÀýµÄref tableÀï¡£ÉèÖá¢È¡¡¢Çå³ý¡£ - // virtual bool PushMemberRef(State& state, int refID) = 0; virtual bool PushUserdata(State& state) = 0; virtual bool PushMemberTable(State& state) = 0; virtual bool PushRefTable(State& state) = 0; - // // ±»NativeClassʵÏÖ¡£±£³ÖºÍÊÍ·Ånative×ÊÔ´¡£ - // virtual void Retain() = 0; virtual void Release() = 0; @@ -56,43 +50,34 @@ namespace LuaBind //{ //} - // // ÐèÒª±©Â¶¸øluaµÄnative classÐèÒª¼Ì³Ð´ËÀࡣͨ¹ýlua¹ÜÀíµÄʵÀýҪȷ±£ÒýÓüÆÊýµÄÕýÈ·ÐÔ£¬ÔÚ¶à¸öÏß³ÌÖÐÐèҪȷ // ¶¨²»»áÎóÊÍ·Å¡£ - // template class NativeClass : public BASE { public: + enum NativeClassTableIndex { kRefTable = 1, kMemberTable = 2, kClassTable = 3 }; - // // ½«userdata×÷Ϊkey£¬ÔÚref tableÀï¶ÔuserdataÌí¼ÓÒ»¸öÒýÓã¬ÒÔά³ÖuserdataµÄÉúÃüÖÜÆÚ¡£ // Ïà±È½Ïmember ref£¬Õâ¸öÓÃÔÚʵÌå»á±»¶à´Î±»²»Í¬ÆäËûʵÌåÒýÓõÄÇé¿ö£¬²¢Æµ·±Ïú»ÙÕâЩʵÌ壬 // ±ÜÃâluaƵ·±µÄµ÷ÓÃgc¼ì²â¡£ - // template void Retain(State& state, DATATYPE* userdata); - // // ¶Ôuserdata¼õÉÙÒ»¸öÒýÓÃÔÚref tableÀÒÔ³¢ÊÔ»ØÊÕuserdata¡£ - // template void Release(State& state, DATATYPE* userdata); - // // ½«userdata pushµ½Õ»¶¥£¬Èç¹ûûÓгõʼ»¯mUserdata£¬³õʼ»¯ÉèÖúÃÔª±í²¢°Ñ³õʼ»¯ºÃµÄ // userdataÁôÔÚÕ»¶¥¡£²¢Ìí¼ÓÒ»¸öÒýÓá£ÕâÊÇÒ»¸ö½«native¶ÔÏóËùÓÐÈ¨ÒÆ½»¸ølua¿ØÖƵķ½·¨¡£ - // + bool PushUserdata(State& state) override; bool PushMemberRef(State& state, int refID) override; - bool PushUserdata(State& state) override; bool PushMemberTable(State& state) override; bool PushRefTable(State& state) override; - // // WatchDogÌí¼ÓÒ»¸önativeÒýÓá£luaVMÒýÓò»»áÌṩÍⲿ½Ó¿Ú¡£¼Ì³Ð´ËÀàµÄÅÉÉúÀ಻ÄÜÖ±½ÓʹÓà // delete·½·¨£¬Ó¦¸ÃʹÓÃReleaseÊÍ·Å¡£Ò»°ãÇé¿öÏÂÕâ¸ö²Ù×÷ÓÉÐéÄâ»ú__gc½øÐУ¬µ«ÊÇÔÊÐíÓû§ // ³ÌÐòÔÚnativeÖиô¾øÐéÄâ»úÇé¿öÏÂÊÍ·Å£¬ÕâÖÖÇé¿öÏÂҪʹÓÃRelease¡£ // // ÕâÁ½¸öº¯ÊýÊÇnative½Ó¿Ú¡£ - // void Retain() override final; void Release() override final; @@ -103,12 +88,11 @@ namespace LuaBind protected: - NativeClass(); + // ÐèÒªÖ¸Ã÷¶ÔÏóËùÊôµÄÐéÄâ»ú + NativeClass(LuaBind::VM* vm); virtual ~NativeClass(); - // // ³ÉÔ±ÒýÓùÜÀí£¬ÔÚʵÀýµÄref tableÀï¡£ÉèÖá¢È¡¡¢Çå³ý - // void SetMemberRef(State& state, MemberRef& memRef, int idx); bool PushMemberRef(State& state, MemberRef& memRef); void ClearMemberRef(State& state, MemberRef& memRef); @@ -119,14 +103,11 @@ namespace LuaBind static void RegisterClassShared(State& state); static void RegisterFactoryClass(State& state); - static void RegisterSingletonClass(State& state); static void SetClassTableRef(State& state, int idx); static void PushClassTable(State& state); - // // ´´½¨userdata£¬°ó¶¨ÊµÀýµ½state¡£ - // void BindToLua(State& state); //------------------------------------------------------------------------------// @@ -149,25 +130,16 @@ namespace LuaBind //--------------------------------------------------------------------------------// - // - // class table£¬¹¤³§ºÍµ¥Àý¶¼ÓС£ - // - static StrongRef mClassTable; + // ÀàÐ͵ÄÈ«¾ÖUID£¬ÔÚ²»Í¬µÄÐéÄâ»úÖÐÏàͬ + static int sClassID; - // - // Èç¹ûÀàÊǵ¥Àý£¬Õâ¸öÓÃÀ´±£´æsingletonµÄÒýÓùØÏµ£¬ÒÔ±£Ö¤²»»á±»»ØÊÕÀàËÆÆÕͨÀàµÄref table¡£ - // µ¥ÀýµÄ³ÉÔ±ÊÇÈ«ÉúÃüÖÜÆÚµÄ£¬ËùÒÔÖ±½ÓÔÚ_LUA_BIND_STRONGREF_TABLE¡£µ¥Àý¶Ôuserdata½øÐÐ - // Retain\ReleaseºÍmember ref²Ù×÷ʱºÍ¹¤³§ÊµÀý²»Í¬£¬ÊÇ´æÔÚÏÂÃæÕâ¸öref tableÀï - // µÄ£¬Õâ¸ötableÔÚ_LUA_BIND_STRONGREF_TABLEÀï¡£ - // - static StrongRef mSingletonRefTable; + // ËùÊôµÄÐéÄâ»ú + LuaBind::VM* mOwner; - // // ͨ¹ýuserdata¿ÉÒÔÄõ½: // 1: ref table // 2: member table // 3: class table - // WeakRef mUserdata; // ͨ¹ýºó²ÅÄÜɾ³ý @@ -204,10 +176,10 @@ namespace LuaBind #endif //--------------------------------------------------------------------------------// + template + int NativeClass::sClassID = CLASS_NONE_ID; - // // ¶Ô²»Í¬ÀàÐÍ£¬Í¨¹ýµ÷ÓÃGetLuaClassName»ñµÃÀàÐÍÃû£¬Èç¹ûÊÇÅÉÉúÀ࣬GetClassName»á±»¸²¸Ç£¬Ö¸Ïòluax_c_getupvalue¡£ - // template int NativeClass::_GetClassName(lua_State* L) { @@ -220,9 +192,7 @@ namespace LuaBind //--------------------------------------------------------------------------------// - // // ×¢²á¹¤³§ºÍµ¥Àý¹²ÓеÄÀà³ÉÔ± - // template void NativeClass::RegisterClassShared(State& state) { @@ -235,9 +205,7 @@ namespace LuaBind state.RegisterMethods(regTable); } - // // ¹¤³§ÀàµÄ³ÉÔ±£¬×¢²áÔÚclass table - // template void NativeClass::RegisterFactoryClass(State& state) { @@ -249,36 +217,27 @@ namespace LuaBind state.RegisterMethods(regTable); } - // - // µ¥ÀýÀàµÄ³ÉÔ±£¬×¢²áÔÚclass table - // template - void NativeClass::RegisterSingletonClass(State& state) + void NativeClass::SetClassTableRef(State& state, int idx) { - luaL_Reg regTable[] = { - { NULL, NULL } - }; - - state.RegisterMethods(regTable); + if (sClassID == CLASS_NONE_ID) + sClassID = gClassIDGenerator.GetID(); + LuaBind::VM* vm = state.GetVM(); + vm->RegisterClassI(state, sClassID, idx); } template void NativeClass::PushClassTable(State& state) { - assert(mClassTable); - - mClassTable.PushRef(state); + LuaBind::VM* vm = state.GetVM(); + vm->PushClassTable(state, sClassID); } template - void NativeClass::SetClassTableRef(State& state, int idx) - { - mClassTable.SetRef(state, idx); - } - - template - NativeClass::NativeClass() + NativeClass::NativeClass(LuaBind::VM* vm) : mWatchDog() + , mUserdata(vm) + , mOwner(vm) #if LUA_BIND_PROFILER , mSafer(false) #endif @@ -380,8 +339,7 @@ namespace LuaBind template bool NativeClass::PushUserdata(State& state) { - assert(!TYPE::IsClassSingleton()); - if (!mUserdata) + if (!mUserdata) // µÚÒ»´Î´´½¨ { BindToLua(state); return true; @@ -413,28 +371,12 @@ namespace LuaBind template bool NativeClass::PushRefTable(State& state) { - // Singleton - if (TYPE::IsClassSingleton()) - { - if (!this->mSingletonRefTable) { - lua_newtable(state); - this->mSingletonRefTable.SetRef(state, -1); // strong ref to member table won't be garbage collected - } - else { - this->mSingletonRefTable.PushRef(state); - } - return true; - } - // Factory - else + if (this->PushUserdata(state)) { - if (this->PushUserdata(state)) + if (lua_getmetatable(state, -1)) // RefTable { - if (lua_getmetatable(state, -1)) - { - lua_replace(state, -2); - return true; - } + lua_replace(state, -2); + return true; } } return false; @@ -450,8 +392,6 @@ namespace LuaBind template void NativeClass::BindToLua(State& state) { - // µ¥Àý²»Äܰó¶¨userdata - assert(!TYPE::IsClassSingleton()); assert(!mUserdata); // ´´½¨userdata²¢ÁôÔÚÕ»¶¥£¬×¢ÒâµØÖ·Òª×ª»»ÎªTYPE*£¬Ö±½ÓÓÃthis¿ÉÄܻᵼÖ¶àÖØ¼Ì³ÐµÄÀàɥʧ¶à̬¡£ @@ -465,10 +405,10 @@ namespace LuaBind PushClassTable(state); // class table // stack: - // -1: class table - // -2: member table - // -3: ref table - // -4: userdata + // -1 class table + // -2 member table + // -3 ref table + // -4 userdata int top = state.GetTop(); int memberTable = top - 1; @@ -488,10 +428,10 @@ namespace LuaBind lua_pushvalue(state, memberTable); lua_setfield(state, refTable, "__newindex"); - // ÉèÖÃÔª±í - lua_setmetatable(state, -2); // class is meta of member - lua_setmetatable(state, -2); // member is meta of ref - lua_setmetatable(state, -2); // ref is meta of userdata + // ÉèÖÃÔª±í userdata -> refTable -> memberTable -> classTable + lua_setmetatable(state, -2); // class is metatable of member + lua_setmetatable(state, -2); // member is metatable of ref + lua_setmetatable(state, -2); // ref is metatable of userdata // ÉèÖÃÒ»¸öuserdataµÄÈõÒýÓ㬷½±ãͨ¹ýPushLuaUserdata·½·¨·µ»Ølua¶ÔÏó mUserdata.SetRef(state, -1); @@ -504,9 +444,7 @@ namespace LuaBind #endif } - // // ³ÉÔ±ÒýÓùÜÀí - // template void NativeClass::SetMemberRef(State& state, MemberRef& memRef, int idx) { @@ -810,10 +748,7 @@ namespace LuaBind int NativeClass::_GetClass(lua_State* L) { LUA_BIND_STATE(L); - if (!mClassTable) - lua_pushnil(L); - else - mClassTable.PushRef(state); + state.GetVM()->PushClassTable(state, sClassID); return 1; } @@ -828,11 +763,6 @@ namespace LuaBind return 1; } - template StrongRef NativeClass::mClassTable; // class table - template StrongRef NativeClass::mSingletonRefTable; // µ¥Àý - - - } #endif \ No newline at end of file diff --git a/Runtime/Lua/LuaBind/LuaBindHelper.cpp b/Runtime/Lua/LuaBind/LuaBindHelper.cpp new file mode 100644 index 0000000..e69de29 diff --git a/Runtime/Lua/LuaBind/LuaBindHelper.h b/Runtime/Lua/LuaBind/LuaBindHelper.h new file mode 100644 index 0000000..f095add --- /dev/null +++ b/Runtime/Lua/LuaBind/LuaBindHelper.h @@ -0,0 +1,16 @@ +#ifndef _LUA_BIND_HELPER_H +#define _LUA_BIND_HELPER_H + +namespace LuaBind +{ + class UIDGenerator + { + public: + UIDGenerator() { m_Cur = 0; } + int GetID() { return ++m_Cur; } + + private: + int m_Cur; + }; +}; +#endif \ No newline at end of file diff --git a/Runtime/Lua/LuaBind/LuaBindMemberRef.h b/Runtime/Lua/LuaBind/LuaBindMemberRef.h index 045d6ef..ecc50f5 100644 --- a/Runtime/Lua/LuaBind/LuaBindMemberRef.h +++ b/Runtime/Lua/LuaBind/LuaBindMemberRef.h @@ -6,10 +6,8 @@ namespace LuaBind { - // // ʵÀýµÄref table±£´æµÄmember ref¡£ÓÉluax class×ö¾ßÌåµÄ¹ÜÀí¡£ÊµÀýµÄref tableÊÇÇ¿ÒýÓã¬ÓÃÀ´¹ÜÀíÀïÃæmemberµÄÉúÃüÖÜÆÚ¡£ // ÓÃÀ´ÔÚluaºÍnativeÖ®¼ä½øÐÐÊý¾Ý¹µÍ¨¡£ - // class MemberRef { public: diff --git a/Runtime/Lua/LuaBind/LuaBindRef.cpp b/Runtime/Lua/LuaBind/LuaBindRef.cpp index 676525a..b2f8e1c 100644 --- a/Runtime/Lua/LuaBind/LuaBindRef.cpp +++ b/Runtime/Lua/LuaBind/LuaBindRef.cpp @@ -4,16 +4,16 @@ namespace LuaBind { - Ref::Ref(RefMode mode) + Ref::Ref(LuaBind::VM* vm, RefMode mode) : mRefID(LUA_NOREF) , mMode(mode) + , mOwner(vm) { } Ref::~Ref() { // ×Ô¶¯ÊÍ·ÅÒýÓà - } Ref::operator bool() @@ -21,11 +21,49 @@ namespace LuaBind return (mRefID != LUA_NOREF); } - bool Ref::PushRef(State& state) + void Ref::UnRef() + { + if (mRefID == LUA_NOREF) + return; + VM* vm = mOwner; + if (!vm) return; + if (mMode == STRONG_REF) + { + RefTable& table = vm->GetStrongRefTable(); + table.UnRef(mRefID); + mRefID = LUA_NOREF; + } + else if (mMode == WEAK_REF) + { + RefTable& table = vm->GetWeakRefTable(); + table.UnRef(mRefID); + mRefID = LUA_NOREF; + } + } + + void Ref::SetRef(LuaBind::State& state, int idx) + { + assert(state.GetVM() == mOwner); + + VM* vm = mOwner; + if (!vm) return; + if (mMode == STRONG_REF) + { + RefTable& table = vm->GetStrongRefTable(); + mRefID = table.Ref(state, idx); + } + else if (mMode == WEAK_REF) + { + RefTable& table = vm->GetWeakRefTable(); + mRefID = table.Ref(state, idx); + } + } + + bool Ref::PushRef(LuaBind::State& state) { assert(mRefID != LUA_NOREF); - VM* vm = state.GetVM(); + VM* vm = mOwner; if (!vm) return false; if (mMode == STRONG_REF) { @@ -39,35 +77,19 @@ namespace LuaBind } else { - state.PushNil(); + state.PushNil(); return false; } return true; } - void Ref::SetRef(State& state, int idx) - { - VM* vm = state.GetVM(); - if (!vm) return; - if (mMode == STRONG_REF) - { - RefTable& table = vm->GetStrongRefTable(); - mRefID = table.Ref(state, idx); - } - else if (mMode == WEAK_REF) - { - RefTable& table = vm->GetWeakRefTable(); - mRefID = table.Ref(state, idx); - } - } - - StrongRef::StrongRef() - : Ref(STRONG_REF) + StrongRef::StrongRef(LuaBind::VM* vm) + : Ref(vm, STRONG_REF) { } - WeakRef::WeakRef() - : Ref(WEAK_REF) + WeakRef::WeakRef(LuaBind::VM* vm) + : Ref(vm, WEAK_REF) { } diff --git a/Runtime/Lua/LuaBind/LuaBindRef.h b/Runtime/Lua/LuaBind/LuaBindRef.h index 7058094..cd2fad1 100644 --- a/Runtime/Lua/LuaBind/LuaBindRef.h +++ b/Runtime/Lua/LuaBind/LuaBindRef.h @@ -11,40 +11,41 @@ namespace LuaBind class Ref { public: - enum RefMode { STRONG_REF, WEAK_REF }; - Ref(RefMode mode = STRONG_REF); + Ref(LuaBind::VM* vm, RefMode mode = STRONG_REF); virtual ~Ref(); operator bool(); // ½«Õ»ÉϵĶÔÏóÌí¼Óµ½È«¾ÖÒýÓñíÖÐ - void SetRef(State& state, int idx); + void SetRef(LuaBind::State& state, int idx); + + // ½â³ýÒýÓà + void UnRef(); // ½«ÒýÓõĶÔÏóѹÈëÕ» - bool PushRef(State& state); + bool PushRef(LuaBind::State& state); int GetRefID() { return mRefID; } RefMode GetRefMode() { return mMode; } private: - - int mRefID; - RefMode mMode; - + LuaBind::VM* mOwner; // ËùÊôµÄÐéÄâ»ú + RefMode mMode; // ģʽ + int mRefID; // ÒýÓÃID }; // Ç¿ÒýÓã¬ÔÚLUA_REGISTRYINDEX["GAMELAB_UNIVERSAL_STRONG_REFERENCE_TABLE"]À±£Ö¤lua object²»»á±»»ØÊÕ class StrongRef: public Ref { public: - StrongRef(); + StrongRef(LuaBind::VM* vm); }; @@ -52,7 +53,7 @@ namespace LuaBind class WeakRef : public Ref { public: - WeakRef(); + WeakRef(LuaBind::VM* vm); }; diff --git a/Runtime/Lua/LuaBind/LuaBindRefTable.cpp b/Runtime/Lua/LuaBind/LuaBindRefTable.cpp index 39ef9ab..f8a7a78 100644 --- a/Runtime/Lua/LuaBind/LuaBindRefTable.cpp +++ b/Runtime/Lua/LuaBind/LuaBindRefTable.cpp @@ -1,11 +1,12 @@ #include "LuaBindRefTable.h" #include "LuaBindState.h" +#include "LuaBindVM.h" namespace LuaBind { - RefTable::RefTable() - : mState(nullptr) + RefTable::RefTable(LuaBind::VM* vm) + : mVM(vm) { } @@ -13,9 +14,9 @@ namespace LuaBind { } - void RefTable::Init(State& state, cc8* name, cc8* mode) + void RefTable::Init( cc8* name, cc8* mode) { - assert(!mState); + assert(mVM); assert(name); mName = name; @@ -25,7 +26,7 @@ namespace LuaBind if (mode[i] == 'k') mMode |= WEAK_KEY; else if (mode[i] == 'v') mMode |= WEAK_VALUE; } - mState = state.GetHandle(); + State state = mVM->GetMainState(); state.GetField(LUA_REGISTRYINDEX, name); // register[mName] if (state.IsNil(-1)) @@ -58,21 +59,22 @@ namespace LuaBind bool RefTable::IsKeyWeak() { - assert(mState); + assert(mVM); return mMode & WEAK_KEY; } bool RefTable::IsValueWeak() { - assert(mState); + assert(mVM); return mMode & WEAK_VALUE; } int RefTable::Ref(State& state, int idx) { - assert(mState); + assert(mVM); + assert(mVM == state.GetVM()); idx = state.AbsIndex(idx); state.GetField(LUA_REGISTRYINDEX, mName); // ref table @@ -83,10 +85,11 @@ namespace LuaBind return refID; } - void RefTable::Unref(State& state, int refID) + void RefTable::UnRef(int refID) { - assert(mState); + assert(mVM); + State state = mVM->GetMainState(); state.GetField(LUA_REGISTRYINDEX, mName); // ref table luaL_unref(state, -1, refID); state.Pop(); @@ -95,24 +98,27 @@ namespace LuaBind void RefTable::PushRefTable(State& state) { - assert(mState); + assert(mVM); + assert(mVM == state.GetVM()); lua_getfield(state, LUA_REGISTRYINDEX, mName); } void RefTable::PushRef(State& state, int refID) { - assert(mState); + assert(mVM); + assert(mVM == state.GetVM()); lua_getfield(state, LUA_REGISTRYINDEX, mName); lua_rawgeti(state, -1, refID); lua_replace(state, -2); } - void RefTable::Clear(State& state) + void RefTable::Clear() { - assert(mState); + assert(mVM); + State state = mVM->GetMainState(); lua_newtable(state); state.SetField(LUA_REGISTRYINDEX, mName); } diff --git a/Runtime/Lua/LuaBind/LuaBindRefTable.h b/Runtime/Lua/LuaBind/LuaBindRefTable.h index 3401a53..d3de7d6 100644 --- a/Runtime/Lua/LuaBind/LuaBindRefTable.h +++ b/Runtime/Lua/LuaBind/LuaBindRefTable.h @@ -7,8 +7,10 @@ namespace LuaBind { class State; + class VM; // ref table ¹ÜÀí£¬¶Ôstrong ref tableºÍweak ref tableÁ½¸ötableµÄ´úÀí¡£ + // ±£´æÔÚglobal_State.l_registry£¬ËùÒÔÊÇÐéÄâ»úϵÄËùÓÐЭ³Ì¹²ÏíµÄ class RefTable { public: @@ -19,19 +21,19 @@ namespace LuaBind WEAK_VALUE = 1 << 1 }; - RefTable(); + RefTable(LuaBind::VM* vm); ~RefTable(); - inline operator bool() { return mState; }; + inline operator bool() { return mVM; }; - void Init(State& state, cc8* name, cc8* mode = nullptr); + void Init(cc8* name, cc8* mode = nullptr); bool IsKeyWeak(); bool IsValueWeak(); // ¶Ôstack[idx]µÄʵÌåÔÚ´Ëref tableÖÐÔö¼ÓÒ»¸öÒýÓ㬲¢·µ»ØrefID int Ref(State& state, int idx); - void Unref(State& state, int refID); + void UnRef(int refID); // ½«´Ë ref table ·ÅÔÚÕ»¶¥ void PushRefTable(State& state); @@ -40,13 +42,14 @@ namespace LuaBind void PushRef(State& state, int refID); // Çå¿Õ ref table£¬±í»¹ÁôÔÚLUA_REGISTRYINDEX[mName] - void Clear(State& state); + void Clear(); private: + friend class VM; friend class State; - lua_State* mState; // ÓÃÀ´×öһЩȷÈϹ¤×÷ + VM* mVM; // ËùÊôµÄÐéÄâ»ú cc8* mName; // ref tableµÄÃû³Æ int mMode; // ref tableµÄÀàÐÍ diff --git a/Runtime/Lua/LuaBind/LuaBindState.h b/Runtime/Lua/LuaBind/LuaBindState.h index 9028583..e5b8f6c 100644 --- a/Runtime/Lua/LuaBind/LuaBindState.h +++ b/Runtime/Lua/LuaBind/LuaBindState.h @@ -27,6 +27,7 @@ namespace LuaBind // userdata // ´Óuserdataͨ¹ýgetmetatable»ñÈ¡Éϼ¶metatable¡£³ý´ËÖ®Í⻹ÓÐÒ»¸öclass table×¢²áÔÚ¶ÔÓ¦ // µÄÃû³Æ¿Õ¼äÀï¡£ + // °ÑLuaStateÀí½â³ÉÖ´ÐÐÕ» LUA_BIND_API class State { public: @@ -151,9 +152,6 @@ namespace LuaBind // ×¢²á¹¤³§£¬ÊÊÓÃÓÚÆÕͨÀ࣬ÓÐNew·½·¨ template void RegisterFactory(); - // ×¢²áµ¥Àý£¬Ã»ÓÐNew·½·¨ - template void RegisterSingleton(); - // ×¢²áö¾Ù void RegisterEnum(cc8* name, Enum* enums); @@ -315,44 +313,7 @@ namespace LuaBind TYPE::SetClassTableRef(state, -1); - SetField(top, type); - - // reset top - lua_settop(L, top); - - // ºó´¦Àí - TYPE::RegisterPostprocess(state); - } - - // ×¢²áµ¥Àý - template - void State::RegisterSingleton() - { - lua_State* L = mState; - State& state = *this; - - int top = lua_gettop(L); // namespace table - assert(lua_istable(L, top)); - - // class table. - lua_newtable(L); - TYPE::RegisterClassShared(state); - TYPE::RegisterSingletonClass(state); - TYPE::RegisterClass(state); - - TYPE::SetClassTableRef(state, -1); - - lua_pushvalue(state, -1); - lua_setfield(state, -2, "__index"); - -#if LUA_BIND_ENABLE_NATIVE_EXTEND - // .Extend() - lua_pushvalue(state, -1); // class table - lua_pushcclosure(state, TYPE::_ExtendSingleton, 1); - lua_setfield(state, -2, "Extend"); -#endif - - cc8* type = TYPE::GetSingletonName(); + // namespace[type] = class SetField(top, type); // reset top diff --git a/Runtime/Lua/LuaBind/LuaBindUtility.h b/Runtime/Lua/LuaBind/LuaBindUtility.h index ffc5099..fd39f47 100644 --- a/Runtime/Lua/LuaBind/LuaBindUtility.h +++ b/Runtime/Lua/LuaBind/LuaBindUtility.h @@ -11,24 +11,13 @@ static void RegisterClass(::State&); \ static void RegisterPostprocess(::State&); \ static const char* GetFactoryName() { return #type; };\ - static const char* GetClassName() { return #type; };\ - static bool IsClassSingleton() { return false; } + static const char* GetClassName() { return #type; }; // ×÷Ϊ»ùÀàµÄ³éÏ󹤳§Àà¿ÉÒÔʹÓô˺꣬ע²áÒ»¸öÈë¿Ú£¬ÔÚÅÉÉúÀàµÄ×¢²áº¯ÊýÖе÷Óã¬×¢²á»ùÀàµÄÕâЩ·½·¨¡£ #define LUA_BIND_DECL_ABSTRACT_FACTORY() \ static void RegisterClass(::State&);\ static void RegisterPostprocess(::State&) -// RegisterClass ×¢²áÀàµÄ·½·¨ºÍ³ÉÔ±£¬±ÈÈçö¾Ù¡¢³£Á¿µÈµ½class table GetSingletonName »ñµÃµ¥ÀýµÄÀàÃû -#define LUA_BIND_DECL_SINGLETON(type, ...) \ - friend class ::State; \ - friend class ::NativeClass; \ - static void RegisterClass(::State&); \ - static void RegisterPostprocess(::State&); \ - static const char* GetSingletonName() { return #type; }; \ - static const char* GetClassName() { return #type; }; \ - static bool IsClassSingleton() { return true; } - #define LUA_BIND_DECL_METHOD(mtd) static int mtd(lua_State* L) #define LUA_BIND_DECL_ENUM(e, under_line_index) @@ -42,7 +31,6 @@ // ÓÃÀ´×¢²áµÄºê¡£Ö®Ç°ÕâÀïÍüÁËÓÿɱäºê£¬µ¼ÖÂûÓÐluaclastable refûÓÐ×¢²á¶Ô¡£ #define LUA_BIND_REGISTER_FACTORY(state, param) state.RegisterFactory() -#define LUA_BIND_REGISTER_SINGLETON(state, param) state.RegisterSingleton() #define LUA_BIND_REGISTER_ABSTRACT_FACTORY(state, type) type::RegisterPostprocess(state) #define LUA_BIND_REGISTER_METHODS(state, ...) \ do{ \ diff --git a/Runtime/Lua/LuaBind/LuaBindVM.cpp b/Runtime/Lua/LuaBind/LuaBindVM.cpp index 268a5ed..6b39288 100644 --- a/Runtime/Lua/LuaBind/LuaBindVM.cpp +++ b/Runtime/Lua/LuaBind/LuaBindVM.cpp @@ -3,8 +3,10 @@ namespace LuaBind { + static cc8* kStrongTableName = "GAMELAB_UNIVERSAL_STRONG_REFERENCE_TABLE"; + static cc8* kWeakTableName = "GAMELAB_UNIVERSAL_WEAK_REFERENCE_TABLE"; - VM::VMap VM::VMs; // ͨ¹ýÏ̲߳éÕÒÐéÄâ»ú£¬ÎªÁË·½±ã + std::map VM::VMs; // ͨ¹ýÏ̲߳éÕÒÐéÄâ»ú£¬ÎªÁË·½±ã VM* VM::TryGetVM(global_State* gState) { @@ -12,7 +14,7 @@ namespace LuaBind if (it != VMs.end()) return it->second; else - return nullptr; + return NULL; } VM* VM::TryGetVM(lua_State* state) @@ -21,11 +23,11 @@ namespace LuaBind } VM::VM() - : mStrongRefTable() - , mWeakRefTable() + : mStrongRefTable(this) + , mWeakRefTable(this) + , mClasses() { mMainThread = luaL_newstate(); - assert(mMainThread); mGlobalState = G(mMainThread); VMs.insert(std::pair(mGlobalState, this)); @@ -42,8 +44,8 @@ namespace LuaBind { LUA_BIND_STATE(mMainThread); - mStrongRefTable.Init(state, "GAMELAB_UNIVERSAL_STRONG_REFERENCE_TABLE"); - mWeakRefTable.Init(state, "GAMELAB_UNIVERSAL_WEAK_REFERENCE_TABLE", "v"); + mStrongRefTable.Init(kStrongTableName); + mWeakRefTable.Init(kWeakTableName, "v"); } lua_State* VM::CreateThread() @@ -79,4 +81,28 @@ namespace LuaBind luaL_openlibs(mMainThread); } + int VM::RegisterClassI(State& state, int classID, int index) + { + assert(state.GetVM() == this); + assert(mClasses.count(classID) == 0); + StrongRef ref = StrongRef(this); + ref.SetRef(state, index); + auto cls = std::pair(classID, ref); + mClasses.insert(cls); + return 1; + } + + void VM::PushClassTable(State& state, int classID) + { + assert(state.GetVM() == this); + auto ref = mClasses.find(classID); + if (ref == mClasses.end()) + { + state.PushNil(); + return; + } + StrongRef cls = ref->second; + cls.PushRef(state); + } + } \ No newline at end of file diff --git a/Runtime/Lua/LuaBind/LuaBindVM.h b/Runtime/Lua/LuaBind/LuaBindVM.h index 3bfe899..37810b9 100644 --- a/Runtime/Lua/LuaBind/LuaBindVM.h +++ b/Runtime/Lua/LuaBind/LuaBindVM.h @@ -3,6 +3,7 @@ #include #include +#include #include "LuaBindRef.h" #include "LuaBindConfig.h" @@ -32,20 +33,22 @@ namespace LuaBind lua_State* CreateThread(); State GetMainState(); - RefTable& GetStrongRefTable(); + RefTable& GetStrongRefTable(); RefTable& GetWeakRefTable(); - private: + int RegisterClassI(State& state, int classID, int index); + void PushClassTable(State& state, int classID); - typedef std::map VMap; + private: + static std::map VMs; // ͨ¹ýglobal_StateË÷ÒýÐéÄâ»ú£¬ÎªÁË·½±ã - static VMap VMs; // ͨ¹ýglobal_StateË÷ÒýÐéÄâ»ú£¬ÎªÁË·½±ã + global_State* mGlobalState; // ÐéÄâ»úµÄglobal_State£¬Óɵ±Ç°ÐéÄâ»úµÄËùÓÐÏ̹߳²Ïí£¬±£´æ×¢²á±í¡¢¹ÜÀíGC + lua_State* mMainThread; // Ö÷Ïß³Ì - RefTable mStrongRefTable; // GAMELAB_UNIVERSAL_STRONG_REFERENCE_TABLE - RefTable mWeakRefTable; // GAMELAB_UNIVERSAL_WEAK_REFERENCE_TABLE + RefTable mStrongRefTable; // È«¾ÖÇ¿ÒýÓñí + RefTable mWeakRefTable; // È«¾ÖÈõÒýÓñí - global_State* mGlobalState; // ÐéÄâ»úµÄglobal_State£¬Óɵ±Ç°ÐéÄâ»úµÄËùÓÐÏ̹߳²Ïí - lua_State* mMainThread; // Ö÷Ïß³Ì + std::unordered_map mClasses; // ÀàÐÍ #if LUA_BIND_PROFILER size_t mObjectCount; // ͳ¼ÆËùÓÐÔÚ´ËÐéÄâ»úÖд´½¨µÄʵÀý diff --git a/Runtime/Lua/LuaBind/signal/bind.h b/Runtime/Lua/LuaBind/signal/bind.h new file mode 100644 index 0000000..e29896b --- /dev/null +++ b/Runtime/Lua/LuaBind/signal/bind.h @@ -0,0 +1,510 @@ +// Aseprite Base Library +// Copyright (c) 2001-2013 David Capello +// +// This file is released under the terms of the MIT license. +// Read LICENSE.txt for more information. + +#ifndef BASE_BIND_H_INCLUDED +#define BASE_BIND_H_INCLUDED +#pragma once + +// BindAdapter0_fun +template +class BindAdapter0_fun +{ + F f; +public: + BindAdapter0_fun(const F& f) : f(f) { } + + R operator()() { return f(); } + + template + R operator()(const A1& a1) { return f(); } + + template + R operator()(const A1& a1, const A2& a2) { return f(); } + + template + R operator()(const A1& a1, const A2& a2, const A3& a3) { return f(); } + + template + R operator()(const A1& a1, const A2& a2, const A3& a3, const A4& a4) { return f(); } +}; + +template +class BindAdapter0_fun +{ + F f; +public: + BindAdapter0_fun(const F& f) : f(f) { } + + void operator()() { f(); } + + template + void operator()(const A1& a1) { f(); } + + template + void operator()(const A1& a1, const A2& a2) { f(); } + + template + void operator()(const A1& a1, const A2& a2, const A3& a3) { f(); } + + template + void operator()(const A1& a1, const A2& a2, const A3& a3, const A4& a4) { f(); } +}; + +template +BindAdapter0_fun +Bind(const F& f) +{ + return BindAdapter0_fun(f); +} + +// BindAdapter0_mem +template +class BindAdapter0_mem +{ + R (T::*m)(); + T* t; +public: + template + BindAdapter0_mem(R (T::*m)(), T2* t) : m(m), t(t) { } + + R operator()() { return (t->*m)(); } + + template + R operator()(const A1& a1) { return (t->*m)(); } + + template + R operator()(const A1& a1, const A2& a2) { return (t->*m)(); } + + template + R operator()(const A1& a1, const A2& a2, const A3& a3) { return (t->*m)(); } + + template + R operator()(const A1& a1, const A2& a2, const A3& a3, const A4& a4) { return (t->*m)(); } +}; + +template +class BindAdapter0_mem +{ + void (T::*m)(); + T* t; +public: + template + BindAdapter0_mem(void (T::*m)(), T2* t) : m(m), t(t) { } + + void operator()() { (t->*m)(); } + + template + void operator()(const A1& a1) { (t->*m)(); } + + template + void operator()(const A1& a1, const A2& a2) { (t->*m)(); } + + template + void operator()(const A1& a1, const A2& a2, const A3& a3) { (t->*m)(); } + + template + void operator()(const A1& a1, const A2& a2, const A3& a3, const A4& a4) { (t->*m)(); } +}; + +template +BindAdapter0_mem +Bind(R (T::*m)(), T2* t) +{ + return BindAdapter0_mem(m, t); +} + +// BindAdapter1_fun +template +class BindAdapter1_fun +{ + F f; + X1 x1; +public: + BindAdapter1_fun(const F& f, X1 x1) : f(f), x1(x1) { } + + R operator()() { return f(x1); } + + template + R operator()(const A1& a1) { return f(x1); } + + template + R operator()(const A1& a1, const A2& a2) { return f(x1); } + + template + R operator()(const A1& a1, const A2& a2, const A3& a3) { return f(x1); } + + template + R operator()(const A1& a1, const A2& a2, const A3& a3, const A4& a4) { return f(x1); } +}; + +template +class BindAdapter1_fun +{ + F f; + X1 x1; +public: + BindAdapter1_fun(const F& f, X1 x1) : f(f), x1(x1) { } + + void operator()() { f(x1); } + + template + void operator()(const A1& a1) { f(x1); } + + template + void operator()(const A1& a1, const A2& a2) { f(x1); } + + template + void operator()(const A1& a1, const A2& a2, const A3& a3) { f(x1); } + + template + void operator()(const A1& a1, const A2& a2, const A3& a3, const A4& a4) { f(x1); } +}; + +template +BindAdapter1_fun +Bind(const F& f, X1 x1) +{ + return BindAdapter1_fun(f, x1); +} + +// BindAdapter1_mem +template +class BindAdapter1_mem +{ + R (T::*m)(B1); + T* t; + X1 x1; +public: + template + BindAdapter1_mem(R (T::*m)(B1), T2* t, X1 x1) : m(m), t(t), x1(x1) { } + + R operator()() { return (t->*m)(x1); } + + template + R operator()(const A1& a1) { return (t->*m)(x1); } + + template + R operator()(const A1& a1, const A2& a2) { return (t->*m)(x1); } + + template + R operator()(const A1& a1, const A2& a2, const A3& a3) { return (t->*m)(x1); } + + template + R operator()(const A1& a1, const A2& a2, const A3& a3, const A4& a4) { return (t->*m)(x1); } +}; + +template +class BindAdapter1_mem +{ + void (T::*m)(B1); + T* t; + X1 x1; +public: + template + BindAdapter1_mem(void (T::*m)(B1), T2* t, X1 x1) : m(m), t(t), x1(x1) { } + + void operator()() { (t->*m)(x1); } + + template + void operator()(const A1& a1) { (t->*m)(x1); } + + template + void operator()(const A1& a1, const A2& a2) { (t->*m)(x1); } + + template + void operator()(const A1& a1, const A2& a2, const A3& a3) { (t->*m)(x1); } + + template + void operator()(const A1& a1, const A2& a2, const A3& a3, const A4& a4) { (t->*m)(x1); } +}; + +template +BindAdapter1_mem +Bind(R (T::*m)(B1), T2* t, X1 x1) +{ + return BindAdapter1_mem(m, t, x1); +} + +// BindAdapter2_fun +template +class BindAdapter2_fun +{ + F f; + X1 x1; + X2 x2; +public: + BindAdapter2_fun(const F& f, X1 x1, X2 x2) : f(f), x1(x1), x2(x2) { } + + R operator()() { return f(x1, x2); } + + template + R operator()(const A1& a1) { return f(x1, x2); } + + template + R operator()(const A1& a1, const A2& a2) { return f(x1, x2); } + + template + R operator()(const A1& a1, const A2& a2, const A3& a3) { return f(x1, x2); } + + template + R operator()(const A1& a1, const A2& a2, const A3& a3, const A4& a4) { return f(x1, x2); } +}; + +template +class BindAdapter2_fun +{ + F f; + X1 x1; + X2 x2; +public: + BindAdapter2_fun(const F& f, X1 x1, X2 x2) : f(f), x1(x1), x2(x2) { } + + void operator()() { f(x1, x2); } + + template + void operator()(const A1& a1) { f(x1, x2); } + + template + void operator()(const A1& a1, const A2& a2) { f(x1, x2); } + + template + void operator()(const A1& a1, const A2& a2, const A3& a3) { f(x1, x2); } + + template + void operator()(const A1& a1, const A2& a2, const A3& a3, const A4& a4) { f(x1, x2); } +}; + +template +BindAdapter2_fun +Bind(const F& f, X1 x1, X2 x2) +{ + return BindAdapter2_fun(f, x1, x2); +} + +// BindAdapter2_mem +template +class BindAdapter2_mem +{ + R (T::*m)(B1, B2); + T* t; + X1 x1; + X2 x2; +public: + template + BindAdapter2_mem(R (T::*m)(B1, B2), T2* t, X1 x1, X2 x2) : m(m), t(t), x1(x1), x2(x2) { } + + R operator()() { return (t->*m)(x1, x2); } + + template + R operator()(const A1& a1) { return (t->*m)(x1, x2); } + + template + R operator()(const A1& a1, const A2& a2) { return (t->*m)(x1, x2); } + + template + R operator()(const A1& a1, const A2& a2, const A3& a3) { return (t->*m)(x1, x2); } + + template + R operator()(const A1& a1, const A2& a2, const A3& a3, const A4& a4) { return (t->*m)(x1, x2); } +}; + +template +class BindAdapter2_mem +{ + void (T::*m)(B1, B2); + T* t; + X1 x1; + X2 x2; +public: + template + BindAdapter2_mem(void (T::*m)(B1, B2), T2* t, X1 x1, X2 x2) : m(m), t(t), x1(x1), x2(x2) { } + + void operator()() { (t->*m)(x1, x2); } + + template + void operator()(const A1& a1) { (t->*m)(x1, x2); } + + template + void operator()(const A1& a1, const A2& a2) { (t->*m)(x1, x2); } + + template + void operator()(const A1& a1, const A2& a2, const A3& a3) { (t->*m)(x1, x2); } + + template + void operator()(const A1& a1, const A2& a2, const A3& a3, const A4& a4) { (t->*m)(x1, x2); } +}; + +template +BindAdapter2_mem +Bind(R (T::*m)(B1, B2), T2* t, X1 x1, X2 x2) +{ + return BindAdapter2_mem(m, t, x1, x2); +} + +// BindAdapter3_fun +template +class BindAdapter3_fun +{ + F f; + X1 x1; + X2 x2; + X3 x3; +public: + BindAdapter3_fun(const F& f, X1 x1, X2 x2, X3 x3) : f(f), x1(x1), x2(x2), x3(x3) { } + + R operator()() { return f(x1, x2, x3); } + + template + R operator()(const A1& a1) { return f(x1, x2, x3); } + + template + R operator()(const A1& a1, const A2& a2) { return f(x1, x2, x3); } + + template + R operator()(const A1& a1, const A2& a2, const A3& a3) { return f(x1, x2, x3); } + + template + R operator()(const A1& a1, const A2& a2, const A3& a3, const A4& a4) { return f(x1, x2, x3); } +}; + +template +class BindAdapter3_fun +{ + F f; + X1 x1; + X2 x2; + X3 x3; +public: + BindAdapter3_fun(const F& f, X1 x1, X2 x2, X3 x3) : f(f), x1(x1), x2(x2), x3(x3) { } + + void operator()() { f(x1, x2, x3); } + + template + void operator()(const A1& a1) { f(x1, x2, x3); } + + template + void operator()(const A1& a1, const A2& a2) { f(x1, x2, x3); } + + template + void operator()(const A1& a1, const A2& a2, const A3& a3) { f(x1, x2, x3); } + + template + void operator()(const A1& a1, const A2& a2, const A3& a3, const A4& a4) { f(x1, x2, x3); } +}; + +template +BindAdapter3_fun +Bind(const F& f, X1 x1, X2 x2, X3 x3) +{ + return BindAdapter3_fun(f, x1, x2, x3); +} + +// BindAdapter3_mem +template +class BindAdapter3_mem +{ + R (T::*m)(B1, B2, B3); + T* t; + X1 x1; + X2 x2; + X3 x3; +public: + template + BindAdapter3_mem(R (T::*m)(B1, B2, B3), T2* t, X1 x1, X2 x2, X3 x3) : m(m), t(t), x1(x1), x2(x2), x3(x3) { } + + R operator()() { return (t->*m)(x1, x2, x3); } + + template + R operator()(const A1& a1) { return (t->*m)(x1, x2, x3); } + + template + R operator()(const A1& a1, const A2& a2) { return (t->*m)(x1, x2, x3); } + + template + R operator()(const A1& a1, const A2& a2, const A3& a3) { return (t->*m)(x1, x2, x3); } + + template + R operator()(const A1& a1, const A2& a2, const A3& a3, const A4& a4) { return (t->*m)(x1, x2, x3); } +}; + +template +class BindAdapter3_mem +{ + void (T::*m)(B1, B2, B3); + T* t; + X1 x1; + X2 x2; + X3 x3; +public: + template + BindAdapter3_mem(void (T::*m)(B1, B2, B3), T2* t, X1 x1, X2 x2) : m(m), t(t), x1(x1), x2(x2) { } + + void operator()() { (t->*m)(x1, x2, x3); } + + template + void operator()(const A1& a1) { (t->*m)(x1, x2, x3); } + + template + void operator()(const A1& a1, const A2& a2) { (t->*m)(x1, x2, x3); } + + template + void operator()(const A1& a1, const A2& a2, const A3& a3) { (t->*m)(x1, x2, x3); } + + template + void operator()(const A1& a1, const A2& a2, const A3& a3, const A4& a4) { (t->*m)(x1, x2, x3); } +}; + +template +BindAdapter3_mem +Bind(R (T::*m)(B1, B2, B3), T2* t, X1 x1, X2 x2) +{ + return BindAdapter3_mem(m, t, x1, x2); +} + +// Helper class to holds references as pointers (to avoid copying the +// original object). +template +class RefWrapper +{ + T* ptr; +public: + RefWrapper(T& ref) : ptr(&ref) { } + operator T&() const { return *ptr; } +}; + +// Creates RefWrappers, useful to wrap arguments that have to be +// passed as a reference when you use Bind. +template +RefWrapper Ref(T& ref) +{ + return RefWrapper(ref); +} + +#endif diff --git a/Runtime/Lua/LuaBind/signal/remove_from_container.h b/Runtime/Lua/LuaBind/signal/remove_from_container.h new file mode 100644 index 0000000..9fdc442 --- /dev/null +++ b/Runtime/Lua/LuaBind/signal/remove_from_container.h @@ -0,0 +1,32 @@ +// Aseprite Base Library +// Copyright (c) 2001-2013 David Capello +// +// This file is released under the terms of the MIT license. +// Read LICENSE.txt for more information. + +#ifndef BASE_REMOVE_FROM_CONTAINER_H_INCLUDED +#define BASE_REMOVE_FROM_CONTAINER_H_INCLUDED +#pragma once + +namespace base { + +// Removes all ocurrences of the specified element from the STL container. +template +void remove_from_container(ContainerType& container, + typename ContainerType::const_reference element) +{ + for (typename ContainerType::iterator + it = container.begin(), + end = container.end(); it != end; ) { + if (*it == element) { + it = container.erase(it); + end = container.end(); + } + else + ++it; + } +} + +} + +#endif diff --git a/Runtime/Lua/LuaBind/signal/signal.h b/Runtime/Lua/LuaBind/signal/signal.h new file mode 100644 index 0000000..97882c6 --- /dev/null +++ b/Runtime/Lua/LuaBind/signal/signal.h @@ -0,0 +1,451 @@ +// Aseprite Base Library +// Copyright (c) 2001-2013 David Capello +// +// This file is released under the terms of the MIT license. +// Read LICENSE.txt for more information. + +#ifndef BASE_SIGNAL_H_INCLUDED +#define BASE_SIGNAL_H_INCLUDED +#pragma once + +//#include "base/slot.h" +//#include "base/remove_from_container.h" + +#include "./slot.h" +#include "./remove_from_container.h" + +#include + +// Signal0_base - Base class to delegate responsibility to +// functions of zero arguments. +template +class Signal0_base +{ +public: + typedef R ReturnType; + typedef Slot0 SlotType; + typedef std::vector SlotList; + +protected: + SlotList m_slots; + +public: + Signal0_base() { } + Signal0_base(const Signal0_base& s) + { + copy(s); + } + ~Signal0_base() + { + disconnectAll(); + } + + SlotType* addSlot(SlotType* slot) + { + m_slots.push_back(slot); + return slot; + } + + template + SlotType* connect(const F& f) + { + return addSlot(new Slot0_fun(f)); + } + + template + SlotType* connect(R (T::*m)(), T* t) + { + return addSlot(new Slot0_mem(m, t)); + } + + const SlotList& getSlots() const + { + return m_slots; + } + + void disconnect(SlotType* slot) + { + base::remove_from_container(m_slots, slot); + } + + void disconnectAll() + { + typename SlotList::iterator end = m_slots.end(); + for (typename SlotList::iterator + it = m_slots.begin(); it != end; ++it) + delete *it; + m_slots.clear(); + } + + bool empty() const + { + return m_slots.empty(); + } + + Signal0_base& operator=(const Signal0_base& s) { + copy(s); + return *this; + } + +private: + + void copy(const Signal0_base& s) + { + typename SlotList::const_iterator end = s.m_slots.end(); + for (typename SlotList::const_iterator + it = s.m_slots.begin(); it != end; ++it) { + m_slots.push_back((*it)->clone()); + } + } + +}; + +// Signal0 +template +class Signal0 : public Signal0_base +{ +public: + Signal0() { } + + Signal0(const Signal0& s) + : Signal0_base(s) { } + + R operator()(R default_result = R()) + { + R result(default_result); + typename Signal0_base::SlotList::iterator end = Signal0_base::m_slots.end(); + for (typename Signal0_base::SlotList::iterator + it = Signal0_base::m_slots.begin(); it != end; ++it) { + typename Signal0_base::SlotType* slot = *it; + result = (*slot)(); + } + return result; + } + + template + R operator()(R default_result, const Merger& m) + { + R result(default_result); + Merger merger(m); + typename Signal0_base::SlotList::iterator end = Signal0_base::m_slots.end(); + for (typename Signal0_base::SlotList::iterator + it = Signal0_base::m_slots.begin(); it != end; ++it) { + typename Signal0_base::SlotType* slot = *it; + result = merger(result, (*slot)()); + } + return result; + } + +}; + +// Signal0 +template<> +class Signal0 : public Signal0_base +{ +public: + Signal0() { } + + Signal0(const Signal0& s) + : Signal0_base(s) { } + + void operator()() + { + SlotList::iterator end = m_slots.end(); + for (SlotList::iterator + it = m_slots.begin(); it != end; ++it) { + SlotType* slot = *it; + (*slot)(); + } + } + +}; + +// Signal1_base - Base class to delegate responsibility to +// functions of one argument. +template +class Signal1_base +{ +public: + typedef R ReturnType; + typedef Slot1 SlotType; + typedef std::vector SlotList; + +protected: + SlotList m_slots; + +public: + Signal1_base() { } + Signal1_base(const Signal1_base& s) + { + copy(s); + } + ~Signal1_base() + { + disconnectAll(); + } + + SlotType* addSlot(SlotType* slot) + { + m_slots.push_back(slot); + return slot; + } + + template + SlotType* connect(const F& f) + { + return addSlot(new Slot1_fun(f)); + } + + template + SlotType* connect(R (T::*m)(A1), T* t) + { + return addSlot(new Slot1_mem(m, t)); + } + + const SlotList& getSlots() const + { + return m_slots; + } + + void disconnect(SlotType* slot) + { + base::remove_from_container(m_slots, slot); + } + + void disconnectAll() + { + typename SlotList::iterator end = m_slots.end(); + for (typename SlotList::iterator + it = m_slots.begin(); it != end; ++it) + delete *it; + m_slots.clear(); + } + + bool empty() const + { + return m_slots.empty(); + } + + Signal1_base& operator=(const Signal1_base& s) { + copy(s); + return *this; + } + +private: + + void copy(const Signal1_base& s) + { + typename SlotList::const_iterator end = s.m_slots.end(); + for (typename SlotList::const_iterator + it = s.m_slots.begin(); it != end; ++it) { + m_slots.push_back((*it)->clone()); + } + } + +}; + +// Signal1 +template +class Signal1 : public Signal1_base +{ +public: + Signal1() { } + + Signal1(const Signal1& s) + : Signal1_base(s) { } + + R operator()(A1 a1, R default_result = R()) + { + R result(default_result); + typename Signal1_base::SlotList::iterator end = Signal1_base::m_slots.end(); + for (typename Signal1_base::SlotList::iterator + it = Signal1_base::m_slots.begin(); it != end; ++it) { + typename Signal1_base::SlotType* slot = *it; + result = (*slot)(a1); + } + return result; + } + + template + R operator()(A1 a1, R default_result, const Merger& m) + { + R result(default_result); + Merger merger(m); + typename Signal1_base::SlotList::iterator end = Signal1_base::m_slots.end(); + for (typename Signal1_base::SlotList::iterator + it = Signal1_base::m_slots.begin(); it != end; ++it) { + typename Signal1_base::SlotType* slot = *it; + result = merger(result, (*slot)(a1)); + } + return result; + } + +}; + +// Signal1 +template +class Signal1 : public Signal1_base +{ +public: + Signal1() { } + + Signal1(const Signal1& s) + : Signal1_base(s) { } + + void operator()(A1 a1) + { + typename Signal1_base::SlotList::iterator end = Signal1_base::m_slots.end(); + for (typename Signal1_base::SlotList::iterator + it = Signal1_base::m_slots.begin(); it != end; ++it) { + typename Signal1_base::SlotType* slot = *it; + (*slot)(a1); + } + } + +}; + +// Signal2_base - Base class to delegate responsibility to +// functions of two arguments. +template +class Signal2_base +{ +public: + typedef R ReturnType; + typedef Slot2 SlotType; + typedef std::vector SlotList; + +protected: + SlotList m_slots; + +public: + Signal2_base() { } + Signal2_base(const Signal2_base& s) + { + copy(s); + } + ~Signal2_base() + { + disconnectAll(); + } + + SlotType* addSlot(SlotType* slot) + { + m_slots.push_back(slot); + return slot; + } + + template + SlotType* connect(const F& f) + { + return addSlot(new Slot2_fun(f)); + } + + template + SlotType* connect(R (T::*m)(A1, A2), T* t) + { + return addSlot(new Slot2_mem(m, t)); + } + + const SlotList& getSlots() const + { + return m_slots; + } + + void disconnect(SlotType* slot) + { + base::remove_from_container(m_slots, slot); + } + + void disconnectAll() + { + typename SlotList::iterator end = m_slots.end(); + for (typename SlotList::iterator + it = m_slots.begin(); it != end; ++it) + delete *it; + m_slots.clear(); + } + + bool empty() const + { + return m_slots.empty(); + } + + Signal2_base& operator=(const Signal2_base& s) { + copy(s); + return *this; + } + +private: + + void copy(const Signal2_base& s) + { + typename SlotList::const_iterator end = s.m_slots.end(); + for (typename SlotList::const_iterator + it = s.m_slots.begin(); it != end; ++it) { + m_slots.push_back((*it)->clone()); + } + } + +}; + +// Signal2 +template +class Signal2 : public Signal2_base +{ +public: + Signal2() { } + + Signal2(const Signal2& s) + : Signal2_base(s) { } + + R operator()(A1 a1, A2 a2, R default_result = R()) + { + R result(default_result); + typename Signal2_base::SlotList::iterator end = Signal2_base::m_slots.end(); + for (typename Signal2_base::SlotList::iterator + it = Signal2_base::m_slots.begin(); it != end; ++it) { + typename Signal2_base::SlotType* slot = *it; + result = (*slot)(a1, a2); + } + return result; + } + + template + R operator()(A1 a1, A2 a2, R default_result, const Merger& m) + { + R result(default_result); + Merger merger(m); + typename Signal2_base::SlotList::iterator end = Signal2_base::m_slots.end(); + for (typename Signal2_base::SlotList::iterator + it = Signal2_base::m_slots.begin(); it != end; ++it) { + typename Signal2_base::SlotType* slot = *it; + result = merger(result, (*slot)(a1, a2)); + } + return result; + } + +}; + +// Signal2 +template +class Signal2 : public Signal2_base +{ +public: + Signal2() { } + + Signal2(const Signal2& s) + : Signal2_base(s) { } + + void operator()(A1 a1, A2 a2) + { + typename Signal2_base::SlotList::iterator end = Signal2_base::m_slots.end(); + for (typename Signal2_base::SlotList::iterator + it = Signal2_base::m_slots.begin(); it != end; ++it) { + typename Signal2_base::SlotType* slot = *it; + (*slot)(a1, a2); + } + } + +}; + +#endif diff --git a/Runtime/Lua/LuaBind/signal/slot.h b/Runtime/Lua/LuaBind/signal/slot.h new file mode 100644 index 0000000..226d382 --- /dev/null +++ b/Runtime/Lua/LuaBind/signal/slot.h @@ -0,0 +1,203 @@ +// Aseprite Base Library +// Copyright (c) 2001-2013 David Capello +// +// This file is released under the terms of the MIT license. +// Read LICENSE.txt for more information. + +#ifndef BASE_SLOT_H_INCLUDED +#define BASE_SLOT_H_INCLUDED +#pragma once + +// Slot0 - Base class for delegates of zero arguments. +template +class Slot0 +{ +public: + Slot0() { } + Slot0(const Slot0& s) { (void)s; } + virtual ~Slot0() { } + virtual R operator()() = 0; + virtual Slot0* clone() const = 0; +}; + +// Slot0_fun - hold a F instance and use the function call operator +template +class Slot0_fun : public Slot0 +{ + F f; +public: + Slot0_fun(const F& f) : f(f) { } + Slot0_fun(const Slot0_fun& s) : Slot0(s), f(s.f) { } + ~Slot0_fun() { } + R operator()() { return f(); } + Slot0_fun* clone() const { return new Slot0_fun(*this); } +}; + +template +class Slot0_fun : public Slot0 +{ + F f; +public: + Slot0_fun(const F& f) : f(f) { } + Slot0_fun(const Slot0_fun& s) : Slot0(s), f(s.f) { } + ~Slot0_fun() { } + void operator()() { f(); } + Slot0_fun* clone() const { return new Slot0_fun(*this); } +}; + +// Slot0_mem - pointer to a member function of the T class +template +class Slot0_mem : public Slot0 +{ + R (T::*m)(); + T* t; +public: + Slot0_mem(R (T::*m)(), T* t) : m(m), t(t) { } + Slot0_mem(const Slot0_mem& s) : Slot0(s), m(s.m), t(s.t) { } + ~Slot0_mem() { } + R operator()() { return (t->*m)(); } + Slot0_mem* clone() const { return new Slot0_mem(*this); } +}; + +template +class Slot0_mem : public Slot0 +{ + void (T::*m)(); + T* t; +public: + Slot0_mem(void (T::*m)(), T* t) : m(m), t(t) { } + Slot0_mem(const Slot0_mem& s) : Slot0(s), m(s.m), t(s.t) { } + ~Slot0_mem() { } + void operator()() { (t->*m)(); } + Slot0_mem* clone() const { return new Slot0_mem(*this); } +}; + +// Slot1 - Base class for delegates of one argument. +template +class Slot1 +{ +public: + Slot1() { } + Slot1(const Slot1& s) { (void)s; } + virtual ~Slot1() { } + virtual R operator()(A1 a1) = 0; + virtual Slot1* clone() const = 0; +}; + +// Slot1_fun - hold a F instance and use the function call operator +template +class Slot1_fun : public Slot1 +{ + F f; +public: + Slot1_fun(const F& f) : f(f) { } + Slot1_fun(const Slot1_fun& s) : Slot1(s), f(s.f) { } + ~Slot1_fun() { } + R operator()(A1 a1) { return f(a1); } + Slot1_fun* clone() const { return new Slot1_fun(*this); } +}; + +template +class Slot1_fun : public Slot1 +{ + F f; +public: + Slot1_fun(const F& f) : f(f) { } + Slot1_fun(const Slot1_fun& s) : Slot1(s), f(s.f) { } + ~Slot1_fun() { } + void operator()(A1 a1) { f(a1); } + Slot1_fun* clone() const { return new Slot1_fun(*this); } +}; + +// Slot1_mem - pointer to a member function of the T class +template +class Slot1_mem : public Slot1 +{ + R (T::*m)(A1); + T* t; +public: + Slot1_mem(R (T::*m)(A1), T* t) : m(m), t(t) { } + Slot1_mem(const Slot1_mem& s) : Slot1(s), m(s.m), t(s.t) { } + ~Slot1_mem() { } + R operator()(A1 a1) { return (t->*m)(a1); } + Slot1_mem* clone() const { return new Slot1_mem(*this); } +}; + +template +class Slot1_mem : public Slot1 +{ + void (T::*m)(A1); + T* t; +public: + Slot1_mem(void (T::*m)(A1), T* t) : m(m), t(t) { } + Slot1_mem(const Slot1_mem& s) : Slot1(s), m(s.m), t(s.t) { } + ~Slot1_mem() { } + void operator()(A1 a1) { (t->*m)(a1); } + Slot1_mem* clone() const { return new Slot1_mem(*this); } +}; + +// Slot2 - Base class for delegates of two arguments. +template +class Slot2 +{ +public: + Slot2() { } + Slot2(const Slot2& s) { (void)s; } + virtual ~Slot2() { } + virtual R operator()(A1 a1, A2 a2) = 0; + virtual Slot2* clone() const = 0; +}; + +// Slot2_fun - hold a F instance and use the function call operator +template +class Slot2_fun : public Slot2 +{ + F f; +public: + Slot2_fun(const F& f) : f(f) { } + Slot2_fun(const Slot2_fun& s) : Slot2(s), f(s.f) { } + ~Slot2_fun() { } + R operator()(A1 a1, A2 a2) { return f(a1, a2); } + Slot2_fun* clone() const { return new Slot2_fun(*this); } +}; + +template +class Slot2_fun : public Slot2 +{ + F f; +public: + Slot2_fun(const F& f) : f(f) { } + Slot2_fun(const Slot2_fun& s) : Slot2(s), f(s.f) { } + ~Slot2_fun() { } + void operator()(A1 a1, A2 a2) { f(a1, a2); } + Slot2_fun* clone() const { return new Slot2_fun(*this); } +}; + +// Slot2_mem - pointer to a member function of the T class +template +class Slot2_mem : public Slot2 +{ + R (T::*m)(A1, A2); + T* t; +public: + Slot2_mem(R (T::*m)(A1, A2), T* t) : m(m), t(t) { } + Slot2_mem(const Slot2_mem& s) : Slot2(s), m(s.m), t(s.t) { } + ~Slot2_mem() { } + R operator()(A1 a1, A2 a2) { return (t->*m)(a1, a2); } + Slot2_mem* clone() const { return new Slot2_mem(*this); } +}; + +template +class Slot2_mem : public Slot2 +{ + void (T::*m)(A1, A2); + T* t; +public: + Slot2_mem(void (T::*m)(A1, A2), T* t) : m(m), t(t) { } + Slot2_mem(const Slot2_mem& s) : Slot2(s), m(s.m), t(s.t) { } + ~Slot2_mem() { } + void operator()(A1 a1, A2 a2) { return (t->*m)(a1, a2); } + Slot2_mem* clone() const { return new Slot2_mem(*this); } +}; + +#endif -- cgit v1.1-26-g67d0