libstatechart.rs 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. use std::collections::BinaryHeap;
  2. use std::cmp::Ordering;
  3. use std::cmp::Reverse;
  4. #[derive(Default)]
  5. struct SameRoundLifeline<InternalType> {
  6. current: InternalType,
  7. }
  8. impl<InternalType: Default> SameRoundLifeline<InternalType> {
  9. fn current(&self) -> &InternalType {
  10. &self.current
  11. }
  12. fn raise(&mut self) -> &mut InternalType {
  13. &mut self.current
  14. }
  15. fn cycle(&mut self) {
  16. self.current = Default::default()
  17. }
  18. }
  19. #[derive(Default)]
  20. struct NextRoundLifeline<InternalType> {
  21. one: InternalType,
  22. two: InternalType,
  23. one_is_current: bool,
  24. }
  25. impl<InternalType: Default> NextRoundLifeline<InternalType> {
  26. fn current(&self) -> &InternalType {
  27. if self.one_is_current { &self.one } else { &self.two }
  28. }
  29. fn raise(&mut self) -> &mut InternalType {
  30. if self.one_is_current { &mut self.two } else { &mut self.one }
  31. }
  32. fn cycle(&mut self) {
  33. if self.one_is_current {
  34. self.one = Default::default();
  35. } else {
  36. self.two = Default::default();
  37. }
  38. self.one_is_current = ! self.one_is_current
  39. }
  40. }
  41. // pub trait State<TimersType, ControllerType> {
  42. // // Execute enter actions of only this state
  43. // fn enter_actions(timers: &mut TimersType, c: &mut ControllerType);
  44. // // Execute exit actions of only this state
  45. // fn exit_actions(timers: &mut TimersType, c: &mut ControllerType);
  46. // // Execute enter actions of this state and its 'default' child(ren), recursively
  47. // fn enter_default(timers: &mut TimersType, c: &mut ControllerType);
  48. // // Execute enter actions as if the configuration recorded in this state is being entered
  49. // fn enter_current(&self, timers: &mut TimersType, c: &mut ControllerType);
  50. // // Execute exit actions as if the configuration recorded in this state is being exited
  51. // fn exit_current(&self, timers: &mut TimersType, c: &mut ControllerType);
  52. // }
  53. pub trait SC<EventType, ControllerType> {
  54. fn init(&mut self, c: &mut ControllerType);
  55. fn big_step(&mut self, event: Option<EventType>, c: &mut ControllerType);
  56. }
  57. type Timestamp = u32;
  58. type TimerId = u16;
  59. #[derive(Default, Copy, Clone, Ord, PartialOrd, PartialEq, Eq)]
  60. pub struct EntryId {
  61. timestamp: Timestamp,
  62. n: TimerId,
  63. }
  64. pub struct QueueEntry<EventType> {
  65. id: EntryId,
  66. event: EventType,
  67. }
  68. impl<EventType> Ord for QueueEntry<EventType> {
  69. fn cmp(&self, other: &Self) -> Ordering {
  70. self.id.cmp(&other.id)
  71. }
  72. }
  73. impl<EventType> PartialOrd for QueueEntry<EventType> {
  74. fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
  75. Some(self.cmp(other))
  76. }
  77. }
  78. impl<EventType> PartialEq for QueueEntry<EventType> {
  79. fn eq(&self, other: &Self) -> bool {
  80. self.id == other.id
  81. }
  82. }
  83. impl<EventType> Eq for QueueEntry<EventType> {}
  84. #[derive(Debug, Eq, PartialEq)]
  85. pub struct OutEvent {
  86. port: &'static str,
  87. event: &'static str,
  88. }
  89. pub struct Controller<EventType, OutputCallback> {
  90. simtime: Timestamp,
  91. next_id: TimerId,
  92. queue: BinaryHeap<Reverse<QueueEntry<EventType>>>,
  93. removed: BinaryHeap<Reverse<EntryId>>,
  94. output: OutputCallback,
  95. }
  96. pub enum Until {
  97. Timestamp(Timestamp),
  98. Eternity,
  99. }
  100. impl<EventType: Copy, OutputCallback: FnMut(OutEvent)>
  101. Controller<EventType, OutputCallback> {
  102. fn new(output: OutputCallback) -> Self {
  103. Self {
  104. simtime: 0,
  105. next_id: 0,
  106. queue: BinaryHeap::with_capacity(8),
  107. removed: BinaryHeap::with_capacity(4),
  108. output,
  109. }
  110. }
  111. fn set_timeout(&mut self, delay: Timestamp, event: EventType) -> EntryId {
  112. let id = EntryId{ timestamp: self.simtime + delay, n: self.next_id };
  113. let entry = QueueEntry::<EventType>{ id, event };
  114. self.queue.push(Reverse(entry));
  115. self.next_id += 1; // TODO: will overflow eventually :(
  116. return id
  117. }
  118. fn unset_timeout(&mut self, id: EntryId) {
  119. self.removed.push(Reverse(id));
  120. }
  121. fn run_until<StatechartType: SC<EventType, Controller<EventType, OutputCallback>>>(&mut self, sc: &mut StatechartType, until: Until) {
  122. 'running: loop {
  123. if let Some(Reverse(entry)) = self.queue.peek() {
  124. // Check if event was removed
  125. if let Some(Reverse(removed)) = self.removed.peek() {
  126. if entry.id == *removed {
  127. self.queue.pop();
  128. self.removed.pop();
  129. continue;
  130. }
  131. }
  132. // Check if event too far in the future
  133. if let Until::Timestamp(t) = until {
  134. if entry.id.timestamp > t {
  135. println!("break, timestamp {}, t {}", entry.id.timestamp, t);
  136. break 'running;
  137. }
  138. }
  139. // OK, handle event
  140. self.simtime = entry.id.timestamp;
  141. println!("time is now {}", self.simtime);
  142. sc.big_step(Some(entry.event), self);
  143. self.queue.pop();
  144. }
  145. else {
  146. break 'running;
  147. }
  148. }
  149. }
  150. }
  151. use std::ops::Deref;
  152. use std::ops::DerefMut;
  153. // This macro lets a struct "inherit" the data members of another struct
  154. // The inherited struct is added as a struct member and the Deref and DerefMut
  155. // traits are implemented to return a reference to the base struct
  156. macro_rules! inherit_struct {
  157. ($name: ident ($base: ty) { $($element: ident: $ty: ty),* $(,)? } ) => {
  158. struct $name {
  159. _base: $base,
  160. $($element: $ty),*
  161. }
  162. impl Deref for $name {
  163. type Target = $base;
  164. fn deref(&self) -> &$base {
  165. &self._base
  166. }
  167. }
  168. impl DerefMut for $name {
  169. fn deref_mut(&mut self) -> &mut $base {
  170. &mut self._base
  171. }
  172. }
  173. }
  174. }
  175. // "Base struct" for all scopes
  176. struct Empty{}
  177. // A closure object is a pair of a functions first argument and that function.
  178. // The call may be part of an larger expression, and therefore we cannot just write 'let' statements to assign the pair's elements to identifiers which we need for the call.
  179. // This macro does exactly that, in an anonymous Rust closure, which is immediately called.
  180. macro_rules! call_closure {
  181. ($closure: expr, $($param: expr),* $(,)?) => {
  182. (||{
  183. let scope = &mut $closure.0;
  184. let function = &mut $closure.1;
  185. return function(scope, $($param),* );
  186. })()
  187. };
  188. }