mirror of
https://github.com/bakpakin/tiny-ecs.git
synced 2026-07-22 07:56:52 -06:00
Update version to 0.0.2
Add System addition and removal Changed implementation for Entity removal Change README and example code
This commit is contained in:
@@ -51,7 +51,7 @@ local talkingSystem = System(
|
|||||||
print("Talking system has started.")
|
print("Talking system has started.")
|
||||||
end,
|
end,
|
||||||
function (p, delta)
|
function (p, delta)
|
||||||
print(p.name .. ", who weighs " .. p.mass .. "pounds, says, " .. p.phrase)
|
print(p.name .. ", who weighs " .. p.mass .. " pounds, says, \"" .. p.phrase .. "\"")
|
||||||
end,
|
end,
|
||||||
personAspect
|
personAspect
|
||||||
)
|
)
|
||||||
@@ -61,7 +61,7 @@ local world = World(talkingSystem)
|
|||||||
local joe = {
|
local joe = {
|
||||||
name = "Joe",
|
name = "Joe",
|
||||||
phrase = "I'm a plumber.",
|
phrase = "I'm a plumber.",
|
||||||
mass = 150,
|
mass = 250,
|
||||||
hairColor = "brown"
|
hairColor = "brown"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
local jojo = {
|
local jojo = {
|
||||||
_VERSION = "0.0.1",
|
_VERSION = "0.0.2",
|
||||||
_URL = "https://github.com/bakpakin/Jojo"
|
_URL = "https://github.com/bakpakin/Jojo"
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -30,6 +30,7 @@ jojo.Aspect = Aspect
|
|||||||
jojo.System = System
|
jojo.System = System
|
||||||
|
|
||||||
local tinsert = table.insert
|
local tinsert = table.insert
|
||||||
|
local tremove = table.remove
|
||||||
local tconcat = table.concat
|
local tconcat = table.concat
|
||||||
local pairs = pairs
|
local pairs = pairs
|
||||||
local ipairs = ipairs
|
local ipairs = ipairs
|
||||||
@@ -216,6 +217,9 @@ function World:init(...)
|
|||||||
-- Table of Entity IDs to Entities
|
-- Table of Entity IDs to Entities
|
||||||
self.entities = {}
|
self.entities = {}
|
||||||
|
|
||||||
|
-- Number of Entities in World.
|
||||||
|
self.entityCount = 0
|
||||||
|
|
||||||
-- List of Systems
|
-- List of Systems
|
||||||
self.systems = args
|
self.systems = args
|
||||||
|
|
||||||
@@ -226,15 +230,54 @@ function World:init(...)
|
|||||||
-- Next available entity ID
|
-- Next available entity ID
|
||||||
self.nextID = 0
|
self.nextID = 0
|
||||||
|
|
||||||
-- Table of System indices to Sets of matching Entity IDs
|
-- Table of System IDs to Sets of matching Entity IDs
|
||||||
local systemEntities = {}
|
local systemEntities = {}
|
||||||
self.systemEntities = systemEntities
|
self.systemEntities = systemEntities
|
||||||
|
|
||||||
for i, sys in ipairs(args) do
|
for i, sys in ipairs(args) do
|
||||||
systemEntities[i] = {}
|
local id = sys.id
|
||||||
systemIndices[sys.id] = i
|
systemEntities[id] = {}
|
||||||
|
systemIndices[id] = i
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- List of Systems to add next update
|
||||||
|
self.systemsToAdd = {}
|
||||||
|
|
||||||
|
-- List of System ids to remove next update
|
||||||
|
self.systemsToRemove = {}
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
function World:__tostring()
|
||||||
|
return "JojoWorld<systemCount: " ..
|
||||||
|
#self.systems ..
|
||||||
|
", entityCount: " ..
|
||||||
|
#self.entityCount ..
|
||||||
|
">"
|
||||||
|
end
|
||||||
|
|
||||||
|
-- World:addSystems(...)
|
||||||
|
|
||||||
|
-- Appends Systems in order to the World. Systems will be added after the next
|
||||||
|
-- call to World:update(dt)
|
||||||
|
function World:addSystems(...)
|
||||||
|
local args = {...}
|
||||||
|
local systemsToAdd = self.systemsToAdd
|
||||||
|
for i, sys in ipairs(args) do
|
||||||
|
tinsert(systemsToAdd, sys)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- World:freeSystems(...)
|
||||||
|
|
||||||
|
-- Appends Systems in order to the World. Systems will be added after the next
|
||||||
|
-- call to World:update(dt)
|
||||||
|
function World:removeSystems(...)
|
||||||
|
local args = {...}
|
||||||
|
local systemsToRemove = self.systemsToRemove
|
||||||
|
for i, sys in ipairs(args) do
|
||||||
|
tinsert(systemsToRemove, sys)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- World:add(...)
|
-- World:add(...)
|
||||||
@@ -287,64 +330,87 @@ function World:update(dt)
|
|||||||
|
|
||||||
local statuses = self.status
|
local statuses = self.status
|
||||||
local systemEntities = self.systemEntities
|
local systemEntities = self.systemEntities
|
||||||
|
local systemIndices = self.systemIndices
|
||||||
local entities = self.entities
|
local entities = self.entities
|
||||||
local systems = self.systems
|
local systems = self.systems
|
||||||
|
local systemsToAdd = self.systemsToAdd
|
||||||
|
local systemsToRemove = self.systemsToRemove
|
||||||
|
|
||||||
for eid, s in pairs(statuses) do
|
-- Remove all Systems queued for removal
|
||||||
if s == "add" then
|
for i = #systemsToRemove, 1, -1 do
|
||||||
local e = entities[eid]
|
-- Pop system off the remove stack
|
||||||
for sysid, eids in pairs(systemEntities) do
|
local sys = systemsToRemove[i]
|
||||||
local a = systems[sysid].aspect
|
systemsToRemove[i] = nil
|
||||||
|
|
||||||
|
local id = sys.id
|
||||||
|
local sysIndex = systemIndices[id]
|
||||||
|
tremove(systems, sysIndex)
|
||||||
|
systemEntities[id] = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Add Systems queued for addition
|
||||||
|
for i = 1, #systemsToAdd do
|
||||||
|
-- Pop system off the add queue
|
||||||
|
local sys = systemsToAdd[i]
|
||||||
|
systemsToAdd[i] = nil
|
||||||
|
|
||||||
|
-- Add system to world
|
||||||
|
local id = sys.id
|
||||||
|
local eids = {}
|
||||||
|
systemEntities[id] = eids
|
||||||
|
tinsert(systems, sys)
|
||||||
|
systemIndices[id] = #systems
|
||||||
|
|
||||||
|
local a = sys.aspect
|
||||||
|
for eid, e in pairs(entities) do
|
||||||
eids[eid] = a:matches(e) and true or nil
|
eids[eid] = a:matches(e) and true or nil
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Kepp track of number of Entities in World
|
||||||
|
local deltaEntityCount = 0
|
||||||
|
|
||||||
|
-- Add, remove, or change Entities
|
||||||
|
for eid, s in pairs(statuses) do
|
||||||
|
local e = entities[eid]
|
||||||
|
if s == "add" then
|
||||||
|
deltaEntityCount = deltaEntityCount + 1
|
||||||
|
for sysID, eids in pairs(systemEntities) do
|
||||||
|
local a = systems[systemIndices[sysID]].aspect
|
||||||
|
eids[eid] = a:matches(e) and true or nil
|
||||||
|
end
|
||||||
|
elseif s == "remove" then
|
||||||
|
deltaEntityCount = deltaEntityCount - 1
|
||||||
|
entities[eid] = nil
|
||||||
|
for _, eids in pairs(systemEntities) do
|
||||||
|
eids[eid] = nil
|
||||||
|
end
|
||||||
|
end
|
||||||
statuses[eid] = nil
|
statuses[eid] = nil
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
|
||||||
for sysid, s in ipairs(self.systems) do
|
-- Update Entity count
|
||||||
|
self.entityCount = self.entityCount + deltaEntityCount
|
||||||
|
|
||||||
|
-- Iterate through Systems IN ORDER
|
||||||
|
for _, s in ipairs(self.systems) do
|
||||||
|
if s.active then
|
||||||
|
|
||||||
local preupdate = s.preupdate
|
local preupdate = s.preupdate
|
||||||
local eids = systemEntities[sysid]
|
local update = s.update
|
||||||
local active = s.active
|
|
||||||
|
|
||||||
-- Preupdate
|
if preupdate then
|
||||||
if active and preupdate then
|
|
||||||
preupdate(dt)
|
preupdate(dt)
|
||||||
end
|
end
|
||||||
|
|
||||||
if active then -- Free freed entities and update the others.
|
if update then
|
||||||
|
local eids = systemEntities[s.id]
|
||||||
local u = s.update
|
|
||||||
|
|
||||||
for eid in pairs(eids) do
|
for eid in pairs(eids) do
|
||||||
local status = statuses[eid]
|
update(entities[eid], dt)
|
||||||
if status == "remove" then
|
|
||||||
eids[eid] = nil
|
|
||||||
else
|
|
||||||
u(entities[eid], dt)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
else -- Just free freed Entities
|
|
||||||
|
|
||||||
for eid in pairs(eids) do
|
|
||||||
if statuses[eid] == "remove" then
|
|
||||||
eids[eid] = nil
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Reset all statuses for next update
|
|
||||||
for eid, s in pairs(statuses) do
|
|
||||||
if s == "remove" then
|
|
||||||
entities[eid].id = nil
|
|
||||||
entities[eid] = nil
|
|
||||||
end
|
|
||||||
statuses[eid] = nil
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
return jojo
|
return jojo
|
||||||
|
|||||||
@@ -83,12 +83,20 @@ assert(e1.xform.x == 21, "e1.xform.x should be 21, but is " .. e1.xform.x)
|
|||||||
assert(e2.xform.x == -19, "e2.xform.x should be -19, but is " .. e2.xform.x)
|
assert(e2.xform.x == -19, "e2.xform.x should be -19, but is " .. e2.xform.x)
|
||||||
assert(e3.xform.y == 68, "e3.xform.y should be 68, but is " .. e3.xform.y)
|
assert(e3.xform.y == 68, "e3.xform.y should be 68, but is " .. e3.xform.y)
|
||||||
|
|
||||||
|
world:removeSystems(moves)
|
||||||
|
world:update(1234567890)
|
||||||
|
world:addSystems(moves)
|
||||||
|
|
||||||
world:remove(e3, e2)
|
world:remove(e3, e2)
|
||||||
world:update(20)
|
world:update(20)
|
||||||
assert(e1.xform.x == 41, "e1.xform.x should be 41, but is " .. e1.xform.x)
|
assert(e1.xform.x == 41, "e1.xform.x should be 41, but is " .. e1.xform.x)
|
||||||
assert(e2.xform.x == -19, "e2.xform.x should be -19, but is " .. e2.xform.x)
|
assert(e2.xform.x == -19, "e2.xform.x should be -19, but is " .. e2.xform.x)
|
||||||
assert(e3.xform.y == 68, "e3.xform.y should be 68, but is " .. e3.xform.y)
|
assert(e3.xform.y == 68, "e3.xform.y should be 68, but is " .. e3.xform.y)
|
||||||
|
|
||||||
|
world:removeSystems(moves)
|
||||||
|
world:update(12345)
|
||||||
|
world:addSystems(moves)
|
||||||
|
|
||||||
world:add(e3, e2)
|
world:add(e3, e2)
|
||||||
world:update(19)
|
world:update(19)
|
||||||
world:remove(e3, e2)
|
world:remove(e3, e2)
|
||||||
|
|||||||
Reference in New Issue
Block a user