|
|
|
@ -245,7 +245,8 @@ insert_id(lua_State *L, int world_index, struct entity_world *w, int cid, unsign
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
add_component_id_(L, world_index, w, cid, eid);
|
|
|
|
// 0xffffffff max uint avoid check
|
|
|
|
|
|
|
|
add_component_id_(L, world_index, w, cid, 0xffffffff);
|
|
|
|
memmove(c->id + from + 1, c->id + from, sizeof(unsigned int) * (c->n - from - 1));
|
|
|
|
memmove(c->id + from + 1, c->id + from, sizeof(unsigned int) * (c->n - from - 1));
|
|
|
|
c->id[from] = eid;
|
|
|
|
c->id[from] = eid;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
@ -1628,6 +1629,65 @@ lorderkey(lua_State *L) {
|
|
|
|
return 0;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
|
|
|
search_id(lua_State *L, int begin, int end, struct entity_world *w, int cid, int64_t value) {
|
|
|
|
|
|
|
|
while (begin < end) {
|
|
|
|
|
|
|
|
int mid = (begin + end)/2;
|
|
|
|
|
|
|
|
int64_t * v = entity_iter_(w, cid, mid);
|
|
|
|
|
|
|
|
if (*v == value) {
|
|
|
|
|
|
|
|
// found
|
|
|
|
|
|
|
|
lua_pushinteger(L, mid + 1);
|
|
|
|
|
|
|
|
lua_seti(L, -2, 1);
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if (*v < value) {
|
|
|
|
|
|
|
|
begin = mid + 1;
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
end = mid;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
|
|
|
lfetch(lua_State *L) {
|
|
|
|
|
|
|
|
struct entity_world *w = getW(L);
|
|
|
|
|
|
|
|
int cid = check_cid(L, w, 2);
|
|
|
|
|
|
|
|
lua_Integer value = luaL_checkinteger(L, 3);
|
|
|
|
|
|
|
|
struct component_pool *c = &w->c[cid];
|
|
|
|
|
|
|
|
if (c->stride != sizeof(int64_t)) {
|
|
|
|
|
|
|
|
return luaL_error(L, "Id component is not int64");
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if (lua_istable(L, 4)) {
|
|
|
|
|
|
|
|
// cache iter
|
|
|
|
|
|
|
|
lua_settop(L, 4);
|
|
|
|
|
|
|
|
lua_geti(L, 4, 1);
|
|
|
|
|
|
|
|
int mid = lua_tointeger(L, -1) - 1;
|
|
|
|
|
|
|
|
lua_pop(L, 1);
|
|
|
|
|
|
|
|
if (mid >=0 && mid < c->n) {
|
|
|
|
|
|
|
|
int64_t * v = entity_iter_(w, cid, mid);
|
|
|
|
|
|
|
|
if (*v == value)
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
if (*v < value) {
|
|
|
|
|
|
|
|
return search_id(L, mid+1, c->n, w, cid, value);
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
if (mid > GUESS_RANGE) {
|
|
|
|
|
|
|
|
return search_id(L, mid - GUESS_RANGE, mid, w, cid, value) ||
|
|
|
|
|
|
|
|
search_id(L, 0, mid - GUESS_RANGE, w, cid, value);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return search_id(L, 0, mid, w, cid, value);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
// new iter
|
|
|
|
|
|
|
|
lua_createtable(L, 2, 0);
|
|
|
|
|
|
|
|
lua_pushinteger(L, cid);
|
|
|
|
|
|
|
|
lua_seti(L, -2, 2);
|
|
|
|
|
|
|
|
return search_id(L, 0, c->n, w, cid, value);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
static int
|
|
|
|
lbsearch(lua_State *L) {
|
|
|
|
lbsearch(lua_State *L) {
|
|
|
|
struct entity_world *w = getW(L);
|
|
|
|
struct entity_world *w = getW(L);
|
|
|
|
@ -1774,6 +1834,80 @@ lreuse(lua_State *L) {
|
|
|
|
return 1;
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
|
|
|
find_boundary(int from, int to, unsigned int *a, unsigned int eid) {
|
|
|
|
|
|
|
|
while(from < to) {
|
|
|
|
|
|
|
|
int mid = (from + to)/2;
|
|
|
|
|
|
|
|
unsigned int aa = a[mid];
|
|
|
|
|
|
|
|
if (aa == eid)
|
|
|
|
|
|
|
|
return mid;
|
|
|
|
|
|
|
|
else if (aa < eid) {
|
|
|
|
|
|
|
|
from = mid + 1;
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
to = mid;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return to;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static inline int
|
|
|
|
|
|
|
|
next_removed_index(int removed_index, struct component_pool *removed, unsigned int *removed_eid) {
|
|
|
|
|
|
|
|
for (;;) {
|
|
|
|
|
|
|
|
++removed_index;
|
|
|
|
|
|
|
|
if (removed_index >= removed->n) {
|
|
|
|
|
|
|
|
*removed_eid = 0;
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
unsigned int last_eid = *removed_eid;
|
|
|
|
|
|
|
|
*removed_eid = removed->id[removed_index];
|
|
|
|
|
|
|
|
if (*removed_eid != last_eid)
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return removed_index;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
|
|
|
lupdate_reference(lua_State *L) {
|
|
|
|
|
|
|
|
struct entity_world *w = getW(L);
|
|
|
|
|
|
|
|
struct component_pool *removed = &w->c[ENTITY_REMOVED];
|
|
|
|
|
|
|
|
if (removed->n == 0) // no removed entity
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
int cid = check_cid(L, w, 2);
|
|
|
|
|
|
|
|
struct component_pool *reference = &w->c[cid];
|
|
|
|
|
|
|
|
if (reference == 0)
|
|
|
|
|
|
|
|
return 0; // no reference
|
|
|
|
|
|
|
|
if (lua_getiuservalue(L, 1, cid * 2 + 2) != LUA_TTABLE) {
|
|
|
|
|
|
|
|
return luaL_error(L, "Invalid reference component %d", cid);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
int i;
|
|
|
|
|
|
|
|
int removed_index = 0;
|
|
|
|
|
|
|
|
unsigned int removed_eid = removed->id[removed_index];
|
|
|
|
|
|
|
|
int index = find_boundary(0, reference->n, reference->id, removed_eid);
|
|
|
|
|
|
|
|
int reference_index = index + 1;
|
|
|
|
|
|
|
|
for (i=index; i< reference->n; i++) {
|
|
|
|
|
|
|
|
if (lua_geti(L, -1, i+1) != LUA_TTABLE) {
|
|
|
|
|
|
|
|
return luaL_error(L, "Invalid reference object");
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if (removed_eid) {
|
|
|
|
|
|
|
|
while (removed_eid < reference->id[i]) {
|
|
|
|
|
|
|
|
removed_index = next_removed_index(removed_index, removed, &removed_eid);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if (removed_eid == reference->id[i]) {
|
|
|
|
|
|
|
|
// removed reference, clear reference id
|
|
|
|
|
|
|
|
lua_pushnil(L);
|
|
|
|
|
|
|
|
removed_index = next_removed_index(removed_index, removed, &removed_eid);
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
// update reference id
|
|
|
|
|
|
|
|
lua_pushinteger(L, reference_index);
|
|
|
|
|
|
|
|
++reference_index;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
lua_seti(L, -2, 1);
|
|
|
|
|
|
|
|
lua_pop(L, 1);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
LUAMOD_API int
|
|
|
|
LUAMOD_API int
|
|
|
|
luaopen_ecs_core(lua_State *L) {
|
|
|
|
luaopen_ecs_core(lua_State *L) {
|
|
|
|
luaL_checkversion(L);
|
|
|
|
luaL_checkversion(L);
|
|
|
|
@ -1792,7 +1926,7 @@ luaopen_ecs_core(lua_State *L) {
|
|
|
|
{ "_newtype",lnew_type },
|
|
|
|
{ "_newtype",lnew_type },
|
|
|
|
{ "_newentity", lnew_entity },
|
|
|
|
{ "_newentity", lnew_entity },
|
|
|
|
{ "_addcomponent", ladd_component },
|
|
|
|
{ "_addcomponent", ladd_component },
|
|
|
|
{ "update", lupdate },
|
|
|
|
{ "_update", lupdate },
|
|
|
|
{ "_clear", lclear_type },
|
|
|
|
{ "_clear", lclear_type },
|
|
|
|
{ "_context", lcontext },
|
|
|
|
{ "_context", lcontext },
|
|
|
|
{ "_groupiter", lgroupiter },
|
|
|
|
{ "_groupiter", lgroupiter },
|
|
|
|
@ -1804,6 +1938,8 @@ luaopen_ecs_core(lua_State *L) {
|
|
|
|
{ "_release", lrelease },
|
|
|
|
{ "_release", lrelease },
|
|
|
|
{ "_bsearch", lbsearch },
|
|
|
|
{ "_bsearch", lbsearch },
|
|
|
|
{ "_reuse", lreuse },
|
|
|
|
{ "_reuse", lreuse },
|
|
|
|
|
|
|
|
{ "_fetch", lfetch },
|
|
|
|
|
|
|
|
{ "_update_reference", lupdate_reference },
|
|
|
|
{ NULL, NULL },
|
|
|
|
{ NULL, NULL },
|
|
|
|
};
|
|
|
|
};
|
|
|
|
luaL_setfuncs(L,l,0);
|
|
|
|
luaL_setfuncs(L,l,0);
|
|
|
|
|