From a4762aa45fcd12929aa28fe640f44a12b20c8e76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sergiusz=20=27q3k=27=20Baza=C5=84ski?= Date: Thu, 28 Nov 2013 11:55:44 +0100 Subject: [PATCH] New event mechanism, whois fixes --- core/plugin.lua | 12 ++----- core/reactor.lua | 53 +++++++++++++++++++++++------ plugins/bitcoin.lua | 8 ----- plugins/identification-freenode.lua | 14 +++++--- 4 files changed, 54 insertions(+), 33 deletions(-) diff --git a/core/plugin.lua b/core/plugin.lua index 8f29e35..7e41c67 100644 --- a/core/plugin.lua +++ b/core/plugin.lua @@ -43,17 +43,11 @@ function API.Sleep(plugin_id, Delay) plugin.ResumeQuota() end - -function API.WaitForEvent(plugin_id, Event) +function API.NewEvent(plugin_id, Event) plugin.PauseQuota() - reactor:WaitForEvent(Event) - plugin.ResumeQuota() -end - -function API.Event(plugin_id, Event) - plugin.PauseQuota() - reactor:Event(Event) + local Event = reactor:NewEvent(Event) plugin.ResumeQuota() + return Event end diff --git a/core/reactor.lua b/core/reactor.lua index 6397b93..24fb23d 100644 --- a/core/reactor.lua +++ b/core/reactor.lua @@ -14,6 +14,7 @@ function reactor:Initialize(quantum) self._coroutines = {} self._timers = {} + self._events = {} end function reactor:Quit() @@ -30,24 +31,54 @@ function reactor:Sleep(time) coroutine.yield() end -function reactor:WaitForEvent(event) - local co = coroutine.running() - if co == nil then +reactor.Event = {} +function reactor.Event:Wait() + if coroutine.running() == nil then error("Main thread waiting for event... wtf?") end - self._co_event[co] = event - coroutine.yield() + self.Waiting[#self.Waiting + 1] = coroutine.running() + local Status, Data = coroutine.yield() + if Status == false then + -- exception! + error(Data) + end + return unpack(Data) end - -function reactor:Event(event) - for Coroutine, Event in pairs(self._co_event) do - if Event == event then - coroutine.resume(Coroutine) - end +function reactor.Event:Fire(...) + local Data = {...} + -- make a local copy of the old waiters, and clear the new ones + local Waiters = {} + for i, Coroutine in pairs(self.Waiting) do + Waiters[#Waiters + 1] = Coroutine + end + self.Waiting = {} + for i, Coroutine in pairs(Waiters) do + coroutine.resume(Coroutine, true, Data) end end +function reactor.Event:Destroy() + -- destroy all waiters + for i, Coroutine in pairs(self.Waiting) do + coroutine.resume(Coroutine, false, "Coroutine destroyed.") + end + self.Reactor._events[self.Identifier] = nil +end + +function reactor:NewEvent() + local Table = {} + Table.Identifier = #self._events + 1 + Table.Reactor = self + Table.Waiting = {} + setmetatable(Table, reactor.Event) + reactor.Event.__index = reactor.Event + + self._events[Table.Identifier] = Identifier + return Table +end + + function reactor:Spawn(f, ...) local Args = {...} local co = coroutine.create(function() f(unpack(Args)) end) diff --git a/plugins/bitcoin.lua b/plugins/bitcoin.lua index 90ce808..be82ea3 100644 --- a/plugins/bitcoin.lua +++ b/plugins/bitcoin.lua @@ -11,11 +11,7 @@ local GetRates = function() end local Rates = {} -<<<<<<< HEAD - for _, Market in pairs(Rates) do -======= for _, Market in pairs(Data) do ->>>>>>> c6688a87ae38c2a483731ec9f4da072f2132c725 local Rate = {} Rate.high = Market.high Rate.low = Market.low @@ -27,11 +23,7 @@ local GetRates = function() end local FormatData = function(Rate, Key) -<<<<<<< HEAD - local Value = Rate[key] -======= local Value = Rate[Key] ->>>>>>> c6688a87ae38c2a483731ec9f4da072f2132c725 local Currency = Rate.currency return string.format("%.2f %s", Value, Currency) diff --git a/plugins/identification-freenode.lua b/plugins/identification-freenode.lua index 19a54cf..45264f4 100644 --- a/plugins/identification-freenode.lua +++ b/plugins/identification-freenode.lua @@ -4,24 +4,28 @@ local Pending = {} plugin.AddHook('auth.GetAccount', 'GetAccount', function(IRC, Username) if Map[Username] == nil then if not Pending[Username] then + -- create and event and wait for it + local Event = plugin.NewEvent() + Pending[Username] = Event IRC:Whois(Username) - Pending[Username] = true end - plugin.WaitForEvent("whois-"..Username) + return Pending[Username]:Wait() end return Map[Username] end) plugin.AddHook('irc.GetResponse330', 'WHOISResponse', function(_, Username, Account, Message) Map[Username] = Account - plugin.Event("whois-" .. Username) + if Pending[Username] ~= nil then + Pending[Username]:Fire(Account) + end end) -plugin.AddHook('irc.ChannelNames', 'ScanChannelUsers', function(Channel) +--[[ plugin.AddHook('irc.ChannelNames', 'ScanChannelUsers', function(Channel) for Nick, Member in pairs(Channel.Members) do if not Pending[Nick] then Channel:Whois(Nick) Pending[Nick] = true end end -end) +end) ]]--