/** * @file script.cpp * Manages all Lua scripts. * * Copyright (C) 2019 Belle-Isle, Andrew <drumsetmonkey@gmail.com> * * 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/>. */ #include <script.hpp> /********************* * SYSTEM SPECIFIC * *********************/ void ScriptSystem::configure([[maybe_unused]]entityx::EntityManager& entities, [[maybe_unused]]entityx::EventManager& events) { this->manager = &entities; this->events = &events; events.subscribe<EntitySpawnEvent>(*this); init(); } void ScriptSystem::update([[maybe_unused]] entityx::EntityManager& entites, [[maybe_unused]] entityx::EventManager& events, [[maybe_unused]] entityx::TimeDelta dt) { } void ScriptSystem::receive(const EntitySpawnEvent &toSpawn) { (void)toSpawn; } /********************* * CLASS FUNCTIONS * *********************/ int ScriptSystem::init(void) { lua.open_libraries(sol::lib::base); scriptExport(); doFile(); return 0; } void ScriptSystem::doFile(void) { auto result = lua.script_file("Scripts/init.lua"); if (!result.valid()) { std::cout << "Lua error: " << std::endl; } } /******************** * SCRIPT PARSING * ********************/ #include <components/Position.hpp> #include <components/Name.hpp> #include <components/Render.hpp> #include <components/Script.hpp> #include <components/Velocity.hpp> void ScriptSystem::scriptExport() { std::function<sol::table(sol::table)> func = [this](sol::table t){ return spawn(t);}; lua.new_usertype<Position>("Position", sol::constructors<Position(float x, float y), Position()>(), "x", &Position::x, "y", &Position::y); lua.new_usertype<Name>("Name", sol::constructors<Name(std::string), Name()>(), "value", &Name::name); lua.new_usertype<Render>("Render", sol::constructors<Render(std::string), Render()>(), "visible", &Render::visible, "texture", &Render::texture); auto gamespace = lua["game"].get_or_create<sol::table>(); gamespace.set_function("spawn", func); } sol::table ScriptSystem::spawn(sol::object param) { sol::table* toRet; // "Entitiy" table to be returned if (param.get_type() == sol::type::table) { sol::table tab = param; // Cast the generic parameter to a table entityx::Entity e = manager->create(); // Create a new entity auto d = e.assign<Scripted>().get(); // Since this entity was created // via Lua, assign the Scripted // component. d->caller = lua.create_table(); // Create our Entity "table" toRet = &(d->caller); // set our return table to the Entity "table" *toRet = tab; /* Copy table to our new entity to preserve functions * this reduces the amount of work done in this function * as well. We are allowed to do this because lua allows * for the reallocation of types. */ /* * Create the component dependancies (i.e.: position) first */ if (tab["Position"] != nullptr) { (*toRet)["Position"] = e.assign<Position>(Position().FromLua(tab["Position"])).get(); } if (tab["Name"] != nullptr) { (*toRet)["Name"] = e.assign<Name>(Name().FromLua(tab["Name"])).get(); } if (tab["Render"] != nullptr) { if (!e.has_component<Position>()) // Position must exist for render (*toRet)["Position"] = e.assign<Position>().get(); (*toRet)["Render"] = e.assign<Render>(Render().FromLua(tab["Render"])).get(); } if (tab["Velocity"] != nullptr) { if (!e.has_component<Position>()) // Position must exist for vel. (*toRet)["Position"] = e.assign<Position>().get(); (*toRet)["Velocity"] = e.assign<Velocity>(Velocity().FromLua(tab["Velocity"])).get(); } } else { // TODO better logging std::cerr << "Parameter to spawn() must be a table!" << std::endl; } // If the Entity has an Init function defined, call it if ((*toRet)["Init"].get_type() == sol::type::function) (*toRet)["Init"](*toRet); return *toRet; }