Code: Select all
local Aspect = require 'aspect'
Aspect.system (aspects, process)
Creates a new system. The system will process entities with components matching each member of the aspects array.
Code: Select all
local drawRectangle = Aspect.system(
{ 'position', 'size', 'color' },
function (pos, size, color)
love.graphics.setColor(color)
love.graphics.rectangle('fill', pos.x, pos.y, size.width, size.height)
end
)
An array of keys which must be present in an entity in order to process it.
param process
A function to run on the components of each matching entity. The function will receive one argument for each member of the aspects array, containing a component.
return function (entities, [context])
The newly created system is returned in the form of a function taking a list of entities to process. The user may optionally pass in a context value which will be made available via the _context meta-aspect (see below).
Aspect.each (entities, aspects, [context], [process])
Process entities without creating a system. May be used from within a system to process entity interactions.
Code: Select all
for pos, vel in Aspect.each(entities, { 'position', 'velocity' }) do
pos.x = pos.x + vel.x
pos.y = pos.y + vel.y
end
An array of entities to process.
param aspects
An array of keys which must be present in the entity in order to process it.
param context
Optional user-defined context value, available via the _context meta-aspect (see below).
param process
Optional function to process matching entities. If omitted, Aspect.each will act as an iterator as in the example above.
Meta-aspects
Meta-aspects work like regular aspects: supply their names in an aspects list and get a matching process argument or iterator result.
_context
User-defined data passed in as the second argument when invoking a system or the third argument to Aspect.each.
_entities
The list of entities being processed.
_entity
The entity being processed. Avoid using this; use components directly whenever possible.
_index
The index of the entity being processed in the entities list.
aspect.lua
Just cut and paste into a file for now. If there's enough interest in this I'll github it later.
Code: Select all
local Aspect = {}
local unpack = table.unpack or _G.unpack
function Aspect.each (entities, aspects, context, process)
function iterate (process)
local meta = { _context = context, _entities = entities }
for index, entity in pairs(entities) do
local components = {}
local isMatchingEntity = true
meta._entity = entity
meta._index = index
for aspectIndex, aspect in pairs(aspects) do
local component = meta[aspect] or entity[aspect]
if not component then
isMatchingEntity = false
break
end
components[aspectIndex] = component
end
if isMatchingEntity then
process(unpack(components))
end
end
end
if process then
iterate(process)
else
return coroutine.wrap(function ()
iterate(coroutine.yield)
end)
end
end
function Aspect.system (aspects, process)
return function (entities, context)
Aspect.each(entities, aspects, context, process)
end
end
return Aspect