Issues (19)

synergine/core/CycleCalculator.py (2 issues)

1
from synergine.lib.process.processmanager import KeepedAliveProcessManager
2
from synergine.core.cycle.PipePackage import PipePackage
3
from synergine.core.simulation.EventManager import EventManager
4
from synergine.core.Signals import Signals
5
from synergine.synergy.event.exception.ActionAborted import ActionAborted
6
7
8
class CycleCalculator():
9
    """
10
    Run cycles of simulation
11
    """
12
13
    ACTION_RUNNED = 'signal.action_runned'
14
15
    def __init__(self, context, synergy_manager, config, force_main_process=False):
16
        self._context = context
17
        self._synergy_manager = synergy_manager
18
        self._event_manager = EventManager(self._synergy_manager)
19
        self._event_manager.refresh()
20
        self._force_main_process = force_main_process
21
        self._config = config
22
        # TODO: Recuprer le nb de process depuis l'os
23
        self._process_manager = KeepedAliveProcessManager(nb_process=self._config.get('engine.processes', 2),
24
                                                          target=self._process_compute)
25
        self._cycle = 0
26
        self._current_cycle_actions_done = []
27
28
    def get_cycle(self):
29
        return self._cycle
30
31
    def compute(self):
32
        self._cycle += 1
33
        #print('cycle: ', self._cycle)
34
        self._current_cycle_actions_done = []
35
        self._compute_events()
36
        self._compute_simulations_end_cycle()
37
        return self._current_cycle_actions_done
38
39
    def _compute_events(self):
40
        for step_key, mechanisms in enumerate(self._event_manager.get_mechanisms_steps()):
41
            actions = self._get_computeds_objects(step_key)
42
            self._apply_cycle_actions(actions)
43
            self._apply_actions(actions)
44
45
    def _get_computeds_objects(self, step_key):
46
        pipe_package = self._get_pipe_package_for_collection(step_key)
47
        if not self._force_main_process:
48
            computeds_objects = self._process_manager.get_their_work(pipe_package)
49
        else:
50
            pipe_package.setCountProcess(1)
51
            pipe_package.setCurrentProcessId(0)
52
            computeds_objects = self._process_compute(pipe_package)
53
        return computeds_objects
54
55
    def _get_pipe_package_for_collection(self, step_key):
0 ignored issues
show
Coding Style Naming introduced by
The name _get_pipe_package_for_collection does not conform to the method naming conventions ([a-z_][a-z0-9_]{2,30}$).

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
56
        pipe_package = PipePackage()
57
        pipe_package.set_step_key(step_key)
58
        self._context.set_cycle(self._cycle)
59
        # TODO: 1: Seule les metas ont besoin d'etre trimbale
60
        # TODO: 2: Transporter le differentiel des metas pour le calculs a traver le reseau
61
        pipe_package.set_context(self._context)
62
63
        # TODO: Le paquet de retour contient les actions instancies. On peu alleger le paquet en retournant qqch comme ca:
0 ignored issues
show
This line is too long as per the coding-style (122/120).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
64
        # {action_id: ((obj_id, obj_id, ...), parameters)}
65
        # import sys
66
        # import pickle
67
        # size = sys.getsizeof(pickle.dumps(pipe_package))
68
        # print(size)
69
70
        return pipe_package
71
72
    def _process_compute(self, pipe_package):
73
        """
74
        Since here, we are in process mode: you only have to use metas (objects_ids, states)
75
        :param pipe_package:
76
        :return:
77
        """
78
        context = pipe_package.get_context()
79
        step_key = pipe_package.get_step_key()
80
        actions = []
81
        for mechanism in self._event_manager.get_mechanisms_steps()[step_key]:
82
            mechanism_actions = mechanism.run(context)
83
            for mechanism_action in mechanism_actions:
84
                actions.append(mechanism_action)
85
        return actions
86
87
    def _apply_cycle_actions(self, actions):
88
        """
89
90
        Execute actions cycle run.
91
92
        :param actions:
93
        :return:
94
        """
95
        executed_cycle_classes = []
96
        for action in actions:
97
            if type(action) not in executed_cycle_classes:
98
                action.cycle_pre_run(self._context, self._synergy_manager)
99
                executed_cycle_classes.append(type(action))
100
101
    def _apply_actions(self, actions):
102
        """
103
104
        Execute all actions run.
105
106
        :param actions: list of actions
107
        :return:
108
        """
109
        for action in actions:
110
            obj = self._synergy_manager.get_map().get_object(action.get_object_id())
111
            try:
112
                action.run(obj, self._context, self._synergy_manager)
113
                Signals.signal(action.__class__).send(obj=obj, context=self._context)
114
                self._current_cycle_actions_done.append(action)
115
            except ActionAborted:
116
                pass
117
118
    def _compute_simulations_end_cycle(self):
119
        for simulation in self._synergy_manager.get_simulations():
120
            simulation.end_cycle(self._context)
121
122
    def end(self):
123
        self._process_manager.stop()