Made systems classes instead of singletons

This commit is contained in:
Justin van der Leij 2018-02-16 15:03:07 +01:00
parent d4297af78e
commit c750ea119f
2 changed files with 47 additions and 26 deletions

View file

@ -4,25 +4,39 @@ local Component = require(PATH..".component")
local Pool = require(PATH..".pool") local Pool = require(PATH..".pool")
local System = {} local System = {}
System.__index = System System.mt = {
__index = System,
__call = function(systemProto, ...)
local system = setmetatable({
__all = {},
__pools = {},
}, 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,
}
function System.new(...) function System.new(...)
local system = setmetatable({ local systemProto = setmetatable({
__all = {}, __filter = {...},
__pools = {}, }, System.mt)
}, System) systemProto.__index = systemProto
for _, filter in pairs({...}) do return systemProto
local pool = system:__buildPool(filter) end
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
return system function System:init(...)
end end
function System:__buildPool(pool) function System:__buildPool(pool)

View file

@ -31,8 +31,9 @@ end)
local RectangleRenderer = System({Position, Rectangle}) local RectangleRenderer = System({Position, Rectangle})
function RectangleRenderer:draw() function RectangleRenderer:draw()
local e
for i = 1, self.pool.size do for i = 1, self.pool.size do
local e = self.pool:get(i) e = self.pool:get(i)
local position = e:get(Position) local position = e:get(Position)
local rectangle = e:get(Rectangle) local rectangle = e:get(Rectangle)
@ -49,8 +50,9 @@ end
local CircleRenderer = System({Position, Circle}) local CircleRenderer = System({Position, Circle})
function CircleRenderer:draw() function CircleRenderer:draw()
local e
for i = 1, self.pool.size do for i = 1, self.pool.size do
local e = self.pool:get(i) e = self.pool:get(i)
local position = e:get(Position) local position = e:get(Position)
local circle = e:get(Circle) local circle = e:get(Circle)
@ -66,13 +68,16 @@ function CircleRenderer:draw()
end end
local RandomRemover = System({}) local RandomRemover = System({})
RandomRemover.time = 0
function RandomRemover:init()
self.time = 0
end
function RandomRemover:update(dt) function RandomRemover:update(dt)
RandomRemover.time = RandomRemover.time + dt self.time = self.time + dt
if RandomRemover.time >= 0.125 then if self.time >= 0.5 then
RandomRemover.time = 0 self.time = 0
if self.pool.size > 0 then if self.pool.size > 0 then
local i = love.math.random(1, self.pool.size) local i = love.math.random(1, self.pool.size)
@ -80,13 +85,15 @@ function RandomRemover:update(dt)
Game:removeEntity(self.pool.objects[i]) Game:removeEntity(self.pool.objects[i])
end end
end end
love.window.setTitle(love.timer.getFPS())
end end
Game:addSystem(RandomRemover, "update") Game:addSystem(RandomRemover(), "update")
Game:addSystem(RectangleRenderer, "draw") Game:addSystem(RectangleRenderer(), "draw")
Game:addSystem(CircleRenderer, "draw") Game:addSystem(CircleRenderer(), "draw")
for i = 1, 50 do for i = 1, 100 do
local e = Entity() local e = Entity()
e:give(Position, love.math.random(0, 700), love.math.random(0, 700)) e:give(Position, love.math.random(0, 700), love.math.random(0, 700))
e:give(Rectangle, love.math.random(5, 20), love.math.random(5, 20)) e:give(Rectangle, love.math.random(5, 20), love.math.random(5, 20))
@ -98,7 +105,7 @@ for i = 1, 50 do
Game:addEntity(e) Game:addEntity(e)
end end
for i = 1, 50 do for i = 1, 100 do
local e = Entity() local e = Entity()
e:give(Position, love.math.random(0, 700), love.math.random(0, 700)) e:give(Position, love.math.random(0, 700), love.math.random(0, 700))
e:give(Circle, love.math.random(5, 20)) e:give(Circle, love.math.random(5, 20))