diff --git a/pykat/commands.py b/pykat/commands.py index 5df7a6b28c25ca667709a71a4d7116516dc3c37a..83aa6f0b81f34048369908cc73d4868234f633f9 100644 --- a/pykat/commands.py +++ b/pykat/commands.py @@ -53,12 +53,25 @@ class Command(object): for _ in self._putters_to_register: kat.registerVariable(_.name, _) - def remove(self): - self._kat.remove(self) + def _on_kat_remove(self): self.__removed = True - for _ in self._putters_to_register: - kat.unregisterVariable(_.name) + for i in range(len(self._putters_to_register)): + _ = self._putters_to_register[i] + + self._kat.unregisterVariable(_.name) + _.clearPuts() + + del self._putters_to_register[i] + + del self._putters_to_register[:] + + + def remove(self): + if self.__removed: + raise pkex.BasePyKatException("{0} has already been marked as removed".format(self.name)) + else: + self._kat.remove(self) @property def name(self): return self.__name diff --git a/pykat/components.py b/pykat/components.py index da2aca3589843796d08e75acbc291754c4de4c42..345e60c45aafbdd56a444e26b098780773e1d1bc 100644 --- a/pykat/components.py +++ b/pykat/components.py @@ -162,7 +162,17 @@ class Component(object): self._kat = kat kat.nodes.registerComponentNodes(self, self._requested_node_names, self.__on_node_change) + + def _on_kat_remove(self): + # inform all parameters that we have removed its owner + # so that it can then warn about any puts/vars/xaxis + for p in self._params: + p._onOwnerRemoved() + del self._params[:] + + self.__removed = True + def __on_node_change(self): # need to update the node gauss parameter setter members self.__update_node_setters() @@ -237,16 +247,10 @@ class Component(object): def __str__(self): return self.name def remove(self): - self._kat.remove(self) - - # inform all parameters that we have removed its owner - # so that it can then warn about any puts/vars/xaxis - for p in self._params: - p._onOwnerRemoved() - - del self._params[:] - - self.__removed = True + if self.__removed: + raise pkex.BasePyKatException("{0} has already been marked as removed".format(self.name)) + else: + self._kat.remove(self) def getOptivisParameterDict(self): if len(self._params) == 0: diff --git a/pykat/detectors.py b/pykat/detectors.py index 4b1b7db9da74b87992b12a4593debfd3955ee040..757494aa8df653068d1456a9415c6b350d732329 100644 --- a/pykat/detectors.py +++ b/pykat/detectors.py @@ -120,6 +120,9 @@ class BaseDetector(object) : if rn != None: self._nodes.append(kat.nodes.createNode(rn)) + def _on_kat_remove(self): + self.__removed = True + def remove(self): if self.__removed: raise pkex.BasePyKatException("{0} has already been marked as removed".format(self.name)) diff --git a/pykat/finesse.py b/pykat/finesse.py index 94403c987e18b6ef6bdb566f87c4ffbd145b9e56..3f9971fca6fff0fc99570f0796f8fddcc3932c2a 100644 --- a/pykat/finesse.py +++ b/pykat/finesse.py @@ -997,8 +997,8 @@ class kat(object): sys.exit(1) else: return - - for o in self.__blocks[name].contents: + + for o in self.__blocks[name].contents.copy(): self.remove(o) del self.__blocks[name] @@ -1810,6 +1810,9 @@ class kat(object): del nodes + if hasattr(obj, "_on_kat_remove"): + obj._on_kat_remove() + #import gc #print (gc.get_referrers(obj)) diff --git a/pykat/param.py b/pykat/param.py index 72740a8e73d2ed82c525db92e128e9c9fc6e4c75..440473c5a0ccf6ccd1c6cd4973a210280bac5b3f 100644 --- a/pykat/param.py +++ b/pykat/param.py @@ -27,29 +27,30 @@ class putable(object): @property def isPutable(self): return self._isPutable - def put(self, var, alt): - if not isinstance(var, putter): + def put(self, var, alt=False): + if var is not None and not isinstance(var, putter): raise pkex.BasePyKatException("`%s` was not something that can be `put` to a parameter" % str(var)) - if self._putter is not None: - self._putter.put_count -= 1 - self._putter.putees.remove(self) + # Remove existing puts + if self._putter is not None: self._putter().unregister(self) - self._putter = var + if var is not None: + self._putter = weakref.ref(var) + else: + self._putter = None + self._alt = alt - if var is not None: - self._putter.put_count += 1 - self._putter.putees.append(self) + if var is not None: self._putter().register(self) def _getPutFinesseText(self): rtn = [] - if self._putter is not None: + if self._putter is not None and self._putter() is not None: putter_enabled = True - if hasattr(self._putter.owner, 'enabled'): - putter_enabled = self._putter.owner.enabled + if hasattr(self._putter().owner, 'enabled'): + putter_enabled = self._putter().owner.enabled if putter_enabled: if self._alt: @@ -58,7 +59,7 @@ class putable(object): alt = '' # if something is being put to this - rtn.append("put{alt} {comp} {param} ${value}".format(alt=alt, comp=self._component_name, param=self._parameter_name, value=self._putter.put_name())) + rtn.append("put{alt} {comp} {param} ${value}".format(alt=alt, comp=self._component_name, param=self._parameter_name, value=self._putter().put_name())) return rtn @@ -73,11 +74,23 @@ class putter(object): self.put_count = 0 self._isPutter = isPutter self.putees = [] # list of params that this puts to - self.__owner = owner + self.__owner = weakref.ref(owner) assert(owner is not None) + def clearPuts(self): + for _ in self.putees: + _.put(None) + + def register(self, toput): + self.put_count += 1 + self.putees.append(toput) + + def unregister(self, item): + self.put_count -= 1 + self.putees.remove(item) + @property - def owner(self): return self.__owner + def owner(self): return self.__owner() @property def name(self): return self._put_name @@ -114,7 +127,7 @@ class Param(putable, putter): if var_name is None: var_name = "var_{0}_{1}".format(owner.name, name) - putter.__init__(self, var_name, isPutter) + putter.__init__(self, var_name, owner, isPutter) putable.__init__(self, owner.name, name, isPutable)