Trellis: ctrl.pulse

Sergey Schetinin <[email protected]> Wed, 15 Apr 2009 23:11:05 +0300
Newsgroups gmane.comp.python.peak
Message-ID <[email protected]>
Importing trellis from stm is ugly, and messes with lazy imports of
trellis (as done by Importing), replacing pulse with a special cell
doesn't seem to hard, see attached patch.



-- 
Best Regards,
Sergey Schetinin

http://s3bk.com/ -- S3 Backup
http://word-to-html.com/ -- Word to HTML Converter

_______________________________________________
PEAK mailing list
[email protected]
http://www.eby-sarna.com/mailman/listinfo/peak
pulse2.patch (application/octet-stream, 4.4 KB)
Index: stm.py
===================================================================
--- stm.py	(revision 2599)
+++ stm.py	(working copy)
@@ -278,13 +279,15 @@



+class _Pulse(AbstractSubject):
+    __slots__ = 'next_listener'
+    def __init__(self):
+        self.next_listener = None
+    def __call__(self, ctrl):
+        map(ctrl.schedule, self.iter_listeners())
+        self.next_listener = None


-
-
-
-
-
 class Controller(STMHistory):
     """STM History with support for subjects, listeners, and queueing"""
     current_listener = destinations = routes = newcells = None
@@ -298,6 +300,7 @@
         self.layers = []    # heap of layer numbers
         self.queues = {}    # [layer]    -> dict of listeners to be run
         self.to_retry = {}
+        self.pulse = _Pulse()

     def checkpoint(self):
         self.has_run.clear()
@@ -319,13 +322,6 @@
             self.to_retry.clear()
             self.destinations = self.routes = None

-    def __getattr__(self, name):
-        if name=='pulse':   # lazy init due to circular dependency
-            from peak.events.trellis import Value
-            self.pulse = Value(0)
-            return self.pulse
-        raise AttributeError(name)
-
     def _unrun(self, listener, notified):
         destinations = self.destinations
         if destinations is not None:
@@ -341,10 +337,10 @@
         old = self.current_listener
         self.current_listener = listener
         try:
-            assert listener not in self.has_run,"Re-run of rule without retry"
+            assert listener not in self.has_run, "Re-run of rule without retry"
             assert self.active, "Rules must be run atomically"
             if old is not None:
-                assert not initialized,"Only un-initialized rules can be nested"
+                assert not initialized, "Only un-initialized rules can be nested"
                 old_reads, self.reads = self.reads, {}
                 try:
                     listener.run()
@@ -366,7 +362,7 @@
                     raise
         finally:
             self.current_listener = old
-
+
     def _process_writes(self, listener):
         #
         # Remove changed items from self.writes and notify their listeners,
@@ -444,8 +446,8 @@
             q = get(new)

         if q is None:
-             q = self.queues[new] = {listener:1}
-             heapq.heappush(self.layers, new)
+            q = self.queues[new] = {listener:1}
+            heapq.heappush(self.layers, new)
         else:
             q[listener] = 1

@@ -471,7 +473,7 @@
             layers = self.layers
             queues = self.queues
             while layers or self.at_commit:
-                self.pulse.value += 1
+                self.pulse(self)
                 while layers:
                     if self.to_retry:
                         self._retry()
Index: trellis.py
===================================================================
--- trellis.py	(revision 2599)
+++ trellis.py	(working copy)
@@ -571,7 +597,6 @@



-
 class _Defaulting(addons.Registry):
     def __init__(self, subject):
         self.defaults = {}
@@ -667,7 +692,8 @@
     if listener is None or not hasattr(listener, '_needs_init'):
         raise RuntimeError("poll() must be called from a rule")
     else:
-        return ctrl.pulse.value
+        on_undo(stm.Link(ctrl.pulse, listener).unlink)

 def mark_dirty():
     """Force the current rule's return value to be treated as if it changed"""
@@ -679,7 +705,6 @@
     if hasattr(rule, '__get__'):
         return rule.__get__(ob, typ)
     return rule
-



@@ -833,7 +862,7 @@
             if getattr(func, '__name__', None)==self.__name__:
                 frame = frame or sys._getframe(2)
                 if frame.f_locals.get(self.__name__) is self:
-                    return self
+                    return self
             return func

         frame = frame or sys._getframe(2)
@@ -844,7 +873,6 @@
             return func

         return decorators.decorate_assignment(callback, frame=frame)
-



@@ -859,6 +887,7 @@



+
 def attr(initially=NO_VALUE, resetting_to=NO_VALUE):
     return CellAttribute.mkattr(initially, resetting_to)

@@ -1104,7 +1133,7 @@
         rule=rule, initially=initially, resetting_to=resetting_to, make=make,
         __proptype = CacheAttr.mkattr
     )
-
+
 class Dict(UserDict.IterableUserDict, Component):
     """Dictionary-like object that recalculates observers when it's changed