|
|
|
|
@ -293,11 +293,9 @@ lookup_component(struct component_pool *pool, unsigned int eid, int guess_index)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline void
|
|
|
|
|
replace_id(struct component_pool *c, int index, unsigned int eid) {
|
|
|
|
|
unsigned int rid = c->id[index];
|
|
|
|
|
c->id[index] = eid;
|
|
|
|
|
replace_id(struct component_pool *c, int from, int to, unsigned int eid) {
|
|
|
|
|
int i;
|
|
|
|
|
for (i=index+1;i<c->n && c->id[i] == rid;i++) {
|
|
|
|
|
for (i=from;i<to;i++) {
|
|
|
|
|
c->id[i] = eid;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
@ -313,20 +311,26 @@ entity_disable_tag_(struct entity_world *w, int cid, int index, int tag_id) {
|
|
|
|
|
if (index < 0)
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
int i;
|
|
|
|
|
for (i=index - 1; i>=0; i--) {
|
|
|
|
|
if (c->id[i] != eid) {
|
|
|
|
|
replace_id(c, i+1, c->id[i]);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
int from,to;
|
|
|
|
|
// find next tag. You may disable subsquent tags in iteration.
|
|
|
|
|
// For example, The sequence is 1 3 5 7 9 . We are now on 5 , and disable 7 .
|
|
|
|
|
// We should change 7 to 9 ( 1 3 5 9 9 ) rather than 7 to 5 ( 1 3 5 5 9 )
|
|
|
|
|
// iterator -> ^ ^
|
|
|
|
|
for (to = index+1; to<c->n; to++) {
|
|
|
|
|
if (c->id[to] != eid) {
|
|
|
|
|
for (from = index-1; from>=0; from--) {
|
|
|
|
|
if (c->id[from] != eid)
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
for (i=index+1;i<c->n;i++) {
|
|
|
|
|
if (c->id[i] != eid) {
|
|
|
|
|
replace_id(c, index, c->id[i]);
|
|
|
|
|
replace_id(c, from+1, to, c->id[to]);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
c->n = 0;
|
|
|
|
|
for (from = index-1; from>=0; from--) {
|
|
|
|
|
if (c->id[from] != eid)
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
c->n = from + 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
@ -517,10 +521,8 @@ entity_iter_(struct entity_world *w, int cid, int index) {
|
|
|
|
|
if (c->stride == STRIDE_TAG) {
|
|
|
|
|
// it's a tag
|
|
|
|
|
unsigned int eid = c->id[index];
|
|
|
|
|
if (index > 0 && eid == c->id[index-1]) {
|
|
|
|
|
remove_dup(c, index);
|
|
|
|
|
if (index >= c->n)
|
|
|
|
|
return NULL;
|
|
|
|
|
if (index < c->n - 1 && eid == c->id[index+1]) {
|
|
|
|
|
remove_dup(c, index+1);
|
|
|
|
|
}
|
|
|
|
|
return DUMMY_PTR;
|
|
|
|
|
}
|
|
|
|
|
@ -1025,37 +1027,14 @@ remove_tag(lua_State *L, int lua_index, const char *name) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
update_last_index(lua_State *L, int world_index, int lua_index, struct group_iter *iter, int idx) {
|
|
|
|
|
update_iter(lua_State *L, int world_index, int lua_index, struct group_iter *iter, int idx, int mainkey, int skip) {
|
|
|
|
|
struct field *f = iter->f;
|
|
|
|
|
|
|
|
|
|
int i;
|
|
|
|
|
int mainkey = iter->k[0].id;
|
|
|
|
|
struct component_pool *c = &iter->world->c[mainkey];
|
|
|
|
|
int disable_mainkey = 0;
|
|
|
|
|
if (!(iter->k[0].attrib & COMPONENT_FILTER)) {
|
|
|
|
|
if (c->stride == STRIDE_TAG) {
|
|
|
|
|
// The mainkey is a tag, delay disable
|
|
|
|
|
disable_mainkey = ((iter->k[0].attrib & COMPONENT_OUT) && remove_tag(L, lua_index, iter->k[0].name));
|
|
|
|
|
} else if ((iter->k[0].attrib & COMPONENT_OUT)
|
|
|
|
|
&& get_write_component(L, lua_index, iter->k[0].name, iter->f, c)) {
|
|
|
|
|
struct component_pool *c = &iter->world->c[mainkey];
|
|
|
|
|
if (c->n <= idx) {
|
|
|
|
|
luaL_error(L, "Can't find component %s for index %d", iter->k[0].name, idx);
|
|
|
|
|
}
|
|
|
|
|
if (c->stride == STRIDE_LUA) {
|
|
|
|
|
if (lua_getiuservalue(L, world_index, mainkey * 2 + 2) != LUA_TTABLE) {
|
|
|
|
|
luaL_error(L, "Missing lua table for %d", mainkey);
|
|
|
|
|
}
|
|
|
|
|
lua_insert(L, -2);
|
|
|
|
|
lua_rawseti(L, -2, idx+1);
|
|
|
|
|
} else {
|
|
|
|
|
void * buffer = get_ptr(c, idx);
|
|
|
|
|
write_component_object(L, iter->k[0].field_n, iter->f, buffer);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
for (i=0;i<skip;i++) {
|
|
|
|
|
f += iter->k[i].field_n;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct field *f = iter->f + iter->k[0].field_n;
|
|
|
|
|
|
|
|
|
|
for (i=1;i<iter->nkey;i++) {
|
|
|
|
|
for (i=skip;i<iter->nkey;i++) {
|
|
|
|
|
struct group_key *k = &iter->k[i];
|
|
|
|
|
if (!(k->attrib & (COMPONENT_FILTER | COMPONENT_REFINDEX))) {
|
|
|
|
|
struct component_pool *c = &iter->world->c[k->id];
|
|
|
|
|
@ -1149,6 +1128,38 @@ update_last_index(lua_State *L, int world_index, int lua_index, struct group_ite
|
|
|
|
|
}
|
|
|
|
|
f += k->field_n;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
update_last_index(lua_State *L, int world_index, int lua_index, struct group_iter *iter, int idx) {
|
|
|
|
|
int mainkey = iter->k[0].id;
|
|
|
|
|
struct component_pool *c = &iter->world->c[mainkey];
|
|
|
|
|
int disable_mainkey = 0;
|
|
|
|
|
if (!(iter->k[0].attrib & COMPONENT_FILTER)) {
|
|
|
|
|
if (c->stride == STRIDE_TAG) {
|
|
|
|
|
// The mainkey is a tag, delay disable
|
|
|
|
|
disable_mainkey = ((iter->k[0].attrib & COMPONENT_OUT) && remove_tag(L, lua_index, iter->k[0].name));
|
|
|
|
|
} else if ((iter->k[0].attrib & COMPONENT_OUT)
|
|
|
|
|
&& get_write_component(L, lua_index, iter->k[0].name, iter->f, c)) {
|
|
|
|
|
struct component_pool *c = &iter->world->c[mainkey];
|
|
|
|
|
if (c->n <= idx) {
|
|
|
|
|
luaL_error(L, "Can't find component %s for index %d", iter->k[0].name, idx);
|
|
|
|
|
}
|
|
|
|
|
if (c->stride == STRIDE_LUA) {
|
|
|
|
|
if (lua_getiuservalue(L, world_index, mainkey * 2 + 2) != LUA_TTABLE) {
|
|
|
|
|
luaL_error(L, "Missing lua table for %d", mainkey);
|
|
|
|
|
}
|
|
|
|
|
lua_insert(L, -2);
|
|
|
|
|
lua_rawseti(L, -2, idx+1);
|
|
|
|
|
} else {
|
|
|
|
|
void * buffer = get_ptr(c, idx);
|
|
|
|
|
write_component_object(L, iter->k[0].field_n, iter->f, buffer);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
update_iter(L, world_index, lua_index, iter, idx, mainkey, 1);
|
|
|
|
|
|
|
|
|
|
if (disable_mainkey) {
|
|
|
|
|
entity_disable_tag_(iter->world, mainkey, idx, mainkey);
|
|
|
|
|
}
|
|
|
|
|
@ -1177,13 +1188,12 @@ read_component_in_field(lua_State *L, int lua_index, const char *name, int n, st
|
|
|
|
|
|
|
|
|
|
// -1 : end ; 0 : next ; 1 : succ
|
|
|
|
|
static int
|
|
|
|
|
query_index(struct group_iter *iter, int mainkey, int idx, unsigned int index[MAX_COMPONENT]) {
|
|
|
|
|
query_index(struct group_iter *iter, int skip, int mainkey, int idx, unsigned int index[MAX_COMPONENT]) {
|
|
|
|
|
if (entity_iter_(iter->world, mainkey, idx) == NULL) {
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
index[0] = idx+1;
|
|
|
|
|
int j;
|
|
|
|
|
for (j=1;j<iter->nkey;j++) {
|
|
|
|
|
for (j=skip;j<iter->nkey;j++) {
|
|
|
|
|
struct group_key *k = &iter->k[j];
|
|
|
|
|
if (k->attrib & COMPONENT_ABSENT) {
|
|
|
|
|
if (entity_sibling_index_(iter->world, mainkey, idx, k->id)) {
|
|
|
|
|
@ -1255,24 +1265,30 @@ read_iter(lua_State *L, int world_index, int obj_index, struct group_iter *iter,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
lsync(lua_State *L) {
|
|
|
|
|
struct group_iter *iter = luaL_checkudata(L, 2, "ENTITY_GROUPITER");
|
|
|
|
|
luaL_checktype(L, 3, LUA_TTABLE);
|
|
|
|
|
if (lua_rawgeti(L, 3, 1) != LUA_TNUMBER) {
|
|
|
|
|
return luaL_error(L, "Invalid iterator");
|
|
|
|
|
get_integer(lua_State *L, int index, int i, const char *key) {
|
|
|
|
|
if (lua_rawgeti(L, index, i) != LUA_TNUMBER) {
|
|
|
|
|
return luaL_error(L, "Can't find %s in iterator", key);
|
|
|
|
|
}
|
|
|
|
|
int idx = lua_tointeger(L, -1) - 1;
|
|
|
|
|
if (idx < 0)
|
|
|
|
|
return luaL_error(L, "Invalid iterator index %d", idx);
|
|
|
|
|
int r = lua_tointeger(L, -1);
|
|
|
|
|
lua_pop(L, 1);
|
|
|
|
|
if (r <= 0)
|
|
|
|
|
return luaL_error(L, "Invalid %s (%d)", key, r);
|
|
|
|
|
return r;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
lsync(lua_State *L) {
|
|
|
|
|
struct group_iter *iter = luaL_checkudata(L, 2, "ENTITY_GROUPITER");
|
|
|
|
|
luaL_checktype(L, 3, LUA_TTABLE);
|
|
|
|
|
int idx = get_integer(L, 3, 1, "index") - 1;
|
|
|
|
|
int mainkey = get_integer(L, 3, 2, "mainkey");
|
|
|
|
|
unsigned int index[MAX_COMPONENT];
|
|
|
|
|
if (query_index(iter, iter->k[0].id, idx, index) <=0) {
|
|
|
|
|
if (query_index(iter, 0, mainkey, idx, index) <=0) {
|
|
|
|
|
return luaL_error(L, "Read pattern fail");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!iter->readonly) {
|
|
|
|
|
update_last_index(L, 1, 3, iter, idx);
|
|
|
|
|
update_iter(L, 1, 3, iter, idx, mainkey, 0);
|
|
|
|
|
}
|
|
|
|
|
read_iter(L, 1, 3, iter, index);
|
|
|
|
|
return 0;
|
|
|
|
|
@ -1301,7 +1317,9 @@ leach_group(lua_State *L) {
|
|
|
|
|
int mainkey = iter->k[0].id;
|
|
|
|
|
unsigned int index[MAX_COMPONENT];
|
|
|
|
|
for (;;) {
|
|
|
|
|
int ret = query_index(iter, mainkey, i++, index);
|
|
|
|
|
int idx = i++;
|
|
|
|
|
index[0] = idx + 1;
|
|
|
|
|
int ret = query_index(iter, 1, mainkey, idx, index);
|
|
|
|
|
if (ret < 0)
|
|
|
|
|
return 0;
|
|
|
|
|
if (ret > 0)
|
|
|
|
|
@ -1548,12 +1566,6 @@ lgroupiter(lua_State *L) {
|
|
|
|
|
iter->readonly = 0;
|
|
|
|
|
}
|
|
|
|
|
int mainkey_attrib = iter->k[0].attrib;
|
|
|
|
|
if (mainkey_attrib & COMPONENT_OPTIONAL) {
|
|
|
|
|
return luaL_error(L, "The main key should not be optional");
|
|
|
|
|
}
|
|
|
|
|
if (is_temporary(mainkey_attrib)) {
|
|
|
|
|
return luaL_error(L, "The main key can't be temporary");
|
|
|
|
|
}
|
|
|
|
|
if (mainkey_attrib & COMPONENT_ABSENT) {
|
|
|
|
|
return luaL_error(L, "The main key can't be absent");
|
|
|
|
|
}
|
|
|
|
|
@ -1565,18 +1577,6 @@ lgroupiter(lua_State *L) {
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
get_integer(lua_State *L, int index, int i, const char *key) {
|
|
|
|
|
if (lua_rawgeti(L, index, i) != LUA_TNUMBER) {
|
|
|
|
|
return luaL_error(L, "Can't find %s in iterator", key);
|
|
|
|
|
}
|
|
|
|
|
int r = lua_tointeger(L, -1);
|
|
|
|
|
lua_pop(L, 1);
|
|
|
|
|
if (r <= 0)
|
|
|
|
|
return luaL_error(L, "Invalid %s (%d)", key, r);
|
|
|
|
|
return r;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
lremove(lua_State *L) {
|
|
|
|
|
struct entity_world *w = getW(L);
|
|
|
|
|
@ -1639,9 +1639,11 @@ lbsearch(lua_State *L) {
|
|
|
|
|
int * v = entity_iter_(w, value_id, mid);
|
|
|
|
|
if (*v == value) {
|
|
|
|
|
// found
|
|
|
|
|
lua_createtable(L, 1, 0);
|
|
|
|
|
lua_createtable(L, 2, 0);
|
|
|
|
|
lua_pushinteger(L, mid + 1);
|
|
|
|
|
lua_seti(L, -2, 1);
|
|
|
|
|
lua_pushinteger(L, sorted_id);
|
|
|
|
|
lua_seti(L, -2, 2);
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
if (*v < value) {
|
|
|
|
|
@ -1660,9 +1662,11 @@ lbsearch(lua_State *L) {
|
|
|
|
|
int * v = entity_iter_(w, value_id, index - 1);
|
|
|
|
|
if (*v == value) {
|
|
|
|
|
// found
|
|
|
|
|
lua_createtable(L, 1, 0);
|
|
|
|
|
lua_createtable(L, 2, 0);
|
|
|
|
|
lua_pushinteger(L, index);
|
|
|
|
|
lua_seti(L, -2, 1);
|
|
|
|
|
lua_pushinteger(L, sorted_id);
|
|
|
|
|
lua_seti(L, -2, 2);
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
if (*v < value) {
|
|
|
|
|
|