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:
bakpakin
2015-03-22 12:07:42 +08:00
parent b98cd5a14d
commit 216064d63c
3 changed files with 132 additions and 58 deletions
+2 -2
View File
@@ -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"
} }
+122 -56
View File
@@ -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
@@ -156,12 +157,12 @@ function Aspect:__tostring()
return "JojoAspect<>" return "JojoAspect<>"
else else
return "JojoAspect<Required: {" .. return "JojoAspect<Required: {" ..
tconcat(self[1], ", ") .. tconcat(self[1], ", ") ..
"}, Excluded: {" .. "}, Excluded: {" ..
tconcat(self[2], ", ") .. tconcat(self[2], ", ") ..
"}, One Req.: {" .. "}, One Req.: {" ..
tconcat(self[3], ", ") .. tconcat(self[3], ", ") ..
"}>" "}>"
end end
end end
@@ -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
-- Remove all Systems queued for removal
for i = #systemsToRemove, 1, -1 do
-- Pop system off the remove stack
local sys = systemsToRemove[i]
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
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 for eid, s in pairs(statuses) do
local e = entities[eid]
if s == "add" then if s == "add" then
local e = entities[eid] deltaEntityCount = deltaEntityCount + 1
for sysid, eids in pairs(systemEntities) do for sysID, eids in pairs(systemEntities) do
local a = systems[sysid].aspect local a = systems[systemIndices[sysID]].aspect
eids[eid] = a:matches(e) and true or nil eids[eid] = a:matches(e) and true or nil
end end
statuses[eid] = nil elseif s == "remove" then
end deltaEntityCount = deltaEntityCount - 1
end
for sysid, s in ipairs(self.systems) do
local preupdate = s.preupdate
local eids = systemEntities[sysid]
local active = s.active
-- Preupdate
if active and preupdate then
preupdate(dt)
end
if active then -- Free freed entities and update the others.
local u = s.update
for eid in pairs(eids) do
local status = statuses[eid]
if status == "remove" then
eids[eid] = nil
else
u(entities[eid], dt)
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
-- Reset all statuses for next update
for eid, s in pairs(statuses) do
if s == "remove" then
entities[eid].id = nil
entities[eid] = nil entities[eid] = nil
for _, eids in pairs(systemEntities) do
eids[eid] = nil
end
end end
statuses[eid] = nil statuses[eid] = nil
end end
-- 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 update = s.update
if preupdate then
preupdate(dt)
end
if update then
local eids = systemEntities[s.id]
for eid in pairs(eids) do
update(entities[eid], dt)
end
end
end
end
end end
return jojo return jojo
+8
View File
@@ -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)