def test_proximity_mechanism_excluding(self): shared.reset() simulation = XYZSimulation(Config()) subject = MySubject(Config(), simulation, position=(0, 0, 0)) other_subject = MySubject(Config(), simulation, position=(11, 0, 0)) simulation.subjects = XYZSubjects( [subject, other_subject], simulation=simulation, ) simulation.subjects.auto_expose = False proximity_mechanism = MyProximityMechanism( config=Config(), simulation=simulation, subject=subject, ) assert 11 == proximity_mechanism.get_distance_of( position=subject.position, subject=other_subject, ) # other_subject is to far away assert [] == proximity_mechanism.run()
def test_terminals_communications(self): terminals_manager = TerminalManager(Config(), terminals=[ MultiplyTerminal(Config()), DivideTerminal(Config()), ]) terminals_manager.start() terminals_manager.send(ValueTerminalPackage(value=42)) # We wait max 2s (see time.sleep) to consider # process have finished. If not, it will fail packages = [] for i in range(200): packages.extend(terminals_manager.receive()) if len(packages) == 4: break time.sleep(0.01) assert 4 == len(packages) values = [p.value for p in packages] assert 84 in values assert 168 in values assert 21 in values assert 10.5 in values terminals_manager.stop() # TODO pytest must execute this if have fail
def test_proximity_mechanism_with_one(self): shared.reset() simulation = XYZSimulation(Config()) subject = MySubject(Config(), simulation, position=(0, 0, 0)) other_subject = MySubject(Config(), simulation, position=(5, 0, 0)) simulation.subjects = XYZSubjects( [subject, other_subject], simulation=simulation, ) simulation.subjects.auto_expose = False proximity_mechanism = MyProximityMechanism( config=Config(), simulation=simulation, subject=subject, ) assert 5 == proximity_mechanism.get_distance_of( position=subject.position, subject=other_subject, ) assert [{ 'subject_id': other_subject.id, 'direction': 90.0, 'distance': 5.0, }] == proximity_mechanism.run()
def main( units_file_path: str, teams_file_path: str, countries: typing.List[str], troops_dir_path: str = '.', ) -> None: config = Config() config.load_yaml('config.yaml') troop_manager = TroopManager( config, units_file_path=units_file_path, teams_file_path=teams_file_path, ) master = Tk() gui = SelectTroopsGui( config, master=master, team_stash=troop_manager.team_stash, troop_manager=troop_manager, countries=countries, troops_dir_path=troops_dir_path, ) master.mainloop()
def test_event_listen_specified(self): class ListenAnEventTerminal(SendBackTerminal): subscribed_events = [AnOtherEvent] terminals_manager = TerminalManager( Config(), terminals=[ListenAnEventTerminal(Config())]) terminals_manager.start() terminals_manager.send(ValueTerminalPackage(value=42)) an_event = AnEvent() an_other_event = AnOtherEvent() terminals_manager.send( TerminalPackage(events=[an_event, an_other_event])) # We wait max 10s (see time.sleep) to consider # process have finished. If not, it will fail packages = [] for i in range(1000): packages.extend(terminals_manager.receive()) if len(packages) == 2: break time.sleep(0.01) assert 2 == len(packages) assert AnOtherEvent == type(packages[1].events[0]) terminals_manager.stop() # TODO pytest must execute this if have fail
def config() -> Config: config_ = Config() config_.load_yaml('test_config.yaml') config_['_runtime'] = {} config_['_runtime']['map_dir_path'] = 'tests/fixtures/map_a/map_a.tmx' return config_
def test_after_created_shared_data(self): shared = SharedDataManager() shared.set('foo_1', 0) def job(worker_id, processes_count, key): shared.refresh() value = shared.get('foo_{}'.format(key)) or 0 return value + 1 process_manager = ProcessManager( config=Config({}), process_count=available_cores, job=job, ) process_manager.start_workers() shared.set('foo_1', 42) shared.commit() results = process_manager.make_them_work('1') assert results[0] == 43 shared.set('foo_2', 52) shared.commit() results = process_manager.make_them_work('2') assert results[0] == 53 process_manager.terminate()
def test_share_data_with_function(self): shared = SharedDataManager() class Foo(object): counter = shared.create('counter', 0) def job(*args, **kwargs): shared.refresh() counter = shared.get('counter') or 0 return counter + 1 process_manager = ProcessManager( config=Config({}), process_count=available_cores, job=job, ) process_manager.start_workers() foo = Foo() foo.counter = 42 shared.commit() results = process_manager.make_them_work(None) assert results[0] == 43 foo.counter = 45 shared.commit() results = process_manager.make_them_work(None) assert results[0] == 46 process_manager.terminate()
def __init__( self, config: Config, simulation: Simulation, process_manager: ProcessManager = None, ): # TODO: reproduire le mechanisme d'index de behaviour/etc pour simulation self.config = config self.logger = get_logger('Cycle', config) self.simulation = simulation self.current_cycle = -1 self.first_cycle = True # TODO NOW: Les processes devront maintenir une liste des subjects qui sont nouveaux.ne connaissent pas # Attention a ce qu'in ne soient pas "expose" quand on créer ces subjects au sein du process. # Ces subjects ont vocation à adopter l'id du vrau subject tout de suite après leur instanciation if process_manager is None: process_manager = ProcessManager( config=config, # TODO: Changer de config de merde (core.use_x_cores) process_count=config.get('core', {}).get('use_x_cores', multiprocessing.cpu_count()), job=self.job, ) self.process_manager = process_manager
def test_new_subject(self): shared.reset() config = Config({'core': {'use_x_cores': 1}}) simulation = Simulation(config) subjects = MySubjects(simulation=simulation) simulation.subjects = subjects for i in range(3): subjects.append(MySubject(config, simulation=simulation)) cycle_manager = CycleManager( config=config, simulation=simulation, ) events = cycle_manager.next() assert 3 == len(events) event_values = [e.value for e in events] assert all([s.id * 2 in event_values for s in subjects]) subjects.append(MySubject(config, simulation=simulation)) events = cycle_manager.next() cycle_manager.stop() assert 4 == len(events) event_values = [e.value for e in events] assert all([s.id * 2 in event_values for s in subjects])
def test_state_loader_builder__ok__nominal_case(simulation, ): config = Config( {'global': { 'state_loader': 'tests.test_state.MyStateLoader', }}) builder = StateConstructorBuilder(config, simulation) state_loader = builder.get_state_loader() assert type(state_loader) == MyStateLoader
def test_subject_composed_behaviour(self): config = Config({}) simulation = XYZSimulation(config) subject = XYZSubject(config, simulation) my_composed_behaviour = MyComposedBehaviour( config=config, simulation=simulation, subject=subject, ) # Thirst cycle, ThirstStep is reached and produce event data = my_composed_behaviour.run({ 'base': 0, }) assert {'base': 0, 'first': 0} == data events = my_composed_behaviour.action(data) assert events assert 2 == len(events) assert isinstance(events[0], BeginBaseEvent) assert isinstance(events[1], BeginFirstEvent) # Second cycle (with previous cycle data), there is data but no events data = my_composed_behaviour.run(data) assert {'base': 0, 'first': 0.5} == data events = my_composed_behaviour.action(data) assert not events # Third cycle (still with previous cycle data) there is data but and events data = my_composed_behaviour.run(data) assert {'base': 0, 'second': 0} == data events = my_composed_behaviour.action(data) assert events assert 2 == len(events) assert isinstance(events[0], BeginSecondEvent) assert isinstance(events[1], FinishFirstEvent) # Fourth cycle (still with previous cycle data) there is data but no events data = my_composed_behaviour.run(data) assert {'base': 0, 'second': 0.5} == data events = my_composed_behaviour.action(data) assert not events # Cycle 5 (still with previous cycle data) there is data and events data = my_composed_behaviour.run(data) assert {'base': 1, 'second': 1} == data events = my_composed_behaviour.action(data) assert events assert 2 == len(events) assert isinstance(events[0], FinishSecondEvent) assert isinstance(events[1], FinishBaseEvent)
def __init__( self, config: Config, actor: 'BaseActor', ) -> None: self.actor = actor self._images_scheme = self.get_rest_images_scheme() self._firing_images_scheme = self.get_firing_images_scheme() self.path_manager = PathManager(config.resolve('global.include_path.graphics')) self._cache = {} # type: typing.Dict[str, Image.Image] self._firing_cache = {} # type: typing.Dict[str, Image.Image]
def __init__( self, actor: 'Actor', config: Config, ) -> None: self.config = config self.actor = actor self.path_manager = PathManager( config.resolve('global.include_path.graphics')) self.animation_cache = AnimationImageCache()
def test_proximity_mechanism_with_multiple(self): shared.reset() simulation = XYZSimulation(Config()) subject = MySubject(Config(), simulation, position=(0, 0, 0)) other_subjects = [] for i in range(3): other_subjects.append( MySubject(Config(), simulation, position=(i, i, 0))) simulation.subjects = XYZSubjects([subject], simulation=simulation) simulation.subjects.extend(other_subjects) simulation.subjects.auto_expose = False proximity_mechanism = MyProximityMechanism( config=Config(), simulation=simulation, subject=subject, ) data = proximity_mechanism.run() assert [ { 'direction': 0, 'subject_id': other_subjects[0].id, 'distance': 0.0, }, { 'direction': 135.0, 'subject_id': other_subjects[1].id, 'distance': 1.41 }, { 'direction': 135.0, 'subject_id': other_subjects[2].id, 'distance': 2.83 }, ] == data
def test_parallel_jobs_with_scalar(self): process_manager = ProcessManager( config=Config({}), process_count=available_cores, job=self.make_job_with_scalar, ) process_manager.start_workers() data = list(range(100)) results = process_manager.make_them_work(data) process_manager.terminate() assert sum(results) == 4950 * available_cores
def test_non_parallel_jobs_with_scalar(self): # TODO: process manager utilise actuellement un cpu quand même, changer ca process_manager = ProcessManager( config=Config({}), process_count=1, job=self.make_job_with_scalar, ) process_manager.start_workers() data = list(range(100)) results = process_manager.make_them_work(data) process_manager.terminate() final_result = results[0] assert len(results) == 1 assert final_result == 4950
def test_terminal_as_main_process(self): shared.reset() config = Config() simulation = Simulation(config) simulation.subjects = Subjects(simulation=simulation) cycle_manager = CycleManager( config=config, simulation=simulation, ) global terminal_pid global core_pid terminal_pid = 0 core_pid = 0 class MyMainTerminal(Terminal): main_process = True def run(self): global terminal_pid terminal_pid = os.getpid() terminal = MyMainTerminal(config) class MyCore(Core): def _end_cycle(self): self._continue = False global core_pid core_pid = os.getpid() core = MyCore( config=config, simulation=simulation, cycle_manager=cycle_manager, terminal_manager=TerminalManager( config=config, terminals=[terminal], ), ) core.run() core.main_process_terminal.core_process.terminate() cycle_manager.stop() assert terminal_pid == os.getpid() assert core_pid == 0 # because changed in other process
def test_parallel_jobs_with_objects(self): process_manager = ProcessManager( config=Config({}), process_count=available_cores, job=self.make_job_with_object, ) process_manager.start_workers() data = [MyFakeClass(v) for v in range(100)] final_result = 0 results = process_manager.make_them_work(data) process_manager.terminate() for result_object in results: final_result += result_object.value assert final_result == 4950 * available_cores
def test_simulation_events(self): shared.reset() config = Config({'core': {'use_x_cores': 2}}) simulation = MySimulation(config) subjects = MySubjects(simulation=simulation) simulation.subjects = subjects cycle_manager = CycleManager( config=config, simulation=simulation, ) events = cycle_manager.next() cycle_manager.stop() assert 1 == len(events) assert events[0].value == 4002
def __init__(self, image_path: str, subject: Subject, position=(0, 0), rotation=0, scale=1, opacity=255, color=(255, 255, 255), anchor=None, properties: dict = None, config: Config = None, **kwargs): # Note: Parameter required, but we want to modify little as possible parent init assert config, "Config is a required parameter" self.config = config self.path_manager = PathManager( config.resolve('global.include_path.graphics')) self.animation_images = { } # type: typing.Dict[str, typing.List[pyglet.image.TextureRegion]] # nopep8 default_texture = self._get_default_image_texture() super().__init__(default_texture, position, rotation, scale, opacity, color, anchor, **kwargs) self.logger = get_logger('Actor', config) self.subject = subject self.cshape = None # type: collision_model.AARectShape self.update_cshape() self.default_texture = default_texture self.need_update_cshape = False self.properties = properties or {} self._freeze = False self.animation_textures_cache = { } # type: typing.Dict[str, typing.List[pyglet.image.TextureRegion]] # nopep8 self.mode_texture_cache = { } # type: typing.Dict[str, pyglet.image.TextureRegion] # nopep8 self.default_image_path = image_path self.image_cache_manager = self.get_image_cache_manager() self.image_cache_manager.build() self.build_textures_cache()
def test_shared_memory_with_shared_manager(self): shared = SharedDataManager() shared.set('counter', 42) shared.commit() def job(*args, **kwargs): shared.refresh() counter = shared.get('counter') or 0 return counter + 1 process_manager = ProcessManager( config=Config({}), process_count=available_cores, job=job, ) process_manager.start_workers() results = process_manager.make_them_work(None) process_manager.terminate() assert results[0] == 43
def get_logger(name: str, config: Config) -> SynergineLogger: global_logging_level = config.resolve('global.logging_level', 'ERROR') logger_level_str = config.resolve('global.logger.{}.level', global_logging_level) logger_level = logging.getLevelName(logger_level_str) return get_default_logger('synergine-{}'.format(name), logger_level)
def main( map_dir_path: str, seed_value: int=None, state_file_path: str=None, troops_file_path: str=None, state_save_dir: str='.', placement_mode: bool = False, ): assert not (state_file_path and troops_file_path),\ 'Do not provide troops file when state file given' if seed_value is not None: seed(seed_value) config = Config() config.load_yaml('config.yaml') # Runtime config config['_runtime'] = {} config['_runtime']['state_save_dir'] = state_save_dir config['_runtime']['placement_mode'] = placement_mode config['_runtime']['map_dir_path'] = map_dir_path level = logging.getLevelName(config.resolve('global.logging_level', 'ERROR')) logger = get_default_logger(level=level) map_file_path = get_map_file_path_from_dir(map_dir_path) simulation = TileStrategySimulation(config, map_file_path=map_file_path) subjects = TileStrategySubjects(simulation=simulation) simulation.subjects = subjects if state_file_path: state_loader_builder = StateConstructorBuilder(config, simulation) state_loader = state_loader_builder.get_state_loader() state = state_loader.get_state(state_file_path) subjects.extend(state.subjects) elif troops_file_path: troop_loader_builder = TroopConstructorBuilder(config, simulation) troop_loader = troop_loader_builder.get_troop_loader() placement = Placement(config, simulation) troops = troop_loader.get_troop(troops_file_path) subjects.extend(troops.subjects) placement.place() core = Core( config=config, simulation=simulation, cycle_manager=CycleManager( config=config, simulation=simulation, ), terminal_manager=TerminalManager( config=config, terminals=[CocosTerminal( config, asynchronous=False, map_dir_path=map_dir_path, )] ), cycles_per_seconds=1 / config.resolve('core.cycle_duration'), ) core.run()
def predicate( config: Config, simulation: Simulation, ): return bool(config.resolve(parameter_to_resolve, False))
def do_nothing_process_manager() -> ProcessManager: return ProcessManager( Config(), process_count=0, job=lambda: None, )
def test_get_map_file_path(self): test = MapMiddleware(Config(), 'map/003') assert test.get_map_file_path() == 'map/003/003.tmx' test = MapMiddleware(Config(), 'map/003/') assert test.get_map_file_path() == 'map/003/003.tmx'
from synergine2.config import Config from synergine2.cycle import CycleManager from synergine2.processing import ProcessManager from synergine2.share import shared from synergine2.simulation import Simulation from synergine2.simulation import Subjects from synergine2.simulation import SubjectBehaviour from synergine2.simulation import SubjectMechanism from synergine2.simulation import Subject from synergine2.simulation import SimulationMechanism from synergine2.simulation import SimulationBehaviour from tests import BaseTest from freezegun import freeze_time config = Config() class MySubjectMechanism(SubjectMechanism): def run(self): return {'foo': 42} class MySimulationMechanism(SimulationMechanism): def run(self, process_number: int=None, process_count: int=None): return {'foo': 42} class MySubjectBehaviour(SubjectBehaviour): use = [MySubjectMechanism]
def __init__( self, config: Config, terminal: Terminal, physics: Physics, read_queue_interval: float = 1 / 60.0, map_dir_path: str = None, ): super().__init__( config, terminal, physics=physics, read_queue_interval=read_queue_interval, map_dir_path=map_dir_path, ) self.sound_lib = AudioLibrary( config.resolve('global.include_path.sounds')) self.graphic_path_manager = PathManager( self.config.resolve('global.include_path.graphics', )) self.debug_gui = self.config.resolve('global.debug_gui', False) self.terminal.register_event_handler( move.SubjectFinishTileMoveEvent, self.set_subject_position, ) self.terminal.register_event_handler( move.SubjectFinishMoveEvent, self.set_subject_position, ) self.terminal.register_event_handler( move.SubjectStartTileMoveEvent, self.start_move_subject, ) self.terminal.register_event_handler( move.SubjectStartRotationEvent, self.start_rotate_subject, ) self.terminal.register_event_handler( move.SubjectFinishRotationEvent, self.rotate_subject, ) self.terminal.register_event_handler( NewVisibleOpponent, self.new_visible_opponent, ) self.terminal.register_event_handler( NoLongerVisibleOpponent, self.no_longer_visible_opponent, ) self.terminal.register_event_handler( FireEvent, self.fire_happen, ) self.terminal.register_event_handler( DieEvent, self.subject_die, ) self.dead_soldier_image = pyglet.resource.image( self.graphic_path_manager.path('actors/man_d1.png', )) # subject/actor mapping self.subject_mapper_factory.register_mapper( ManSubject, SubjectMapper(self.config, ManActor), ) self.subject_mapper_factory.register_mapper( TankSubject, SubjectMapper(self.config, HeavyVehicleActor), )