Skip to content

Instantly share code, notes, and snippets.

@ahappyforest
Created January 6, 2013 07:50
Show Gist options
  • Save ahappyforest/4465918 to your computer and use it in GitHub Desktop.
Save ahappyforest/4465918 to your computer and use it in GitHub Desktop.
--- agent.lua
local setmetatable = setmetatable
local coroutine = coroutine
local assert = assert
local unpack = unpack
local print = print
local pairs = pairs
module "agent"
local function create_event_group(self, events, thread , parent_group)
local group = {
event = {},
thread = thread,
parent = parent_group,
}
if parent_group then
for k,v in pairs(parent_group.event) do
self.event[k] = nil
end
end
for k,v in pairs(events) do
group.event[k] = { func = v , group = group }
assert(self.event[k] == nil , k)
self.event[k] = group.event[k]
end
end
local function pop_event_group(self, group)
for k in pairs(group.event) do
self.event[k] = nil
end
if group.parent then
for k,v in pairs(group.parent.event) do
assert(self.event[k] == nil , k)
self.event[k] = v
end
end
end
function create(main)
local mainthread = coroutine.create(main)
local self = setmetatable( { event = {} } , { __index = _M })
local r , command , events = coroutine.resume(mainthread , self)
assert(r , command)
assert(command == "listen" , command)
create_event_group(self, events, mainthread)
return self
end
function send(self, msg , ...)
local event = self.event[msg]
if event == nil then
print (msg .. " unknown" , ...)
else
local event_thread = coroutine.create(event.func)
local group = event.group
while true do
local r, command, events = coroutine.resume(event_thread, self, ...)
assert(r,command)
if command == "listen" then
create_event_group(self, events, event_thread , group)
break
elseif command == "fork" then
create_event_group(self, events, event_thread)
break
elseif command == "break" then
pop_event_group(self, group)
event_thread = group.thread
group = group.parent
else
break
end
end
end
end
function listen(agent , msg)
coroutine.yield("listen",msg)
end
function quit(agent)
coroutine.yield "break"
end
function fork(agent, msg)
coroutine.yield("fork",msg)
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment