[Anygui-checkins] CVS: anygui/lib/anygui Rules.py,1.13,1.14
Brought to you by:
mlh
From: Magnus L. H. <ml...@us...> - 2002-04-17 17:37:21
|
Update of /cvsroot/anygui/anygui/lib/anygui In directory usw-pr-cvs1:/tmp/cvs-serv24771 Modified Files: Rules.py Log Message: Checking in this just to have it in the repository. Will probably not use this approach (for now at least). Index: Rules.py =================================================================== RCS file: /cvsroot/anygui/anygui/lib/anygui/Rules.py,v retrieving revision 1.13 retrieving revision 1.14 diff -C2 -r1.13 -r1.14 *** Rules.py 8 Apr 2002 06:11:59 -0000 1.13 --- Rules.py 17 Apr 2002 17:37:15 -0000 1.14 *************** *** 1,76 **** ! class IllegalState(Exception): pass ! # TODO: ! # - Add checking of state integrity ! # - Add support for "full sync" without defs ! def addSubKey(dict, key, subkey): ! dict.setdefault(key, {})[subkey] = 1 ! # This is extremely klutzy and sketchy at the moment ! class AggregateRuleEngine: ! def __init__(self): ! self.parts = {} ! self.whole = {} ! self.rules = {} ! ! def getChildren(self, name): ! return self.parts.get(name, {}) ! ! def getOrderedChildren(self, name): ! return self.rules.get(name, []) ! ! def getParents(self, name): ! return self.whole.get(name, {}) ! ! def getSpouses(self, name): ! result = {} ! for child in self.getChildren(name).keys(): ! result.update(self.getParents(child)) ! try: del result[name] ! except: pass ! return result ! ! def define(self, rule): ! whole, parts = rule.split('=') ! whole = whole.strip() ! rule = [] ! for part in parts.split(','): ! part = part.strip() ! rule.append(part) ! addSubKey(self.whole, part, whole) ! addSubKey(self.parts, whole, part) ! self.rules[whole] = rule ! ! def sync(self, state, defs): undef = {} ! for name in defs: ! undef.update(self.getChildren(name)) ! undef.update(self.getParents(name)) ! undef.update(self.getSpouses(name)) stable = 0 while undef and not stable: ! stable = 1 ! for name in undef.keys(): ! newValue = self.newValue(name, state, undef) ! if newValue is not None: ! state[name] = newValue ! del undef[name] stable = 0 return undef.keys() - - def newValue(self, name, state, undef): - for parent in self.getParents(name).keys(): - if not undef.has_key(parent): - pos = self.rules[parent].index(name) - return state[parent][pos] - value = [] - for child in self.getOrderedChildren(name): - if undef.has_key(child): - return None - else: - value.append(state[child]) - return tuple(value) or None --- 1,85 ---- ! # ********** Experimental version ********** ! # Doesn't work properly yet (the geometry test in test_rules fails.) ! # E.g. position isn't directly damaged by geometry, and is therefore ! # treated as defined (which it isn't)... ! # TODO: ! # Add error checking for underspecified stuff... ! # Iterative stuff...? ! class GroupRule: ! def __init__(self, name, parts): ! self.name = name ! self.deps = parts ! self.inverses = [] ! for i in range(len(parts)): ! rule = SplitRule(parts[i], name, i) ! self.inverses.append(rule) ! def fire(self, state, locked): ! value = [] ! for i in range(len(self.deps)): ! value.append(state[self.deps[i]]) ! value = tuple(value) ! if self.name in locked and tuple(state[self.name]) != value: ! raise Exception # Be more specific... :) ! state[self.name] = value ! ! class SplitRule: ! def __init__(self, name, whole, index): ! self.name = name ! self.deps = [whole] ! self.index = index ! def fire(self, state, locked): ! value = state[self.deps[0]][self.index] ! if self.name in locked and value != state[self.name]: ! raise Exception # Be more specific... :) ! state[self.name] = value ! if locked == ['geometry']: # DEBUG ! print self.name, '=', value, '[', self.deps[0], ']' ! class RuleEngine: def __init__(self): ! self.rules = [] ! self.damage = {} ! def getDamage(self, dep): ! return self.damage.setdefault(dep, {}) ! def addDamage(self, dep, name): ! self.getDamage(dep)[name] = 1 ! def define(self, string): ! name, expr = string.split('=') ! name = name.strip() ! deps = [n.strip() for n in expr.split(',')] ! rule = GroupRule(name, deps) ! self.rules.append(rule) ! self.rules.extend(rule.inverses) ! for rule in [rule] + rule.inverses: ! for dep in rule.deps: ! self.addDamage(dep, rule.name) ! def sync(self, state, locked): ! DEBUG = locked == ['geometry'] undef = {} ! finished = {} # Hack ! for name in locked: ! undef.update(self.getDamage(name)) ! finished[name] = 1 stable = 0 while undef and not stable: ! for rule in self.rules: ! if finished.has_key(rule.name) or not undef.has_key(rule.name): continue ! for dep in rule.deps: ! if DEBUG: print dep ! if undef.has_key(dep) and not finished.has_key(dep): ! break ! else: ! rule.fire(state, locked) stable = 0 + del undef[rule.name] + finished[rule.name] = 1 + # Hack: + for key, val in self.getDamage(rule.name).items(): + if not finished.has_key(key): + undef[key] = val + #undef.update(self.getDamage(rule.name)) return undef.keys() |