Coil: Cooperative threading library
Posted: Sat Aug 16, 2014 1:02 pm
Coil is a small module which, using coroutines, provides easy to use cooperative threading -- coil refers to each cooperative thread as a task, you can have thousands of tasks running at a time. Coil uses a similar API to flux, its groups, for example, are used the same way.
There are some small usage examples and an overview of the library on its github page. I've also provided a heavily commented example program -- note that though the example uses fading in / out to demonstrate coil's API, transitions like this would be better suited to something like flux.
You can find the module on github along with instructions on how to use it.
There are some small usage examples and an overview of the library on its github page. I've also provided a heavily commented example program -- note that though the example uses fading in / out to demonstrate coil's API, transitions like this would be better suited to something like flux.
Code: Select all
local coil = require "lib.coil"
local Object = require "lib.classic"
local _ = require "lib.lume"
-------------------------------------------------------------------------------
-- Entity
-------------------------------------------------------------------------------
local Entity = Object:extend()
function Entity:new()
-- Init the entity's size and position
self.x = _.random(0, 500)
self.y = _.random(0, 500)
self.size = _.random(10, 30)
-- Init velocity
self.velocity = { x = 0, y = 0 }
-- Init alpha (this is increase with a task below)
self.alpha = 0
-- Init tick (this is increased each second with a task below)
self.tick = 0
-- Init the entity's coil group -- All the tasks related to the entity are
-- added to its own group, this group is updated in the entity's :update().
-- As the entity is in charge of its own coil group, when the entity is
-- destroyed all its tasks go with it.
self.tasks = coil.group()
-- Start a new task to fade the entity in
self.tasks:add(function()
while self.alpha < 1 do
self.alpha = self.alpha + .01
coil.wait(.01)
end
self.alpha = 1
end)
-- Start a new task for handling the entities movement -- the task randomly
-- assigns a velocity to the entity then waits and repeats
self.tasks:add(function()
while true do
self.velocity.x = _.random(-20, 20)
self.velocity.y = _.random(-20, 20)
coil.wait(_.random(.5, 2))
end
end)
-- Start entity's tick timer, increase by one tick per second
self.tasks:add(function()
for i = 1, math.huge do
self.tick = i
coil.wait(1)
end
end)
end
function Entity:update(dt)
-- Update tasks
self.tasks:update(dt)
-- Update movement
self.x = self.x + self.velocity.x * dt
self.y = self.y + self.velocity.y * dt
end
function Entity:draw()
love.graphics.setColor(255, 255, 255, self.alpha * 255)
-- Draw square
love.graphics.rectangle("fill", self.x, self.y, self.size, self.size)
-- Draw tick number
love.graphics.print(self.tick, self.x + self.size + 2, self.y)
end
-------------------------------------------------------------------------------
-- Main
-------------------------------------------------------------------------------
local background = 0
local entities = {}
function love.load()
-- Start a task to add 50 entities, 5 entities every second. When all the
-- entities have been added the background is faded from black to grey
coil.add(function()
-- Add 50 entities
for i = 1, 50 do
local e = Entity()
table.insert(entities, e)
coil.wait(.2)
end
-- Fade background
while background < 50 do
background = background + .25
coil.wait(.01)
end
background = 50
end)
end
function love.update(dt)
coil.update(dt)
_.each(entities, "update", dt)
end
function love.draw()
_.each(entities, "draw")
love.graphics.setBackgroundColor(background, background, background)
love.graphics.setColor(255, 255, 255)
love.graphics.print(love.timer.getFPS() .. "fps", 10, 10)
end