rebuild world cache on cache miss

This commit is contained in:
Fabian Dill 2020-09-08 15:02:37 +02:00
parent 21e4135f5f
commit ada13a67fc
1 changed files with 22 additions and 19 deletions

View File

@ -144,6 +144,17 @@ class World(object):
region.world = self region.world = self
self._region_cache[region.player][region.name] = region self._region_cache[region.player][region.name] = region
def _recache(self):
"""Rebuild world cache"""
for region in self.regions:
player = region.player
self._region_cache[player][region.name] = region
for exit in region.exits:
self._entrance_cache[exit.name, player] = exit
for r_location in region.locations:
self._location_cache[r_location.name, player] = r_location
def get_regions(self, player=None): def get_regions(self, player=None):
return self.regions if player is None else self._region_cache[player].values() return self.regions if player is None else self._region_cache[player].values()
@ -151,11 +162,8 @@ class World(object):
try: try:
return self._region_cache[player][regionname] return self._region_cache[player][regionname]
except KeyError: except KeyError:
for region in self.regions: self._recache()
if region.name == regionname and region.player == player: return self._region_cache[player][regionname]
assert not region.world # this should only happen before initialization
return region
raise RuntimeError('No such region %s for player %d' % (regionname, player))
def _debug_get_region(self, regionname: str, player: int) -> Region: def _debug_get_region(self, regionname: str, player: int) -> Region:
if type(regionname) != str: if type(regionname) != str:
@ -166,19 +174,16 @@ class World(object):
for region in self.regions: for region in self.regions:
if region.name == regionname and region.player == player: if region.name == regionname and region.player == player:
assert not region.world # this should only happen before initialization assert not region.world # this should only happen before initialization
self._region_cache[player][regionname] = region
return region return region
raise RuntimeError('No such region %s for player %d' % (regionname, player)) raise RuntimeError('No such region %s for player %d' % (regionname, player))
def get_entrance(self, entrance: str, player: int) -> Entrance: def get_entrance(self, entrance: str, player: int) -> Entrance:
try: try:
return self._entrance_cache[(entrance, player)] return self._entrance_cache[entrance, player]
except KeyError: except KeyError:
for region in self.regions: self._recache()
for exit in region.exits: return self._entrance_cache[entrance, player]
if exit.name == entrance and exit.player == player:
self._entrance_cache[(entrance, player)] = exit
return exit
raise RuntimeError('No such entrance %s for player %d' % (entrance, player))
def _debug_get_entrance(self, entrance: str, player: int) -> Entrance: def _debug_get_entrance(self, entrance: str, player: int) -> Entrance:
if type(entrance) != str: if type(entrance) != str:
@ -191,18 +196,15 @@ class World(object):
if exit.name == entrance and exit.player == player: if exit.name == entrance and exit.player == player:
self._entrance_cache[(entrance, player)] = exit self._entrance_cache[(entrance, player)] = exit
return exit return exit
raise RuntimeError('No such entrance %s for player %d' % (entrance, player)) raise RuntimeError('No such entrance %s for player %d' % (entrance, player))
def get_location(self, location: str, player: int) -> Location: def get_location(self, location: str, player: int) -> Location:
try: try:
return self._location_cache[(location, player)] return self._location_cache[location, player]
except KeyError: except KeyError:
for region in self.regions: self._recache()
for r_location in region.locations: return self._location_cache[location, player]
if r_location.name == location and r_location.player == player:
self._location_cache[(location, player)] = r_location
return r_location
raise RuntimeError('No such location %s for player %d' % (location, player))
def _debug_get_location(self, location: str, player: int) -> Location: def _debug_get_location(self, location: str, player: int) -> Location:
if type(location) != str: if type(location) != str:
@ -215,6 +217,7 @@ class World(object):
if r_location.name == location and r_location.player == player: if r_location.name == location and r_location.player == player:
self._location_cache[(location, player)] = r_location self._location_cache[(location, player)] = r_location
return r_location return r_location
raise RuntimeError('No such location %s for player %d' % (location, player)) raise RuntimeError('No such location %s for player %d' % (location, player))
def get_dungeon(self, dungeonname: str, player: int) -> Dungeon: def get_dungeon(self, dungeonname: str, player: int) -> Dungeon: