diff --git a/framework/lualib-src/lua-ecs/luaecs.c b/framework/lualib-src/lua-ecs/luaecs.c index ec9d62e..351d989 100644 --- a/framework/lualib-src/lua-ecs/luaecs.c +++ b/framework/lualib-src/lua-ecs/luaecs.c @@ -132,7 +132,6 @@ add_component_id_(lua_State *L, int world_index, struct entity_world *w, int cid struct component_pool *pool = &w->c[cid]; int cap = pool->cap; int index = pool->n; - assert(pool->stride != STRIDE_ORDER); if (pool->n == 0) { if (pool->id == NULL) { pool->id = (unsigned int *)lua_newuserdatauv(L, cap * sizeof(unsigned int), 0); @@ -163,7 +162,7 @@ add_component_id_(lua_State *L, int world_index, struct entity_world *w, int cid } ++pool->n; pool->id[index] = eid; - if (index > 0 && eid < pool->id[index-1]) { + if (pool->stride != STRIDE_ORDER && index > 0 && eid < pool->id[index-1]) { luaL_error(L, "Add component %d fail", cid); } return index; @@ -651,55 +650,6 @@ entity_add_sibling_index_(lua_State *L, int world_index, struct entity_world *w, return ret; } -static inline int -comp_index(const void *a, const void *b, void *v) { - const unsigned int *aa = (const unsigned int *)a; - const unsigned int *bb = (const unsigned int *)b; - int * vv = (int *)v; - return vv[*aa] - vv[*bb]; -} - -static inline int -comp_index_s(void *v, const void *a, const void *b) { - return comp_index(a,b,v); -} - -static inline void -reserve_(struct entity_world *w, int orderid, int cap, void *L, int world_index) { - struct component_pool *c = &w->c[orderid]; - if (c->id == NULL || c->cap < cap) { - c->cap = cap; - c->id = (unsigned int *)lua_newuserdatauv(L, cap * sizeof(unsigned int), 0); - lua_setiuservalue(L, world_index, orderid * 2 + 1); - } -} - -static void -entity_sort_key_(struct entity_world *w, int orderid, int cid, void *L, int world_index) { - struct component_pool *c = &w->c[cid]; - assert(c->stride == sizeof(int)); - struct component_pool *order = &w->c[orderid]; - assert(order->stride == STRIDE_ORDER); - reserve_(w, orderid, c->cap, L, world_index); - int i; - for (i = 0; i < c->n ; i++) { - order->id[i] = i; - } -#ifdef _GNU_SOURCE - qsort_r(order->id, c->n, sizeof(unsigned int), comp_index, c->buffer); -#elif defined(__APPLE__) - qsort_r(order->id, c->n, sizeof(unsigned int), c->buffer, comp_index_s); -#elif defined(_WIN32) - qsort_s(order->id, c->n, sizeof(unsigned int), comp_index_s, c->buffer); -#else -# error Unknown operating system -#endif - for (i = 0; i < c->n ; i++) { - order->id[i] = c->id[order->id[i]]; - } - order->n = c->n; -} - static int lcontext(lua_State *L) { struct entity_world *w = getW(L); @@ -727,7 +677,6 @@ lcontext(lua_State *L) { entity_remove_, entity_enable_tag_, entity_disable_tag_, - entity_sort_key_, entity_iter_lua_, entity_assign_lua_, }; @@ -1307,6 +1256,20 @@ lsync(lua_State *L) { return 0; } +static int +postpone(lua_State *L, struct group_iter *iter, struct component_pool *c) { + int ret = 0; + if (c->stride == STRIDE_ORDER) { + if (lua_getfield(L, 2, iter->k[0].name) == LUA_TBOOLEAN) { + ret = (lua_toboolean(L, -1) == 0); + lua_pushnil(L); + lua_setfield(L, 2, iter->k[0].name); + } + lua_pop(L, 1); + } + return ret; +} + static int leach_group(lua_State *L) { struct group_iter *iter = lua_touserdata(L, 1); @@ -1324,11 +1287,20 @@ leach_group(lua_State *L) { int world_index = lua_gettop(L); - if (i > 0 && !iter->readonly) { - update_last_index(L, world_index, 2, iter, i-1); - } - int mainkey = iter->k[0].id; unsigned int index[MAX_COMPONENT]; + int mainkey = iter->k[0].id; + + struct component_pool *c = &iter->world->c[mainkey]; + if (i>0) { + if (postpone(L, iter, c)) { + --i; + unsigned int tmp = c->id[i]; + memmove(&c->id[i], &c->id[i+1], (c->n-i-1) * sizeof(c->id[0])); + c->id[c->n-1] = tmp; + } else if (!iter->readonly) { + update_last_index(L, world_index, 2, iter, i-1); + } + } for (;;) { int idx = i++; index[0] = idx + 1; @@ -1565,8 +1537,8 @@ lgroupiter(lua_State *L) { } else if (c->stride == STRIDE_ORDER) { if (i != 0) { return luaL_error(L, ".%s is an order key, must be main key", iter->k[i].name); - } else if (iter->k[0].attrib & COMPONENT_OUT) { - return luaL_error(L, ".%s is an order key, it should be readonly", iter->k[0].name); + } else if (!(iter->k[0].attrib & COMPONENT_EXIST)) { + return luaL_error(L, ".%s is an order key, it can be exist", iter->k[0].name); } } int attrib = iter->k[i].attrib; @@ -1600,41 +1572,6 @@ lremove(lua_State *L) { return 0; } -static int -lsortkey(lua_State *L) { - struct entity_world *w = getW(L); - int oid = check_cid(L, w, 2); - int cid = check_cid(L, w, 3); - entity_sort_key_(w, oid, cid, L, 1); - return 0; -} - -static int -lorderkey(lua_State *L) { - struct entity_world *w = getW(L); - int oid = check_cid(L, w, 2); - int cid = check_cid(L, w, 3); - struct component_pool *c = &w->c[oid]; - if (c->stride != STRIDE_ORDER) - return luaL_error(L, "Need order component"); - int n = get_len(L, 4); - reserve_(w, oid, n, L, 1); - struct component_pool *ref = &w->c[cid]; - if (n > ref->n) { - return luaL_error(L, "Invalid length of order array (%d/%d)", n, ref->n); - } - int i; - for (i=0;i ref->n) { - return luaL_error(L, "Invalid refid %d", refid); - } - c->id[i] = ref->id[refid - 1]; - } - c->n = n; - return 0; -} - static int lobject(lua_State *L) { struct group_iter *iter = luaL_checkudata(L, 1, "ENTITY_GROUPITER"); @@ -1871,8 +1808,6 @@ luaopen_ecs_core(lua_State *L) { { "_context", lcontext }, { "_groupiter", lgroupiter }, { "remove", lremove }, - { "_sortkey", lsortkey }, - { "_orderkey", lorderkey }, { "_object", lobject }, { "_sync", lsync }, { "_release", lrelease }, diff --git a/framework/lualib-src/lua-ecs/luaecs.h b/framework/lualib-src/lua-ecs/luaecs.h index 5db8e83..ad56212 100644 --- a/framework/lualib-src/lua-ecs/luaecs.h +++ b/framework/lualib-src/lua-ecs/luaecs.h @@ -14,7 +14,6 @@ struct ecs_capi { void (*remove)(struct entity_world *w, int cid, int index, void *L, int world_index); void (*enable_tag)(struct entity_world *w, int cid, int index, int tag_id, void *L, int world_index); void (*disable_tag)(struct entity_world *w, int cid, int index, int tag_id); - void (*sort_key)(struct entity_world *w, int orderid, int cid, void *L, int world_index); void * (*iter_lua)(struct entity_world *w, int cid, int index, void *L, int world_index); int (*assign_lua)(struct entity_world *w, int cid, int index, void *L, int world_index); }; @@ -104,13 +103,6 @@ entity_disable_tag(struct ecs_context *ctx, int cid, int index, int tag_id) { ctx->api->disable_tag(ctx->world, ctx->cid[cid], index, ctx->cid[tag_id]); } -static inline void -entity_sort_key(struct ecs_context *ctx, int orderid, int cid) { - check_id_(ctx, orderid); - check_id_(ctx, cid); - ctx->api->sort_key(ctx->world, ctx->cid[orderid], ctx->cid[cid], ctx->L, 1); -} - static inline int entity_assign_lua(struct ecs_context *ctx, int cid, int index) { check_id_(ctx, cid); diff --git a/framework/lualib-src/lua-ecs/test.lua b/framework/lualib-src/lua-ecs/test.lua index 752f563..09e08b3 100644 --- a/framework/lualib-src/lua-ecs/test.lua +++ b/framework/lualib-src/lua-ecs/test.lua @@ -143,7 +143,7 @@ for v in w:select "vector:update" do end print "vector:in id?out" -for v in w:select "vector:in id?temp" do +for v in w:select "vector:in id?out" do print(v.vector.x, v.vector.y, v.id) if v.id then v.id = 200 diff --git a/framework/lualib-src/lua-ecs/test11.lua b/framework/lualib-src/lua-ecs/test11.lua index 6e3ece1..a7c7c91 100644 --- a/framework/lualib-src/lua-ecs/test11.lua +++ b/framework/lualib-src/lua-ecs/test11.lua @@ -3,28 +3,36 @@ local ecs = require "ecs" local w = ecs.world() w:register { - name = "id", - type = "int64", + name = "order", + order = true, } w:register { - name = "data", - type = "lua", + name = "node", + "id:int", + "parent:int", } -for i = 1 , 10 do - w:new { - id = i, - data = "Hello " .. i, - } -end +w:new { + node = { id = 1, parent = 0 } , + order = true, +} -local function fetch(id) - local v = w:sync("data:in", w:fetch("id", id)) - return v.data -end +w:new { + node = { id = 0, parent = -1 }, + order = true, +} + +local cache = {} -for i = 1, 10 do - print(fetch(i)) +for v in w:select "order node:update" do + local node = v.node + if node.parent < 0 or cache[node.parent] then + cache[node.id] = true + print(node.id, node.parent) + else + v.order = false + end end +assert(pcall(w.select, w, "node order") == false) diff --git a/framework/lualib-src/lua-ecs/test9.lua b/framework/lualib-src/lua-ecs/test9.lua index 87e6844..0754867 100644 --- a/framework/lualib-src/lua-ecs/test9.lua +++ b/framework/lualib-src/lua-ecs/test9.lua @@ -35,8 +35,6 @@ w:new { index = 1, } -w:sort("sort", "index") - for v in w:select "mark" do w:readall(v) for k,v in pairs(v) do @@ -44,7 +42,7 @@ for v in w:select "mark" do end end -local ids = w:dumpid "sort" +local ids = w:dumpid "index" for idx, id in ipairs(ids) do print(idx, id) diff --git a/framework/lualib/3rd/misc/ecs.lua b/framework/lualib/3rd/misc/ecs.lua index 47fa6df..9892fa5 100644 --- a/framework/lualib/3rd/misc/ecs.lua +++ b/framework/lualib/3rd/misc/ecs.lua @@ -63,9 +63,8 @@ local function cache_world(obj, k) local function gen_all_pat() local desc = {} local i = 1 - local _ORDERKEY = ecs._ORDERKEY for name,t in pairs(c.typenames) do - if t.size ~= _ORDERKEY then + if t.tag ~= "ORDER" then local a = { name = t.name, id = t.id, @@ -248,6 +247,9 @@ do -- newtype c.type = t c.size = typesize[t] c[1] = { t, "v", 0 } + elseif typeclass.order then + c.size = ecs._ORDERKEY + c.tag = "ORDER" else c.tag = true end @@ -287,7 +289,9 @@ function M:new(obj) error ("Invalid key : ".. k) end local id = self:_addcomponent(eid, tc.id) - self:object(k, id, v) + if tc.tag ~= "ORDER" then + self:object(k, id, v) + end end if reference then local id = self:_addcomponent(eid, REFERENCE_ID) @@ -369,38 +373,6 @@ function M:clear(name) self:_clear(id) end -local function gen_sorted_id(self, sorted, name) - local ctx = context[self] - local typenames = ctx.typenames - local t = assert(typenames[name]) - local stype = typenames[sorted] - if stype == nil then - local id = ctx.id + 1 - assert(id <= ecs._MAXTYPE) - ctx.id = id - stype = { - id = id, - name = sorted, - size = ecs._ORDERKEY, - tag = true - } - self:_newtype(id, stype.size) - typenames[sorted] = stype - else - assert(stype.size == ecs._ORDERKEY) - end - return stype.id, t.id -end - -function M:sort(sorted, name) - self:_sortkey(gen_sorted_id(self, sorted, name)) -end - -function M:order(sorted, refname, order_array) - local sid, rid = gen_sorted_id(self, sorted, refname) - self:_orderkey(sid, rid, order_array) -end - function M:dumpid(name) local typenames = context[self].typenames return self:_dumpid(typenames[name].id)