/MUSHclient/lua/listener.lua
http://xymud.googlecode.com/ · Lua · 263 lines · 202 code · 42 blank · 19 comment · 29 complexity · 49a782edeb0025ed79588f0f08f66130 MD5 · raw file
- -- ameng 2010/12/1
- -- 增加临时trigger并监听之,使用方法
- -- event = Event.new("^[> ]*袁守诚给你一本〖无字天书〗。$", "yaozhou", "yaobishuizhou")
- -- call = Callback.new("s: return 'ok'")
- -- Listener.add(event, call)
- -- if listen("yaozhou") == "ok" then --等待返回
- -- 这些封在了helper 的 addListener 和 listen 函数 中
-
-
- module("Listener",package.seeall)
-
- local threads = {} --协同列表
- local listeners = {} --放入group列表
- local callbacks = {}
- local timeouts = {}
-
- --如果不是oneshot 触发器,用这个记录数据
- local defaultTimeout = 59
-
- function reset()
- threads = {}
- listeners = {}
- callbacks = {}
- timeouts = {}
- Note("Listener reset now")
- end
-
- function add(event,callback)
- local id = event.name
- local group = event.group
- --local name = genName(id, group, callback:getHexscript())
- register(id, group, callback)
- local match = event.match
- local flag = event.flag
- check (AddTriggerEx(id, match, "", flag,
- custom_colour.NoChange,0, "",
- "Listener.OnEvent",
- 12,
- 100))
-
- SetTriggerOption(id, "group", group)
- if event.line > 1 then
- SetTriggerOption (id, "multi_line", 1)
- SetTriggerOption (id, "lines_to_match", event.line)
- end
-
- return id
- end
-
- function genName(id,group,script)
- return id .. "_" .. group .. "_" .. script
- end
-
- function getGroup(group)
- listeners[group] = listeners[group] or {}
- return listeners[group]
- end
-
- function register(id, group, callback)
- if not listeners[group] then
- listeners[group] = {}
- end
- listeners[group][id] = true
-
- threads[id] = assert(coroutine.running(), "Must be in coroutine")
- callbacks[id] = callback
- end
-
- function remove(id, flag)
- local group = GetTriggerOption(id, "group")
- --正在执行是删不掉的
- if IsTrigger(id) then
- DeleteTrigger(id)
- end
- if group and listeners[group] then
- listeners[group][id] = nil
- end
-
- callbacks[id] = nil
- if flag then
- threads[id] = nil
- end
- end
-
- function removeGroup(group)
- local groups = listeners[group]
- if groups then
- for id in pairs(groups) do
- --print("删除id:"..id)
- threads[id] = nil
- callbacks[id] = nil
- end
- end
-
- listeners[group] = nil
- DeleteTriggerGroup(group)
- end
-
- function resume(id, ...)
- local thread = threads[id]
- if not thread then
- logfile("error.txt", "Listener resume 错误的协程id:"..id)
- return
- end
- threads[id] = nil
- local ok, err = coroutine.resume(thread,...)
- checkresume(ok,err,thread, id)
- end
-
- function OnEvent(name,line,wildcards)
- local callback = callbacks[name]
- local result = {callback:invoke(name,line,wildcards)}
- if result[1] == nil then
- result = {name}
- end
-
- remove(name)
- resume(name, unpack(result))
- end
-
-
- function OnTimeout(name)
- --Note("Timeout:"..name)
- local thread = threads[name]
- --是否已经被删除了
- if thread and name then
- local info = name
- if timeouts[name] then
- info = timeouts[name]
- end
-
- removeTimeout(name)
- local ok, err = coroutine.resume(thread, "timeout", info)
- checkresume(ok,err,thread,name)
- end
- end
-
-
- function setTimeout(seconds, info)
- local thread = assert(coroutine.running(), "Must be in coroutine")
- local id = "timeout" .. "_" .. GetUniqueNumber()
- threads[id] = thread
- if info then
- timeouts[id] = info
- else
- logfile("error.txt", string.format("Listener setTimeout no name:%s", debug.traceback()))
- end
-
- seconds = seconds or defaultTimeout
- --Note(string.format("addtimeout:id %s date: %s", id, os.date("%c")))
- local hours, minutes, seconds = convert_seconds(seconds)
- check(AddTimer(id, hours, minutes, seconds, "", bit.bor (timer_flag.Enabled,
- timer_flag.OneShot, timer_flag.Temporary, timer_flag.Replace),
- "Listener.OnTimeout"))
- check(SetTimerOption (id, "send_to", 12)) -- send to script
- return id
- end
-
- function removeTimeout(id)
- --Note("removetimeout:"..id)
- if IsTimer(id) == error_code.eOK then
- EnableTimer(id, false)
- if DeleteTimer(id) == error_code.eItemInUse then
-
- end
- end
- threads[id] = nil
- timeouts[id] = nil
- end
-
-
- function OnWaitTimeout(name)
- local thread = threads[name]
- if thread then
- threads[name] = nil
- local ok, err = coroutine.resume(thread, name)
- checkresume(ok,err,thread,"timer:"..name)
- else
- logfile("error.txt", "Listener resume 错误的协程id:"..name)
- end
- end
-
- function wait(seconds)
- Note("Listener wait:"..seconds.." seconds")
- local thread = assert(coroutine.running(), "Must be in coroutine")
-
- local id = "Wait_" .. GetUniqueNumber()
- threads[id] = thread
- local hours, minutes, seconds = convert_seconds(seconds)
-
- check(AddTimer(id, hours, minutes, seconds, "",
- bit.bor (timer_flag.Enabled,
- timer_flag.OneShot,
- timer_flag.Temporary,
- timer_flag.Replace),
- "Listener.OnWaitTimeout"))
- check (SetTimerOption (id, "send_to", 12))
- local id1 = coroutine.yield()
- if id1 ~= id then
- threads[id] = nil
- logfile("error.txt", "listener wait() resume result = ".. id1.." not: "..id)
- end
- end
-
- --不移出协同
- function resume2(id, ...)
- local thread = threads[id]
- if not thread then
- logfile("error.txt", "Listener resume2 错误的协程id:"..id)
- return
- end
- local ok, err = coroutine.resume(thread,...)
- checkresume(ok,err,thread,id)
- end
-
- --不删除trigger信息
- function OnSetEvent(name,line,wildcards)
- local callback = callbacks[name]
- local result = {callback:invoke(name,line,wildcards)}
- resume2(name, unpack(result))
- end
-
- function addSet(event,callback)
- local id = event.name
- local group = event.group
- --local name = genName(id, group, callback:getHexscript())
- register(id, group, callback)
- local match = event.match
- local flag = event.flag
-
- check(AddTriggerEx(id, match, "", flag, -1, 0, "","Listener.OnSetEvent", 12, 100))
-
- SetTriggerOption(id,"group",group)
- if event.line > 1 then
- SetTriggerOption (id, "multi_line", 1)
- SetTriggerOption (id, "lines_to_match", event.line)
- end
-
- return id
- end
-
- function checkresume(ok,err,thread,name)
- if not ok then
- if name == nil then
- name = "unknow"
- end
-
- logfile("error.txt", "Error raised in Listener module, id is:"..name)
- logfile("error.txt", debug.traceback(thread))
- logfile("error.txt", err)
- end
- end
-
- ----------------------------debug------------------------------
- function checklistener()
- print("checklistener:threads")
- tprint(threads)
- print("checklistener:listeners")
- tprint(listeners)
- print("checklistener:callbacks")
- tprint(callbacks)
- end