🐳 chore(库): 更新 lua ecs

develop
xiaojin 5 years ago
parent 15de42b61a
commit a8793bcae4

@ -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) {
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);
}
int mainkey = iter->k[0].id;
unsigned int index[MAX_COMPONENT];
}
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<n;i++) {
int refid = get_integer(L, 4, i+1, "order");
if (refid > 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 },

@ -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);

@ -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

@ -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)

@ -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)

@ -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,8 +289,10 @@ function M:new(obj)
error ("Invalid key : ".. k)
end
local id = self:_addcomponent(eid, tc.id)
if tc.tag ~= "ORDER" then
self:object(k, id, v)
end
end
if reference then
local id = self:_addcomponent(eid, REFERENCE_ID)
reference[1] = 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)

Loading…
Cancel
Save