Moved some files

This commit is contained in:
Justin van der Leij 2018-04-07 18:24:52 +02:00
parent 281bb53a5b
commit 6c98c259e4
10 changed files with 673 additions and 676 deletions

View file

@ -1,36 +1,36 @@
local Component = {} local Component = {}
Component.__index = Component Component.__index = Component
--- Creates a new Component. --- Creates a new Component.
-- @param populate A function that populates the Bag with values -- @param populate A function that populates the Bag with values
-- @return A Component object -- @return A Component object
function Component.new(populate) function Component.new(populate)
local component = setmetatable({ local component = setmetatable({
__populate = populate, __populate = populate,
__inherit = inherit, __inherit = inherit,
__isComponent = true, __isComponent = true,
}, Component) }, Component)
component.__mt = {__index = component} component.__mt = {__index = component}
return component return component
end end
--- Creates and initializes a new Bag. --- Creates and initializes a new Bag.
-- @param ... The values passed to the populate function -- @param ... The values passed to the populate function
-- @return A new initialized Bag -- @return A new initialized Bag
function Component:__initialize(...) function Component:__initialize(...)
if self.__populate then if self.__populate then
local bag = setmetatable({}, self.__mt) local bag = setmetatable({}, self.__mt)
self.__populate(bag, ...) self.__populate(bag, ...)
return bag return bag
end end
return true return true
end end
return setmetatable(Component, { return setmetatable(Component, {
__call = function(_, ...) return Component.new(...) end, __call = function(_, ...) return Component.new(...) end,
}) })

View file

@ -1,46 +0,0 @@
local PATH = (...):gsub('%.init$', '')
local Type = require(PATH..".type")
local Concord = {}
--- Initializes the library with some optional settings
-- @param settings Table of settings: {
-- useEvents Flag to overwrite love.run and use events. Defaults to false
-- }
-- @return Concord
function Concord.init(settings)
Concord.entity = require(PATH..".entity")
Concord.component = require(PATH..".component")
Concord.system = require(PATH..".system")
Concord.instance = require(PATH..".instance")
if settings and settings.useEvents then
Concord.instances = {}
Concord.addInstance = function(instance)
if not Type.isInstance(instance) then
error("bad argument #1 to 'Concord.addInstance' (Instance expected, got "..type(instance)..")", 2)
end
table.insert(Concord.instances, instance)
end
Concord.removeInstance = function(instance)
if not Type.isInstance(instance) then
error("bad argument #1 to 'Concord.addInstance' (Instance expected, got "..type(instance)..")", 2)
end
for i, instance in ipairs(Concord.instances) do
table.remove(Concord.instances, i)
break
end
end
love.run = require(PATH..".run")
end
return Concord
end
return Concord

View file

@ -1,99 +1,99 @@
local PATH = (...):gsub('%.[^%.]+$', '') local PATH = (...):gsub('%.[^%.]+$', '')
local Type = require(PATH..".type") local Type = require(PATH..".type")
local List = require(PATH..".list") local List = require(PATH..".list")
local Entity = {} local Entity = {}
Entity.__index = Entity Entity.__index = Entity
--- Creates and initializes a new Entity. --- Creates and initializes a new Entity.
-- @return A new Entity -- @return A new Entity
function Entity.new() function Entity.new()
local e = setmetatable({ local e = setmetatable({
components = {}, components = {},
removed = {}, removed = {},
instances = List(), instances = List(),
__isEntity = true, __isEntity = true,
}, Entity) }, Entity)
return e return e
end end
--- Gives an Entity a component with values. --- Gives an Entity a component with values.
-- @param component The Component to add -- @param component The Component to add
-- @param ... The values passed to the Component -- @param ... The values passed to the Component
-- @return self -- @return self
function Entity:give(component, ...) function Entity:give(component, ...)
if not Type.isComponent(component) then if not Type.isComponent(component) then
error("bad argument #1 to 'Entity:give' (Component expected, got "..type(component)..")", 2) error("bad argument #1 to 'Entity:give' (Component expected, got "..type(component)..")", 2)
end end
self.components[component] = component:__initialize(...) self.components[component] = component:__initialize(...)
return self return self
end end
--- Removes a component from an Entity. --- Removes a component from an Entity.
-- @param component The Component to remove -- @param component The Component to remove
-- @return self -- @return self
function Entity:remove(component) function Entity:remove(component)
if not Type.isComponent(component) then if not Type.isComponent(component) then
error("bad argument #1 to 'Entity:remove' (Component expected, got "..type(component)..")") error("bad argument #1 to 'Entity:remove' (Component expected, got "..type(component)..")")
end end
self.removed[component] = true self.removed[component] = true
return self return self
end end
--- Checks the Entity against the pools again. --- Checks the Entity against the pools again.
-- @return self -- @return self
function Entity:apply() function Entity:apply()
for i = 1, self.instances.size do for i = 1, self.instances.size do
self.instances:get(i):checkEntity(self) self.instances:get(i):checkEntity(self)
end end
for component, _ in pairs(self.removed) do for component, _ in pairs(self.removed) do
self.components[component] = nil self.components[component] = nil
self.removed[component] = nil self.removed[component] = nil
end end
return self return self
end end
--- Destroys the Entity. --- Destroys the Entity.
-- @return self -- @return self
function Entity:destroy() function Entity:destroy()
for i = 1, self.instances.size do for i = 1, self.instances.size do
self.instances:get(i):removeEntity(self) self.instances:get(i):removeEntity(self)
end end
return self return self
end end
--- Gets a Component from the Entity. --- Gets a Component from the Entity.
-- @param component The Component to get -- @param component The Component to get
-- @return The Bag from the Component -- @return The Bag from the Component
function Entity:get(component) function Entity:get(component)
if not Type.isComponent(component) then if not Type.isComponent(component) then
error("bad argument #1 to 'Entity:get' (Component expected, got "..type(component)..")") error("bad argument #1 to 'Entity:get' (Component expected, got "..type(component)..")")
end end
return self.components[component] return self.components[component]
end end
--- Returns true if the Entity has the Component. --- Returns true if the Entity has the Component.
-- @params component The Component to check against -- @params component The Component to check against
-- @return True if the entity has the Bag. False otherwise -- @return True if the entity has the Bag. False otherwise
function Entity:has(component) function Entity:has(component)
if not Type.isComponent(component) then if not Type.isComponent(component) then
error("bad argument #1 to 'Entity:has' (Component expected, got "..type(component)..")") error("bad argument #1 to 'Entity:has' (Component expected, got "..type(component)..")")
end end
return self.components[component] ~= nil return self.components[component] ~= nil
end end
return setmetatable(Entity, { return setmetatable(Entity, {
__call = function(_, ...) return Entity.new(...) end, __call = function(_, ...) return Entity.new(...) end,
}) })

View file

@ -1,3 +1,46 @@
local PATH = (...):gsub('%.init$', '') local PATH = (...):gsub('%.init$', '')
return require(PATH..".concord") local Type = require(PATH..".type")
local Concord = {}
--- Initializes the library with some optional settings
-- @param settings Table of settings: {
-- useEvents Flag to overwrite love.run and use events. Defaults to false
-- }
-- @return Concord
function Concord.init(settings)
Concord.entity = require(PATH..".entity")
Concord.component = require(PATH..".component")
Concord.system = require(PATH..".system")
Concord.instance = require(PATH..".instance")
if settings and settings.useEvents then
Concord.instances = {}
Concord.addInstance = function(instance)
if not Type.isInstance(instance) then
error("bad argument #1 to 'Concord.addInstance' (Instance expected, got "..type(instance)..")", 2)
end
table.insert(Concord.instances, instance)
end
Concord.removeInstance = function(instance)
if not Type.isInstance(instance) then
error("bad argument #1 to 'Concord.addInstance' (Instance expected, got "..type(instance)..")", 2)
end
for i, instance in ipairs(Concord.instances) do
table.remove(Concord.instances, i)
break
end
end
love.run = require(PATH..".run")
end
return Concord
end
return Concord

View file

@ -1,209 +1,209 @@
local PATH = (...):gsub('%.[^%.]+$', '') local PATH = (...):gsub('%.[^%.]+$', '')
local Entity = require(PATH..".entity") local Entity = require(PATH..".entity")
local System = require(PATH..".system") local System = require(PATH..".system")
local Type = require(PATH..".type") local Type = require(PATH..".type")
local List = require(PATH..".list") local List = require(PATH..".list")
local Instance = {} local Instance = {}
Instance.__index = Instance Instance.__index = Instance
--- Creates a new Instance. --- Creates a new Instance.
-- @return The new instance -- @return The new instance
function Instance.new() function Instance.new()
local instance = setmetatable({ local instance = setmetatable({
entities = List(), entities = List(),
systems = List(), systems = List(),
events = {}, events = {},
removed = {}, removed = {},
__isInstance = true, __isInstance = true,
}, Instance) }, Instance)
return instance return instance
end end
--- Adds an Entity to the Instance. --- Adds an Entity to the Instance.
-- @param e The Entity to add -- @param e The Entity to add
-- @return self -- @return self
function Instance:addEntity(e) function Instance:addEntity(e)
if not Type.isEntity(e) then if not Type.isEntity(e) then
error("bad argument #1 to 'Instance:addEntity' (Entity expected, got "..type(e)..")", 2) error("bad argument #1 to 'Instance:addEntity' (Entity expected, got "..type(e)..")", 2)
end end
e.instances:add(self) e.instances:add(self)
self.entities:add(e) self.entities:add(e)
self:checkEntity(e) self:checkEntity(e)
return self return self
end end
--- Checks an Entity against all the systems in the Instance. --- Checks an Entity against all the systems in the Instance.
-- @param e The Entity to check -- @param e The Entity to check
-- @return self -- @return self
function Instance:checkEntity(e) function Instance:checkEntity(e)
if not Type.isEntity(e) then if not Type.isEntity(e) then
error("bad argument #1 to 'Instance:checkEntity' (Entity expected, got "..type(e)..")", 2) error("bad argument #1 to 'Instance:checkEntity' (Entity expected, got "..type(e)..")", 2)
end end
for i = 1, self.systems.size do for i = 1, self.systems.size do
self.systems:get(i):__check(e) self.systems:get(i):__check(e)
end end
return self return self
end end
--- Marks an Entity as removed from the Instance. --- Marks an Entity as removed from the Instance.
-- @param e The Entity to mark -- @param e The Entity to mark
-- @return self -- @return self
function Instance:removeEntity(e) function Instance:removeEntity(e)
if not Type.isEntity(e) then if not Type.isEntity(e) then
error("bad argument #1 to 'Instance:removeEntity' (Entity expected, got "..type(e)..")", 2) error("bad argument #1 to 'Instance:removeEntity' (Entity expected, got "..type(e)..")", 2)
end end
self.removed[#self.removed + 1] = e self.removed[#self.removed + 1] = e
return self return self
end end
--- Completely removes all marked Entities in the Instance. --- Completely removes all marked Entities in the Instance.
-- @return self -- @return self
function Instance:flush() function Instance:flush()
if #self.removed > 0 then if #self.removed > 0 then
for i = 1, #self.removed do for i = 1, #self.removed do
local e = self.removed[i] local e = self.removed[i]
e.instances:remove(self) e.instances:remove(self)
self.entities:remove(e) self.entities:remove(e)
for i = 1, self.systems.size do for i = 1, self.systems.size do
self.systems:get(i):__remove(e) self.systems:get(i):__remove(e)
end end
end end
self.removed = {} self.removed = {}
end end
return self return self
end end
--- Adds a System to the Instance. --- Adds a System to the Instance.
-- @param system The System to add -- @param system The System to add
-- @param eventName The Event to register to -- @param eventName The Event to register to
-- @param callback The function name to call. Defaults to eventName -- @param callback The function name to call. Defaults to eventName
-- @param enabled If the system is enabled. Defaults to true -- @param enabled If the system is enabled. Defaults to true
-- @return self -- @return self
function Instance:addSystem(system, eventName, callback, enabled) function Instance:addSystem(system, eventName, callback, enabled)
if not Type.isSystem(system) then if not Type.isSystem(system) then
error("bad argument #1 to 'Instance:addSystem' (System expected, got "..type(system)..")", 2) error("bad argument #1 to 'Instance:addSystem' (System expected, got "..type(system)..")", 2)
end end
if system.__instance and system.__instance ~= self then if system.__instance and system.__instance ~= self then
error("System already in instance '" ..tostring(system.__instance).."'") error("System already in instance '" ..tostring(system.__instance).."'")
end end
if not self.systems:has(system) then if not self.systems:has(system) then
self.systems:add(system) self.systems:add(system)
system.__instance = self system.__instance = self
end end
if eventName then if eventName then
self.events[eventName] = self.events[eventName] or {} self.events[eventName] = self.events[eventName] or {}
local i = #self.events[eventName] + 1 local i = #self.events[eventName] + 1
self.events[eventName][i] = { self.events[eventName][i] = {
system = system, system = system,
callback = callback or eventName, callback = callback or eventName,
enabled = enabled == nil and true or enabled, enabled = enabled == nil and true or enabled,
} }
end end
return self return self
end end
--- Enables a System in the Instance. --- Enables a System in the Instance.
-- @param system The System to enable -- @param system The System to enable
-- @param eventName The Event it was registered to -- @param eventName The Event it was registered to
-- @param callback The callback it was registered with. Defaults to eventName -- @param callback The callback it was registered with. Defaults to eventName
-- @return self -- @return self
function Instance:enableSystem(system, eventName, callback) function Instance:enableSystem(system, eventName, callback)
if not Type.isSystem(system) then if not Type.isSystem(system) then
error("bad argument #1 to 'Instance:enableSystem' (System expected, got "..type(system)..")", 2) error("bad argument #1 to 'Instance:enableSystem' (System expected, got "..type(system)..")", 2)
end end
return self:setSystem(system, eventName, callback, true) return self:setSystem(system, eventName, callback, true)
end end
--- Disables a System in the Instance. --- Disables a System in the Instance.
-- @param system The System to disable -- @param system The System to disable
-- @param eventName The Event it was registered to -- @param eventName The Event it was registered to
-- @param callback The callback it was registered with. Defaults to eventName -- @param callback The callback it was registered with. Defaults to eventName
-- @return self -- @return self
function Instance:disableSystem(system, eventName, callback) function Instance:disableSystem(system, eventName, callback)
if not Type.isSystem(system) then if not Type.isSystem(system) then
error("bad argument #1 to 'Instance:disableSystem' (System expected, got "..type(system)..")", 2) error("bad argument #1 to 'Instance:disableSystem' (System expected, got "..type(system)..")", 2)
end end
return self:setSystem(system, eventName, callback, false) return self:setSystem(system, eventName, callback, false)
end end
--- Sets a System 'enable' in the Instance. --- Sets a System 'enable' in the Instance.
-- @param system The System to set -- @param system The System to set
-- @param eventName The Event it was registered to -- @param eventName The Event it was registered to
-- @param callback The callback it was registered with. Defaults to eventName -- @param callback The callback it was registered with. Defaults to eventName
-- @param enable The state to set it to -- @param enable The state to set it to
-- @return self -- @return self
function Instance:setSystem(system, eventName, callback, enable) function Instance:setSystem(system, eventName, callback, enable)
if not Type.isSystem(system) then if not Type.isSystem(system) then
error("bad argument #1 to 'Instance:setSystem' (System expected, got "..type(system)..")", 2) error("bad argument #1 to 'Instance:setSystem' (System expected, got "..type(system)..")", 2)
end end
callback = callback or eventName callback = callback or eventName
if callback then if callback then
local listeners = self.events[eventName] local listeners = self.events[eventName]
if listeners then if listeners then
for i = 1, #listeners do for i = 1, #listeners do
local listener = listeners[i] local listener = listeners[i]
if listener.system == system and listener.callback == callback then if listener.system == system and listener.callback == callback then
listener.enabled = enable listener.enabled = enable
break break
end end
end end
end end
end end
return self return self
end end
--- Emits an Event in the Instance. --- Emits an Event in the Instance.
-- @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
-- @return self -- @return self
function Instance:emit(eventName, ...) function Instance:emit(eventName, ...)
if not eventName or type(eventName) ~= "string" then if not eventName or type(eventName) ~= "string" then
error("bad argument #1 to 'Instance:emit' (String expected, got "..type(eventName)..")") error("bad argument #1 to 'Instance:emit' (String expected, got "..type(eventName)..")")
end end
self:flush() self:flush()
local listeners = self.events[eventName] local listeners = self.events[eventName]
if listeners then if listeners then
for i = 1, #listeners do for i = 1, #listeners do
local listener = listeners[i] local listener = listeners[i]
if listener.enabled then if listener.enabled then
listener.system[listener.callback](listener.system, ...) listener.system[listener.callback](listener.system, ...)
end end
end end
end end
return self return self
end end
return setmetatable(Instance, { return setmetatable(Instance, {
__call = function(_, ...) return Instance.new(...) end, __call = function(_, ...) return Instance.new(...) end,
}) })

View file

@ -1,75 +1,75 @@
local List = {} local List = {}
local mt = {__index = List} local mt = {__index = List}
--- Creates a new List. --- Creates a new List.
-- @return A new list -- @return A new list
function List.new() function List.new()
return setmetatable({ return setmetatable({
objects = {}, objects = {},
pointers = {}, pointers = {},
size = 0, size = 0,
}, mt) }, mt)
end end
--- Clears the List completely. --- Clears the List completely.
-- @return self -- @return self
function List:clear() function List:clear()
self.objects = {} self.objects = {}
self.pointers = {} self.pointers = {}
self.size = 0 self.size = 0
return self return self
end end
--- Adds an object to the List. --- Adds an object to the List.
-- @param obj The object to add -- @param obj The object to add
-- @return self -- @return self
function List:add(obj) function List:add(obj)
local size = self.size + 1 local size = self.size + 1
self.objects[size] = obj self.objects[size] = obj
self.pointers[obj] = size self.pointers[obj] = size
self.size = size self.size = size
return self return self
end end
--- Removes an object from the List. --- Removes an object from the List.
-- @param obj The object to remove -- @param obj The object to remove
-- @return self -- @return self
function List:remove(obj) function List:remove(obj)
local index = self.pointers[obj] local index = self.pointers[obj]
local size = self.size local size = self.size
if index == size then if index == size then
self.objects[size] = nil self.objects[size] = nil
else else
local other = self.objects[size] local other = self.objects[size]
self.objects[index] = other self.objects[index] = other
self.pointers[other] = index self.pointers[other] = index
self.objects[size] = nil self.objects[size] = nil
end end
self.pointers[obj] = nil self.pointers[obj] = nil
self.size = size - 1 self.size = size - 1
end end
--- Gets an object by numerical index. --- Gets an object by numerical index.
-- @param index The index to look at -- @param index The index to look at
-- @return The object at the index -- @return The object at the index
function List:get(index) function List:get(index)
return self.objects[index] return self.objects[index]
end end
--- Gets if the List has the object. --- Gets if the List has the object.
-- @param obj The object to search for -- @param obj The object to search for
-- @param true if the list has the object, false otherwise -- @param true if the list has the object, false otherwise
function List:has(obj) function List:has(obj)
return self.pointers[obj] and true return self.pointers[obj] and true
end end
return setmetatable(List, { return setmetatable(List, {
__call = function() return List.new() end, __call = function() return List.new() end,
}) })

View file

@ -1,39 +1,39 @@
local PATH = (...):gsub('%.[^%.]+$', '') local PATH = (...):gsub('%.[^%.]+$', '')
local List = require(PATH..".list") local List = require(PATH..".list")
local Pool = {} local Pool = {}
Pool.__index = Pool Pool.__index = Pool
--- Creates a new Pool --- Creates a new Pool
-- @param name Identifier for the Pool. -- @param name Identifier for the Pool.
-- @param filter Table containing the required Components -- @param filter Table containing the required Components
-- @return The new Pool -- @return The new Pool
function Pool.new(name, filter) function Pool.new(name, filter)
local pool = setmetatable(List(), Pool) local pool = setmetatable(List(), Pool)
pool.name = name pool.name = name
pool.filter = filter pool.filter = filter
pool.__isPool = true pool.__isPool = true
return pool return pool
end end
--- Checks if an Entity is eligible for the Pool. --- Checks if an Entity is eligible for the Pool.
-- @param e The Entity to check -- @param e The Entity to check
-- @return True if the entity is eligible, false otherwise -- @return True if the entity is eligible, false otherwise
function Pool:eligible(e) function Pool:eligible(e)
for _, component in ipairs(self.filter) do for _, component in ipairs(self.filter) do
if not e.components[component] or e.removed[component] then if not e.components[component] or e.removed[component] then
return false return false
end end
end end
return true return true
end end
return setmetatable(Pool, { return setmetatable(Pool, {
__index = List, __index = List,
__call = function(_, ...) return Pool.new(...) end, __call = function(_, ...) return Pool.new(...) end,
}) })

View file

@ -1,171 +1,171 @@
local PATH = (...):gsub('%.[^%.]+$', '') local PATH = (...):gsub('%.[^%.]+$', '')
local Component = require(PATH..".component") local Component = require(PATH..".component")
local Pool = require(PATH..".pool") local Pool = require(PATH..".pool")
local System = {} local System = {}
System.mt = { System.mt = {
__index = System, __index = System,
__call = function(systemProto, ...) __call = function(systemProto, ...)
local system = setmetatable({ local system = setmetatable({
__all = {}, __all = {},
__pools = {}, __pools = {},
__instance = nil, __instance = nil,
__isSystem = true, __isSystem = true,
}, systemProto) }, systemProto)
for _, filter in pairs(systemProto.__filter) do for _, filter in pairs(systemProto.__filter) do
local pool = system:__buildPool(filter) local pool = system:__buildPool(filter)
if not system[pool.name] then if not system[pool.name] then
system[pool.name] = pool system[pool.name] = pool
system.__pools[#system.__pools + 1] = pool system.__pools[#system.__pools + 1] = pool
else else
error("Pool with name '"..pool.name.."' already exists.") error("Pool with name '"..pool.name.."' already exists.")
end end
end end
system:init(...) system:init(...)
return system return system
end, end,
} }
--- Creates a new System prototype. --- Creates a new System prototype.
-- @param ... Variable amounts of filters -- @param ... Variable amounts of filters
-- @return A new System prototype -- @return A new System prototype
function System.new(...) function System.new(...)
local systemProto = setmetatable({ local systemProto = setmetatable({
__filter = {...}, __filter = {...},
}, System.mt) }, System.mt)
systemProto.__index = systemProto systemProto.__index = systemProto
return systemProto return systemProto
end end
--- Default initialization function. --- Default initialization function.
-- @param ... Varags -- @param ... Varags
function System:init(...) function System:init(...)
end end
--- Builds a Pool for the System. --- Builds a Pool for the System.
-- @param baseFilter The 'raw' Filter -- @param baseFilter The 'raw' Filter
-- @return A new Pool -- @return A new Pool
function System:__buildPool(baseFilter) function System:__buildPool(baseFilter)
local name = "pool" local name = "pool"
local filter = {} local filter = {}
for i, v in ipairs(baseFilter) do for i, v in ipairs(baseFilter) do
if type(v) == "table" then if type(v) == "table" then
filter[#filter + 1] = v filter[#filter + 1] = v
elseif type(v) == "string" then elseif type(v) == "string" then
name = v name = v
end end
end end
return Pool(name, filter) return Pool(name, filter)
end end
--- Checks and applies an Entity to the System's pools. --- Checks and applies an Entity to the System's pools.
-- @param e The Entity to check -- @param e The Entity to check
-- @return True if the Entity was added, false if it was removed. Nil if nothing happend -- @return True if the Entity was added, false if it was removed. Nil if nothing happend
function System:__check(e) function System:__check(e)
local systemHas = self:__has(e) local systemHas = self:__has(e)
for _, pool in ipairs(self.__pools) do for _, pool in ipairs(self.__pools) do
local poolHas = pool:has(e) local poolHas = pool:has(e)
local eligible = pool:eligible(e) local eligible = pool:eligible(e)
if not poolHas and eligible then if not poolHas and eligible then
pool:add(e) pool:add(e)
self:entityAddedTo(e, pool) self:entityAddedTo(e, pool)
self:__tryAdd(e) self:__tryAdd(e)
return true return true
elseif poolHas and not eligible then elseif poolHas and not eligible then
pool:remove(e) pool:remove(e)
self:entityRemovedFrom(e, pool) self:entityRemovedFrom(e, pool)
self:__tryRemove(e) self:__tryRemove(e)
return false return false
end end
end end
end end
--- Removed an Entity from the System. --- Removed an Entity from the System.
-- @param e The Entity to remove -- @param e The Entity to remove
function System:__remove(e) function System:__remove(e)
if self:__has(e) then if self:__has(e) then
for _, pool in ipairs(self.__pools) do for _, pool in ipairs(self.__pools) do
if pool:has(e) then if pool:has(e) then
pool:remove(e) pool:remove(e)
self:entityRemovedFrom(e, pool) self:entityRemovedFrom(e, pool)
end end
end end
self.__all[e] = nil self.__all[e] = nil
self:entityRemoved(e) self:entityRemoved(e)
end end
end end
--- Tries to add an Entity to the System. --- Tries to add an Entity to the System.
-- @param e The Entity to add -- @param e The Entity to add
function System:__tryAdd(e) function System:__tryAdd(e)
if not self:__has(e) then if not self:__has(e) then
self.__all[e] = 0 self.__all[e] = 0
self:entityAdded(e) self:entityAdded(e)
end end
self.__all[e] = self.__all[e] + 1 self.__all[e] = self.__all[e] + 1
end end
--- Tries to remove an Entity from the System. --- Tries to remove an Entity from the System.
-- @param e The Entity to remove -- @param e The Entity to remove
function System:__tryRemove(e) function System:__tryRemove(e)
if self:__has(e) then if self:__has(e) then
self.__all[e] = self.__all[e] - 1 self.__all[e] = self.__all[e] - 1
if self.__all[e] == 0 then if self.__all[e] == 0 then
self.__all[e] = nil self.__all[e] = nil
self:entityRemoved(e) self:entityRemoved(e)
end end
end end
end end
--- Returns the Instance the System is in. --- Returns the Instance the System is in.
-- @return The Instance -- @return The Instance
function System:getInstance() function System:getInstance()
return self.__instance return self.__instance
end end
--- Returns if the System has the Entity. --- Returns if the System has the Entity.
-- @param The Entity to check for -- @param The Entity to check for
-- @return True if the System has the Entity. False otherwise -- @return True if the System has the Entity. False otherwise
function System:__has(e) function System:__has(e)
return self.__all[e] and true return self.__all[e] and true
end end
--- Default callback for adding an Entity. --- Default callback for adding an Entity.
-- @param e The Entity that was added -- @param e The Entity that was added
function System:entityAdded(e) function System:entityAdded(e)
end end
--- Default callback for adding an Entity to a pool. --- Default callback for adding an Entity to a pool.
-- @param e The Entity that was added -- @param e The Entity that was added
-- @param pool The pool the Entity was added to -- @param pool The pool the Entity was added to
function System:entityAddedTo(e, pool) function System:entityAddedTo(e, pool)
end end
--- Default callback for removing an Entity. --- Default callback for removing an Entity.
-- @param e The Entity that was removed -- @param e The Entity that was removed
function System:entityRemoved(e) function System:entityRemoved(e)
end end
--- Default callback for removing an Entity from a pool. --- Default callback for removing an Entity from a pool.
-- @param e The Entity that was removed -- @param e The Entity that was removed
-- @param pool The pool the Entity was removed from -- @param pool The pool the Entity was removed from
function System:entityRemovedFrom(e, pool) function System:entityRemovedFrom(e, pool)
end end
return setmetatable(System, { return setmetatable(System, {
__call = function(_, ...) return System.new(...) end, __call = function(_, ...) return System.new(...) end,
}) })