diff options
-rw-r--r-- | Scripts/init.lua | 14 | ||||
-rw-r--r-- | src/components/EventListener.hpp | 60 | ||||
-rw-r--r-- | src/engine.cpp | 5 | ||||
-rw-r--r-- | src/player.cpp | 34 | ||||
-rw-r--r-- | src/player.hpp | 4 | ||||
-rw-r--r-- | src/script.cpp | 7 |
6 files changed, 115 insertions, 9 deletions
diff --git a/Scripts/init.lua b/Scripts/init.lua index 6d225f5..d1f108c 100644 --- a/Scripts/init.lua +++ b/Scripts/init.lua @@ -1,5 +1,19 @@ bird = { Player = 0, + EventListeners = { + MoveLeftPressed = function(self) + self.Velocity.x = self.Velocity.x - 100 + end, + MoveLeftReleased = function(self) + self.Velocity.x = self.Velocity.x + 100 + end, + MoveRightPressed = function(self) + self.Velocity.x = self.Velocity.x + 100 + end, + MoveRightReleased = function(self) + self.Velocity.x = self.Velocity.x - 100 + end + }, Position = { x = 150, y = 75 diff --git a/src/components/EventListener.hpp b/src/components/EventListener.hpp new file mode 100644 index 0000000..77a004e --- /dev/null +++ b/src/components/EventListener.hpp @@ -0,0 +1,60 @@ +/** + * @file EventListener.hpp + * Allows entities to receive events and handle them in Lua. + * + * Copyright (C) 2019 Clyne Sullivan + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef COMPONENT_EVENTLISTENER_HPP_ +#define COMPONENT_EVENTLISTENER_HPP_ + +#include "Component.hpp" + +struct EventListener : Component<EventListener> +{ +public: + sol::table listeners; + + EventListener(sol::table _listeners) : + listeners(_listeners) {} + + ~EventListener(void) {} + + void cleanup(void) { + listeners = sol::nil; + } + + EventListener FromLua([[maybe_unused]] sol::object ref) + { + return *this; + } + + void tryListener(const std::string& name, sol::table& self) + { + if (listeners[name] == sol::type::function) + listeners[name](self); + } + + void serialize([[maybe_unused]] cereal::JSONOutputArchive& ar) final {} + void serialize([[maybe_unused]] cereal::JSONInputArchive& ar) final {} + + std::string serializeName(void) const final { + return "EventListener"; + } +}; + +#endif // COMPONENT_EVENTLISTENER_HPP_ + diff --git a/src/engine.cpp b/src/engine.cpp index e959f21..fe9af3d 100644 --- a/src/engine.cpp +++ b/src/engine.cpp @@ -27,6 +27,7 @@ #include "script.hpp" #include "render.hpp" +#include "components/EventListener.hpp" #include "components/Script.hpp" #include "components/Position.hpp" #include "components/Velocity.hpp" @@ -41,7 +42,7 @@ int Engine::init(void) { systems.add<GameRunSystem>(); systems.add<InputSystem>(); - systems.add<PlayerSystem>(); + systems.add<PlayerSystem>(entities); systems.add<RenderSystem>(); systems.add<ScriptSystem>(); systems.configure(); @@ -102,6 +103,8 @@ void Engine::logicLoop(void) // Remove all Lua references from entities entities.each<Scripted>([](entityx::Entity, Scripted &f){ f.cleanup(); }); + entities.each<EventListener>([](entityx::Entity, EventListener &f){ + f.cleanup(); }); } void Engine::renderLoop(void) diff --git a/src/player.cpp b/src/player.cpp index 187d61a..5346a24 100644 --- a/src/player.cpp +++ b/src/player.cpp @@ -20,6 +20,8 @@ #include "player.hpp" +#include "components/EventListener.hpp" +#include "components/Script.hpp" #include "components/Velocity.hpp" void PlayerSystem::configure([[maybe_unused]] entityx::EntityManager& entities, @@ -52,11 +54,19 @@ void PlayerSystem::receive(const KeyDownEvent& kue) { if (player.valid()) { if (kue.sym == SDLK_a) { - if (auto vel = player.component<Velocity>(); vel) - vel->x -= GROUND_VELOCITY; + entities.each<EventListener>([&]([[maybe_unused]] entityx::Entity e, + EventListener& el) + { + el.tryListener("MoveLeftPressed", + e.component<Scripted>()->caller); + }); } else if (kue.sym == SDLK_d) { - if (auto vel = player.component<Velocity>(); vel) - vel->x += GROUND_VELOCITY; + entities.each<EventListener>([&]([[maybe_unused]] entityx::Entity e, + EventListener& el) + { + el.tryListener("MoveRightPressed", + e.component<Scripted>()->caller); + }); } } } @@ -65,11 +75,19 @@ void PlayerSystem::receive(const KeyUpEvent& kue) { if (player.valid()) { if (kue.sym == SDLK_a) { - if (auto vel = player.component<Velocity>(); vel) - vel->x += GROUND_VELOCITY; + entities.each<EventListener>([&]([[maybe_unused]] entityx::Entity e, + EventListener& el) + { + el.tryListener("MoveLeftReleased", + e.component<Scripted>()->caller); + }); } else if (kue.sym == SDLK_d) { - if (auto vel = player.component<Velocity>(); vel) - vel->x -= GROUND_VELOCITY; + entities.each<EventListener>([&]([[maybe_unused]] entityx::Entity e, + EventListener& el) + { + el.tryListener("MoveRightReleased", + e.component<Scripted>()->caller); + }); } } } diff --git a/src/player.hpp b/src/player.hpp index b1821c5..d9a9237 100644 --- a/src/player.hpp +++ b/src/player.hpp @@ -40,9 +40,13 @@ private: */ constexpr static double GROUND_VELOCITY = 100; + entityx::EntityManager& entities; entityx::Entity player; public: + PlayerSystem(entityx::EntityManager& _entities) : + entities(_entities) {} + /** * Prepares the system for running. */ diff --git a/src/script.cpp b/src/script.cpp index 351aae4..d8f23ec 100644 --- a/src/script.cpp +++ b/src/script.cpp @@ -78,6 +78,7 @@ void ScriptSystem::doFile(void) /******************** * SCRIPT PARSING * ********************/ +#include <components/EventListener.hpp> #include <components/Position.hpp> #include <components/Player.hpp> #include <components/Name.hpp> @@ -182,6 +183,12 @@ sol::table ScriptSystem::spawn(sol::object param) e.assign<Light>(Light().FromLua(tab["Light"])).get(); } + // Probably should be last + if (tab["EventListeners"] != nullptr) { + sol::table listeners = tab["EventListeners"]; + e.assign<EventListener>(listeners); + } + } else { // TODO better logging std::cerr << "Parameter to spawn() must be a table!" << std::endl; |