From 45328cbadd8a946c19a77301f218efbf650e2f28 Mon Sep 17 00:00:00 2001 From: chai Date: Mon, 18 Oct 2021 19:56:41 +0800 Subject: *misc --- .../\345\233\276\347\211\207/1599987193.png" | Bin 0 -> 3913 bytes .../\345\233\276\347\211\207/1599987443.png" | Bin 0 -> 6425 bytes .../\345\233\276\347\211\207/1600091210.png" | Bin 0 -> 2627 bytes .../\345\233\276\347\211\207/1600136270.png" | Bin 0 -> 2223 bytes .../gamelab_full_logo_small-2.png" | Bin 0 -> 2604 bytes .../gamelab_full_logo_small.png" | Bin 0 -> 3060 bytes "Documents/\350\256\276\350\256\241.xlsx" | Bin 0 -> 9144 bytes Editor/EditorApplication.cpp | 41 + Editor/EditorApplication.h | 31 + Editor/EditorMain.cpp | 48 +- Editor/GUI/ContainnerWindow.cpp | 11 + Editor/GUI/EditorWindows.h | 24 +- Editor/GUI/GUIWindow.cpp | 14 +- Editor/GUI/WindowUtil.cpp | 2 +- Editor/Graphics/Graphics.cpp | 3 + Editor/Graphics/Graphics.h | 3 + Editor/Scripting/Editor/Editor.bind.cpp | 17 + Editor/Scripting/Editor/EditorApplication.bind.cpp | 47 ++ .../Scripting/EditorGUI/ContainerWindow.bind.cpp | 50 +- Editor/Scripting/EditorGUI/EditorGUI.bind.cpp | 3 +- Editor/Scripting/EditorGUI/GUIWindow.bind.cpp | 63 ++ Editor/Scripting/EditorScripting.cpp | 4 +- Editor/Scripting/EditorScripting.h | 2 +- Projects/VisualStudio/Editor/Editor.vcxproj | 490 +++++------ .../VisualStudio/Editor/Editor.vcxproj.filters | 665 +++++++-------- Projects/VisualStudio/Editor/Editor.vcxproj.user | 15 +- Resources/Scripts/Editor/ProjectWindow.lua | 18 + Resources/Scripts/EditorApplication.lua | 26 +- Resources/Scripts/Utils/Utils.lua | 4 + Runtime/Lua/LuaBind/LuaBind.h | 18 + Runtime/Lua/LuaBind/LuaBindCFunctions.cpp | 19 + Runtime/Lua/LuaBind/LuaBindCFunctions.h | 38 + Runtime/Lua/LuaBind/LuaBindClass.cpp | 243 ++++++ Runtime/Lua/LuaBind/LuaBindClass.hpp | 208 +++++ Runtime/Lua/LuaBind/LuaBindClass.inc | 632 +++++++++++++++ Runtime/Lua/LuaBind/LuaBindConfig.h | 65 ++ Runtime/Lua/LuaBind/LuaBindEnum.cpp | 67 ++ Runtime/Lua/LuaBind/LuaBindEnum.h | 39 + Runtime/Lua/LuaBind/LuaBindGlobalState.h | 7 + Runtime/Lua/LuaBind/LuaBindInternal.h | 12 + Runtime/Lua/LuaBind/LuaBindMemberRef.cpp | 16 + Runtime/Lua/LuaBind/LuaBindMemberRef.h | 27 + Runtime/Lua/LuaBind/LuaBindRef.cpp | 72 ++ Runtime/Lua/LuaBind/LuaBindRef.h | 62 ++ Runtime/Lua/LuaBind/LuaBindRefTable.cpp | 120 +++ Runtime/Lua/LuaBind/LuaBindRefTable.h | 67 ++ Runtime/Lua/LuaBind/LuaBindState.cpp | 893 +++++++++++++++++++++ Runtime/Lua/LuaBind/LuaBindState.h | 266 ++++++ Runtime/Lua/LuaBind/LuaBindState.inc | 180 +++++ Runtime/Lua/LuaBind/LuaBindUtility.h | 69 ++ Runtime/Lua/LuaBind/LuaBindVM.cpp | 82 ++ Runtime/Lua/LuaBind/LuaBindVM.h | 58 ++ Runtime/Lua/LuaBind/LuaBindWatchDog.cpp | 0 Runtime/Lua/LuaBind/LuaBindWatchDog.h | 33 + Runtime/Lua/LuaHelper.cpp | 23 + Runtime/Lua/LuaHelper.h | 10 + Runtime/LuaBind/LuaBind.h | 18 - Runtime/LuaBind/LuaBindCFunctions.cpp | 19 - Runtime/LuaBind/LuaBindCFunctions.h | 38 - Runtime/LuaBind/LuaBindClass.cpp | 243 ------ Runtime/LuaBind/LuaBindClass.hpp | 207 ----- Runtime/LuaBind/LuaBindClass.inc | 637 --------------- Runtime/LuaBind/LuaBindConfig.h | 66 -- Runtime/LuaBind/LuaBindEnum.cpp | 67 -- Runtime/LuaBind/LuaBindEnum.h | 39 - Runtime/LuaBind/LuaBindGlobalState.h | 7 - Runtime/LuaBind/LuaBindInternal.h | 12 - Runtime/LuaBind/LuaBindMemberRef.cpp | 16 - Runtime/LuaBind/LuaBindMemberRef.h | 27 - Runtime/LuaBind/LuaBindRef.cpp | 72 -- Runtime/LuaBind/LuaBindRef.h | 62 -- Runtime/LuaBind/LuaBindRefTable.cpp | 120 --- Runtime/LuaBind/LuaBindRefTable.h | 67 -- Runtime/LuaBind/LuaBindState.cpp | 893 --------------------- Runtime/LuaBind/LuaBindState.h | 266 ------ Runtime/LuaBind/LuaBindState.inc | 180 ----- Runtime/LuaBind/LuaBindUtility.h | 66 -- Runtime/LuaBind/LuaBindVM.cpp | 82 -- Runtime/LuaBind/LuaBindVM.h | 58 -- Runtime/LuaBind/LuaBindWatchDog.cpp | 0 Runtime/LuaBind/LuaBindWatchDog.h | 33 - Runtime/Scripting/GL/GL.bind.cpp | 2 +- 82 files changed, 4268 insertions(+), 3936 deletions(-) create mode 100644 "Documents/\345\233\276\347\211\207/1599987193.png" create mode 100644 "Documents/\345\233\276\347\211\207/1599987443.png" create mode 100644 "Documents/\345\233\276\347\211\207/1600091210.png" create mode 100644 "Documents/\345\233\276\347\211\207/1600136270.png" create mode 100644 "Documents/\345\233\276\347\211\207/gamelab_full_logo_small-2.png" create mode 100644 "Documents/\345\233\276\347\211\207/gamelab_full_logo_small.png" create mode 100644 "Documents/\350\256\276\350\256\241.xlsx" create mode 100644 Editor/EditorApplication.cpp create mode 100644 Editor/EditorApplication.h create mode 100644 Editor/Graphics/Graphics.cpp create mode 100644 Editor/Graphics/Graphics.h create mode 100644 Resources/Scripts/Editor/ProjectWindow.lua create mode 100644 Resources/Scripts/Utils/Utils.lua create mode 100644 Runtime/Lua/LuaBind/LuaBind.h create mode 100644 Runtime/Lua/LuaBind/LuaBindCFunctions.cpp create mode 100644 Runtime/Lua/LuaBind/LuaBindCFunctions.h create mode 100644 Runtime/Lua/LuaBind/LuaBindClass.cpp create mode 100644 Runtime/Lua/LuaBind/LuaBindClass.hpp create mode 100644 Runtime/Lua/LuaBind/LuaBindClass.inc create mode 100644 Runtime/Lua/LuaBind/LuaBindConfig.h create mode 100644 Runtime/Lua/LuaBind/LuaBindEnum.cpp create mode 100644 Runtime/Lua/LuaBind/LuaBindEnum.h create mode 100644 Runtime/Lua/LuaBind/LuaBindGlobalState.h create mode 100644 Runtime/Lua/LuaBind/LuaBindInternal.h create mode 100644 Runtime/Lua/LuaBind/LuaBindMemberRef.cpp create mode 100644 Runtime/Lua/LuaBind/LuaBindMemberRef.h create mode 100644 Runtime/Lua/LuaBind/LuaBindRef.cpp create mode 100644 Runtime/Lua/LuaBind/LuaBindRef.h create mode 100644 Runtime/Lua/LuaBind/LuaBindRefTable.cpp create mode 100644 Runtime/Lua/LuaBind/LuaBindRefTable.h create mode 100644 Runtime/Lua/LuaBind/LuaBindState.cpp create mode 100644 Runtime/Lua/LuaBind/LuaBindState.h create mode 100644 Runtime/Lua/LuaBind/LuaBindState.inc create mode 100644 Runtime/Lua/LuaBind/LuaBindUtility.h create mode 100644 Runtime/Lua/LuaBind/LuaBindVM.cpp create mode 100644 Runtime/Lua/LuaBind/LuaBindVM.h create mode 100644 Runtime/Lua/LuaBind/LuaBindWatchDog.cpp create mode 100644 Runtime/Lua/LuaBind/LuaBindWatchDog.h create mode 100644 Runtime/Lua/LuaHelper.cpp create mode 100644 Runtime/Lua/LuaHelper.h delete mode 100644 Runtime/LuaBind/LuaBind.h delete mode 100644 Runtime/LuaBind/LuaBindCFunctions.cpp delete mode 100644 Runtime/LuaBind/LuaBindCFunctions.h delete mode 100644 Runtime/LuaBind/LuaBindClass.cpp delete mode 100644 Runtime/LuaBind/LuaBindClass.hpp delete mode 100644 Runtime/LuaBind/LuaBindClass.inc delete mode 100644 Runtime/LuaBind/LuaBindConfig.h delete mode 100644 Runtime/LuaBind/LuaBindEnum.cpp delete mode 100644 Runtime/LuaBind/LuaBindEnum.h delete mode 100644 Runtime/LuaBind/LuaBindGlobalState.h delete mode 100644 Runtime/LuaBind/LuaBindInternal.h delete mode 100644 Runtime/LuaBind/LuaBindMemberRef.cpp delete mode 100644 Runtime/LuaBind/LuaBindMemberRef.h delete mode 100644 Runtime/LuaBind/LuaBindRef.cpp delete mode 100644 Runtime/LuaBind/LuaBindRef.h delete mode 100644 Runtime/LuaBind/LuaBindRefTable.cpp delete mode 100644 Runtime/LuaBind/LuaBindRefTable.h delete mode 100644 Runtime/LuaBind/LuaBindState.cpp delete mode 100644 Runtime/LuaBind/LuaBindState.h delete mode 100644 Runtime/LuaBind/LuaBindState.inc delete mode 100644 Runtime/LuaBind/LuaBindUtility.h delete mode 100644 Runtime/LuaBind/LuaBindVM.cpp delete mode 100644 Runtime/LuaBind/LuaBindVM.h delete mode 100644 Runtime/LuaBind/LuaBindWatchDog.cpp delete mode 100644 Runtime/LuaBind/LuaBindWatchDog.h diff --git "a/Documents/\345\233\276\347\211\207/1599987193.png" "b/Documents/\345\233\276\347\211\207/1599987193.png" new file mode 100644 index 0000000..cf03096 Binary files /dev/null and "b/Documents/\345\233\276\347\211\207/1599987193.png" differ diff --git "a/Documents/\345\233\276\347\211\207/1599987443.png" "b/Documents/\345\233\276\347\211\207/1599987443.png" new file mode 100644 index 0000000..0124a7a Binary files /dev/null and "b/Documents/\345\233\276\347\211\207/1599987443.png" differ diff --git "a/Documents/\345\233\276\347\211\207/1600091210.png" "b/Documents/\345\233\276\347\211\207/1600091210.png" new file mode 100644 index 0000000..7413af7 Binary files /dev/null and "b/Documents/\345\233\276\347\211\207/1600091210.png" differ diff --git "a/Documents/\345\233\276\347\211\207/1600136270.png" "b/Documents/\345\233\276\347\211\207/1600136270.png" new file mode 100644 index 0000000..32be590 Binary files /dev/null and "b/Documents/\345\233\276\347\211\207/1600136270.png" differ diff --git "a/Documents/\345\233\276\347\211\207/gamelab_full_logo_small-2.png" "b/Documents/\345\233\276\347\211\207/gamelab_full_logo_small-2.png" new file mode 100644 index 0000000..e93e741 Binary files /dev/null and "b/Documents/\345\233\276\347\211\207/gamelab_full_logo_small-2.png" differ diff --git "a/Documents/\345\233\276\347\211\207/gamelab_full_logo_small.png" "b/Documents/\345\233\276\347\211\207/gamelab_full_logo_small.png" new file mode 100644 index 0000000..adc1374 Binary files /dev/null and "b/Documents/\345\233\276\347\211\207/gamelab_full_logo_small.png" differ diff --git "a/Documents/\350\256\276\350\256\241.xlsx" "b/Documents/\350\256\276\350\256\241.xlsx" new file mode 100644 index 0000000..db598ba Binary files /dev/null and "b/Documents/\350\256\276\350\256\241.xlsx" differ diff --git a/Editor/EditorApplication.cpp b/Editor/EditorApplication.cpp new file mode 100644 index 0000000..0ebff72 --- /dev/null +++ b/Editor/EditorApplication.cpp @@ -0,0 +1,41 @@ +#include "EditorApplication.h" +#include "Runtime/Utilities/Assert.h" +#include "Editor/EditorManager.h" + +static bool s_Created; + +EditorApplication::EditorApplication() +{ + Assert(!s_Created); +} + +EditorApplication::~EditorApplication() +{ + +} + +void EditorApplication::SetMainWindow(ContainnerWindow* wnd) +{ + Assert(wnd); + EditorManager::Instance()->SetMainWindow(wnd); +} + +void EditorApplication::PullMessage() +{ + MSG msg; + while (PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE) != 0) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + + if (msg.message == WM_QUIT) + { + OnQuit(); + } + } +} + +void EditorApplication::OnQuit() +{ + +} \ No newline at end of file diff --git a/Editor/EditorApplication.h b/Editor/EditorApplication.h new file mode 100644 index 0000000..eb08c46 --- /dev/null +++ b/Editor/EditorApplication.h @@ -0,0 +1,31 @@ +#include +#include +#include "Runtime/Lua/LuaBind/LuaBind.h" +#include "Editor/GUI/EditorWindows.h" +#include "Editor/GUI/MenuManager.h" + +using namespace LuaBind; + +class EditorApplication + : public LuaBind::NativeClass +{ +public: + EditorApplication(); + ~EditorApplication(); + + void PullMessage(); + void SetMainWindow(ContainnerWindow* wnd); + + void OnQuit(); + +private : + + LUA_BIND_DECL_FACTORY(EditorApplication); + + LUA_BIND_DECL_METHOD(_New); + LUA_BIND_DECL_METHOD(_SetMainWindow); + LUA_BIND_DECL_METHOD(_SetupMenu); + LUA_BIND_DECL_METHOD(_PullMessage); + + +}; diff --git a/Editor/EditorMain.cpp b/Editor/EditorMain.cpp index 1606e94..67ddc38 100644 --- a/Editor/EditorMain.cpp +++ b/Editor/EditorMain.cpp @@ -1,7 +1,7 @@ #include #include #include "GUI/EditorWindows.h" -#include "Runtime/LuaBind/LuaBind.h" +#include "Runtime/Lua/LuaBind/LuaBind.h" #include "EditorManager.h" #include "Runtime/Graphics/OpenGL.h" #include "Editor/Scripting/EditorScripting.h" @@ -54,51 +54,9 @@ int main() int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR szCmdLine, int sw) #endif { - InitLuaState(); - - WindowUtil::Init(); - - ContainnerWindow* wnd = new ContainnerWindow(); - Vector2f min = Vector2f(100, 100); - Vector2f max = Vector2f(700, 700); - wnd->Init(Rectf(400, 400, 800, 500), ContainnerWindow::kShowMainWindow, min, max); - wnd->SetTitle("GameLab"); - wnd->SetIcon("./Icon/GameLab.ico"); - - EditorManager::Instance()->SetMainWindow(wnd); - MenuManager::Instance()->Init(); - - GUIWindow* guiWnd = new GUIWindow(); - guiWnd->Init(); - guiWnd->SetContainnerWindow(wnd); - Rectf position; - position.x = 0; - position.y = 0; - position.width = 200; - position.height = 200; - guiWnd->SetPosition(position); + WindowUtil::RegisterClasses(); - GUIWindow* guiWnd2 = new GUIWindow(); - guiWnd2->Init(); - guiWnd2->SetContainnerWindow(wnd); - position.x = 200; - position.y = 0; - position.width = 200; - position.height = 200; - guiWnd2->SetPosition(position); - - // init gl - wglMakeCurrent(guiWnd2->GetDC(), guiWnd2->GetRC()); - if (!gladLoadGL()) { - log_error("³õʼ»¯GL´íÎó"); - } - - // force repaint - wnd->DoPaint(); - guiWnd->DoPaint(); - guiWnd2->DoPaint(); - - MainLoop(); + InitLuaState(); return 0; } \ No newline at end of file diff --git a/Editor/GUI/ContainnerWindow.cpp b/Editor/GUI/ContainnerWindow.cpp index 3778485..d6a67c9 100644 --- a/Editor/GUI/ContainnerWindow.cpp +++ b/Editor/GUI/ContainnerWindow.cpp @@ -5,6 +5,7 @@ #include "Editor/Utils/HelperFuncs.h" #include "MenuManager.h" #include "Runtime/Utilities/Assert.h" +#include "Editor/Graphics/Graphics.h" using namespace std; @@ -260,6 +261,15 @@ bool ContainnerWindow::SetRenderContext() return FALSE; // Return FALSE } + if (m_RC && !g_IsGLInitialized) + { + log_info("Initialize OpenGL"); + wglMakeCurrent(m_DC, m_RC); + if (!gladLoadGL()) { + log_error("³õʼ»¯GL´íÎó"); + } + g_IsGLInitialized = true; + } } // ³õʼ»¯£¬´´½¨´°¿Ú @@ -388,6 +398,7 @@ void ContainnerWindow::Init(Rectf pixelRect, int showMode, const Vector2f& minSi //ShowInTaskbarIfNoMainWindow(m_Window); SetRenderContext(); + } void ContainnerWindow::SetTitle(const char* title) diff --git a/Editor/GUI/EditorWindows.h b/Editor/GUI/EditorWindows.h index 307ab86..97175b3 100644 --- a/Editor/GUI/EditorWindows.h +++ b/Editor/GUI/EditorWindows.h @@ -4,7 +4,8 @@ #include #include #include "Runtime/Math/Rect.h" -#include "Runtime/LuaBind/LuaBind.h" +#include "Runtime/Lua/LuaBind/LuaBind.h" +#include "Runtime/Lua/LuaHelper.h" #include "Runtime/Utilities/Singleton.h" #include "Runtime/Debug/Log.h" #include "Runtime/Graphics/OpenGL.h" @@ -18,7 +19,7 @@ class GUIWindow; class WindowUtil { public : - static void Init(); + static void RegisterClasses(); static const wchar_t* kContainerWindowClassName; static const wchar_t* kPopupWindowClassName; @@ -89,8 +90,11 @@ private: POINT m_MaxSize; LUA_BIND_DECL_FACTORY(ContainnerWindow); - LUA_BIND_DECL_METHOD(_SetTitle); - LUA_BIND_DECL_METHOD(_DoPaint); + + LUA_BIND_DECL_METHOD(_New); + LUA_BIND_DECL_METHOD(_SetTitle); + LUA_BIND_DECL_METHOD(_SetIcon); + LUA_BIND_DECL_METHOD(_DoPaint); }; @@ -122,7 +126,9 @@ private: }; // GUI´°¿Ú£¬Ê¼þÏàÓ¦¡¢»æÖÆ¡¢²¼¾ÖµÄµ¥Ôª -class GUIWindow : public WindowBase +class GUIWindow + : public WindowBase + , public LuaBind::NativeClass { public: static LRESULT CALLBACK GUIViewWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); @@ -155,6 +161,14 @@ private: LuaBind::Ref m_Script; + LUA_BIND_DECL_FACTORY(GUIWindow); + + LUA_BIND_DECL_METHOD(_New); + LUA_BIND_DECL_METHOD(_DoPaint); + LUA_BIND_DECL_METHOD(_Focus); + LUA_BIND_DECL_METHOD(_SetContainnerWindow); + LUA_BIND_DECL_METHOD(_SetPosition); + }; #endif \ No newline at end of file diff --git a/Editor/GUI/GUIWindow.cpp b/Editor/GUI/GUIWindow.cpp index 3df0370..34d7705 100644 --- a/Editor/GUI/GUIWindow.cpp +++ b/Editor/GUI/GUIWindow.cpp @@ -1,6 +1,7 @@ #include "EditorWindows.h" #include "WinUtils.h" #include "Runtime/Graphics/OpenGL.h" +#include "Editor/Graphics/Graphics.h" static bool RedirectMouseWheel(HWND window, WPARAM wParam, LPARAM lParam) { @@ -223,10 +224,12 @@ void GUIWindow::Init(std::string name) ShowWindow(m_Handle, SW_SHOW); - if (!SetRenderContext()) + bool bRC = SetRenderContext(); + if (!bRC) log_error("Failed to setup rendering context"); log_info("Created GUIWindow " /*+ (long)this*/); + } bool GUIWindow::SetRenderContext() @@ -288,6 +291,15 @@ bool GUIWindow::SetRenderContext() return FALSE; // Return FALSE } + if (m_RC && !g_IsGLInitialized) + { + log_info("Initialize OpenGL"); + wglMakeCurrent(m_DC, m_RC); + if (!gladLoadGL()) { + log_error("³õʼ»¯GL´íÎó"); + } + g_IsGLInitialized = true; + } return true; } diff --git a/Editor/GUI/WindowUtil.cpp b/Editor/GUI/WindowUtil.cpp index fc32719..b76b6d0 100644 --- a/Editor/GUI/WindowUtil.cpp +++ b/Editor/GUI/WindowUtil.cpp @@ -9,7 +9,7 @@ static ATOM ContainerWindowClassAtom; static ATOM PopupWindowClassAtom; static ATOM GUIViewClassAtom; -void WindowUtil::Init() +void WindowUtil::RegisterClasses() { log_info("WindowUtil::Init()"); diff --git a/Editor/Graphics/Graphics.cpp b/Editor/Graphics/Graphics.cpp new file mode 100644 index 0000000..af48d75 --- /dev/null +++ b/Editor/Graphics/Graphics.cpp @@ -0,0 +1,3 @@ +#include "Graphics.h" + +bool g_IsGLInitialized = false; diff --git a/Editor/Graphics/Graphics.h b/Editor/Graphics/Graphics.h new file mode 100644 index 0000000..ad27ede --- /dev/null +++ b/Editor/Graphics/Graphics.h @@ -0,0 +1,3 @@ +#pragma once + +extern bool g_IsGLInitialized; diff --git a/Editor/Scripting/Editor/Editor.bind.cpp b/Editor/Scripting/Editor/Editor.bind.cpp index e69de29..2300d2f 100644 --- a/Editor/Scripting/Editor/Editor.bind.cpp +++ b/Editor/Scripting/Editor/Editor.bind.cpp @@ -0,0 +1,17 @@ +#include "Editor/EditorApplication.h" + +// GameLab.Editor +int luaopen_GameLab_Editor(lua_State* L) +{ + log_info("Scripting", "luaopen_GameLab_Editor()"); + + LUA_BIND_STATE(L); + + state.PushGlobalNamespace(); + state.PushNamespace("GameLab"); + state.PushNamespace("Editor"); + + state.RegisterFactory(); + + return 1; +} \ No newline at end of file diff --git a/Editor/Scripting/Editor/EditorApplication.bind.cpp b/Editor/Scripting/Editor/EditorApplication.bind.cpp index e69de29..82abdd5 100644 --- a/Editor/Scripting/Editor/EditorApplication.bind.cpp +++ b/Editor/Scripting/Editor/EditorApplication.bind.cpp @@ -0,0 +1,47 @@ +#include "Editor/EditorApplication.h" + +LUA_BIND_REGISTRY(EditorApplication) +{ + LUA_BIND_REGISTER_METHODS(state, + {"New", EditorApplication::_New}, + { "SetMainWindow", _SetMainWindow }, + { "SetupMenu", _SetupMenu }, + { "PullMessage", _PullMessage } + ); +} + +LUA_BIND_POSTPROCESS(EditorApplication) +{ +} + +LUA_BIND_IMPL_METHOD(EditorApplication, EditorApplication::_New) +{ + LUA_BIND_PREPARE(L, EditorApplication); + EditorApplication* app = new EditorApplication(); + app->PushUserdata(state); + return 1; +} + +LUA_BIND_IMPL_METHOD(EditorApplication, EditorApplication::_PullMessage) +{ + LUA_BIND_PREPARE(L, EditorApplication); + self->PullMessage(); + return 0; +} + +LUA_BIND_IMPL_METHOD(EditorApplication, _SetMainWindow) +{ + LUA_BIND_PREPARE(L, EditorApplication); + LUA_BIND_CHECK(L, "UU"); + + ContainnerWindow* wnd = state.GetUserdata(2); + self->SetMainWindow(wnd); + return 0; +} + +LUA_BIND_IMPL_METHOD(EditorApplication, _SetupMenu) +{ + LUA_BIND_PREPARE(L, EditorApplication); + MenuManager::Instance()->Init(); + return 0; +} \ No newline at end of file diff --git a/Editor/Scripting/EditorGUI/ContainerWindow.bind.cpp b/Editor/Scripting/EditorGUI/ContainerWindow.bind.cpp index 265ea2e..d3d0997 100644 --- a/Editor/Scripting/EditorGUI/ContainerWindow.bind.cpp +++ b/Editor/Scripting/EditorGUI/ContainerWindow.bind.cpp @@ -3,9 +3,11 @@ LUA_BIND_REGISTRY(ContainnerWindow) { LUA_BIND_REGISTER_METHODS(state, - { "SetTitle", _SetTitle }, - { "DoPaint", _DoPaint } - ); + { "SetTitle", _SetTitle }, + { "SetIcon", _SetIcon }, + { "DoPaint", _DoPaint }, + { "New", _New } + ); } LUA_BIND_POSTPROCESS(ContainnerWindow) @@ -22,16 +24,46 @@ LUA_BIND_POSTPROCESS(ContainnerWindow) LUA_BIND_IMPL_METHOD(ContainnerWindow, _SetTitle) { - LUA_BIND_PREPARE(L, ContainnerWindow); + LUA_BIND_PREPARE(L, ContainnerWindow); + + cc8* title = state.GetValue(2, ""); + self->SetTitle(title); + return 0; +} +LUA_BIND_IMPL_METHOD(ContainnerWindow, _SetIcon) +{ + LUA_BIND_PREPARE(L, ContainnerWindow); - return 0; + cc8* path = state.GetValue(2, ""); + self->SetIcon(path); + + return 0; } LUA_BIND_IMPL_METHOD(ContainnerWindow, _DoPaint) { - LUA_BIND_PREPARE(L, ContainnerWindow); - self->DoPaint(); - return 0; -} \ No newline at end of file + LUA_BIND_PREPARE(L, ContainnerWindow); + self->DoPaint(); + return 0; +} + +LUA_BIND_IMPL_METHOD(ContainnerWindow, ContainnerWindow::_New) +{ + LUA_BIND_STATE(L, ContainnerWindow); + LUA_BIND_CHECK(L, "TNTT"); + + ContainnerWindow* wnd = new ContainnerWindow(); + + Rectf rect = state.GetValue(state, Rectf()); + int showMode = state.GetValue(2, 0); + Vector2f min = state.GetValue(state, Vector2f()); + Vector2f max = state.GetValue(state, Vector2f()); + + wnd->Init(rect, showMode, min, max); + + wnd->PushUserdata(state); + + return 1; +} diff --git a/Editor/Scripting/EditorGUI/EditorGUI.bind.cpp b/Editor/Scripting/EditorGUI/EditorGUI.bind.cpp index 57c45ca..4e908c4 100644 --- a/Editor/Scripting/EditorGUI/EditorGUI.bind.cpp +++ b/Editor/Scripting/EditorGUI/EditorGUI.bind.cpp @@ -12,7 +12,8 @@ int luaopen_GameLab_Editor_GUI(lua_State* L) state.PushNamespace("Editor"); state.PushNamespace("GUI"); - state.RegisterFactory(); + state.RegisterFactory(); + state.RegisterFactory(); return 1; } \ No newline at end of file diff --git a/Editor/Scripting/EditorGUI/GUIWindow.bind.cpp b/Editor/Scripting/EditorGUI/GUIWindow.bind.cpp index e69de29..ec8f830 100644 --- a/Editor/Scripting/EditorGUI/GUIWindow.bind.cpp +++ b/Editor/Scripting/EditorGUI/GUIWindow.bind.cpp @@ -0,0 +1,63 @@ +#include "Editor/GUI/EditorWindows.h" + +LUA_BIND_REGISTRY(GUIWindow) +{ + LUA_BIND_REGISTER_METHODS(state, + { "DoPaint", _DoPaint }, + { "Focus", _Focus }, + { "SetContainnerWindow", _SetContainnerWindow }, + { "SetPosition", _SetPosition }, + { "New", _New } + ); +} + +LUA_BIND_POSTPROCESS(GUIWindow) +{ +} + +LUA_BIND_IMPL_METHOD(GUIWindow, _DoPaint) +{ + LUA_BIND_PREPARE(L, GUIWindow); + self->DoPaint(); + return 0; +} + +LUA_BIND_IMPL_METHOD(GUIWindow, _Focus) +{ + LUA_BIND_PREPARE(L, GUIWindow); + self->Focus(); + return 0; +} + +LUA_BIND_IMPL_METHOD(GUIWindow, _SetContainnerWindow) +{ + LUA_BIND_PREPARE(L, GUIWindow); + ContainnerWindow* wnd = state.GetUserdata(2); + self->SetContainnerWindow(wnd); + return 0; +} + +// GUIWindow.SetPosition(self, {x, y, width, height}) +LUA_BIND_IMPL_METHOD(GUIWindow, _SetPosition) +{ + LUA_BIND_PREPARE(L, GUIWindow); + if (!state.CheckParams(1, "UT")) + return 0; + + Rectf rect; + rect.x = state.GetField(2, 1, 0); + rect.y = state.GetField(2, 2, 0); + rect.width = state.GetField(2, 3, 0); + rect.height = state.GetField(2, 4, 0); + self->SetPosition(rect); + return 0; +} + +LUA_BIND_IMPL_METHOD(GUIWindow, _New) +{ + LUA_BIND_PREPARE(L, GUIWindow); + GUIWindow* wnd = new GUIWindow(); + wnd->PushUserdata(state); + wnd->Init(); + return 1; +} \ No newline at end of file diff --git a/Editor/Scripting/EditorScripting.cpp b/Editor/Scripting/EditorScripting.cpp index 294d6f9..bb53848 100644 --- a/Editor/Scripting/EditorScripting.cpp +++ b/Editor/Scripting/EditorScripting.cpp @@ -32,7 +32,9 @@ bool SetupGameLabEditorScripting(lua_State* L) log_info("Scripting", "SetupGameLabEditorScripting()"); openlib(luaopen_GameLab_Debug); - openlib(luaopen_GameLab_Editor_GUI); + + openlib(luaopen_GameLab_Editor); + openlib(luaopen_GameLab_Editor_GUI); return true; } diff --git a/Editor/Scripting/EditorScripting.h b/Editor/Scripting/EditorScripting.h index 2ed2233..301ac3f 100644 --- a/Editor/Scripting/EditorScripting.h +++ b/Editor/Scripting/EditorScripting.h @@ -1,4 +1,4 @@ #pragma once -#include "Runtime/LuaBind/LuaBind.h" +#include "Runtime/Lua/LuaBind/LuaBind.h" bool SetupGameLabEditorScripting(lua_State* L); diff --git a/Projects/VisualStudio/Editor/Editor.vcxproj b/Projects/VisualStudio/Editor/Editor.vcxproj index ce23a28..8dfc5c6 100644 --- a/Projects/VisualStudio/Editor/Editor.vcxproj +++ b/Projects/VisualStudio/Editor/Editor.vcxproj @@ -1,243 +1,249 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - Debug - x64 - - - Release - x64 - - - - 15.0 - {CB47B19A-6649-4A1A-8FE5-6359178AA48F} - Editor - 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 - _CRT_SECURE_NO_WARNINGS;GAMELAB_DEBUG;GAMELAB_EDITOR;%(PreprocessorDefinitions) - $(SolutionDir)..\..\;$(SolutionDir)..\..\ThirdParty\;%(AdditionalIncludeDirectories) - - - Console - %(AdditionalDependencies) - - - - - Level3 - Disabled - true - true - _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - $(SolutionDir)..\..\;%(AdditionalIncludeDirectories) - - - Windows - %(AdditionalDependencies) - - - - - Level3 - MaxSpeed - true - true - true - true - $(SolutionDir)..\..\;%(AdditionalIncludeDirectories) - - - Windows - true - true - - - - - Level3 - MaxSpeed - true - true - true - true - $(SolutionDir)..\..\;%(AdditionalIncludeDirectories) - - - Windows - true - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {385f2d3a-1cef-4aa1-8051-527f6b68dd81} - - - {ad09415f-4bf9-4fce-901f-7ab22d429cfc} - - - - - - - - - + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 15.0 + {CB47B19A-6649-4A1A-8FE5-6359178AA48F} + Editor + 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 + _CRT_SECURE_NO_WARNINGS;GAMELAB_DEBUG;GAMELAB_EDITOR;%(PreprocessorDefinitions) + $(SolutionDir)..\..\;$(SolutionDir)..\..\ThirdParty\;%(AdditionalIncludeDirectories) + + + Console + %(AdditionalDependencies) + + + + + Level3 + Disabled + true + true + _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + $(SolutionDir)..\..\;%(AdditionalIncludeDirectories) + + + Windows + %(AdditionalDependencies) + + + + + Level3 + MaxSpeed + true + true + true + true + $(SolutionDir)..\..\;%(AdditionalIncludeDirectories) + + + Windows + true + true + + + + + Level3 + MaxSpeed + true + true + true + true + $(SolutionDir)..\..\;%(AdditionalIncludeDirectories) + + + Windows + true + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {385f2d3a-1cef-4aa1-8051-527f6b68dd81} + + + {ad09415f-4bf9-4fce-901f-7ab22d429cfc} + + + + + + + + + \ No newline at end of file diff --git a/Projects/VisualStudio/Editor/Editor.vcxproj.filters b/Projects/VisualStudio/Editor/Editor.vcxproj.filters index 88ad2a6..5062a9f 100644 --- a/Projects/VisualStudio/Editor/Editor.vcxproj.filters +++ b/Projects/VisualStudio/Editor/Editor.vcxproj.filters @@ -1,320 +1,347 @@ - - - - - {37e66f64-a2fe-4adf-b435-e2e42ea17414} - - - {376fd2a5-5333-4bcb-9122-a112c40d5287} - - - {ed31f129-996f-4a1c-b8d5-5c3d74139940} - - - {61174975-2b52-426f-b871-d33e1bf956d4} - - - {e7e5a875-cafb-48df-9659-8f88d0377208} - - - {87a57ef1-78d8-42b8-b179-ce1bbb5c4f8b} - - - {6c7e1979-1cd3-40c7-98e1-f063c325d642} - - - {47032dd6-dca2-478f-b594-d08c0b22e119} - - - {bfc8b148-db9d-403d-96b9-32c946e15402} - - - {5b8dba28-42d0-450a-98e1-ca4a65a4fc76} - - - {848489fc-f661-4b10-91f5-db1687293b95} - - - {87edd159-c171-4ccb-9094-9e5061c980d0} - - - {476cedf1-fc4a-48a5-8782-bed16dabb86e} - - - {337f607e-8c00-4e7b-a925-9380e08a30f0} - - - {f9573ff2-4a53-4953-806e-f0ce0c586910} - - - {c1e200c9-0eec-40e2-a69f-ccaaaa208200} - - - {0d57b53a-e29a-4ece-a6d8-f5aa13d15891} - - - {707a995f-6856-44c8-857c-14e7834e86e3} - - - {df6cfcb1-ec0a-4b6d-b80d-8ee197425509} - - - {be13ccc9-0b31-4d22-b512-e2a05d7f3c5b} - - - {1186771e-bd0f-45de-94a4-373ab489d274} - - - - - Editor\GUI - - - Runtime\Math - - - Runtime\Math - - - Runtime\Utilities - - - Runtime\Utilities - - - Editor\GUI - - - Editor\GUI - - - Editor\GUI - - - Editor\GUI - - - Editor\GUI - - - Editor\GUI - - - Editor - - - Editor - - - Editor\GUI - - - Editor\Utils - - - Editor\GUI - - - Editor\Resource - - - Editor\Scripting\EditorGUI - - - Editor\Scripting - - - Editor\Scripting\EditorGUI - - - Editor\Scripting\EditorGUI - - - Editor\Scripting\EditorGUI - - - Editor\IMGUI - - - Editor\Scripting\IMGUI - - - Runtime\LuaBind - - - Runtime\LuaBind - - - Runtime\LuaBind - - - Runtime\LuaBind - - - Runtime\LuaBind - - - Runtime\LuaBind - - - Runtime\LuaBind - - - Runtime\LuaBind - - - Runtime\LuaBind - - - Editor\Shaders - - - Runtime\Debug - - - Runtime\Scripting\GL - - - Runtime\Scripting\Debug - - - Runtime\Graphics - - - Editor\Scripting\Editor - - - Editor\Scripting\Editor - - - - - Editor\GUI - - - Editor\GUI - - - Runtime\Math - - - Runtime\Math - - - Runtime\Math - - - Runtime\Math - - - Runtime\Math - - - Runtime\Utilities - - - Runtime\Utilities - - - Runtime\Utilities - - - Runtime\Utilities - - - Runtime\Utilities - - - Runtime\Utilities - - - Runtime\Utilities - - - Runtime\Utilities - - - Runtime\Utilities - - - Editor\GUI - - - Editor\GUI - - - Editor - - - Editor\Utils - - - Editor\GUI - - - Editor\Resource - - - Editor\Scripting - - - Runtime\LuaBind - - - Runtime\LuaBind - - - Runtime\LuaBind - - - Runtime\LuaBind - - - Runtime\LuaBind - - - Runtime\LuaBind - - - Runtime\LuaBind - - - Runtime\LuaBind - - - Runtime\LuaBind - - - Runtime\LuaBind - - - Runtime\LuaBind - - - Runtime\LuaBind - - - Runtime\LuaBind - - - Runtime\LuaBind - - - Editor\Shaders - - - Runtime\Debug - - - Runtime\Graphics - - - - - Runtime\LuaBind - - - Runtime\LuaBind - - + + + + + {37e66f64-a2fe-4adf-b435-e2e42ea17414} + + + {376fd2a5-5333-4bcb-9122-a112c40d5287} + + + {ed31f129-996f-4a1c-b8d5-5c3d74139940} + + + {61174975-2b52-426f-b871-d33e1bf956d4} + + + {e7e5a875-cafb-48df-9659-8f88d0377208} + + + {87a57ef1-78d8-42b8-b179-ce1bbb5c4f8b} + + + {6c7e1979-1cd3-40c7-98e1-f063c325d642} + + + {47032dd6-dca2-478f-b594-d08c0b22e119} + + + {bfc8b148-db9d-403d-96b9-32c946e15402} + + + {5b8dba28-42d0-450a-98e1-ca4a65a4fc76} + + + {848489fc-f661-4b10-91f5-db1687293b95} + + + {87edd159-c171-4ccb-9094-9e5061c980d0} + + + {476cedf1-fc4a-48a5-8782-bed16dabb86e} + + + {337f607e-8c00-4e7b-a925-9380e08a30f0} + + + {c1e200c9-0eec-40e2-a69f-ccaaaa208200} + + + {0d57b53a-e29a-4ece-a6d8-f5aa13d15891} + + + {707a995f-6856-44c8-857c-14e7834e86e3} + + + {df6cfcb1-ec0a-4b6d-b80d-8ee197425509} + + + {be13ccc9-0b31-4d22-b512-e2a05d7f3c5b} + + + {1186771e-bd0f-45de-94a4-373ab489d274} + + + {66d581bf-85b1-4108-b1e1-d5e44f391af8} + + + {8810f29e-3166-4dd6-af85-8eebab583f0c} + + + {d076ff69-6f78-4c7d-be95-e59daf26a3e2} + + + {f9573ff2-4a53-4953-806e-f0ce0c586910} + + + + + Editor\GUI + + + Runtime\Math + + + Runtime\Math + + + Runtime\Utilities + + + Runtime\Utilities + + + Editor\GUI + + + Editor\GUI + + + Editor\GUI + + + Editor\GUI + + + Editor\GUI + + + Editor\GUI + + + Editor + + + Editor + + + Editor\GUI + + + Editor\Utils + + + Editor\GUI + + + Editor\Resource + + + Editor\Scripting\EditorGUI + + + Editor\Scripting + + + Editor\Scripting\EditorGUI + + + Editor\Scripting\EditorGUI + + + Editor\Scripting\EditorGUI + + + Editor\IMGUI + + + Editor\Scripting\IMGUI + + + Editor\Shaders + + + Runtime\Debug + + + Runtime\Scripting\GL + + + Runtime\Scripting\Debug + + + Runtime\Graphics + + + Editor\Scripting\Editor + + + Editor\Scripting\Editor + + + Editor + + + Editor\Graphics + + + Runtime\Lua\LuaBind + + + Runtime\Lua\LuaBind + + + Runtime\Lua\LuaBind + + + Runtime\Lua\LuaBind + + + Runtime\Lua\LuaBind + + + Runtime\Lua\LuaBind + + + Runtime\Lua\LuaBind + + + Runtime\Lua\LuaBind + + + Runtime\Lua\LuaBind + + + Runtime\Lua + + + + + Editor\GUI + + + Editor\GUI + + + Runtime\Math + + + Runtime\Math + + + Runtime\Math + + + Runtime\Math + + + Runtime\Math + + + Runtime\Utilities + + + Runtime\Utilities + + + Runtime\Utilities + + + Runtime\Utilities + + + Runtime\Utilities + + + Runtime\Utilities + + + Runtime\Utilities + + + Runtime\Utilities + + + Runtime\Utilities + + + Editor\GUI + + + Editor\GUI + + + Editor + + + Editor\Utils + + + Editor\GUI + + + Editor\Resource + + + Editor\Scripting + + + Editor\Shaders + + + Runtime\Debug + + + Runtime\Graphics + + + Editor + + + Editor\Graphics + + + Runtime\Lua\LuaBind + + + Runtime\Lua\LuaBind + + + Runtime\Lua\LuaBind + + + Runtime\Lua\LuaBind + + + Runtime\Lua\LuaBind + + + Runtime\Lua\LuaBind + + + Runtime\Lua\LuaBind + + + Runtime\Lua\LuaBind + + + Runtime\Lua\LuaBind + + + Runtime\Lua\LuaBind + + + Runtime\Lua\LuaBind + + + Runtime\Lua\LuaBind + + + Runtime\Lua\LuaBind + + + Runtime\Lua\LuaBind + + + Runtime\Lua + + + + + Runtime\Lua\LuaBind + + + Runtime\Lua\LuaBind + + \ No newline at end of file diff --git a/Projects/VisualStudio/Editor/Editor.vcxproj.user b/Projects/VisualStudio/Editor/Editor.vcxproj.user index db52b6c..f86de5d 100644 --- a/Projects/VisualStudio/Editor/Editor.vcxproj.user +++ b/Projects/VisualStudio/Editor/Editor.vcxproj.user @@ -1,7 +1,10 @@ - - - - $(SolutionDir)..\..\Resources - WindowsLocalDebugger - + + + + $(SolutionDir)..\..\Resources + WindowsLocalDebugger + + + true + \ No newline at end of file diff --git a/Resources/Scripts/Editor/ProjectWindow.lua b/Resources/Scripts/Editor/ProjectWindow.lua new file mode 100644 index 0000000..18959f2 --- /dev/null +++ b/Resources/Scripts/Editor/ProjectWindow.lua @@ -0,0 +1,18 @@ +local GUI = GameLab.Editor.GUI +local GUILayout = GameLab.Editor.GUILayout + +local ProjectWindow = { + ["name"] = "Project", +} + +ProjectWindow.OnGUI = function(self) + if GUILayout.Button("click") then + + end +end + +ProjectWindow.OnUpdate = function(self) + +end + +GUI.RegisterEditorWindow("Project", ProjectWindow, "Custom/Project") \ No newline at end of file diff --git a/Resources/Scripts/EditorApplication.lua b/Resources/Scripts/EditorApplication.lua index 935547d..c8438cf 100644 --- a/Resources/Scripts/EditorApplication.lua +++ b/Resources/Scripts/EditorApplication.lua @@ -1,19 +1,27 @@ +require "./Scripts/Utils/Utils" + local Debug = GameLab.Debug local GUI = GameLab.Editor.GUI +local app = GameLab.Editor.EditorApplication.New() -Debug.OpenTag("WndProc") - -Debug.Log("WndProc", "123") +if app == nil then + Debug.LogError("app is nil") +end -local i = 0 -while i < 10 do +local mainWindow = GUI.ContainnerWindow.New({400, 400, 800, 500}, GUI.EShowMode.MainWindow, {100, 100}, {700, 700}) +mainWindow:SetTitle("GameLab") +mainWindow:SetIcon("./Icon/GameLab.ico") - i = i + 1 - Debug.Log(i) +app:SetMainWindow(mainWindow) +app:SetupMenu() -end +local guiWindow = GUI.GUIWindow.New() +guiWindow:SetContainnerWindow(mainWindow) +guiWindow:SetPosition({0,0, 500, 400}) +while true do -Debug.Log(GUI.EShowMode.NoShadow) + app:PullMessage() +end \ No newline at end of file diff --git a/Resources/Scripts/Utils/Utils.lua b/Resources/Scripts/Utils/Utils.lua new file mode 100644 index 0000000..678217b --- /dev/null +++ b/Resources/Scripts/Utils/Utils.lua @@ -0,0 +1,4 @@ +local Utils = GameLab.Editor.Utils or {} +GameLab.Editor.Utils = Utils + + diff --git a/Runtime/Lua/LuaBind/LuaBind.h b/Runtime/Lua/LuaBind/LuaBind.h new file mode 100644 index 0000000..1494b5c --- /dev/null +++ b/Runtime/Lua/LuaBind/LuaBind.h @@ -0,0 +1,18 @@ +#ifndef __LUA_BIND_H__ +#define __LUA_BIND_H__ + +// +// (port) library ÓÃÓÚ¸ølua×¢²áÀàºÍº¯Êý +// + +#include "LuaBindState.h" +#include "LuaBindVM.h" +#include "LuaBindRef.h" +#include "LuaBindRefTable.h" +#include "LuaBindEnum.h" +#include "LuaBindClass.hpp" +#include "LuaBindMemberRef.h" +#include "LuaBindClass.inc" +#include "LuaBindState.inc" + +#endif \ No newline at end of file diff --git a/Runtime/Lua/LuaBind/LuaBindCFunctions.cpp b/Runtime/Lua/LuaBind/LuaBindCFunctions.cpp new file mode 100644 index 0000000..ca662a3 --- /dev/null +++ b/Runtime/Lua/LuaBind/LuaBindCFunctions.cpp @@ -0,0 +1,19 @@ +#include "LuaBindCFunctions.h" +#include "LuaBindConfig.h" + +namespace LuaBind +{ + + int luax_c_getupvalue(lua_State* L) + { + lua_pushvalue(L, lua_upvalueindex(1)); + return 1; + } + + int luax_c_errfunc(lua_State* L) + { + cc8* msg = luaL_optstring(L, lua_upvalueindex(1), ""); + return luaL_error(L, msg); + } + +} \ No newline at end of file diff --git a/Runtime/Lua/LuaBind/LuaBindCFunctions.h b/Runtime/Lua/LuaBind/LuaBindCFunctions.h new file mode 100644 index 0000000..f0f07dd --- /dev/null +++ b/Runtime/Lua/LuaBind/LuaBindCFunctions.h @@ -0,0 +1,38 @@ +#ifndef __LUA_BIND_CFUNCTIONS_H__ +#define __LUA_BIND_CFUNCTIONS_H__ + +#include "LuaBindConfig.h" + +/** + * luax_cfunctionÀïµÄº¯ÊýÓÃÀ´×¢²á¸ølua£¬Ò»Ð©ÌØÊ⹦ÄܵÄͨÓú¯Êý¡£ +*/ + +namespace +{ + + // »ñµÃµÚÒ»¸öupvalue + extern int luax_c_getupvalue(lua_State* L); + + // µ÷Óô˺¯Êýʱ»á±¨´í£¬upvalue(1)ÊÇ´íÎóÐÅÏ¢ + extern int luax_c_errfunc(lua_State* L); + +#define luax_is(T, L, i) (lua_is##T(L, i)) +#define luax_isnumber(L, i) luax_is(number, L, i) + + inline int luax_isinteger(lua_State* L, int i) + { + if (!luax_isnumber(L, i)) + return 0; + return lua_tonumber(L, i) == lua_tointeger(L, i); + } + + inline int luax_isfloat(lua_State* L, int i) + { + if (!luax_isnumber(L, i)) + return 0; + return lua_tonumber(L, i) != lua_tointeger(L, i); + } + +} + +#endif \ No newline at end of file diff --git a/Runtime/Lua/LuaBind/LuaBindClass.cpp b/Runtime/Lua/LuaBind/LuaBindClass.cpp new file mode 100644 index 0000000..7fd603c --- /dev/null +++ b/Runtime/Lua/LuaBind/LuaBindClass.cpp @@ -0,0 +1,243 @@ +#include "LuaBindClass.hpp" +#include "LuaBindCFunctions.h" +#include "LuaBindVM.h" + +namespace LuaBind +{ + +#if LUA_BIND_ENABLE_PLAIN_CLASS + + int PlainClass::registry(lua_State* L) + { + LUA_BIND_STATE(L); + + // params: + // 1: class name + + cc8* type = state.GetValue(1, ""); + + lua_newtable(L); // class table + + // GetClassName() + lua_pushstring(L, type); + lua_pushcclosure(L, luax_c_getupvalue, 1); + lua_setfield(L, -2, "GetClassName"); + + // GetClass() + lua_pushvalue(L, -1); // class table + lua_pushcclosure(L, luax_c_getupvalue, 1); + lua_setfield(L, -2, "GetClass"); + + // TypeOf() + lua_pushcfunction(L, _TypeOf); + lua_setfield(L, -2, "TypeOf"); + + // New() + lua_pushvalue(L, -1); // class table + lua_pushcclosure(L, _New, 1); + lua_setfield(L, -2, "New"); + + // Extend() + lua_pushvalue(L, -1); // class table + lua_pushcclosure(L, _Extend, 1); + lua_setfield(L, -2, "Extend"); + + lua_pushvalue(L, -1); // class table + lua_setfield(L, -2, "__index"); + + lua_pushstring(L, type); + lua_pushcclosure(L, __tostring, 1); + lua_setfield(L, -2, "__tostring"); + + return 1; + } + + int PlainClass::__tostring(lua_State* L) + { + // upvalues: + // 1: class name + + // params: + // 1: instance + + if (!lua_istable(L, 1)) + { + return luaL_typerror(L, 1, lua_typename(L, LUA_TTABLE)); + } + + cc8* type = lua_tostring(L, lua_upvalueindex(1)); + + lua_pushfstring(L, "%s: %p", type, lua_topointer(L, 1)); + + return 1; + } + + // + // Newº¯Êý½ÓÊÜn¸ö²ÎÊý£¬²¢³¢ÊÔ»ñÈ¡__init£¬½«²ÎÊý´«¸ø__init³õʼ»¯ÊµÀý¡£ + // + int PlainClass::_New(lua_State* L) + { + LUA_BIND_STATE(L); + + // upvalues: + // 1: class table + + // params: + // n: params + int n = lua_gettop(L); + + int classTable = lua_upvalueindex(1); + + lua_newtable(L); // instance table + + // instance µÄ metatable ÉèÖÃΪ class + lua_pushvalue(L, classTable); + lua_setmetatable(L, -2); + + // ÕÒµ½¹¹Ô캯Êý£¬»á´¥·¢metatable.__index,¸ù¾Ý¼Ì³ÐÁ´ÏòÉÏÕÒ¡£ + lua_getfield(L, classTable, "__init"); + if (state.IsType(-1, LUA_TFUNCTION)) + { + // stack: + // -1: __init() + // -2: instance + // -3~-n-2: params + + lua_insert(L, -2 - n); + // stack: + // -1: instance + // -2~-n-1: params + // -n-2: __init() + + lua_pushvalue(L, -1); + // stack: + // -1: instance + // -2: instance + // -3~-n-2: params + // -n-3: __init + + lua_insert(L, -3 - n); + // stack: + // -1: instance + // -2~-n-1: params + // -n-2: __init() + // -n-3: instance + + lua_insert(L, -1 - n); + // stack: + // -1~-n: params + // -n-1: instance + // -n-2: __init() + // -n-3: instance + + lua_pcall(L, n + 1, 0, 0); + } + else + { + state.Pop(); + } + + return 1; + } + + int PlainClass::_Extend(lua_State* L) + { + LUA_BIND_STATE(L); + + // upvalues: + // 1: base class + + // params: + // 1: class name + + cc8* type = state.GetValue(1, ""); + + int baseClass = lua_upvalueindex(1); + + lua_newtable(L); // class table + + // GetClassName() + lua_pushstring(L, type); + lua_pushcclosure(L, luax_c_getupvalue, 1); + lua_setfield(L, -2, "GetClassName"); + + // GetClass() + lua_pushvalue(L, -1); // class table + lua_pushcclosure(L, luax_c_getupvalue, 1); + lua_setfield(L, -2, "GetClass"); + + // New() + lua_pushvalue(L, -1); // class table + lua_pushcclosure(L, _New, 1); + lua_setfield(L, -2, "New"); + + // Extend() + lua_pushvalue(L, -1); // class table + lua_pushcclosure(L, _Extend, 1); + lua_setfield(L, -2, "Extend"); + + // .__base ÓÃÀ´Ë÷Òýµ½»ùÀà + lua_pushvalue(L, baseClass); // base class + lua_setfield(L, -2, "__base"); + + lua_pushvalue(L, -1); // class table + lua_setfield(L, -2, "__index"); + + lua_pushstring(L, type); + lua_pushcclosure(L, __tostring, 1); + lua_setfield(L, -2, "__tostring"); + + // classµÄmetatableÉèÖÃΪbaseClass + lua_pushvalue(L, baseClass); + lua_setmetatable(L, -2); + + return 1; + } + + int PlainClass::_TypeOf(lua_State* L) + { + // params: + // 1: lua instance + // 2: type string + + LUA_BIND_STATE(L); + + cc8* type = state.GetValue(2, ""); + + if (!lua_istable(L, 1)) + { + return luaL_typerror(L, 1, "Object"); + } + + lua_pushvalue(L, 1); // lua instance + + while (lua_getmetatable(L, -1)) + { + lua_getfield(L, -1, "GetClassName"); + if (lua_isfunction(L, -1)) + { + state.Call(0, 1); + cc8* name = state.GetValue(-1, ""); + if (strcmp(name, type) == 0) + { + lua_pushboolean(L, true); + return 1; + } + else + { + state.Pop(); // name + } + } + else + { + state.Pop(); + } + } + + lua_pushboolean(L, false); + return 1; + } + +#endif /*LUA_BIND_ENABLE_PLAIN_CLASS*/ + +} \ No newline at end of file diff --git a/Runtime/Lua/LuaBind/LuaBindClass.hpp b/Runtime/Lua/LuaBind/LuaBindClass.hpp new file mode 100644 index 0000000..2bf1451 --- /dev/null +++ b/Runtime/Lua/LuaBind/LuaBindClass.hpp @@ -0,0 +1,208 @@ +#ifndef __LUA_BIND_CLASS_H__ +#define __LUA_BIND_CLASS_H__ + +#include "LuaBindConfig.h" + +#if LUA_BIND_PROFILER +#include +#endif + +#include + +#include "LuaBindRef.h" +#include "LuaBindMemberRef.h" +#include "LuaBindCFunctions.h" +#include "LuaBindWatchDog.h" +#include "LuaBindUtility.h" + +namespace LuaBind +{ + + class VM; + + // + // Ðé»ùÀ࣬ΪÁËʵÏÖ¶à̬¡£ÐèÒª·ÃÎÊÏÂÃæÕâЩ½Ó¿ÚµÄÍⲿ»ùÀàÐèÒªÐé¼Ì³Ð´ËÀ֮࣬ºóÔÙÅÉÉúÁ´Öоͻá + // µ÷ÓöÔӦʵÌåµÄ·½·¨¡£×¢Òâ¼Ì³Ð´ËÀàʱ²»ÄÜʵÏÖÏÂÃæµÄ·½·¨£¬ÊµÏÖÔÚNativeClassÖУ¬ÊµÏÖ»á + // µ¼Ö¶þÒåÐÔ¡£ + // + // ÒÀ¾Ý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; + + }; + + // TODO: ½«¹«¹²²¿·ÖÌáÈ¡³öÀ´£¬²»ÒªÖظ´Éú³É´úÂë + //class NativeClassBase + //{ + //} + + // + // ÐèÒª±©Â¶¸øluaµÄnative classÐèÒª¼Ì³Ð´ËÀࡣͨ¹ýlua¹ÜÀíµÄʵÀýҪȷ±£ÒýÓüÆÊýµÄÕýÈ·ÐÔ£¬ÔÚ¶à¸öÏß³ÌÖÐÐèҪȷ + // ¶¨²»»áÎóÊÍ·Å¡£ + // + template + class NativeClass : public BASE + { + public: + + // + // ½«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 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; + +#if LUA_BIND_PROFILER + // ¶Ô¶ÑÉÏ´´½¨µÄʵÀý½øÐÐdelete±£ÏÕ¼ì²é + static void operator delete(void* pdead, size_t size); +#endif + + protected: + + NativeClass(); + virtual ~NativeClass(); + + // + // ³ÉÔ±ÒýÓùÜÀí£¬ÔÚʵÀýµÄref tableÀï¡£ÉèÖá¢È¡¡¢Çå³ý + // + void SetMemberRef(State& state, MemberRef& memRef, int idx); + bool PushMemberRef(State& state, MemberRef& memRef); + void ClearMemberRef(State& state, MemberRef& memRef); + + private: + + friend class State; + + 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); + + //------------------------------------------------------------------------------// + + // ¹«¹²ÄÚÈÝ + static int __tostring (lua_State*); + static int _GetClass (lua_State*); + static int _GetClassName (lua_State*); + + // ¹¤³§ÀàÏà¹Ø + static int __gc (lua_State*); + static int _GetRefTable (lua_State*); + +#if LUA_BIND_ENABLE_NATIVE_EXTEND + static int _New(lua_State*); + + static int _ExtendFactory (lua_State*); + static int _ExtendSingleton (lua_State*); +#endif + + //--------------------------------------------------------------------------------// + + // + // class table£¬¹¤³§ºÍµ¥Àý¶¼ÓС£ + // + static StrongRef mClassTable; + + // + // Èç¹ûÀàÊǵ¥Àý£¬Õâ¸öÓÃÀ´±£´æsingletonµÄÒýÓùØÏµ£¬ÒÔ±£Ö¤²»»á±»»ØÊÕÀàËÆÆÕͨÀàµÄref table¡£ + // µ¥ÀýµÄ³ÉÔ±ÊÇÈ«ÉúÃüÖÜÆÚµÄ£¬ËùÒÔÖ±½ÓÔÚ_LUA_BIND_STRONGREF_TABLE¡£µ¥Àý¶Ôuserdata½øÐÐ + // Retain\ReleaseºÍmember ref²Ù×÷ʱºÍ¹¤³§ÊµÀý²»Í¬£¬ÊÇ´æÔÚÏÂÃæÕâ¸öref tableÀï + // µÄ£¬Õâ¸ötableÔÚ_LUA_BIND_STRONGREF_TABLEÀï¡£ + // + static StrongRef mSingletonRefTable; + + // + // ͨ¹ýuserdata¿ÉÒÔÄõ½: + // 1: ref table + // 2: member table + // 3: class table + // + WeakRef mUserdata; + + // ͨ¹ýºó²ÅÄÜɾ³ý + WatchDog mWatchDog; + +#if LUA_BIND_PROFILER + // Íйܴ˶ÔÏóµÄÐéÄâ»ú + std::unordered_set mRefVMs; + // ±£ÏÕ£¬´ËÀàµÄÅÉÉúÀ಻ÄÜÔÚÍⲿʹÓÃdeleteÖ±½Óɾ³ý£¬¶øÓ¦¸ÃʹÓÃRelease + bool mSafer; +#endif + + }; + +#if LUA_BIND_ENABLE_PLAIN_CLASS + // + // ´¿luaÀà + // + class PlainClass + { + public: + + // + // ÓÃÀ´×¢²áÀàµÄÈë¿Úº¯Êý¡£¿ÉÒÔͨ¹ýregistry(ÀàÃû)×¢²áÀà¡£ + // + static int registry(lua_State* L); + + LUA_BIND_DECL_METHOD(__tostring); + LUA_BIND_DECL_METHOD(_Extend); + LUA_BIND_DECL_METHOD(_New); + LUA_BIND_DECL_METHOD(_TypeOf); + + }; +#endif + +} + +#endif \ No newline at end of file diff --git a/Runtime/Lua/LuaBind/LuaBindClass.inc b/Runtime/Lua/LuaBind/LuaBindClass.inc new file mode 100644 index 0000000..05bd9c7 --- /dev/null +++ b/Runtime/Lua/LuaBind/LuaBindClass.inc @@ -0,0 +1,632 @@ +namespace LuaBind +{ + + //--------------------------------------------------------------------------------// + + // + // ¶Ô²»Í¬ÀàÐÍ£¬Í¨¹ýµ÷ÓÃGetLuaClassName»ñµÃÀàÐÍÃû£¬Èç¹ûÊÇÅÉÉúÀ࣬GetClassName»á±»¸²¸Ç£¬Ö¸Ïòluax_c_getupvalue¡£ + // + template + int NativeClass::_GetClassName(lua_State* L) + { + LUA_BIND_SETUP(L, "*"); + + cc8* type = TYPE::GetClassName(); + state.Push(type); + return 1; + } + + //--------------------------------------------------------------------------------// + + // + // ×¢²á¹¤³§ºÍµ¥Àý¹²ÓеÄÀà³ÉÔ± + // + template + void NativeClass::RegisterClassShared(State& state) + { + luaL_Reg regTable[] = { + { "GetClass", _GetClass }, + { "GetClassName", _GetClassName }, + { NULL, NULL } + }; + + state.RegisterMethods(regTable); + } + + // + // ¹¤³§ÀàµÄ³ÉÔ±£¬×¢²áÔÚclass table + // + template + void NativeClass::RegisterFactoryClass(State& state) + { + luaL_Reg regTable[] = { + { "GetRefTable", _GetRefTable }, + { NULL, NULL } + }; + + state.RegisterMethods(regTable); + } + + // + // µ¥ÀýÀàµÄ³ÉÔ±£¬×¢²áÔÚclass table + // + template + void NativeClass::RegisterSingletonClass(State& state) + { + luaL_Reg regTable[] = { + { NULL, NULL } + }; + + state.RegisterMethods(regTable); + } + + template + void NativeClass::PushClassTable(State& state) + { + assert(mClassTable); + + mClassTable.PushRef(state); + } + + template + void NativeClass::SetClassTableRef(State& state, int idx) + { + mClassTable.SetRef(state, idx); + } + + template + NativeClass::NativeClass() + : mWatchDog() +#if LUA_BIND_PROFILER + , mSafer(false) +#endif + { + } + + template + NativeClass::~NativeClass() + { + } + +#if LUA_BIND_PROFILER + template + void NativeClass::operator delete(void* pdead, size_t size) + { + if (pdead == nullptr) + return; + // ¶ÑÉÏ´´½¨µÄʵÀý±ØÐëʹÓÃReleaseÊÍ·Å¡£ + TYPE* p = static_cast(pdead); + assert(p->mSafer); + ::operator delete(pdead, size); + } +#endif + + template + void NativeClass::Retain() + { + ++mWatchDog.mNativeRef; + } + + template + void NativeClass::Release() + { + if (mWatchDog.mNativeRef > 0) + --mWatchDog.mNativeRef; + if (mWatchDog) + { +#if LUA_BIND_PROFILER + mSafer = true; +#endif + delete this; + } + } + + template + template + void NativeClass::Retain(State& state, U* userdata) + { + if (PushRefTable(state)) + { + if (userdata->PushUserdata(state)) + { + lua_pushvalue(state, -1); // copy the userdata + lua_gettable(state, -3); // get the count (or nil) + u32 count = state.GetValue(-1, 0); // get the count (or 0) + lua_pop(state, 1); // pop the old count + lua_pushnumber(state, count + 1); // push the new count + lua_settable(state, -3); // save it in the table: reftable[userdata] = count + } + } + } + + template + template + void NativeClass::Release(State& state, U* userdata) + { + if (PushRefTable(state)) + { + if (userdata->PushUserdata(state)) + { + lua_pushvalue(state, -1); // copy the userdata + lua_gettable(state, -3); // get the count (or nil) + u32 count = state.GetValue(-1, 0); // get the count (or 0) + lua_pop(state, 1); // pop the old count + + // no such reference + if (count == 0) + { + state.Pop(2); // userdata, reftable + return; // nothing to do + } + + if (count > 1) { + lua_pushnumber(state, count - 1); // push the new count + } + else { + lua_pushnil(state); // maybe cause gc + } + lua_settable(state, -3); // save it in the table + + state.Pop(1); // reftable + return; + } + state.Pop(2); // nil, reftable + return; + } + } + + template + bool NativeClass::PushUserdata(State& state) + { + assert(!TYPE::IsClassSingleton()); + if (!mUserdata) + { + BindToLua(state); + return true; + } + return mUserdata.PushRef(state); + } + + template + bool NativeClass::PushMemberTable(State& state) + { + int top = state.GetTop(); + if (this->PushUserdata(state)) + { + if (lua_getmetatable(state, -1)) // ref table + { + lua_replace(state, -2); + if (lua_getmetatable(state, -1)) // member table + { + lua_replace(state, -2); + return true; + } + } + } + lua_settop(state, top); + lua_pushnil(state); + return false; + } + + 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 (lua_getmetatable(state, -1)) + { + lua_replace(state, -2); + return true; + } + } + } + return false; + } + + // ´´½¨userdata£¬²¢ÒÔ´ËÌí¼Óref table£¬member tableºÍclass table¡£ + // ref table ÊÇkvÇ¿ÒýÓÃtable£¬±£´æ¶ÔÆäËûuserdataµÄÒýÓüÆÊý£¨Í¨¹ýuserdata×÷Ϊkey£¬ + // ¼ÆÊýΪvalue£©£¬ÒÔ¼°³ÉÔ±ÒýÓà + // member table ±£´ælua´´½¨µÄʵÀýµÄ³ÉÔ± + // class table ËùÓб¾ÀàÐ͵ÄʵÀý¹²Óеĺ¯Êý±í + // + // BindToLuaÖ»»áÔÚµÚÒ»´Î×¢²á¸øLuaÐéÄâ»úʱµ÷Óᣠ+ template + void NativeClass::BindToLua(State& state) + { + // µ¥Àý²»Äܰó¶¨userdata + assert(!TYPE::IsClassSingleton()); + assert(!mUserdata); + + // ´´½¨userdata²¢ÁôÔÚÕ»¶¥£¬×¢ÒâµØÖ·Òª×ª»»ÎªTYPE*£¬Ö±½ÓÓÃthis¿ÉÄܻᵼÖ¶àÖØ¼Ì³ÐµÄÀàɥʧ¶à̬¡£ + // Èç¹ûÖ±½Ó´«this½øÈ¥£¬ÔÚ¶àÖØ¼Ì³ÐÇé¿öÏ£¬ÊÇÄò»µ½ÁíһͷµÄÐ麯Êý±íµÄ¡£ËùÒÔÕâÀïÐèÒª½«this + // ת»»ÎªÕû¸ö¶ÔÏóµÄµÍµØÖ·£¬ÕâÑù¿ÉÒÔÄõ½ÁíÒ»¸ö»ùÀàµÄÐ麯Êý±í£¬Í¨¹ýÁíÒ»¸ö»ùÀàʵÏÖ¶à̬¡£ + TYPE* p = static_cast(this); + state.PushPtrUserdata(p); + + lua_newtable(state); // ref table£¬ÎÞ·¨ÔÚlua´¦·ÃÎÊ£¬ÓÃÀ´¹ÜÀíC¶ÔÏóµÄÉúÃüÖÜÆÚ + lua_newtable(state); // member table£¬luaÖд´½¨µÄ¶ÔÏó³ÉÔ±¶¼±£´æÔÚÕâÀï + PushClassTable(state); // class table + + // stack: + // -1: class table + // -2: member table + // -3: ref table + // -4: userdata + + int top = state.GetTop(); + int memberTable = top - 1; + int refTable = top - 2; + + // ref table ×¢²á __tostring ºÍ __gc + lua_pushcfunction(state, __tostring); + lua_setfield(state, refTable, "__tostring"); + + lua_pushcfunction(state, __gc); + lua_setfield(state, refTable, "__gc"); + + // ref table µÄ __index ºÍ __newindex ÉèΪ member table + lua_pushvalue(state, memberTable); + lua_setfield(state, refTable, "__index"); + + 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µÄÈõÒýÓ㬷½±ãͨ¹ýPushLuaUserdata·½·¨·µ»Ølua¶ÔÏó + mUserdata.SetRef(state, -1); + assert(mUserdata); + + // Ôö¼ÓÒ»¸öÐéÄâ»úÒýÓã¬ÔÚGCʱ-1 + ++mWatchDog.mVMRef; +#if LUA_BIND_PROFILER + mRefVMs.insert(state.GetVM()); +#endif + } + + // + // ³ÉÔ±ÒýÓùÜÀí + // + template + void NativeClass::SetMemberRef(State& state, MemberRef& memRef, int idx) + { + ClearMemberRef(state, memRef); + if (!lua_isnil(state, idx)) + { + idx = state.AbsIndex(idx); + if (PushRefTable(state)) + { + lua_pushvalue(state, idx); + memRef.refID = luaL_ref(state, -2); + state.Pop(); // ref table + } + } + } + + template + bool NativeClass::PushMemberRef(State& state, MemberRef& memRef) + { + if (memRef) + { + if (PushRefTable(state)) + { + lua_rawgeti(state, -1, memRef.refID); + lua_replace(state, -2); // ref table + if (lua_isnil(state, -1)) + goto failed; + return true; + } + } + lua_pushnil(state); + failed: + memRef.refID = LUA_NOREF; + return false; + } + + template + bool NativeClass::PushMemberRef(State& state, int refID) + { + if (PushRefTable(state)) + { + lua_rawgeti(state, -1, refID); + lua_replace(state, -2); // ref table + if (lua_isnil(state, -1)) + goto failed; + return true; + } + lua_pushnil(state); + failed: + return false; + } + + template + void NativeClass::ClearMemberRef(State& state, MemberRef& memRef) + { + if (memRef) + { + if (PushRefTable(state)) + { + luaL_unref(state, -1, memRef.refID); + state.Pop(); // ref table + } + memRef.refID = LUA_NOREF; + } + } + + //--------------------------------------------------------------------------------// + + // + // Êͷʤ³§´´½¨µÄʵÀý + // + template + int NativeClass::__gc(lua_State* L) + { + LUA_BIND_STATE(L); + + TYPE* self = state.GetUserdata(1); + assert(self); + +#if LUA_BIND_PROFILER + std::cout << ": GC<" << TYPE::GetClassName() << ">\n"; +#endif + + if(self->mWatchDog.mVMRef > 0) + --self->mWatchDog.mVMRef; + + self->Release(); + + return 0; + } + + // + // Êä³ö¸ñʽÈçÏÂ: + // µØÖ· ÀàÃû + // + template + int NativeClass::__tostring(lua_State* L) + { + // params: + // 1: userdata + + LUA_BIND_STATE(L); + TYPE* self = state.GetUserdata(1); + if (self) + { + cc8* classname = ""; + lua_getfield(state, 1, "GetClassName"); + if (state.IsType(-1, LUA_TFUNCTION)) + { + lua_pushvalue(L, 1); // userdata + state.Call(1, 1); // ÅÉÉúÀàµÄGetClassNameº¯Êý + classname = state.GetValue(-1, ""); + } + else + { + classname = TYPE::GetClassName(); + } + lua_pushfstring(L, "%s: %p", classname, self); + return 1; + } + return 0; + } + +#if LUA_BIND_ENABLE_NATIVE_EXTEND + // ÅÉÉú³ö×ÓÀ࣬ÔÚluaÀï¶ÔÅÉÉúÀàµÄ³ÉÔ±ºÍÐÐΪ½øÐÐÖØÐÂÉè¼Æ£¬µ«ÊDZ£Ö¤ÁËuserdataµÄͳһ¡£Native classµÄÅÉÉúÌṩ__initÖ§³Ö£¬ÔÚ + // nativeʵÌå´´½¨ºó¿ÉÒÔʹÓÃ__init½øÐгõʼ»¯£¬ÅÉÉúÀàÓµÓкͻùÀàÒ»ÑùµÄNew²ÎÊýÁÐ±í£¬ÇÒnative¶ÔÏóÊÇÒ»ÑùµÄÀàÐÍ¡£ + template + int NativeClass::_ExtendFactory(lua_State* L) + { + // upvalues: + // 1: base class + + // params: + // 1: class name + + int baseClass = lua_upvalueindex(1); + + lua_newtable(L); // class table + + int inheritClass = lua_gettop(L); + + // .GetClassName() + cc8* type = lua_tostring(L, 1); + lua_pushstring(L, type); + lua_pushcclosure(L, luax_c_getupvalue, 1); + lua_setfield(L, -2, "GetClassName"); + + // .GetClass() + lua_pushvalue(L, inheritClass); + lua_pushcclosure(L, luax_c_getupvalue, 1); + lua_setfield(L, -2, "GetClass"); + + // .Extend() + lua_pushvalue(L, inheritClass); + lua_pushcclosure(L, _ExtendFactory, 1); + lua_setfield(L, -2, "Extend"); + + // .New() + lua_pushvalue(L, inheritClass); + lua_getfield(L, baseClass, "New"); + lua_pushcclosure(L, _New, 2); + lua_setfield(L, -2, "New"); + + // __base = baseClass + lua_pushvalue(L, baseClass); + lua_setfield(L, -2, "__base"); + + // __index = inheritClass + lua_pushvalue(L, inheritClass); + lua_setfield(L, -2, "__index"); + + // metatable is baseClass + lua_pushvalue(L, baseClass); + lua_setmetatable(L, inheritClass); + + return 1; + } + + template + int NativeClass::_ExtendSingleton(lua_State* L) + { + // upvalues: + // 1: base class + + // params: + // 1: class name + + int baseClass = lua_upvalueindex(1); + + lua_newtable(L); // class name + + int inheritClass = lua_gettop(L); + + // .GetClassName() + cc8* type = lua_tostring(L, 1); + lua_pushstring(L, type); + lua_pushcclosure(L, luax_c_getupvalue, 1); + lua_setfield(L, -2, "GetClassName"); + + // .GetClass() + lua_pushvalue(L, inheritClass); + lua_pushcclosure(L, luax_c_getupvalue, 1); + lua_setfield(L, -2, "GetClass"); + + // .Extend() + lua_pushvalue(L, inheritClass); + lua_pushcclosure(L, _ExtendFactory, 1); + lua_setfield(L, -2, "Extend"); + + // __base = baseClass + lua_pushvalue(L, baseClass); + lua_setfield(L, -2, "__base"); + + // __index = inheritClass + lua_pushvalue(L, inheritClass); + lua_setfield(L, -2, "__index"); + + // metatable is baseClass + lua_pushvalue(L, baseClass); + lua_setmetatable(L, inheritClass); + + return 1; + } + + template + int NativeClass::_New(lua_State* L) + { + LUA_BIND_STATE(L); + + // upvalues: + // 1: class table + // 2: original New() + + // stack: + // -1~-n: args + + int n = lua_gettop(L); // n args + + lua_pushvalue(L, lua_upvalueindex(2)); + if (state.IsType(-1, LUA_TFUNCTION)) + { + // stack: + // -1: New + // -2~-1-n: args + + state.PushValues(-1 - n, n); + + // stack: + // -1~-n: args + // -n-1: New + // -n-2~-1-2n: args + + state.Call(n, 1); + + // stack: + // -1: userdata + // -2~-1-n: args + + // reset member table's metatable to class table + if (state.IsType(-1, LUA_TUSERDATA)) + { + if (lua_getmetatable(L, -1)) // ref table + { + if (lua_getmetatable(L, -1)) // member table + { + lua_pushvalue(L, lua_upvalueindex(1)); // class table + lua_setmetatable(L, -2); + state.Pop(); // member table + } + state.Pop(); // ref table + } + + // stack: + // -1: userdata + // -2~-1-n: args + + int args = state.AbsIndex(-1 - n); + + // ³¢ÊÔµ÷ÓÃ__initº¯Êý + lua_getfield(L, lua_upvalueindex(1), "__init"); + + if (state.IsType(-1, LUA_TFUNCTION)) + { + lua_pushvalue(L, -2); // userdata + state.PushValues(args, n); + state.Call(n + 1, 0); + } + else + state.Pop(); + + } + + return 1; + } + return 0; + } + +#endif /*LUA_BIND_ENABLE_NATIVE_EXTEND*/ + + template + int NativeClass::_GetClass(lua_State* L) + { + LUA_BIND_STATE(L); + if (!mClassTable) + lua_pushnil(L); + else + mClassTable.PushRef(state); + return 1; + } + + template + int NativeClass::_GetRefTable(lua_State* L) + { + LUA_BIND_STATE(L); + TYPE* self = state.GetUserdata(1); + bool success = self->PushRefTable(state); + if (!success) + lua_pushnil(L); + return 1; + } + + template StrongRef NativeClass::mClassTable; // class table + template StrongRef NativeClass::mSingletonRefTable; // µ¥Àý + +} \ No newline at end of file diff --git a/Runtime/Lua/LuaBind/LuaBindConfig.h b/Runtime/Lua/LuaBind/LuaBindConfig.h new file mode 100644 index 0000000..ded072e --- /dev/null +++ b/Runtime/Lua/LuaBind/LuaBindConfig.h @@ -0,0 +1,65 @@ +#ifndef __LUA_BIND_TYPE_H__ +#define __LUA_BIND_TYPE_H__ + +#include + +extern "C" { +#include "ThirdParty/lua51/lua.h" +#include "ThirdParty/lua51/lualib.h" +#include "ThirdParty/lua51/lauxlib.h" +} + +#include + +namespace LuaBind +{ + + typedef unsigned int uint; + typedef unsigned long uintptr; + typedef long sintptr; + + typedef const char cc8; + + typedef unsigned char u8; + typedef unsigned short u16; + typedef unsigned int u32; + typedef unsigned long long u64; + + typedef signed char s8; + typedef signed short s16; + typedef signed int s32; + typedef signed long long s64; + +#ifdef _WIN32 + #define LUA_BIND_FINAL final + #define LUA_BIND_LIBRARY_EXPORT __declspec(dllexport) + #define LUA_BIND_LIBRARY_IMPORT __declspec(dllimport) + #define LUA_BIND_FORCE_INLINE __forceinline + #define LUA_BIND_RESTRICT __restrict + #define LUA_BIND_ATTRIBUTE_USED + #define LUA_BIND_ABSTRACT + #define LUA_BIND_API LUA_BIND_LIBRARY_EXPORT +#else + #define LUA_BIND_FINAL final + #define LUA_BIND_LIBRARY_EXPORT __attribute__((visibility("default"))) + #define LUA_BIND_LIBRARY_IMPORT + #define LUA_BIND_FORCE_INLINE __attribute__((always_inline)) inline + #define LUA_BIND_RESTRICT __restrict__ + #define LUA_BIND_ATTRIBUTE_USED __attribute__((used)) + #define LUA_BIND_ABSTRACT + #define LUA_BIND_API LUA_BIND_LIBRARY_EXPORT +#endif + +#define LUA_BIND_ENABLE_NATIVE_EXTEND 0 +#define LUA_BIND_ENABLE_PLAIN_CLASS 0 +#define LUA_BIND_ENABLE_PLAIN_ENUM 0 + +#define LUA_BIND_PROFILER 1 + +} + +#if LUA_BIND_PROFILER +#include +#endif + +#endif // __LUA_BIND_TYPE_H__ \ No newline at end of file diff --git a/Runtime/Lua/LuaBind/LuaBindEnum.cpp b/Runtime/Lua/LuaBind/LuaBindEnum.cpp new file mode 100644 index 0000000..63e2567 --- /dev/null +++ b/Runtime/Lua/LuaBind/LuaBindEnum.cpp @@ -0,0 +1,67 @@ +#include "LuaBindEnum.h" +#include "LuaBindState.h" +#include "LuaBindVM.h" + +namespace LuaBind +{ + + // + // Ö»¶ÁmetatableµÄ__index + // + int _rmt__index(lua_State* L) + { + // params: + // 1: enum table + // 2: key + + // upvalues: + // 1: metatable + + int mt = lua_upvalueindex(1); + lua_pushvalue(L, 2); + lua_rawget(L, mt); + + return 1; + } + + int _rmt__newindex(lua_State* L) + { + // upvalue: + // 1: enum table name + + cc8* name = lua_tostring(L, lua_upvalueindex(1)); + + return luaL_error(L, "Enum called \"%s\" is readonly.", name); + } + + //--------------------------------------------------------------------------------// +#if LUA_BIND_ENABLE_PLAIN_ENUM + int PlainEnum::registry(lua_State* L) + { + // params: + // 1: enum name + // 2: metatable + + cc8* name = luaL_checkstring(L, 1); + + if (!lua_istable(L, 2)) + { + return luaL_error(L, "Create plain enum failed. Require table, but get %s", luaL_typename(L, 2)); + } + + lua_pushvalue(L, -1); + lua_setfield(L, -2, "__index"); + + lua_pushstring(L, name); + lua_pushcclosure(L, _rmt__newindex, 1); + lua_setfield(L, -2, "__newindex"); + + lua_newtable(L); // enum table + + lua_pushvalue(L, -2); // metatable + lua_setmetatable(L, -2); + + return 1; + } +#endif +} \ No newline at end of file diff --git a/Runtime/Lua/LuaBind/LuaBindEnum.h b/Runtime/Lua/LuaBind/LuaBindEnum.h new file mode 100644 index 0000000..122e845 --- /dev/null +++ b/Runtime/Lua/LuaBind/LuaBindEnum.h @@ -0,0 +1,39 @@ +#ifndef __LUA_BIND_ENUM_H__ +#define __LUA_BIND_ENUM_H__ + +#include "LuaBindConfig.h" + +namespace LuaBind +{ + + // + // µ¼³öö¾Ù£¬Ã¶¾ÙÊÇÒ»À಻¿ÉÐÞ¸ÄÕûÐͼ¯ºÏ£¬Ã¶¾ÙµÄÖµÔÚ + // + struct Enum + { + cc8* name; + int value; + }; + + extern int _rmt__index(lua_State* L); + + extern int _rmt__newindex(lua_State* L); + + //--------------------------------------------------------------------------------// + +#if LUA_BIND_ENABLE_PLAIN_ENUM + // + // ´¿luaµÄö¾Ù£¬´´½¨²»¿ÉÐ޸ĵÄtable + // + class PlainEnum + { + public: + + static int registry(lua_State* L); + + }; +#endif + +} + +#endif \ No newline at end of file diff --git a/Runtime/Lua/LuaBind/LuaBindGlobalState.h b/Runtime/Lua/LuaBind/LuaBindGlobalState.h new file mode 100644 index 0000000..fa3cc4f --- /dev/null +++ b/Runtime/Lua/LuaBind/LuaBindGlobalState.h @@ -0,0 +1,7 @@ +#ifndef __LUA_BIND_GLOBAL_STATE_H__ +#define __LUA_BIND_GLOBAL_STATE_H__ + +// Ë÷Òýµ½luaÀïµÄglobal_State +typedef struct global_State global_State; + +#endif \ No newline at end of file diff --git a/Runtime/Lua/LuaBind/LuaBindInternal.h b/Runtime/Lua/LuaBind/LuaBindInternal.h new file mode 100644 index 0000000..1d4a226 --- /dev/null +++ b/Runtime/Lua/LuaBind/LuaBindInternal.h @@ -0,0 +1,12 @@ +#ifndef __LUA_BIND_INTERNAL_H__ +#define __LUA_BIND_INTERNAL_H__ + +// +// ¶ÔluaÔ´´úÂëµÄÉî¶ÈʹÓà +// +extern "C" +{ +#include "ThirdParty/lua51/lstate.h" +} + +#endif \ No newline at end of file diff --git a/Runtime/Lua/LuaBind/LuaBindMemberRef.cpp b/Runtime/Lua/LuaBind/LuaBindMemberRef.cpp new file mode 100644 index 0000000..e680cce --- /dev/null +++ b/Runtime/Lua/LuaBind/LuaBindMemberRef.cpp @@ -0,0 +1,16 @@ +#include "LuaBindMemberRef.h" + +namespace LuaBind +{ + + MemberRef::MemberRef() + : refID(LUA_NOREF) + { + } + + MemberRef::~MemberRef() + { + + } + +} \ No newline at end of file diff --git a/Runtime/Lua/LuaBind/LuaBindMemberRef.h b/Runtime/Lua/LuaBind/LuaBindMemberRef.h new file mode 100644 index 0000000..045d6ef --- /dev/null +++ b/Runtime/Lua/LuaBind/LuaBindMemberRef.h @@ -0,0 +1,27 @@ +#ifndef __LUA_BIND_MEMBER_REF_H__ +#define __LUA_BIND_MEMBER_REF_H__ + +#include "LuaBindConfig.h" + +namespace LuaBind +{ + + // + // ʵÀýµÄref table±£´æµÄmember ref¡£ÓÉluax class×ö¾ßÌåµÄ¹ÜÀí¡£ÊµÀýµÄref tableÊÇÇ¿ÒýÓã¬ÓÃÀ´¹ÜÀíÀïÃæmemberµÄÉúÃüÖÜÆÚ¡£ + // ÓÃÀ´ÔÚluaºÍnativeÖ®¼ä½øÐÐÊý¾Ý¹µÍ¨¡£ + // + class MemberRef + { + public: + MemberRef(); + ~MemberRef(); + + inline operator bool() { return refID != LUA_NOREF; }; + + int refID; + + }; + +} + +#endif \ No newline at end of file diff --git a/Runtime/Lua/LuaBind/LuaBindRef.cpp b/Runtime/Lua/LuaBind/LuaBindRef.cpp new file mode 100644 index 0000000..00a65d0 --- /dev/null +++ b/Runtime/Lua/LuaBind/LuaBindRef.cpp @@ -0,0 +1,72 @@ +#include "LuaBindVM.h" +#include "LuaBindRef.h" + +namespace LuaBind +{ + + Ref::Ref(int mode) + : mRefID(LUA_NOREF) + , mMode(mode) + { + } + + Ref::~Ref() + { + } + + Ref::operator bool() + { + return (mRefID != LUA_NOREF); + } + + bool Ref::PushRef(State& state) + { + assert(mRefID != LUA_NOREF); + + VM* vm = state.GetVM(); + if (!vm) return false; + if (mMode == STRONG_REF) + { + RefTable& table = vm->GetStrongRefTable(); + table.PushRef(state, mRefID); + } + else if (mMode == WEAK_REF) + { + RefTable& table = vm->GetWeakRefTable(); + table.PushRef(state, mRefID); + } + else + { + 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) + { + } + + WeakRef::WeakRef() + : Ref(WEAK_REF) + { + } + +} diff --git a/Runtime/Lua/LuaBind/LuaBindRef.h b/Runtime/Lua/LuaBind/LuaBindRef.h new file mode 100644 index 0000000..93b30be --- /dev/null +++ b/Runtime/Lua/LuaBind/LuaBindRef.h @@ -0,0 +1,62 @@ +#ifndef __LUA_BIND_REF_H__ +#define __LUA_BIND_REF_H__ + +#include "LuaBindConfig.h" +#include "LuaBindState.h" + +namespace LuaBind +{ + + // + // ÒýÓ㬴æÔÚLUA_REGISTRYINDEXÏÂÃæµÄÁ½¸ö±íÀï + // + class Ref + { + public: + + enum RefMode + { + STRONG_REF, + WEAK_REF + }; + + Ref(int mode = STRONG_REF); + virtual ~Ref(); + + operator bool(); + + void SetRef(State& state, int idx); + bool PushRef(State& state); + + int GetRefID(); + + private: + + int mRefID; // luaL_ref + int mMode; // strong or weak + + }; + + // + // Ç¿ÒýÓã¬ÔÚLUA_REGISTRYINDEX["_LUA_BIND_STRONGREF_TABLE"]À±£Ö¤lua object²»»á±»»ØÊÕ¡£ + // + class StrongRef: public Ref + { + public: + StrongRef(); + + }; + + // + // ÈõÒýÓã¬ÔÚLUA_REGISTRYINDEX["_LUA_BIND_WEAKREF_TABLE"]À²»Ó°Ïìlua objectµÄ»ØÊÕ£¬Ö»ÊÇ×÷Ϊһ¸ö·½±ãÈ¡lua objectµÄÓ³Éä¡£ + // + class WeakRef : public Ref + { + public: + WeakRef(); + + }; + +} + +#endif \ No newline at end of file diff --git a/Runtime/Lua/LuaBind/LuaBindRefTable.cpp b/Runtime/Lua/LuaBind/LuaBindRefTable.cpp new file mode 100644 index 0000000..39ef9ab --- /dev/null +++ b/Runtime/Lua/LuaBind/LuaBindRefTable.cpp @@ -0,0 +1,120 @@ +#include "LuaBindRefTable.h" +#include "LuaBindState.h" + +namespace LuaBind +{ + + RefTable::RefTable() + : mState(nullptr) + { + } + + RefTable::~RefTable() + { + } + + void RefTable::Init(State& state, cc8* name, cc8* mode) + { + assert(!mState); + assert(name); + + mName = name; + mMode = 0; + for (int i = 0; mode && mode[i]; ++i) + { + if (mode[i] == 'k') mMode |= WEAK_KEY; + else if (mode[i] == 'v') mMode |= WEAK_VALUE; + } + mState = state.GetHandle(); + + state.GetField(LUA_REGISTRYINDEX, name); // register[mName] + if (state.IsNil(-1)) + { + state.Pop(); + + lua_newtable(state); // ref table + int ridx = state.AbsIndex(-1); + lua_newtable(state); // metatable of ref table + int idx = state.AbsIndex(-1); + + // __mode + if (mode) + { + state.Push(mode); + state.SetField(idx, "__mode"); + } + + state.Settop(idx); + lua_setmetatable(state, ridx); + + state.Settop(ridx); + state.SetField(LUA_REGISTRYINDEX, name); + } + else + { + state.Pop(); + } + } + + bool RefTable::IsKeyWeak() + { + assert(mState); + + return mMode & WEAK_KEY; + } + + bool RefTable::IsValueWeak() + { + assert(mState); + + return mMode & WEAK_VALUE; + } + + int RefTable::Ref(State& state, int idx) + { + assert(mState); + + idx = state.AbsIndex(idx); + state.GetField(LUA_REGISTRYINDEX, mName); // ref table + lua_pushvalue(state, idx); // stuff + int refID = luaL_ref(state, -2); + assert(refID != LUA_NOREF); + state.Pop(); + return refID; + } + + void RefTable::Unref(State& state, int refID) + { + assert(mState); + + state.GetField(LUA_REGISTRYINDEX, mName); // ref table + luaL_unref(state, -1, refID); + state.Pop(); + return; + } + + void RefTable::PushRefTable(State& state) + { + assert(mState); + + lua_getfield(state, LUA_REGISTRYINDEX, mName); + } + + void RefTable::PushRef(State& state, int refID) + { + assert(mState); + + lua_getfield(state, LUA_REGISTRYINDEX, mName); + lua_rawgeti(state, -1, refID); + lua_replace(state, -2); + } + + void RefTable::Clear(State& state) + { + assert(mState); + + lua_newtable(state); + state.SetField(LUA_REGISTRYINDEX, mName); + } + +} \ No newline at end of file diff --git a/Runtime/Lua/LuaBind/LuaBindRefTable.h b/Runtime/Lua/LuaBind/LuaBindRefTable.h new file mode 100644 index 0000000..0d4c2d4 --- /dev/null +++ b/Runtime/Lua/LuaBind/LuaBindRefTable.h @@ -0,0 +1,67 @@ +#ifndef __LUA_BIND_REFTABLE_H__ +#define __LUA_BIND_REFTABLE_H__ + +#include "LuaBindConfig.h" + +namespace LuaBind +{ + + class State; + + // + // ref table ¹ÜÀí£¬¶Ôstrong ref tableºÍweak ref tableÁ½¸ötableµÄ´úÀí¡£ + // + class RefTable + { + public: + + enum + { + WEAK_KEY = 1, + WEAK_VALUE = 1 << 1 + }; + + RefTable(); + ~RefTable(); + + inline operator bool() { return mState; }; + + void Init(State& state, 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); + + // + // ½«´Ë ref table ·ÅÔÚÕ»¶¥ + // + void PushRefTable(State& state); + + // + // ½« reftable[refID] ·ÅÔÚÕ»¶¥ + // + void PushRef(State& state, int refID); + + // + // Çå¿Õ ref table£¬±í»¹ÁôÔÚLUA_REGISTRYINDEX[mName] + // + void Clear(State& state); + + private: + + friend class State; + + lua_State* mState; // ÓÃÀ´×öһЩȷÈϹ¤×÷ + cc8* mName; // ref tableµÄÃû³Æ + int mMode; // ref tableµÄÀàÐÍ + + }; + +} + +#endif \ No newline at end of file diff --git a/Runtime/Lua/LuaBind/LuaBindState.cpp b/Runtime/Lua/LuaBind/LuaBindState.cpp new file mode 100644 index 0000000..4ee87f4 --- /dev/null +++ b/Runtime/Lua/LuaBind/LuaBindState.cpp @@ -0,0 +1,893 @@ +#include "LuaBindEnum.h" +#include "LuaBindState.h" +#include "LuaBindVM.h" +#include "LuaBindClass.hpp" +#include "LuaBindInternal.h" + +#include + +namespace LuaBind +{ + + State::State(lua_State* state) + : mState(state) + { + assert(state); + } + + State::State(const State& state) + : mState(state.mState) + { + assert(state.mState); + } + + State::~State() + { + } + + void State::OpenLibs() + { + luaL_openlibs(mState); + } + + global_State* State::GetGlobalState() + { + return G(mState); + } + + VM* State::GetVM() + { + return VM::TryGetVM(G(mState)); + } + + void State::PushGlobalNamespace() + { +#if false + int top = GetTop(); + + lua_newtable(mState); // pseudo namespace table + int pnt = GetTop(); + + lua_newtable(mState); // metatable + int mt = GetTop(); + + // __index = _G + // __newindex = _G + lua_pushvalue(mState, LUA_GLOBALSINDEX); + lua_pushvalue(mState, LUA_GLOBALSINDEX); + lua_setfield(mState, mt, "__index"); + lua_setfield(mState, mt, "__newindex"); + + lua_setmetatable(mState, pnt); + + // stack: + // -1 pseudo global namespace +#else + lua_pushvalue(mState, LUA_GLOBALSINDEX); +#endif + } + + void State::PushNamespace(cc8* name) + { + assert(IsNamespace(-1)); + + int top = GetTop(); + + lua_getfield(mState, -1, name); + if (lua_isnil(mState, -1)) + { + lua_pop(mState, 1); + + lua_newtable(mState); + lua_pushvalue(mState, -1); + lua_setfield(mState, top, name); + } + + // stack: + // -1 namespace + } + + void State::PopNamespace() + { + assert(lua_istable(mState, -1)); + lua_pop(mState, 1); + } + + bool State::IsNamespace(int idx) + { + return lua_istable(mState, idx); + } + + void State::DoString(const std::string& code) + { + luaL_dostring(mState, code.c_str()); + } + + void State::DoFile(const std::string & path) + { + luaL_dofile(mState, path.c_str()); + } + + int State::AbsIndex(int idx) + { +/* +#define abs_index(mState, i) ((i) > 0 || (i) <= LUA_REGISTRYINDEX ? (i) : \ + lua_gettop(mState) + (i) + 1) +*/ + if (idx < 0) { + //return lua_gettop(mState) + idx + 1; + return ((idx) > 0 || (idx) <= LUA_REGISTRYINDEX ? (idx) : \ + lua_gettop(mState) + (idx)+1); + } + return idx; + } + + void State::Call(int nArgs, int nResults) + { + lua_pcall(mState, nArgs, nResults, 0); + } + + void State::PushNil() + { + lua_pushnil(mState); + } + + void State::Push(bool value) + { + lua_pushboolean(mState, value ? 1 : 0); + } + + void State::Push(cc8* value) + { + lua_pushstring(mState, value); + } + + void State::Push(double value) + { + lua_pushnumber(mState, value); + } + + void State::Push(float value) + { + lua_pushnumber(mState, value); + } + + void State::Push(int value) + { + lua_pushnumber(mState, value); + } + + void State::Push(u16 value) + { + lua_pushnumber(mState, value); + } + + void State::Push(u32 value) + { + lua_pushnumber(mState, value); + } + + void State::Push(u64 value) + { + lua_pushnumber(mState, (double)value); + } + + void State::Push(s64 value) + { + lua_pushinteger(mState, value); + } + + void State::Push(uintptr value) + { + lua_pushlightuserdata(mState, (void*)value); + } + + void State::Push(lua_CFunction value) + { + lua_pushcfunction(mState, value); + } + + void State::Push(void* data, size_t size) + { + lua_pushlstring(mState, (cc8*)data, size); + } + + void State::Push(const void* value) + { + lua_pushlightuserdata(mState, (void*)value); + } + + void State::Push(std::string value) + { + Push(value.c_str()); + } + + void State::PushValues(int idx, int n) + { + idx = AbsIndex(idx); + for (int i = idx; i < idx + n; ++i) + lua_pushvalue(mState, i); + } + + void State::Pop(int n /* = 1 */) + { + lua_pop(mState, n); + } + + bool State::IsNil(int idx) + { + return lua_isnil(mState, idx); + } + + bool State::IsNilOrNone(int idx) + { + int t = lua_type(mState, idx); + return ((t == LUA_TNONE) || (t == LUA_TNIL)); + } + + bool State::IsTableOrUserdata(int idx) + { + int check = lua_type(mState, idx); + return ((check == LUA_TTABLE) || (check == LUA_TUSERDATA)); + } + + bool State::IsTrueOrNotNil(int idx) + { + if (lua_isboolean(mState, idx)) { + return lua_toboolean(mState, idx) ? true : false; + } + return !lua_isnil(mState, idx); + } + + bool State::IsType(int idx, int type) + { + return (lua_type(mState, idx) == type); + } + + bool State::IsType(int idx, cc8* name, int type) + { + return this->HasField(idx, name, type); + } + + bool State::IsValid() + { + return (mState != 0); + } + + void State::Settop(int idx) + { + lua_settop(mState, idx); + } + + int State::GetTop() + { + return lua_gettop(mState); + } + + bool State::HasField(int idx, cc8* name) { + + lua_getfield(mState, idx, name); + bool hasField = (lua_isnil(mState, -1) == false); + lua_pop(mState, 1); + + return hasField; + } + + bool State::HasField(int idx, int key) { + + this->GetField(idx, key); + bool hasField = (lua_isnil(mState, -1) == false); + lua_pop(mState, 1); + + return hasField; + } + + bool State::HasField(int idx, cc8* name, int type) { + + lua_getfield(mState, idx, name); + bool hasField = (lua_type(mState, -1) == type); + lua_pop(mState, 1); + + return hasField; + } + + bool State::HasField(int idx, int key, int type) { + + this->GetField(idx, key); + bool hasField = (lua_type(mState, -1) == type); + lua_pop(mState, 1); + + return hasField; + } + + bool State::HasKeys(int idx) { + + idx = this->AbsIndex(idx); + + lua_pushnil(mState); /* first key */ + if (lua_next(mState, idx) != 0) { + lua_pop(mState, 2); + return true; + } + return false; + } + + void State::GetField(int idx, cc8* name) + { + lua_getfield(mState, idx, name); + } + + void State::GetField(int idx, int key) + { + idx = this->AbsIndex(idx); + + lua_pushinteger(mState, key); + lua_gettable(mState, idx); + } + + std::string State::GetField(int idx, cc8* key, cc8* default_value) + { + std::string str; + if (this->GetFieldWithType(idx, key, LUA_TSTRING)) { + str = lua_tostring(mState, -1); + lua_pop(mState, 1); + } + else { + str = default_value; + } + return str; + } + + std::string State::GetField(int idx, int key, cc8* default_value) + { + std::string str; + if (this->GetFieldWithType(idx, key, LUA_TSTRING)) { + str = lua_tostring(mState, -1); + lua_pop(mState, 1); + } + else { + str = default_value; + } + return str; + } + + std::string State::GetField(int idx, cc8* key, const std::string& value) + { + std::string str; + if (this->GetFieldWithType(idx, key, LUA_TSTRING)) { + str = lua_tostring(mState, -1); + lua_pop(mState, 1); + } + else { + str = value; + } + return str; + } + + std::string State::GetField(int idx, int key, const std::string& value) + { + std::string str; + if (this->GetFieldWithType(idx, key, LUA_TSTRING)) { + str = lua_tostring(mState, -1); + lua_pop(mState, 1); + } + else { + str = value; + } + return str; + } + + bool State::GetFieldWithType(int idx, cc8* name, int type) + { + lua_getfield(mState, idx, name); + if (lua_type(mState, -1) != type) { + lua_pop(mState, 1); + return false; + } + return true; + } + + bool State::GetFieldWithType(int idx, int key, int type) + { + this->GetField(idx, key); + if (lua_type(mState, -1) != type) { + lua_pop(mState, 1); + return false; + } + return true; + } + + void State::SetField(int idx, cc8* key) + { + if (IsTableOrUserdata(idx)) + { + idx = AbsIndex(idx); + lua_setfield(mState, idx, key); + } + } + + cc8* State::GetLuaTypeName(int type) + { + switch (type) { + case LUA_TNONE: return "none"; + case LUA_TNIL: return "nil"; + case LUA_TBOOLEAN: return "boolean"; + case LUA_TLIGHTUSERDATA: return "lightuserdata"; + case LUA_TNUMBER: return "number"; + case LUA_TSTRING: return "string"; + case LUA_TTABLE: return "table"; + case LUA_TFUNCTION: return "function"; + case LUA_TUSERDATA: return "userdata"; + case LUA_TTHREAD: return "thread"; + } + return "unknown"; + } + + + bool State::GetSubfieldWithType(int idx, cc8* format, int type, ...) + { + va_list args; + va_start(args, type); + + idx = this->AbsIndex(idx); + lua_pushvalue(this->mState, idx); + + for (cc8* c = format; *c; ++c) { + switch (*c) { + // number + case 'N': + lua_pushnumber(this->mState, va_arg(args, int)); + lua_gettable(this->mState, -1); + break; + + // string + case 'S': + lua_getfield(this->mState, -1, va_arg(args, char*)); + break; + + default: + lua_pushnil(this->mState); + } + + if (lua_isnil(this->mState, -1)) break; + lua_replace(this->mState, -2); + } + va_end(args); + if (lua_type(this->mState, -1) != type) { + lua_pop(this->mState, 1); + return false; + } + return true; + } + + bool State::CheckParams(int idx, cc8* format) + { + idx = AbsIndex(idx); + + for (int i = 0; format[i]; ++i) { + + int pos = idx + i; + int type = LUA_TNIL; + int expected = LUA_TNONE; + + if (pos <= GetTop()) { + type = lua_type(mState, pos); + } + + switch (format[i]) { + + // boolean + case 'B': + if (type != LUA_TBOOLEAN) expected = LUA_TBOOLEAN; + break; + + // coroutine + case 'C': + if (type != LUA_TTHREAD) expected = LUA_TTHREAD; + break; + + // function + case 'F': + if (type != LUA_TFUNCTION) expected = LUA_TFUNCTION; + break; + + // light userdata + case 'L': + if (type != LUA_TLIGHTUSERDATA) expected = LUA_TLIGHTUSERDATA; + break; + + // number + case 'N': + if (type != LUA_TNUMBER) expected = LUA_TNUMBER; + break; + + // string + case 'S': + if (type != LUA_TSTRING) expected = LUA_TSTRING; + break; + + // table + case 'T': + if (type != LUA_TTABLE) expected = LUA_TTABLE; + break; + + // userdata + case 'U': + if (type != LUA_TUSERDATA) expected = LUA_TUSERDATA; + break; + + // any type + case '*': + case '.': + break; + } + + if (expected != LUA_TNONE) { + return false; + } + } + + return true; + } + + template <> + bool State::GetValue < bool >(int idx, const bool value) { + + if (this->IsType(idx, LUA_TBOOLEAN)) { + return (lua_toboolean(this->mState, idx) != 0); + } + return value; + } + + static std::string s_str; + template <> + cc8* State::GetValue < cc8* >(int idx, const cc8* value) { + + if (this->IsType(idx, LUA_TSTRING)) { + return lua_tostring(this->mState, idx); + } + + if (this->IsType(idx, LUA_TNUMBER)) { + if (luax_isinteger(mState, -1)) { + int num = lua_tointeger(this->mState, idx); + s_str = std::to_string(num); + cc8* str = s_str.c_str(); + return str; + } + else { + float num = lua_tonumber(this->mState, idx); + s_str = std::to_string(num); + cc8* str = s_str.c_str(); + return str; + } + } + + if (this->IsType(idx, LUA_TBOOLEAN)) { + bool b = lua_toboolean(this->mState, idx); + return b ? "true" : "false"; + } + + if (this->IsType(idx, LUA_TNIL)) { + return "NIL"; + } + + return value; + } + + template <> + std::string State::GetValue(int idx, const std::string value) + { + std::string str; + if (lua_type(this->mState, idx) == LUA_TSTRING) { + str = lua_tostring(this->mState, idx); + } + else { + str = value; + } + return str; + } + + template <> + double State::GetValue < double >(int idx, const double value) + { + if (this->IsType(idx, LUA_TNUMBER)) { + return lua_tonumber(this->mState, idx); + } + return value; + } + + template <> + float State::GetValue < float >(int idx, const float value) + { + if (this->IsType(idx, LUA_TNUMBER)) { + return (float)lua_tonumber(this->mState, idx); + } + return value; + } + + template <> + s8 State::GetValue < s8 >(int idx, const s8 value) + { + if (this->IsType(idx, LUA_TNUMBER)) { + return (s8)lua_tonumber(this->mState, idx); + } + return value; + } + + + template <> + s16 State::GetValue < s16 >(int idx, const s16 value) + { + if (this->IsType(idx, LUA_TNUMBER)) { + return (s16)lua_tonumber(this->mState, idx); + } + return value; + } + + + template <> + s32 State::GetValue < s32 >(int idx, const s32 value) + { + if (this->IsType(idx, LUA_TNUMBER)) { + return (s32)lua_tonumber(this->mState, idx); + } + return value; + } + + template <> + s64 State::GetValue < s64 >(int idx, const s64 value) + { + if (this->IsType(idx, LUA_TNUMBER)) { + return (s64)lua_tonumber(this->mState, idx); + } + return value; + } + + template <> + u8 State::GetValue < u8 >(int idx, const u8 value) + { + if (this->IsType(idx, LUA_TNUMBER)) { + return (u8)lua_tonumber(this->mState, idx); + } + return value; + } + + template <> + u16 State::GetValue < u16 >(int idx, const u16 value) + { + if (this->IsType(idx, LUA_TNUMBER)) { + return (u16)lua_tonumber(this->mState, idx); + } + return value; + } + + template <> + u32 State::GetValue < u32 >(int idx, const u32 value) + { + if (this->IsType(idx, LUA_TNUMBER)) { + return (u32)lua_tonumber(this->mState, idx); + } + return value; + } + + template <> + u64 State::GetValue < u64 >(int idx, const u64 value) + { + if (this->IsType(idx, LUA_TNUMBER)) { + return (u64)lua_tonumber(this->mState, idx); + } + return value; + } + + template <> + const void* State::GetValue < const void* >(int idx, const void* value) + { + if (this->IsType(idx, LUA_TLIGHTUSERDATA)) { + return (void*)lua_touserdata(this->mState, idx); + } + return value; + } + + void State::PushPtrUserdata(void* ptr) + { + void** handle = (void**)lua_newuserdata(this->mState, sizeof(void*)); + assert(handle); + (*handle) = ptr; + } + + void State::RegisterEnum(cc8* name, Enum* en) + { + assert(name); + assert(en); + + // short name + lua_State* L = mState; + + int top = GetTop(); + + lua_newtable(L); // enum table + + int et = GetTop(); + + lua_newtable(L); // matatable + + // ËùÓÐö¾Ù¶¼´æÔÚmetatableÏ£¬ÐÞ¸Äʱ´¥·¢__newindex±¨´í + for (; en->name; ++en) + { + lua_pushinteger(L, en->value); + lua_setfield(L, -2, en->name); + } + + // __index + //lua_pushvalue(L, -1); // metatable + //lua_pushcclosure(L, _rmt__index, 1); + lua_pushvalue(L, -1); + lua_setfield(L, -2, "__index"); + + // __newinedx + lua_pushstring(L, name); // enum name + lua_pushcclosure(L, _rmt__newindex, 1); + lua_setfield(L, -2, "__newindex"); + + lua_setmetatable(L, et); + + lua_setfield(L, top, name); + } + + + void State::RegisterMethods(const luaL_Reg *l) + { + assert(lua_istable(mState, -1)); + // luaL_registerµÚ¶þ¸ö²ÎÊýΪ¿Õ£¬ÔòÏò-1λÖÃ×¢²áluaL_RegÖÐÕâЩº¯Êý + luaL_register(mState, 0, l); + } + + void State::RegisterMethod(cc8* fname, lua_CFunction func) + { + assert(lua_istable(mState, -1)); + lua_pushcfunction(mState, func); + lua_setfield(mState, -2, fname); + } + + void State::RegisterPreloader(cc8* libname, lua_CFunction preloader) + { + lua_getglobal(mState, "package"); + lua_getfield(mState, -1, "preload"); + lua_pushcfunction(mState, preloader); + lua_setfield(mState, -2, libname); + lua_pop(mState, 2); + } + + void State::RegisterLib(cc8* libname, const luaL_Reg* l) + { + luaL_register(mState, libname, l); + } + +#if LUA_BIND_ENABLE_PLAIN_CLASS + void State::RegisterPlainClassRegistry(cc8* name) + { + assert(lua_istable(mState, -1)); + lua_pushcfunction(mState, PlainClass::registry); + lua_setfield(mState, -2, name); + } +#endif + +#if LUA_BIND_ENABLE_PLAIN_ENUM + void State::RegisterPlainEnumRegistry(cc8* name) + { + assert(lua_istable(mState, -1)); + lua_pushcfunction(mState, PlainEnum::registry); + lua_setfield(mState, -2, name); + } +#endif + + int State::ErrorType(int idx, cc8* hint) + { + return luaL_typerror(mState, idx, hint); + } + + template <> + bool State::CheckValue < bool >(int idx) + { + bool b = false; + if (lua_type(mState, idx) == LUA_TBOOLEAN) + { + b = lua_toboolean(mState, idx); + } + else + { + luaL_typerror(mState, idx, lua_typename(mState, LUA_TBOOLEAN)); + } + return b; + } + + template <> + cc8* State::CheckValue < cc8* >(int idx) + { + return luaL_checkstring(mState, idx); + } + + template <> + double State::CheckValue < double >(int idx) + { + return luaL_checknumber(mState, idx); + } + + template <> + float State::CheckValue < float >(int idx) + { + return luaL_checknumber(mState, idx); + } + + template <> + s8 State::CheckValue < s8 >(int idx) + { + return luaL_checkinteger(mState, idx); + } + + template <> + s16 State::CheckValue < s16 >(int idx) + { + return luaL_checkinteger(mState, idx); + } + + template <> + s32 State::CheckValue < s32 >(int idx) + { + return luaL_checkinteger(mState, idx); + } + + template <> + s64 State::CheckValue < s64 >(int idx) + { + return luaL_checkinteger(mState, idx); + } + + template <> + u8 State::CheckValue < u8 >(int idx) + { + return luaL_checkinteger(mState, idx); + } + + template <> + u16 State::CheckValue < u16 >(int idx) + { + return luaL_checkinteger(mState, idx); + } + + template <> + u32 State::CheckValue < u32 >(int idx) + { + return luaL_checkinteger(mState, idx); + } + + template <> + u64 State::CheckValue < u64 >(int idx) + { + return luaL_checkinteger(mState, idx); + } + + template <> + std::string State::CheckValue < std::string >(int idx) + { + return luaL_checkstring(mState, idx); + } + + // + // check light userdata + // + template <> + const void* State::CheckValue < const void* >(int idx) + { + if (IsType(idx, LUA_TLIGHTUSERDATA)) + { + return GetValue(idx, nullptr); + } + else + { + luaL_typerror(mState, idx, "light userdata"); + return nullptr; + } + } + +} \ No newline at end of file diff --git a/Runtime/Lua/LuaBind/LuaBindState.h b/Runtime/Lua/LuaBind/LuaBindState.h new file mode 100644 index 0000000..776b23d --- /dev/null +++ b/Runtime/Lua/LuaBind/LuaBindState.h @@ -0,0 +1,266 @@ +#ifndef __LUA_BIND_STATE_H__ +#define __LUA_BIND_STATE_H__ + +#include + +#include "LuaBindConfig.h" +#include "LuaBindRefTable.h" +#include "LuaBindGlobalState.h" + +namespace LuaBind +{ + + class VM; + class Enum; + class StrongRef; + class WeakRef; + + // ¶Ôlua_StateµÄ´úÀí£¬³ýÁ˱£´æÒ»¸ölua_StateµÄÒýÓò»±£´æÆäËûÄÚÈÝ¡£Ò»¸öʵÀýµÄmetatableÈçÏ£º + // class table + // member table + // ref table + // userdata + // ´Óuserdataͨ¹ýgetmetatable»ñÈ¡Éϼ¶metatable¡£³ý´ËÖ®Í⻹ÓÐÒ»¸öclass table×¢²áÔÚ¶ÔÓ¦ + // µÄÃû³Æ¿Õ¼äÀï¡£ + LUA_BIND_API class State + { + public: + + State(lua_State* state); + State(const State& state); + virtual ~State(); + + inline lua_State* operator ->() { return mState; }; + inline lua_State& operator *() { return *mState; }; + inline operator lua_State*() { return mState; } + inline operator bool() { return mState != nullptr; }; + + // »ñÈ¡°ó¶¨µÄlua_State + inline lua_State* GetHandle() { return mState; }; + + global_State* GetGlobalState(); + + VM* GetVM(); + + //------------------------------------------------------------------------------// + + void OpenLibs(); + + //------------------------------------------------------------------------------// + // Ãû³Æ¿Õ¼ä¹ÜÀí£¬Ãû³Æ¿Õ¼ä¾ÍÊÇÒ»¸ö±í£¬_GÊÇ×îÉÏÃæµÄ±í + + void PushGlobalNamespace(); + void PushNamespace(cc8* name); + void PopNamespace(); + bool IsNamespace(int idx); + + //------------------------------------------------------------------------------// + + void SetTop(int top); + int GetTop(); + bool CheckParams(int idx, cc8* format); + int AbsIndex(int idx); + void Call(int nArgs, int nResults); + + //------------------------------------------------------------------------------// + + void GetField(int idx, cc8* name); + void GetField(int idx, int key); + std::string GetField(int idx, cc8* key, cc8* value); + std::string GetField(int idx, int key, cc8* value); + std::string GetField(int idx, cc8* key, const std::string& value); + std::string GetField(int idx, int key, const std::string& value); + bool GetFieldWithType(int idx, cc8* name, int type); + bool GetFieldWithType(int idx, int key, int type); + bool GetSubfieldWithType(int idx, cc8* format, int type, ...); + static cc8* GetLuaTypeName(int type); + + void SetField(int idx, cc8* key); + + bool IsNil(int idx); + bool IsNilOrNone(int idx); + bool IsTableOrUserdata(int idx); + bool IsTrueOrNotNil(int idx); + bool IsType(int idx, int type); + bool IsType(int idx, cc8* name, int type); + bool IsValid(); + + bool HasField(int idx, cc8* name); + bool HasField(int idx, int key); + bool HasField(int idx, cc8* name, int type); + bool HasField(int idx, int name, int type); + bool HasKeys(int idx); + + void PushNil(); + void Push(bool value); + void Push(cc8* value); + void Push(double value); + void Push(float value); + void Push(int value); + void Push(u16 value); + void Push(u32 value); + void Push(u64 value); + void Push(s64 value); + void Push(uintptr value); + void Push(lua_CFunction value); + void Push(void* data, size_t size); + void Push(const void* value); + void Push(std::string value); + + // ½«idx¿ªÊ¼µÄn¸öpushµ½Õ»¶¥£¬idx»á±»È¡Õý£¬nÏòÉÏÉú³¤¡£ + void PushValues(int idx, int n); + + // ÒÔvoid** µÄÐÎʽ´´½¨userdata£¬²¢½«ÖµÉèÖÃΪptr + void PushPtrUserdata(void* ptr); + + void Pop(int n = 1); + + void Settop(int idx); + + template T* GetUserdata(int idx = 1); + + //------------------------------------------------------------------------------// + + int ErrorType(int idx, cc8* hint); + + //------------------------------------------------------------------------------// + + template T GetValue(int idx, T default_value); + template T GetField(int idx, int key, T value); + template T GetField(int idx, cc8* key, T value); + template void SetField(int idx, cc8* key, T value); + template void SetFieldByIndex(int idx, int key, T value); + + template T* CheckUserdata(int idx); + template T CheckValue(int idx); + + //------------------------------------------------------------------------------// + + void DoString(const std::string& code); + void DoFile(const std::string& file); + + //------------------------------------------------------------------------------// + // ×¢²á·½·¨ + + // ×¢²á¹¤³§£¬ÊÊÓÃÓÚÆÕͨÀ࣬ÓÐNew·½·¨ + template void RegisterFactory(); + + // ×¢²áµ¥Àý£¬Ã»ÓÐNew·½·¨ + template void RegisterSingleton(); + + // ×¢²áö¾Ù + void RegisterEnum(cc8* name, Enum* enums); + + // ×¢²áCº¯Êý£¬×¢ÒâºóÃæ¼ÓÒ»ÐÐ{0£¬ 0} + void RegisterMethods(const luaL_Reg *l); + + // ×¢²áµ¥¸öCº¯Êý + void RegisterMethod(cc8* fname, lua_CFunction func); + + // °Ñpreloader¼Óµ½package.preloadÀµ±require"libname"ʱluaµÄloader_preload¸ù¾Ý + // libnameÕÒµ½preloaderÖ±½Ó¼ÓÔØ¡£ÓÃÀ´ÊµÏÖÐèÒªrequireµÄʱºò²Å¼ÓÔØ£¬²¢ÇÒ¼ÓÔØ¹ýÒ»´Îºó + // package.loaded¼Ç¼ÏÂÀ´£¬Ï´β»»áÔÙ¼ÓÔØ¡£Í¨¹ýrequire»áµ÷ÓÃÕâ¸öpreloader¡£ + void RegisterPreloader(cc8* libname, lua_CFunction preloader); + + // ¸ù¾ÝluaL_Reg½¨Á¢lib table£¬²¢ÔÚ_GºÍpackage.loaded½¨Á¢¶ÔlibnameµÄË÷Òý£¬Ö¸Ïòlib table¡£ + void RegisterLib(cc8* libname, const luaL_Reg* l); + +#if LUA_BIND_ENABLE_PLAIN_CLASS + // ×¢²á´¿luaÀàµÄ×¢²áº¯Êý£¬ÓÃÀ´´´½¨´¿luaÀà¡£ + void RegisterPlainClassRegistry(cc8* name); +#endif + +#if LUA_BIND_ENABLE_PLAIN_ENUM + // ×¢²á´¿luaµÄö¾Ù£¬ÒÔ·ÀÖ¹ÐÞ¸Äö¾ÙÖµ¡£ + void RegisterPlainEnumRegistry(cc8* name); +#endif + + protected: + + friend class VM; + + // ÆÁ±Î¶ÔStateµÄµØÖ·Ïà¹Ø²Ù×÷ + void* operator &(); + void* operator new(size_t size); + + lua_State* const mState; + }; + + //--------------------------------------------------------------------------------// + // GetValue()Ä£°åÌØ»¯ + + template <> bool State::GetValue < bool >(int idx, const bool value); + template <> cc8* State::GetValue < cc8* >(int idx, const cc8* value); + template <> double State::GetValue < double >(int idx, const double value); + template <> float State::GetValue < float >(int idx, const float value); + template <> s8 State::GetValue < s8 >(int idx, const s8 value); + template <> s16 State::GetValue < s16 >(int idx, const s16 value); + template <> s32 State::GetValue < s32 >(int idx, const s32 value); + template <> s64 State::GetValue < s64 >(int idx, const s64 value); + template <> u8 State::GetValue < u8 >(int idx, const u8 value); + template <> u16 State::GetValue < u16 >(int idx, const u16 value); + template <> u32 State::GetValue < u32 >(int idx, const u32 value); + template <> u64 State::GetValue < u64 >(int idx, const u64 value); + template <> std::string State::GetValue < std::string >(int idx, const std::string value); + template <> const void* State::GetValue < const void* >(int idx, const void* value); + + //--------------------------------------------------------------------------------// + // CheckValueÄ£°åÌØ»¯ + + template <> bool State::CheckValue < bool >(int idx); + template <> cc8* State::CheckValue < cc8* >(int idx); + template <> double State::CheckValue < double >(int idx); + template <> float State::CheckValue < float >(int idx); + template <> s8 State::CheckValue < s8 >(int idx); + template <> s16 State::CheckValue < s16 >(int idx); + template <> s32 State::CheckValue < s32 >(int idx); + template <> s64 State::CheckValue < s64 >(int idx); + template <> u8 State::CheckValue < u8 >(int idx); + template <> u16 State::CheckValue < u16 >(int idx); + template <> u32 State::CheckValue < u32 >(int idx); + template <> u64 State::CheckValue < u64 >(int idx); + template <> std::string State::CheckValue < std::string >(int idx); + template <> const void* State::CheckValue < const void* >(int idx); + + // ÔÚ³ÉÔ±·½·¨Àï´´½¨State²¢¶Ô²ÎÊý½øÐмì²é¡£ +#define LUA_BIND_SETUP(L, params) \ + LuaBind::State state(L); \ + if(!state.CheckParams(1, params)) return 0 + +#define LUA_BIND_STATE(L) \ + LuaBind::State state(L) + + //--------------------------------------------------------------------------------// + + // È·±£²»°²È«µÄluaµ÷ÓÃÄܹ»ÔÚµ÷ÓÃÖ®ºó·µ»Øµ½×î³õstack״̬¡£ + class ScopedState + : public State + { + public: + ScopedState(lua_State* state) + : State(state) + { + mRestoreTop = lua_gettop(mState); + } + ScopedState(const State& state) + : State(state) + { + mRestoreTop = lua_gettop(mState); + } + ~ScopedState() + { + if (mState) { + if (lua_gettop(mState) != mRestoreTop) { + lua_settop(mState, mRestoreTop); + } + } + } + private: + void* operator new(size_t); + int mRestoreTop; + + }; + +} + +#endif \ No newline at end of file diff --git a/Runtime/Lua/LuaBind/LuaBindState.inc b/Runtime/Lua/LuaBind/LuaBindState.inc new file mode 100644 index 0000000..4e7090d --- /dev/null +++ b/Runtime/Lua/LuaBind/LuaBindState.inc @@ -0,0 +1,180 @@ +namespace LuaBind +{ + + // + // ×¢²á¹¤³§£¬×¢²áclass table£¬ÒÔtype nameΪ¼üÉèÖÃÔÚÃû³Æ¿Õ¼äÉÏ¡£ÔÚ×¢²á½×¶Î²»»áÉèÖÃÔª±í£¬µÈµ½New·½·¨µ÷ÓõÄʱºò²Å»á¡£ + // + template + void State::RegisterFactory() + { + cc8* type = TYPE::GetFactoryName(); + + 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::RegisterFactoryClass(state); + TYPE::RegisterClass(state); + + // ¼ì²âTYPEÀïÃæÊÇ·ñûÓÐ×¢²á±ØÐëµÄ·½·¨ +#define _assertmethod(I, NAME) \ + GetField(I, NAME); \ + assert(IsType(-1, LUA_TFUNCTION)); \ + Pop(); + + //_assertmethod(-1, "New"); + +#undef _assertmethod + +#if LUA_BIND_ENABLE_NATIVE_EXTEND + // .Extend() + lua_pushvalue(state, -1); // class table + lua_pushcclosure(state, TYPE::_ExtendFactory, 1); + lua_setfield(state, -2, "Extend"); +#endif + + // class["__index"] = class + lua_pushvalue(state, -1); // class table + lua_setfield(state, -2, "__index"); + + TYPE::SetClassTableRef(state, -1); + + SetField(top, type); + + // reset top + lua_settop(L, top); + + // ºó´¦Àí + TYPE::RegisterPostprocess(state); + } + + // + // Singleton + // + 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(); + SetField(top, type); + + // reset top + lua_settop(L, top); + + // ºó´¦Àí + TYPE::RegisterPostprocess(state); + } + + template + void State::SetField(int idx, cc8* key, TYPE value) + { + if (IsTableOrUserdata(idx)) + { + idx = AbsIndex(idx); + this->Push(value); + lua_setfield(mState, idx, key); + } + } + + template + void State::SetFieldByIndex(int idx, int key, TYPE value) + { + if (IsTableOrUserdata(idx)) + { + idx = AbsIndex(idx); + this->Push(value); + lua_rawseti(mState, idx, key); + } + } + + template + TYPE State::GetField(int idx, cc8* key, TYPE value) + { + GetField(idx, key); + TYPE result = GetValue < TYPE >(-1, value); + this->Pop(); + + return result; + } + + template + TYPE State::GetField(int idx, int key, TYPE value) + { + GetField(idx, key); + TYPE result = GetValue < TYPE >(-1, value); + Pop(); + + return result; + } + + template + TYPE* State::GetUserdata(int idx) + { + void* p = nullptr; + + if (IsType(idx, LUA_TUSERDATA)) + { + p = *(void**)lua_touserdata(mState, idx); + } + + return static_cast(p); + } + + template + TYPE* State::CheckUserdata(int idx) + { + if (IsType(idx, LUA_TUSERDATA)) + { + if (lua_getmetatable(mState, idx)) // ref table + { + if (lua_getmetatable(mState, -1)) // member table + { + if (lua_getmetatable(mState, -1)) // class table + { + TYPE::PushClassTable(*this); // target class table + if (lua_rawequal(mState, -1, -2)) + { + Pop(4); // ref\member\class\target class + TYPE* udata = GetUserdata(idx); + return udata; // userdata + } + Pop(2); // target class table\class table + } + Pop(1); // member table + } + Pop(1); // ref table + } + } + luaL_typerror(mState, idx, TYPE::GetClassName()); + return nullptr; + } + +} \ No newline at end of file diff --git a/Runtime/Lua/LuaBind/LuaBindUtility.h b/Runtime/Lua/LuaBind/LuaBindUtility.h new file mode 100644 index 0000000..ffc5099 --- /dev/null +++ b/Runtime/Lua/LuaBind/LuaBindUtility.h @@ -0,0 +1,69 @@ +#ifndef __LUA_BIND_UTILITY_H__ +#define __LUA_BIND_UTILITY_H__ + +// µ¼³önative½Ó¿Ú + +// RegisterClass ×¢²áÀàµÄ·½·¨ºÍ³ÉÔ±£¬±ÈÈçö¾Ù¡¢³£Á¿µÈµ½class table GetFactoryName »ñµÃ¹¤³§µÄÀàÃû£¬ +// ͬʱÓÃÀ´±ÜÃâ×¢²áʱ´íÎó×¢²áΪÁËsingleton£¬Í¨¹ý±àÒëʱ±¨´í±ÜÃâ +#define LUA_BIND_DECL_FACTORY(type, ...) \ + friend class ::State; \ + friend class ::NativeClass; \ + 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; } + +// ×÷Ϊ»ùÀàµÄ³éÏ󹤳§Àà¿ÉÒÔʹÓô˺꣬ע²áÒ»¸öÈë¿Ú£¬ÔÚÅÉÉúÀàµÄ×¢²áº¯ÊýÖе÷Óã¬×¢²á»ùÀàµÄÕâЩ·½·¨¡£ +#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) + +// ±êÃ÷·½·¨ÊµÏֵĺꡣÉÏÏÂÎÄÀïÓÐÒ»¸öL¡£ +#define LUA_BIND_IMPL_METHOD(type, f) int type::f(lua_State* L) + +// ÓÉÓ¦ÓóÌÐòʵÏÖµÄÁ½¸ö½Ó¿Ú¡£ÉÏÏÂÎÄÀïÓÐÒ»¸östate¡£ +#define LUA_BIND_REGISTRY(type) void type::RegisterClass(::State& state) +#define LUA_BIND_POSTPROCESS(type) void type::RegisterPostprocess(::State& state) + +// ÓÃÀ´×¢²áµÄºê¡£Ö®Ç°ÕâÀïÍüÁËÓÿɱäºê£¬µ¼ÖÂûÓÐ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{ \ + luaL_Reg __m[] = {__VA_ARGS__,{0, 0}}; \ + state.RegisterMethods(__m); \ + }while(0) +#define LUA_BIND_REGISTER_ENUM(state, name, ...) \ + do{ \ + ::Enum __e[] = {__VA_ARGS__,{0, 0}}; \ + state.RegisterEnum(name, __e); \ + }while(0) + +#define LUA_BIND_PREPARE(L, T) \ + LUA_BIND_STATE(L); \ + T* self = state.GetUserdata(1); + +#define LUA_BIND_CHECK(L, params)\ + if(!state.CheckParams(1, params)) return 0 + +#define LUA_BIND_INHERIT(state, type) type::RegisterClass(state) + +#define luaxport private + +#endif \ No newline at end of file diff --git a/Runtime/Lua/LuaBind/LuaBindVM.cpp b/Runtime/Lua/LuaBind/LuaBindVM.cpp new file mode 100644 index 0000000..268a5ed --- /dev/null +++ b/Runtime/Lua/LuaBind/LuaBindVM.cpp @@ -0,0 +1,82 @@ +#include "LuaBindInternal.h" +#include "LuaBindVM.h" + +namespace LuaBind +{ + + VM::VMap VM::VMs; // ͨ¹ýÏ̲߳éÕÒÐéÄâ»ú£¬ÎªÁË·½±ã + + VM* VM::TryGetVM(global_State* gState) + { + auto it = VMs.find(gState); + if (it != VMs.end()) + return it->second; + else + return nullptr; + } + + VM* VM::TryGetVM(lua_State* state) + { + return TryGetVM(G(state)); + } + + VM::VM() + : mStrongRefTable() + , mWeakRefTable() + { + mMainThread = luaL_newstate(); + assert(mMainThread); + mGlobalState = G(mMainThread); + + VMs.insert(std::pair(mGlobalState, this)); + } + + VM::~VM() + { + VMs.erase(mGlobalState); + lua_close(mMainThread); + } + + // ³õʼ»¯context + void VM::Setup() + { + LUA_BIND_STATE(mMainThread); + + mStrongRefTable.Init(state, "GAMELAB_UNIVERSAL_STRONG_REFERENCE_TABLE"); + mWeakRefTable.Init(state, "GAMELAB_UNIVERSAL_WEAK_REFERENCE_TABLE", "v"); + } + + lua_State* VM::CreateThread() + { + lua_State* thread = lua_newthread(mMainThread); + assert(thread); + return thread; + } + + lua_State* VM::GetMainThread() + { + return mMainThread; + } + + State VM::GetMainState() + { + return mMainThread; + } + + RefTable& VM::GetStrongRefTable() + { + return mStrongRefTable; + } + + RefTable& VM::GetWeakRefTable() + { + return mWeakRefTable; + } + + void VM::OpenLibs() + { + assert(mMainThread); + luaL_openlibs(mMainThread); + } + +} \ No newline at end of file diff --git a/Runtime/Lua/LuaBind/LuaBindVM.h b/Runtime/Lua/LuaBind/LuaBindVM.h new file mode 100644 index 0000000..3bfe899 --- /dev/null +++ b/Runtime/Lua/LuaBind/LuaBindVM.h @@ -0,0 +1,58 @@ +#ifndef __LUA_BIND_CONTEXT_H__ +#define __LUA_BIND_CONTEXT_H__ + +#include +#include + +#include "LuaBindRef.h" +#include "LuaBindConfig.h" +#include "LuaBindState.h" +#include "LuaBindGlobalState.h" + +namespace LuaBind +{ + + // µ¥¸ölua_stateÏà¹ØµÄcontext¡£ÊÇһϵÁдúÀíµÄ¼¯ºÏ£¬¿½±´Ò²Ã»¹ØÏµ£¬Ö÷ÒªÊÇΪÁ˽ÚÔ¼ÄÚ´æ¡£ + class VM + { + public: + + // ¸ù¾Ýglobal_StateÄõ½ÐéÄâ»ú¡£ + static VM* TryGetVM(global_State* gState); + static VM* TryGetVM(lua_State* state); + + VM(); + ~VM(); + + // ´´½¨ÐéÄâ»úºó£¬ÐèÒªÊÖ¶¯µ÷ÓÃSetupº¯Êý£¬³õʼ»¯Ò»Ð©ÐéÄâ»ú״̬¡£ + void Setup(); + void OpenLibs(); + + lua_State* GetMainThread(); + lua_State* CreateThread(); + State GetMainState(); + + RefTable& GetStrongRefTable(); + RefTable& GetWeakRefTable(); + + private: + + typedef std::map VMap; + + static VMap VMs; // ͨ¹ýglobal_StateË÷ÒýÐéÄâ»ú£¬ÎªÁË·½±ã + + RefTable mStrongRefTable; // GAMELAB_UNIVERSAL_STRONG_REFERENCE_TABLE + RefTable mWeakRefTable; // GAMELAB_UNIVERSAL_WEAK_REFERENCE_TABLE + + global_State* mGlobalState; // ÐéÄâ»úµÄglobal_State£¬Óɵ±Ç°ÐéÄâ»úµÄËùÓÐÏ̹߳²Ïí + lua_State* mMainThread; // Ö÷Ïß³Ì + +#if LUA_BIND_PROFILER + size_t mObjectCount; // ͳ¼ÆËùÓÐÔÚ´ËÐéÄâ»úÖд´½¨µÄʵÀý +#endif + + }; + +} + +#endif \ No newline at end of file diff --git a/Runtime/Lua/LuaBind/LuaBindWatchDog.cpp b/Runtime/Lua/LuaBind/LuaBindWatchDog.cpp new file mode 100644 index 0000000..e69de29 diff --git a/Runtime/Lua/LuaBind/LuaBindWatchDog.h b/Runtime/Lua/LuaBind/LuaBindWatchDog.h new file mode 100644 index 0000000..794faa9 --- /dev/null +++ b/Runtime/Lua/LuaBind/LuaBindWatchDog.h @@ -0,0 +1,33 @@ +#ifndef __LUA_BIND_DOG_H__ +#define __LUA_BIND_DOG_H__ + +#include "LuaBindConfig.h" + +namespace LuaBind +{ + + // + // NativeClassʵÀýµÄÒýÓüÆÊý¶îwatch dog£¬Ö»ÓÐÔÚwatch dogͨ¹ýʱ²Å¿ÉÒÔdelete¡£ + // + class WatchDog + { + public: + WatchDog() + : mVMRef(0) + , mNativeRef(0) + { + } + + inline operator bool() + { + return mVMRef == 0 && mNativeRef == 0; + } + + uint mVMRef; // ÍйܸøµÄÐéÄâ»úÊý + uint mNativeRef; // ±¾µØÒýÓÃÊý + + }; + +} + +#endif \ No newline at end of file diff --git a/Runtime/Lua/LuaHelper.cpp b/Runtime/Lua/LuaHelper.cpp new file mode 100644 index 0000000..289f0f6 --- /dev/null +++ b/Runtime/Lua/LuaHelper.cpp @@ -0,0 +1,23 @@ +#include "LuaHelper.h" + +using namespace LuaBind; + +template <> +Rectf State::GetValue < Rectf >(int idx, const Rectf value) +{ + Rectf rect; + rect.x = GetField(idx, 1, 0); + rect.y = GetField(idx, 2, 0); + rect.width = GetField(idx, 3, 0); + rect.height = GetField(idx, 4, 0); + return rect; +} + +template <> +Vector2f State::GetValue < Vector2f >(int idx, const Vector2f value) +{ + Vector2f v2; + v2.x = GetField(idx, 1, 0); + v2.y = GetField(idx, 2, 0); + return v2; +} diff --git a/Runtime/Lua/LuaHelper.h b/Runtime/Lua/LuaHelper.h new file mode 100644 index 0000000..5e9bf90 --- /dev/null +++ b/Runtime/Lua/LuaHelper.h @@ -0,0 +1,10 @@ +#pragma once +#include "Runtime/Math/Rect.h" +#include "Runtime/Math/Vector2.h" +#include "./LuaBind/LuaBind.h" + +class LuaHelper +{ +public: + +}; diff --git a/Runtime/LuaBind/LuaBind.h b/Runtime/LuaBind/LuaBind.h deleted file mode 100644 index 1494b5c..0000000 --- a/Runtime/LuaBind/LuaBind.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef __LUA_BIND_H__ -#define __LUA_BIND_H__ - -// -// (port) library ÓÃÓÚ¸ølua×¢²áÀàºÍº¯Êý -// - -#include "LuaBindState.h" -#include "LuaBindVM.h" -#include "LuaBindRef.h" -#include "LuaBindRefTable.h" -#include "LuaBindEnum.h" -#include "LuaBindClass.hpp" -#include "LuaBindMemberRef.h" -#include "LuaBindClass.inc" -#include "LuaBindState.inc" - -#endif \ No newline at end of file diff --git a/Runtime/LuaBind/LuaBindCFunctions.cpp b/Runtime/LuaBind/LuaBindCFunctions.cpp deleted file mode 100644 index ca662a3..0000000 --- a/Runtime/LuaBind/LuaBindCFunctions.cpp +++ /dev/null @@ -1,19 +0,0 @@ -#include "LuaBindCFunctions.h" -#include "LuaBindConfig.h" - -namespace LuaBind -{ - - int luax_c_getupvalue(lua_State* L) - { - lua_pushvalue(L, lua_upvalueindex(1)); - return 1; - } - - int luax_c_errfunc(lua_State* L) - { - cc8* msg = luaL_optstring(L, lua_upvalueindex(1), ""); - return luaL_error(L, msg); - } - -} \ No newline at end of file diff --git a/Runtime/LuaBind/LuaBindCFunctions.h b/Runtime/LuaBind/LuaBindCFunctions.h deleted file mode 100644 index f0f07dd..0000000 --- a/Runtime/LuaBind/LuaBindCFunctions.h +++ /dev/null @@ -1,38 +0,0 @@ -#ifndef __LUA_BIND_CFUNCTIONS_H__ -#define __LUA_BIND_CFUNCTIONS_H__ - -#include "LuaBindConfig.h" - -/** - * luax_cfunctionÀïµÄº¯ÊýÓÃÀ´×¢²á¸ølua£¬Ò»Ð©ÌØÊ⹦ÄܵÄͨÓú¯Êý¡£ -*/ - -namespace -{ - - // »ñµÃµÚÒ»¸öupvalue - extern int luax_c_getupvalue(lua_State* L); - - // µ÷Óô˺¯Êýʱ»á±¨´í£¬upvalue(1)ÊÇ´íÎóÐÅÏ¢ - extern int luax_c_errfunc(lua_State* L); - -#define luax_is(T, L, i) (lua_is##T(L, i)) -#define luax_isnumber(L, i) luax_is(number, L, i) - - inline int luax_isinteger(lua_State* L, int i) - { - if (!luax_isnumber(L, i)) - return 0; - return lua_tonumber(L, i) == lua_tointeger(L, i); - } - - inline int luax_isfloat(lua_State* L, int i) - { - if (!luax_isnumber(L, i)) - return 0; - return lua_tonumber(L, i) != lua_tointeger(L, i); - } - -} - -#endif \ No newline at end of file diff --git a/Runtime/LuaBind/LuaBindClass.cpp b/Runtime/LuaBind/LuaBindClass.cpp deleted file mode 100644 index 7fd603c..0000000 --- a/Runtime/LuaBind/LuaBindClass.cpp +++ /dev/null @@ -1,243 +0,0 @@ -#include "LuaBindClass.hpp" -#include "LuaBindCFunctions.h" -#include "LuaBindVM.h" - -namespace LuaBind -{ - -#if LUA_BIND_ENABLE_PLAIN_CLASS - - int PlainClass::registry(lua_State* L) - { - LUA_BIND_STATE(L); - - // params: - // 1: class name - - cc8* type = state.GetValue(1, ""); - - lua_newtable(L); // class table - - // GetClassName() - lua_pushstring(L, type); - lua_pushcclosure(L, luax_c_getupvalue, 1); - lua_setfield(L, -2, "GetClassName"); - - // GetClass() - lua_pushvalue(L, -1); // class table - lua_pushcclosure(L, luax_c_getupvalue, 1); - lua_setfield(L, -2, "GetClass"); - - // TypeOf() - lua_pushcfunction(L, _TypeOf); - lua_setfield(L, -2, "TypeOf"); - - // New() - lua_pushvalue(L, -1); // class table - lua_pushcclosure(L, _New, 1); - lua_setfield(L, -2, "New"); - - // Extend() - lua_pushvalue(L, -1); // class table - lua_pushcclosure(L, _Extend, 1); - lua_setfield(L, -2, "Extend"); - - lua_pushvalue(L, -1); // class table - lua_setfield(L, -2, "__index"); - - lua_pushstring(L, type); - lua_pushcclosure(L, __tostring, 1); - lua_setfield(L, -2, "__tostring"); - - return 1; - } - - int PlainClass::__tostring(lua_State* L) - { - // upvalues: - // 1: class name - - // params: - // 1: instance - - if (!lua_istable(L, 1)) - { - return luaL_typerror(L, 1, lua_typename(L, LUA_TTABLE)); - } - - cc8* type = lua_tostring(L, lua_upvalueindex(1)); - - lua_pushfstring(L, "%s: %p", type, lua_topointer(L, 1)); - - return 1; - } - - // - // Newº¯Êý½ÓÊÜn¸ö²ÎÊý£¬²¢³¢ÊÔ»ñÈ¡__init£¬½«²ÎÊý´«¸ø__init³õʼ»¯ÊµÀý¡£ - // - int PlainClass::_New(lua_State* L) - { - LUA_BIND_STATE(L); - - // upvalues: - // 1: class table - - // params: - // n: params - int n = lua_gettop(L); - - int classTable = lua_upvalueindex(1); - - lua_newtable(L); // instance table - - // instance µÄ metatable ÉèÖÃΪ class - lua_pushvalue(L, classTable); - lua_setmetatable(L, -2); - - // ÕÒµ½¹¹Ô캯Êý£¬»á´¥·¢metatable.__index,¸ù¾Ý¼Ì³ÐÁ´ÏòÉÏÕÒ¡£ - lua_getfield(L, classTable, "__init"); - if (state.IsType(-1, LUA_TFUNCTION)) - { - // stack: - // -1: __init() - // -2: instance - // -3~-n-2: params - - lua_insert(L, -2 - n); - // stack: - // -1: instance - // -2~-n-1: params - // -n-2: __init() - - lua_pushvalue(L, -1); - // stack: - // -1: instance - // -2: instance - // -3~-n-2: params - // -n-3: __init - - lua_insert(L, -3 - n); - // stack: - // -1: instance - // -2~-n-1: params - // -n-2: __init() - // -n-3: instance - - lua_insert(L, -1 - n); - // stack: - // -1~-n: params - // -n-1: instance - // -n-2: __init() - // -n-3: instance - - lua_pcall(L, n + 1, 0, 0); - } - else - { - state.Pop(); - } - - return 1; - } - - int PlainClass::_Extend(lua_State* L) - { - LUA_BIND_STATE(L); - - // upvalues: - // 1: base class - - // params: - // 1: class name - - cc8* type = state.GetValue(1, ""); - - int baseClass = lua_upvalueindex(1); - - lua_newtable(L); // class table - - // GetClassName() - lua_pushstring(L, type); - lua_pushcclosure(L, luax_c_getupvalue, 1); - lua_setfield(L, -2, "GetClassName"); - - // GetClass() - lua_pushvalue(L, -1); // class table - lua_pushcclosure(L, luax_c_getupvalue, 1); - lua_setfield(L, -2, "GetClass"); - - // New() - lua_pushvalue(L, -1); // class table - lua_pushcclosure(L, _New, 1); - lua_setfield(L, -2, "New"); - - // Extend() - lua_pushvalue(L, -1); // class table - lua_pushcclosure(L, _Extend, 1); - lua_setfield(L, -2, "Extend"); - - // .__base ÓÃÀ´Ë÷Òýµ½»ùÀà - lua_pushvalue(L, baseClass); // base class - lua_setfield(L, -2, "__base"); - - lua_pushvalue(L, -1); // class table - lua_setfield(L, -2, "__index"); - - lua_pushstring(L, type); - lua_pushcclosure(L, __tostring, 1); - lua_setfield(L, -2, "__tostring"); - - // classµÄmetatableÉèÖÃΪbaseClass - lua_pushvalue(L, baseClass); - lua_setmetatable(L, -2); - - return 1; - } - - int PlainClass::_TypeOf(lua_State* L) - { - // params: - // 1: lua instance - // 2: type string - - LUA_BIND_STATE(L); - - cc8* type = state.GetValue(2, ""); - - if (!lua_istable(L, 1)) - { - return luaL_typerror(L, 1, "Object"); - } - - lua_pushvalue(L, 1); // lua instance - - while (lua_getmetatable(L, -1)) - { - lua_getfield(L, -1, "GetClassName"); - if (lua_isfunction(L, -1)) - { - state.Call(0, 1); - cc8* name = state.GetValue(-1, ""); - if (strcmp(name, type) == 0) - { - lua_pushboolean(L, true); - return 1; - } - else - { - state.Pop(); // name - } - } - else - { - state.Pop(); - } - } - - lua_pushboolean(L, false); - return 1; - } - -#endif /*LUA_BIND_ENABLE_PLAIN_CLASS*/ - -} \ No newline at end of file diff --git a/Runtime/LuaBind/LuaBindClass.hpp b/Runtime/LuaBind/LuaBindClass.hpp deleted file mode 100644 index c27af4e..0000000 --- a/Runtime/LuaBind/LuaBindClass.hpp +++ /dev/null @@ -1,207 +0,0 @@ -#ifndef __LUA_BIND_CLASS_H__ -#define __LUA_BIND_CLASS_H__ - -#include "LuaBindConfig.h" - -#if LUA_BIND_PROFILER -#include -#endif - -#include - -#include "LuaBindRef.h" -#include "LuaBindMemberRef.h" -#include "LuaBindCFunctions.h" -#include "LuaBindWatchDog.h" -#include "LuaBindUtility.h" - -namespace LuaBind -{ - - class VM; - - // - // Ðé»ùÀ࣬ΪÁËʵÏÖ¶à̬¡£ÐèÒª·ÃÎÊÏÂÃæÕâЩ½Ó¿ÚµÄÍⲿ»ùÀàÐèÒªÐé¼Ì³Ð´ËÀ֮࣬ºóÔÙÅÉÉúÁ´Öоͻá - // µ÷ÓöÔӦʵÌåµÄ·½·¨¡£×¢Òâ¼Ì³Ð´ËÀàʱ²»ÄÜʵÏÖÏÂÃæµÄ·½·¨£¬ÊµÏÖÔÚNativeClassÖУ¬ÊµÏÖ»á - // µ¼Ö¶þÒåÐÔ¡£ - // - // ÒÀ¾Ý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; - - }; - - // TODO: ½«¹«¹²²¿·ÖÌáÈ¡³öÀ´£¬²»ÒªÖظ´Éú³É´úÂë - //class NativeClassBase - //{ - //} - - // - // ÐèÒª±©Â¶¸øluaµÄnative classÐèÒª¼Ì³Ð´ËÀࡣͨ¹ýlua¹ÜÀíµÄʵÀýҪȷ±£ÒýÓüÆÊýµÄÕýÈ·ÐÔ£¬ÔÚ¶à¸öÏß³ÌÖÐÐèҪȷ - // ¶¨²»»áÎóÊÍ·Å¡£ - // - template - class NativeClass : public BASE - { - public: - - // - // ½«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 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; - -#if LUA_BIND_PROFILER - // ¶Ô¶ÑÉÏ´´½¨µÄʵÀý½øÐÐdelete±£ÏÕ¼ì²é - static void operator delete(void* pdead, size_t size); -#endif - - protected: - - NativeClass(); - virtual ~NativeClass(); - - // - // ³ÉÔ±ÒýÓùÜÀí£¬ÔÚʵÀýµÄref tableÀï¡£ÉèÖá¢È¡¡¢Çå³ý - // - void SetMemberRef(State& state, MemberRef& memRef, int idx); - bool PushMemberRef(State& state, MemberRef& memRef); - void ClearMemberRef(State& state, MemberRef& memRef); - - private: - - friend class State; - - 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); - - //------------------------------------------------------------------------------// - - // ¹«¹²ÄÚÈÝ - static int __tostring (lua_State*); - static int _GetClass (lua_State*); - static int _GetClassName (lua_State*); - - // ¹¤³§ÀàÏà¹Ø - static int __gc (lua_State*); - static int _GetRefTable (lua_State*); - static int _New (lua_State*); - -#if LUA_BIND_ENABLE_NATIVE_EXTEND - static int _ExtendFactory (lua_State*); - static int _ExtendSingleton (lua_State*); -#endif - - //--------------------------------------------------------------------------------// - - // - // class table£¬¹¤³§ºÍµ¥Àý¶¼ÓС£ - // - static StrongRef mClassTable; - - // - // Èç¹ûÀàÊǵ¥Àý£¬Õâ¸öÓÃÀ´±£´æsingletonµÄÒýÓùØÏµ£¬ÒÔ±£Ö¤²»»á±»»ØÊÕÀàËÆÆÕͨÀàµÄref table¡£ - // µ¥ÀýµÄ³ÉÔ±ÊÇÈ«ÉúÃüÖÜÆÚµÄ£¬ËùÒÔÖ±½ÓÔÚ_LUA_BIND_STRONGREF_TABLE¡£µ¥Àý¶Ôuserdata½øÐÐ - // Retain\ReleaseºÍmember ref²Ù×÷ʱºÍ¹¤³§ÊµÀý²»Í¬£¬ÊÇ´æÔÚÏÂÃæÕâ¸öref tableÀï - // µÄ£¬Õâ¸ötableÔÚ_LUA_BIND_STRONGREF_TABLEÀï¡£ - // - static StrongRef mSingletonRefTable; - - // - // ͨ¹ýuserdata¿ÉÒÔÄõ½: - // 1: ref table - // 2: member table - // 3: class table - // - WeakRef mUserdata; - - // ͨ¹ýºó²ÅÄÜɾ³ý - WatchDog mWatchDog; - -#if LUA_BIND_PROFILER - // Íйܴ˶ÔÏóµÄÐéÄâ»ú - std::unordered_set mRefVMs; - // ±£ÏÕ£¬´ËÀàµÄÅÉÉúÀ಻ÄÜÔÚÍⲿʹÓÃdeleteÖ±½Óɾ³ý£¬¶øÓ¦¸ÃʹÓÃRelease - bool mSafer; -#endif - - }; - -#if LUA_BIND_ENABLE_PLAIN_CLASS - // - // ´¿luaÀà - // - class PlainClass - { - public: - - // - // ÓÃÀ´×¢²áÀàµÄÈë¿Úº¯Êý¡£¿ÉÒÔͨ¹ýregistry(ÀàÃû)×¢²áÀà¡£ - // - static int registry(lua_State* L); - - LUA_BIND_DECL_METHOD(__tostring); - LUA_BIND_DECL_METHOD(_Extend); - LUA_BIND_DECL_METHOD(_New); - LUA_BIND_DECL_METHOD(_TypeOf); - - }; -#endif - -} - -#endif \ No newline at end of file diff --git a/Runtime/LuaBind/LuaBindClass.inc b/Runtime/LuaBind/LuaBindClass.inc deleted file mode 100644 index 1d05f98..0000000 --- a/Runtime/LuaBind/LuaBindClass.inc +++ /dev/null @@ -1,637 +0,0 @@ -namespace LuaBind -{ - - //--------------------------------------------------------------------------------// - - // - // ¶Ô²»Í¬ÀàÐÍ£¬Í¨¹ýµ÷ÓÃGetLuaClassName»ñµÃÀàÐÍÃû£¬Èç¹ûÊÇÅÉÉúÀ࣬GetClassName»á±»¸²¸Ç£¬Ö¸Ïòluax_c_getupvalue¡£ - // - template - int NativeClass::_GetClassName(lua_State* L) - { - LUA_BIND_SETUP(L, "*"); - - cc8* type = TYPE::GetClassName(); - state.Push(type); - return 1; - } - - //--------------------------------------------------------------------------------// - - // - // ×¢²á¹¤³§ºÍµ¥Àý¹²ÓеÄÀà³ÉÔ± - // - template - void NativeClass::RegisterClassShared(State& state) - { - luaL_Reg regTable[] = { - { "GetClass", _GetClass }, - { "GetClassName", _GetClassName }, - { NULL, NULL } - }; - - state.RegisterMethods(regTable); - } - - // - // ¹¤³§ÀàµÄ³ÉÔ±£¬×¢²áÔÚclass table - // - template - void NativeClass::RegisterFactoryClass(State& state) - { - luaL_Reg regTable[] = { - { "GetRefTable", _GetRefTable }, - { NULL, NULL } - }; - - state.RegisterMethods(regTable); - } - - // - // µ¥ÀýÀàµÄ³ÉÔ±£¬×¢²áÔÚclass table - // - template - void NativeClass::RegisterSingletonClass(State& state) - { - luaL_Reg regTable[] = { - { NULL, NULL } - }; - - state.RegisterMethods(regTable); - } - - template - void NativeClass::PushClassTable(State& state) - { - assert(mClassTable); - - mClassTable.PushRef(state); - } - - template - void NativeClass::SetClassTableRef(State& state, int idx) - { - mClassTable.SetRef(state, idx); - } - - template - NativeClass::NativeClass() - : mWatchDog() -#if LUA_BIND_PROFILER - , mSafer(false) -#endif - { - } - - template - NativeClass::~NativeClass() - { - } - -#if LUA_BIND_PROFILER - template - void NativeClass::operator delete(void* pdead, size_t size) - { - if (pdead == nullptr) - return; - // ¶ÑÉÏ´´½¨µÄʵÀý±ØÐëʹÓÃReleaseÊÍ·Å¡£ - TYPE* p = static_cast(pdead); - assert(p->mSafer); - ::operator delete(pdead, size); - } -#endif - - template - void NativeClass::Retain() - { - ++mWatchDog.mNativeRef; - } - - template - void NativeClass::Release() - { - if (mWatchDog.mNativeRef > 0) - --mWatchDog.mNativeRef; - if (mWatchDog) - { -#if LUA_BIND_PROFILER - mSafer = true; -#endif - delete this; - } - } - - template - template - void NativeClass::Retain(State& state, U* userdata) - { - if (PushRefTable(state)) - { - if (userdata->PushUserdata(state)) - { - lua_pushvalue(state, -1); // copy the userdata - lua_gettable(state, -3); // get the count (or nil) - u32 count = state.GetValue(-1, 0); // get the count (or 0) - lua_pop(state, 1); // pop the old count - lua_pushnumber(state, count + 1); // push the new count - lua_settable(state, -3); // save it in the table: reftable[userdata] = count - } - } - } - - template - template - void NativeClass::Release(State& state, U* userdata) - { - if (PushRefTable(state)) - { - if (userdata->PushUserdata(state)) - { - lua_pushvalue(state, -1); // copy the userdata - lua_gettable(state, -3); // get the count (or nil) - u32 count = state.GetValue(-1, 0); // get the count (or 0) - lua_pop(state, 1); // pop the old count - - // no such reference - if (count == 0) - { - state.Pop(2); // userdata, reftable - return; // nothing to do - } - - if (count > 1) { - lua_pushnumber(state, count - 1); // push the new count - } - else { - lua_pushnil(state); // maybe cause gc - } - lua_settable(state, -3); // save it in the table - - state.Pop(1); // reftable - return; - } - state.Pop(2); // nil, reftable - return; - } - } - - template - bool NativeClass::PushUserdata(State& state) - { - assert(!TYPE::IsClassSingleton()); - if (!mUserdata) - { - BindToLua(state); - return true; - } - return mUserdata.PushRef(state); - } - - template - bool NativeClass::PushMemberTable(State& state) - { - int top = state.GetTop(); - if (this->PushUserdata(state)) - { - if (lua_getmetatable(state, -1)) // ref table - { - lua_replace(state, -2); - if (lua_getmetatable(state, -1)) // member table - { - lua_replace(state, -2); - return true; - } - } - } - lua_settop(state, top); - lua_pushnil(state); - return false; - } - - 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 (lua_getmetatable(state, -1)) - { - lua_replace(state, -2); - return true; - } - } - } - return false; - } - - // - // ´´½¨userdata£¬²¢ÒÔ´ËÌí¼Óref table£¬member tableºÍclass table¡£ - // ref table ÊÇkvÇ¿ÒýÓÃtable£¬±£´æ¶ÔÆäËûuserdataµÄÒýÓüÆÊý£¨Í¨¹ýuserdata×÷Ϊkey£¬ - // ¼ÆÊýΪvalue£©£¬ÒÔ¼°³ÉÔ±ÒýÓà - // member table ±£´ælua´´½¨µÄʵÀýµÄ³ÉÔ± - // class table ËùÓб¾ÀàÐ͵ÄʵÀý¹²Óеĺ¯Êý±í - // - // BindToLuaÖ»»áÔÚµÚÒ»´Î×¢²á¸øLuaÐéÄâ»úʱµ÷Óᣠ- // - template - void NativeClass::BindToLua(State& state) - { - // µ¥Àý²»Äܰó¶¨userdata - assert(!TYPE::IsClassSingleton()); - assert(!mUserdata); - - // - // ´´½¨userdata²¢ÁôÔÚÕ»¶¥£¬×¢ÒâµØÖ·Òª×ª»»ÎªTYPE*£¬Ö±½ÓÓÃthis¿ÉÄܻᵼÖ¶àÖØ¼Ì³ÐµÄÀàɥʧ¶à̬¡£ - // Èç¹ûÖ±½Ó´«this½øÈ¥£¬ÔÚ¶àÖØ¼Ì³ÐÇé¿öÏ£¬ÊÇÄò»µ½ÁíһͷµÄÐ麯Êý±íµÄ¡£ËùÒÔÕâÀïÐèÒª½«this - // ת»»ÎªÕû¸ö¶ÔÏóµÄµÍµØÖ·£¬ÕâÑù¿ÉÒÔÄõ½ÁíÒ»¸ö»ùÀàµÄÐ麯Êý±í£¬Í¨¹ýÁíÒ»¸ö»ùÀàʵÏÖ¶à̬¡£ - // - TYPE* p = static_cast(this); - state.PushPtrUserdata(p); - - lua_newtable(state); // ref table£¬ÎÞ·¨ÔÚlua´¦·ÃÎÊ£¬ÓÃÀ´¹ÜÀíC¶ÔÏóµÄÉúÃüÖÜÆÚ - lua_newtable(state); // member table£¬luaÖд´½¨µÄ¶ÔÏó³ÉÔ±¶¼±£´æÔÚÕâÀï - PushClassTable(state); // class table - - // stack: - // -1: class table - // -2: member table - // -3: ref table - // -4: userdata - - int top = state.GetTop(); - int memberTable = top - 1; - int refTable = top - 2; - - // ref table ×¢²á __tostring ºÍ __gc - lua_pushcfunction(state, __tostring); - lua_setfield(state, refTable, "__tostring"); - - lua_pushcfunction(state, __gc); - lua_setfield(state, refTable, "__gc"); - - // ref table µÄ __index ºÍ __newindex ÉèΪ member table - lua_pushvalue(state, memberTable); - lua_setfield(state, refTable, "__index"); - - 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µÄÈõÒýÓ㬷½±ãͨ¹ýPushLuaUserdata·½·¨·µ»Ølua¶ÔÏó - mUserdata.SetRef(state, -1); - assert(mUserdata); - - // Ôö¼ÓÒ»¸öÐéÄâ»úÒýÓã¬ÔÚGCʱ-1 - ++mWatchDog.mVMRef; -#if LUA_BIND_PROFILER - mRefVMs.insert(state.GetVM()); -#endif - } - - // - // ³ÉÔ±ÒýÓùÜÀí - // - template - void NativeClass::SetMemberRef(State& state, MemberRef& memRef, int idx) - { - ClearMemberRef(state, memRef); - if (!lua_isnil(state, idx)) - { - idx = state.AbsIndex(idx); - if (PushRefTable(state)) - { - lua_pushvalue(state, idx); - memRef.refID = luaL_ref(state, -2); - state.Pop(); // ref table - } - } - } - - template - bool NativeClass::PushMemberRef(State& state, MemberRef& memRef) - { - if (memRef) - { - if (PushRefTable(state)) - { - lua_rawgeti(state, -1, memRef.refID); - lua_replace(state, -2); // ref table - if (lua_isnil(state, -1)) - goto failed; - return true; - } - } - lua_pushnil(state); - failed: - memRef.refID = LUA_NOREF; - return false; - } - - template - bool NativeClass::PushMemberRef(State& state, int refID) - { - if (PushRefTable(state)) - { - lua_rawgeti(state, -1, refID); - lua_replace(state, -2); // ref table - if (lua_isnil(state, -1)) - goto failed; - return true; - } - lua_pushnil(state); - failed: - return false; - } - - template - void NativeClass::ClearMemberRef(State& state, MemberRef& memRef) - { - if (memRef) - { - if (PushRefTable(state)) - { - luaL_unref(state, -1, memRef.refID); - state.Pop(); // ref table - } - memRef.refID = LUA_NOREF; - } - } - - //--------------------------------------------------------------------------------// - - // - // Êͷʤ³§´´½¨µÄʵÀý - // - template - int NativeClass::__gc(lua_State* L) - { - LUA_BIND_STATE(L); - - TYPE* self = state.GetUserdata(1); - assert(self); - -#if LUA_BIND_PROFILER - std::cout << ": GC<" << TYPE::GetClassName() << ">\n"; -#endif - - if(self->mWatchDog.mVMRef > 0) - --self->mWatchDog.mVMRef; - - self->Release(); - - return 0; - } - - // - // Êä³ö¸ñʽÈçÏÂ: - // µØÖ· ÀàÃû - // - template - int NativeClass::__tostring(lua_State* L) - { - // params: - // 1: userdata - - LUA_BIND_STATE(L); - TYPE* self = state.GetUserdata(1); - if (self) - { - cc8* classname = ""; - lua_getfield(state, 1, "GetClassName"); - if (state.IsType(-1, LUA_TFUNCTION)) - { - lua_pushvalue(L, 1); // userdata - state.Call(1, 1); // ÅÉÉúÀàµÄGetClassNameº¯Êý - classname = state.GetValue(-1, ""); - } - else - { - classname = TYPE::GetClassName(); - } - lua_pushfstring(L, "%s: %p", classname, self); - return 1; - } - return 0; - } - -#if LUA_BIND_ENABLE_NATIVE_EXTEND - // - // ÅÉÉú³ö×ÓÀ࣬ÔÚluaÀï¶ÔÅÉÉúÀàµÄ³ÉÔ±ºÍÐÐΪ½øÐÐÖØÐÂÉè¼Æ£¬µ«ÊDZ£Ö¤ÁËuserdataµÄͳһ¡£Native classµÄÅÉÉúÌṩ__initÖ§³Ö£¬ÔÚ - // nativeʵÌå´´½¨ºó¿ÉÒÔʹÓÃ__init½øÐгõʼ»¯£¬ÅÉÉúÀàÓµÓкͻùÀàÒ»ÑùµÄNew²ÎÊýÁÐ±í£¬ÇÒnative¶ÔÏóÊÇÒ»ÑùµÄÀàÐÍ¡£ - // - template - int NativeClass::_ExtendFactory(lua_State* L) - { - // upvalues: - // 1: base class - - // params: - // 1: class name - - int baseClass = lua_upvalueindex(1); - - lua_newtable(L); // class table - - int inheritClass = lua_gettop(L); - - // .GetClassName() - cc8* type = lua_tostring(L, 1); - lua_pushstring(L, type); - lua_pushcclosure(L, luax_c_getupvalue, 1); - lua_setfield(L, -2, "GetClassName"); - - // .GetClass() - lua_pushvalue(L, inheritClass); - lua_pushcclosure(L, luax_c_getupvalue, 1); - lua_setfield(L, -2, "GetClass"); - - // .Extend() - lua_pushvalue(L, inheritClass); - lua_pushcclosure(L, _ExtendFactory, 1); - lua_setfield(L, -2, "Extend"); - - // .New() - lua_pushvalue(L, inheritClass); - lua_getfield(L, baseClass, "New"); - lua_pushcclosure(L, _New, 2); - lua_setfield(L, -2, "New"); - - // __base = baseClass - lua_pushvalue(L, baseClass); - lua_setfield(L, -2, "__base"); - - // __index = inheritClass - lua_pushvalue(L, inheritClass); - lua_setfield(L, -2, "__index"); - - // metatable is baseClass - lua_pushvalue(L, baseClass); - lua_setmetatable(L, inheritClass); - - return 1; - } - - template - int NativeClass::_ExtendSingleton(lua_State* L) - { - // upvalues: - // 1: base class - - // params: - // 1: class name - - int baseClass = lua_upvalueindex(1); - - lua_newtable(L); // class name - - int inheritClass = lua_gettop(L); - - // .GetClassName() - cc8* type = lua_tostring(L, 1); - lua_pushstring(L, type); - lua_pushcclosure(L, luax_c_getupvalue, 1); - lua_setfield(L, -2, "GetClassName"); - - // .GetClass() - lua_pushvalue(L, inheritClass); - lua_pushcclosure(L, luax_c_getupvalue, 1); - lua_setfield(L, -2, "GetClass"); - - // .Extend() - lua_pushvalue(L, inheritClass); - lua_pushcclosure(L, _ExtendFactory, 1); - lua_setfield(L, -2, "Extend"); - - // __base = baseClass - lua_pushvalue(L, baseClass); - lua_setfield(L, -2, "__base"); - - // __index = inheritClass - lua_pushvalue(L, inheritClass); - lua_setfield(L, -2, "__index"); - - // metatable is baseClass - lua_pushvalue(L, baseClass); - lua_setmetatable(L, inheritClass); - - return 1; - } -#endif /*LUA_BIND_ENABLE_NATIVE_EXTEND*/ - - template - int NativeClass::_GetClass(lua_State* L) - { - LUA_BIND_STATE(L); - if (!mClassTable) - lua_pushnil(L); - else - mClassTable.PushRef(state); - return 1; - } - - template - int NativeClass::_GetRefTable(lua_State* L) - { - LUA_BIND_STATE(L); - TYPE* self = state.GetUserdata(1); - bool success = self->PushRefTable(state); - if (!success) - lua_pushnil(L); - return 1; - } - - template - int NativeClass::_New(lua_State* L) - { - LUA_BIND_STATE(L); - - // upvalues: - // 1: class table - // 2: original New() - - // stack: - // -1~-n: args - - int n = lua_gettop(L); // n args - - lua_pushvalue(L, lua_upvalueindex(2)); - if (state.IsType(-1, LUA_TFUNCTION)) - { - // stack: - // -1: New - // -2~-1-n: args - - state.PushValues(-1 - n, n); - - // stack: - // -1~-n: args - // -n-1: New - // -n-2~-1-2n: args - - state.Call(n, 1); - - // stack: - // -1: userdata - // -2~-1-n: args - - // reset member table's metatable to class table - if (state.IsType(-1, LUA_TUSERDATA)) - { - if (lua_getmetatable(L, -1)) // ref table - { - if (lua_getmetatable(L, -1)) // member table - { - lua_pushvalue(L, lua_upvalueindex(1)); // class table - lua_setmetatable(L, -2); - state.Pop(); // member table - } - state.Pop(); // ref table - } - - // stack: - // -1: userdata - // -2~-1-n: args - - int args = state.AbsIndex(-1 - n); - - // ³¢ÊÔµ÷ÓÃ__initº¯Êý - lua_getfield(L, lua_upvalueindex(1), "__init"); - - if (state.IsType(-1, LUA_TFUNCTION)) - { - lua_pushvalue(L, -2); // userdata - state.PushValues(args, n); - state.Call(n + 1, 0); - } - else - state.Pop(); - - } - - return 1; - } - return 0; - } - - template StrongRef NativeClass::mClassTable; // class table - template StrongRef NativeClass::mSingletonRefTable; // µ¥Àý - -} \ No newline at end of file diff --git a/Runtime/LuaBind/LuaBindConfig.h b/Runtime/LuaBind/LuaBindConfig.h deleted file mode 100644 index 72709bd..0000000 --- a/Runtime/LuaBind/LuaBindConfig.h +++ /dev/null @@ -1,66 +0,0 @@ -#ifndef __LUA_BIND_TYPE_H__ -#define __LUA_BIND_TYPE_H__ - -#include - -extern "C" { -#include "ThirdParty/lua51/lua.h" -#include "ThirdParty/lua51/lualib.h" -#include "ThirdParty/lua51/lauxlib.h" -} - -#include - -namespace LuaBind -{ - - typedef unsigned int uint; - typedef unsigned long uintptr; - typedef long sintptr; - - typedef const char cc8; - - typedef unsigned char u8; - typedef unsigned short u16; - typedef unsigned int u32; - typedef unsigned long long u64; - - typedef signed char s8; - typedef signed short s16; - typedef signed int s32; - typedef signed long long s64; - -#ifdef _WIN32 - #define LUA_BIND_FINAL final - #define LUA_BIND_LIBRARY_EXPORT __declspec(dllexport) - #define LUA_BIND_LIBRARY_IMPORT __declspec(dllimport) - #define LUA_BIND_FORCE_INLINE __forceinline - #define LUA_BIND_RESTRICT __restrict - #define LUA_BIND_ATTRIBUTE_USED - #define LUA_BIND_ABSTRACT - #define LUA_BIND_API LUA_BIND_LIBRARY_EXPORT -#else - #define LUA_BIND_FINAL final - #define LUA_BIND_LIBRARY_EXPORT __attribute__((visibility("default"))) - #define LUA_BIND_LIBRARY_IMPORT - #define LUA_BIND_FORCE_INLINE __attribute__((always_inline)) inline - #define LUA_BIND_RESTRICT __restrict__ - #define LUA_BIND_ATTRIBUTE_USED __attribute__((used)) - #define LUA_BIND_ABSTRACT - #define LUA_BIND_API LUA_BIND_LIBRARY_EXPORT -#endif - -#define LUA_BIND_ENABLE_NATIVE_EXTEND 0 - -#define LUA_BIND_ENABLE_PLAIN_CLASS 0 -#define LUA_BIND_ENABLE_PLAIN_ENUM 0 - -#define LUA_BIND_PROFILER 1 - -} - -#if LUA_BIND_PROFILER -#include -#endif - -#endif // __LUA_BIND_TYPE_H__ \ No newline at end of file diff --git a/Runtime/LuaBind/LuaBindEnum.cpp b/Runtime/LuaBind/LuaBindEnum.cpp deleted file mode 100644 index 63e2567..0000000 --- a/Runtime/LuaBind/LuaBindEnum.cpp +++ /dev/null @@ -1,67 +0,0 @@ -#include "LuaBindEnum.h" -#include "LuaBindState.h" -#include "LuaBindVM.h" - -namespace LuaBind -{ - - // - // Ö»¶ÁmetatableµÄ__index - // - int _rmt__index(lua_State* L) - { - // params: - // 1: enum table - // 2: key - - // upvalues: - // 1: metatable - - int mt = lua_upvalueindex(1); - lua_pushvalue(L, 2); - lua_rawget(L, mt); - - return 1; - } - - int _rmt__newindex(lua_State* L) - { - // upvalue: - // 1: enum table name - - cc8* name = lua_tostring(L, lua_upvalueindex(1)); - - return luaL_error(L, "Enum called \"%s\" is readonly.", name); - } - - //--------------------------------------------------------------------------------// -#if LUA_BIND_ENABLE_PLAIN_ENUM - int PlainEnum::registry(lua_State* L) - { - // params: - // 1: enum name - // 2: metatable - - cc8* name = luaL_checkstring(L, 1); - - if (!lua_istable(L, 2)) - { - return luaL_error(L, "Create plain enum failed. Require table, but get %s", luaL_typename(L, 2)); - } - - lua_pushvalue(L, -1); - lua_setfield(L, -2, "__index"); - - lua_pushstring(L, name); - lua_pushcclosure(L, _rmt__newindex, 1); - lua_setfield(L, -2, "__newindex"); - - lua_newtable(L); // enum table - - lua_pushvalue(L, -2); // metatable - lua_setmetatable(L, -2); - - return 1; - } -#endif -} \ No newline at end of file diff --git a/Runtime/LuaBind/LuaBindEnum.h b/Runtime/LuaBind/LuaBindEnum.h deleted file mode 100644 index 122e845..0000000 --- a/Runtime/LuaBind/LuaBindEnum.h +++ /dev/null @@ -1,39 +0,0 @@ -#ifndef __LUA_BIND_ENUM_H__ -#define __LUA_BIND_ENUM_H__ - -#include "LuaBindConfig.h" - -namespace LuaBind -{ - - // - // µ¼³öö¾Ù£¬Ã¶¾ÙÊÇÒ»À಻¿ÉÐÞ¸ÄÕûÐͼ¯ºÏ£¬Ã¶¾ÙµÄÖµÔÚ - // - struct Enum - { - cc8* name; - int value; - }; - - extern int _rmt__index(lua_State* L); - - extern int _rmt__newindex(lua_State* L); - - //--------------------------------------------------------------------------------// - -#if LUA_BIND_ENABLE_PLAIN_ENUM - // - // ´¿luaµÄö¾Ù£¬´´½¨²»¿ÉÐ޸ĵÄtable - // - class PlainEnum - { - public: - - static int registry(lua_State* L); - - }; -#endif - -} - -#endif \ No newline at end of file diff --git a/Runtime/LuaBind/LuaBindGlobalState.h b/Runtime/LuaBind/LuaBindGlobalState.h deleted file mode 100644 index fa3cc4f..0000000 --- a/Runtime/LuaBind/LuaBindGlobalState.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef __LUA_BIND_GLOBAL_STATE_H__ -#define __LUA_BIND_GLOBAL_STATE_H__ - -// Ë÷Òýµ½luaÀïµÄglobal_State -typedef struct global_State global_State; - -#endif \ No newline at end of file diff --git a/Runtime/LuaBind/LuaBindInternal.h b/Runtime/LuaBind/LuaBindInternal.h deleted file mode 100644 index 1d4a226..0000000 --- a/Runtime/LuaBind/LuaBindInternal.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef __LUA_BIND_INTERNAL_H__ -#define __LUA_BIND_INTERNAL_H__ - -// -// ¶ÔluaÔ´´úÂëµÄÉî¶ÈʹÓà -// -extern "C" -{ -#include "ThirdParty/lua51/lstate.h" -} - -#endif \ No newline at end of file diff --git a/Runtime/LuaBind/LuaBindMemberRef.cpp b/Runtime/LuaBind/LuaBindMemberRef.cpp deleted file mode 100644 index e680cce..0000000 --- a/Runtime/LuaBind/LuaBindMemberRef.cpp +++ /dev/null @@ -1,16 +0,0 @@ -#include "LuaBindMemberRef.h" - -namespace LuaBind -{ - - MemberRef::MemberRef() - : refID(LUA_NOREF) - { - } - - MemberRef::~MemberRef() - { - - } - -} \ No newline at end of file diff --git a/Runtime/LuaBind/LuaBindMemberRef.h b/Runtime/LuaBind/LuaBindMemberRef.h deleted file mode 100644 index 045d6ef..0000000 --- a/Runtime/LuaBind/LuaBindMemberRef.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef __LUA_BIND_MEMBER_REF_H__ -#define __LUA_BIND_MEMBER_REF_H__ - -#include "LuaBindConfig.h" - -namespace LuaBind -{ - - // - // ʵÀýµÄref table±£´æµÄmember ref¡£ÓÉluax class×ö¾ßÌåµÄ¹ÜÀí¡£ÊµÀýµÄref tableÊÇÇ¿ÒýÓã¬ÓÃÀ´¹ÜÀíÀïÃæmemberµÄÉúÃüÖÜÆÚ¡£ - // ÓÃÀ´ÔÚluaºÍnativeÖ®¼ä½øÐÐÊý¾Ý¹µÍ¨¡£ - // - class MemberRef - { - public: - MemberRef(); - ~MemberRef(); - - inline operator bool() { return refID != LUA_NOREF; }; - - int refID; - - }; - -} - -#endif \ No newline at end of file diff --git a/Runtime/LuaBind/LuaBindRef.cpp b/Runtime/LuaBind/LuaBindRef.cpp deleted file mode 100644 index 00a65d0..0000000 --- a/Runtime/LuaBind/LuaBindRef.cpp +++ /dev/null @@ -1,72 +0,0 @@ -#include "LuaBindVM.h" -#include "LuaBindRef.h" - -namespace LuaBind -{ - - Ref::Ref(int mode) - : mRefID(LUA_NOREF) - , mMode(mode) - { - } - - Ref::~Ref() - { - } - - Ref::operator bool() - { - return (mRefID != LUA_NOREF); - } - - bool Ref::PushRef(State& state) - { - assert(mRefID != LUA_NOREF); - - VM* vm = state.GetVM(); - if (!vm) return false; - if (mMode == STRONG_REF) - { - RefTable& table = vm->GetStrongRefTable(); - table.PushRef(state, mRefID); - } - else if (mMode == WEAK_REF) - { - RefTable& table = vm->GetWeakRefTable(); - table.PushRef(state, mRefID); - } - else - { - 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) - { - } - - WeakRef::WeakRef() - : Ref(WEAK_REF) - { - } - -} diff --git a/Runtime/LuaBind/LuaBindRef.h b/Runtime/LuaBind/LuaBindRef.h deleted file mode 100644 index 93b30be..0000000 --- a/Runtime/LuaBind/LuaBindRef.h +++ /dev/null @@ -1,62 +0,0 @@ -#ifndef __LUA_BIND_REF_H__ -#define __LUA_BIND_REF_H__ - -#include "LuaBindConfig.h" -#include "LuaBindState.h" - -namespace LuaBind -{ - - // - // ÒýÓ㬴æÔÚLUA_REGISTRYINDEXÏÂÃæµÄÁ½¸ö±íÀï - // - class Ref - { - public: - - enum RefMode - { - STRONG_REF, - WEAK_REF - }; - - Ref(int mode = STRONG_REF); - virtual ~Ref(); - - operator bool(); - - void SetRef(State& state, int idx); - bool PushRef(State& state); - - int GetRefID(); - - private: - - int mRefID; // luaL_ref - int mMode; // strong or weak - - }; - - // - // Ç¿ÒýÓã¬ÔÚLUA_REGISTRYINDEX["_LUA_BIND_STRONGREF_TABLE"]À±£Ö¤lua object²»»á±»»ØÊÕ¡£ - // - class StrongRef: public Ref - { - public: - StrongRef(); - - }; - - // - // ÈõÒýÓã¬ÔÚLUA_REGISTRYINDEX["_LUA_BIND_WEAKREF_TABLE"]À²»Ó°Ïìlua objectµÄ»ØÊÕ£¬Ö»ÊÇ×÷Ϊһ¸ö·½±ãÈ¡lua objectµÄÓ³Éä¡£ - // - class WeakRef : public Ref - { - public: - WeakRef(); - - }; - -} - -#endif \ No newline at end of file diff --git a/Runtime/LuaBind/LuaBindRefTable.cpp b/Runtime/LuaBind/LuaBindRefTable.cpp deleted file mode 100644 index 39ef9ab..0000000 --- a/Runtime/LuaBind/LuaBindRefTable.cpp +++ /dev/null @@ -1,120 +0,0 @@ -#include "LuaBindRefTable.h" -#include "LuaBindState.h" - -namespace LuaBind -{ - - RefTable::RefTable() - : mState(nullptr) - { - } - - RefTable::~RefTable() - { - } - - void RefTable::Init(State& state, cc8* name, cc8* mode) - { - assert(!mState); - assert(name); - - mName = name; - mMode = 0; - for (int i = 0; mode && mode[i]; ++i) - { - if (mode[i] == 'k') mMode |= WEAK_KEY; - else if (mode[i] == 'v') mMode |= WEAK_VALUE; - } - mState = state.GetHandle(); - - state.GetField(LUA_REGISTRYINDEX, name); // register[mName] - if (state.IsNil(-1)) - { - state.Pop(); - - lua_newtable(state); // ref table - int ridx = state.AbsIndex(-1); - lua_newtable(state); // metatable of ref table - int idx = state.AbsIndex(-1); - - // __mode - if (mode) - { - state.Push(mode); - state.SetField(idx, "__mode"); - } - - state.Settop(idx); - lua_setmetatable(state, ridx); - - state.Settop(ridx); - state.SetField(LUA_REGISTRYINDEX, name); - } - else - { - state.Pop(); - } - } - - bool RefTable::IsKeyWeak() - { - assert(mState); - - return mMode & WEAK_KEY; - } - - bool RefTable::IsValueWeak() - { - assert(mState); - - return mMode & WEAK_VALUE; - } - - int RefTable::Ref(State& state, int idx) - { - assert(mState); - - idx = state.AbsIndex(idx); - state.GetField(LUA_REGISTRYINDEX, mName); // ref table - lua_pushvalue(state, idx); // stuff - int refID = luaL_ref(state, -2); - assert(refID != LUA_NOREF); - state.Pop(); - return refID; - } - - void RefTable::Unref(State& state, int refID) - { - assert(mState); - - state.GetField(LUA_REGISTRYINDEX, mName); // ref table - luaL_unref(state, -1, refID); - state.Pop(); - return; - } - - void RefTable::PushRefTable(State& state) - { - assert(mState); - - lua_getfield(state, LUA_REGISTRYINDEX, mName); - } - - void RefTable::PushRef(State& state, int refID) - { - assert(mState); - - lua_getfield(state, LUA_REGISTRYINDEX, mName); - lua_rawgeti(state, -1, refID); - lua_replace(state, -2); - } - - void RefTable::Clear(State& state) - { - assert(mState); - - lua_newtable(state); - state.SetField(LUA_REGISTRYINDEX, mName); - } - -} \ No newline at end of file diff --git a/Runtime/LuaBind/LuaBindRefTable.h b/Runtime/LuaBind/LuaBindRefTable.h deleted file mode 100644 index 0d4c2d4..0000000 --- a/Runtime/LuaBind/LuaBindRefTable.h +++ /dev/null @@ -1,67 +0,0 @@ -#ifndef __LUA_BIND_REFTABLE_H__ -#define __LUA_BIND_REFTABLE_H__ - -#include "LuaBindConfig.h" - -namespace LuaBind -{ - - class State; - - // - // ref table ¹ÜÀí£¬¶Ôstrong ref tableºÍweak ref tableÁ½¸ötableµÄ´úÀí¡£ - // - class RefTable - { - public: - - enum - { - WEAK_KEY = 1, - WEAK_VALUE = 1 << 1 - }; - - RefTable(); - ~RefTable(); - - inline operator bool() { return mState; }; - - void Init(State& state, 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); - - // - // ½«´Ë ref table ·ÅÔÚÕ»¶¥ - // - void PushRefTable(State& state); - - // - // ½« reftable[refID] ·ÅÔÚÕ»¶¥ - // - void PushRef(State& state, int refID); - - // - // Çå¿Õ ref table£¬±í»¹ÁôÔÚLUA_REGISTRYINDEX[mName] - // - void Clear(State& state); - - private: - - friend class State; - - lua_State* mState; // ÓÃÀ´×öһЩȷÈϹ¤×÷ - cc8* mName; // ref tableµÄÃû³Æ - int mMode; // ref tableµÄÀàÐÍ - - }; - -} - -#endif \ No newline at end of file diff --git a/Runtime/LuaBind/LuaBindState.cpp b/Runtime/LuaBind/LuaBindState.cpp deleted file mode 100644 index 4ee87f4..0000000 --- a/Runtime/LuaBind/LuaBindState.cpp +++ /dev/null @@ -1,893 +0,0 @@ -#include "LuaBindEnum.h" -#include "LuaBindState.h" -#include "LuaBindVM.h" -#include "LuaBindClass.hpp" -#include "LuaBindInternal.h" - -#include - -namespace LuaBind -{ - - State::State(lua_State* state) - : mState(state) - { - assert(state); - } - - State::State(const State& state) - : mState(state.mState) - { - assert(state.mState); - } - - State::~State() - { - } - - void State::OpenLibs() - { - luaL_openlibs(mState); - } - - global_State* State::GetGlobalState() - { - return G(mState); - } - - VM* State::GetVM() - { - return VM::TryGetVM(G(mState)); - } - - void State::PushGlobalNamespace() - { -#if false - int top = GetTop(); - - lua_newtable(mState); // pseudo namespace table - int pnt = GetTop(); - - lua_newtable(mState); // metatable - int mt = GetTop(); - - // __index = _G - // __newindex = _G - lua_pushvalue(mState, LUA_GLOBALSINDEX); - lua_pushvalue(mState, LUA_GLOBALSINDEX); - lua_setfield(mState, mt, "__index"); - lua_setfield(mState, mt, "__newindex"); - - lua_setmetatable(mState, pnt); - - // stack: - // -1 pseudo global namespace -#else - lua_pushvalue(mState, LUA_GLOBALSINDEX); -#endif - } - - void State::PushNamespace(cc8* name) - { - assert(IsNamespace(-1)); - - int top = GetTop(); - - lua_getfield(mState, -1, name); - if (lua_isnil(mState, -1)) - { - lua_pop(mState, 1); - - lua_newtable(mState); - lua_pushvalue(mState, -1); - lua_setfield(mState, top, name); - } - - // stack: - // -1 namespace - } - - void State::PopNamespace() - { - assert(lua_istable(mState, -1)); - lua_pop(mState, 1); - } - - bool State::IsNamespace(int idx) - { - return lua_istable(mState, idx); - } - - void State::DoString(const std::string& code) - { - luaL_dostring(mState, code.c_str()); - } - - void State::DoFile(const std::string & path) - { - luaL_dofile(mState, path.c_str()); - } - - int State::AbsIndex(int idx) - { -/* -#define abs_index(mState, i) ((i) > 0 || (i) <= LUA_REGISTRYINDEX ? (i) : \ - lua_gettop(mState) + (i) + 1) -*/ - if (idx < 0) { - //return lua_gettop(mState) + idx + 1; - return ((idx) > 0 || (idx) <= LUA_REGISTRYINDEX ? (idx) : \ - lua_gettop(mState) + (idx)+1); - } - return idx; - } - - void State::Call(int nArgs, int nResults) - { - lua_pcall(mState, nArgs, nResults, 0); - } - - void State::PushNil() - { - lua_pushnil(mState); - } - - void State::Push(bool value) - { - lua_pushboolean(mState, value ? 1 : 0); - } - - void State::Push(cc8* value) - { - lua_pushstring(mState, value); - } - - void State::Push(double value) - { - lua_pushnumber(mState, value); - } - - void State::Push(float value) - { - lua_pushnumber(mState, value); - } - - void State::Push(int value) - { - lua_pushnumber(mState, value); - } - - void State::Push(u16 value) - { - lua_pushnumber(mState, value); - } - - void State::Push(u32 value) - { - lua_pushnumber(mState, value); - } - - void State::Push(u64 value) - { - lua_pushnumber(mState, (double)value); - } - - void State::Push(s64 value) - { - lua_pushinteger(mState, value); - } - - void State::Push(uintptr value) - { - lua_pushlightuserdata(mState, (void*)value); - } - - void State::Push(lua_CFunction value) - { - lua_pushcfunction(mState, value); - } - - void State::Push(void* data, size_t size) - { - lua_pushlstring(mState, (cc8*)data, size); - } - - void State::Push(const void* value) - { - lua_pushlightuserdata(mState, (void*)value); - } - - void State::Push(std::string value) - { - Push(value.c_str()); - } - - void State::PushValues(int idx, int n) - { - idx = AbsIndex(idx); - for (int i = idx; i < idx + n; ++i) - lua_pushvalue(mState, i); - } - - void State::Pop(int n /* = 1 */) - { - lua_pop(mState, n); - } - - bool State::IsNil(int idx) - { - return lua_isnil(mState, idx); - } - - bool State::IsNilOrNone(int idx) - { - int t = lua_type(mState, idx); - return ((t == LUA_TNONE) || (t == LUA_TNIL)); - } - - bool State::IsTableOrUserdata(int idx) - { - int check = lua_type(mState, idx); - return ((check == LUA_TTABLE) || (check == LUA_TUSERDATA)); - } - - bool State::IsTrueOrNotNil(int idx) - { - if (lua_isboolean(mState, idx)) { - return lua_toboolean(mState, idx) ? true : false; - } - return !lua_isnil(mState, idx); - } - - bool State::IsType(int idx, int type) - { - return (lua_type(mState, idx) == type); - } - - bool State::IsType(int idx, cc8* name, int type) - { - return this->HasField(idx, name, type); - } - - bool State::IsValid() - { - return (mState != 0); - } - - void State::Settop(int idx) - { - lua_settop(mState, idx); - } - - int State::GetTop() - { - return lua_gettop(mState); - } - - bool State::HasField(int idx, cc8* name) { - - lua_getfield(mState, idx, name); - bool hasField = (lua_isnil(mState, -1) == false); - lua_pop(mState, 1); - - return hasField; - } - - bool State::HasField(int idx, int key) { - - this->GetField(idx, key); - bool hasField = (lua_isnil(mState, -1) == false); - lua_pop(mState, 1); - - return hasField; - } - - bool State::HasField(int idx, cc8* name, int type) { - - lua_getfield(mState, idx, name); - bool hasField = (lua_type(mState, -1) == type); - lua_pop(mState, 1); - - return hasField; - } - - bool State::HasField(int idx, int key, int type) { - - this->GetField(idx, key); - bool hasField = (lua_type(mState, -1) == type); - lua_pop(mState, 1); - - return hasField; - } - - bool State::HasKeys(int idx) { - - idx = this->AbsIndex(idx); - - lua_pushnil(mState); /* first key */ - if (lua_next(mState, idx) != 0) { - lua_pop(mState, 2); - return true; - } - return false; - } - - void State::GetField(int idx, cc8* name) - { - lua_getfield(mState, idx, name); - } - - void State::GetField(int idx, int key) - { - idx = this->AbsIndex(idx); - - lua_pushinteger(mState, key); - lua_gettable(mState, idx); - } - - std::string State::GetField(int idx, cc8* key, cc8* default_value) - { - std::string str; - if (this->GetFieldWithType(idx, key, LUA_TSTRING)) { - str = lua_tostring(mState, -1); - lua_pop(mState, 1); - } - else { - str = default_value; - } - return str; - } - - std::string State::GetField(int idx, int key, cc8* default_value) - { - std::string str; - if (this->GetFieldWithType(idx, key, LUA_TSTRING)) { - str = lua_tostring(mState, -1); - lua_pop(mState, 1); - } - else { - str = default_value; - } - return str; - } - - std::string State::GetField(int idx, cc8* key, const std::string& value) - { - std::string str; - if (this->GetFieldWithType(idx, key, LUA_TSTRING)) { - str = lua_tostring(mState, -1); - lua_pop(mState, 1); - } - else { - str = value; - } - return str; - } - - std::string State::GetField(int idx, int key, const std::string& value) - { - std::string str; - if (this->GetFieldWithType(idx, key, LUA_TSTRING)) { - str = lua_tostring(mState, -1); - lua_pop(mState, 1); - } - else { - str = value; - } - return str; - } - - bool State::GetFieldWithType(int idx, cc8* name, int type) - { - lua_getfield(mState, idx, name); - if (lua_type(mState, -1) != type) { - lua_pop(mState, 1); - return false; - } - return true; - } - - bool State::GetFieldWithType(int idx, int key, int type) - { - this->GetField(idx, key); - if (lua_type(mState, -1) != type) { - lua_pop(mState, 1); - return false; - } - return true; - } - - void State::SetField(int idx, cc8* key) - { - if (IsTableOrUserdata(idx)) - { - idx = AbsIndex(idx); - lua_setfield(mState, idx, key); - } - } - - cc8* State::GetLuaTypeName(int type) - { - switch (type) { - case LUA_TNONE: return "none"; - case LUA_TNIL: return "nil"; - case LUA_TBOOLEAN: return "boolean"; - case LUA_TLIGHTUSERDATA: return "lightuserdata"; - case LUA_TNUMBER: return "number"; - case LUA_TSTRING: return "string"; - case LUA_TTABLE: return "table"; - case LUA_TFUNCTION: return "function"; - case LUA_TUSERDATA: return "userdata"; - case LUA_TTHREAD: return "thread"; - } - return "unknown"; - } - - - bool State::GetSubfieldWithType(int idx, cc8* format, int type, ...) - { - va_list args; - va_start(args, type); - - idx = this->AbsIndex(idx); - lua_pushvalue(this->mState, idx); - - for (cc8* c = format; *c; ++c) { - switch (*c) { - // number - case 'N': - lua_pushnumber(this->mState, va_arg(args, int)); - lua_gettable(this->mState, -1); - break; - - // string - case 'S': - lua_getfield(this->mState, -1, va_arg(args, char*)); - break; - - default: - lua_pushnil(this->mState); - } - - if (lua_isnil(this->mState, -1)) break; - lua_replace(this->mState, -2); - } - va_end(args); - if (lua_type(this->mState, -1) != type) { - lua_pop(this->mState, 1); - return false; - } - return true; - } - - bool State::CheckParams(int idx, cc8* format) - { - idx = AbsIndex(idx); - - for (int i = 0; format[i]; ++i) { - - int pos = idx + i; - int type = LUA_TNIL; - int expected = LUA_TNONE; - - if (pos <= GetTop()) { - type = lua_type(mState, pos); - } - - switch (format[i]) { - - // boolean - case 'B': - if (type != LUA_TBOOLEAN) expected = LUA_TBOOLEAN; - break; - - // coroutine - case 'C': - if (type != LUA_TTHREAD) expected = LUA_TTHREAD; - break; - - // function - case 'F': - if (type != LUA_TFUNCTION) expected = LUA_TFUNCTION; - break; - - // light userdata - case 'L': - if (type != LUA_TLIGHTUSERDATA) expected = LUA_TLIGHTUSERDATA; - break; - - // number - case 'N': - if (type != LUA_TNUMBER) expected = LUA_TNUMBER; - break; - - // string - case 'S': - if (type != LUA_TSTRING) expected = LUA_TSTRING; - break; - - // table - case 'T': - if (type != LUA_TTABLE) expected = LUA_TTABLE; - break; - - // userdata - case 'U': - if (type != LUA_TUSERDATA) expected = LUA_TUSERDATA; - break; - - // any type - case '*': - case '.': - break; - } - - if (expected != LUA_TNONE) { - return false; - } - } - - return true; - } - - template <> - bool State::GetValue < bool >(int idx, const bool value) { - - if (this->IsType(idx, LUA_TBOOLEAN)) { - return (lua_toboolean(this->mState, idx) != 0); - } - return value; - } - - static std::string s_str; - template <> - cc8* State::GetValue < cc8* >(int idx, const cc8* value) { - - if (this->IsType(idx, LUA_TSTRING)) { - return lua_tostring(this->mState, idx); - } - - if (this->IsType(idx, LUA_TNUMBER)) { - if (luax_isinteger(mState, -1)) { - int num = lua_tointeger(this->mState, idx); - s_str = std::to_string(num); - cc8* str = s_str.c_str(); - return str; - } - else { - float num = lua_tonumber(this->mState, idx); - s_str = std::to_string(num); - cc8* str = s_str.c_str(); - return str; - } - } - - if (this->IsType(idx, LUA_TBOOLEAN)) { - bool b = lua_toboolean(this->mState, idx); - return b ? "true" : "false"; - } - - if (this->IsType(idx, LUA_TNIL)) { - return "NIL"; - } - - return value; - } - - template <> - std::string State::GetValue(int idx, const std::string value) - { - std::string str; - if (lua_type(this->mState, idx) == LUA_TSTRING) { - str = lua_tostring(this->mState, idx); - } - else { - str = value; - } - return str; - } - - template <> - double State::GetValue < double >(int idx, const double value) - { - if (this->IsType(idx, LUA_TNUMBER)) { - return lua_tonumber(this->mState, idx); - } - return value; - } - - template <> - float State::GetValue < float >(int idx, const float value) - { - if (this->IsType(idx, LUA_TNUMBER)) { - return (float)lua_tonumber(this->mState, idx); - } - return value; - } - - template <> - s8 State::GetValue < s8 >(int idx, const s8 value) - { - if (this->IsType(idx, LUA_TNUMBER)) { - return (s8)lua_tonumber(this->mState, idx); - } - return value; - } - - - template <> - s16 State::GetValue < s16 >(int idx, const s16 value) - { - if (this->IsType(idx, LUA_TNUMBER)) { - return (s16)lua_tonumber(this->mState, idx); - } - return value; - } - - - template <> - s32 State::GetValue < s32 >(int idx, const s32 value) - { - if (this->IsType(idx, LUA_TNUMBER)) { - return (s32)lua_tonumber(this->mState, idx); - } - return value; - } - - template <> - s64 State::GetValue < s64 >(int idx, const s64 value) - { - if (this->IsType(idx, LUA_TNUMBER)) { - return (s64)lua_tonumber(this->mState, idx); - } - return value; - } - - template <> - u8 State::GetValue < u8 >(int idx, const u8 value) - { - if (this->IsType(idx, LUA_TNUMBER)) { - return (u8)lua_tonumber(this->mState, idx); - } - return value; - } - - template <> - u16 State::GetValue < u16 >(int idx, const u16 value) - { - if (this->IsType(idx, LUA_TNUMBER)) { - return (u16)lua_tonumber(this->mState, idx); - } - return value; - } - - template <> - u32 State::GetValue < u32 >(int idx, const u32 value) - { - if (this->IsType(idx, LUA_TNUMBER)) { - return (u32)lua_tonumber(this->mState, idx); - } - return value; - } - - template <> - u64 State::GetValue < u64 >(int idx, const u64 value) - { - if (this->IsType(idx, LUA_TNUMBER)) { - return (u64)lua_tonumber(this->mState, idx); - } - return value; - } - - template <> - const void* State::GetValue < const void* >(int idx, const void* value) - { - if (this->IsType(idx, LUA_TLIGHTUSERDATA)) { - return (void*)lua_touserdata(this->mState, idx); - } - return value; - } - - void State::PushPtrUserdata(void* ptr) - { - void** handle = (void**)lua_newuserdata(this->mState, sizeof(void*)); - assert(handle); - (*handle) = ptr; - } - - void State::RegisterEnum(cc8* name, Enum* en) - { - assert(name); - assert(en); - - // short name - lua_State* L = mState; - - int top = GetTop(); - - lua_newtable(L); // enum table - - int et = GetTop(); - - lua_newtable(L); // matatable - - // ËùÓÐö¾Ù¶¼´æÔÚmetatableÏ£¬ÐÞ¸Äʱ´¥·¢__newindex±¨´í - for (; en->name; ++en) - { - lua_pushinteger(L, en->value); - lua_setfield(L, -2, en->name); - } - - // __index - //lua_pushvalue(L, -1); // metatable - //lua_pushcclosure(L, _rmt__index, 1); - lua_pushvalue(L, -1); - lua_setfield(L, -2, "__index"); - - // __newinedx - lua_pushstring(L, name); // enum name - lua_pushcclosure(L, _rmt__newindex, 1); - lua_setfield(L, -2, "__newindex"); - - lua_setmetatable(L, et); - - lua_setfield(L, top, name); - } - - - void State::RegisterMethods(const luaL_Reg *l) - { - assert(lua_istable(mState, -1)); - // luaL_registerµÚ¶þ¸ö²ÎÊýΪ¿Õ£¬ÔòÏò-1λÖÃ×¢²áluaL_RegÖÐÕâЩº¯Êý - luaL_register(mState, 0, l); - } - - void State::RegisterMethod(cc8* fname, lua_CFunction func) - { - assert(lua_istable(mState, -1)); - lua_pushcfunction(mState, func); - lua_setfield(mState, -2, fname); - } - - void State::RegisterPreloader(cc8* libname, lua_CFunction preloader) - { - lua_getglobal(mState, "package"); - lua_getfield(mState, -1, "preload"); - lua_pushcfunction(mState, preloader); - lua_setfield(mState, -2, libname); - lua_pop(mState, 2); - } - - void State::RegisterLib(cc8* libname, const luaL_Reg* l) - { - luaL_register(mState, libname, l); - } - -#if LUA_BIND_ENABLE_PLAIN_CLASS - void State::RegisterPlainClassRegistry(cc8* name) - { - assert(lua_istable(mState, -1)); - lua_pushcfunction(mState, PlainClass::registry); - lua_setfield(mState, -2, name); - } -#endif - -#if LUA_BIND_ENABLE_PLAIN_ENUM - void State::RegisterPlainEnumRegistry(cc8* name) - { - assert(lua_istable(mState, -1)); - lua_pushcfunction(mState, PlainEnum::registry); - lua_setfield(mState, -2, name); - } -#endif - - int State::ErrorType(int idx, cc8* hint) - { - return luaL_typerror(mState, idx, hint); - } - - template <> - bool State::CheckValue < bool >(int idx) - { - bool b = false; - if (lua_type(mState, idx) == LUA_TBOOLEAN) - { - b = lua_toboolean(mState, idx); - } - else - { - luaL_typerror(mState, idx, lua_typename(mState, LUA_TBOOLEAN)); - } - return b; - } - - template <> - cc8* State::CheckValue < cc8* >(int idx) - { - return luaL_checkstring(mState, idx); - } - - template <> - double State::CheckValue < double >(int idx) - { - return luaL_checknumber(mState, idx); - } - - template <> - float State::CheckValue < float >(int idx) - { - return luaL_checknumber(mState, idx); - } - - template <> - s8 State::CheckValue < s8 >(int idx) - { - return luaL_checkinteger(mState, idx); - } - - template <> - s16 State::CheckValue < s16 >(int idx) - { - return luaL_checkinteger(mState, idx); - } - - template <> - s32 State::CheckValue < s32 >(int idx) - { - return luaL_checkinteger(mState, idx); - } - - template <> - s64 State::CheckValue < s64 >(int idx) - { - return luaL_checkinteger(mState, idx); - } - - template <> - u8 State::CheckValue < u8 >(int idx) - { - return luaL_checkinteger(mState, idx); - } - - template <> - u16 State::CheckValue < u16 >(int idx) - { - return luaL_checkinteger(mState, idx); - } - - template <> - u32 State::CheckValue < u32 >(int idx) - { - return luaL_checkinteger(mState, idx); - } - - template <> - u64 State::CheckValue < u64 >(int idx) - { - return luaL_checkinteger(mState, idx); - } - - template <> - std::string State::CheckValue < std::string >(int idx) - { - return luaL_checkstring(mState, idx); - } - - // - // check light userdata - // - template <> - const void* State::CheckValue < const void* >(int idx) - { - if (IsType(idx, LUA_TLIGHTUSERDATA)) - { - return GetValue(idx, nullptr); - } - else - { - luaL_typerror(mState, idx, "light userdata"); - return nullptr; - } - } - -} \ No newline at end of file diff --git a/Runtime/LuaBind/LuaBindState.h b/Runtime/LuaBind/LuaBindState.h deleted file mode 100644 index 776b23d..0000000 --- a/Runtime/LuaBind/LuaBindState.h +++ /dev/null @@ -1,266 +0,0 @@ -#ifndef __LUA_BIND_STATE_H__ -#define __LUA_BIND_STATE_H__ - -#include - -#include "LuaBindConfig.h" -#include "LuaBindRefTable.h" -#include "LuaBindGlobalState.h" - -namespace LuaBind -{ - - class VM; - class Enum; - class StrongRef; - class WeakRef; - - // ¶Ôlua_StateµÄ´úÀí£¬³ýÁ˱£´æÒ»¸ölua_StateµÄÒýÓò»±£´æÆäËûÄÚÈÝ¡£Ò»¸öʵÀýµÄmetatableÈçÏ£º - // class table - // member table - // ref table - // userdata - // ´Óuserdataͨ¹ýgetmetatable»ñÈ¡Éϼ¶metatable¡£³ý´ËÖ®Í⻹ÓÐÒ»¸öclass table×¢²áÔÚ¶ÔÓ¦ - // µÄÃû³Æ¿Õ¼äÀï¡£ - LUA_BIND_API class State - { - public: - - State(lua_State* state); - State(const State& state); - virtual ~State(); - - inline lua_State* operator ->() { return mState; }; - inline lua_State& operator *() { return *mState; }; - inline operator lua_State*() { return mState; } - inline operator bool() { return mState != nullptr; }; - - // »ñÈ¡°ó¶¨µÄlua_State - inline lua_State* GetHandle() { return mState; }; - - global_State* GetGlobalState(); - - VM* GetVM(); - - //------------------------------------------------------------------------------// - - void OpenLibs(); - - //------------------------------------------------------------------------------// - // Ãû³Æ¿Õ¼ä¹ÜÀí£¬Ãû³Æ¿Õ¼ä¾ÍÊÇÒ»¸ö±í£¬_GÊÇ×îÉÏÃæµÄ±í - - void PushGlobalNamespace(); - void PushNamespace(cc8* name); - void PopNamespace(); - bool IsNamespace(int idx); - - //------------------------------------------------------------------------------// - - void SetTop(int top); - int GetTop(); - bool CheckParams(int idx, cc8* format); - int AbsIndex(int idx); - void Call(int nArgs, int nResults); - - //------------------------------------------------------------------------------// - - void GetField(int idx, cc8* name); - void GetField(int idx, int key); - std::string GetField(int idx, cc8* key, cc8* value); - std::string GetField(int idx, int key, cc8* value); - std::string GetField(int idx, cc8* key, const std::string& value); - std::string GetField(int idx, int key, const std::string& value); - bool GetFieldWithType(int idx, cc8* name, int type); - bool GetFieldWithType(int idx, int key, int type); - bool GetSubfieldWithType(int idx, cc8* format, int type, ...); - static cc8* GetLuaTypeName(int type); - - void SetField(int idx, cc8* key); - - bool IsNil(int idx); - bool IsNilOrNone(int idx); - bool IsTableOrUserdata(int idx); - bool IsTrueOrNotNil(int idx); - bool IsType(int idx, int type); - bool IsType(int idx, cc8* name, int type); - bool IsValid(); - - bool HasField(int idx, cc8* name); - bool HasField(int idx, int key); - bool HasField(int idx, cc8* name, int type); - bool HasField(int idx, int name, int type); - bool HasKeys(int idx); - - void PushNil(); - void Push(bool value); - void Push(cc8* value); - void Push(double value); - void Push(float value); - void Push(int value); - void Push(u16 value); - void Push(u32 value); - void Push(u64 value); - void Push(s64 value); - void Push(uintptr value); - void Push(lua_CFunction value); - void Push(void* data, size_t size); - void Push(const void* value); - void Push(std::string value); - - // ½«idx¿ªÊ¼µÄn¸öpushµ½Õ»¶¥£¬idx»á±»È¡Õý£¬nÏòÉÏÉú³¤¡£ - void PushValues(int idx, int n); - - // ÒÔvoid** µÄÐÎʽ´´½¨userdata£¬²¢½«ÖµÉèÖÃΪptr - void PushPtrUserdata(void* ptr); - - void Pop(int n = 1); - - void Settop(int idx); - - template T* GetUserdata(int idx = 1); - - //------------------------------------------------------------------------------// - - int ErrorType(int idx, cc8* hint); - - //------------------------------------------------------------------------------// - - template T GetValue(int idx, T default_value); - template T GetField(int idx, int key, T value); - template T GetField(int idx, cc8* key, T value); - template void SetField(int idx, cc8* key, T value); - template void SetFieldByIndex(int idx, int key, T value); - - template T* CheckUserdata(int idx); - template T CheckValue(int idx); - - //------------------------------------------------------------------------------// - - void DoString(const std::string& code); - void DoFile(const std::string& file); - - //------------------------------------------------------------------------------// - // ×¢²á·½·¨ - - // ×¢²á¹¤³§£¬ÊÊÓÃÓÚÆÕͨÀ࣬ÓÐNew·½·¨ - template void RegisterFactory(); - - // ×¢²áµ¥Àý£¬Ã»ÓÐNew·½·¨ - template void RegisterSingleton(); - - // ×¢²áö¾Ù - void RegisterEnum(cc8* name, Enum* enums); - - // ×¢²áCº¯Êý£¬×¢ÒâºóÃæ¼ÓÒ»ÐÐ{0£¬ 0} - void RegisterMethods(const luaL_Reg *l); - - // ×¢²áµ¥¸öCº¯Êý - void RegisterMethod(cc8* fname, lua_CFunction func); - - // °Ñpreloader¼Óµ½package.preloadÀµ±require"libname"ʱluaµÄloader_preload¸ù¾Ý - // libnameÕÒµ½preloaderÖ±½Ó¼ÓÔØ¡£ÓÃÀ´ÊµÏÖÐèÒªrequireµÄʱºò²Å¼ÓÔØ£¬²¢ÇÒ¼ÓÔØ¹ýÒ»´Îºó - // package.loaded¼Ç¼ÏÂÀ´£¬Ï´β»»áÔÙ¼ÓÔØ¡£Í¨¹ýrequire»áµ÷ÓÃÕâ¸öpreloader¡£ - void RegisterPreloader(cc8* libname, lua_CFunction preloader); - - // ¸ù¾ÝluaL_Reg½¨Á¢lib table£¬²¢ÔÚ_GºÍpackage.loaded½¨Á¢¶ÔlibnameµÄË÷Òý£¬Ö¸Ïòlib table¡£ - void RegisterLib(cc8* libname, const luaL_Reg* l); - -#if LUA_BIND_ENABLE_PLAIN_CLASS - // ×¢²á´¿luaÀàµÄ×¢²áº¯Êý£¬ÓÃÀ´´´½¨´¿luaÀà¡£ - void RegisterPlainClassRegistry(cc8* name); -#endif - -#if LUA_BIND_ENABLE_PLAIN_ENUM - // ×¢²á´¿luaµÄö¾Ù£¬ÒÔ·ÀÖ¹ÐÞ¸Äö¾ÙÖµ¡£ - void RegisterPlainEnumRegistry(cc8* name); -#endif - - protected: - - friend class VM; - - // ÆÁ±Î¶ÔStateµÄµØÖ·Ïà¹Ø²Ù×÷ - void* operator &(); - void* operator new(size_t size); - - lua_State* const mState; - }; - - //--------------------------------------------------------------------------------// - // GetValue()Ä£°åÌØ»¯ - - template <> bool State::GetValue < bool >(int idx, const bool value); - template <> cc8* State::GetValue < cc8* >(int idx, const cc8* value); - template <> double State::GetValue < double >(int idx, const double value); - template <> float State::GetValue < float >(int idx, const float value); - template <> s8 State::GetValue < s8 >(int idx, const s8 value); - template <> s16 State::GetValue < s16 >(int idx, const s16 value); - template <> s32 State::GetValue < s32 >(int idx, const s32 value); - template <> s64 State::GetValue < s64 >(int idx, const s64 value); - template <> u8 State::GetValue < u8 >(int idx, const u8 value); - template <> u16 State::GetValue < u16 >(int idx, const u16 value); - template <> u32 State::GetValue < u32 >(int idx, const u32 value); - template <> u64 State::GetValue < u64 >(int idx, const u64 value); - template <> std::string State::GetValue < std::string >(int idx, const std::string value); - template <> const void* State::GetValue < const void* >(int idx, const void* value); - - //--------------------------------------------------------------------------------// - // CheckValueÄ£°åÌØ»¯ - - template <> bool State::CheckValue < bool >(int idx); - template <> cc8* State::CheckValue < cc8* >(int idx); - template <> double State::CheckValue < double >(int idx); - template <> float State::CheckValue < float >(int idx); - template <> s8 State::CheckValue < s8 >(int idx); - template <> s16 State::CheckValue < s16 >(int idx); - template <> s32 State::CheckValue < s32 >(int idx); - template <> s64 State::CheckValue < s64 >(int idx); - template <> u8 State::CheckValue < u8 >(int idx); - template <> u16 State::CheckValue < u16 >(int idx); - template <> u32 State::CheckValue < u32 >(int idx); - template <> u64 State::CheckValue < u64 >(int idx); - template <> std::string State::CheckValue < std::string >(int idx); - template <> const void* State::CheckValue < const void* >(int idx); - - // ÔÚ³ÉÔ±·½·¨Àï´´½¨State²¢¶Ô²ÎÊý½øÐмì²é¡£ -#define LUA_BIND_SETUP(L, params) \ - LuaBind::State state(L); \ - if(!state.CheckParams(1, params)) return 0 - -#define LUA_BIND_STATE(L) \ - LuaBind::State state(L) - - //--------------------------------------------------------------------------------// - - // È·±£²»°²È«µÄluaµ÷ÓÃÄܹ»ÔÚµ÷ÓÃÖ®ºó·µ»Øµ½×î³õstack״̬¡£ - class ScopedState - : public State - { - public: - ScopedState(lua_State* state) - : State(state) - { - mRestoreTop = lua_gettop(mState); - } - ScopedState(const State& state) - : State(state) - { - mRestoreTop = lua_gettop(mState); - } - ~ScopedState() - { - if (mState) { - if (lua_gettop(mState) != mRestoreTop) { - lua_settop(mState, mRestoreTop); - } - } - } - private: - void* operator new(size_t); - int mRestoreTop; - - }; - -} - -#endif \ No newline at end of file diff --git a/Runtime/LuaBind/LuaBindState.inc b/Runtime/LuaBind/LuaBindState.inc deleted file mode 100644 index 4e7090d..0000000 --- a/Runtime/LuaBind/LuaBindState.inc +++ /dev/null @@ -1,180 +0,0 @@ -namespace LuaBind -{ - - // - // ×¢²á¹¤³§£¬×¢²áclass table£¬ÒÔtype nameΪ¼üÉèÖÃÔÚÃû³Æ¿Õ¼äÉÏ¡£ÔÚ×¢²á½×¶Î²»»áÉèÖÃÔª±í£¬µÈµ½New·½·¨µ÷ÓõÄʱºò²Å»á¡£ - // - template - void State::RegisterFactory() - { - cc8* type = TYPE::GetFactoryName(); - - 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::RegisterFactoryClass(state); - TYPE::RegisterClass(state); - - // ¼ì²âTYPEÀïÃæÊÇ·ñûÓÐ×¢²á±ØÐëµÄ·½·¨ -#define _assertmethod(I, NAME) \ - GetField(I, NAME); \ - assert(IsType(-1, LUA_TFUNCTION)); \ - Pop(); - - //_assertmethod(-1, "New"); - -#undef _assertmethod - -#if LUA_BIND_ENABLE_NATIVE_EXTEND - // .Extend() - lua_pushvalue(state, -1); // class table - lua_pushcclosure(state, TYPE::_ExtendFactory, 1); - lua_setfield(state, -2, "Extend"); -#endif - - // class["__index"] = class - lua_pushvalue(state, -1); // class table - lua_setfield(state, -2, "__index"); - - TYPE::SetClassTableRef(state, -1); - - SetField(top, type); - - // reset top - lua_settop(L, top); - - // ºó´¦Àí - TYPE::RegisterPostprocess(state); - } - - // - // Singleton - // - 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(); - SetField(top, type); - - // reset top - lua_settop(L, top); - - // ºó´¦Àí - TYPE::RegisterPostprocess(state); - } - - template - void State::SetField(int idx, cc8* key, TYPE value) - { - if (IsTableOrUserdata(idx)) - { - idx = AbsIndex(idx); - this->Push(value); - lua_setfield(mState, idx, key); - } - } - - template - void State::SetFieldByIndex(int idx, int key, TYPE value) - { - if (IsTableOrUserdata(idx)) - { - idx = AbsIndex(idx); - this->Push(value); - lua_rawseti(mState, idx, key); - } - } - - template - TYPE State::GetField(int idx, cc8* key, TYPE value) - { - GetField(idx, key); - TYPE result = GetValue < TYPE >(-1, value); - this->Pop(); - - return result; - } - - template - TYPE State::GetField(int idx, int key, TYPE value) - { - GetField(idx, key); - TYPE result = GetValue < TYPE >(-1, value); - Pop(); - - return result; - } - - template - TYPE* State::GetUserdata(int idx) - { - void* p = nullptr; - - if (IsType(idx, LUA_TUSERDATA)) - { - p = *(void**)lua_touserdata(mState, idx); - } - - return static_cast(p); - } - - template - TYPE* State::CheckUserdata(int idx) - { - if (IsType(idx, LUA_TUSERDATA)) - { - if (lua_getmetatable(mState, idx)) // ref table - { - if (lua_getmetatable(mState, -1)) // member table - { - if (lua_getmetatable(mState, -1)) // class table - { - TYPE::PushClassTable(*this); // target class table - if (lua_rawequal(mState, -1, -2)) - { - Pop(4); // ref\member\class\target class - TYPE* udata = GetUserdata(idx); - return udata; // userdata - } - Pop(2); // target class table\class table - } - Pop(1); // member table - } - Pop(1); // ref table - } - } - luaL_typerror(mState, idx, TYPE::GetClassName()); - return nullptr; - } - -} \ No newline at end of file diff --git a/Runtime/LuaBind/LuaBindUtility.h b/Runtime/LuaBind/LuaBindUtility.h deleted file mode 100644 index edc5b18..0000000 --- a/Runtime/LuaBind/LuaBindUtility.h +++ /dev/null @@ -1,66 +0,0 @@ -#ifndef __LUA_BIND_UTILITY_H__ -#define __LUA_BIND_UTILITY_H__ - -// µ¼³önative½Ó¿Ú - -// RegisterClass ×¢²áÀàµÄ·½·¨ºÍ³ÉÔ±£¬±ÈÈçö¾Ù¡¢³£Á¿µÈµ½class table GetFactoryName »ñµÃ¹¤³§µÄÀàÃû£¬ -// ͬʱÓÃÀ´±ÜÃâ×¢²áʱ´íÎó×¢²áΪÁËsingleton£¬Í¨¹ý±àÒëʱ±¨´í±ÜÃâ -#define LUA_BIND_DECL_FACTORY(type, ...) \ - friend class ::State; \ - friend class ::NativeClass; \ - 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; } - -// ×÷Ϊ»ùÀàµÄ³éÏ󹤳§Àà¿ÉÒÔʹÓô˺꣬ע²áÒ»¸öÈë¿Ú£¬ÔÚÅÉÉúÀàµÄ×¢²áº¯ÊýÖе÷Óã¬×¢²á»ùÀàµÄÕâЩ·½·¨¡£ -#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) - -// ±êÃ÷·½·¨ÊµÏֵĺꡣÉÏÏÂÎÄÀïÓÐÒ»¸öL¡£ -#define LUA_BIND_IMPL_METHOD(type, f) int type::f(lua_State* L) - -// ÓÉÓ¦ÓóÌÐòʵÏÖµÄÁ½¸ö½Ó¿Ú¡£ÉÏÏÂÎÄÀïÓÐÒ»¸östate¡£ -#define LUA_BIND_REGISTRY(type) void type::RegisterClass(::State& state) -#define LUA_BIND_POSTPROCESS(type) void type::RegisterPostprocess(::State& state) - -// ÓÃÀ´×¢²áµÄºê¡£Ö®Ç°ÕâÀïÍüÁËÓÿɱäºê£¬µ¼ÖÂûÓÐ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{ \ - luaL_Reg __m[] = {__VA_ARGS__,{0, 0}}; \ - state.RegisterMethods(__m); \ - }while(0) -#define LUA_BIND_REGISTER_ENUM(state, name, ...) \ - do{ \ - ::Enum __e[] = {__VA_ARGS__,{0, 0}}; \ - state.RegisterEnum(name, __e); \ - }while(0) - -#define LUA_BIND_PREPARE(L, T) \ - LUA_BIND_STATE(L); \ - T* self = state.GetUserdata(1); - -#define LUA_BIND_INHERIT(state, type) type::RegisterClass(state) - -#define luaxport private - -#endif \ No newline at end of file diff --git a/Runtime/LuaBind/LuaBindVM.cpp b/Runtime/LuaBind/LuaBindVM.cpp deleted file mode 100644 index 268a5ed..0000000 --- a/Runtime/LuaBind/LuaBindVM.cpp +++ /dev/null @@ -1,82 +0,0 @@ -#include "LuaBindInternal.h" -#include "LuaBindVM.h" - -namespace LuaBind -{ - - VM::VMap VM::VMs; // ͨ¹ýÏ̲߳éÕÒÐéÄâ»ú£¬ÎªÁË·½±ã - - VM* VM::TryGetVM(global_State* gState) - { - auto it = VMs.find(gState); - if (it != VMs.end()) - return it->second; - else - return nullptr; - } - - VM* VM::TryGetVM(lua_State* state) - { - return TryGetVM(G(state)); - } - - VM::VM() - : mStrongRefTable() - , mWeakRefTable() - { - mMainThread = luaL_newstate(); - assert(mMainThread); - mGlobalState = G(mMainThread); - - VMs.insert(std::pair(mGlobalState, this)); - } - - VM::~VM() - { - VMs.erase(mGlobalState); - lua_close(mMainThread); - } - - // ³õʼ»¯context - void VM::Setup() - { - LUA_BIND_STATE(mMainThread); - - mStrongRefTable.Init(state, "GAMELAB_UNIVERSAL_STRONG_REFERENCE_TABLE"); - mWeakRefTable.Init(state, "GAMELAB_UNIVERSAL_WEAK_REFERENCE_TABLE", "v"); - } - - lua_State* VM::CreateThread() - { - lua_State* thread = lua_newthread(mMainThread); - assert(thread); - return thread; - } - - lua_State* VM::GetMainThread() - { - return mMainThread; - } - - State VM::GetMainState() - { - return mMainThread; - } - - RefTable& VM::GetStrongRefTable() - { - return mStrongRefTable; - } - - RefTable& VM::GetWeakRefTable() - { - return mWeakRefTable; - } - - void VM::OpenLibs() - { - assert(mMainThread); - luaL_openlibs(mMainThread); - } - -} \ No newline at end of file diff --git a/Runtime/LuaBind/LuaBindVM.h b/Runtime/LuaBind/LuaBindVM.h deleted file mode 100644 index 3bfe899..0000000 --- a/Runtime/LuaBind/LuaBindVM.h +++ /dev/null @@ -1,58 +0,0 @@ -#ifndef __LUA_BIND_CONTEXT_H__ -#define __LUA_BIND_CONTEXT_H__ - -#include -#include - -#include "LuaBindRef.h" -#include "LuaBindConfig.h" -#include "LuaBindState.h" -#include "LuaBindGlobalState.h" - -namespace LuaBind -{ - - // µ¥¸ölua_stateÏà¹ØµÄcontext¡£ÊÇһϵÁдúÀíµÄ¼¯ºÏ£¬¿½±´Ò²Ã»¹ØÏµ£¬Ö÷ÒªÊÇΪÁ˽ÚÔ¼ÄÚ´æ¡£ - class VM - { - public: - - // ¸ù¾Ýglobal_StateÄõ½ÐéÄâ»ú¡£ - static VM* TryGetVM(global_State* gState); - static VM* TryGetVM(lua_State* state); - - VM(); - ~VM(); - - // ´´½¨ÐéÄâ»úºó£¬ÐèÒªÊÖ¶¯µ÷ÓÃSetupº¯Êý£¬³õʼ»¯Ò»Ð©ÐéÄâ»ú״̬¡£ - void Setup(); - void OpenLibs(); - - lua_State* GetMainThread(); - lua_State* CreateThread(); - State GetMainState(); - - RefTable& GetStrongRefTable(); - RefTable& GetWeakRefTable(); - - private: - - typedef std::map VMap; - - static VMap VMs; // ͨ¹ýglobal_StateË÷ÒýÐéÄâ»ú£¬ÎªÁË·½±ã - - RefTable mStrongRefTable; // GAMELAB_UNIVERSAL_STRONG_REFERENCE_TABLE - RefTable mWeakRefTable; // GAMELAB_UNIVERSAL_WEAK_REFERENCE_TABLE - - global_State* mGlobalState; // ÐéÄâ»úµÄglobal_State£¬Óɵ±Ç°ÐéÄâ»úµÄËùÓÐÏ̹߳²Ïí - lua_State* mMainThread; // Ö÷Ïß³Ì - -#if LUA_BIND_PROFILER - size_t mObjectCount; // ͳ¼ÆËùÓÐÔÚ´ËÐéÄâ»úÖд´½¨µÄʵÀý -#endif - - }; - -} - -#endif \ No newline at end of file diff --git a/Runtime/LuaBind/LuaBindWatchDog.cpp b/Runtime/LuaBind/LuaBindWatchDog.cpp deleted file mode 100644 index e69de29..0000000 diff --git a/Runtime/LuaBind/LuaBindWatchDog.h b/Runtime/LuaBind/LuaBindWatchDog.h deleted file mode 100644 index 794faa9..0000000 --- a/Runtime/LuaBind/LuaBindWatchDog.h +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef __LUA_BIND_DOG_H__ -#define __LUA_BIND_DOG_H__ - -#include "LuaBindConfig.h" - -namespace LuaBind -{ - - // - // NativeClassʵÀýµÄÒýÓüÆÊý¶îwatch dog£¬Ö»ÓÐÔÚwatch dogͨ¹ýʱ²Å¿ÉÒÔdelete¡£ - // - class WatchDog - { - public: - WatchDog() - : mVMRef(0) - , mNativeRef(0) - { - } - - inline operator bool() - { - return mVMRef == 0 && mNativeRef == 0; - } - - uint mVMRef; // ÍйܸøµÄÐéÄâ»úÊý - uint mNativeRef; // ±¾µØÒýÓÃÊý - - }; - -} - -#endif \ No newline at end of file diff --git a/Runtime/Scripting/GL/GL.bind.cpp b/Runtime/Scripting/GL/GL.bind.cpp index 57dba09..bed55ca 100644 --- a/Runtime/Scripting/GL/GL.bind.cpp +++ b/Runtime/Scripting/GL/GL.bind.cpp @@ -1,5 +1,5 @@ #include "Runtime/Graphics/OpenGL.h" -#include "Runtime/LuaBind/LuaBind.h" +#include "Runtime/Lua/LuaBind/LuaBind.h" // GameLab.Engine.GL void luaopen_GameLab_Engine_GL(lua_State* L) -- cgit v1.1-26-g67d0