mirror of
https://github.com/Keyslam-Group/Concord.git
synced 2025-09-04 05:13:55 -04:00
Rename 'lib' directory to 'src'
This commit is contained in:
parent
39ec2106b7
commit
89a3a7fa8a
9 changed files with 0 additions and 0 deletions
26
src/assemblage.lua
Normal file
26
src/assemblage.lua
Normal file
|
@ -0,0 +1,26 @@
|
|||
--- Assemblage
|
||||
|
||||
local Assemblage = {}
|
||||
Assemblage.__index = Assemblage
|
||||
|
||||
function Assemblage.new(assemble)
|
||||
local assemblage = setmetatable({
|
||||
__assemble = assemble,
|
||||
|
||||
__isAssemblage = true,
|
||||
}, Assemblage)
|
||||
|
||||
return assemblage
|
||||
end
|
||||
|
||||
function Assemblage:assemble(e, ...)
|
||||
self.__assemble(e, ...)
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
return setmetatable(Assemblage, {
|
||||
__call = function(_, ...)
|
||||
return Assemblage.new(...)
|
||||
end,
|
||||
})
|
39
src/component.lua
Normal file
39
src/component.lua
Normal file
|
@ -0,0 +1,39 @@
|
|||
--- Component
|
||||
|
||||
local Component = {}
|
||||
Component.__index = Component
|
||||
|
||||
--- Creates a new Component.
|
||||
-- @param populate A function that populates the Bag with values
|
||||
-- @return A Component object
|
||||
function Component.new(populate)
|
||||
local component = setmetatable({
|
||||
__populate = populate,
|
||||
|
||||
__isComponent = true,
|
||||
}, Component)
|
||||
|
||||
component.__mt = {__index = component}
|
||||
|
||||
return component
|
||||
end
|
||||
|
||||
--- Creates and initializes a new Bag.
|
||||
-- @param ... The values passed to the populate function
|
||||
-- @return A new initialized Bag
|
||||
function Component:__initialize(...)
|
||||
if self.__populate then
|
||||
local bag = setmetatable({}, self.__mt)
|
||||
self.__populate(bag, ...)
|
||||
|
||||
return bag
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
return setmetatable(Component, {
|
||||
__call = function(_, ...)
|
||||
return Component.new(...)
|
||||
end,
|
||||
})
|
142
src/entity.lua
Normal file
142
src/entity.lua
Normal file
|
@ -0,0 +1,142 @@
|
|||
--- Entity
|
||||
|
||||
local PATH = (...):gsub('%.[^%.]+$', '')
|
||||
|
||||
local Type = require(PATH..".type")
|
||||
local List = require(PATH..".list")
|
||||
|
||||
local Entity = {}
|
||||
Entity.__index = Entity
|
||||
|
||||
--- Creates and initializes a new Entity.
|
||||
-- @return A new Entity
|
||||
function Entity.new()
|
||||
local e = setmetatable({
|
||||
removed = {},
|
||||
instances = List(),
|
||||
|
||||
__isEntity = true,
|
||||
}, Entity)
|
||||
|
||||
return e
|
||||
end
|
||||
|
||||
local function give(e, component, ...)
|
||||
local comp = component:__initialize(...)
|
||||
e[component] = comp
|
||||
|
||||
e:mark()
|
||||
end
|
||||
|
||||
--- Gives an Entity a component with values.
|
||||
-- @param component The Component to add
|
||||
-- @param ... The values passed to the Component
|
||||
-- @return self
|
||||
function Entity:give(component, ...)
|
||||
if not Type.isComponent(component) then
|
||||
error("bad argument #1 to 'Entity:give' (Component expected, got "..type(component)..")", 2)
|
||||
end
|
||||
|
||||
if self[component] then
|
||||
self:remove(component):apply()
|
||||
end
|
||||
|
||||
give(self, component, ...)
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
function Entity:ensure(component, ...)
|
||||
if not Type.isComponent(component) then
|
||||
error("bad argument #1 to 'Entity:ensure' (Component expected, got "..type(component)..")", 2)
|
||||
end
|
||||
|
||||
if self[component] then
|
||||
return self
|
||||
end
|
||||
|
||||
give(self, component, ...)
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- Removes a component from an Entity.
|
||||
-- @param component The Component to remove
|
||||
-- @return self
|
||||
function Entity:remove(component)
|
||||
if not Type.isComponent(component) then
|
||||
error("bad argument #1 to 'Entity:remove' (Component expected, got "..type(component)..")")
|
||||
end
|
||||
|
||||
self.removed[#self.removed + 1] = component
|
||||
|
||||
self:mark()
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
function Entity:assemble(assemblage, ...)
|
||||
if not Type.isAssemblage(assemblage) then
|
||||
error("bad argument #1 to 'Entity:assemble' (Assemblage expected, got "..type(assemblage)..")")
|
||||
end
|
||||
|
||||
assemblage:assemble(self, ...)
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
function Entity:mark()
|
||||
for i = 1, self.instances.size do
|
||||
self.instances:get(i):markEntity(self)
|
||||
end
|
||||
end
|
||||
|
||||
function Entity:apply()
|
||||
for i = 1, #self.removed do
|
||||
local component = self.removed[i]
|
||||
|
||||
self[component] = nil
|
||||
|
||||
self.removed[i] = nil
|
||||
end
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- Destroys the Entity.
|
||||
-- @return self
|
||||
function Entity:destroy()
|
||||
for i = 1, self.instances.size do
|
||||
self.instances:get(i):removeEntity(self)
|
||||
end
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- Gets a Component from the Entity.
|
||||
-- @param component The Component to get
|
||||
-- @return The Bag from the Component
|
||||
function Entity:get(component)
|
||||
if not Type.isComponent(component) then
|
||||
error("bad argument #1 to 'Entity:get' (Component expected, got "..type(component)..")")
|
||||
end
|
||||
|
||||
return self[component]
|
||||
end
|
||||
|
||||
--- Returns true if the Entity has the Component.
|
||||
-- @param component The Component to check against
|
||||
-- @return True if the entity has the Bag. False otherwise
|
||||
function Entity:has(component)
|
||||
if not Type.isComponent(component) then
|
||||
error("bad argument #1 to 'Entity:has' (Component expected, got "..type(component)..")")
|
||||
end
|
||||
|
||||
return self[component] ~= nil
|
||||
end
|
||||
|
||||
return setmetatable(Entity, {
|
||||
__call = function(_, ...)
|
||||
return Entity.new(...)
|
||||
end,
|
||||
})
|
40
src/init.lua
Normal file
40
src/init.lua
Normal file
|
@ -0,0 +1,40 @@
|
|||
--- init
|
||||
|
||||
local PATH = (...):gsub('%.init$', '')
|
||||
|
||||
local Concord = {
|
||||
_VERSION = "1.0",
|
||||
_DESCRIPTION = "A feature-complete ECS library",
|
||||
_LICENCE = [[
|
||||
MIT LICENSE
|
||||
|
||||
Copyright (c) 2018 Justin van der Leij / Tjakka5
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
]]
|
||||
}
|
||||
|
||||
Concord.entity = require(PATH..".entity")
|
||||
Concord.component = require(PATH..".component")
|
||||
Concord.system = require(PATH..".system")
|
||||
Concord.instance = require(PATH..".instance")
|
||||
Concord.assemblage = require(PATH..".assemblage")
|
||||
|
||||
return Concord
|
288
src/instance.lua
Normal file
288
src/instance.lua
Normal file
|
@ -0,0 +1,288 @@
|
|||
--- Instance
|
||||
|
||||
local PATH = (...):gsub('%.[^%.]+$', '')
|
||||
|
||||
local Type = require(PATH..".type")
|
||||
local List = require(PATH..".list")
|
||||
|
||||
local Instance = {}
|
||||
Instance.__index = Instance
|
||||
|
||||
--- Creates a new Instance.
|
||||
-- @return The new instance
|
||||
function Instance.new()
|
||||
local instance = setmetatable({
|
||||
entities = List(),
|
||||
systems = List(),
|
||||
events = {},
|
||||
|
||||
marked = {},
|
||||
removed = {},
|
||||
|
||||
__isInstance = true,
|
||||
}, Instance)
|
||||
|
||||
return instance
|
||||
end
|
||||
|
||||
--- Adds an Entity to the Instance.
|
||||
-- @param e The Entity to add
|
||||
-- @return self
|
||||
function Instance:addEntity(e)
|
||||
if not Type.isEntity(e) then
|
||||
error("bad argument #1 to 'Instance:addEntity' (Entity expected, got "..type(e)..")", 2)
|
||||
end
|
||||
|
||||
self:onEntityAdded(e)
|
||||
|
||||
e.instances:add(self)
|
||||
self.entities:add(e)
|
||||
self:checkEntity(e)
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- Marks an Entity as removed from the Instance.
|
||||
-- @param e The Entity to mark
|
||||
-- @return self
|
||||
function Instance:removeEntity(e)
|
||||
if not Type.isEntity(e) then
|
||||
error("bad argument #1 to 'Instance:removeEntity' (Entity expected, got "..type(e)..")", 2)
|
||||
end
|
||||
|
||||
self.removed[#self.removed + 1] = e
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
function Instance:markEntity(e)
|
||||
if not Type.isEntity(e) then
|
||||
error("bad argument #1 to 'Instance:markEntity' (Entity expected, got "..type(e)..")", 2)
|
||||
end
|
||||
|
||||
self.marked[#self.marked + 1] = e
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- Checks an Entity against all the systems in the Instance.
|
||||
-- @param e The Entity to check
|
||||
-- @return self
|
||||
function Instance:checkEntity(e)
|
||||
if not Type.isEntity(e) then
|
||||
error("bad argument #1 to 'Instance:checkEntity' (Entity expected, got "..type(e)..")", 2)
|
||||
end
|
||||
|
||||
for i = 1, self.systems.size do
|
||||
self.systems:get(i):__check(e)
|
||||
end
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- Completely removes all marked Entities in the Instance.
|
||||
-- @return self
|
||||
function Instance:flush()
|
||||
while #self.marked > 0 do
|
||||
local marked = self.removed
|
||||
self.removed = {}
|
||||
|
||||
for i = 1, #marked do
|
||||
local e = marked[i]
|
||||
|
||||
e.instances:apply()
|
||||
e.instances:checkEntity(e)
|
||||
end
|
||||
end
|
||||
|
||||
while #self.removed > 0 do
|
||||
local removed = self.removed
|
||||
self.removed = {}
|
||||
|
||||
for i = 1, #removed do
|
||||
local e = removed[i]
|
||||
|
||||
e.instances:remove(self)
|
||||
self.entities:remove(e)
|
||||
|
||||
for j = 1, self.systems.size do
|
||||
self.systems:get(j):__remove(e)
|
||||
end
|
||||
|
||||
self:onEntityRemoved(e)
|
||||
end
|
||||
end
|
||||
|
||||
for i = 1, self.systems.size do
|
||||
local system = self.systems:get(i)
|
||||
system:flush()
|
||||
system:clear()
|
||||
end
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- Adds a System to the Instance.
|
||||
-- @param system The System to add
|
||||
-- @param eventName The Event to register to
|
||||
-- @param callback The function name to call. Defaults to eventName
|
||||
-- @param enabled If the system is enabled. Defaults to true
|
||||
-- @return self
|
||||
function Instance:addSystem(system, eventName, callback, enabled)
|
||||
if not Type.isSystem(system) then
|
||||
error("bad argument #1 to 'Instance:addSystem' (System expected, got "..type(system)..")", 2)
|
||||
end
|
||||
|
||||
if system.__instance and system.__instance ~= self then
|
||||
error("System already in instance '" ..tostring(system.__instance).."'")
|
||||
end
|
||||
|
||||
if not self.systems:has(system) then
|
||||
self.systems:add(system)
|
||||
system.__instance = self
|
||||
|
||||
system:addedTo(self)
|
||||
end
|
||||
|
||||
if eventName then
|
||||
self.events[eventName] = self.events[eventName] or {}
|
||||
|
||||
local i = #self.events[eventName] + 1
|
||||
self.events[eventName][i] = {
|
||||
system = system,
|
||||
callback = callback or eventName,
|
||||
enabled = enabled == nil or enabled,
|
||||
}
|
||||
|
||||
if enabled == nil or enabled then
|
||||
system:enabledCallback(callback or eventName)
|
||||
end
|
||||
end
|
||||
|
||||
local e
|
||||
for i = 1, self.entities.size do
|
||||
e = self.entities:get(i)
|
||||
|
||||
self:checkEntity(e)
|
||||
end
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- Enables a System in the Instance.
|
||||
-- @param system The System to enable
|
||||
-- @param eventName The Event it was registered to
|
||||
-- @param callback The callback it was registered with. Defaults to eventName
|
||||
-- @return self
|
||||
function Instance:enableSystem(system, eventName, callback)
|
||||
if not Type.isSystem(system) then
|
||||
error("bad argument #1 to 'Instance:enableSystem' (System expected, got "..type(system)..")", 2)
|
||||
end
|
||||
|
||||
return self:setSystem(system, eventName, callback, true)
|
||||
end
|
||||
|
||||
--- Disables a System in the Instance.
|
||||
-- @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 Instance:disableSystem(system, eventName, callback)
|
||||
if not Type.isSystem(system) then
|
||||
error("bad argument #1 to 'Instance:disableSystem' (System expected, got "..type(system)..")", 2)
|
||||
end
|
||||
|
||||
return self:setSystem(system, eventName, callback, false)
|
||||
end
|
||||
|
||||
--- Sets a System 'enable' in the Instance.
|
||||
-- @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 Instance:setSystem(system, eventName, callback, enable)
|
||||
if not Type.isSystem(system) then
|
||||
error("bad argument #1 to 'Instance:setSystem' (System expected, got "..type(system)..")", 2)
|
||||
end
|
||||
|
||||
callback = callback or eventName
|
||||
|
||||
if callback then
|
||||
local listeners = self.events[eventName]
|
||||
|
||||
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 Instance.
|
||||
-- @param eventName The Event that should be emitted
|
||||
-- @param ... Parameters passed to listeners
|
||||
-- @return self
|
||||
function Instance:emit(eventName, ...)
|
||||
if not eventName or type(eventName) ~= "string" then
|
||||
error("bad argument #1 to 'Instance:emit' (String expected, got "..type(eventName)..")")
|
||||
end
|
||||
|
||||
self:flush()
|
||||
|
||||
local listeners = self.events[eventName]
|
||||
|
||||
if listeners then
|
||||
for i = 1, #listeners do
|
||||
local listener = listeners[i]
|
||||
|
||||
if listener.enabled then
|
||||
listener.system[listener.callback](listener.system, ...)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- Removes all entities from the Instance
|
||||
-- @return self
|
||||
function Instance:clear()
|
||||
for i = 1, self.entities.size do
|
||||
self.entities:get(i):destroy()
|
||||
end
|
||||
|
||||
self:flush()
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- Default callback for adding an Entity.
|
||||
-- @param e The Entity that was added
|
||||
function Instance:onEntityAdded(e) -- luacheck: ignore
|
||||
end
|
||||
|
||||
--- Default callback for removing an Entity.
|
||||
-- @param e The Entity that was removed
|
||||
function Instance:onEntityRemoved(e) -- luacheck: ignore
|
||||
end
|
||||
|
||||
return setmetatable(Instance, {
|
||||
__call = function(_, ...)
|
||||
return Instance.new(...)
|
||||
end,
|
||||
})
|
83
src/list.lua
Normal file
83
src/list.lua
Normal file
|
@ -0,0 +1,83 @@
|
|||
--- List
|
||||
|
||||
local List = {}
|
||||
local mt = {__index = List}
|
||||
|
||||
--- Creates a new List.
|
||||
-- @return A new list
|
||||
function List.new()
|
||||
return setmetatable({
|
||||
size = 0,
|
||||
}, mt)
|
||||
end
|
||||
|
||||
--- Clears the List completely.
|
||||
-- @return self
|
||||
function List:clear()
|
||||
for i = 1, self.size do
|
||||
local o = self[i]
|
||||
|
||||
self[o] = nil
|
||||
self[i] = nil
|
||||
end
|
||||
|
||||
self.size = 0
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- Adds an object to the List.
|
||||
-- @param obj The object to add
|
||||
-- @return self
|
||||
function List:add(obj) -- obj can not be a number and also not the string "size"
|
||||
local size = self.size + 1
|
||||
|
||||
self[size] = obj
|
||||
self[obj] = size
|
||||
self.size = size
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- Removes an object from the List.
|
||||
-- @param obj The object to remove
|
||||
-- @return self
|
||||
function List:remove(obj)
|
||||
local index = self[obj]
|
||||
if not index then return end
|
||||
local size = self.size
|
||||
|
||||
if index == size then
|
||||
self[size] = nil
|
||||
else
|
||||
local other = self[size]
|
||||
|
||||
self[index] = other
|
||||
self[other] = index
|
||||
|
||||
self[size] = nil
|
||||
end
|
||||
|
||||
self[obj] = nil
|
||||
self.size = size - 1
|
||||
end
|
||||
|
||||
--- Gets an object by numerical index.
|
||||
-- @param index The index to look at
|
||||
-- @return The object at the index
|
||||
function List:get(index)
|
||||
return self[index]
|
||||
end
|
||||
|
||||
--- Gets if the List has the object.
|
||||
-- @param obj The object to search for
|
||||
-- true if the list has the object, false otherwise
|
||||
function List:has(obj)
|
||||
return self[obj] and true
|
||||
end
|
||||
|
||||
return setmetatable(List, {
|
||||
__call = function()
|
||||
return List.new()
|
||||
end,
|
||||
})
|
52
src/pool.lua
Normal file
52
src/pool.lua
Normal file
|
@ -0,0 +1,52 @@
|
|||
--- Pool
|
||||
|
||||
local PATH = (...):gsub('%.[^%.]+$', '')
|
||||
|
||||
local List = require(PATH..".list")
|
||||
|
||||
local Pool = {}
|
||||
Pool.__index = Pool
|
||||
|
||||
--- Creates a new Pool
|
||||
-- @param name Identifier for the Pool.
|
||||
-- @param filter Table containing the required Components
|
||||
-- @return The new Pool
|
||||
function Pool.new(name, filter)
|
||||
local pool = setmetatable(List(), Pool)
|
||||
|
||||
pool.added = {}
|
||||
pool.removed = {}
|
||||
|
||||
pool.name = name
|
||||
pool.filter = filter
|
||||
|
||||
pool.__isPool = true
|
||||
|
||||
return pool
|
||||
end
|
||||
|
||||
function Pool:flush()
|
||||
for i = 1, math.max(#self.added, #self.removed) do
|
||||
self.added[i], self.removed[i] = nil, nil
|
||||
end
|
||||
end
|
||||
|
||||
--- Checks if an Entity is eligible for the Pool.
|
||||
-- @param e The Entity to check
|
||||
-- @return True if the entity is eligible, false otherwise
|
||||
function Pool:eligible(e)
|
||||
for _, component in ipairs(self.filter) do
|
||||
if not e[component] or e.removed[component] then
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
return setmetatable(Pool, {
|
||||
__index = List,
|
||||
__call = function(_, ...)
|
||||
return Pool.new(...)
|
||||
end,
|
||||
})
|
162
src/system.lua
Normal file
162
src/system.lua
Normal file
|
@ -0,0 +1,162 @@
|
|||
--- System
|
||||
|
||||
local PATH = (...):gsub('%.[^%.]+$', '')
|
||||
|
||||
local Pool = require(PATH..".pool")
|
||||
|
||||
local System = {}
|
||||
System.mt = {
|
||||
__index = System,
|
||||
__call = function(systemProto, ...)
|
||||
local system = setmetatable({
|
||||
__all = {},
|
||||
__pools = {},
|
||||
__instance = nil,
|
||||
|
||||
__isSystem = true,
|
||||
}, systemProto)
|
||||
|
||||
for _, filter in pairs(systemProto.__filter) do
|
||||
local pool = system:__buildPool(filter)
|
||||
if not system[pool.name] then
|
||||
system[pool.name] = pool
|
||||
system.__pools[#system.__pools + 1] = pool
|
||||
else
|
||||
error("Pool with name '"..pool.name.."' already exists.")
|
||||
end
|
||||
end
|
||||
|
||||
system:init(...)
|
||||
return system
|
||||
end,
|
||||
}
|
||||
|
||||
--- Creates a new System prototype.
|
||||
-- @param ... Variable amounts of filters
|
||||
-- @return A new System prototype
|
||||
function System.new(...)
|
||||
local systemProto = setmetatable({
|
||||
__filter = {...},
|
||||
}, System.mt)
|
||||
systemProto.__index = systemProto
|
||||
|
||||
return systemProto
|
||||
end
|
||||
|
||||
--- Builds a Pool for the System.
|
||||
-- @param baseFilter The 'raw' Filter
|
||||
-- @return A new Pool
|
||||
function System:__buildPool(baseFilter) -- luacheck: ignore
|
||||
local name = "pool"
|
||||
local filter = {}
|
||||
|
||||
for _, v in ipairs(baseFilter) do
|
||||
if type(v) == "table" then
|
||||
filter[#filter + 1] = v
|
||||
elseif type(v) == "string" then
|
||||
name = v
|
||||
end
|
||||
end
|
||||
|
||||
return Pool(name, filter)
|
||||
end
|
||||
|
||||
--- Checks and applies an Entity to the System's pools.
|
||||
-- @param e The Entity to check
|
||||
-- @return True if the Entity was added, false if it was removed. Nil if nothing happend
|
||||
function System:__check(e)
|
||||
for _, pool in ipairs(self.__pools) do
|
||||
local poolHas = pool:has(e)
|
||||
local eligible = pool:eligible(e)
|
||||
|
||||
if not poolHas and eligible then
|
||||
pool:add(e)
|
||||
pool.added[#pool.added + 1] = e
|
||||
|
||||
self:__tryAdd(e)
|
||||
elseif poolHas and not eligible then
|
||||
pool:remove(e)
|
||||
pool.removed[#pool.removed + 1] = e
|
||||
|
||||
self:__tryRemove(e)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--- Remove an Entity from the System.
|
||||
-- @param e The Entity to remove
|
||||
function System:__remove(e)
|
||||
if self.__all[e] then
|
||||
for _, pool in ipairs(self.__pools) do
|
||||
if pool:has(e) then
|
||||
pool:remove(e)
|
||||
pool.removed[#pool.removed + 1] = e
|
||||
end
|
||||
end
|
||||
|
||||
self.__all[e] = nil
|
||||
end
|
||||
end
|
||||
|
||||
--- Tries to add an Entity to the System.
|
||||
-- @param e The Entity to add
|
||||
function System:__tryAdd(e)
|
||||
if not self.__all[e] then
|
||||
self.__all[e] = 0
|
||||
end
|
||||
|
||||
self.__all[e] = self.__all[e] + 1
|
||||
end
|
||||
|
||||
--- Tries to remove an Entity from the System.
|
||||
-- @param e The Entity to remove
|
||||
function System:__tryRemove(e)
|
||||
if self.__all[e] then
|
||||
self.__all[e] = self.__all[e] - 1
|
||||
|
||||
if self.__all[e] == 0 then
|
||||
self.__all[e] = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function System:flush() -- luacheck: ignore
|
||||
end
|
||||
|
||||
function System:clear()
|
||||
for i = 1, #self.__pools do
|
||||
self.__pools[i]:flush()
|
||||
end
|
||||
end
|
||||
|
||||
--- Returns the Instance the System is in.
|
||||
-- @return The Instance
|
||||
function System:getInstance()
|
||||
return self.__instance
|
||||
end
|
||||
|
||||
--- Default callback for system initialization.
|
||||
-- @param ... Varags
|
||||
function System:init(...) -- luacheck: ignore
|
||||
end
|
||||
|
||||
-- Default callback for when the System is added to an Instance.
|
||||
-- @param instance The Instance the System was added to
|
||||
function System:addedTo(instance) -- luacheck: ignore
|
||||
end
|
||||
|
||||
-- Default callback for when a System's callback is enabled.
|
||||
-- @param callbackName The name of the callback that was enabled
|
||||
function System:enabledCallback(callbackName) -- luacheck: ignore
|
||||
end
|
||||
|
||||
-- Default callback for when a System's callback is disabled.
|
||||
-- @param callbackName The name of the callback that was disabled
|
||||
function System:disabledCallback(callbackName) -- luacheck: ignore
|
||||
end
|
||||
|
||||
return setmetatable(System, {
|
||||
__call = function(_, ...)
|
||||
return System.new(...)
|
||||
end,
|
||||
})
|
25
src/type.lua
Normal file
25
src/type.lua
Normal file
|
@ -0,0 +1,25 @@
|
|||
-- Type
|
||||
|
||||
local Type = {}
|
||||
|
||||
function Type.isComponent(t)
|
||||
return type(t) == "table" and t.__isComponent
|
||||
end
|
||||
|
||||
function Type.isEntity(t)
|
||||
return type(t) == "table" and t.__isEntity
|
||||
end
|
||||
|
||||
function Type.isSystem(t)
|
||||
return type(t) == "table" and t.__isSystem
|
||||
end
|
||||
|
||||
function Type.isInstance(t)
|
||||
return type(t) == "table" and t.__isInstance
|
||||
end
|
||||
|
||||
function Type.isAssemblage(t)
|
||||
return type(t) == "table" and t.__isAssemblage
|
||||
end
|
||||
|
||||
return Type
|
Loading…
Add table
Add a link
Reference in a new issue