🐳 chore(库): 更新

develop
xiaojin 5 years ago
parent 74640736cc
commit b5659bc39b

@ -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));
c->id[from] = eid;
}
@ -1628,6 +1629,65 @@ lorderkey(lua_State *L) {
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
lbsearch(lua_State *L) {
struct entity_world *w = getW(L);
@ -1774,6 +1834,80 @@ lreuse(lua_State *L) {
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
luaopen_ecs_core(lua_State *L) {
luaL_checkversion(L);
@ -1792,7 +1926,7 @@ luaopen_ecs_core(lua_State *L) {
{ "_newtype",lnew_type },
{ "_newentity", lnew_entity },
{ "_addcomponent", ladd_component },
{ "update", lupdate },
{ "_update", lupdate },
{ "_clear", lclear_type },
{ "_context", lcontext },
{ "_groupiter", lgroupiter },
@ -1804,6 +1938,8 @@ luaopen_ecs_core(lua_State *L) {
{ "_release", lrelease },
{ "_bsearch", lbsearch },
{ "_reuse", lreuse },
{ "_fetch", lfetch },
{ "_update_reference", lupdate_reference },
{ NULL, NULL },
};
luaL_setfuncs(L,l,0);

@ -0,0 +1,30 @@
local ecs = require "ecs"
local w = ecs.world()
w:register {
name = "id",
type = "int64",
}
w:register {
name = "data",
type = "lua",
}
for i = 1 , 10 do
w:new {
id = i,
data = "Hello " .. i,
}
end
local function fetch(id)
local v = w:sync("data:in", w:fetch("id", id))
return v.data
end
for i = 1, 10 do
print(fetch(i))
end

@ -0,0 +1,48 @@
local ecs = require "ecs"
local w = ecs.world()
w:register {
name = "value",
type = "int",
}
local r = {}
for i=1, 42 do
r[i] = w:new {
value = i,
reference = true,
}
w:new {
value = -i,
}
end
for v in w:select("value:in") do
print(v.value)
if v.value < 0 then
w:remove(v)
end
end
local function read(i)
local v = w:sync("value:in", r[i])
return v.value
end
w:remove(r[1])
w:remove(r[10])
w:remove(r[20])
w:remove(r[30])
w:update()
for i=1,42 do
print(pcall(read,i))
end
for v in w:select("value:in") do
print(v.value)
end

@ -17,12 +17,20 @@ w:register {
name = "mark"
}
w:register {
name = "index",
type = "int",
}
w:new {
vector = { x = 1, y = 2 },
text = "Hello World",
mark = true,
index = 1,
}
w:sort("sort", "index")
for v in w:select "mark" do
w:readall(v)
for k,v in pairs(v) do

@ -1,5 +1,7 @@
local ecs = require "ecs.core"
local REFERENCE_ID <const> = 1
local function get_attrib(opt, inout)
if opt == nil then
return { exist = true }
@ -12,7 +14,7 @@ local function get_attrib(opt, inout)
end
if inout == "in" then
desc.r = true
elseif inout == "out" or inout == "new" then
elseif inout == "out" then
desc.w = true
elseif inout == "update" then
desc.r = true
@ -61,7 +63,9 @@ 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
local a = {
name = t.name,
id = t.id,
@ -73,6 +77,7 @@ local function cache_world(obj, k)
desc[i] = a
i = i + 1
end
end
return desc
end
@ -272,6 +277,11 @@ function M:new(obj)
-- dump(obj)
local eid = self:_newentity()
local typenames = context[self].typenames
local reference = obj.reference
if reference then
reference = {}
obj.reference = nil
end
for k,v in pairs(obj) do
local tc = typenames[k]
if not tc then
@ -280,6 +290,13 @@ function M:new(obj)
local id = self:_addcomponent(eid, tc.id)
self:object(k, id, v)
end
if reference then
local id = self:_addcomponent(eid, REFERENCE_ID)
reference[1] = id
reference[2] = REFERENCE_ID
self:object("reference", id, reference)
return reference
end
end
function M:ref(name, refobj)
@ -391,6 +408,27 @@ function M:bsearch(sorted, name, value)
return self:_bsearch(sorted_id, value_id, value)
end
function M:fetch(idtype, id)
local c = context[self].typenames[idtype]
local f = c.fetch
if not f then
f = setmetatable({}, { __mode = "kv" })
c.fetch = f
end
local cid = c.id
local iter = f[id]
local ret = self:_fetch(cid, id, iter)
if not iter then
f[id] = ret
end
return ret
end
function M:update()
self:_update_reference(REFERENCE_ID)
self:_update()
end
do
local _object = M._object
function M:object(name, refid, v)
@ -412,6 +450,11 @@ function ecs.world()
size = 0,
tag = true,
}
w:register {
name = "reference",
type = "lua",
}
assert(context[w].typenames.reference.id == REFERENCE_ID)
return w
end

@ -0,0 +1,84 @@
-- https://github.com/LuaDist-testing/ltdiff
local ltdiff = {}
local function table_diff(A, B)
local diff = {
del = {},
mod = {},
sub = {},
}
for k, v in pairs(A) do
if type(A[k]) == "function" or type(A[k]) == "userdata" then
error("table_diff only supports diffs of tables!")
elseif B[k] ~= nil and type(A[k]) == "table" and type(B[k]) == "table" then
diff.sub[k] = table_diff(A[k], B[k])
if next(diff.sub[k]) == nil then
diff.sub[k] = nil
end
elseif B[k] == nil then
diff.del[#(diff.del) + 1] = k
elseif B[k] ~= v then
diff.mod[k] = B[k]
end
end
for k, v in pairs(B) do
if type(B[k]) == "function" or type(B[k]) == "userdata" then
error("table_diff only supports diffs of tables!")
elseif diff.sub[k] ~= nil then
-- skip
elseif A[k] ~= nil and type(A[k]) == "table" and type(B[k]) == "table" then
diff.sub[k] = table_diff(B[k], A[k])
if next(diff.sub[k]) == nil then
diff.sub[k] = nil
end
elseif B[k] ~= A[k] then
diff.mod[k] = v
end
end
if next(diff.sub) == nil then
diff.sub = nil
end
if next(diff.mod) == nil then
diff.mod = nil
end
if next(diff.del) == nil then
diff.del = nil
end
return diff
end
local function table_patch(A, diff)
if diff.sub ~= nil then
for k, v in pairs(diff.sub) do
A[k] = table_patch(A[k], v)
end
end
if diff.del ~= nil then
for _, v in pairs(diff.del) do
A[v] = nil
end
end
if diff.mod ~= nil then
for k, v in pairs(diff.mod) do
A[k] = v
end
end
return A
end
ltdiff.diff = table_diff
ltdiff.patch = table_patch
return ltdiff

@ -1,3 +1,4 @@
-- https://github.com/cloudwu/skynet/pull/1419
local skynet = require "skynet"
local coroutine = coroutine
@ -6,7 +7,9 @@ local tinsert = table.insert
local tremove = table.remove
local setmetatable = setmetatable
function skynet.cs()
-- local scope_lock<close> = lock()
function skynet.lock()
local current_thread
local ref = 0
local thread_queue = {}
@ -37,4 +40,4 @@ function skynet.cs()
end
end
return skynet.cs
return skynet.lock

@ -10,6 +10,7 @@ if not ok then
return
end
local dump = require "dump"
local termfx = require "termfx"
local ui = require "simpleui"
@ -43,7 +44,6 @@ local function main(token)
termfx.present()
local evt = termfx.pollevent(100)
if evt then
if evt.type == 'key' then
@ -67,7 +67,7 @@ local function main(token)
local r, msgid, msg = recv_msg()
if r == true then
table.insert(msg_list, {MN[msgid] or msgid, inspect(msg)})
table.insert(msg_list, {MN[msgid] or msgid, dump(msg)})
elseif r == false then
p('网络断开,结束客户端', msgid)
break

@ -1 +1 @@
Subproject commit bc298e4a91d016df653e9a48f118672d209a3a05
Subproject commit 0d5638125b8f7fcab8bbe93343ca36a57820a717
Loading…
Cancel
Save