From a5c1875a29cc4289fb74b64a9cc69c83dfa5a8bb Mon Sep 17 00:00:00 2001 From: DarkPhoenix Date: Wed, 13 Nov 2019 13:48:13 +0300 Subject: [PATCH] Make sure to cache ammo set to reuse it when applying ammo to multiple modules --- gui/builtinContextMenus/moduleAmmoChange.py | 49 ++++++++++++--------- service/ammo.py | 4 +- 2 files changed, 29 insertions(+), 24 deletions(-) diff --git a/gui/builtinContextMenus/moduleAmmoChange.py b/gui/builtinContextMenus/moduleAmmoChange.py index c9adc25b9..b0fa1c8e7 100644 --- a/gui/builtinContextMenus/moduleAmmoChange.py +++ b/gui/builtinContextMenus/moduleAmmoChange.py @@ -1,3 +1,5 @@ +from itertools import chain + # noinspection PyPackageRequirements import wx @@ -12,13 +14,10 @@ from service.fit import Fit class ChangeModuleAmmo(ContextMenuCombined): - DAMAGE_TYPES = ('em', 'explosive', 'kinetic', 'thermal') - MISSILE_ORDER = ('em', 'thermal', 'kinetic', 'explosive', 'mixed') - def __init__(self): self.mainFrame = gui.mainFrame.MainFrame.getInstance() # Format: {type ID: set(loadable, charges)} - self.loadableCharges = {} + self.loadableChargesCache = {} def display(self, callingWindow, srcContext, mainItem, selection): if srcContext not in ('fittingModule', 'projectedModule'): @@ -27,7 +26,7 @@ class ChangeModuleAmmo(ContextMenuCombined): if self.mainFrame.getActiveFit() is None: return False - self.mainCharges = Ammo.getInstance().getModuleFlatAmmo(mainItem) + self.mainCharges = self._getAmmo(mainItem) if not self.mainCharges: return False @@ -39,7 +38,14 @@ class ChangeModuleAmmo(ContextMenuCombined): def getText(self, callingWindow, itmContext, mainItem, selection): return 'Charge' - def addCharge(self, menu, charge): + def _getAmmo(self, mod): + if mod.itemID is None: + return set() + if mod.itemID not in self.loadableChargesCache: + self.loadableChargesCache[mod.itemID] = Ammo.getInstance().getModuleFlatAmmo(mod) + return self.loadableChargesCache[mod.itemID] + + def _addCharge(self, menu, charge): id_ = ContextMenuCombined.nextID() name = charge.name if charge is not None else 'Empty' self.chargeEventMap[id_] = charge @@ -50,11 +56,10 @@ class ChangeModuleAmmo(ContextMenuCombined): bitmap = BitmapLoader.getBitmap(charge.iconID, 'icons') if bitmap is not None: item.SetBitmap(bitmap) - return item @staticmethod - def addSeparator(m, text): + def _addSeparator(m, text): id_ = ContextMenuCombined.nextID() m.Append(id_, '─ %s ─' % text) m.Enable(id_, False) @@ -63,29 +68,29 @@ class ChangeModuleAmmo(ContextMenuCombined): msw = True if 'wxMSW' in wx.PlatformInfo else False menu = wx.Menu() self.chargeEventMap = {} - modType, chargeDict = Ammo.getInstance().getModuleStructuredAmmo(self.module) + modType, chargeDict = Ammo.getInstance().getModuleStructuredAmmo(self.module, ammo=self.mainCharges) if modType == 'ddTurret': - self.addSeparator(menu, 'Long Range') + self._addSeparator(menu, 'Long Range') menuItems = [] for charges in chargeDict.values(): if len(charges) == 1: - menuItems.append(self.addCharge(rootMenu if msw else menu, charges[0])) + menuItems.append(self._addCharge(rootMenu if msw else menu, charges[0])) else: subMenu = wx.Menu() subMenu.Bind(wx.EVT_MENU, self.handleAmmoSwitch) baseCharge = charges[0] - menuItem = self.addCharge(rootMenu if msw else menu, baseCharge) + menuItem = self._addCharge(rootMenu if msw else menu, baseCharge) menuItems.append(menuItem) subMenu = wx.Menu() subMenu.Bind(wx.EVT_MENU, self.handleAmmoSwitch) menuItem.SetSubMenu(subMenu) - self.addSeparator(subMenu, 'Less Damage') + self._addSeparator(subMenu, 'Less Damage') for charge in charges: - subMenu.Append(self.addCharge(rootMenu if msw else subMenu, charge)) - self.addSeparator(subMenu, 'More Damage') + subMenu.Append(self._addCharge(rootMenu if msw else subMenu, charge)) + self._addSeparator(subMenu, 'More Damage') for menuItem in menuItems: menu.Append(menuItem) - self.addSeparator(menu, 'Short Range') + self._addSeparator(menu, 'Short Range') elif modType == 'ddMissile': menuItems = [] for chargeCatName, charges in chargeDict.items(): @@ -96,16 +101,16 @@ class ChangeModuleAmmo(ContextMenuCombined): subMenu = wx.Menu() subMenu.Bind(wx.EVT_MENU, self.handleAmmoSwitch) menuItem.SetSubMenu(subMenu) - self.addSeparator(subMenu, 'Less Damage') + self._addSeparator(subMenu, 'Less Damage') for charge in charges: - subMenu.Append(self.addCharge(rootMenu if msw else subMenu, charge)) - self.addSeparator(subMenu, 'More Damage') + subMenu.Append(self._addCharge(rootMenu if msw else subMenu, charge)) + self._addSeparator(subMenu, 'More Damage') for menuItem in menuItems: menu.Append(menuItem) elif modType == 'general': for charge in chargeDict['general']: - menu.Append(self.addCharge(rootMenu if msw else menu, charge)) - menu.Append(self.addCharge(rootMenu if msw else menu, None)) + menu.Append(self._addCharge(rootMenu if msw else menu, charge)) + menu.Append(self._addCharge(rootMenu if msw else menu, None)) return menu def handleAmmoSwitch(self, event): @@ -145,7 +150,7 @@ class ChangeModuleAmmo(ContextMenuCombined): positions = [] for position, mod in enumerate(modContainer): if mod in self.selection: - modCharges = Ammo.getInstance().getModuleFlatAmmo(mod) + modCharges = self._getAmmo(mod) if modCharges.issubset(self.mainCharges): positions.append(position) self.mainFrame.command.Submit(command( diff --git a/service/ammo.py b/service/ammo.py index cce6dba24..a4d50656f 100644 --- a/service/ammo.py +++ b/service/ammo.py @@ -52,8 +52,8 @@ class Ammo: return chargeSet @classmethod - def getModuleStructuredAmmo(cls, mod): - chargesFlat = cls.getModuleFlatAmmo(mod) + def getModuleStructuredAmmo(cls, mod, ammo=None): + chargesFlat = cls.getModuleFlatAmmo(mod) if ammo is None else ammo # Make sure we do not consider mining turrets as combat turrets if mod.hardpoint == FittingHardpoint.TURRET and mod.getModifiedItemAttr('miningAmount', None) is None: