From e9758416b18b27a65337c28d9641afc0ee89b34b Mon Sep 17 00:00:00 2001
From: Andy Belle-Isle <drumsetmonkey@gmail.com>
Date: Thu, 29 Aug 2019 01:39:40 -0400
Subject: Created (very messy) script system

---
 src/Script/entityx/EntityLua.hpp  | 242 --------------------------------------
 src/Script/entityx/LuaTypes.hpp   |  96 ---------------
 src/Script/entityx/entity_lua.cpp | 183 ----------------------------
 src/Script/entityx/entity_lua.hpp |  13 --
 src/components/Component.hpp      |  33 ++++++
 src/components/Position.hpp       |  47 ++++++++
 src/main.cpp                      | 118 +++++++++++--------
 src/script.hpp                    | 154 ++++++++++++++++++++++++
 8 files changed, 302 insertions(+), 584 deletions(-)
 delete mode 100644 src/Script/entityx/EntityLua.hpp
 delete mode 100644 src/Script/entityx/LuaTypes.hpp
 delete mode 100644 src/Script/entityx/entity_lua.cpp
 delete mode 100644 src/Script/entityx/entity_lua.hpp
 create mode 100644 src/components/Component.hpp
 create mode 100644 src/components/Position.hpp
 create mode 100644 src/script.hpp

(limited to 'src')

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_
-- 
cgit v1.2.3