aboutsummaryrefslogtreecommitdiffstats
path: root/src/Script/entityx/EntityLua.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/Script/entityx/EntityLua.hpp')
-rw-r--r--src/Script/entityx/EntityLua.hpp242
1 files changed, 0 insertions, 242 deletions
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