Microscopic Traffic Simulator
SimulationControlViewModel.cs
Go to the documentation of this file.
6 using System;
7 using System.Windows.Input;
8 
9 namespace Microscopic_Traffic_Simulator.ViewModels
10 {
15  {
19  internal class CellularTopologyMessage : ParameterizedMessage<CellularTopology> { }
20 
24  internal class SwitchToConstructionModeMessage : Message { }
25 
29  private IInteractions interactions;
30 
34  private ISettings settings;
35 
39  private CellularTopology cellularTopology;
43  internal CellularTopology CellularTopology { get { return cellularTopology; } }
44 
48  public double SimulationSpeed
49  {
50  get { return cellularTopology.Simulation.SimulationSpeed; }
51  private set
52  {
53  cellularTopology.Simulation.SimulationSpeed = value;
54  }
55  }
56 
60  public int Seed { get { return cellularTopology.Simulation.UsedSeed; } }
61 
65  public int CustomSeed { get; set; }
66 
70  public bool IsPreviousSeedAvailable
71  {
72  get { return !settings.PreviousSeedNull; }
73  set
74  {
75  settings.PreviousSeedNull = !value;
76  if (settings.PreviousSeedNull)
77  {
78  IsPreviousSeedUsed = false;
79  }
80  OnPropertyChanged("IsPreviousSeedAvailable");
81  }
82  }
83 
87  public bool IsPreviousSeedUsed
88  {
89  get { return settings.IsPreviousSeedUsed; }
90  set
91  {
92  settings.IsPreviousSeedUsed = value;
93  settings.Save();
94  OnPropertyChanged("IsPreviousSeedUsed");
95  }
96  }
97 
101  public bool IsSeedSettingAutomatic
102  {
103  get { return settings.IsSeedSettingAutomatic; }
104  set
105  {
106  settings.IsSeedSettingAutomatic = value;
107  settings.Save();
108  }
109  }
110 
114  public ulong SimulationSteps
115  {
116  get { return cellularTopology.SimulationSteps; }
117  }
118 
122  public ulong SimulationStepsToPause
123  {
124  get { return cellularTopology.SimulationStepsToPause; }
125  set
126  {
127  cellularTopology.SimulationStepsToPause = value;
128  OnPropertyChanged("SimulationStepsToPause");
129  }
130  }
131 
135  public ulong SimulationStepsToPauseToSet { get; set; }
136 
140  public TimeSpan ModelTime
141  {
142  get { return cellularTopology.Simulation.CurrentModelTime; }
143  }
144 
148  public TimeSpan ModelTimeToPause
149  {
150  get { return cellularTopology.Simulation.ModelTimeToPause; }
151  set
152  {
153  cellularTopology.Simulation.ModelTimeToPause = value;
154  OnPropertyChanged("ModelTimeToPause");
155  }
156  }
157 
162  public TimeSpan ModelTimeToPauseToSet { get; set; }
163 
167  private double customSimulationSpeed;
171  public double CustomSimulationSpeed
172  {
173  get { return customSimulationSpeed; }
174  set { customSimulationSpeed = value; OnPropertyChanged("CustomSimulationSpeed"); }
175  }
176 
180  private bool IsNotRunning
181  {
182  get { return cellularTopology.Simulation.SimulationState != SimulationState.Running; }
183  }
184 
188  private bool CanPause
189  {
190  get { return cellularTopology.Simulation.SimulationState == SimulationState.Running; }
191  }
192 
196  private bool SimulationStarted
197  {
198  get
199  {
200  return CanPause ||
201  cellularTopology.Simulation.SimulationState == SimulationState.Paused;
202  }
203  }
204 
208  private bool isMaxSimulationSpeed;
212  public bool IsMaxSimulationSpeed
213  {
214  get { return isMaxSimulationSpeed; }
215  set
216  {
217  if (isMaxSimulationSpeed != value)
218  {
219  isMaxSimulationSpeed = value;
220  cellularTopology.Simulation.IsMaxSimulationSpeed = isMaxSimulationSpeed;
221  OnPropertyChanged("IsNotMaxSimulationSpeed");
222  }
223  }
224  }
228  public bool IsNotMaxSimulationSpeed { get { return !isMaxSimulationSpeed; } }
229 
233  private ICommand switchToConstructionModeCommand;
237  public ICommand SwitchToConstructionModeCommand
238  {
239  get
240  {
241  if (switchToConstructionModeCommand == null)
242  {
243  switchToConstructionModeCommand = new ObservableRelayCommand(
244  i => SwitchToConstructionMode());
245  }
246  return switchToConstructionModeCommand;
247  }
248  }
249 
253  private ICommand forwardCommand;
257  public ICommand ForwardCommand
258  {
259  get
260  {
261  if (forwardCommand == null)
262  {
263  forwardCommand = new ObservableRelayCommand(i => Run(), i => IsNotRunning);
264  }
265  return forwardCommand;
266  }
267  }
268 
272  private ICommand forwardStepCommand;
276  public ICommand ForwardStepCommand
277  {
278  get
279  {
280  if (forwardStepCommand == null)
281  {
282  forwardStepCommand = new ObservableRelayCommand(i => Step(), i => IsNotRunning);
283  }
284  return forwardStepCommand;
285  }
286  }
287 
291  private ICommand stopCommand;
295  public ICommand StopCommand
296  {
297  get
298  {
299  if (stopCommand == null)
300  {
301  stopCommand = new ObservableRelayCommand(i => Stop(), i => SimulationStarted);
302  }
303  return stopCommand;
304  }
305  }
306 
310  private ICommand pauseCommand;
314  public ICommand PauseCommand
315  {
316  get
317  {
318  if (pauseCommand == null)
319  {
320  pauseCommand = new ObservableRelayCommand(i => Pause(), i => CanPause);
321  }
322  return pauseCommand;
323  }
324  }
325 
329  private ICommand fasterCommand;
333  public ICommand FasterCommand
334  {
335  get
336  {
337  if (fasterCommand == null)
338  {
339  fasterCommand = new ObservableRelayCommand(i =>
340  {
341  SimulationSpeed *= 2.0;
342  OnPropertyChanged("SimulationSpeed");
343  CustomSimulationSpeed = cellularTopology.Simulation.SimulationSpeed;
344  }, i => IsNotMaxSimulationSpeed);
345  }
346  return fasterCommand;
347  }
348  }
349 
353  private ICommand slowerCommand;
357  public ICommand SlowerCommand
358  {
359  get
360  {
361  if (slowerCommand == null)
362  {
363  slowerCommand = new ObservableRelayCommand(i =>
364  {
365  SimulationSpeed /= 2.0;
366  OnPropertyChanged("SimulationSpeed");
367  CustomSimulationSpeed = cellularTopology.Simulation.SimulationSpeed;
368  }, i => IsNotMaxSimulationSpeed);
369  }
370  return slowerCommand;
371  }
372  }
373 
377  private ICommand customSimulationSpeedCommand;
381  public ICommand CustomSimulationSpeedCommand
382  {
383  get
384  {
385  if (customSimulationSpeedCommand == null)
386  {
387  customSimulationSpeedCommand = new ObservableRelayCommand(i =>
388  {
389  SimulationSpeed = customSimulationSpeed;
390  OnPropertyChanged("SimulationSpeed");
391  }, i => IsNotMaxSimulationSpeed);
392  }
393  return customSimulationSpeedCommand;
394  }
395  }
396 
400  private ICommand restartCommand;
404  public ICommand RestartCommand
405  {
406  get
407  {
408  if (restartCommand == null)
409  {
410  restartCommand = new ObservableRelayCommand(i =>
411  {
412  Stop();
413  Run();
414  }, i => SimulationStarted);
415  }
416  return restartCommand;
417  }
418  }
419 
423  private ICommand applyTimeAlarmCommand;
427  public ICommand ApplyTimeAlarmCommand
428  {
429  get
430  {
431  if (applyTimeAlarmCommand == null)
432  {
433  applyTimeAlarmCommand = new RelayCommand(
434  i => ModelTimeToPause = ModelTimeToPauseToSet);
435  }
436  return applyTimeAlarmCommand;
437  }
438  }
439 
443  private ICommand applySimulationStepsAlarmCommand;
447  public ICommand ApplySimulationStepsAlarmCommand
448  {
449  get
450  {
451  if (applySimulationStepsAlarmCommand == null)
452  {
453  applySimulationStepsAlarmCommand = new RelayCommand(
454  i => SimulationStepsToPause = SimulationStepsToPauseToSet);
455  }
456  return applySimulationStepsAlarmCommand;
457  }
458  }
459 
463  private ICommand resetModelTimeAlarmCommand;
467  public ICommand ResetModelTimeAlarmCommand
468  {
469  get
470  {
471  if (resetModelTimeAlarmCommand == null)
472  {
473  resetModelTimeAlarmCommand = new RelayCommand(i => ModelTimeToPause = TimeSpan.MaxValue);
474  }
475  return resetModelTimeAlarmCommand;
476  }
477  }
478 
482  private ICommand resetSimulationStepsAlarmCommand;
486  public ICommand ResetSimulationStepsAlarmCommand
487  {
488  get
489  {
490  if (resetSimulationStepsAlarmCommand == null)
491  {
492  resetSimulationStepsAlarmCommand = new RelayCommand(i => SimulationStepsToPause = ulong.MaxValue);
493  }
494  return resetSimulationStepsAlarmCommand;
495  }
496  }
497 
502  internal SimulationControlViewModel(Messenger messenger, IInteractions interactions, ISettings settings)
503  {
504  this.messenger = messenger;
505  this.interactions = interactions;
506  this.settings = settings;
507  messenger.GetEvent<ConstructionViewModel.BuildCellularTopologyMessage>().Subscribe(
508  (topology, parameters) => BuildCellularTopology(topology, parameters));
509  }
510 
515  private void BuildCellularTopology(GeometricTopology geometricTopology, Parameters parameters)
516  {
517  if (cellularTopology != null)
518  {
519  cellularTopology.Simulation.ModelTimeChanged -= Simulation_ModelTimeChanged;
520  cellularTopology.SimulationStepsChanged -= cellularTopology_SimulationStepsChanged;
521  }
522  cellularTopology = new CellularTopology(geometricTopology, parameters);
523  CustomSimulationSpeed = cellularTopology.Simulation.SimulationSpeed;
524  cellularTopology.Simulation.ModelTimeChanged += Simulation_ModelTimeChanged;
525  cellularTopology.SimulationStepsChanged += cellularTopology_SimulationStepsChanged;
526  messenger.GetEvent<CellularTopologyMessage>().Publish(cellularTopology);
527  }
528 
532  private void SwitchToConstructionMode()
533  {
534  if (cellularTopology.Simulation.SimulationState == SimulationState.Running)
535  {
536  Stop();
537  }
538  cellularTopology.GeneratorsManager.DetachFromGeneratorEvents();
539  messenger.GetEvent<SwitchToConstructionModeMessage>().Publish();
540  }
541 
545  private void Run()
546  {
547  RunOrStepForward(cellularTopology.Run);
548  }
549 
553  private void Step()
554  {
555  RunOrStepForward(cellularTopology.StepForward);
556  }
557 
562  private void RunOrStepForward(Action<int?> runOrStepForward)
563  {
564  int? seedToUse = null;
565  bool simulationIsInitialized = false;
566  if (cellularTopology.Simulation.SimulationState == SimulationState.NotRunning)
567  {
568  simulationIsInitialized = true;
569  if (settings.IsSeedSettingAutomatic)
570  seedToUse = null;
571  else if (settings.IsPreviousSeedUsed)
572  seedToUse = settings.PreviousSeed;
573  else
574  seedToUse = CustomSeed;
575  }
576  runOrStepForward(seedToUse);
577  if (simulationIsInitialized)
578  {
579  settings.PreviousSeed = cellularTopology.Simulation.UsedSeed;
580  IsPreviousSeedAvailable = true;
581  settings.Save();
582  }
583  RefreshAlarmAndSeedProperties();
584  }
585 
589  private void RefreshAlarmAndSeedProperties()
590  {
591  RefreshAlarmProperties();
592  OnPropertyChanged("Seed");
593  }
594 
598  private void Stop()
599  {
600  cellularTopology.Stop();
601  RefreshAlarmProperties();
602  }
603 
607  private void Pause()
608  {
609  cellularTopology.Pause();
610  }
611 
617  void Simulation_ModelTimeChanged(object sender, EventArgs e)
618  {
619  OnPropertyChanged("ModelTime");
620  }
621 
627  void cellularTopology_SimulationStepsChanged(object sender, EventArgs e)
628  {
629  OnPropertyChanged("SimulationSteps");
630  }
631 
636  private void RefreshAlarmProperties()
637  {
638  OnPropertyChanged("ModelTimeToPause");
639  OnPropertyChanged("SimulationStepsToPause");
640  }
641  }
642 }
EventHandler ModelTimeChanged
An event informing about changing of model time.
Definition: Simulation.cs:67
Simulation Simulation
Simulation object which controls the simulation on the cellular topology.
Class representing geometric topology of road network.
bool IsSeedSettingAutomatic
Determines whether the seed is initialized automatically.
Definition: ISettings.cs:26
void Run(int?seed=null)
Runs simulation. Seed to be used in the simulation.
Interface of application settings.
Definition: ISettings.cs:6
Class representing messenger for communicating between viewmodels.
Definition: Messenger.cs:9
bool IsPreviousSeedUsed
Determines whether the seed from previous simulation run is used.
Definition: ISettings.cs:31
bool PreviousSeedNull
Determines whether there is any previous seed (whether any simulation was running in past)...
Definition: ISettings.cs:21
Command class for binding UI commands with view models.
Definition: RelayCommand.cs:10
EventHandler SimulationStepsChanged
Event handler of change of number of simulation steps.
TimeSpan CurrentModelTime
Model time of last tick of simulation timer or last change of simulation run.
Definition: Simulation.cs:49
bool IsMaxSimulationSpeed
Indicates whether the simulation speed is maximal.
Definition: Simulation.cs:157
Interface for interactions with user.
Definition: IInteractions.cs:6
void DetachFromGeneratorEvents()
Detaches event handler ZeroToOneTicketsInGenerator from its publisher in generator.
SimulationState SimulationState
Current simulation status of simulation.
Definition: Simulation.cs:96
void StepForward(int?seed=null)
Perform step in simulation. Seed to be used in the simulation.
Message for sending geometric topology simulation control viewmodel to build cellular topology from i...
int UsedSeed
Seed which is used in the simulation.
Definition: Simulation.cs:105
Extended relay command class by adding event after executing command. Useful for performing additiona...
TimeSpan ModelTimeToPause
Simulation model time when the simulation will be paused.
Definition: Simulation.cs:59
double SimulationSpeed
Current simulation speed in model time speed divided by computer/user time speed
Definition: Simulation.cs:123
int PreviousSeed
Seed which was used in the last simulation.
Definition: ISettings.cs:16
void Save()
Saves application settings.
Class representing message without payload.
Definition: Message.cs:9
ulong SimulationStepsToPause
Number of simulation steps after which the simulation control pauses simulation.