simulation.py 2.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. import collections
  2. from synergine2.utils import initialize_subject
  3. class Simulation(object):
  4. def __init__(self):
  5. self.collections = collections.defaultdict(list)
  6. self._subjects = None
  7. @property
  8. def subjects(self):
  9. return self._subjects
  10. @subjects.setter
  11. def subjects(self, value: 'Subjects'):
  12. if not isinstance(value, Subjects):
  13. raise Exception('Simulation.subjects must be Subjects type')
  14. self._subjects = value
  15. class Subject(object):
  16. collections = []
  17. behaviours_classes = []
  18. def __init__(self, simulation: Simulation):
  19. self.id = id(self) # We store object id because it's lost between process
  20. self.simulation = simulation
  21. self.behaviours = {}
  22. self.mechanisms = {}
  23. for collection in self.collections:
  24. self.simulation.collections[collection].append(self)
  25. initialize_subject(
  26. simulation=simulation,
  27. subject=self,
  28. )
  29. class Subjects(list):
  30. def __init__(self, *args, **kwargs):
  31. self.simulation = kwargs.pop('simulation')
  32. super().__init__(*args, **kwargs)
  33. def remove(self, value: Subject):
  34. super().remove(value)
  35. for collection_name in value.collections:
  36. self.simulation.collections[collection_name].remove(value)
  37. class Mechanism(object):
  38. def __init__(
  39. self,
  40. simulation: Simulation,
  41. subject: Subject,
  42. ):
  43. self.simulation = simulation
  44. self.subject = subject
  45. def run(self):
  46. raise NotImplementedError()
  47. class Behaviour(object):
  48. def __init__(
  49. self,
  50. simulation: Simulation,
  51. subject: Subject,
  52. ):
  53. self.simulation = simulation
  54. self.subject = subject
  55. def run(self, data):
  56. """
  57. Method called in subprocess.
  58. If return equivalent to False, behaviour produce nothing.
  59. If return equivalent to True, action bahaviour method
  60. will be called with these data
  61. Note: Returned data will be transfered from sub processes.
  62. Prefer scalar types.
  63. """
  64. raise NotImplementedError()
  65. def action(self, data):
  66. """
  67. Method called in main process
  68. """
  69. raise NotImplementedError()