[kupfer: 5/53] commandexec: Allow passing down an ExecutionToken with Action.activate
- From: Ulrik Sverdrup <usverdrup src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [kupfer: 5/53] commandexec: Allow passing down an ExecutionToken with Action.activate
- Date: Thu, 24 Mar 2011 16:30:58 +0000 (UTC)
commit 3d3acac48c5671773c8f566373865eac5c110b0a
Author: Ulrik Sverdrup <ulrik sverdrup gmail com>
Date: Thu Mar 24 17:22:32 2011 +0100
commandexec: Allow passing down an ExecutionToken with Action.activate
Shift the model away from global state, and pass along a context
object with each activate.
To keep compatibility, an action has to define::
def wants_context(self):
return True
And the action will receive an ExecutionToken as the ctx keyword
argument in activate or activate-multiple::
def activate(self, obj, iobj, ctx):
pass
kupfer/commandexec.py | 66 +++++++++++++++++++++++++++++++++++++++---------
kupfer/obj/base.py | 8 ++++++
2 files changed, 61 insertions(+), 13 deletions(-)
---
diff --git a/kupfer/commandexec.py b/kupfer/commandexec.py
index 8e7f649..fe87edf 100644
--- a/kupfer/commandexec.py
+++ b/kupfer/commandexec.py
@@ -68,33 +68,40 @@ def _get_leaf_members(leaf):
def _is_multiple(leaf):
return hasattr(leaf, "get_multiple_leaf_representation")
-def activate_action(obj, action, iobj):
+def _wants_context(action):
+ return action.wants_context()
+
+def activate_action(context, obj, action, iobj):
""" Activate @action in simplest manner """
+ kwargs = {}
+ if _wants_context(action):
+ kwargs['ctx'] = context
if not _is_multiple(obj) and not _is_multiple(iobj):
- return _activate_action_single(obj, action, iobj)
+ return _activate_action_single(obj, action, iobj, kwargs)
else:
- return _activate_action_multiple(obj, action, iobj)
+ return _activate_action_multiple(obj, action, iobj, kwargs)
-def _activate_action_single(obj, action, iobj):
+def _activate_action_single(obj, action, iobj, kwargs):
if action.requires_object():
- ret = action.activate(obj, iobj)
+ ret = action.activate(obj, iobj, **kwargs)
else:
- ret = action.activate(obj)
+ ret = action.activate(obj, **kwargs)
return ret
-def _activate_action_multiple(obj, action, iobj):
+def _activate_action_multiple(obj, action, iobj, kwargs):
if not hasattr(action, "activate_multiple"):
iobjs = (None, ) if iobj is None else _get_leaf_members(iobj)
return _activate_action_multiple_multiplied(_get_leaf_members(obj),
- action, iobjs)
+ action, iobjs, kwargs)
if action.requires_object():
- ret = action.activate_multiple(_get_leaf_members(obj), _get_leaf_members(iobj))
+ ret = action.activate_multiple(_get_leaf_members(obj),
+ _get_leaf_members(iobj), kwargs)
else:
- ret = action.activate_multiple(_get_leaf_members(obj))
+ ret = action.activate_multiple(_get_leaf_members(obj), **kwargs)
return ret
-def _activate_action_multiple_multiplied(objs, action, iobjs):
+def _activate_action_multiple_multiplied(objs, action, iobjs, kwargs):
"""
Multiple dispatch by "mulitplied" invocation of the simple activation
@@ -103,7 +110,7 @@ def _activate_action_multiple_multiplied(objs, action, iobjs):
rets = []
for L in objs:
for I in iobjs:
- ret = _activate_action_single(L, action, I)
+ ret = _activate_action_single(L, action, I, kwargs)
rets.append(ret)
ctx = DefaultActionExecutionContext()
ret = ctx._combine_action_result_multiple(action, rets)
@@ -124,6 +131,37 @@ def parse_action_result(action, ret):
res = RESULT_ASYNC
return res
+class ExecutionToken (object):
+ """
+ A token object that an ``Action`` carries with it
+ from ``activate``.
+
+ Must be used for access to current execution context,
+ and to access the environment.
+ """
+ def __init__(self, aectx, async_token, ui_ctx):
+ self._aectx = aectx
+ self._token = async_token
+ self._ui_ctx = ui_ctx
+
+ def register_late_result(self, result_object, show=True):
+ self._aectx.register_late_result(self._token, result_object, show=show)
+
+ def register_late_error(self, exc_info=None):
+ self._aectx.register_late_error(self._token, exc_info)
+
+ def delegated_run(self, *objs):
+ return self._aectx.run(*objs, delegate=True)
+
+ def get_environment_timestamp(self):
+ raise NotImplementedError
+
+ def get_environment_startup_notification_id(self):
+ raise NotImplementedError
+
+ def get_environment_screen(self):
+ raise NotImplementedError
+
class ActionExecutionContext (gobject.GObject, pretty.OutputMixin):
"""
@@ -246,9 +284,11 @@ class ActionExecutionContext (gobject.GObject, pretty.OutputMixin):
if iobj is None and action.requires_object():
raise ActionExecutionError("%s requires indirect object" % action)
+ # The execution token object for the current invocation
+ execution_token = ExecutionToken(self, self.get_async_token(), None)
with self._error_conversion(obj, action, iobj):
with self._nesting():
- ret = activate_action(obj, action, iobj)
+ ret = activate_action(execution_token, obj, action, iobj)
# remember last command, but not delegated commands.
if not delegate:
diff --git a/kupfer/obj/base.py b/kupfer/obj/base.py
index 61f6c60..4fd5da9 100644
--- a/kupfer/obj/base.py
+++ b/kupfer/obj/base.py
@@ -245,6 +245,14 @@ class Action (KupferObject):
"""
pass
+ def wants_context(self):
+ """Return ``True`` if ``activate`` should receive the
+ ActionExecutionContext as the keyword argument context
+
+ Defaults to ``False`` in accordance with the old protocol
+ """
+ return False
+
def is_factory(self):
"""Return whether action may return a result collection as a Source"""
return False
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]