Concord/lib/entity.lua
Justin van der Leij f7a394f057 Added assemblages
2018-11-12 15:18:17 +01:00

140 lines
3.1 KiB
Lua

--- 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,
})