From 31951696faf591c6d92236c70a9637c7620111e5 Mon Sep 17 00:00:00 2001 From: Christian Heller Date: Sat, 5 Dec 2020 02:46:53 +0100 Subject: [PATCH] Multi-process FOV generation on send_gamestate. --- plomrogue/game.py | 18 +++++++++++++++++- plomrogue/mapping.py | 10 ++++++++-- plomrogue/things.py | 20 ++++++++++++++++---- 3 files changed, 41 insertions(+), 7 deletions(-) diff --git a/plomrogue/game.py b/plomrogue/game.py index 453ee30..ff76155 100755 --- a/plomrogue/game.py +++ b/plomrogue/game.py @@ -203,7 +203,23 @@ class Game(GameBase): """Send out game state data relevant to clients.""" self.io.send('TURN ' + str(self.turn)) - for c_id in self.sessions: + from plomrogue.mapping import FovMap + import multiprocessing + pool = multiprocessing.Pool() + players = [] + c_ids = [c_id for c_id in self.sessions] + for c_id in c_ids: + players += [self.get_player(c_id)] + player_fovs = [] + for player in players: + player.prepare_multiprocessible_fov_stencil() + player_fovs += [player._fov] + new_fovs = pool.map(FovMap.init_terrain, [fov for fov in player_fovs]) + for i in range(len(players)): + players[i]._fov = new_fovs[i] + pool.close() + pool.join() + for c_id in c_ids: player = self.get_player(c_id) visible_terrain = player.fov_stencil_map() self.io.send('FOV %s' % quote(player.fov_stencil.terrain), c_id) diff --git a/plomrogue/mapping.py b/plomrogue/mapping.py index d1fc9fb..e806ef7 100644 --- a/plomrogue/mapping.py +++ b/plomrogue/mapping.py @@ -210,7 +210,6 @@ class Map(): class SourcedMap(Map): def __init__(self, things, source_maps, source_center, radius, get_map): - self.source_maps = source_maps self.radius = radius example_map = get_map(YX(0, 0)) self.source_geometry = example_map.geometry @@ -233,7 +232,7 @@ class SourcedMap(Map): if big_yx in obstacles and little_yx in obstacles[big_yx]: self.source_map_segment += 'X' else: - self.source_map_segment += self.source_maps[big_yx][little_yx] + self.source_map_segment += source_maps[big_yx][little_yx] def source_yxyx(self, yx): absolute_yx = yx + self.offset @@ -294,7 +293,14 @@ class FovMap(SourcedMap): self.terrain = '?' * self.size_i self[self.center] = '.' self.shadow_cones = [] + #self.circle_out(self.center, self.shadow_process) + + def init_terrain(self): + # we outsource this to allow multiprocessing some stab at it, + # and return it since multiprocessing does not modify its + # processing sources self.circle_out(self.center, self.shadow_process) + return self def throws_shadow(self, yx): return self.source_map_segment[self.get_position_index(yx)] == 'X' diff --git a/plomrogue/things.py b/plomrogue/things.py index a5d3889..9edfa68 100644 --- a/plomrogue/things.py +++ b/plomrogue/things.py @@ -329,16 +329,28 @@ class ThingAnimate(Thing): self.game.changed = True self.task = self.get_next_task() + def prepare_multiprocessible_fov_stencil(self): + fov_map_class = self.game.map_geometry.fov_map_class + fov_radius = 3 if self.drunk > 0 else 12 + self._fov = fov_map_class(self.game.things, self.game.maps, + self.position, fov_radius, self.game.get_map) + + def multiprocessible_fov_stencil(self): + self._fov.init_terrain() + @property def fov_stencil(self): if self._fov: return self._fov - fov_map_class = self.game.map_geometry.fov_map_class - fov_radius = 3 if self.drunk > 0 else 12 - self._fov = fov_map_class(self.game.things, self.game.maps, self.position, - fov_radius, self.game.get_map) + # due to the pre-multiprocessing in game.send_gamestate, + # the following should actually never be called + self.prepare_multiprocessible_fov_stencil() + self.multiprocessible_fov_stencil() return self._fov + def fov_stencil_make(self): + self._fov.make() + def fov_test(self, big_yx, little_yx): test_position = self.fov_stencil.target_yx(big_yx, little_yx) if self.fov_stencil.inside(test_position): -- 2.30.2