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