sparse_set.lua
· 1.1 KiB · Lua
原始檔案
Playground
local function push(self, thing)
-- Attempt to recycle a previously freed ID
local id = self.free_ids[#self.free_ids]
table.remove(self.free_ids)
if not id then
-- Othewise generate a new ID
id = self.next_id
self.next_id = self.next_id + 1
end
-- Assign the ID, the push the object into items
-- and add its position to indices.
thing.id = id
table.insert(self.items, thing)
self.indices[thing.id] = #self.items
end
local function pop(self, thing)
assert(self.indices[thing.id], "ID is not bound in this set")
assert(self.items[self.indices[thing.id]] == thing, "ID does not belong to this object")
-- Add the ID of this object to the free stack
table.insert(self.free_ids, thing.id)
-- Consume the current index
local index = self.indices[thing.id]
self.indices[thing.id] = nil
-- Swap and pop the last item in the set.
self.items[index] = self.items[#self.items]
table.remove(self.items)
end
local function each(self)
return ipairs(self.items)
end
local function sparse_set()
return { push = push, pop = pop, each = each, items = {}, indices = {}, free_ids = {}, next_id = 1 }
end
return sparse_set
| 1 | local function push(self, thing) |
| 2 | -- Attempt to recycle a previously freed ID |
| 3 | local id = self.free_ids[#self.free_ids] |
| 4 | table.remove(self.free_ids) |
| 5 | if not id then |
| 6 | -- Othewise generate a new ID |
| 7 | id = self.next_id |
| 8 | self.next_id = self.next_id + 1 |
| 9 | end |
| 10 | -- Assign the ID, the push the object into items |
| 11 | -- and add its position to indices. |
| 12 | thing.id = id |
| 13 | table.insert(self.items, thing) |
| 14 | self.indices[thing.id] = #self.items |
| 15 | end |
| 16 | |
| 17 | local function pop(self, thing) |
| 18 | assert(self.indices[thing.id], "ID is not bound in this set") |
| 19 | assert(self.items[self.indices[thing.id]] == thing, "ID does not belong to this object") |
| 20 | -- Add the ID of this object to the free stack |
| 21 | table.insert(self.free_ids, thing.id) |
| 22 | |
| 23 | -- Consume the current index |
| 24 | local index = self.indices[thing.id] |
| 25 | self.indices[thing.id] = nil |
| 26 | |
| 27 | -- Swap and pop the last item in the set. |
| 28 | self.items[index] = self.items[#self.items] |
| 29 | table.remove(self.items) |
| 30 | end |
| 31 | |
| 32 | local function each(self) |
| 33 | return ipairs(self.items) |
| 34 | end |
| 35 | |
| 36 | local function sparse_set() |
| 37 | return { push = push, pop = pop, each = each, items = {}, indices = {}, free_ids = {}, next_id = 1 } |
| 38 | end |
| 39 | |
| 40 | return sparse_set |
| 41 |