mirror of
https://github.com/Keyslam-Group/Concord.git
synced 2025-09-02 04:13:58 -04:00
Revamp how systems are added to worlds
This commit is contained in:
parent
f6468fbe6b
commit
6eaf66308d
2 changed files with 61 additions and 118 deletions
3
main.lua
3
main.lua
|
@ -73,8 +73,7 @@ local world = World()
|
||||||
local entity = Entity(world)
|
local entity = Entity(world)
|
||||||
entity:give(test_comp_1, 100, 100)
|
entity:give(test_comp_1, 100, 100)
|
||||||
|
|
||||||
world:addSystem(test_system_1, "test")
|
world:addSystems(test_system_1, test_system_2)
|
||||||
world:addSystem(test_system_2, "test")
|
|
||||||
|
|
||||||
print("Iteration: 1")
|
print("Iteration: 1")
|
||||||
world:emit("test")
|
world:emit("test")
|
||||||
|
|
176
src/world.lua
176
src/world.lua
|
@ -15,7 +15,7 @@ function World.new()
|
||||||
entities = List(),
|
entities = List(),
|
||||||
systems = List(),
|
systems = List(),
|
||||||
|
|
||||||
events = {},
|
events = {},
|
||||||
|
|
||||||
__added = List(), __backAdded = List(),
|
__added = List(), __backAdded = List(),
|
||||||
__removed = List(), __backRemoved = List(),
|
__removed = List(), __backRemoved = List(),
|
||||||
|
@ -69,6 +69,11 @@ end
|
||||||
|
|
||||||
-- @return self
|
-- @return self
|
||||||
function World:__flush()
|
function World:__flush()
|
||||||
|
-- Early out
|
||||||
|
if (self.__added.size == 0 and self.__removed.size == 0 and self.__dirty.size == 0) then
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
-- Switch buffers
|
-- Switch buffers
|
||||||
self.__added, self.__backAdded = self.__backAdded, self.__added
|
self.__added, self.__backAdded = self.__backAdded, self.__added
|
||||||
self.__removed, self.__backRemoved = self.__backRemoved, self.__removed
|
self.__removed, self.__backRemoved = self.__backRemoved, self.__removed
|
||||||
|
@ -76,7 +81,7 @@ function World:__flush()
|
||||||
|
|
||||||
local e
|
local e
|
||||||
|
|
||||||
-- Added
|
-- Process added entities
|
||||||
for i = 1, self.__backAdded.size do
|
for i = 1, self.__backAdded.size do
|
||||||
e = self.__backAdded[i]
|
e = self.__backAdded[i]
|
||||||
|
|
||||||
|
@ -90,7 +95,7 @@ function World:__flush()
|
||||||
end
|
end
|
||||||
self.__backAdded:clear()
|
self.__backAdded:clear()
|
||||||
|
|
||||||
-- Removed
|
-- Process removed entities
|
||||||
for i = 1, self.__backRemoved.size do
|
for i = 1, self.__backRemoved.size do
|
||||||
e = self.__backRemoved[i]
|
e = self.__backRemoved[i]
|
||||||
|
|
||||||
|
@ -105,7 +110,7 @@ function World:__flush()
|
||||||
end
|
end
|
||||||
self.__backRemoved:clear()
|
self.__backRemoved:clear()
|
||||||
|
|
||||||
-- Dirty
|
-- Process dirty entities
|
||||||
for i = 1, self.__backDirty.size do
|
for i = 1, self.__backDirty.size do
|
||||||
e = self.__backDirty[i]
|
e = self.__backDirty[i]
|
||||||
|
|
||||||
|
@ -118,6 +123,55 @@ function World:__flush()
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local blacklistedSystemMethods = {
|
||||||
|
"init",
|
||||||
|
}
|
||||||
|
|
||||||
|
function World:addSystem(baseSystem)
|
||||||
|
if (not Type.isBaseSystem(baseSystem)) then
|
||||||
|
error("bad argument #"..i.." to 'World:addSystems' (baseSystem expected, got "..type(baseSystem)..")", 2)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- TODO: Check if baseSystem was already added
|
||||||
|
|
||||||
|
-- Create instance of system
|
||||||
|
local system = baseSystem(self)
|
||||||
|
|
||||||
|
self.__systemLookup[baseSystem] = system
|
||||||
|
self.systems:add(system)
|
||||||
|
|
||||||
|
for callbackName, callback in pairs(baseSystem) do
|
||||||
|
-- Skip callback if its blacklisted
|
||||||
|
if (not blacklistedSystemMethods[callbackName]) then
|
||||||
|
-- Make container for all listeners of the callback if it does not exist yet
|
||||||
|
if (not self.events[callbackName]) then
|
||||||
|
self.events[callbackName] = {}
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Add callback to listeners
|
||||||
|
local listeners = self.events[callbackName]
|
||||||
|
listeners[#listeners + 1] = {
|
||||||
|
system = system,
|
||||||
|
callback = callback,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Evaluate all existing entities
|
||||||
|
for j = 1, self.entities.size do
|
||||||
|
system:__evaluate(self.entities[j])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function World:addSystems(...)
|
||||||
|
for i = 1, select("#", ...) do
|
||||||
|
local baseSystem = select(i, ...)
|
||||||
|
|
||||||
|
self:addSystem(baseSystem)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
function World:hasSystem(baseSystem)
|
function World:hasSystem(baseSystem)
|
||||||
if not Type.isBaseSystem(baseSystem) then
|
if not Type.isBaseSystem(baseSystem) then
|
||||||
error("bad argument #1 to 'World:getSystem' (baseSystem expected, got "..type(baseSystem)..")", 2)
|
error("bad argument #1 to 'World:getSystem' (baseSystem expected, got "..type(baseSystem)..")", 2)
|
||||||
|
@ -134,114 +188,6 @@ function World:getSystem(baseSystem)
|
||||||
return self.__systemLookup[baseSystem]
|
return self.__systemLookup[baseSystem]
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Adds a System to the World.
|
|
||||||
-- @param baseSystem The BaseSystem of the system to add
|
|
||||||
-- @param callbackName The callbackName to register to
|
|
||||||
-- @param callback The function name to call. Defaults to callbackName
|
|
||||||
-- @param enabled If the system is enabled. Defaults to true
|
|
||||||
-- @return self
|
|
||||||
function World:addSystem(baseSystem, callbackName, callback, enabled)
|
|
||||||
if not Type.isBaseSystem(baseSystem) then
|
|
||||||
error("bad argument #1 to 'World:addSystem' (baseSystem expected, got "..type(baseSystem)..")", 2)
|
|
||||||
end
|
|
||||||
|
|
||||||
local system = self.__systemLookup[baseSystem]
|
|
||||||
if (not system) then
|
|
||||||
-- System was not created for this world yet, so we create it ourselves
|
|
||||||
system = baseSystem(self)
|
|
||||||
|
|
||||||
self.__systemLookup[baseSystem] = system
|
|
||||||
|
|
||||||
self.systems:add(system)
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Retroactively evaluate all entities for this system
|
|
||||||
for i = 1, self.entities.size do
|
|
||||||
system:__evaluate(self.entities[i])
|
|
||||||
end
|
|
||||||
|
|
||||||
if callbackName then
|
|
||||||
self.events[callbackName] = self.events[callbackName] or {}
|
|
||||||
|
|
||||||
local i = #self.events[callbackName] + 1
|
|
||||||
self.events[callbackName][i] = {
|
|
||||||
system = system,
|
|
||||||
callback = callback or callbackName,
|
|
||||||
enabled = enabled == nil or enabled,
|
|
||||||
}
|
|
||||||
|
|
||||||
if enabled == nil or enabled then
|
|
||||||
system:enabledCallback(callback or callbackName)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
return self
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Enables a System in the World.
|
|
||||||
-- @param system The System to enable
|
|
||||||
-- @param callbackName The Event it was registered to
|
|
||||||
-- @param callback The callback it was registered with. Defaults to eventName
|
|
||||||
-- @return self
|
|
||||||
function World:enableSystem(system, callbackName, callback)
|
|
||||||
if not Type.isSystem(system) then
|
|
||||||
error("bad argument #1 to 'World:enableSystem' (System expected, got "..type(system)..")", 2)
|
|
||||||
end
|
|
||||||
|
|
||||||
return self:setSystem(system, callbackName, callback, true)
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Disables a System in the World.
|
|
||||||
-- @param system The System to disable
|
|
||||||
-- @param eventName The Event it was registered to
|
|
||||||
-- @param callback The callback it was registered with. Defaults to eventName
|
|
||||||
-- @return self
|
|
||||||
function World:disableSystem(system, callbackName, callback)
|
|
||||||
if not Type.isSystem(system) then
|
|
||||||
error("bad argument #1 to 'World:disableSystem' (System expected, got "..type(system)..")", 2)
|
|
||||||
end
|
|
||||||
|
|
||||||
return self:setSystem(system, callbackName, callback, false)
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Sets a System 'enable' in the World.
|
|
||||||
-- @param system The System to set
|
|
||||||
-- @param eventName The Event it was registered to
|
|
||||||
-- @param callback The callback it was registered with. Defaults to eventName
|
|
||||||
-- @param enable The state to set it to
|
|
||||||
-- @return self
|
|
||||||
function World:setSystem(system, callbackName, callback, enable)
|
|
||||||
if not Type.isSystem(system) then
|
|
||||||
error("bad argument #1 to 'World:setSystem' (System expected, got "..type(system)..")", 2)
|
|
||||||
end
|
|
||||||
|
|
||||||
callback = callback or callbackName
|
|
||||||
|
|
||||||
if callback then
|
|
||||||
local listeners = self.events[callbackName]
|
|
||||||
|
|
||||||
if listeners then
|
|
||||||
for i = 1, #listeners do
|
|
||||||
local listener = listeners[i]
|
|
||||||
|
|
||||||
if listener.system == system and listener.callback == callback then
|
|
||||||
if enable and not listener.enabled then
|
|
||||||
system:enabledCallback(callback)
|
|
||||||
elseif not enable and listener.enabled then
|
|
||||||
system:disabledCallback(callback)
|
|
||||||
end
|
|
||||||
|
|
||||||
listener.enabled = enable
|
|
||||||
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
return self
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Emits an Event in the World.
|
--- Emits an Event in the World.
|
||||||
-- @param eventName The Event that should be emitted
|
-- @param eventName The Event that should be emitted
|
||||||
-- @param ... Parameters passed to listeners
|
-- @param ... Parameters passed to listeners
|
||||||
|
@ -257,11 +203,9 @@ function World:emit(callbackName, ...)
|
||||||
for i = 1, #listeners do
|
for i = 1, #listeners do
|
||||||
local listener = listeners[i]
|
local listener = listeners[i]
|
||||||
|
|
||||||
if listener.enabled then
|
self:__flush()
|
||||||
self:__flush()
|
|
||||||
|
|
||||||
listener.system[listener.callback](listener.system, ...)
|
listener.callback(listener.system, ...)
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue