From e943a556267c5c5ca2958208482ded870afaf929 Mon Sep 17 00:00:00 2001 From: nemunaire Date: Fri, 4 Sep 2015 17:07:21 +0200 Subject: [PATCH] wip event manager --- nemubot/event/__init__.py | 65 ++++++++++++++++++++------------------- nemubot/modulecontext.py | 6 ++-- 2 files changed, 38 insertions(+), 33 deletions(-) diff --git a/nemubot/event/__init__.py b/nemubot/event/__init__.py index 96f226a..345200d 100644 --- a/nemubot/event/__init__.py +++ b/nemubot/event/__init__.py @@ -24,8 +24,8 @@ class ModuleEvent: """Representation of a event initiated by a bot module""" def __init__(self, call=None, call_data=None, func=None, func_data=None, - cmp=None, cmp_data=None, interval=60, offset=0, times=1): - + cmp=None, cmp_data=None, end_call=None, end_data=None, + interval=60, offset=0, times=1, max_attempt=-1): """Initialize the event Keyword arguments: @@ -35,9 +35,12 @@ class ModuleEvent: func_data -- Argument(s) (single or dict) to pass as argument OR if no func, initial data to watch cmp -- Boolean function called to check changes cmp_data -- Argument(s) (single or dict) to pass as argument OR if no cmp, data compared to previous + end_call -- Function called when times or max_attempt reach 0 (mainly for interaction with the event manager) + end_data -- Argument(s) (single or dict) to pass as argument interval -- Time in seconds between each check (default: 60) offset -- Time in seconds added to interval before the first check (default: 0) times -- Number of times the event has to be realized before being removed; -1 for no limit (default: 1) + max_attempt -- Maximum number of times the event will be checked """ # What have we to check? @@ -46,16 +49,17 @@ class ModuleEvent: # How detect a change? self.cmp = cmp - self.cmp_data = None if cmp_data is not None: self.cmp_data = cmp_data - elif self.func is not None: + elif callable(self.func): if self.func_data is None: self.cmp_data = self.func() elif isinstance(self.func_data, dict): self.cmp_data = self.func(**self.func_data) else: self.cmp_data = self.func(self.func_data) + else: + self.cmp_data = None # What should we call when? self.call = call @@ -64,46 +68,29 @@ class ModuleEvent: else: self.call_data = func_data - # Store times - self.offset = timedelta(seconds=offset) # Time to wait before the first check + # Store time between each event self.interval = timedelta(seconds=interval) - self._end = None # Cache - # How many times do this event? self.times = times - @property - def current(self): - """Return the date of the near check""" - if self.times != 0: - if self._end is None: - self._end = datetime.now(timezone.utc) + self.offset + self.interval - return self._end - return None + # Cache the time of the next occurence + self.next_occur = datetime.now(timezone.utc) + timedelta(seconds=offset) + self.interval - @property - def next(self): - """Return the date of the next check""" - if self.times != 0: - if self._end is None: - return self.current - elif self._end < datetime.now(timezone.utc): - self._end += self.interval - return self._end - return None @property def time_left(self): """Return the time left before/after the near check""" - if self.current is not None: - return self.current - datetime.now(timezone.utc) - return 99999 # TODO: 99999 is not a valid time to return + + return self.next_occur - datetime.now(timezone.utc) + def check(self): """Run a check and realized the event if this is time""" + self.max_attempt -= 1 + # Get initial data - if self.func is None: + if not callable(self.func): d_init = self.func_data elif self.func_data is None: d_init = self.func() @@ -113,7 +100,7 @@ class ModuleEvent: d_init = self.func(self.func_data) # then compare with current data - if self.cmp is None: + if not callable(self.cmp): if self.cmp_data is None: rlz = True else: @@ -138,3 +125,19 @@ class ModuleEvent: self.call(d_init, **self.call_data) else: self.call(d_init, self.call_data) + + # Is it finished? + if self.times == 0 or self.max_attempt == 0: + if not callable(self.end_call): + pass # TODO: log a WARN here + else: + if self.end_data is None: + self.end_call() + elif isinstance(self.end_data, dict): + self.end_call(**self.end_data) + else: + self.end_call(self.end_data) + + # Not finished, ready to next one! + else: + self.next_occur += self.interval diff --git a/nemubot/modulecontext.py b/nemubot/modulecontext.py index 5b47278..0814215 100644 --- a/nemubot/modulecontext.py +++ b/nemubot/modulecontext.py @@ -51,7 +51,7 @@ class ModuleContext: self.config = ModuleState("module") self.hooks = list() - self.events = list() + self.events = list() # Un eventManager, qui contient une liste globale et un thread global et quelques méthodes statique, mais chaque événement est exécuté dans son propre contexte :) self.debug = context.verbosity > 0 if context is not None else False # Define some callbacks @@ -79,7 +79,9 @@ class ModuleContext: def subtreat(msg): yield from context.treater.treat_msg(msg) def add_event(evt, eid=None): - return context.add_event(evt, eid, module_src=module) + eid = context.add_event(evt, eid, module_src=module) + self.events.append(eid) + return eid def del_event(evt): return context.del_event(evt, module_src=module)