From d738ba615e393c7ef4a9871965fbfb5312a88975 Mon Sep 17 00:00:00 2001 From: DarkPhoenix Date: Fri, 12 Apr 2019 14:32:25 +0300 Subject: [PATCH] Finish overhauling module-related fit commands --- eos/effectHandlerHelpers.py | 3 + gui/fitCommands/calc/fitAddModule.py | 11 ++- gui/fitCommands/calc/fitAddProjectedModule.py | 22 +++-- gui/fitCommands/calc/fitCloneModule.py | 66 +++++++------ .../calc/fitImportMutatedModule.py | 97 ------------------- gui/fitCommands/calc/fitRemoveModule.py | 6 +- .../calc/fitRemoveProjectedModule.py | 3 +- gui/fitCommands/calc/fitReplaceModule.py | 15 ++- gui/fitCommands/calc/fitSwapModule.py | 31 +++--- gui/fitCommands/guiImportMutatedModule.py | 40 ++++---- service/port/muta.py | 31 +++--- 11 files changed, 132 insertions(+), 193 deletions(-) delete mode 100644 gui/fitCommands/calc/fitImportMutatedModule.py diff --git a/eos/effectHandlerHelpers.py b/eos/effectHandlerHelpers.py index 248003e3c..3c1dfb611 100644 --- a/eos/effectHandlerHelpers.py +++ b/eos/effectHandlerHelpers.py @@ -200,10 +200,13 @@ class HandledModuleList(HandledList): dummy = mod.buildEmpty(mod.slot) dummy.position = index self[index] = dummy + mod.position = None def __toModule(self, index, mod): + oldMod = self[index] mod.position = index self[index] = mod + oldMod.position = None @deprecated def freeSlot(self, slot): diff --git a/gui/fitCommands/calc/fitAddModule.py b/gui/fitCommands/calc/fitAddModule.py index 4f3cc3d7f..b4a0ac95b 100644 --- a/gui/fitCommands/calc/fitAddModule.py +++ b/gui/fitCommands/calc/fitAddModule.py @@ -2,6 +2,7 @@ import wx from logbook import Logger import eos.db +from eos.exception import HandledListActionError from gui.fitCommands.helpers import stateLimit from service.fit import Fit @@ -40,14 +41,16 @@ class FitAddModuleCommand(wx.Command): if not newMod.fits(fit): pyfalog.warning('Module does not fit') - self.Undo() return False newMod.owner = fit - fit.modules.append(newMod) - + try: + fit.modules.append(newMod) + except HandledListActionError: + pyfalog.warning('Failed to append to list') + eos.db.commit() + return False sFit.checkStates(fit, newMod) - eos.db.commit() self.savedPosition = newMod.modPosition return True diff --git a/gui/fitCommands/calc/fitAddProjectedModule.py b/gui/fitCommands/calc/fitAddProjectedModule.py index cf9eae055..2baefc96e 100644 --- a/gui/fitCommands/calc/fitAddProjectedModule.py +++ b/gui/fitCommands/calc/fitAddProjectedModule.py @@ -3,6 +3,7 @@ from logbook import Logger import eos.db from eos.const import FittingModuleState +from eos.exception import HandledListActionError from service.fit import Fit @@ -20,26 +21,28 @@ class FitAddProjectedModuleCommand(wx.Command): self.oldPosition = None def Do(self): - pyfalog.debug('Doing projection of module {} onto: {}'.format(self.newModInfo, self.fitID)) + pyfalog.debug('Doing addition of projected module {} onto: {}'.format(self.newModInfo, self.fitID)) fit = Fit.getInstance().getFit(self.fitID) newMod = self.newModInfo.toModule(fallbackState=FittingModuleState.ACTIVE) if newMod is None: return False - if not newMod.canHaveState(newMod.state, fit): + if not newMod.canHaveState(newMod.state, projectedOnto=fit): newMod.state = FittingModuleState.OFFLINE self.oldPosition, self.oldModInfo = fit.projectedModules.makeRoom(newMod) if self.newPosition is not None: - fit.projectedModules.insert(self.newPosition, newMod) - if not fit.projectedModules.lastOpState: - self.Undo() + try: + fit.projectedModules.insert(self.newPosition, newMod) + except HandledListActionError: + eos.db.commit() return False else: - fit.projectedModules.append(newMod) - if not fit.projectedModules.lastOpState: - self.Undo() + try: + fit.projectedModules.append(newMod) + except HandledListActionError: + eos.db.commit() return False self.newPosition = fit.projectedModules.index(newMod) @@ -47,12 +50,15 @@ class FitAddProjectedModuleCommand(wx.Command): return True def Undo(self): + pyfalog.debug('Undoing addition of projected module {} onto: {}'.format(self.newModInfo, self.fitID)) if self.oldPosition is not None and self.oldModInfo is not None: cmd = FitAddProjectedModuleCommand( fitID=self.fitID, newModInfo=self.oldModInfo, newPosition=self.oldPosition) return cmd.Do() + if self.newPosition is None: + return False from gui.fitCommands.calc.fitRemoveProjectedModule import FitRemoveProjectedModuleCommand cmd = FitRemoveProjectedModuleCommand(self.fitID, self.newPosition) cmd.Do() diff --git a/gui/fitCommands/calc/fitCloneModule.py b/gui/fitCommands/calc/fitCloneModule.py index 519b653ef..207cd7dbd 100644 --- a/gui/fitCommands/calc/fitCloneModule.py +++ b/gui/fitCommands/calc/fitCloneModule.py @@ -1,44 +1,50 @@ -import wx -import eos.db -from logbook import Logger import copy + +import wx +from logbook import Logger + +import eos.db +from eos.exception import HandledListActionError +from gui.fitCommands.helpers import ModuleInfo +from service.fit import Fit + + pyfalog = Logger(__name__) class FitCloneModuleCommand(wx.Command): - """ - Clone a module from src to dst - This will overwrite dst! Checking for empty module must be - done at a higher level - from sFit.cloneModule - """ - def __init__(self, fitID, src, dst): - wx.Command.__init__(self, True, "Module Clone") + def __init__(self, fitID, srcPosition, dstPosition): + wx.Command.__init__(self, True, 'Clone Module') self.fitID = fitID - self.src = src - self.dst = dst + self.srcPosition = srcPosition + self.dstPosition = dstPosition + self.dstModInfo = None def Do(self): - fit = eos.db.getFit(self.fitID) - # Gather modules - srcMod = fit.modules[self.src] - dstMod = fit.modules[self.dst] # should be a placeholder module - - new = copy.deepcopy(srcMod) - new.owner = fit - if new.fits(fit): - pyfalog.debug("Cloning {} from source {} to destination {} for fit ID {}", srcMod, self.src, self.dst, self.fitID) - # insert copy if module meets hardpoint restrictions - fit.modules.remove(dstMod) - fit.modules.insert(self.dst, new) - + pyfalog.debug('Doing cloning from position {} to position {} for fit ID {}'.format(self.srcPosition, self.dstPosition, self.fitID)) + sFit = Fit.getInstance() + fit = sFit.getFit(self.fitID) + srcMod = fit.modules[self.srcPosition] + copyMod = copy.deepcopy(srcMod) + copyMod.owner = fit + if not copyMod.fits(fit): + return False + if not fit.modules[self.dstPosition].isEmpty: + return False + try: + fit.modules.replace(self.dstPosition, copyMod) + except HandledListActionError: + pyfalog.warning('Failed to replace module') eos.db.commit() - return True - return False + return False + sFit.checkStates(fit, copyMod) + eos.db.commit() + return True def Undo(self): - from .fitRemoveModule import FitRemoveModuleCommand # Avoid circular import - cmd = FitRemoveModuleCommand(self.fitID, [self.dst]) + pyfalog.debug('Undoing cloning from position {} to position {} for fit ID {}'.format(self.srcPosition, self.dstPosition, self.fitID)) + from .fitRemoveModule import FitRemoveModuleCommand + cmd = FitRemoveModuleCommand(self.fitID, [self.dstPosition]) cmd.Do() return True diff --git a/gui/fitCommands/calc/fitImportMutatedModule.py b/gui/fitCommands/calc/fitImportMutatedModule.py deleted file mode 100644 index 948f0b511..000000000 --- a/gui/fitCommands/calc/fitImportMutatedModule.py +++ /dev/null @@ -1,97 +0,0 @@ -import wx -from eos.saveddata.module import Module -from eos.const import FittingModuleState -import eos.db -from eos.db.gamedata.queries import getDynamicItem -from logbook import Logger -from service.fit import Fit -pyfalog = Logger(__name__) - - -class FitImportMutatedCommand(wx.Command): - """" - Fitting command that takes info about mutated module, composes it and adds it to a fit - """ - def __init__(self, fitID, baseItem, mutaItem, attrMap): - wx.Command.__init__(self, True) - self.fitID = fitID - self.baseItem = baseItem - self.mutaItem = mutaItem - self.attrMap = attrMap - self.new_position = None - self.change = None - self.replace_cmd = None - - def Do(self): - sFit = Fit.getInstance() - fitID = self.fitID - if fitID is None: - return False - - fit = eos.db.getFit(fitID) - - if self.baseItem is None: - pyfalog.warning("Unable to build non-mutated module: no base item to build from") - return False - - try: - mutaTypeID = self.mutaItem.ID - except AttributeError: - mutaplasmid = None - else: - mutaplasmid = getDynamicItem(mutaTypeID) - # Try to build simple item even though no mutaplasmid found - if mutaplasmid is None: - try: - module = Module(self.baseItem) - except ValueError: - pyfalog.warning("Unable to build non-mutated module: {}", self.baseItem) - return False - # Build mutated module otherwise - else: - try: - module = Module(mutaplasmid.resultingItem, self.baseItem, mutaplasmid) - except ValueError: - pyfalog.warning("Unable to build mutated module: {} {}", self.baseItem, self.mutaItem) - return False - else: - for attrID, mutator in module.mutators.items(): - if attrID in self.attrMap: - mutator.value = self.attrMap[attrID] - - - # this is essentially the same as the FitAddModule command. possibly look into centralizing this functionality somewhere? - if module.fits(fit): - pyfalog.debug("Adding {} as module for fit {}", module, fit) - module.owner = fit - numSlots = len(fit.modules) - fit.modules.append(module) - if module.isValidState(FittingModuleState.ACTIVE): - module.state = FittingModuleState.ACTIVE - - # todo: fix these - # As some items may affect state-limiting attributes of the ship, calculate new attributes first - # self.recalc(fit) - # Then, check states of all modules and change where needed. This will recalc if needed - sFit.checkStates(fit, module) - - # fit.fill() - eos.db.commit() - - self.change = numSlots != len(fit.modules) - self.new_position = module.modPosition - else: - return False - - return True - - def Undo(self): - # We added a subsystem module, which actually ran the replace command. Run the undo for that guy instead - if self.replace_cmd: - return self.replace_cmd.Undo() - - from .fitRemoveModule import FitRemoveModuleCommand # Avoid circular import - if self.new_position is not None: - cmd = FitRemoveModuleCommand(self.fitID, [self.new_position]) - cmd.Do() - return True diff --git a/gui/fitCommands/calc/fitRemoveModule.py b/gui/fitCommands/calc/fitRemoveModule.py index b59b6e512..c386a3b76 100644 --- a/gui/fitCommands/calc/fitRemoveModule.py +++ b/gui/fitCommands/calc/fitRemoveModule.py @@ -29,14 +29,16 @@ class FitRemoveModuleCommand(wx.Command): # If no modules were removed, report that command was not completed if not len(self.oldModInfos) > 0: + eos.db.commit() return False eos.db.commit() return True def Undo(self): pyfalog.debug('Undoing removal of modules {} on fit {}'.format(self.oldModInfos, self.fitID)) + results = [] from gui.fitCommands.calc.fitReplaceModule import FitReplaceModuleCommand for position, modInfo in self.oldModInfos.items(): cmd = FitReplaceModuleCommand(fitID=self.fitID, position=position, newModInfo=modInfo) - cmd.Do() - return True + results.append(cmd.Do()) + return any(results) diff --git a/gui/fitCommands/calc/fitRemoveProjectedModule.py b/gui/fitCommands/calc/fitRemoveProjectedModule.py index 30e20c8a1..d285ad4fd 100644 --- a/gui/fitCommands/calc/fitRemoveProjectedModule.py +++ b/gui/fitCommands/calc/fitRemoveProjectedModule.py @@ -18,7 +18,7 @@ class FitRemoveProjectedModuleCommand(wx.Command): self.savedModInfo = None def Do(self): - pyfalog.debug("Removing ({}) onto: {}".format(self.fitID, self.position)) + pyfalog.debug('Doing removal of projected module from position {} on fit {}'.format(self.position, self.fitID)) fit = Fit.getInstance().getFit(self.fitID) mod = fit.projectedModules[self.position] self.savedModInfo = ModuleInfo.fromModule(mod) @@ -27,6 +27,7 @@ class FitRemoveProjectedModuleCommand(wx.Command): return True def Undo(self): + pyfalog.debug('Undoing removal of projected module {} on fit {}'.format(self.savedModInfo, self.fitID)) from gui.fitCommands.calc.fitAddProjectedModule import FitAddProjectedModuleCommand cmd = FitAddProjectedModuleCommand( fitID=self.fitID, diff --git a/gui/fitCommands/calc/fitReplaceModule.py b/gui/fitCommands/calc/fitReplaceModule.py index 93ab3ec04..67827a608 100644 --- a/gui/fitCommands/calc/fitReplaceModule.py +++ b/gui/fitCommands/calc/fitReplaceModule.py @@ -2,6 +2,7 @@ import wx from logbook import Logger import eos.db +from eos.exception import HandledListActionError from gui.fitCommands.helpers import ModuleInfo, stateLimit from service.fit import Fit @@ -35,7 +36,12 @@ class FitReplaceModuleCommand(wx.Command): self.Undo() return False newMod.owner = fit - fit.modules.replace(self.position, newMod) + try: + fit.modules.replace(self.position, newMod) + except HandledListActionError: + pyfalog.warning('Failed to replace in list') + self.Undo() + return False sFit.checkStates(fit, newMod) eos.db.commit() return True @@ -59,7 +65,12 @@ class FitReplaceModuleCommand(wx.Command): self.Do() return False oldMod.owner = fit - fit.modules.replace(self.position, oldMod) + try: + fit.modules.replace(self.position, oldMod) + except HandledListActionError: + pyfalog.warning('Failed to replace in list') + self.Do() + return False sFit.checkStates(fit, oldMod) eos.db.commit() return True diff --git a/gui/fitCommands/calc/fitSwapModule.py b/gui/fitCommands/calc/fitSwapModule.py index 38ed8d4eb..07721b703 100644 --- a/gui/fitCommands/calc/fitSwapModule.py +++ b/gui/fitCommands/calc/fitSwapModule.py @@ -1,38 +1,37 @@ import wx -import eos.db from logbook import Logger + +import eos.db +from service.fit import Fit + + pyfalog = Logger(__name__) class FitSwapModuleCommand(wx.Command): - """" - from sFit.swapModules - """ - def __init__(self, fitID, src, dst): - wx.Command.__init__(self, True, "Module Swap") + + def __init__(self, fitID, position1, position2): + wx.Command.__init__(self, True, 'Swap Modules') self.fitID = fitID - self.src = src - self.dst = dst + self.position1 = position1 + self.position2 = position2 def Do(self): - self.__swap(self.fitID, self.src, self.dst) + pyfalog.debug('Doing swapping between {} and {} for fit {}'.format(self.position1, self.position2, self.fitID)) + self.__swap(self.fitID, self.position1, self.position2) return True def Undo(self): - self.__swap(self.fitID, self.dst, self.src) + self.__swap(self.fitID, self.position2, self.position1) + pyfalog.debug('Undoing swapping between {} and {} for fit {}'.format(self.position1, self.position2, self.fitID)) return True def __swap(self, fitID, src, dst): - pyfalog.debug("Swapping modules from source ({0}) to destination ({1}) for fit ID: {1}", src, dst, fitID) - fit = eos.db.getFit(fitID) - # Gather modules + fit = Fit.getInstance().getFit(fitID) srcMod = fit.modules[src] dstMod = fit.modules[dst] - - # To swap, we simply remove mod and insert at destination. fit.modules.remove(srcMod) fit.modules.insert(dst, srcMod) fit.modules.remove(dstMod) fit.modules.insert(src, dstMod) - eos.db.commit() diff --git a/gui/fitCommands/guiImportMutatedModule.py b/gui/fitCommands/guiImportMutatedModule.py index 9187adf7e..8f7a1a5f9 100644 --- a/gui/fitCommands/guiImportMutatedModule.py +++ b/gui/fitCommands/guiImportMutatedModule.py @@ -1,38 +1,42 @@ import wx -import eos.db +from logbook import Logger + import gui.mainFrame from gui import globalEvents as GE -from .calc.fitImportMutatedModule import FitImportMutatedCommand +from gui.fitCommands.helpers import ModuleInfo from service.fit import Fit -from logbook import Logger +from .calc.fitAddModule import FitAddModuleCommand + + pyfalog = Logger(__name__) class GuiImportMutatedModuleCommand(wx.Command): - def __init__(self, fitID, baseItem, mutaItem, attrMap): - wx.Command.__init__(self, True, "Mutated Module Import: {} {} {}".format(baseItem, mutaItem, attrMap)) - self.mainFrame = gui.mainFrame.MainFrame.getInstance() - self.sFit = Fit.getInstance() + def __init__(self, fitID, baseItem, mutaplasmid, mutations): + wx.Command.__init__(self, True, "Mutated Module Import: {} {} {}".format(baseItem, mutaplasmid, mutations)) + self.internalHistory = wx.CommandProcessor() self.fitID = fitID - self.baseItem = baseItem - self.mutaItem = mutaItem - self.attrMap = attrMap - self.internal_history = wx.CommandProcessor() + self.newModInfo = ModuleInfo( + itemID=mutaplasmid.resultingItem.ID, + baseItemID=baseItem.ID, + mutaplasmidID=mutaplasmid.ID, + mutations=mutations) + print(self.newModInfo) def Do(self): pyfalog.debug("{} Do()".format(self)) - if self.internal_history.Submit(FitImportMutatedCommand(self.fitID, self.baseItem, self.mutaItem, self.attrMap)): - self.sFit.recalc(self.fitID) - wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=self.fitID, action="modadd")) + if self.internalHistory.Submit(FitAddModuleCommand(fitID=self.fitID, newModInfo=self.newModInfo)): + Fit.getInstance().recalc(self.fitID) + wx.PostEvent(gui.mainFrame.MainFrame.getInstance(), GE.FitChanged(fitID=self.fitID, action="modadd")) return True return False def Undo(self): pyfalog.debug("{} Undo()".format(self)) - for _ in self.internal_history.Commands: - self.internal_history.Undo() - self.sFit.recalc(self.fitID) - wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=self.fitID, action="moddel")) + for _ in self.internalHistory.Commands: + self.internalHistory.Undo() + Fit.getInstance().recalc(self.fitID) + wx.PostEvent(gui.mainFrame.MainFrame.getInstance(), GE.FitChanged(fitID=self.fitID, action="moddel")) return True diff --git a/service/port/muta.py b/service/port/muta.py index dc1b4492c..7e742ecdc 100644 --- a/service/port/muta.py +++ b/service/port/muta.py @@ -18,7 +18,7 @@ # ============================================================================= -from eos.db.gamedata.queries import getAttributeInfo +from eos.db.gamedata.queries import getAttributeInfo, getDynamicItem from gui.utils.numberFormatter import roundToPrec from service.port.shared import fetchItem @@ -42,27 +42,28 @@ def renderMutant(mutant, firstPrefix='', prefix=''): def parseMutant(lines): # Fetch base item type try: - baseName = lines[0] + baseItemName = lines[0] except IndexError: return None - baseType = fetchItem(baseName.strip()) - if baseType is None: + baseItem = fetchItem(baseItemName.strip()) + if baseItem is None: return None, None, {} # Fetch mutaplasmid item type and actual item try: - mutaName = lines[1] + mutaplasmidName = lines[1] except IndexError: - return baseType, None, {} - mutaType = fetchItem(mutaName.strip()) - if mutaType is None: - return baseType, None, {} + return baseItem, None, {} + mutaplasmidItem = fetchItem(mutaplasmidName.strip()) + if mutaplasmidItem is None: + return baseItem, None, {} + mutaplasmidItem = getDynamicItem(mutaplasmidItem.ID) # Process mutated attribute values try: - mutaAttrsLine = lines[2] + mutationsLine = lines[2] except IndexError: - return baseType, mutaType, {} - mutaAttrs = {} - pairs = [p.strip() for p in mutaAttrsLine.split(',')] + return baseItem, mutaplasmidItem, {} + mutations = {} + pairs = [p.strip() for p in mutationsLine.split(',')] for pair in pairs: try: attrName, value = pair.split(' ') @@ -75,5 +76,5 @@ def parseMutant(lines): attrInfo = getAttributeInfo(attrName.strip()) if attrInfo is None: continue - mutaAttrs[attrInfo.ID] = value - return baseType, mutaType, mutaAttrs + mutations[attrInfo.ID] = value + return baseItem, mutaplasmidItem, mutations