Source code for pisak.signals

"""
Implementation of signal connecting strategy for ClutterScript.
"""
import sys
import inspect
from functools import wraps

from gi.repository import GObject

from pisak import logger


_LOG = logger.get_logger(__name__)


[docs]def wrap_function(function): """ Decorator that wraps a given function with some master function. :param function: function to be wrapped. :return: wrapper function with the given function wrapped inside. """ @wraps(function) def master_wrapper(*master_args): """ Master function which can accept any number of non-keyword arguments, inspects a wrapped function arguments specification and then just calls it in a proper way. If there are more arguments passed than the function can accept, then the excessive ones are ignored. """ args, varargs, _keywords, _defaults = inspect.getargspec(function) if not varargs and len(master_args) > len(args): _LOG.warning("Excessive arguments: {}, for function: {}".format( master_args[len(args) : ], function)) master_args = master_args[ : len(args)] return function(*master_args) return master_wrapper
[docs]def connect_function(gobject, signal, target, flags, function, data): """ Wrapper that connects a GObject signals handlers in a proper way, taking into consideration any requested flags or parameters. :param gobject: any :class:`GObject.GObject` instance. :param signal: signal name. :param target: object that should be passed to the handler as an argument, can be None. :param flags: any extra flags, supported now: GObject.ConnectFlags.AFTER. :param function: callable, handler function. :param data: any extra data, can be anything, depending on the 'function' signature. """ # TODO: # make 'git grep connect' and redirect all the resulted connections in here if target is not None: if GObject.ConnectFlags.AFTER == flags: gobject.connect_object_after(signal, function, target, data) else: gobject.connect_object(signal, function, target, data) elif GObject.ConnectFlags.AFTER == flags: gobject.connect_after(signal, function, data) else: gobject.connect(signal, function, data)
[docs]def connect_registered(script, gobject, signal, handler, target, flags, data): """ Alternate implementation of signal connector. Uses only registered functions instead of introspection. :param script: ClutterScript. :param gobject: any :class:`GObject.GObject` instance. :param signal: signal name. :param handler: callable, handler function. :param target: object that should be passed to the handler as an argument, can be None. :param flags: any extra flags, supported now: GObject.ConnectFlags.AFTER. :param data: any extra data, can be anything, depending on the 'function' signature. """ function = resolve_registered(handler) wrapped = wrap_function(function) connect_function(gobject, signal, target, flags, wrapped, data)
_HANDLER_MAP = {}
[docs]def resolve_registered(handler): """ Resolve registered function. :param handler: handler name. :return: callable, previously registered function. """ function = _HANDLER_MAP.get(handler) if function is not None: return function else: raise Exception("No such function: " + handler)
[docs]def register_function(handler, function): """ Registers a function as handler. :param handler: handler name. :param function: callable, handler function. """ if callable(function): _HANDLER_MAP[handler] = function else: raise Exception("Not a function", function)
[docs]def registered_handler(handler_name): """ Decorator. :param handler_name: name that the function should be regitered with. """ def f_reg(function): register_function(handler_name, function) return function return f_reg