impl id freelist

This commit is contained in:
BlackMATov
2024-12-12 16:25:52 +07:00
parent 1afac4886d
commit b9bc621267

View File

@@ -6,29 +6,133 @@ local evolved = {}
---@alias evolved.fragment evolved.id
---@alias evolved.component any
---@return evolved.id
---@nodiscard
function evolved.id() end
---
---
---
---
---
local __freelist_ids = {} ---@type evolved.id[]
local __available_idx = 0 ---@type integer
---
---
---
---
---
---@param index integer
---@param version integer
---@return evolved.id
---@nodiscard
function evolved.pack(index, version) end
local function __pack_id(index, version)
assert(index >= 1 and index <= 0xFFFFF, 'id index out of range [1;0xFFFFF]')
assert(version >= 1 and version <= 0x7FF, 'id version out of range [1;0x7FF]')
return index + version * 0x100000
end
---@param id evolved.id
---@return integer index
---@return integer version
---@nodiscard
function evolved.unpack(id) end
local function __unpack_id(id)
local index = id % 0x100000
local version = (id - index) / 0x100000
return index, version
end
---@return evolved.id
---@nodiscard
local function __acquire_id()
if __available_idx ~= 0 then
local index = __available_idx
local freelist_id = __freelist_ids[index]
__available_idx = freelist_id % 0x100000
local version = freelist_id - __available_idx
local acquired_id = index + version
__freelist_ids[index] = acquired_id
return acquired_id
else
if #__freelist_ids == 0xFFFFF then
error('id index overflow', 2)
end
local index = #__freelist_ids + 1
local version = 0x100000
local acquired_id = index + version
__freelist_ids[index] = acquired_id
return acquired_id
end
end
---@param id evolved.id
---@return boolean
---@nodiscard
function evolved.alive(id) end
local function __alive_id(id)
local index = id % 0x100000
return __freelist_ids[index] == id
end
---@param id evolved.id
function evolved.destroy(id) end
local function __release_id(id)
local index = id % 0x100000
local version = id - index
if __freelist_ids[index] ~= id then
error('id is not acquired or already released', 2)
end
version = version == 0x7FF00000
and 0x100000
or version + 0x100000
__freelist_ids[index] = __available_idx + version
__available_idx = index
end
---
---
---
---
---
---@return evolved.id
---@nodiscard
function evolved.id()
return __acquire_id()
end
---@param index integer
---@param version integer
---@return evolved.id
---@nodiscard
function evolved.pack(index, version)
return __pack_id(index, version)
end
---@param id evolved.id
---@return integer index
---@return integer version
---@nodiscard
function evolved.unpack(id)
return __unpack_id(id)
end
---@param id evolved.id
---@return boolean
---@nodiscard
function evolved.alive(id)
return __alive_id(id)
end
---@param id evolved.id
function evolved.destroy(id)
if __alive_id(id) then
__release_id(id)
end
end
---@param entity evolved.entity
---@param ... evolved.fragment fragments