mirror of
https://github.com/bakpakin/tiny-ecs.git
synced 2024-11-28 23:54:21 +00:00
Change API.
Remove Aspects for Filters.
This commit is contained in:
parent
eb1ee4c210
commit
8d4b994329
34
README.md
34
README.md
@ -9,8 +9,9 @@ Component Systems, here is some
|
|||||||
Copy paste tiny.lua into your source folder.
|
Copy paste tiny.lua into your source folder.
|
||||||
|
|
||||||
## Overview ##
|
## Overview ##
|
||||||
Tiny-ecs has four important types: Worlds, Aspects, Systems, and Entities.
|
Tiny-ecs has four important types: Worlds, Filters, Systems, and Entities.
|
||||||
Entities, however, can be any lua table.
|
Entities, however, can be any lua table, and Filters are just functions that
|
||||||
|
take an Entity as a parameter.
|
||||||
|
|
||||||
### Entities ###
|
### Entities ###
|
||||||
Entities are simply lua tables of data that gets processed by Systems. Entities
|
Entities are simply lua tables of data that gets processed by Systems. Entities
|
||||||
@ -24,32 +25,25 @@ and Entities. In typical use, only one World is used at a time.
|
|||||||
|
|
||||||
### Systems ###
|
### Systems ###
|
||||||
Systems in tiny-ecs describe how to update Entities. Systems select certain Entities
|
Systems in tiny-ecs describe how to update Entities. Systems select certain Entities
|
||||||
using an aspect, and then only update those select Entities. Systems have three
|
using a Filter, and then only update those select Entities. Some Systems don't
|
||||||
parts: a one-time update function, a per Entity update function, and an Aspect.
|
update Entities, and instead just act as function callbacks every update. Tiny-ecs
|
||||||
The one-time update function is called once per World update, and the per Entity
|
provides functions for creating Systems easily.
|
||||||
update function is called once per Entity per World update. The Aspect is used
|
|
||||||
to select which Entities the System will update.
|
|
||||||
|
|
||||||
### Aspects ###
|
### Filters ###
|
||||||
Aspects are used to select Entities by the presence or absence of specific
|
Filters are used to select Entities. Filters can be any lua function, but
|
||||||
Components. If an Entity contains all Components required by an Aspect, and
|
tiny-ecs provides some functions for generating common ones, like selecting
|
||||||
doesn't contain Components that are excluded by the Aspect, it is said to match
|
only Entities that have all required components.
|
||||||
the Aspect. Aspects can also be composed into more complicated Aspects that
|
|
||||||
are equivalent to the union of all sub-Aspects.
|
|
||||||
|
|
||||||
## Example ##
|
## Example ##
|
||||||
```lua
|
```lua
|
||||||
local tiny = require("tiny")
|
local tiny = require("tiny")
|
||||||
|
|
||||||
local personAspect = tiny.Aspect({"name", "mass", "phrase"})
|
local talkingSystem = tiny.processingSystem(
|
||||||
|
tiny.requireAll("name", "mass", "phrase"),
|
||||||
local talkingSystem = tiny.System(
|
|
||||||
nil,
|
|
||||||
function (p, delta)
|
function (p, delta)
|
||||||
p.mass = p.mass + delta * 3
|
p.mass = p.mass + delta * 3
|
||||||
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
|
|
||||||
)
|
)
|
||||||
|
|
||||||
local joe = {
|
local joe = {
|
||||||
@ -59,7 +53,7 @@ local joe = {
|
|||||||
hairColor = "brown"
|
hairColor = "brown"
|
||||||
}
|
}
|
||||||
|
|
||||||
local world = tiny.World(talkingSystem, joe)
|
local world = tiny.newWorld(talkingSystem, joe)
|
||||||
|
|
||||||
for i = 1, 20 do
|
for i = 1, 20 do
|
||||||
world:update(1)
|
world:update(1)
|
||||||
|
@ -1,9 +1,5 @@
|
|||||||
local tiny = require "tiny"
|
local tiny = require "tiny"
|
||||||
|
|
||||||
local World = tiny.World
|
|
||||||
local Aspect = tiny.Aspect
|
|
||||||
local System = tiny.System
|
|
||||||
|
|
||||||
-- Taken from answer at http://stackoverflow.com/questions/640642/how-do-you-copy-a-lua-table-by-value
|
-- Taken from answer at http://stackoverflow.com/questions/640642/how-do-you-copy-a-lua-table-by-value
|
||||||
local function deep_copy(o, seen)
|
local function deep_copy(o, seen)
|
||||||
seen = seen or {}
|
seen = seen or {}
|
||||||
@ -39,7 +35,8 @@ local entityTemplate2 = {
|
|||||||
vel = {x = -1, y = 0},
|
vel = {x = -1, y = 0},
|
||||||
name = "E2",
|
name = "E2",
|
||||||
size = 10,
|
size = 10,
|
||||||
description = "It does not go to 11."
|
description = "It does not go to 11.",
|
||||||
|
onlyTen = true
|
||||||
}
|
}
|
||||||
|
|
||||||
local entityTemplate3 = {
|
local entityTemplate3 = {
|
||||||
@ -47,12 +44,13 @@ local entityTemplate3 = {
|
|||||||
vel = {x = 0, y = 3},
|
vel = {x = 0, y = 3},
|
||||||
name = "E3",
|
name = "E3",
|
||||||
size = 8,
|
size = 8,
|
||||||
description = "The smallest entity."
|
description = "The smallest entity.",
|
||||||
|
littleMan = true
|
||||||
}
|
}
|
||||||
|
|
||||||
describe('tiny-ecs:', function()
|
describe('tiny-ecs:', function()
|
||||||
|
|
||||||
describe('Aspect:', function()
|
describe('Filters:', function()
|
||||||
|
|
||||||
local entity1, entity2, entity3
|
local entity1, entity2, entity3
|
||||||
|
|
||||||
@ -62,21 +60,22 @@ describe('tiny-ecs:', function()
|
|||||||
entity3 = deep_copy(entityTemplate3)
|
entity3 = deep_copy(entityTemplate3)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
it("Correctly match Aspects and Entities", function()
|
it("Default Filters", function()
|
||||||
|
|
||||||
local atap = Aspect({"spinalTap"})
|
local ftap = tiny.requireAll("spinalTap")
|
||||||
local avel = Aspect({"vel"})
|
local fvel = tiny.requireAll("vel")
|
||||||
local axform = Aspect({"xform"})
|
local fxform = tiny.requireAll("xform")
|
||||||
local aall = Aspect({})
|
local fall = tiny.requireOne("spinalTap", "onlyTen", "littleMan")
|
||||||
local aboth = Aspect.compose(atap, axform)
|
|
||||||
local amove = Aspect.compose(axform, avel)
|
|
||||||
|
|
||||||
assert.truthy(atap:matches(entity1))
|
assert.truthy(fall(entity1))
|
||||||
assert.falsy(atap:matches(entity2))
|
assert.truthy(ftap(entity1))
|
||||||
assert.truthy(axform:matches(entity1))
|
assert.falsy(ftap(entity2))
|
||||||
assert.truthy(axform:matches(entity2))
|
assert.truthy(fxform(entity1))
|
||||||
assert.truthy(aboth:matches(entity1))
|
assert.truthy(fxform(entity2))
|
||||||
assert.falsy(aboth:matches(entity2))
|
|
||||||
|
assert.truthy(fall(entity1))
|
||||||
|
assert.truthy(fall(entity2))
|
||||||
|
assert.truthy(fall(entity3))
|
||||||
|
|
||||||
end)
|
end)
|
||||||
|
|
||||||
@ -86,20 +85,19 @@ describe('tiny-ecs:', function()
|
|||||||
|
|
||||||
local world, entity1, entity2, entity3
|
local world, entity1, entity2, entity3
|
||||||
|
|
||||||
local moveSystem = System(
|
local moveSystem = tiny.processingSystem(
|
||||||
nil,
|
tiny.requireAll("xform", "vel"),
|
||||||
function(e, dt)
|
function(e, dt)
|
||||||
local xform = e.xform
|
local xform = e.xform
|
||||||
local vel = e.vel
|
local vel = e.vel
|
||||||
local x, y = xform.x, xform.y
|
local x, y = xform.x, xform.y
|
||||||
local xvel, yvel = vel.x, vel.y
|
local xvel, yvel = vel.x, vel.y
|
||||||
xform.x, xform.y = x + xvel * dt, y + yvel * dt
|
xform.x, xform.y = x + xvel * dt, y + yvel * dt
|
||||||
end,
|
end
|
||||||
Aspect({"xform", "vel"})
|
|
||||||
)
|
)
|
||||||
|
|
||||||
local timePassed = 0
|
local timePassed = 0
|
||||||
local oneTimeSystem = System(
|
local oneTimeSystem = tiny.emptySystem(
|
||||||
function(dt)
|
function(dt)
|
||||||
timePassed = timePassed + dt
|
timePassed = timePassed + dt
|
||||||
end
|
end
|
||||||
@ -109,7 +107,7 @@ describe('tiny-ecs:', function()
|
|||||||
entity1 = deep_copy(entityTemplate1)
|
entity1 = deep_copy(entityTemplate1)
|
||||||
entity2 = deep_copy(entityTemplate2)
|
entity2 = deep_copy(entityTemplate2)
|
||||||
entity3 = deep_copy(entityTemplate3)
|
entity3 = deep_copy(entityTemplate3)
|
||||||
world = World(moveSystem, oneTimeSystem, entity1, entity2, entity3)
|
world = tiny.newWorld(moveSystem, oneTimeSystem, entity1, entity2, entity3)
|
||||||
timePassed = 0
|
timePassed = 0
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
257
tiny.lua
257
tiny.lua
@ -12,13 +12,12 @@ local ipairs = ipairs
|
|||||||
local setmetatable = setmetatable
|
local setmetatable = setmetatable
|
||||||
local getmetatable = getmetatable
|
local getmetatable = getmetatable
|
||||||
|
|
||||||
-- Simplified class implementation with no inheritance or polymorphism.
|
-- Simple class implementation with no inheritance or polymorphism.
|
||||||
local function class(name)
|
local function class()
|
||||||
local c = {}
|
local c = {}
|
||||||
local mt = {}
|
local mt = {}
|
||||||
setmetatable(c, mt)
|
setmetatable(c, mt)
|
||||||
c.__index = c
|
c.__index = c
|
||||||
c.name = name
|
|
||||||
function mt.__call(_, ...)
|
function mt.__call(_, ...)
|
||||||
local newobj = {}
|
local newobj = {}
|
||||||
setmetatable(newobj, c)
|
setmetatable(newobj, c)
|
||||||
@ -30,159 +29,14 @@ local function class(name)
|
|||||||
return c
|
return c
|
||||||
end
|
end
|
||||||
|
|
||||||
local World = class("World")
|
-- --- System --- --
|
||||||
local Aspect = class("Aspect")
|
local System = class()
|
||||||
local System = class("System")
|
|
||||||
|
|
||||||
tiny.World = World
|
-- Initializes a System.
|
||||||
tiny.Aspect = Aspect
|
function System:init(preupdate, filter, update, add, remove)
|
||||||
tiny.System = System
|
|
||||||
|
|
||||||
----- Aspect -----
|
|
||||||
|
|
||||||
-- Aspect(required, excluded, oneRequired)
|
|
||||||
|
|
||||||
-- Creates an Aspect. Aspects are used to select which Entities are inlcuded
|
|
||||||
-- in each system. An Aspect has three fields, namely all required Components,
|
|
||||||
-- all excluded Components, and Components of which a system requires only one.
|
|
||||||
-- If an Entitiy has all required Components, none of the excluded Components,
|
|
||||||
-- and at least one of the oneRequired Components, it matches the Aspects.
|
|
||||||
-- This method expects at least one and up to three lists of strings, the names
|
|
||||||
-- of components. If no arguments are supplied, the Aspect will not match any
|
|
||||||
-- Entities. Will not mutate supplied arguments.
|
|
||||||
function Aspect:init(required, excluded, oneRequired)
|
|
||||||
|
|
||||||
local r, e, o = {}, {}, {}
|
|
||||||
self[1], self[2], self[3] = r, e, o
|
|
||||||
|
|
||||||
-- Check for empty Aspect
|
|
||||||
if not required and not oneRequired then
|
|
||||||
self[4] = true
|
|
||||||
return
|
|
||||||
end
|
|
||||||
self[4] = false
|
|
||||||
|
|
||||||
local excludeSet, requiredSet = {}, {}
|
|
||||||
|
|
||||||
-- Iterate through excluded Components
|
|
||||||
for _, v in ipairs(excluded or {}) do
|
|
||||||
tinsert(e, v)
|
|
||||||
excludeSet[v] = true
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Iterate through required Components
|
|
||||||
for _, v in ipairs(required or {}) do
|
|
||||||
if excludeSet[v] then -- If Comp. is required and excluded, empty Aspect
|
|
||||||
self[1], self[2], self[3], self[4] = {}, {}, {}, true
|
|
||||||
return
|
|
||||||
else
|
|
||||||
tinsert(r, v)
|
|
||||||
requiredSet[v] = true
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Iterate through one-required Components
|
|
||||||
for _, v in ipairs(oneRequired or {}) do
|
|
||||||
if requiredSet[v] then -- If one-required Comp. is also required,
|
|
||||||
-- don't need one required Components
|
|
||||||
self[3] = {}
|
|
||||||
return
|
|
||||||
end
|
|
||||||
if not excludeSet[v] then
|
|
||||||
tinsert(o, v)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Aspect.compose(...)
|
|
||||||
|
|
||||||
-- Composes multiple Aspects into one Aspect. The resulting Aspect will match
|
|
||||||
-- any Entity that matches all sub Aspects.
|
|
||||||
function Aspect.compose(...)
|
|
||||||
|
|
||||||
local newa = {{}, {}, {}}
|
|
||||||
|
|
||||||
for _, a in ipairs{...} do
|
|
||||||
|
|
||||||
if a[4] then -- Aspect must be empty Aspect
|
|
||||||
return Aspect()
|
|
||||||
end
|
|
||||||
|
|
||||||
for i = 1, 3 do
|
|
||||||
for _, c in ipairs(a[i]) do
|
|
||||||
tinsert(newa[i], c)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
return Aspect(newa[1], newa[2], newa[3])
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Aspect:matches(entity)
|
|
||||||
|
|
||||||
-- Returns boolean indicating if an Entity matches the Aspect.
|
|
||||||
function Aspect:matches(entity)
|
|
||||||
|
|
||||||
-- Aspect is the empty Aspect
|
|
||||||
if self[4] then return false end
|
|
||||||
|
|
||||||
local rs, es, os = self[1], self[2], self[3]
|
|
||||||
|
|
||||||
-- Assert Entity has all required Components
|
|
||||||
for i = 1, #rs do
|
|
||||||
local r = rs[i]
|
|
||||||
if entity[r] == nil then return false end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Assert Entity has no excluded Components
|
|
||||||
for i = 1, #es do
|
|
||||||
local e = es[i]
|
|
||||||
if entity[e] ~= nil then return false end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- if Aspect has at least one Component in the one-required
|
|
||||||
-- field, assert that the Entity has at least one of these.
|
|
||||||
if #os >= 1 then
|
|
||||||
for i = 1, #os do
|
|
||||||
local o = os[i]
|
|
||||||
if entity[o] ~= nil then return true end
|
|
||||||
end
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
|
|
||||||
function Aspect:__tostring()
|
|
||||||
if self[4] then
|
|
||||||
return "TinyAspect<>"
|
|
||||||
else
|
|
||||||
return "TinyAspect<Required: {" ..
|
|
||||||
tconcat(self[1], ", ") ..
|
|
||||||
"}, Excluded: {" ..
|
|
||||||
tconcat(self[2], ", ") ..
|
|
||||||
"}, One Req.: {" ..
|
|
||||||
tconcat(self[3], ", ") ..
|
|
||||||
"}>"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
----- System -----
|
|
||||||
|
|
||||||
-- System(preupdate, update, [aspect, addCallback, removeCallback])
|
|
||||||
|
|
||||||
-- Creates a new System with the given aspect and update callback. The update
|
|
||||||
-- callback should be a function of one parameter, an entity. If no aspect is
|
|
||||||
-- provided the empty Aspect, which matches no Entity, is used. Preupdate is a
|
|
||||||
-- function of no arguments that is called once per system update before the
|
|
||||||
-- entities are updated. The add and remove callbacks are optional functions
|
|
||||||
-- that are called when entities are added or removed from the system. They
|
|
||||||
-- should each take one argument - an Entity.
|
|
||||||
function System:init(preupdate, update, aspect, add, remove)
|
|
||||||
self.preupdate = preupdate
|
self.preupdate = preupdate
|
||||||
self.update = update
|
self.update = update
|
||||||
self.aspect = aspect or Aspect()
|
self.filter = filter
|
||||||
self.add = add
|
self.add = add
|
||||||
self.remove = remove
|
self.remove = remove
|
||||||
end
|
end
|
||||||
@ -192,16 +46,15 @@ function System:__tostring()
|
|||||||
self.preupdate ..
|
self.preupdate ..
|
||||||
", update: " ..
|
", update: " ..
|
||||||
self.update ..
|
self.update ..
|
||||||
", aspect: " ..
|
", filter: " ..
|
||||||
self.aspect ..
|
self.filter ..
|
||||||
">"
|
">"
|
||||||
end
|
end
|
||||||
|
|
||||||
----- World -----
|
-- --- World --- --
|
||||||
|
local World = class()
|
||||||
|
|
||||||
-- World(...)
|
-- Initializes a World.
|
||||||
|
|
||||||
-- Creates a new World with the given Systems and Entities in order.
|
|
||||||
function World:init(...)
|
function World:init(...)
|
||||||
|
|
||||||
-- Table of Entities to status
|
-- Table of Entities to status
|
||||||
@ -252,7 +105,7 @@ end
|
|||||||
|
|
||||||
-- Adds Entities and Systems to the World. New objects will enter the World the
|
-- Adds Entities and Systems to the World. New objects will enter the World the
|
||||||
-- next time World:update(dt) is called. Also call this method when an Entity
|
-- next time World:update(dt) is called. Also call this method when an Entity
|
||||||
-- has had its Components changed, such that it matches different Aspects.
|
-- has had its Components changed, such that it matches different Filters.
|
||||||
function World:add(...)
|
function World:add(...)
|
||||||
local args = {...}
|
local args = {...}
|
||||||
local status = self.status
|
local status = self.status
|
||||||
@ -275,11 +128,12 @@ end
|
|||||||
function World:remove(...)
|
function World:remove(...)
|
||||||
local args = {...}
|
local args = {...}
|
||||||
local status = self.status
|
local status = self.status
|
||||||
|
local entities = self.entities
|
||||||
local systemsToRemove = self.systemsToRemove
|
local systemsToRemove = self.systemsToRemove
|
||||||
for _, obj in ipairs(args) do
|
for _, obj in ipairs(args) do
|
||||||
if getmetatable(obj) == System then
|
if getmetatable(obj) == System then
|
||||||
tinsert(systemsToRemove, obj)
|
tinsert(systemsToRemove, obj)
|
||||||
else -- Assume obj is an Entity
|
elseif entities[obj] then -- Assume obj is an Entity
|
||||||
status[obj] = "remove"
|
status[obj] = "remove"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -360,9 +214,11 @@ function World:manageSystems()
|
|||||||
systemIndices[sys] = #systems
|
systemIndices[sys] = #systems
|
||||||
activeSystems[sys] = true
|
activeSystems[sys] = true
|
||||||
|
|
||||||
local a = sys.aspect
|
local a = sys.filter
|
||||||
for e in pairs(entities) do
|
if a then
|
||||||
es[e] = a:matches(e) and true or nil
|
for e in pairs(entities) do
|
||||||
|
es[e] = a(e) and true or nil
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
deltaSystemCount = deltaSystemCount + 1
|
deltaSystemCount = deltaSystemCount + 1
|
||||||
@ -391,19 +247,22 @@ function World:manageEntities()
|
|||||||
if s == "add" then
|
if s == "add" then
|
||||||
deltaEntityCount = deltaEntityCount + 1
|
deltaEntityCount = deltaEntityCount + 1
|
||||||
for sys, es in pairs(systemEntities) do
|
for sys, es in pairs(systemEntities) do
|
||||||
local matches = sys.aspect:matches(e) and true or nil
|
local filter = sys.filter
|
||||||
local addCallback = sys.add
|
if filter then
|
||||||
if addCallback and matches and not es[e] then
|
local matches = filter(e) and true or nil
|
||||||
addCallback(e)
|
local addCallback = sys.add
|
||||||
|
if addCallback and matches and not es[e] then
|
||||||
|
addCallback(e)
|
||||||
|
end
|
||||||
|
es[e] = matches
|
||||||
end
|
end
|
||||||
es[e] = matches
|
|
||||||
end
|
end
|
||||||
elseif s == "remove" then
|
elseif s == "remove" then
|
||||||
deltaEntityCount = deltaEntityCount - 1
|
deltaEntityCount = deltaEntityCount - 1
|
||||||
entities[e] = nil
|
entities[e] = nil
|
||||||
for sys, es in pairs(systemEntities) do
|
for sys, es in pairs(systemEntities) do
|
||||||
local removec = sys.remove
|
local removec = sys.remove
|
||||||
if removec then
|
if es[e] and removec then
|
||||||
removec(e)
|
removec(e)
|
||||||
end
|
end
|
||||||
es[e] = nil
|
es[e] = nil
|
||||||
@ -467,4 +326,62 @@ function World:setSystemActive(system, active)
|
|||||||
self.activeSystem[system] = active and true or nil
|
self.activeSystem[system] = active and true or nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- --- Top Level module functions --- --
|
||||||
|
|
||||||
|
--- Creates a new tiny-ecs World.
|
||||||
|
function tiny.newWorld(...)
|
||||||
|
return World(...)
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Makes a Filter that filters Entities with specified Components.
|
||||||
|
-- An Entity must have all Components to match the filter.
|
||||||
|
function tiny.requireAll(...)
|
||||||
|
local components = {...}
|
||||||
|
local len = #components
|
||||||
|
return function(e)
|
||||||
|
local c
|
||||||
|
for i = 1, len do
|
||||||
|
c = components[i]
|
||||||
|
if e[c] == nil then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Makes a Filter that filters Entities with specified Components.
|
||||||
|
-- An Entity must have at least one specified Component to match the filter.
|
||||||
|
function tiny.requireOne(...)
|
||||||
|
local components = {...}
|
||||||
|
local len = #components
|
||||||
|
return function(e)
|
||||||
|
local c
|
||||||
|
for i = 1, len do
|
||||||
|
c = components[i]
|
||||||
|
if e[c] ~= nil then
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Creates a System that doesn't update any Entities, but executes a callback
|
||||||
|
-- once per update.
|
||||||
|
function tiny.emptySystem(callback)
|
||||||
|
return System(callback)
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Creates a System that processes Entities every update. Also provides
|
||||||
|
-- optional callbacks for when Entities are added or removed from the System.
|
||||||
|
function tiny.processingSystem(filter, entityCallback, onAdd, onRemove)
|
||||||
|
return System(nil, filter, entityCallback, onAdd, onRemove)
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Creates a System.
|
||||||
|
function tiny.system(callback, filter, entityCallback, onAdd, onRemove)
|
||||||
|
return System(callback, filter, entityCallback, onAdd, onRemove)
|
||||||
|
end
|
||||||
|
|
||||||
return tiny
|
return tiny
|
||||||
|
Loading…
Reference in New Issue
Block a user