aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndy Belle-Isle <drumsetmonkey@gmail.com>2019-08-29 01:39:40 -0400
committerAndy Belle-Isle <drumsetmonkey@gmail.com>2019-08-29 01:39:40 -0400
commite9758416b18b27a65337c28d9641afc0ee89b34b (patch)
tree2e4d3037aa5dbc71206c91a36ca7d00e108036ba
parent41addc2d6b600e9cade63884de1c13dba662dc31 (diff)
Created (very messy) script system
-rw-r--r--Scripts/init.lua14
-rw-r--r--src/Script/entityx/EntityLua.hpp242
-rw-r--r--src/Script/entityx/LuaTypes.hpp96
-rw-r--r--src/Script/entityx/entity_lua.cpp183
-rw-r--r--src/Script/entityx/entity_lua.hpp13
-rw-r--r--src/components/Component.hpp33
-rw-r--r--src/components/Position.hpp47
-rw-r--r--src/main.cpp118
-rw-r--r--src/script.hpp154
9 files changed, 316 insertions, 584 deletions
diff --git a/Scripts/init.lua b/Scripts/init.lua
index 20ea044..5b0f915 100644
--- a/Scripts/init.lua
+++ b/Scripts/init.lua
@@ -24,5 +24,19 @@ bird = {
end
}
+dog = {
+ Position = {
+ x = 6.5,
+ y = 1.3
+ },
+ init = function(self)
+ print(self.Position.x .. "," .. self.Position.y)
+ end
+}
+
birdSpawn = game.spawn(bird);
birdSpawn:init()
+
+dogSpawn = game.spawn(dog);
+dogSpawn:init()
+dogSpawn.Position.x = 37.5
diff --git a/src/Script/entityx/EntityLua.hpp b/src/Script/entityx/EntityLua.hpp
deleted file mode 100644
index 780f051..0000000
--- a/src/Script/entityx/EntityLua.hpp
+++ /dev/null
@@ -1,242 +0,0 @@
-#ifndef ENTITYLUA_HPP
-#define ENTITYLUA_HPP
-
-// Check is_trivially_destructible so we don't need __gc for userdata.
-static_assert(std::is_trivially_destructible<entityx::Entity::Id>::value, "Entity::Id is not trivially destructible");
-// Check is_copy_constructible so that we can copy data onto memory for userdata created by lua.
-static_assert(std::is_copy_constructible<entityx::Entity::Id>::value, "Entity::Id is not copy constructible");
-
-namespace entityx
-{
- namespace lua
- {
- typedef std::shared_ptr<entityx::EntityManager> EntityManagerSharedPtr;
-
- // This component is internally assigned to all entities created from lua.
- // It is used to store the ref of the lua table
- struct LuaComponent : entityx::Component<LuaComponent>
- {
- // ref of the lua object in LUA_REGISTRYINDEX
- int ref;
- LuaComponent(int ref = LUA_REFNIL) : ref(ref) {}
- };
-
- // This function should be called right after luaL_openlibs, to create global entityx table
- void setup_entityx_api(lua_State* L);
-
- // This function add a new entity manager to lua global "entityx.xxx" where xxx is the name provided
- void new_entity_manager(lua_State* L, const EntityManagerSharedPtr& manager, const char* name);
-
- // This function is used to push an entity manager to lua.
- // It only pushes the userdata onto the stack, so use lua api such as lua_setglobal,
- // lua_setfield, or lua_settable to really save it to lua.
- void push_entity_manager(lua_State* L, const EntityManagerSharedPtr& manager);
-
- typedef std::map<std::string, std::function<void(lua_State*)>> ComponentList;
- extern ComponentList components;
-
- template <typename C>
- class MemberRegister
- {
- lua_State* L;
- public:
- MemberRegister(lua_State* L) : L(L) {}
-
- template <typename T>
- void add(const char* name, T C::*ptr)
- {
- // Now the ComponentHandler should be at #-2 of stack (-1 is the metatable), this will be used as up-values
- lua_pushvalue(L, -2);
- // Also remember the offset
- int offset = typename ComponentHelper<C>::offset(ptr);
- lua_pushinteger(L, offset);
- lua_pushcclosure(L, [](lua_State* L){
- // This function is used as both getter and setter:
- // value = entity.comp.x()
- // entity.comp.x(value)
- // Note that self is not needed (that is, use comp.x() instead of comp:x())
- typename ComponentHelper<C>::ptr* pptr = static_cast<typename ComponentHelper<C>::ptr*>(lua_touserdata(L, lua_upvalueindex(1)));
- int offset = lua_tointeger(L, lua_upvalueindex(2));
-
- T& ref = typename ComponentHelper<C>::get(**pptr, offset);
- if (lua_gettop(L) == 0 || lua_isnil(L, 1))
- {
- // Getter mode, push value of at pptr
- CToLua(L, ref);
- }
- else
- {
- // Setter mode, set value to pptr
- LuaToC(L, ref);
- }
- return 1;
- }, 2);
- lua_setfield(L, -2, name);
- }
- };
-
- template <typename C>
- struct ComponentHelper
- {
- public:
- // Use this ptr to get the ComponentHandle type, to support both 0.x and 1.x of entityx.
- typedef decltype(entityx::Entity().assign<C>()) ptr;
-
- template <typename Member>
- static ptrdiff_t offset(Member ptr)
- {
- C c;
- return static_cast<char*>(static_cast<void*>(&(c.*ptr))) - static_cast<char*>(static_cast<void*>(&c));
- }
-
- template <typename T>
- static T& get(C& c, ptrdiff_t offset)
- {
- return *static_cast<T*>(static_cast<void*>(
- static_cast<char*>(static_cast<void*>(&c)) + offset
- ));
- }
-
- typedef std::function<void(MemberRegister<C>&)> memreg_func;
- };
-
- namespace lua_params
- {
- // gens<n>::type = seq<0, 1, ..., n-1>
- template<int ...>
- struct seq {};
-
- template<int N, int ...S>
- struct gens : gens<N - 1, N - 1, S...> { };
-
- template<int ...S>
- struct gens<0, S...> {
- typedef seq<S...> type;
- };
-
- template <typename T>
- T get_param_from_lua(lua_State* L, int n)
- {
- T ret;
- lua_pushvalue(L, n);
- LuaToC<T>(L, ret);
- return ret;
- }
-
- template <typename Func, typename Ret, typename... Args, int... N>
- Ret call_func(lua_State* L, Func func, seq<N...>)
- {
- // This function is called with a table on top of the stack,
- // first we call table.unpack to get the elements in the table
- lua_getglobal(L, "table");
- lua_getfield(L, -1, "unpack");
- lua_remove(L, -2); // now function is pushed
- lua_pushvalue(L, -2); // push the table
- lua_call(L, 1, sizeof...(N)); // we only receive sizeof...(N) results
-
- // Then we call func with get_param_from_lua
- int start_from = lua_gettop(L) - sizeof...(N)+1;
- // Note that N... itself starts from 0
- return func(std::forward<Args>(get_param_from_lua<Args>(L, N + start_from))...);
- }
-
- // std::function version
- template <typename Ret, typename... Args>
- Ret call_func(lua_State* L, const std::function<Ret(Args...)>& func)
- {
- return call_func<std::function<Ret(Args...)>, Ret, Args...>(L, func, gens<sizeof...(Args)>::type());
- }
- }
-
- template <typename C, typename... Args>
- std::function<C(lua_State*)> wrap_ctor(const std::function<C(Args...)>& func)
- {
- return [func](lua_State* L) {
- return lua_params::call_func<C, Args...>(L, func);
- };
- }
-
- template <typename C>
- std::function<C(lua_State*)> wrap_ctor_no_args(C(*func)())
- {
- return [func](lua_State* L) {
- return lua_params::call_func<C>(L, func);
- };
- }
-
- template <typename C>
- std::function<C(lua_State*)> use_default_ctor()
- {
- static_assert(std::is_constructible<C>::value, "Not able to use default ctor here");
- return [](lua_State* L) {
- return C();
- };
- }
-
- template <typename C, typename Str, typename Ctor>
- void export_component(Str name, Ctor ctor, const std::function<void(MemberRegister<C>&)>& memreg)
- {
- static_assert(std::is_constructible<std::string, Str>::value, "Bad type of name");
- static_assert(std::is_same<Ctor, std::function<C(lua_State*)>>::value, "Bad type of ctor");
-
- // Create memreg as a std::function
- //ComponentHelper<C>::memreg_func memreg_func_save = memreg;
-
- std::function<void(lua_State*)> create_component = [ctor, memreg](lua_State* L) {
- // This function is called with (name, entity_manager_weak_pointer, id, params)
- EntityManagerSharedPtr* m = static_cast<EntityManagerSharedPtr*>(lua_touserdata(L, 2));
- entityx::Entity::Id* id = static_cast<entityx::Entity::Id*>(lua_touserdata(L, 3));
- entityx::Entity entity = (*m)->get(*id);
-
- typedef typename ComponentHelper<C>::ptr CompPtr;
- // Create the c++ component
- CompPtr component = entity.assign<C>(std::move(ctor(L)));
-
- // Create the component as a lightuserdata (although no data is stored in it)
- lua_pushlightuserdata(L, 0);
-
- // Push CompPtr which will be used in MemberRegister (will be removed after pushing members)
- lua_newuserdata(L, sizeof(CompPtr));
- new (lua_touserdata(L, -1)) CompPtr(component);
-
- // If needed, create metatable for it (we only need __gc)
- if (!std::is_trivially_destructible<CompPtr>::value)
- {
- lua_newtable(L);
- lua_pushcfunction(L, [](lua_State* L){
- CompPtr* component = static_cast<CompPtr*>(lua_touserdata(L, -1));
- component->~CompPtr();
- return 0;
- });
- lua_setfield(L, -2, "__gc");
- lua_setmetatable(L, -2);
- }
-
- // Stack: lightuserdata(0) | CompPtr
-
- // Create metatable for the lightuserdata
- lua_newtable(L);
- lua_pushvalue(L, -1);
- lua_setfield(L, -2, "__index");
-
- // Stack: lightuserdata(0) | CompPtr | metatable
-
- // Now we're ready to push members
- MemberRegister<C> reg(L);
- memreg(reg);
-
- // Stack: lightuserdata(0) | CompPtr | metatable
-
- // Remove the CompPtr
- lua_remove(L, -2);
- // Set metatable for the lightuserdata
- lua_setmetatable(L, -2);
-
- // Leave the result on top of the stack
- };
- components[name] = std::move(create_component);
- }
- }
-}
-
-#endif//ENTITYLUA_HPP
diff --git a/src/Script/entityx/LuaTypes.hpp b/src/Script/entityx/LuaTypes.hpp
deleted file mode 100644
index 66d1f47..0000000
--- a/src/Script/entityx/LuaTypes.hpp
+++ /dev/null
@@ -1,96 +0,0 @@
-#ifndef LUATYPES_HPP
-#define LUATYPES_HPP
-
-#include "lua.hpp"
-
-namespace entityx
-{
- namespace lua
- {
- /*************
- * GENERIC *
- *************/
- template<typename T>
- inline void LuaToC(lua_State* L, T& ref);
-
- template<typename T>
- inline void CToLua(lua_State* L, T& ref);
-
- /************
- * DOUBLE *
- ************/
- template<>
- inline void LuaToC<double>(lua_State* L, double& ref)
- {
- ref = lua_tonumber(L, -1);
- }
-
- template<>
- inline void CToLua(lua_State* L, double& ref)
- {
- lua_pushnumber(L, ref);
- }
-
- /***********
- * FLOAT *
- ***********/
- template<>
- inline void LuaToC<float>(lua_State* L, float& ref)
- {
- ref = static_cast<float>(lua_tonumber(L, -1));
- }
-
- template<>
- inline void CToLua<float>(lua_State* L, float& ref)
- {
- lua_pushnumber(L, ref);
- }
-
- /*************
- * INTEGER *
- *************/
- template<>
- inline void LuaToC<int>(lua_State* L, int& ref)
- {
- ref = lua_tointeger(L, -1);
- }
-
- template<>
- inline void CToLua<int>(lua_State* L, int& ref)
- {
- lua_pushnumber(L, ref);
- }
-
- /*************
- * BOOLEAN *
- *************/
- template<>
- inline void LuaToC<bool>(lua_State* L, bool& ref)
- {
- ref = lua_toboolean(L, -1);
- }
-
- template<>
- inline void CToLua<bool>(lua_State* L, bool& ref)
- {
- lua_pushboolean(L, ref);
- }
-
- /************
- * STRING *
- ************/
- template<>
- inline void LuaToC<std::string>(lua_State* L, std::string& ref)
- {
- ref = lua_tostring(L, -1);
- }
-
- template<>
- inline void CToLua<std::string>(lua_State* L, std::string& ref)
- {
- lua_pushstring(L, ref.c_str());
- }
- }
-}
-
-#endif//LUATYPES_HPP
diff --git a/src/Script/entityx/entity_lua.cpp b/src/Script/entityx/entity_lua.cpp
deleted file mode 100644
index b23628b..0000000
--- a/src/Script/entityx/entity_lua.cpp
+++ /dev/null
@@ -1,183 +0,0 @@
-//#include "entityx_lua.h"
-#include <Script/entityx/entity_lua.hpp>
-#include <stdio.h>
-#include <string.h>
-
-using namespace entityx::lua;
-ComponentList entityx::lua::components;
-
-namespace {
- int ref_EntityManagerSharedPtr = LUA_REFNIL;
- int ref_EntityId = LUA_REFNIL;
- const char* TypeName_EntityManagerSharedPtr = "EntityManagerSharedPtr";
- const char* TypeName_EntityId = "EntityId";
- const char* setup_lua_create_entity_factory =
- "function entityx.create_entity_factory(entity_manager_pointer)\n"
- " local c = {}\n"
- " c.__index = c\n"
- " function c:new()\n"
- " local ret = {}\n"
- " ret.__index = ret\n"
- " function ret:init()\n"
- " -- Empty\n"
- " end\n"
- " function ret:instance(param)\n"
- " -- Make id const\n"
- " local r = {}\n"
- " local id = entityx.create_new_entity(entity_manager_pointer, r)\n"
- " r.id = id\n"
- " function r:component(name, params)\n"
- " return entityx.create_new_component(name, entity_manager_pointer, id, params)\n"
- " end\n"
- " setmetatable(r, self)\n"
- " r:init(param)\n"
- " return r\n"
- " end\n"
- " return ret\n"
- " end\n"
- " function c:get(id)\n"
- " return entityx.get_lua_object(entity_manager_pointer, id)\n"
- " end\n"
- " return c\n"
- "end\n";
-}
-
-//TODO replace:entityx_lua:: settable->setfield/rawset
-void entityx::lua::setup_entityx_api(lua_State* L)
-{
- // Create metatables for userdata
- // metatable for shared_ptr of EntityManager
- lua_newtable(L);
- lua_pushstring(L, TypeName_EntityManagerSharedPtr);
- lua_setfield(L, -2, "type");
- lua_pushcfunction(L, [](lua_State* L){
- EntityManagerSharedPtr* ptr = static_cast<EntityManagerSharedPtr*>(lua_touserdata(L, 1));
- (*ptr).~EntityManagerSharedPtr();
- return 0;
- });
- lua_setfield(L, -2, "__gc");
- ref_EntityManagerSharedPtr = luaL_ref(L, LUA_REGISTRYINDEX);
-
- // metatable for Entity::Id
- lua_newtable(L);
- lua_pushstring(L, TypeName_EntityId);
- lua_setfield(L, -2, "type");
- // We don't need __gc for Entity::Id (with static_assert it is_trivially_destructible)
- ref_EntityId = luaL_ref(L, LUA_REGISTRYINDEX);
-
- // Create global entityx table
- lua_newtable(L);
-
- // create_new_entity
- lua_pushcfunction(L, [](lua_State* L){
- // First check the type of the parameter
- lua_getmetatable(L, 1);
- lua_pushstring(L, "type");
- lua_rawget(L, -2);
- if (!lua_isuserdata(L, 1) || strcmp(lua_tostring(L, -1), TypeName_EntityManagerSharedPtr) != 0 || !lua_istable(L, 2))
- {
- lua_pushstring(L, "create_new_entity should be called with pointer of EntityManager and a table.");
- return lua_error(L);
- }
- lua_pop(L, 2);
-
- lua_pushvalue(L, 2);
- int ref = luaL_ref(L, LUA_REGISTRYINDEX);
-
- // Create an new entity
- EntityManagerSharedPtr* ptr = static_cast<EntityManagerSharedPtr*>(lua_touserdata(L, 1));
- entityx::Entity entity = (*ptr)->create();
-
- // Save the lua object (ref) in the entity
- entity.assign<LuaComponent>(ref);
-
- // Return the Id of the entity
- lua_newuserdata(L, sizeof(entityx::Entity::Id));
- lua_rawgeti(L, LUA_REGISTRYINDEX, ref_EntityId);
- lua_setmetatable(L, -2);
- new (lua_touserdata(L, -1)) entityx::Entity::Id(entity.id());
-
- return 1;
- });
- lua_setfield(L, -2, "create_new_entity");
-
- // get_lua_object
- lua_pushcfunction(L, [](lua_State* L){
- // First check the type of the parameters
- lua_getmetatable(L, 1);
- lua_pushstring(L, "type");
- lua_rawget(L, -2);
- if (!lua_isuserdata(L, 1) || strcmp(lua_tostring(L, -1), TypeName_EntityManagerSharedPtr) != 0)
- {
- lua_pushstring(L, "get_lua_object should be called with pointer of EntityManager and an EntityId.");
- return lua_error(L);
- }
- lua_pop(L, 2);
-
- lua_getmetatable(L, 2);
- lua_pushstring(L, "type");
- lua_rawget(L, -2);
- if (!lua_isuserdata(L, 2) || strcmp(lua_tostring(L, -1), TypeName_EntityId) != 0)
- {
- lua_pushstring(L, "get_lua_object should be called with pointer of EntityManager and an EntityId.");
- return lua_error(L);
- }
- lua_pop(L, 2);
-
- // Get the object
- EntityManagerSharedPtr* ptr = static_cast<EntityManagerSharedPtr*>(lua_touserdata(L, 1));
- entityx::Entity::Id* id = static_cast<entityx::Entity::Id*>(lua_touserdata(L, 2));
-
- entityx::Entity entity = (*ptr)->get(*id);
- int ref = entity.component<LuaComponent>()->ref;
-
- lua_rawgeti(L, LUA_REGISTRYINDEX, ref);
- return 1;
- });
- lua_setfield(L, -2, "get_lua_object");
-
- // create_new_component
- lua_pushcfunction(L, [](lua_State* L){
- ComponentList::iterator i;
- //return 0;
- if ((i = components.find(std::string(lua_tostring(L, 1)))) != components.end())
- {
- i->second(L);
- }
- else
- {
- lua_pushstring(L, "Component not found.");
- return lua_error(L);
- }
- return 1;
- });
- lua_setfield(L, -2, "create_new_component");
-
- lua_setglobal(L, "entityx");
-
- luaL_loadstring(L, setup_lua_create_entity_factory);
- lua_call(L, 0, 0);
-}
-
-void entityx::lua::push_entity_manager(lua_State* L, const EntityManagerSharedPtr& manager)
-{
- lua_newuserdata(L, sizeof(EntityManagerSharedPtr));
- lua_rawgeti(L, LUA_REGISTRYINDEX, ref_EntityManagerSharedPtr);
- lua_setmetatable(L, -2);
-
- new (lua_touserdata(L, -1)) EntityManagerSharedPtr(manager);
-}
-
-void entityx::lua::new_entity_manager(lua_State* L, const EntityManagerSharedPtr& manager, const char* name)
-{
- lua_getglobal(L, "entityx");
- lua_getfield(L, -1, "create_entity_factory");
- lua_remove(L, -2); // _G["entityx"]
- push_entity_manager(L, manager);
- lua_pcall(L, 1, 1, 1);
-
- lua_getglobal(L, "entityx");
- lua_pushvalue(L, -2);
- lua_setfield(L, -2, name);
- lua_pop(L, 2); // original return value & entityx
-}
diff --git a/src/Script/entityx/entity_lua.hpp b/src/Script/entityx/entity_lua.hpp
deleted file mode 100644
index bcad91c..0000000
--- a/src/Script/entityx/entity_lua.hpp
+++ /dev/null
@@ -1,13 +0,0 @@
-#ifndef ENTITY_LUA_HPP
-#define ENTITY_LUA_HPP
-
-#include <map>
-#include <type_traits>
-
-#include <lua.hpp>
-#include <entityx/entityx.h>
-
-#include <Script/entityx/LuaTypes.hpp>
-#include <Script/entityx/EntityLua.hpp>
-
-#endif//ENTITY_LUA_HPP
diff --git a/src/components/Component.hpp b/src/components/Component.hpp
new file mode 100644
index 0000000..84e860c
--- /dev/null
+++ b/src/components/Component.hpp
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2019 Belle-Isle, Andrew <drumsetmonkey@gmail.com>
+ * Author: 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/>.
+ */
+
+#ifndef COMPONENT_HPP_
+#define COMPONENT_HPP_
+
+#include "LuaBridge/LuaBridge.h"
+
+template <typename T>
+class Component
+{
+ public:
+ Component(){};
+
+ virtual T FromLua(luabridge::LuaRef) = 0;
+};
+
+#endif//COMPONENT_HPP_
diff --git a/src/components/Position.hpp b/src/components/Position.hpp
new file mode 100644
index 0000000..aaa99f9
--- /dev/null
+++ b/src/components/Position.hpp
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2019 Belle-Isle, Andrew <drumsetmonkey@gmail.com>
+ * Author: 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/>.
+ */
+
+#ifndef POSITION_HPP_
+#define POSITION_HPP_
+
+#include "components/Component.hpp"
+
+struct Position : Component<Position>, entityx::Component<Position>
+{
+
+ public:
+ float x,y;
+ Position(float _x, float _y): x(_x), y(_y) {}
+ Position(void){x = y = 0.0;}
+
+ Position FromLua(luabridge::LuaRef ref)
+ {
+ if (ref.isTable()){
+ if (!ref["x"].isNil())
+ this->x = ref["x"];
+ if (!ref["y"].isNil())
+ this->y = ref["y"];
+ } else {
+ throw std::string("Position table not formatted properly");
+ }
+
+ return *this;
+ }
+};
+
+#endif//POSITION_HPP_
diff --git a/src/main.cpp b/src/main.cpp
index 57a4efb..23cfe2d 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -20,7 +20,6 @@
#include <lua.hpp>
#include <entityx/entityx.h>
-#include <Script/entityx/entity_lua.hpp>
#include <LuaBridge/LuaBridge.h>
#include <SDL2/SDL.h>
@@ -31,6 +30,9 @@
#include <memory>
#include <thread>
+#include <components/Position.hpp>
+#include <script.hpp>
+
class Window {
private:
constexpr static const char *title = "gamedev2";
@@ -140,16 +142,15 @@ void logicLoop(void)
}
}
-struct Position : entityx::Component<Position>
-{
- Position(float _x, float _y): x(_x), y(_y) {}
- Position(void){x = y = 0.0;}
-
- float x,y;
-};
+//struct Position : entityx::Component<Position>
+//{
+// Position(float _x, float _y): x(_x), y(_y) {}
+// Position(void){x = y = 0.0;}
+//
+// float x,y;
+//};
using namespace entityx;
-using namespace entityx::lua;
namespace lb = luabridge;
EventManager events;
@@ -157,58 +158,75 @@ EntityManager entities(events);
lua_State* L;
+//lb::LuaRef spawn(lb::LuaRef ref)
+//{
+// lb::LuaRef entity(L);
+// entity = lb::newTable(L);
+//
+// if (ref.isTable()) {
+//
+// Entity e = entities.create();
+//
+// for (auto &&comp : lb::pairs(ref)) {
+// if (comp.first.cast<std::string>() == "Position") {
+// entity["Position"] =
+// e.assign<Position>(Position().FromLua(comp.second)).get();
+// } else if (comp.first.cast<std::string>() == "init") {
+// entity["init"] = comp.second;
+// }
+// }
+// } else {
+// std::cerr << "Parameter to spawn() must be a table!" << std::endl;
+// }
+//
+// return entity;
+//}
+//
+
+ScriptSystem sc;
+
lb::LuaRef spawn(lb::LuaRef ref)
{
- lb::LuaRef entity(L);
- entity = lb::newTable(L);
-
- if (ref.isTable()) {
-
- Entity e = entities.create();
-
- for (auto &&comp : lb::pairs(ref)) {
- if (comp.first.cast<std::string>() == "Position") {
- float x = comp.second["x"];
- float y = comp.second["y"];
- entity["Position"] = e.assign<Position>(x, y).get();
- } else if (comp.first.cast<std::string>() == "init") {
- entity["init"] = comp.second;
- }
- }
- } else {
- std::cerr << "Parameter to spawn() must be a table!" << std::endl;
- }
-
- return entity;
+ return sc.spawn(ref);
}
void LuaTest(void)
{
-
- L = luaL_newstate();
- luaL_openlibs(L);
-
- lb::getGlobalNamespace(L).
- beginNamespace("comp")
- .beginClass<Position>("Position")
- .addConstructor<void(*)(float, float)>()
- .addProperty("x", &Position::x)
- .addProperty("y", &Position::y)
- .endClass()
- .endNamespace();
-
- lb::getGlobalNamespace(L)
+
+ sc.configure(entities, events);
+
+ // Functions export
+ lb::getGlobalNamespace(sc.getState())
.beginNamespace("game")
.addFunction("spawn", spawn)
.endNamespace();
- if (luaL_dofile(L, "Scripts/init.lua"))
- {
- std::cout << "Lua error: " << lua_tostring(L, -1) << std::endl;
- }
+ sc.doFile();
+
+
+ //L = luaL_newstate();
+ //luaL_openlibs(L);
+
+ //lb::getGlobalNamespace(L).
+ // beginNamespace("comp")
+ // .beginClass<Position>("Position")
+ // .addConstructor<void(*)(float, float)>()
+ // .addProperty("x", &Position::x)
+ // .addProperty("y", &Position::y)
+ // .endClass()
+ // .endNamespace();
+
+ //lb::getGlobalNamespace(L)
+ // .beginNamespace("game")
+ // .addFunction("spawn", spawn)
+ // .endNamespace();
+
+ //if (luaL_dofile(L, "Scripts/init.lua")) {
+ // std::cout << "Lua error: " << lua_tostring(L, -1) << std::endl;
+ //}
- entities.each<Position>([&](Entity e, Position& p){ (void)e;std::cout << p.x << std::endl;});
+ //entities.each<Position>([&](Entity, Position& p){std::cout << p.x << "," << p.y << std::endl;});
- lua_close(L);
+ //lua_close(L);
}
diff --git a/src/script.hpp b/src/script.hpp
new file mode 100644
index 0000000..1dc2df2
--- /dev/null
+++ b/src/script.hpp
@@ -0,0 +1,154 @@
+/*
+ * Copyright (C) 2019 Belle-Isle, Andrew <drumsetmonkey@gmail.com>
+ * Author: 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/>.
+ */
+
+#ifndef SCRIPT_HPP_
+#define SCRIPT_HPP_
+
+#include <entityx/entityx.h>
+#include <lua.hpp>
+#include <LuaBridge/LuaBridge.h>
+
+/****************
+* COMPONENTS *
+****************/
+#include <components/Position.hpp>
+
+namespace lb = luabridge;
+
+struct EntitySpawnEvent {
+ EntitySpawnEvent (const lb::LuaRef ref)
+ : ref(ref){}
+
+ lb::LuaRef ref;
+};
+
+/**
+ * @class ScriptSystem
+ * Handles all the game's scripting requests
+ */
+class ScriptSystem : public entityx::System<ScriptSystem>
+ , public entityx::Receiver<ScriptSystem>
+{
+ private:
+ /**
+ * The script systems internal lua state that handles all
+ * interactions between C and Lua
+ */
+ std::unique_ptr<lua_State, void(*)(lua_State *)> state;
+ entityx::EventManager events;
+ entityx::EntityManager manager;
+
+ public:
+ ScriptSystem(void)
+ : state(luaL_newstate(), lua_close),
+ manager(events){}
+
+ ~ScriptSystem(void)
+ {
+
+ }
+
+ lua_State* getState()
+ {
+ return state.get();
+ }
+
+ int init(void)
+ {
+ luaL_openlibs(state.get());
+ return 0;
+ }
+
+ void configure([[maybe_unused]]entityx::EntityManager& entities,
+ [[maybe_unused]]entityx::EventManager& events) final
+ {
+ //manager = std::make_shared<entityx::EntityManager>(std::move(entities));
+
+ events.subscribe<EntitySpawnEvent>(*this);
+
+ init();
+ scriptExport();
+ }
+
+ void update([[maybe_unused]] entityx::EntityManager& entites,
+ [[maybe_unused]] entityx::EventManager& events,
+ [[maybe_unused]] entityx::TimeDelta dt) final
+ {
+
+ }
+
+ void doFile(void)
+ {
+ if (luaL_dofile(state.get(), "Scripts/init.lua")) {
+ std::cout << "Lua error: " << lua_tostring(state.get(), -1) << std::endl;
+ }
+
+ manager.each<Position>([&](entityx::Entity, Position& p){std::cout << p.x << "," << p.y << std::endl;});
+
+ }
+
+ lb::LuaRef spawn(lb::LuaRef ref)
+ {
+ lb::LuaRef entity(state.get());
+ entity = lb::newTable(state.get());
+
+ if (ref.isTable()) {
+
+ entityx::Entity e = manager.create();
+
+ for (auto &&comp : lb::pairs(ref)) {
+ if (comp.first.cast<std::string>() == "Position") {
+ entity["Position"] =
+ e.assign<Position>(Position().FromLua(comp.second)).get();
+ } else if (comp.first.cast<std::string>() == "init") {
+ entity["init"] = comp.second;
+ }
+ }
+ } else {
+ std::cerr << "Parameter to spawn() must be a table!" << std::endl;
+ }
+
+ return entity;
+ }
+
+ void scriptExport()
+ {
+ // Components export
+ lb::getGlobalNamespace(state.get()).
+ beginNamespace("comp")
+ .beginClass<Position>("Position")
+ .addConstructor<void(*)(float, float)>()
+ .addProperty("x", &Position::x)
+ .addProperty("y", &Position::y)
+ .endClass()
+ .endNamespace();
+
+ // Functions export
+ //lb::getGlobalNamespace(state.get())
+ // .beginNamespace("game")
+ // .addFunction("spawn", &ScriptSystem::spawn)
+ // .endNamespace();
+ }
+
+ void receive (const EntitySpawnEvent &spawn)
+ {
+ lb::push(state.get(), this->spawn(spawn.ref));
+ }
+};
+
+#endif//SCRIPT_HPP_