From a5f288ca3f4621ad60ed270a2e95ef8acc6c90d2 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sat, 27 Sep 2014 16:25:26 +0200 Subject: Add Lua scripting context --- CMakeLists.txt | 1 + resources/script/test.lua | 14 ++++++ src/CMakeLists.txt | 10 ++--- src/control/RPGEdit.cpp | 1 + src/control/ScriptContext.hpp | 102 ++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 123 insertions(+), 5 deletions(-) create mode 100644 resources/script/test.lua create mode 100644 src/control/ScriptContext.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index b0a5fe3..8d575ce 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,6 +4,7 @@ project(RPGEDIT CXX) find_package(PkgConfig REQUIRED) pkg_check_modules(SDL2 REQUIRED sdl2 SDL2_image) +pkg_check_modules(LUA REQUIRED lua>=5.2) add_subdirectory(src) diff --git a/resources/script/test.lua b/resources/script/test.lua new file mode 100644 index 0000000..f78cf13 --- /dev/null +++ b/resources/script/test.lua @@ -0,0 +1,14 @@ +function print_table(foo, bar) + for k, v in pairs(foo) do + print(bar .. k, v) + + if type(v) == 'table' and bar .. k ~= '_G' then + print_table(v, bar .. k .. '.') + end + end +end + +print_table(_G, '') + +print(getmetatable('').__index) +print(string) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 54836d0..8a38474 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,5 +1,5 @@ -include_directories(${SDL2_INCLUDE_DIRS}) -link_directories(${SDL2_LIBRARY_DIRS}) +include_directories(${SDL2_INCLUDE_DIRS} ${LUA_INCLUDE_DIRS}) +link_directories(${SDL2_LIBRARY_DIRS} ${LUA_LIBRARY_DIRS}) add_executable(rpgedit rpgedit.cpp @@ -9,6 +9,6 @@ add_executable(rpgedit view/MapView.cpp view/SpriteCache.cpp ) -set_target_properties(rpgedit PROPERTIES COMPILE_FLAGS "-std=c++11 -Wall ${SDL2_CFLAGS_OTHER}") -set_target_properties(rpgedit PROPERTIES LINK_FLAGS "${SDL2_LDFLAGS_OTHER}") -target_link_libraries(rpgedit ${SDL2_LIBRARIES}) +set_target_properties(rpgedit PROPERTIES COMPILE_FLAGS "-std=c++11 -Wall ${SDL2_CFLAGS_OTHER} ${LUA_CFLAGS_OTHER}") +set_target_properties(rpgedit PROPERTIES LINK_FLAGS "${SDL2_LDFLAGS_OTHER} ${LUA_LDFLAGS_OTHER}") +target_link_libraries(rpgedit ${SDL2_LIBRARIES} ${LUA_LIBRARIES}) diff --git a/src/control/RPGEdit.cpp b/src/control/RPGEdit.cpp index f42a774..a1a699f 100644 --- a/src/control/RPGEdit.cpp +++ b/src/control/RPGEdit.cpp @@ -26,6 +26,7 @@ #include "RPGEdit.hpp" #include "MapContext.hpp" +#include "ScriptContext.hpp" #include "../view/MapView.hpp" diff --git a/src/control/ScriptContext.hpp b/src/control/ScriptContext.hpp new file mode 100644 index 0000000..34dc8fc --- /dev/null +++ b/src/control/ScriptContext.hpp @@ -0,0 +1,102 @@ +/* + Copyright (c) 2014, Matthias Schiffer + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + +#pragma once + +extern "C" { +#include +#include +#include +} + +#include +#include + + +namespace RPGEdit { + +namespace Control { + +class ScriptContext { +private: + lua_State *L; + +public: + ScriptContext(const ScriptContext &other) = delete; + ScriptContext(ScriptContext &&other) = delete; + ScriptContext & operator=(const ScriptContext &other) = delete; + ScriptContext & operator=(ScriptContext &&other) = delete; + + ScriptContext() { + const std::pair libs[] = { + {"_G", luaopen_base}, + {"bit32", luaopen_bit32}, + {"math", luaopen_math}, + {"string", luaopen_string}, + {"table", luaopen_table}, + }; + + L = luaL_newstate(); + + for (auto &lib : libs) { + luaL_requiref(L, lib.first, lib.second, 1); + lua_pop(L, 1); + } + + for (const char *f : {"dofile", "loadfile", "require"}) { + lua_pushnil(L); + lua_setglobal(L, f); + } + + lua_newtable(L); + lua_rawsetp(L, LUA_REGISTRYINDEX, this); + } + + ~ScriptContext() { + lua_close(L); + } + + void load(const std::string &name) { + std::string filename = "../resources/script/" + name + ".lua"; + + lua_rawgetp(L, LUA_REGISTRYINDEX, this); + lua_pushstring(L, name.c_str()); + luaL_loadfile(L, filename.c_str()); + lua_rawset(L, -3); + lua_pop(L, 1); + } + + void run(const std::string &name) { + lua_rawgetp(L, LUA_REGISTRYINDEX, this); + lua_getfield(L, -1, name.c_str()); + lua_remove(L, -2); + lua_call(L, 0, 0); + } +}; + +} + +} -- cgit v1.2.3