mirror of
https://github.com/Ukendio/jecs.git
synced 2025-04-24 09:00:02 +00:00
158 lines
3.2 KiB
Text
158 lines
3.2 KiB
Text
local c = {
|
|
white_underline = function(s: any)
|
|
return `\27[1;4m{s}\27[0m`
|
|
end,
|
|
|
|
white = function(s: any)
|
|
return `\27[37;1m{s}\27[0m`
|
|
end,
|
|
|
|
green = function(s: any)
|
|
return `\27[32;1m{s}\27[0m`
|
|
end,
|
|
|
|
red = function(s: any)
|
|
return `\27[31;1m{s}\27[0m`
|
|
end,
|
|
|
|
yellow = function(s: any)
|
|
return `\27[33;1m{s}\27[0m`
|
|
end,
|
|
|
|
red_highlight = function(s: any)
|
|
return `\27[41;1;30m{s}\27[0m`
|
|
end,
|
|
|
|
green_highlight = function(s: any)
|
|
return `\27[42;1;30m{s}\27[0m`
|
|
end,
|
|
|
|
gray = function(s: any)
|
|
return `\27[30;1m{s}\27[0m`
|
|
end,
|
|
}
|
|
|
|
|
|
local ECS_PAIR_FLAG = 0x8
|
|
local ECS_ID_FLAGS_MASK = 0x10
|
|
local ECS_ENTITY_MASK = bit32.lshift(1, 24)
|
|
local ECS_GENERATION_MASK = bit32.lshift(1, 16)
|
|
|
|
type i53 = number
|
|
type i24 = number
|
|
|
|
local function ECS_ENTITY_T_LO(e: i53): i24
|
|
return if e > ECS_ENTITY_MASK then (e // ECS_ID_FLAGS_MASK) // ECS_ENTITY_MASK else e
|
|
end
|
|
|
|
local function ECS_GENERATION(e: i53): i24
|
|
return if e > ECS_ENTITY_MASK then (e // ECS_ID_FLAGS_MASK) % ECS_GENERATION_MASK else 0
|
|
end
|
|
|
|
local ECS_ID = ECS_ENTITY_T_LO
|
|
|
|
local function ECS_COMBINE(source: number, target: number): i53
|
|
return (source * 268435456) + (target * ECS_ID_FLAGS_MASK)
|
|
end
|
|
|
|
local function ECS_GENERATION_INC(e: i53)
|
|
if e > ECS_ENTITY_MASK then
|
|
local flags = e // ECS_ID_FLAGS_MASK
|
|
local id = flags // ECS_ENTITY_MASK
|
|
local generation = flags % ECS_GENERATION_MASK
|
|
|
|
local next_gen = generation + 1
|
|
if next_gen > ECS_GENERATION_MASK then
|
|
return id
|
|
end
|
|
|
|
return ECS_COMBINE(id, next_gen) + flags
|
|
end
|
|
return ECS_COMBINE(e, 1)
|
|
end
|
|
|
|
local function bl()
|
|
print("")
|
|
end
|
|
|
|
local function pe(e)
|
|
local gen = ECS_GENERATION(e)
|
|
return c.green(`e{ECS_ID(e)}`)..c.yellow(`v{gen}`)
|
|
end
|
|
|
|
local function dprint(tbl: { [number]: number })
|
|
bl()
|
|
print("--------")
|
|
for i, e in tbl do
|
|
print("| "..pe(e).." |")
|
|
print("--------")
|
|
end
|
|
bl()
|
|
end
|
|
|
|
local max_id = 0
|
|
local alive_count = 0
|
|
local dense = {}
|
|
local sparse = {}
|
|
local function alloc()
|
|
if alive_count ~= #dense then
|
|
alive_count += 1
|
|
print("*recycled", pe(dense[alive_count]))
|
|
return dense[alive_count]
|
|
end
|
|
max_id += 1
|
|
local id = max_id
|
|
alive_count += 1
|
|
dense[alive_count] = id
|
|
sparse[id] = {
|
|
dense = alive_count
|
|
}
|
|
print("*allocated", pe(id))
|
|
return id
|
|
end
|
|
|
|
local function remove(entity)
|
|
local id = ECS_ID(entity)
|
|
local r = sparse[id]
|
|
local index_of_deleted_entity = r.dense
|
|
local last_entity_alive_at_index = alive_count -- last entity alive
|
|
alive_count -= 1
|
|
local last_alive_entity = dense[last_entity_alive_at_index]
|
|
local r_swap = sparse[ECS_ID(last_alive_entity)]
|
|
r_swap.dense = r.dense
|
|
r.dense = last_entity_alive_at_index
|
|
dense[index_of_deleted_entity] = last_alive_entity
|
|
dense[last_entity_alive_at_index] = ECS_GENERATION_INC(entity)
|
|
print("*dellocated", pe(id))
|
|
end
|
|
|
|
local function alive(e)
|
|
local r = sparse[ECS_ID(e)]
|
|
|
|
return dense[r.dense] == e
|
|
end
|
|
|
|
local function pa(e)
|
|
print(`{pe(e)} is {if alive(e) then "alive" else "not alive"}`)
|
|
end
|
|
|
|
local tprint = require("@testkit").print
|
|
local e1v0 = alloc()
|
|
local e2v0 = alloc()
|
|
local e3v0 = alloc()
|
|
local e4v0 = alloc()
|
|
local e5v0 = alloc()
|
|
pa(e1v0)
|
|
pa(e4v0)
|
|
remove(e5v0)
|
|
pa(e5v0)
|
|
|
|
local e5v1 = alloc()
|
|
pa(e5v0)
|
|
pa(e5v1)
|
|
pa(e2v0)
|
|
print(ECS_ID(e2v0))
|
|
|
|
dprint(dense)
|
|
remove(e2v0)
|
|
dprint(dense)
|