diff options
Diffstat (limited to 'src/control')
-rw-r--r-- | src/control/MapContext.cpp | 14 | ||||
-rw-r--r-- | src/control/MapContext.hpp | 4 | ||||
-rw-r--r-- | src/control/RPGEdit.cpp | 3 | ||||
-rw-r--r-- | src/control/RPGEdit.hpp | 2 | ||||
-rw-r--r-- | src/control/ScriptContext.cpp | 90 | ||||
-rw-r--r-- | src/control/ScriptContext.hpp | 63 |
6 files changed, 128 insertions, 48 deletions
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<View::Window> &window, const Model::Map &map0) - : eventBus(eventBus0), inputHandler(inputHandler0), map(map0) { +MapContext::MapContext(EventBus *eventBus0, InputHandler *inputHandler0, ScriptContext *scriptContext0, const std::shared_ptr<View::Window> &window, const Model::Map &map0) + : eventBus(eventBus0), inputHandler(inputHandler0), scriptContext(scriptContext0), map(map0) { view = std::unique_ptr<View::MapView>(new View::MapView(window, map.getTileset())); + Model::Entity *square = map.addEntity("square", Model::Position<int>{10, 10}); + square->setScriptInteract("interact", "interact"); + playerEntity = map.addEntity("square", Model::Position<int>{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<std::string, std::string> &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::MapView> view; @@ -59,7 +61,7 @@ private: } public: - MapContext(EventBus *eventBus0, InputHandler *inputHandler0, const std::shared_ptr<View::Window> &window, const Model::Map &map0); + MapContext(EventBus *eventBus0, InputHandler *inputHandler0, ScriptContext *scriptContext0, const std::shared_ptr<View::Window> &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<View::Window>(); - ctx = std::make_shared<MapContext>(&eventBus, &inputHandler, window, *map); + ctx = std::make_shared<MapContext>(&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<View::Window> window; std::shared_ptr<MapContext> 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 <mschiffer@universe-factory.net> + 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<const char *, lua_CFunction> 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 <memory> #include <string> +#include <unordered_set> namespace RPGEdit { @@ -46,43 +47,25 @@ class ScriptContext { private: lua_State *L; - void setupEnv() { - const std::pair<const char *, lua_CFunction> 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); - } - } + std::unordered_set<std::string> loadedScripts; - void cleanupEnv() { - lua_pushglobaltable(L); + void setupEnv(); + void cleanupEnv(); - lua_pushnil(L); - lua_setmetatable(L, -2); + void load(const std::string &script); - lua_pushnil(L); - while (lua_next(L, -2) != 0) { - lua_pop(L, 1); + size_t pushArgs() { + return 0; + } - lua_pushvalue(L, -1); + template<typename... Args> + 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<typename... Args> + 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(); } }; |