Created
January 6, 2013 07:50
-
-
Save ahappyforest/4465918 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--- 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