core.py 2.4KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. # coding: utf-8
  2. import time
  3. from synergine2.cycle import CycleManager
  4. from synergine2.simulation import Simulation
  5. from synergine2.terminals import TerminalManager
  6. from synergine2.terminals import TerminalPackage
  7. class Core(object):
  8. def __init__(
  9. self,
  10. simulation: Simulation,
  11. cycle_manager: CycleManager,
  12. terminal_manager: TerminalManager=None,
  13. cycles_per_seconds: int=1,
  14. ):
  15. self.simulation = simulation
  16. self.cycle_manager = cycle_manager
  17. self.terminal_manager = terminal_manager or TerminalManager([])
  18. self._loop_delta = 1./cycles_per_seconds
  19. self._current_cycle_start_time = None
  20. def run(self):
  21. try:
  22. self.terminal_manager.start()
  23. start_package = TerminalPackage(
  24. subjects=self.simulation.subjects,
  25. )
  26. self.terminal_manager.send(start_package)
  27. while True:
  28. self._start_cycle()
  29. events = []
  30. packages = self.terminal_manager.receive()
  31. for package in packages:
  32. events.extend(self.cycle_manager.apply_actions(
  33. simulation_actions=package.simulation_actions,
  34. subject_actions=package.subject_actions,
  35. ))
  36. events.extend(self.cycle_manager.next())
  37. cycle_package = TerminalPackage(
  38. events=events,
  39. add_subjects=self.simulation.subjects.adds,
  40. remove_subjects=self.simulation.subjects.removes,
  41. is_cycle=True,
  42. )
  43. self.terminal_manager.send(cycle_package)
  44. # Reinitialize these list for next cycle
  45. self.simulation.subjects.adds = []
  46. self.simulation.subjects.removes = []
  47. self._end_cycle()
  48. except KeyboardInterrupt:
  49. pass # Just stop while
  50. self.terminal_manager.stop()
  51. def _start_cycle(self):
  52. self._current_cycle_start_time = time.time()
  53. def _end_cycle(self) -> None:
  54. """
  55. Make a sleep if cycle duration take less time of wanted (see
  56. cycles_per_seconds constructor parameter)
  57. """
  58. cycle_duration = time.time() - self._current_cycle_start_time
  59. sleep_time = self._loop_delta - cycle_duration
  60. if sleep_time > 0:
  61. time.sleep(sleep_time)