diff --git a/dfhack/python/pydfhack/decorators.py b/dfhack/python/pydfhack/decorators.py index 702cf18f9..db0f565fd 100644 --- a/dfhack/python/pydfhack/decorators.py +++ b/dfhack/python/pydfhack/decorators.py @@ -7,9 +7,14 @@ from decorator import decorator @decorator def suspend(func, self, *args, **kw): """ - This decorator will try to suspend DF and start needed module before running func + This decorator will try to suspend DF and start needed module before running func. + If DF was resumed when decorator was run, it will try to resume back after executing func """ + susp = not self.api.is_attached or self.api.is_suspended if self.prepare(): - return func(self, *args, **kw) + res = func(self, *args, **kw) + if not susp: + self.api.Resume() + return res else: raise Exception(u"Could not suspend/start") diff --git a/dfhack/python/pydfhack/mixins.py b/dfhack/python/pydfhack/mixins.py index 67e069b70..29ef213d0 100644 --- a/dfhack/python/pydfhack/mixins.py +++ b/dfhack/python/pydfhack/mixins.py @@ -20,8 +20,13 @@ class NeedsStart(object): return False def Start(self): + if self.started: + return True + if self.api.prepare(): self.started = self.cls.Start(self) + if self.started: + self.api.started.append(self) return self.started else: return False @@ -32,6 +37,8 @@ class NeedsStart(object): if self.started: self.cls.Finish(self) self.started = False + if self in self.api.started: + self.api.started.remove(self) finish = Finish diff --git a/dfhack/python/pydfhack/pydfapi.py b/dfhack/python/pydfhack/pydfapi.py index c172bc05f..94efb5f9a 100644 --- a/dfhack/python/pydfhack/pydfapi.py +++ b/dfhack/python/pydfhack/pydfapi.py @@ -10,33 +10,43 @@ from .construction import Construction from .vegetation import Vegetation from .gui import GUI class API(_pydfhack._API): - for file in ["Memory.xml", os.path.join("..","..","output","Memory.xml")]: - if os.path.isfile(file): - datafile = file - break - else: - raise ImportError, "Memory.xml not found." + started = None + + for file in ["Memory.xml", os.path.join("..","..","output","Memory.xml")]: + if os.path.isfile(file): + datafile = file + break + else: + raise ImportError, "Memory.xml not found." - def prepare(self): - """ - Enforce Attach/Suspend behavior. - Return True if succeeded, else False - """ - r = True - if not self.is_attached: - r = self.Attach() - if r and not self.is_suspended: - r = self.Suspend() - return r + def prepare(self): + """ + Enforce Attach/Suspend behavior. + Return True if succeeded, else False + """ + r = True + if not self.is_attached: + r = self.Attach() + if r and not self.is_suspended: + r = self.Suspend() + return r - def __init__(self, *args, **kwds): - _pydfhack._API.__init__(self, API.datafile) - self._mem_info_mgr_type = MemInfo - self._position_mgr_type = Position - self._material_mgr_type = Materials - self._creature_mgr_type = Creature - self._map_mgr_type = Map - self._translate_mgr_type = Translation - self._construction_mgr_type = Construction - self._vegetation_mgr_type = Vegetation - self._gui_mgr_type = GUI + def __init__(self, *args, **kwds): + _pydfhack._API.__init__(self, API.datafile) + self._mem_info_mgr_type = MemInfo + self._position_mgr_type = Position + self._material_mgr_type = Materials + self._creature_mgr_type = Creature + self._map_mgr_type = Map + self._translate_mgr_type = Translation + self._construction_mgr_type = Construction + self._vegetation_mgr_type = Vegetation + self._gui_mgr_type = GUI + self.started = [] + + def Resume(self): + # Explicitly Finish() all started modules + for m in self.started[:]: + m.Finish() + self.started = [] + _pydfhack._API.Resume(self)