From c708e9f57b44f564b6b26acc10c035ac2a10d560 Mon Sep 17 00:00:00 2001 From: Daniel Brown <ddb@star.sr.bham.ac.uk> Date: Tue, 16 Aug 2016 19:33:28 -0700 Subject: [PATCH] Cleaning up removing of components/commands/detectors and loose references. Fixing block remove --- pykat/commands.py | 21 +++++++++++++++++---- pykat/components.py | 24 ++++++++++++++---------- pykat/detectors.py | 3 +++ pykat/finesse.py | 7 +++++-- pykat/param.py | 45 +++++++++++++++++++++++++++++---------------- 5 files changed, 68 insertions(+), 32 deletions(-) diff --git a/pykat/commands.py b/pykat/commands.py index 5df7a6b..83aa6f0 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 da2aca3..345e60c 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 4b1b7db..757494a 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 94403c9..3f9971f 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 72740a8..440473c 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) -- GitLab