From f80244d56013202c6342d3c7c5a198514fcd9a89 Mon Sep 17 00:00:00 2001 From: DarkPhoenix Date: Sun, 14 Apr 2019 14:14:14 +0300 Subject: [PATCH] Add custom command processor for our internal needs and use it in booster add command --- gui/fitCommands/__init__.py | 68 ++++++++++++++--------------- gui/fitCommands/calc/booster/add.py | 2 +- gui/fitCommands/calc/implant/add.py | 2 +- gui/fitCommands/guiAddBooster.py | 11 +++-- gui/fitCommands/guiRebaseItems.py | 18 ++++---- gui/fitCommands/helpers.py | 31 ++++++++++++- 6 files changed, 80 insertions(+), 52 deletions(-) diff --git a/gui/fitCommands/__init__.py b/gui/fitCommands/__init__.py index a92196694..371a6136f 100644 --- a/gui/fitCommands/__init__.py +++ b/gui/fitCommands/__init__.py @@ -1,45 +1,45 @@ -from .guiToggleModuleState import GuiModuleStateChangeCommand -from .guiAddModule import GuiModuleAddCommand -from .guiRemoveModule import GuiModuleRemoveCommand -from .guiAddCharge import GuiModuleAddChargeCommand -from .guiFillWithModule import GuiFillWithModuleCommand -from .guiSwapCloneModule import GuiModuleSwapOrCloneCommand -from .guiRemoveCargo import GuiRemoveCargoCommand -from .guiAddCargo import GuiAddCargoCommand -from .guiRemoveImplant import GuiRemoveImplantCommand -from .guiAddImplant import GuiAddImplantCommand from .guiAddBooster import GuiAddBoosterCommand -from .guiRemoveBooster import GuiRemoveBoosterCommand +from .guiAddCargo import GuiAddCargoCommand +from .guiAddCharge import GuiModuleAddChargeCommand from .guiAddCommand import GuiAddCommandCommand -from .guiRemoveCommand import GuiRemoveCommandCommand -from .guiSetMode import GuiSetModeCommand -from .guiToggleCommand import GuiToggleCommandCommand -from .guiAddProjected import GuiAddProjectedCommand -from .guiRemoveProjected import GuiRemoveProjectedCommand -from .guiCargoToModule import GuiCargoToModuleCommand -from .guiModuleToCargo import GuiModuleToCargoCommand -from .guiAddFighter import GuiAddFighterCommand -from .guiRemoveFighter import GuiRemoveFighterCommand -from .guiMetaSwap import GuiMetaSwapCommand -from .guiToggleFighter import GuiToggleFighterCommand -from .guiToggleImplant import GuiToggleImplantCommand -from .guiToggleBooster import GuiToggleBoosterCommand from .guiAddDrone import GuiAddDroneCommand -from .guiRemoveDrone import GuiRemoveDroneCommand -from .guiChangeFighterQty import GuiChangeFighterQty +from .guiAddFighter import GuiAddFighterCommand +from .guiAddImplant import GuiAddImplantCommand +from .guiAddModule import GuiModuleAddCommand +from .guiAddProjected import GuiAddProjectedCommand +from .guiCargoToModule import GuiCargoToModuleCommand from .guiChangeCargoQty import GuiChangeCargoQty -from .guiChangeProjectedFitQty import GuiChangeProjectedFitQty from .guiChangeDroneQty import GuiChangeDroneQty -from .guiChangeProjectedDroneQty import GuiChangeProjectedDroneQty -from .guiToggleDrone import GuiToggleDroneCommand -from .guiFitRename import GuiFitRenameCommand +from .guiChangeFighterQty import GuiChangeFighterQty from .guiChangeImplantLocation import GuiChangeImplantLocation +from .guiChangeProjectedDroneQty import GuiChangeProjectedDroneQty +from .guiChangeProjectedFighterAmount import GuiChangeProjectedFighterAmount +from .guiChangeProjectedFitQty import GuiChangeProjectedFitQty +from .guiFillWithModule import GuiFillWithModuleCommand +from .guiFitRename import GuiFitRenameCommand from .guiImportMutatedModule import GuiImportMutatedModuleCommand -from .guiSetSpoolup import GuiSetSpoolup -from .guiRebaseItems import GuiRebaseItemsCommand +from .guiMetaSwap import GuiMetaSwapCommand +from .guiModuleToCargo import GuiModuleToCargoCommand from .guiMutaConvert import GuiMutaConvertCommand from .guiMutaRevert import GuiMutaRevertCommand -from .guiToggleProjected import GuiToggleProjectedCommand +from .guiRebaseItems import GuiRebaseItemsCommand +from .guiRemoveBooster import GuiRemoveBoosterCommand +from .guiRemoveCargo import GuiRemoveCargoCommand +from .guiRemoveCommand import GuiRemoveCommandCommand +from .guiRemoveDrone import GuiRemoveDroneCommand +from .guiRemoveFighter import GuiRemoveFighterCommand +from .guiRemoveImplant import GuiRemoveImplantCommand +from .guiRemoveModule import GuiModuleRemoveCommand +from .guiRemoveProjected import GuiRemoveProjectedCommand +from .guiSetMode import GuiSetModeCommand +from .guiSetSpoolup import GuiSetSpoolup +from .guiSwapCloneModule import GuiModuleSwapOrCloneCommand +from .guiToggleBooster import GuiToggleBoosterCommand from .guiToggleBoosterSideEffect import GuiToggleBoosterSideEffectCommand +from .guiToggleCommand import GuiToggleCommandCommand +from .guiToggleDrone import GuiToggleDroneCommand +from .guiToggleFighter import GuiToggleFighterCommand from .guiToggleFighterAbility import GuiToggleFighterAbilityCommand -from .guiChangeProjectedFighterAmount import GuiChangeProjectedFighterAmount +from .guiToggleImplant import GuiToggleImplantCommand +from .guiToggleModuleState import GuiModuleStateChangeCommand +from .guiToggleProjected import GuiToggleProjectedCommand diff --git a/gui/fitCommands/calc/booster/add.py b/gui/fitCommands/calc/booster/add.py index 434cf408e..2a32c9ad8 100644 --- a/gui/fitCommands/calc/booster/add.py +++ b/gui/fitCommands/calc/booster/add.py @@ -56,7 +56,7 @@ class CalcAddBoosterCommand(wx.Command): def Undo(self): pyfalog.debug('Undo addition of booster {} to fit {}'.format(self.newBoosterInfo, self.fitID)) - if self.oldBoosterInfo and self.oldPosition: + if self.oldBoosterInfo is not None and self.oldPosition is not None: cmd = CalcAddBoosterCommand(fitID=self.fitID, boosterInfo=self.oldBoosterInfo, position=self.oldPosition) return cmd.Do() from .remove import CalcRemoveBoosterCommand diff --git a/gui/fitCommands/calc/implant/add.py b/gui/fitCommands/calc/implant/add.py index d07c66a69..e5e023728 100644 --- a/gui/fitCommands/calc/implant/add.py +++ b/gui/fitCommands/calc/implant/add.py @@ -55,7 +55,7 @@ class CalcAddImplantCommand(wx.Command): def Undo(self): pyfalog.debug('Undo addition of implant {} to fit {}'.format(self.newImplantInfo, self.fitID)) - if self.oldImplantInfo and self.oldPosition: + if self.oldImplantInfo is not None and self.oldPosition is not None: cmd = CalcAddImplantCommand(fitID=self.fitID, implantInfo=self.oldImplantInfo, position=self.oldPosition) return cmd.Do() from .remove import CalcRemoveImplantCommand diff --git a/gui/fitCommands/guiAddBooster.py b/gui/fitCommands/guiAddBooster.py index 1aab8dd98..4710f8430 100644 --- a/gui/fitCommands/guiAddBooster.py +++ b/gui/fitCommands/guiAddBooster.py @@ -1,9 +1,9 @@ import wx -from service.fit import Fit import gui.mainFrame from gui import globalEvents as GE -from gui.fitCommands.helpers import BoosterInfo +from gui.fitCommands.helpers import InternalCommandHistory, BoosterInfo +from service.fit import Fit from .calc.booster.add import CalcAddBoosterCommand @@ -13,20 +13,19 @@ class GuiAddBoosterCommand(wx.Command): wx.Command.__init__(self, True, 'Add Booster') self.mainFrame = gui.mainFrame.MainFrame.getInstance() self.sFit = Fit.getInstance() - self.internal_history = wx.CommandProcessor() + self.internalHistory = InternalCommandHistory() self.fitID = fitID self.itemID = itemID def Do(self): - if self.internal_history.Submit(CalcAddBoosterCommand(fitID=self.fitID, boosterInfo=BoosterInfo(itemID=self.itemID))): + if self.internalHistory.submit(CalcAddBoosterCommand(fitID=self.fitID, boosterInfo=BoosterInfo(itemID=self.itemID))): self.sFit.recalc(self.fitID) wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=self.fitID)) return True return False def Undo(self): - for _ in self.internal_history.Commands: - self.internal_history.Undo() + self.internalHistory.undoAll() self.sFit.recalc(self.fitID) wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=self.fitID)) return True diff --git a/gui/fitCommands/guiRebaseItems.py b/gui/fitCommands/guiRebaseItems.py index e12738e5f..5baa44059 100644 --- a/gui/fitCommands/guiRebaseItems.py +++ b/gui/fitCommands/guiRebaseItems.py @@ -9,6 +9,7 @@ from .calc.itemRebase import CalcRebaseItemCommand from .calc.module.changeCharges import CalcChangeModuleChargesCommand from .calc.cargo.add import CalcAddCargoCommand from .calc.cargo.remove import CalcRemoveCargoCommand +from gui.fitCommands.helpers import InternalCommandHistory @@ -19,28 +20,28 @@ class GuiRebaseItemsCommand(wx.Command): self.mainFrame = gui.mainFrame.MainFrame.getInstance() self.fitID = fitID self.rebaseMap = rebaseMap - self.internal_history = wx.CommandProcessor() + self.internalHistory = InternalCommandHistory() def Do(self): fit = eos.db.getFit(self.fitID) for mod in fit.modules: if mod.itemID in self.rebaseMap: - self.internal_history.Submit(CalcRebaseItemCommand(fitID=self.fitID, containerName="modules", position=mod.modPosition, itemID=self.rebaseMap[mod.itemID], commit=False)) + self.internalHistory.submit(CalcRebaseItemCommand(fitID=self.fitID, containerName="modules", position=mod.modPosition, itemID=self.rebaseMap[mod.itemID], commit=False)) if mod.chargeID in self.rebaseMap: - self.internal_history.Submit(CalcChangeModuleChargesCommand(fitID=self.fitID, chargeMap={mod.modPosition: self.rebaseMap[mod.chargeID]})) + self.internalHistory.submit(CalcChangeModuleChargesCommand(fitID=self.fitID, chargeMap={mod.modPosition: self.rebaseMap[mod.chargeID]})) for containerName in ("drones", "fighters", "implants", "boosters"): container = getattr(fit, containerName) for obj in container: if obj.itemID in self.rebaseMap: - self.internal_history.Submit(CalcRebaseItemCommand(fitID=self.fitID, containerName=containerName, position=container.index(obj), itemID=self.rebaseMap[obj.itemID], commit=False)) + self.internalHistory.submit(CalcRebaseItemCommand(fitID=self.fitID, containerName=containerName, position=container.index(obj), itemID=self.rebaseMap[obj.itemID], commit=False)) # Need to process cargo separately as we want to merge items when needed, # e.g. FN iron and CN iron into single stack of CN iron for cargo in fit.cargo: if cargo.itemID in self.rebaseMap: amount = cargo.amount - self.internal_history.Submit(CalcRemoveCargoCommand(fitID=self.fitID, cargoInfo=CargoInfo(itemID=cargo.itemID, amount=amount))) - self.internal_history.Submit(CalcAddCargoCommand(fitID=self.fitID, cargoInfo=CargoInfo(itemID=self.rebaseMap[cargo.itemID], amount=amount))) - if self.internal_history.Commands: + self.internalHistory.submit(CalcRemoveCargoCommand(fitID=self.fitID, cargoInfo=CargoInfo(itemID=cargo.itemID, amount=amount))) + self.internalHistory.submit(CalcAddCargoCommand(fitID=self.fitID, cargoInfo=CargoInfo(itemID=self.rebaseMap[cargo.itemID], amount=amount))) + if self.internalHistory: eos.db.commit() Fit.getInstance().recalc(self.fitID) wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=self.fitID)) @@ -49,8 +50,7 @@ class GuiRebaseItemsCommand(wx.Command): return False def Undo(self): - for _ in self.internal_history.Commands: - self.internal_history.Undo() + self.internalHistory.undoAll() eos.db.commit() Fit.getInstance().recalc(self.fitID) wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=self.fitID)) diff --git a/gui/fitCommands/helpers.py b/gui/fitCommands/helpers.py index 6165b093e..e580d794a 100644 --- a/gui/fitCommands/helpers.py +++ b/gui/fitCommands/helpers.py @@ -1,3 +1,4 @@ +import wx from logbook import Logger import eos.db @@ -5,8 +6,8 @@ from eos.const import FittingModuleState from eos.saveddata.booster import Booster from eos.saveddata.cargo import Cargo from eos.saveddata.drone import Drone -from eos.saveddata.implant import Implant from eos.saveddata.fighter import Fighter +from eos.saveddata.implant import Implant from eos.saveddata.module import Module from service.market import Market from utils.repr import makeReprStr @@ -15,6 +16,34 @@ from utils.repr import makeReprStr pyfalog = Logger(__name__) +class InternalCommandHistory: + + def __init__(self): + self.__buffer = wx.CommandProcessor() + + def submit(self, *args, **kwargs): + return self.__buffer.Submit(*args, **kwargs) + + def undoAll(self): + undoneCommands = [] + # Undo commands one by one, starting from the last + for cmdToUndo in reversed(self.__buffer.Commands): + if cmdToUndo.Undo(): + undoneCommands.append(cmdToUndo) + # If undoing fails, redo already undone commands, starting from the last undone + else: + for cmdToRedo in reversed(undoneCommands): + if not cmdToRedo.Do(): + break + self.__buffer.ClearCommands() + return False + self.__buffer.ClearCommands() + return True + + def __len__(self): + return len(self.__buffer.Commands) + + class ModuleInfo: def __init__(self, itemID, baseItemID=None, mutaplasmidID=None, mutations=None, chargeID=None, state=None, spoolType=None, spoolAmount=None):