import sys,os from tree import * sys.path.insert(0,os.pardir) from constant import * HASCYCLE=1 NOCYCLE=0 __verbose__=0 class Data: def __init__(self, dict, xpos, ypos): self.xpos=xpos self.ypos=ypos self.parents=[] # the cell data depend on me self.children=[] # the cell data on which I depend. self.tree=None self.val=None self.data_dict=dict def getXPosition(self): return self.xpos def getYPosition(self): return self.ypos def getValue(self): return self.val def setTree(self, tree): changedcells=[] if tree==None: self.tree=None self.val=None self.children=[] self.notify(changedcells) return changedcells self.cyclestr=[] dep=self.checkDependence((self.xpos,self.ypos),self.cyclestr, tree) if dep==HASCYCLE: if __verbose__: for s in self.cyclestr: print s print 'cyclic dependence detected.' return (CYCLICDEPENDENCEERROR, self.cyclestr) else: # # remove this cell data from it's current children's parent list, since # new relationship is defined by a new tree. # for child in self.children: child.removeParent(self) self.tree=tree # # update the children of this cell data # self.children=[] #remove all the previous children. iterator=tree.createIterator() while not iterator.isDone(): node=iterator.next() if isinstance(node, CellNode): self.children.append(self.data_dict[(node.row,node.col)]) #print `self.children` # # Update add this cell node to its new children's parent list # for child in self.children: child.addParent(self) # # Calculate the new value for this cell node if possible, which means all its # children are defined. # childrendefined=1 for child in self.children: if child.getValue==None: childrendefined=0 break # # this cell node, its parents, and its parents' parents will change their value # since they all directly or indirectly depend on this cell node. # # self.notify(changedcells) if __verbose__: for d in changedcells: print `d` return changedcells def notify(self, changedcells): # # Calculate the new value for this cell node if possible, which means all its # children are defined. # childrendefined=1 for child in self.children: if child.getValue()==None: childrendefined=0 break if childrendefined and (not self.tree==None): self.val=self.tree.root.interpret(self.data_dict) else: self.val=None changedcells.append(self) if __verbose__: for p in self.parents: print `p` for parent in self.parents: parent.notify(changedcells) def checkDependence(self, cellposition, cyclestr, tree=None): if tree==None: tree=self.tree if tree==None: return NOCYCLE iterator=tree.createIterator() while not iterator.isDone(): node=iterator.next() if isinstance(node, NumNode): pass elif isinstance(node, CellNode): if (node.row, node.col)==cellposition: cyclestr.insert(0,'$%d$%d-->$%d$%d'%(self.xpos, self.ypos,node.row,node.col)+\ '\t'+'$%d$%d'%(self.xpos,self.ypos)+'='+`tree`) return HASCYCLE else: if self.data_dict[(node.row, node.col)].checkDependence(cellposition, cyclestr): cyclestr.insert(0, '$%d$%d-->$%d$%d' %(self.xpos,self.ypos,node.row,node.col)+\ '\t'+'$%d$%d'%(self.xpos,self.ypos)+'='+`tree`) return HASCYCLE else: pass else: pass # it should raise an error. return NOCYCLE def getParents(self): return self.parents def getChildren(self): return self.children def addParent(self, parent): self.parents.append(parent) def removeParent(self, parent): self.parents.remove(parent) def addChildList(self, childlist): self.parent.children=childlist def __repr__(self): return '('+'('+`self.xpos`+','+`self.ypos`+')'+','+`self.val`+')'