From 1b250f668bf31bdfc9d4e7975daa23f3474c298a Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 5 Oct 2014 15:46:50 +0200 Subject: [PATCH 01/10] Implement mappings for Lua types --- src/CMakeLists.txt | 1 + src/control/ScriptContext.hpp | 7 ++ src/model/ScriptValue.hpp | 143 ++++++++++++++++++++++++++++++++++ src/model/Scriptable.cpp | 58 ++++++++++++++ src/model/Scriptable.hpp | 57 ++++++++++++++ 5 files changed, 266 insertions(+) create mode 100644 src/model/ScriptValue.hpp create mode 100644 src/model/Scriptable.cpp create mode 100644 src/model/Scriptable.hpp diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 8a38474..3ba9985 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -6,6 +6,7 @@ add_executable(rpgedit control/MapContext.cpp control/RPGEdit.cpp model/Map.cpp + model/Scriptable.cpp view/MapView.cpp view/SpriteCache.cpp ) diff --git a/src/control/ScriptContext.hpp b/src/control/ScriptContext.hpp index 23f0fab..86c8c0f 100644 --- a/src/control/ScriptContext.hpp +++ b/src/control/ScriptContext.hpp @@ -26,6 +26,8 @@ #pragma once +#include "../model/ScriptValue.hpp" + extern "C" { #include #include @@ -100,6 +102,11 @@ public: lua_close(L); } + void setGlobal(const std::string &key, Model::ScriptValue *value) { + value->push(L); + lua_setglobal(L, key.c_str()); + } + void load(const std::string &name) { std::string filename = "../resources/script/" + name + ".lua"; diff --git a/src/model/ScriptValue.hpp b/src/model/ScriptValue.hpp new file mode 100644 index 0000000..a82ba8e --- /dev/null +++ b/src/model/ScriptValue.hpp @@ -0,0 +1,143 @@ +/* + 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 +#include + +namespace RPGEdit { + +namespace Model { + +class ScriptValue { +public: + virtual void push(lua_State *L) = 0; + + virtual ~ScriptValue() {} +}; + + +class ScriptBoolean : public ScriptValue { +private: + bool value; + +public: + ScriptBoolean(bool value0) : value(value0) { + } + + ScriptBoolean & operator=(bool newValue) { + value = newValue; + return *this; + } + + operator bool() const { + return value; + } + + virtual void push(lua_State *L) { + lua_pushboolean(L, value); + } +}; + +class ScriptNumber : public ScriptValue { +private: + lua_Number value; + +public: + ScriptNumber(lua_Number value0) : value(value0) { + } + + ScriptNumber & operator=(lua_Number newValue) { + value = newValue; + return *this; + } + + operator lua_Number() const { + return value; + } + + virtual void push(lua_State *L) { + lua_pushnumber(L, value); + } +}; + +class ScriptString : public ScriptValue { +private: + std::string value; + +public: + ScriptString(std::string &value0) : value(value0) { + } + + ScriptString & operator=(std::string &newValue) { + value = newValue; + return *this; + } + + operator std::string &() { + return value; + } + + virtual void push(lua_State *L) { + lua_pushstring(L, value.c_str()); + } +}; + +class ScriptTable : public ScriptValue { +public: + typedef std::unordered_map> MapType; + +private: + MapType value; + +public: + std::shared_ptr & operator[](const std::string &key) { + return value[key]; + } + + virtual void push(lua_State *L) { + lua_createtable(L, 0, value.size()); + + for (const auto &entry : value) { + lua_pushstring(L, entry.first.c_str()); + entry.second->push(L); + + lua_settable(L, -3); + } + } +}; + +} + +} diff --git a/src/model/Scriptable.cpp b/src/model/Scriptable.cpp new file mode 100644 index 0000000..5bec739 --- /dev/null +++ b/src/model/Scriptable.cpp @@ -0,0 +1,58 @@ +/* + 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. +*/ + + +#include "Scriptable.hpp" + + +namespace RPGEdit { + +namespace Model { + +int Scriptable::gc(lua_State *L) { + std::shared_ptr *value = static_cast *>(lua_touserdata(L, -1)); + + value->~shared_ptr(); + + return 0; +} + +void Scriptable::setupMetatable(lua_State *L) { + if (luaL_newmetatable(L, "RPGEdit::Model::Scriptable")) { + lua_pushstring(L, "__metatable"); + lua_pushstring(L, "protected"); + lua_rawset(L, -3); + + lua_pushstring(L, "__gc"); + lua_pushcfunction(L, &gc); + lua_rawset(L, -3); + } + + lua_setmetatable(L, -2); +} + +} + +} diff --git a/src/model/Scriptable.hpp b/src/model/Scriptable.hpp new file mode 100644 index 0000000..20ae7ff --- /dev/null +++ b/src/model/Scriptable.hpp @@ -0,0 +1,57 @@ +/* + 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 + + +#include "ScriptValue.hpp" + +#include + + +namespace RPGEdit { + +namespace Model { + +class Scriptable : public ScriptValue, public std::enable_shared_from_this { +private: + static int gc(lua_State *L); + + void setupMetatable(lua_State *L); + +public: + virtual void push(lua_State *L) { + + void *ptr = lua_newuserdata(L, sizeof(std::shared_ptr)); + setupMetatable(L); + + new (ptr) std::shared_ptr(shared_from_this()); + } +}; + +} + +} From 2453bcdcc11a371baafaa94f30685e71ddd56638 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Fri, 26 Dec 2014 22:38:07 +0100 Subject: [PATCH 02/10] Cleanup some includes --- src/model/Entity.hpp | 2 -- src/model/Map.hpp | 1 + 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/model/Entity.hpp b/src/model/Entity.hpp index 677eeb5..fc1debb 100644 --- a/src/model/Entity.hpp +++ b/src/model/Entity.hpp @@ -28,11 +28,9 @@ #include "Direction.hpp" -#include "Position.hpp" #include -#include namespace RPGEdit { diff --git a/src/model/Map.hpp b/src/model/Map.hpp index ed58fd6..20b13a3 100644 --- a/src/model/Map.hpp +++ b/src/model/Map.hpp @@ -35,6 +35,7 @@ #include "CollisionType.hpp" #include "Entity.hpp" +#include "Position.hpp" namespace RPGEdit { From 12cf10a35ca156e4d34f5b2154e01484fdfaf41c Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sat, 14 Feb 2015 20:05:58 +0100 Subject: [PATCH 03/10] Initialize SDL image and check initialization return --- src/rpgedit.cpp | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/rpgedit.cpp b/src/rpgedit.cpp index 6ef5dd3..fc3fe5f 100644 --- a/src/rpgedit.cpp +++ b/src/rpgedit.cpp @@ -27,15 +27,27 @@ #include "control/RPGEdit.hpp" #include +#include #include +#include + extern "C" int main(__attribute__((unused)) int argc, __attribute__((unused)) char *argv[]) { - SDL_Init(SDL_INIT_VIDEO); + if (SDL_Init(SDL_INIT_VIDEO) < 0) { + std::cerr << "Unable to initialize SDL" << std::endl; + return 1; + } + + if (!(IMG_Init(IMG_INIT_PNG) & IMG_INIT_PNG)) { + std::cerr << "Unable to initialize PNG loader" << std::endl; + return 1; + } RPGEdit::Control::RPGEdit().run(); + IMG_Quit(); SDL_Quit(); return 0; From f05141f1f78d9e0d917b2cc07f0fb09fd7f62801 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sat, 14 Feb 2015 21:27:42 +0100 Subject: [PATCH 04/10] Find only Lua 5.2 --- CMakeLists.txt | 2 +- src/CMakeLists.txt | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8d575ce..0cdd80d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,7 +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) +find_package(Lua 5.2 EXACT REQUIRED) add_subdirectory(src) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 3ba9985..3e7dd61 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,5 +1,5 @@ -include_directories(${SDL2_INCLUDE_DIRS} ${LUA_INCLUDE_DIRS}) -link_directories(${SDL2_LIBRARY_DIRS} ${LUA_LIBRARY_DIRS}) +include_directories(${SDL2_INCLUDE_DIRS} ${LUA_INCLUDE_DIR}) +link_directories(${SDL2_LIBRARY_DIRS}) add_executable(rpgedit rpgedit.cpp @@ -10,6 +10,6 @@ add_executable(rpgedit view/MapView.cpp view/SpriteCache.cpp ) -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}") +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} ${LUA_LIBRARIES}) From 0b3e29dea9863c4b5ca0c77958bbcb32a05867ca Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sat, 14 Feb 2015 23:12:07 +0100 Subject: [PATCH 05/10] Some work towards scriptable events --- resources/script/interact.lua | 3 ++ resources/script/test.lua | 20 +++++--- src/CMakeLists.txt | 1 + src/control/MapContext.cpp | 14 ++++-- src/control/MapContext.hpp | 4 +- src/control/RPGEdit.cpp | 3 +- src/control/RPGEdit.hpp | 2 + src/control/ScriptContext.cpp | 90 +++++++++++++++++++++++++++++++++++ src/control/ScriptContext.hpp | 63 ++++++++---------------- src/model/Entity.hpp | 15 ++++-- src/model/ScriptValue.hpp | 6 +-- 11 files changed, 160 insertions(+), 61 deletions(-) create mode 100644 resources/script/interact.lua create mode 100644 src/control/ScriptContext.cpp diff --git a/resources/script/interact.lua b/resources/script/interact.lua new file mode 100644 index 0000000..98bb34f --- /dev/null +++ b/resources/script/interact.lua @@ -0,0 +1,3 @@ +function interact(entity, time) + print('Interact! ' .. time) +end diff --git a/resources/script/test.lua b/resources/script/test.lua index f78cf13..1dc1fc4 100644 --- a/resources/script/test.lua +++ b/resources/script/test.lua @@ -1,14 +1,20 @@ -function print_table(foo, bar) +local 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 + --if type(v) == 'table' and bar .. k ~= '_G' then + -- print_table(v, bar .. k .. '.') + --end end end -print_table(_G, '') +--print(getmetatable(_G)) +--setmetatable(_G, {}) +--print_table(_G, '') -print(getmetatable('').__index) -print(string) +print(bar) +print(getmetatable(bar)) + +--print(getmetatable('').bar) +--getmetatable('').bar = 'bar' +--print(getmetatable('').bar) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 3e7dd61..46eb1a2 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -5,6 +5,7 @@ add_executable(rpgedit rpgedit.cpp control/MapContext.cpp control/RPGEdit.cpp + control/ScriptContext.cpp model/Map.cpp model/Scriptable.cpp view/MapView.cpp diff --git a/src/control/MapContext.cpp b/src/control/MapContext.cpp index 6ba3b6b..f7ad2fe 100644 --- a/src/control/MapContext.cpp +++ b/src/control/MapContext.cpp @@ -31,10 +31,13 @@ namespace RPGEdit { namespace Control { -MapContext::MapContext(EventBus *eventBus0, InputHandler *inputHandler0, const std::shared_ptr &window, const Model::Map &map0) - : eventBus(eventBus0), inputHandler(inputHandler0), map(map0) { +MapContext::MapContext(EventBus *eventBus0, InputHandler *inputHandler0, ScriptContext *scriptContext0, const std::shared_ptr &window, const Model::Map &map0) + : eventBus(eventBus0), inputHandler(inputHandler0), scriptContext(scriptContext0), map(map0) { view = std::unique_ptr(new View::MapView(window, map.getTileset())); + Model::Entity *square = map.addEntity("square", Model::Position{10, 10}); + square->setScriptInteract("interact", "interact"); + playerEntity = map.addEntity("square", Model::Position{8, 8}); view->updateEntities(map.getEntities()); @@ -80,7 +83,12 @@ void MapContext::interact(uint64_t time) { if (!target) return; - target->interact(time); + const std::pair &interactScript = target->getScriptInteract(); + if (interactScript.first.empty()) + return; + + Model::ScriptNumber scriptTime(time); + scriptContext->run(interactScript.first, interactScript.second, nullptr, &scriptTime); } void MapContext::keyPressed(uint16_t key, uint64_t time) { diff --git a/src/control/MapContext.hpp b/src/control/MapContext.hpp index 18d4cfe..5e17a42 100644 --- a/src/control/MapContext.hpp +++ b/src/control/MapContext.hpp @@ -28,6 +28,7 @@ #include "EventBus.hpp" #include "InputHandler.hpp" +#include "ScriptContext.hpp" #include "../model/Map.hpp" #include "../view/MapView.hpp" @@ -43,6 +44,7 @@ class MapContext { private: EventBus *const eventBus; InputHandler *const inputHandler; + ScriptContext *const scriptContext; std::unique_ptr view; @@ -59,7 +61,7 @@ private: } public: - MapContext(EventBus *eventBus0, InputHandler *inputHandler0, const std::shared_ptr &window, const Model::Map &map0); + MapContext(EventBus *eventBus0, InputHandler *inputHandler0, ScriptContext *scriptContext0, const std::shared_ptr &window, const Model::Map &map0); void render(uint64_t time) { view->render(&map, getViewPosition(time), time); diff --git a/src/control/RPGEdit.cpp b/src/control/RPGEdit.cpp index a1a699f..6068236 100644 --- a/src/control/RPGEdit.cpp +++ b/src/control/RPGEdit.cpp @@ -26,7 +26,6 @@ #include "RPGEdit.hpp" #include "MapContext.hpp" -#include "ScriptContext.hpp" #include "../view/MapView.hpp" @@ -106,7 +105,7 @@ void RPGEdit::run() { window = std::make_shared(); - ctx = std::make_shared(&eventBus, &inputHandler, window, *map); + ctx = std::make_shared(&eventBus, &inputHandler, &scriptContext, window, *map); eventThread = std::thread([this] { eventLoop(); }); diff --git a/src/control/RPGEdit.hpp b/src/control/RPGEdit.hpp index 6011ecd..6c6c743 100644 --- a/src/control/RPGEdit.hpp +++ b/src/control/RPGEdit.hpp @@ -46,6 +46,8 @@ private: EventBus eventBus; InputHandler inputHandler; + ScriptContext scriptContext; + std::shared_ptr window; std::shared_ptr ctx; diff --git a/src/control/ScriptContext.cpp b/src/control/ScriptContext.cpp new file mode 100644 index 0000000..cc10f74 --- /dev/null +++ b/src/control/ScriptContext.cpp @@ -0,0 +1,90 @@ +/* + 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. +*/ + + +#include "ScriptContext.hpp" + + +namespace RPGEdit { + +namespace Control { + +void ScriptContext::setupEnv() { + const std::pair libs[] = { + {"_G", luaopen_base}, + {"bit32", luaopen_bit32}, + {"math", luaopen_math}, + {"string", luaopen_string}, + {"table", luaopen_table}, + }; + + 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); + } +} + +void ScriptContext::cleanupEnv() { + lua_pushglobaltable(L); + + lua_pushnil(L); + lua_setmetatable(L, -2); + + lua_pushnil(L); + while (lua_next(L, -2) != 0) { + lua_pop(L, 1); + + lua_pushvalue(L, -1); + lua_pushnil(L); + + lua_rawset(L, -4); + } + + lua_pop(L, 1); +} + +void ScriptContext::load(const std::string &script) { + if (loadedScripts.count(script)) + return; + + std::string filename = "../resources/script/" + script + ".lua"; + + lua_rawgetp(L, LUA_REGISTRYINDEX, this); + lua_pushstring(L, script.c_str()); + luaL_loadfile(L, filename.c_str()); + lua_rawset(L, -3); + lua_pop(L, 1); + + loadedScripts.insert(script); +} + +} + +} diff --git a/src/control/ScriptContext.hpp b/src/control/ScriptContext.hpp index 86c8c0f..f9f8445 100644 --- a/src/control/ScriptContext.hpp +++ b/src/control/ScriptContext.hpp @@ -36,6 +36,7 @@ extern "C" { #include #include +#include namespace RPGEdit { @@ -46,43 +47,25 @@ class ScriptContext { private: lua_State *L; - void setupEnv() { - const std::pair libs[] = { - {"_G", luaopen_base}, - {"bit32", luaopen_bit32}, - {"math", luaopen_math}, - {"string", luaopen_string}, - {"table", luaopen_table}, - }; + std::unordered_set loadedScripts; - for (auto &lib : libs) { - luaL_requiref(L, lib.first, lib.second, 1); - lua_pop(L, 1); - } + void setupEnv(); + void cleanupEnv(); - for (const char *f : {"dofile", "loadfile", "require"}) { - lua_pushnil(L); - lua_setglobal(L, f); - } + void load(const std::string &script); + + size_t pushArgs() { + return 0; } - void cleanupEnv() { - lua_pushglobaltable(L); - - lua_pushnil(L); - lua_setmetatable(L, -2); - - lua_pushnil(L); - while (lua_next(L, -2) != 0) { - lua_pop(L, 1); - - lua_pushvalue(L, -1); + template + size_t pushArgs(Model::ScriptValue *v, Args ...args) { + if (v) + v->push(L); + else lua_pushnil(L); - lua_rawset(L, -4); - } - - lua_pop(L, 1); + return pushArgs(args...) + 1; } public: @@ -107,25 +90,21 @@ public: lua_setglobal(L, key.c_str()); } - void load(const std::string &name) { - std::string filename = "../resources/script/" + name + ".lua"; + template + void run(const std::string &script, const std::string &name, Args ...args) { + load(script); - 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) { setupEnv(); lua_rawgetp(L, LUA_REGISTRYINDEX, this); - lua_getfield(L, -1, name.c_str()); + lua_getfield(L, -1, script.c_str()); lua_remove(L, -2); lua_call(L, 0, 0); + lua_getglobal(L, name.c_str()); + lua_call(L, pushArgs(args...), 0); + cleanupEnv(); } }; diff --git a/src/model/Entity.hpp b/src/model/Entity.hpp index fc1debb..b14e122 100644 --- a/src/model/Entity.hpp +++ b/src/model/Entity.hpp @@ -28,19 +28,23 @@ #include "Direction.hpp" +#include "Scriptable.hpp" #include +#include namespace RPGEdit { namespace Model { -class Entity { +class Entity : public Scriptable { private: std::string name; + std::pair scriptInteract; + Direction direction; public: @@ -60,8 +64,13 @@ public: direction = dir; } - void interact(uint64_t time) { - std::fprintf(stderr, "Tried to interact with `%s' entity at %llu\n", name.c_str(), (unsigned long long)time); + const std::pair & getScriptInteract() const { + return scriptInteract; + } + + void setScriptInteract(const std::string &script, const std::string &name) { + scriptInteract.first = script; + scriptInteract.second = name; } }; diff --git a/src/model/ScriptValue.hpp b/src/model/ScriptValue.hpp index a82ba8e..04c4e55 100644 --- a/src/model/ScriptValue.hpp +++ b/src/model/ScriptValue.hpp @@ -116,13 +116,13 @@ public: class ScriptTable : public ScriptValue { public: - typedef std::unordered_map> MapType; + typedef std::unordered_map, std::shared_ptr> MapType; private: MapType value; public: - std::shared_ptr & operator[](const std::string &key) { + std::shared_ptr & operator[](const std::shared_ptr &key) { return value[key]; } @@ -130,7 +130,7 @@ public: lua_createtable(L, 0, value.size()); for (const auto &entry : value) { - lua_pushstring(L, entry.first.c_str()); + entry.first->push(L); entry.second->push(L); lua_settable(L, -3); From 969de84c135ed73db31aa96ef12fe1d589460aed Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sat, 14 Feb 2015 23:14:34 +0100 Subject: [PATCH 06/10] Update license years --- src/control/EventBus.hpp | 2 +- src/control/InputHandler.hpp | 2 +- src/control/MapContext.cpp | 2 +- src/control/MapContext.hpp | 2 +- src/control/RPGEdit.cpp | 2 +- src/control/RPGEdit.hpp | 2 +- src/control/ScriptContext.cpp | 2 +- src/control/ScriptContext.hpp | 2 +- src/control/TimeProvider.hpp | 2 +- src/model/CollisionType.hpp | 2 +- src/model/Direction.hpp | 2 +- src/model/Entity.hpp | 2 +- src/model/Map.cpp | 2 +- src/model/Map.hpp | 2 +- src/model/Position.hpp | 2 +- src/model/ScriptValue.hpp | 2 +- src/model/Scriptable.cpp | 2 +- src/model/Scriptable.hpp | 2 +- src/rpgedit.cpp | 2 +- src/view/MapView.cpp | 2 +- src/view/MapView.hpp | 2 +- src/view/SpriteCache.cpp | 2 +- src/view/SpriteCache.hpp | 2 +- src/view/Window.hpp | 2 +- 24 files changed, 24 insertions(+), 24 deletions(-) diff --git a/src/control/EventBus.hpp b/src/control/EventBus.hpp index 7284883..e94c494 100644 --- a/src/control/EventBus.hpp +++ b/src/control/EventBus.hpp @@ -1,5 +1,5 @@ /* - Copyright (c) 2014, Matthias Schiffer + Copyright (c) 2014-2015, Matthias Schiffer All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/src/control/InputHandler.hpp b/src/control/InputHandler.hpp index 7eb98a9..ecb7876 100644 --- a/src/control/InputHandler.hpp +++ b/src/control/InputHandler.hpp @@ -1,5 +1,5 @@ /* - Copyright (c) 2014, Matthias Schiffer + Copyright (c) 2014-2015, Matthias Schiffer All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/src/control/MapContext.cpp b/src/control/MapContext.cpp index f7ad2fe..8065b04 100644 --- a/src/control/MapContext.cpp +++ b/src/control/MapContext.cpp @@ -1,5 +1,5 @@ /* - Copyright (c) 2014, Matthias Schiffer + Copyright (c) 2014-2015, Matthias Schiffer All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/src/control/MapContext.hpp b/src/control/MapContext.hpp index 5e17a42..316f70b 100644 --- a/src/control/MapContext.hpp +++ b/src/control/MapContext.hpp @@ -1,5 +1,5 @@ /* - Copyright (c) 2014, Matthias Schiffer + Copyright (c) 2014-2015, Matthias Schiffer All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/src/control/RPGEdit.cpp b/src/control/RPGEdit.cpp index 6068236..71f7dcf 100644 --- a/src/control/RPGEdit.cpp +++ b/src/control/RPGEdit.cpp @@ -1,5 +1,5 @@ /* - Copyright (c) 2014, Matthias Schiffer + Copyright (c) 2014-2015, Matthias Schiffer All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/src/control/RPGEdit.hpp b/src/control/RPGEdit.hpp index 6c6c743..e1f1731 100644 --- a/src/control/RPGEdit.hpp +++ b/src/control/RPGEdit.hpp @@ -1,5 +1,5 @@ /* - Copyright (c) 2014, Matthias Schiffer + Copyright (c) 2014-2015, Matthias Schiffer All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/src/control/ScriptContext.cpp b/src/control/ScriptContext.cpp index cc10f74..b92c8e5 100644 --- a/src/control/ScriptContext.cpp +++ b/src/control/ScriptContext.cpp @@ -1,5 +1,5 @@ /* - Copyright (c) 2014, Matthias Schiffer + Copyright (c) 2014-2015, Matthias Schiffer All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/src/control/ScriptContext.hpp b/src/control/ScriptContext.hpp index f9f8445..9416d0e 100644 --- a/src/control/ScriptContext.hpp +++ b/src/control/ScriptContext.hpp @@ -1,5 +1,5 @@ /* - Copyright (c) 2014, Matthias Schiffer + Copyright (c) 2014-2015, Matthias Schiffer All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/src/control/TimeProvider.hpp b/src/control/TimeProvider.hpp index 1880f7b..2278114 100644 --- a/src/control/TimeProvider.hpp +++ b/src/control/TimeProvider.hpp @@ -1,5 +1,5 @@ /* - Copyright (c) 2014, Matthias Schiffer + Copyright (c) 2014-2015, Matthias Schiffer All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/src/model/CollisionType.hpp b/src/model/CollisionType.hpp index 50bb608..d44c2dc 100644 --- a/src/model/CollisionType.hpp +++ b/src/model/CollisionType.hpp @@ -1,5 +1,5 @@ /* - Copyright (c) 2014, Matthias Schiffer + Copyright (c) 2014-2015, Matthias Schiffer All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/src/model/Direction.hpp b/src/model/Direction.hpp index e817170..a9c4776 100644 --- a/src/model/Direction.hpp +++ b/src/model/Direction.hpp @@ -1,5 +1,5 @@ /* - Copyright (c) 2014, Matthias Schiffer + Copyright (c) 2014-2015, Matthias Schiffer All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/src/model/Entity.hpp b/src/model/Entity.hpp index b14e122..169b54d 100644 --- a/src/model/Entity.hpp +++ b/src/model/Entity.hpp @@ -1,5 +1,5 @@ /* - Copyright (c) 2014, Matthias Schiffer + Copyright (c) 2014-2015, Matthias Schiffer All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/src/model/Map.cpp b/src/model/Map.cpp index 2df54b7..191297a 100644 --- a/src/model/Map.cpp +++ b/src/model/Map.cpp @@ -1,5 +1,5 @@ /* - Copyright (c) 2014, Matthias Schiffer + Copyright (c) 2014-2015, Matthias Schiffer All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/src/model/Map.hpp b/src/model/Map.hpp index 20b13a3..3786d1d 100644 --- a/src/model/Map.hpp +++ b/src/model/Map.hpp @@ -1,5 +1,5 @@ /* - Copyright (c) 2014, Matthias Schiffer + Copyright (c) 2014-2015, Matthias Schiffer All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/src/model/Position.hpp b/src/model/Position.hpp index c8fc477..a2f5c6f 100644 --- a/src/model/Position.hpp +++ b/src/model/Position.hpp @@ -1,5 +1,5 @@ /* - Copyright (c) 2014, Matthias Schiffer + Copyright (c) 2014-2015, Matthias Schiffer All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/src/model/ScriptValue.hpp b/src/model/ScriptValue.hpp index 04c4e55..7a2e0b4 100644 --- a/src/model/ScriptValue.hpp +++ b/src/model/ScriptValue.hpp @@ -1,5 +1,5 @@ /* - Copyright (c) 2014, Matthias Schiffer + Copyright (c) 2014-2015, Matthias Schiffer All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/src/model/Scriptable.cpp b/src/model/Scriptable.cpp index 5bec739..f2deee2 100644 --- a/src/model/Scriptable.cpp +++ b/src/model/Scriptable.cpp @@ -1,5 +1,5 @@ /* - Copyright (c) 2014, Matthias Schiffer + Copyright (c) 2014-2015, Matthias Schiffer All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/src/model/Scriptable.hpp b/src/model/Scriptable.hpp index 20ae7ff..473a50a 100644 --- a/src/model/Scriptable.hpp +++ b/src/model/Scriptable.hpp @@ -1,5 +1,5 @@ /* - Copyright (c) 2014, Matthias Schiffer + Copyright (c) 2014-2015, Matthias Schiffer All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/src/rpgedit.cpp b/src/rpgedit.cpp index fc3fe5f..54c34fc 100644 --- a/src/rpgedit.cpp +++ b/src/rpgedit.cpp @@ -1,5 +1,5 @@ /* - Copyright (c) 2014, Matthias Schiffer + Copyright (c) 2014-2015, Matthias Schiffer All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/src/view/MapView.cpp b/src/view/MapView.cpp index 20d5af5..b8bc25b 100644 --- a/src/view/MapView.cpp +++ b/src/view/MapView.cpp @@ -1,5 +1,5 @@ /* - Copyright (c) 2014, Matthias Schiffer + Copyright (c) 2014-2015, Matthias Schiffer All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/src/view/MapView.hpp b/src/view/MapView.hpp index c5867cc..fdd30aa 100644 --- a/src/view/MapView.hpp +++ b/src/view/MapView.hpp @@ -1,5 +1,5 @@ /* - Copyright (c) 2014, Matthias Schiffer + Copyright (c) 2014-2015, Matthias Schiffer All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/src/view/SpriteCache.cpp b/src/view/SpriteCache.cpp index bd67346..206aa1c 100644 --- a/src/view/SpriteCache.cpp +++ b/src/view/SpriteCache.cpp @@ -1,5 +1,5 @@ /* - Copyright (c) 2014, Matthias Schiffer + Copyright (c) 2014-2015, Matthias Schiffer All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/src/view/SpriteCache.hpp b/src/view/SpriteCache.hpp index ae01887..151fe19 100644 --- a/src/view/SpriteCache.hpp +++ b/src/view/SpriteCache.hpp @@ -1,5 +1,5 @@ /* - Copyright (c) 2014, Matthias Schiffer + Copyright (c) 2014-2015, Matthias Schiffer All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/src/view/Window.hpp b/src/view/Window.hpp index 8c4c7a7..9bfcbb4 100644 --- a/src/view/Window.hpp +++ b/src/view/Window.hpp @@ -1,5 +1,5 @@ /* - Copyright (c) 2014, Matthias Schiffer + Copyright (c) 2014-2015, Matthias Schiffer All rights reserved. Redistribution and use in source and binary forms, with or without From f41fc409959c5c050c3774c654e655589e744e22 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sat, 14 Feb 2015 23:44:20 +0100 Subject: [PATCH 07/10] Make calling ScriptContext::run nicer --- src/control/MapContext.cpp | 3 +-- src/control/ScriptContext.hpp | 30 +++++++++++++++++++++++++----- 2 files changed, 26 insertions(+), 7 deletions(-) diff --git a/src/control/MapContext.cpp b/src/control/MapContext.cpp index 8065b04..246ee96 100644 --- a/src/control/MapContext.cpp +++ b/src/control/MapContext.cpp @@ -87,8 +87,7 @@ void MapContext::interact(uint64_t time) { if (interactScript.first.empty()) return; - Model::ScriptNumber scriptTime(time); - scriptContext->run(interactScript.first, interactScript.second, nullptr, &scriptTime); + scriptContext->run(interactScript.first, interactScript.second, nullptr, time); } void MapContext::keyPressed(uint16_t key, uint64_t time) { diff --git a/src/control/ScriptContext.hpp b/src/control/ScriptContext.hpp index 9416d0e..13279ec 100644 --- a/src/control/ScriptContext.hpp +++ b/src/control/ScriptContext.hpp @@ -59,12 +59,32 @@ private: } template - size_t pushArgs(Model::ScriptValue *v, Args ...args) { - if (v) - v->push(L); - else - lua_pushnil(L); + size_t pushArgs(std::nullptr_t __attribute__((unused)) v, Args ...args) { + lua_pushnil(L); + return pushArgs(args...) + 1; + } + template + size_t pushArgs(const std::string &v, Args ...args) { + lua_pushstring(L, v.c_str()); + return pushArgs(args...) + 1; + } + + template + size_t pushArgs(T v, Args ...args) { + lua_pushnumber(L, v); + return pushArgs(args...) + 1; + } + + template + size_t pushArgs(bool v, Args ...args) { + lua_pushboolean(L, v); + return pushArgs(args...) + 1; + } + + template + size_t pushArgs(Model::ScriptValue &v, Args ...args) { + v.push(L); return pushArgs(args...) + 1; } From cc6a8f553e703ca305454f612256fb734861ad0f Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 15 Feb 2015 13:03:49 +0100 Subject: [PATCH 08/10] ScriptContext pushArgs cleanup --- src/control/ScriptContext.hpp | 50 +++++++++++++++++------------------ 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/src/control/ScriptContext.hpp b/src/control/ScriptContext.hpp index 13279ec..191be92 100644 --- a/src/control/ScriptContext.hpp +++ b/src/control/ScriptContext.hpp @@ -36,6 +36,7 @@ extern "C" { #include #include +#include #include @@ -54,37 +55,36 @@ private: void load(const std::string &script); + + void pushArg(std::nullptr_t __attribute__((unused)) v) { + lua_pushnil(L); + } + + void pushArg(const std::string &v) { + lua_pushstring(L, v.c_str()); + } + + template::value>::type> + void pushArg(T v) { + lua_pushnumber(L, v); + } + + void pushArg(bool v) { + lua_pushboolean(L, v); + } + + void pushArg(Model::ScriptValue &v) { + v.push(L); + } + + size_t pushArgs() { return 0; } - template - size_t pushArgs(std::nullptr_t __attribute__((unused)) v, Args ...args) { - lua_pushnil(L); - return pushArgs(args...) + 1; - } - - template - size_t pushArgs(const std::string &v, Args ...args) { - lua_pushstring(L, v.c_str()); - return pushArgs(args...) + 1; - } - template size_t pushArgs(T v, Args ...args) { - lua_pushnumber(L, v); - return pushArgs(args...) + 1; - } - - template - size_t pushArgs(bool v, Args ...args) { - lua_pushboolean(L, v); - return pushArgs(args...) + 1; - } - - template - size_t pushArgs(Model::ScriptValue &v, Args ...args) { - v.push(L); + pushArg(v); return pushArgs(args...) + 1; } From c5a98c282b86d97330352fe17a7b6998b38237e5 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Thu, 10 Dec 2015 00:02:59 +0100 Subject: [PATCH 09/10] SpriteCache: use correct pitch for sprite rotation --- src/view/SpriteCache.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/view/SpriteCache.cpp b/src/view/SpriteCache.cpp index 206aa1c..a7018f7 100644 --- a/src/view/SpriteCache.cpp +++ b/src/view/SpriteCache.cpp @@ -70,6 +70,8 @@ SpriteCache::sprite_value SpriteCache::load(const std::string &id, unsigned rota uint8_t *src = reinterpret_cast(base->pixels); uint8_t *dst = reinterpret_cast(surface->pixels); + int pitch = base->pitch; + int pitch2 = surface->pitch; for (int x = 0; x < w; x++) { for (int y = 0; y < h; y++) { @@ -89,7 +91,7 @@ SpriteCache::sprite_value SpriteCache::load(const std::string &id, unsigned rota y2 = x; } - std::memcpy(dst + d * (y2*w2 + x2), src + d * (y*w + x), d); + std::memcpy(dst + y2*pitch2 + d*x2, src + y*pitch + d*x, d); } } From 4135928a9f74bf431b6cbca4ad47f00fa47aea56 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Wed, 9 Dec 2015 23:52:21 +0100 Subject: [PATCH 10/10] Update to Lua 5.3 --- CMakeLists.txt | 2 +- src/control/ScriptContext.cpp | 8 +++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0cdd80d..25165ce 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,6 +5,6 @@ project(RPGEDIT CXX) find_package(PkgConfig REQUIRED) pkg_check_modules(SDL2 REQUIRED sdl2 SDL2_image) -find_package(Lua 5.2 EXACT REQUIRED) +find_package(Lua 5.3 EXACT REQUIRED) add_subdirectory(src) diff --git a/src/control/ScriptContext.cpp b/src/control/ScriptContext.cpp index b92c8e5..e92e275 100644 --- a/src/control/ScriptContext.cpp +++ b/src/control/ScriptContext.cpp @@ -34,15 +34,17 @@ namespace Control { void ScriptContext::setupEnv() { const std::pair libs[] = { {"_G", luaopen_base}, - {"bit32", luaopen_bit32}, {"math", luaopen_math}, {"string", luaopen_string}, {"table", luaopen_table}, + {"utf8", luaopen_utf8}, }; for (auto &lib : libs) { - luaL_requiref(L, lib.first, lib.second, 1); - lua_pop(L, 1); + lua_pushcfunction(L, lib.second); + lua_pushstring(L, lib.first); + lua_call(L, 1, 1); + lua_setglobal(L, lib.first); } for (const char *f : {"dofile", "loadfile", "require"}) {