Commit MetaInfo

Revisão4d54ef32a3a7df5aae647507921265d131597412 (tree)
Hora2012-02-15 19:11:12
Autorbijoux
Commiterbijoux

Mensagem de Log

Fixed recursive problem between Rule and Terminal

Mudança Sumário

Diff

diff -r 297a1b795a7a -r 4d54ef32a3a7 src/pylafii/mplext.py
--- a/src/pylafii/mplext.py Tue Feb 14 17:43:34 2012 +0900
+++ b/src/pylafii/mplext.py Wed Feb 15 19:11:12 2012 +0900
@@ -245,9 +245,13 @@
245245 self.xlabel = self._config['xlabel']
246246 self.ylabel = self._config['ylabel']
247247
248+class BasePlotPanel(Panel):
249+ def layout(self):
250+ Embed(self,BasePlot,name='result').pack()
251+
248252 class ScalarTable(Logic):
249253 value = Terminal()
250- format = Terminal('-+')
254+ format = Terminal('-')
251255 @rule('value')
252256 def result(self):
253257 if self.value is None: return (array([0.,1.]),array([0.,1.]))
diff -r 297a1b795a7a -r 4d54ef32a3a7 src/pylafii/term.py
--- a/src/pylafii/term.py Tue Feb 14 17:43:34 2012 +0900
+++ b/src/pylafii/term.py Wed Feb 15 19:11:12 2012 +0900
@@ -5,6 +5,9 @@
55
66 # class ConcreteTerminal(object)
77
8+#TRACE = True
9+TRACE = False
10+
811 class _PortException(Exception):
912 def __init__(self, value):
1013 self.value = value
@@ -62,22 +65,31 @@
6265 '''
6366 def __init__(self,init_value=None):
6467 self.init_value = init_value
65- self.name = None # 最初にset/get/linkが呼び出されたときにオーナーを検索して取得
68+ self.name = None # 最初にset/get/linkが呼び出されたときにオーナーを検索して取得
69+ self.from_rule = None
6670 def __get__(self, owner, ownertype):
67- if owner == None:
68- return self
69- else:
70- attr = self.get_attribute(owner)
71- # attr.node.getlog[attr] = None # get 参照したことを対象の node.getlog へ記録
72- attr.node.notify('get')
73- return attr.node.value
71+ if owner == None: return self
72+ attr = self.get_attribute(owner)
73+ #
74+ # set イベント処理中には get 参照されてもイベントは発行せずに set された内容を返す
75+ #
76+ try: self.__set_event
77+ except AttributeError: pass
78+ else: return attr.node.value
79+# attr.node.getlog[attr] = None # get 参照したことを対象の node.getlog へ記録
80+ if TRACE: print '= get = %s.%s' % (owner.__class__.__name__,self.name)
81+ attr.node.notify('get')
82+ return attr.node.value
7483 def __set__(self, owner, value):
7584 node = self.get_attribute(owner).node
7685 node.value = value
7786 node.getlog.clear() # node を変更したので node.getlog を消去
87+ if TRACE: print '= set = %s.%s' % (owner.__class__.__name__,self.name)
7888 node.notify('set')
7989 def notify(self, attr, event):
8090 if not event == 'set': return
91+ self.__set_event = True
92+ if TRACE: print '- set -> %s.%s' % (attr.owner().__class__.__name__,self.name)
8193 owner = attr.owner()
8294 #
8395 # 依存関係のある rule を起動
@@ -88,10 +100,19 @@
88100 term = attr.terminal()
89101 for name in term.dependency: # 未更新の Terminal がひとつもなければルールを実行する
90102 if name == self.name: # 1つでも自身に依存していたらルールを実行可能か評価する
91- for name in term.dependency: # 未更新の依存 Terminal がひとつでも見つかればルールを実行しない
92- if attr in terminal(owner,name).get_attribute(owner).node.getlog: break # ログに attr が見つかれば未更新
103+ for myname in term.dependency: # 未更新の依存 Terminal がひとつでも見つかればルールを実行しない
104+ if TRACE: print '[%s]' % myname,
105+ if attr in terminal(owner,myname).get_attribute(owner).node.getlog:
106+ if TRACE: print 'not modified'
107+ break # ログに attr が見つかれば未更新
93108 else: # break で脱出しなかった場合
94- if not len(attr.terminal().dependency) == 0: term.notify(attr,'get') # かつ依存関係が空()でない場合にはルールを実行する
109+ if not len(attr.terminal().dependency) == 0:
110+ if TRACE: print '\n%s.%s - get ->' % (attr.owner().__class__.__name__,self.name)
111+ term.notify(attr,'get') # かつ依存関係が空()でない場合にはルールを実行する
112+# if TRACE: print '\n%s.%s - get ->' % (attr.owner().__class__.__name__,self.name)
113+# term.notify(attr,'get')
114+ try: del self.__set_event
115+ except AttributeError: pass
95116 def get_name(self, owner): # オーナーインスタンスからの参照名を取得する
96117 if self.name == None: # オーナーインスタンスが生成されてから最初に参照されたときには名称探索をする
97118 # 呼び出しのコンテキストから、オーナーインスタンスにオブジェクトが存在することが保証されているので(はずなので)チェック省略
@@ -161,6 +182,7 @@
161182 if not event == 'get': return
162183 try: self.rule
163184 except: return # undefined rule error!!
185+ if TRACE: print '- get -> %s.%s' % (attr.owner().__class__.__name__,self.name)
164186 #
165187 # Event からの循環参照を検出したら脱出する
166188 #
@@ -182,9 +204,13 @@
182204 owner = attr.owner()
183205 for name in self.dependency: # 依存関係のある Terminal がひとつでも更新されていれば else 節を実行してなにもせず脱出
184206 myattr = terminal(owner,name).get_attribute(owner)
185- if not attr in myattr.node.getlog: break
207+ if TRACE: print '[%s]' % name,
208+ if not attr in myattr.node.getlog:
209+ if TRACE: print 'modified'
210+ break
186211 else: # 依存関係のある Terminal がひとつも更新されていなかった場合(break で脱出しなかった場合)
187- if not len(self.dependency) == 0: return # 依存関係が()の場合にも else 節が実行されてしまう例外処理
212+ if not len(self.dependency) == 0:
213+ return # 依存関係が()の場合にも else 節が実行されてしまう例外処理
188214 #
189215 # ルールの実行に先立って依存ターミナルへ get を通知しリンクを遡り getlog を更新する
190216 #
@@ -194,7 +220,7 @@
194220 for o in dependent.node.get_observers():
195221 if isinstance(o.terminal(),Rule):
196222 o.ignore[dependent] = None
197- getattr(owner,name)
223+ getattr(owner,name) # 依存ターミナルを参照してルール起動を試みる
198224 for o in dependent.node.get_observers():
199225 try:
200226 o.detected
@@ -213,16 +239,17 @@
213239 #
214240 # ルールの実行
215241 #
242+ if TRACE: print 'exec %s.%s.rule' % (attr.owner().__class__.__name__,self.name)
216243 attr.node.value = self.rule(owner) # rule を実行してその結果を node に保存する
217244 attr.node.getlog.clear() # node を変更したので node.getlog を消去
245+ if TRACE: print '%s.%s - set ->' % (attr.owner().__class__.__name__,self.name)
218246 attr.node.notify('set',ignore=attr.ignore)
219247 attr.ignore.clear()
220-
248+
221249 class Event(Terminal):
222250 def __init__(self,value=None,*args,**kw):
223251 Terminal.__init__(self,value)
224252 if 'rule' in kw: self.rule = kw['rule']
225- self.from_rule = None
226253 def notify(self, attr, event):
227254 if not event == 'set': return
228255 try: self.rule
diff -r 297a1b795a7a -r 4d54ef32a3a7 src/test/test_pylafii/anim.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/test/test_pylafii/anim.py Wed Feb 15 19:11:12 2012 +0900
@@ -0,0 +1,56 @@
1+# coding: utf-8
2+from pylafii import Terminal, rule, connect
3+from pylafii import Entry, Button
4+from pylafii import Logic, Equipment, Embed
5+from pylafii import MatrixPlotPanel
6+from pylafii import InteractiveWidget, Panel, Layout
7+from numpy import arange, zeros, pi, sin
8+from scipy import rand
9+import Tkinter
10+import weakref
11+
12+class AutoTrig(Logic):
13+ value = Terminal()
14+ class Control(Panel):
15+ def layout(self):
16+ InteractiveWidget(self,name='value').pack()
17+ self.children['value'].switch = True
18+ self.children['value'].interval = 10
19+
20+class LogicA(Logic):
21+ counter = 0
22+ freq = Terminal(0.01)
23+ points = Terminal(500)
24+ speed = Terminal(100)
25+ @rule()
26+ def result(self):
27+ a = zeros((self.points,2))
28+ a[:,0] = arange(self.points)
29+ a[:,1] = sin(2. * pi * self.freq * a[:,0] + 2. * pi * self.counter / self.speed)
30+ self.counter = self.counter + 1
31+ if self.counter >= self.speed: self.counter = 0
32+# a[:,1] = rand(self.points)
33+ return a
34+ class Control(Panel):
35+ def layout(self):
36+ Entry(self,name='freq').pack()
37+ Entry(self,name='points').pack()
38+ Entry(self,name='speed').pack()
39+ Button(self,name='result',text='Trig').pack()
40+ class Plot(MatrixPlotPanel): pass
41+
42+tk = Tkinter.Tk()
43+
44+o = Equipment(tk,LogicA).pack()
45+i = Embed(o.layout.rack,AutoTrig,Layout).pack()
46+connect((o.logic,'result'),(i.logic,'value'))
47+
48+#o.panel['plot'].children['result'].layout.popup_config()
49+#o.logic.nos = 8
50+#o.panel['plot'].children['result'].logic.plot.ax.set_title('TITLE')
51+
52+# print '-------------'
53+tk.mainloop()
54+
55+i = weakref.ref(i); print i
56+o = weakref.ref(o); print o
diff -r 297a1b795a7a -r 4d54ef32a3a7 src/test/test_pylafii/loop.py
--- a/src/test/test_pylafii/loop.py Tue Feb 14 17:43:34 2012 +0900
+++ b/src/test/test_pylafii/loop.py Wed Feb 15 19:11:12 2012 +0900
@@ -240,9 +240,9 @@
240240 self.assertEqual(a.status(),[True, True, True])
241241 self.assertEqual(b.status(),[True, True, True])
242242 b.a = 1
243- self.assertEqual(a.count,1); a.count = 0 # dependent が更新されているのでルールが1回実行される
243+ self.assertEqual(a.count,0); # ルールは評価されない
244244 self.assertEqual(b.count,1); b.count = 0 # dependent が更新されているのでルールが1回実行される
245- self.assertEqual(a.status(),[True, False, True])
245+ self.assertEqual(a.status(),[True, True, True])
246246 self.assertEqual(b.status(),[True, False, True])
247247 #
248248 # 循環接続した後に任意の dependent から get された場合
Show on old repository browser