在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
Play mud games? Using Mush Client to write robot? Let's see what I show you~ In order to use this framework to develop your robot, you can follow this way: for example:
-- handle "event1"
Listener.new():Register(Event.new("event1"), EventHandler1.new()) EventHander1 = class(Callback) function EventHander1:Do(event, ) -- do something cmdSender:Add("cmd1;#3 cmd2;@2;cmd3") -- #3 means repeat 3 times, @2 means delay 2 seconds end -- handle "event2" five times Listener.new():Register(Event.new("event2, 0, 5"), EventHandler2.new()) EventHander2 = class(Callback) function EventHander2:Do(event, ) -- do something cmdSender:Add({"cmd4", "@3", "#2 cmd5"}) -- accept commands in a table end -- handle "event3" twice within 10 seconds. if it is not triggered twice within 10 seconds, a timeout event is sent. Listener.new():Register(Event.new("event3, 10, 2"), EventHandler3.new()) EventHander3 = class(Callback) function EventHander3:Do(event, ) -- do something if (event.isTimeout) then cmdSender:Add("cmd6") else cmdSender:Add({"cmd7", "cmd8"}) end end
---------------------------------------------------------
-- OO, implement class module --------------------------------------------------------- local _class = {} function class(super) local class_type = {} class_type.ctor = false class_type.super = super class_type.new = function() local obj = {} do local create create = function(c, ) if c.super then create(c.super, ) end if c.ctor then c.ctor(obj, ) end end create(class_type, ) end setmetatable(obj, { __index = _class[class_type] }) return obj end local vtbl = {} _class[class_type] = vtbl setmetatable(class_type, { __newindex = function(t, k, v) vtbl[k] = v end }) if super then setmetatable(vtbl, { __index = function(t,k) local ret = _class[super][k] vtbl[k] = ret return ret end }) end return class_type end
---------------------------------------------------------
-- event --- type: type of an event --- timeout: in a particular time(in seconds) didn't receive the event will fire a timeout event --- times: the event will be triggered how many times, then will be self removed --------------------------------------------------------- Event = class() function Event:ctor(type, timeout, times) self.type = type if (timeout == nil and times == nil) then -- if both timeout and times are not set, then can be triggered any times (set times to zero) self.timeout = 0 self.times = 0 elseif (timeout ~= nil and times == nil) then -- if timeout is set, times is not set, then can be trigger only once self.timeout = timeout self.times = 1 else -- if both timeout and times are set, then can be trigger any times within timeout self.timeout = timeout self.times = times end self.isTimeout = false self.triggered = 0 end function Event:Reset() self.isTimeout = false self.triggered = 0 end
---------------------------------------------------------
-- callback: callback function when receved an event --------------------------------------------------------- Callback = class() function Callback:ctor(insideFunc) self.func = insideFunc end function Callback:Invoke(event, ) -- logging helper:Print("Event:", event.type, " Timeout:", event.isTimeout, " Triggered:", event.triggered) -- call handler self:Do(event, ) end function Callback:Do(event, ) helper:Print("Do Noting") end
---------------------------------------------------------
-- listener --------------------------------------------------------- Listener = class() function Listener:ctor() self.id = CreateGUID() end function Listener:Register(event, callback) assert(event.type ~= nil, "event type is nil") self.event = event self.callback = callback -- create timer if has timeout if (event.timeout ~= 0) then -- create timer using type as timer name helper:AddTimer(self.event.type, self.event.timeout) end -- add self in listener list dispatcher:AddListener(self) end function Listener:Remove() assert(self.event ~= nil, "have to register event then remove it") -- if has timer and the timer is not timeout, delete it if (self.event.timeout ~= 0 and not self.event.isTimeout) then helper:RemoveTimer(self.event.type) end -- remove self in listener list dispatcher:RemoveListener(self) end function Listener:OnEvent() -- add triggered times self.event.triggered = self.event.triggered + 1 -- check if reach triggered times if (self.event.times ~= 0 and self.event.triggered == self.event.times) then self:Remove() end -- call back self.callback:Invoke(self.event, ) end function Listener:OnTimeout() -- set isTimeout and call back self.event.isTimeout = true -- delete listener self:Remove() -- call back self.callback:Invoke(self.event) end
---------------------------------------------------------
-- event dispatcher --------------------------------------------------------- EventDispatcher = class() function EventDispatcher:ctor() self.listeners = {} end function EventDispatcher:AddListener(listener) self.listeners[listener.id] = listener end function EventDispatcher:RemoveListener(listener) self.listeners[listener.id] = nil end function EventDispatcher:IsListening(listener) return (self.listeners[listener.id] ~= nil) end function EventDispatcher:Match(eventType) local matchs = {} for k, v in pairs (self.listeners) do if (v.event.type == eventType) then table.insert(matchs, v) end end return matchs end function EventDispatcher:SendEvent(eventType, ) local matchs = self:Match(eventType) if (#matchs ~= 0) then for k, v in pairs (matchs) do v:OnEvent() end end end function EventDispatcher:SendTimeout(timerName) local matchs = self:Match(timerName) if (#matchs ~= 0) then for k, v in pairs (matchs) do v:OnTimeout() end end end -- only one instance dispatcher = EventDispatcher.new()
---------------------------------------------------------
-- Helper --------------------------------------------------------- Helper = class() function Helper:ctor() self.isPrint = false self.cmds = {} end function Helper:Print() if self.isPrint then Note() end end function Helper:AddTimer(name, interval) local hours = math.floor(interval / 3600) interval = interval - (hours * 3600) local minutes = math.floor(interval / 60) local seconds = interval - (minutes * 60) local status = AddTimer (name, hours, minutes, seconds, "dispatcher:SendTimeout(\"" .. name .. "\")", timer_flag.OneShot + timer_flag.Temporary + timer_flag.Replace, "") assert(status == error_code.eOK, "fail to create timer:" .. name) SetTimerOption(name, "send_to", 12) EnableTimer(name, true) ResetTimer(name) end function Helper:ResetTimer(name, interval) assert(IsTimer(name), "timer doesn't exist") EnableTimer(name, false) local hours = math.floor(interval / 3600) interval = interval - (hours * 3600) local minutes = math.floor(interval / 60) local seconds = interval - (minutes * 60) SetTimerOption(name, "hour", hours) SetTimerOption(name, "minute", minutes) SetTimerOption(name, "second", seconds) EnableTimer(name, true) ResetTimer(name) end function Helper:RemoveTimer(name) EnableTimer(name, false) DeleteTimer(name) end -- only one instance helper = Helper.new()
---------------------------------------------------------
-- Command --- Repeat: #4 xx (repeat 4 times for command xx) --- Delay: @3 (delay 3 seconds) --------------------------------------------------------- Command = class() function Command:ctor() self.cmds = {} self.isRunning = false self.thread = nil end function Command:ToTable(cmds) assert(type(cmds) == "string", "commands must be string type") local retVal = {} for k, v in pairs(utils.split(cmds, ";")) do if (string.sub(v, 1, 1) == "#") then -- convert repeat command local sb, se = string.find(v, "%s+") assert(sb ~= nil and se ~= nil, "wrong repeat command format") local times = tonumber(string.sub(v, 2, sb - 1)) local cmd = string.sub(v, se + 1) for i = 1, times, 1 do retVal[#retVal + 1] = cmd end else retVal[#retVal + 1] = v end end return retVal end function Command:Add(cmds) if (type(cmds) == "string") then cmds = self:ToTable(cmds) end assert(type(cmds) == "table", "commands must be string or table type") -- add cmds for k, v in pairs (cmds) do self.cmds[#self.cmds + 1] = v end -- wakeup to process self:Wakeup() end function Command:Clear() self.cmds = {} end function Command:Wakeup() if (self.thread == nil) then cmdSender.thread = coroutine.create(cmdSender.Do) end if (not self.isRunning) then coroutine.resume(self.thread) end 全部评论
专题导读
热门推荐
热门话题
阅读排行榜
|
请发表评论