mirror of
https://github.com/MarioSpore/Grinch-AP.git
synced 2025-10-21 20:21:32 -06:00
SM: Speed up deepcopy in copy_mixin (#4228)
This commit is contained in:
@@ -8,6 +8,7 @@ from ..utils.doorsmanager import DoorsManager
|
||||
from ..utils.objectives import Objectives
|
||||
from ..utils.parameters import Knows, isKnows
|
||||
import logging
|
||||
from copy import deepcopy
|
||||
import sys
|
||||
|
||||
class SMBoolManager(object):
|
||||
@@ -34,6 +35,46 @@ class SMBoolManager(object):
|
||||
self.createFacadeFunctions()
|
||||
self.createKnowsFunctions(player)
|
||||
self.resetItems()
|
||||
self.itemsPositions = {}
|
||||
|
||||
def __deepcopy__(self, memodict):
|
||||
# Use __new__ to avoid calling __init__ like copy.deepcopy without __deepcopy__ implemented.
|
||||
new = object.__new__(type(self))
|
||||
|
||||
# Copy everything over in the same order as __init__, ensuring that mutable attributes are deeply copied.
|
||||
|
||||
# SMBool instances contain mutable lists, so must be deep-copied.
|
||||
new._items = {i: deepcopy(v, memodict) for i, v in self._items.items()}
|
||||
# `_counts` is a dict[str, int], so the dict can be copied because its keys and values are immutable.
|
||||
new._counts = self._counts.copy()
|
||||
# `player` is an int.
|
||||
new.player = self.player
|
||||
# `maxDiff` is an int.
|
||||
new.maxDiff = self.maxDiff
|
||||
# `onlyBossLeft` is a bool.
|
||||
new.onlyBossLeft = self.onlyBossLeft
|
||||
# The HelpersGraph keeps reference to the instance, so a new HelpersGraph is required.
|
||||
new.helpers = Logic.HelpersGraph(new)
|
||||
# DoorsManager is stateless, so the same instance can be used.
|
||||
new.doorsManager = self.doorsManager
|
||||
# Objectives are cached by self.player, so will be the same instance for the copy.
|
||||
new.objectives = self.objectives
|
||||
# Copy the facade functions from new.helpers into new.__dict__.
|
||||
new.createFacadeFunctions()
|
||||
# Copying the existing 'knows' functions from `self` to `new` is faster than re-creating all the lambdas with
|
||||
# `new.createKnowsFunctions(player)`.
|
||||
for key in Knows.__dict__.keys():
|
||||
if isKnows(key):
|
||||
attribute_name = "knows"+key
|
||||
knows_func = getattr(self, attribute_name)
|
||||
setattr(new, attribute_name, knows_func)
|
||||
# There is no need to call `new.resetItems()` because `_items` and `_counts` have been copied over.
|
||||
# new.resetItems()
|
||||
# itemsPositions is a `dict[str, tuple[int, int]]`, so the dict can be copied because the keys and values are
|
||||
# immutable.
|
||||
new.itemsPositions = self.itemsPositions.copy()
|
||||
|
||||
return new
|
||||
|
||||
def computeItemsPositions(self):
|
||||
# compute index in cache key for each items
|
||||
@@ -245,6 +286,9 @@ class SMBoolManagerPlando(SMBoolManager):
|
||||
def __init__(self):
|
||||
super(SMBoolManagerPlando, self).__init__()
|
||||
|
||||
def __deepcopy__(self, memodict):
|
||||
return super().__deepcopy__(memodict)
|
||||
|
||||
def addItem(self, item):
|
||||
# a new item is available
|
||||
already = self.haveItem(item)
|
||||
|
||||
Reference in New Issue
Block a user