diff options
author | hut <hut@lavabit.com> | 2010-03-30 04:50:38 +0200 |
---|---|---|
committer | hut <hut@lavabit.com> | 2010-03-30 04:50:38 +0200 |
commit | 1c1b6c31de513f0f056a915bf7d8e608c485ae50 (patch) | |
tree | b2dd0153d058cdbcf0c24b033703ab6d7f0efa8e /ranger | |
parent | 489a1616407a3d6c588b1890c9ddbf795ae5724f (diff) | |
download | ranger-1c1b6c31de513f0f056a915bf7d8e608c485ae50.tar.gz |
added SignalDispatcher class
Diffstat (limited to 'ranger')
-rw-r--r-- | ranger/core/fm.py | 4 | ||||
-rw-r--r-- | ranger/ext/signal_dispatcher.py | 79 |
2 files changed, 82 insertions, 1 deletions
diff --git a/ranger/core/fm.py b/ranger/core/fm.py index 94d0d85d..aef10150 100644 --- a/ranger/core/fm.py +++ b/ranger/core/fm.py @@ -26,18 +26,20 @@ from ranger.container import Bookmarks from ranger.core.runner import Runner from ranger import relpath_conf from ranger.ext.get_executables import get_executables +from ranger.ext.signal_dispatcher import SignalDispatcher from ranger import __version__ from ranger.fsobject import Loader CTRL_C = 3 TICKS_BEFORE_COLLECTING_GARBAGE = 100 -class FM(Actions): +class FM(Actions, SignalDispatcher): input_blocked = False input_blocked_until = 0 def __init__(self, ui=None, bookmarks=None, tags=None): """Initialize FM.""" Actions.__init__(self) + SignalDispatcher.__init__(self) self.ui = ui self.log = deque(maxlen=20) self.bookmarks = bookmarks diff --git a/ranger/ext/signal_dispatcher.py b/ranger/ext/signal_dispatcher.py new file mode 100644 index 00000000..542fb472 --- /dev/null +++ b/ranger/ext/signal_dispatcher.py @@ -0,0 +1,79 @@ +# Copyright (C) 2009, 2010 Roman Zimbelmann <romanz@lavabit.com> +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +class Signal(dict): + stopped = False + def __init__(self, **keywords): + dict.__init__(self, keywords) + self.__dict__ = self + + def stop(self): + self.stopped = True + + +class SignalHandler(object): + active = True + def __init__(self, signal_name, function, priority, pass_signal): + self.priority = max(0, min(1, priority)) + self.signal_name = signal_name + self.function = function + self.pass_signal = pass_signal + + +class SignalDispatcher(object): + def __init__(self): + self._signals = dict() + + signal_clear = __init__ + + def signal_bind(self, signal_name, function, priority=0.5): + assert isinstance(signal_name, str) + try: + handlers = self._signals[signal_name] + except: + handlers = self._signals[signal_name] = [] + nargs = function.__code__.co_argcount - hasattr(function, 'im_func') + handler = SignalHandler(signal_name, function, priority, nargs > 0) + handlers.append(handler) + handlers.sort(key=lambda handler: -handler.priority) + return handler + + def signal_unbind(self, signal_handler): + try: + handlers = self._signals[signal_handler.signal_name] + except KeyError: + pass + else: + handlers.remove(signal_handler) + + def signal_emit(self, signal_name, **kw): + assert isinstance(signal_name, str) + try: + handlers = self._signals[signal_name] + except: + return + if not handlers: + return + + signal = Signal(origin=self, name=signal_name, **kw) + + for handler in handlers: # propagate + if handler.active: + if handler.pass_signal: + handler.function(signal) + else: + handler.function() + if signal.stopped: + return |