mirror of
https://github.com/BlackMATov/evolved.lua.git
synced 2025-12-13 03:29:08 +07:00
simple idpools module
This commit is contained in:
3
.vscode/extensions.json
vendored
3
.vscode/extensions.json
vendored
@@ -1,5 +1,6 @@
|
||||
{
|
||||
"recommendations": [
|
||||
"sumneko.lua"
|
||||
"sumneko.lua",
|
||||
"tomblind.local-lua-debugger-vscode"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -1 +1 @@
|
||||
local evo = require 'evolved.evolved'
|
||||
require 'develop.untests.idpools_untests'
|
||||
|
||||
85
develop/untests/idpools_untests.lua
Normal file
85
develop/untests/idpools_untests.lua
Normal file
@@ -0,0 +1,85 @@
|
||||
local evo = require 'evolved.evolved'
|
||||
|
||||
do
|
||||
local p1 = evo.idpools.idpool()
|
||||
local p2 = evo.idpools.idpool()
|
||||
assert(p1 ~= p2)
|
||||
end
|
||||
|
||||
do
|
||||
local p = evo.idpools.idpool()
|
||||
|
||||
local i1_1 = evo.idpools.acquire_id(p)
|
||||
assert(i1_1 == 0x100001)
|
||||
|
||||
local i2_1 = evo.idpools.acquire_id(p)
|
||||
assert(i2_1 == 0x100002)
|
||||
|
||||
do
|
||||
local i, v = evo.idpools.unpack_id(i1_1)
|
||||
assert(i == 1 and v == 1)
|
||||
end
|
||||
|
||||
do
|
||||
local i, v = evo.idpools.unpack_id(i2_1)
|
||||
assert(i == 2 and v == 1)
|
||||
end
|
||||
end
|
||||
|
||||
do
|
||||
local p = evo.idpools.idpool()
|
||||
|
||||
local i1_1 = evo.idpools.acquire_id(p)
|
||||
local i2_1 = evo.idpools.acquire_id(p)
|
||||
assert(evo.idpools.is_id_alive(p, i1_1))
|
||||
assert(evo.idpools.is_id_alive(p, i2_1))
|
||||
|
||||
evo.idpools.release_id(p, i1_1)
|
||||
assert(not evo.idpools.is_id_alive(p, i1_1))
|
||||
assert(evo.idpools.is_id_alive(p, i2_1))
|
||||
|
||||
evo.idpools.release_id(p, i2_1)
|
||||
assert(not evo.idpools.is_id_alive(p, i1_1))
|
||||
assert(not evo.idpools.is_id_alive(p, i2_1))
|
||||
|
||||
local i2_2 = evo.idpools.acquire_id(p)
|
||||
assert(i2_2 == 0x200002)
|
||||
|
||||
local i1_2 = evo.idpools.acquire_id(p)
|
||||
assert(i1_2 == 0x200001)
|
||||
|
||||
assert(not evo.idpools.is_id_alive(p, i1_1))
|
||||
assert(not evo.idpools.is_id_alive(p, i2_1))
|
||||
assert(evo.idpools.is_id_alive(p, i1_2))
|
||||
assert(evo.idpools.is_id_alive(p, i2_2))
|
||||
end
|
||||
|
||||
do
|
||||
local p = evo.idpools.idpool()
|
||||
|
||||
for _ = 1, 0xFFFFF - 1 do
|
||||
_ = evo.idpools.acquire_id(p)
|
||||
end
|
||||
|
||||
assert(evo.idpools.acquire_id(p) == 0x1FFFFF)
|
||||
|
||||
if not os.getenv("LOCAL_LUA_DEBUGGER_VSCODE") then
|
||||
assert(not pcall(evo.idpools.acquire_id, p))
|
||||
end
|
||||
end
|
||||
|
||||
do
|
||||
local p = evo.idpools.idpool()
|
||||
|
||||
for _ = 1, 0x7FF - 1 do
|
||||
evo.idpools.release_id(p, evo.idpools.acquire_id(p))
|
||||
end
|
||||
|
||||
local i1_7FF = evo.idpools.acquire_id(p)
|
||||
assert(i1_7FF == 0x7FF00001)
|
||||
evo.idpools.release_id(p, i1_7FF)
|
||||
|
||||
local i1_1 = evo.idpools.acquire_id(p)
|
||||
assert(i1_1 == 0x100001)
|
||||
evo.idpools.release_id(p, i1_1)
|
||||
end
|
||||
@@ -1,4 +1,5 @@
|
||||
return {
|
||||
idpools = require 'evolved.idpools',
|
||||
registry = require 'evolved.registry',
|
||||
singles = require 'evolved.singles',
|
||||
vectors = require 'evolved.vectors',
|
||||
|
||||
69
evolved/idpools.lua
Normal file
69
evolved/idpools.lua
Normal file
@@ -0,0 +1,69 @@
|
||||
local bit = require 'bit'
|
||||
|
||||
---@class evolved.idpools
|
||||
local idpools = {}
|
||||
|
||||
---@class evolved.idpool
|
||||
---@field acquired_ids integer[]
|
||||
---@field available_index integer
|
||||
local evolved_idpool_mt = {}
|
||||
evolved_idpool_mt.__index = evolved_idpool_mt
|
||||
|
||||
---@return evolved.idpool
|
||||
function idpools.idpool()
|
||||
---@type evolved.idpool
|
||||
local self = {
|
||||
acquired_ids = {},
|
||||
available_index = 0,
|
||||
}
|
||||
return setmetatable(self, evolved_idpool_mt)
|
||||
end
|
||||
|
||||
---@param id integer
|
||||
---@return integer index
|
||||
---@return integer version
|
||||
function idpools.unpack_id(id)
|
||||
return bit.band(id, 0xFFFFF), bit.rshift(id, 20)
|
||||
end
|
||||
|
||||
---@param idpool evolved.idpool
|
||||
---@return integer
|
||||
---@nodiscard
|
||||
function idpools.acquire_id(idpool)
|
||||
if idpool.available_index ~= 0 then
|
||||
local index = idpool.available_index
|
||||
local version = bit.band(idpool.acquired_ids[index], 0x7FF00000)
|
||||
idpool.available_index = bit.band(idpool.acquired_ids[index], 0xFFFFF)
|
||||
idpool.acquired_ids[index] = index + version
|
||||
return idpool.acquired_ids[index]
|
||||
end
|
||||
|
||||
if #idpool.acquired_ids == 0xFFFFF then
|
||||
error('id index overflow', 2)
|
||||
end
|
||||
|
||||
local index, version = #idpool.acquired_ids + 1, 0x100000
|
||||
idpool.acquired_ids[index] = index + version
|
||||
return idpool.acquired_ids[index]
|
||||
end
|
||||
|
||||
---@param idpool evolved.idpool
|
||||
---@param id integer
|
||||
function idpools.release_id(idpool, id)
|
||||
local index = bit.band(id, 0xFFFFF)
|
||||
local version = bit.band(id, 0x7FF00000)
|
||||
version = version == 0x7FF00000 and 0x100000 or version + 0x100000
|
||||
idpool.acquired_ids[index] = idpool.available_index + version
|
||||
idpool.available_index = index
|
||||
end
|
||||
|
||||
---@param idpool evolved.idpool
|
||||
---@param id integer
|
||||
---@return boolean
|
||||
---@nodiscard
|
||||
function idpools.is_id_alive(idpool, id)
|
||||
local index = bit.band(id, 0xFFFFF)
|
||||
return idpool.acquired_ids[index] == id
|
||||
end
|
||||
|
||||
return idpools
|
||||
Reference in New Issue
Block a user