TrueReality  v0.1.1912
SystemDirector.cpp
Go to the documentation of this file.
1 /*
2 * True Reality Open Source Game and Simulation Engine
3 * Copyright © 2021 Acid Rain Studios LLC
4 *
5 * This library is free software; you can redistribute it and/or modify it under
6 * the terms of the GNU Lesser General Public License as published by the Free
7 * Software Foundation; either version 3.0 of the License, or (at your option)
8 * any later version.
9 *
10 * This library is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
13 * details.
14 *
15 * You should have received a copy of the GNU Lesser General Public License
16 * along with this library; if not, write to the Free Software Foundation, Inc.,
17 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 *
19 * @author Maxim Serebrennik
20 */
21 
22 #include <trCore/SystemDirector.h>
23 
30 #include <trCore/MessageFrame.h>
32 #include <trCore/SystemControls.h>
33 #include <trCore/SystemEvents.h>
35 #include <trManager/MessageTick.h>
36 #include <trBase/SmrtPtr.h>
37 #include <trUtil/Logging/Log.h>
38 
39 namespace trCore
40 {
41  const trUtil::RefStr SystemDirector::CLASS_TYPE = trUtil::RefStr("trCore::SystemDirector");
42 
43  const double SystemDirector::MAX_TIME_SCALE = 1048576;
44  const double SystemDirector::MIN_TIME_SCALE = 0.03125;
45 
47  SystemDirector::SystemDirector(const std::string name) : BaseClass(name)
48  {
49  }
50 
53  {
54  }
55 
57  const std::string& SystemDirector::GetType() const
58  {
59  return CLASS_TYPE;
60  }
61 
64  {
66  {
67  const trCore::MessageSystemControl& message = static_cast<const trCore::MessageSystemControl&>(msg);
68 
70  {
71  mIsPaused = true;
72  }
74  {
75  mIsPaused = false;
76  }
78  {
80  }
82  {
84  }
86  {
87  SetTimeScale(message.GetSystemValue());
88  }
90  {
91  ShutDown();
92  }
93  }
94  }
95 
98  {
99  //Call the initial Tick to start the timer
101 
102  //Enable the run loop
103  mIsRunning = true;
104 
105  while (mIsRunning)
106  {
107  if (IsRegistered())
108  {
109  LOG_D("\n***************** Starting Frame #" << mTimeStruct.frameNumber)
110 
118 
119  LOG_D("\n***************** Ending Frame #" << mTimeStruct.frameNumber)
120 
121  //Get the time between frames in seconds
122  mSystemTimer.Tick();
123 
124  //Update System Timing
126  }
127  }
128  }
129 
132  {
133  //Call the initial Tick to start the timer
134  if (!mIsRunning)
135  {
137  }
138 
139  //Enable the run loop
140  mIsRunning = true;
141 
142  if (mIsRunning)
143  {
144  if (IsRegistered())
145  {
146  LOG_D("\n***************** Starting Frame #" << mTimeStruct.frameNumber)
147 
155 
156  LOG_D("\n***************** Ending Frame #" << mTimeStruct.frameNumber)
157 
158  //Get the time between frames in seconds
159  mSystemTimer.Tick();
160 
161  //Update System Timing
163  }
164  }
165  }
166 
169  {
170  return mIsRunning;
171  }
172 
175  {
176  LOG_D("Shutting down System")
177 
179  SendMessage(*msg);
180  mIsRunning = false;
181  mIsShuttingDown = true;
182  }
183 
186  {
187  return mTimeStruct;
188  }
189 
192  {
193  //If the sim is paused, we should make dt = 0
194  if (!mIsPaused)
195  {
196  timeStruct.deltaSimTime = dt * timeStruct.timeScale;
197  }
198  else
199  {
200  timeStruct.deltaSimTime = 0.;
201  }
202 
203  timeStruct.deltaRealTime = dt;
204  timeStruct.realTime += dt;
205  timeStruct.simTime += timeStruct.deltaSimTime;
206  timeStruct.frameNumber++;
207  }
208 
211  {
212  LOG_D("Event Traversal")
213  //Create and send out an Event Traversal System Event Message
215  SendMessage(*msg);
216  //Create and send out an Event Traversal Message
218  SendMessage(*et);
219  //Make the System Manager send out all its queued messages
220  mSysMan->ProcessMessages();
221 
222  //Make the System Manager send out all its queued messages after the Event Traversal and System Event messages got processed.
223  mSysMan->ProcessMessages();
224  }
225 
228  {
229  LOG_D("Post Event Traversal")
230  //Create and send out an Post Event Traversal System Event Message
232  mSysMan->ProcessMessage(*msg);
233  //Create and queue the Post Event Traversal Message
235  SendMessage(*pet);
236  //Make the System Manager send out all its queued messages
237  mSysMan->ProcessMessages();
238 
239  //Make the System Manager send out all its queued messages after the Post Event Traversal and System Event messages got processed.
240  mSysMan->ProcessMessages();
241  }
242 
245  {
246  LOG_D("Pre Frame")
247  //Create and queue out an Pre Frame System Event Message
249  SendMessage(*msg);
250  //Create and queue the Tick Message
252  SendMessage(*tick);
253  //Send out the two Queues messaged
254  mSysMan->ProcessMessages();
255 
256  //Make the System Manager send out all its queued messages after the PreFrame and Tick messages got processed.
257  mSysMan->ProcessMessages();
258  }
259 
262  {
263  LOG_D("Camera Synch")
264  //Create and send out an Camera Synch System Event Message
266  mSysMan->ProcessMessage(*msg);
267  //Create and queue the Camera Sync Message
269  SendMessage(*cs);
270  //Send out the two Queues messaged
271  mSysMan->ProcessMessages();
272 
273  //Make the System Manager send out all its queued messages after the Camera Synch and System Event messages got processed.
274  mSysMan->ProcessMessages();
275  }
276 
279  {
280  LOG_D("Frame Synch")
281  //Create and send out an Frame Synch System Event Message
283  mSysMan->ProcessMessage(*msg);
284  //Create and queue the Frame Sync Message
286  SendMessage(*fs);
287  //Send out the two Queues messaged
288  mSysMan->ProcessMessages();
289 
290  //Make the System Manager send out all its queued messages after the Frame Synch and System Event messages got processed.
291  mSysMan->ProcessMessages();
292  }
293 
296  {
297  LOG_D("Frame")
298  //Create and send out a Frame System Event Message
300  SendMessage(*msg);
301  //Create and queue the Frame Message
302  trBase::SmrtPtr<trCore::MessageFrame> frame = new trCore::MessageFrame(&this->GetUUID(), timeStruct);
303  SendMessage(*frame);
304  //Send out the two Queues messaged
305  mSysMan->ProcessMessages();
306 
307  //Make the System Manager send out all its queued messages after the Frame and System Event messages got processed.
308  mSysMan->ProcessMessages();
309  }
310 
313  {
314  LOG_D("Post Frame")
315  //Create and send out an Post Frame System Event Message
317  SendMessage(*msg);
318  //Create and queue the Frame Message
320  SendMessage(*pf);
321  //Send out the two Queues messaged
322  mSysMan->ProcessMessages();
323 
324  //Make the System Manager send out all its queued messages after the Post Frame and System Event messages got processed.
325  mSysMan->ProcessMessages();
326 
327  //Removes all entities that were unregistered during this frame.
328  mSysMan->RemoveMarkedEntities();
329 
330  //Check if we entered the shutdown phase.
332  }
333 
335  void SystemDirector::SetTimeScale(const double timeScale)
336  {
337  if (timeScale > MAX_TIME_SCALE)
338  {
340  }
341  else if (timeScale < -MAX_TIME_SCALE)
342  {
344  }
345  else if (-MIN_TIME_SCALE < timeScale && timeScale < MIN_TIME_SCALE)
346  {
347  mTimeStruct.timeScale = 0.;
348  }
349  else
350  {
351  mTimeStruct.timeScale = timeScale;
352  }
354  SendMessage(*msg);
355 
356  LOG_D("Time Scale Changed to: " << mTimeStruct.timeScale)
357  }
358 
361  {
362  double timeScale = mTimeStruct.timeScale;
363  if (timeScale > 0)
364  {
365  SetTimeScale(timeScale * 2.);
366  }
367  else
368  {
369  timeScale /= 2.;
370  if (timeScale > -MIN_TIME_SCALE)
371  {
373  }
374  else
375  {
376  SetTimeScale(timeScale);
377  }
378  }
379 
380  LOG_D("Time Scale Incremented to: " << mTimeStruct.timeScale)
381  }
382 
385  {
386  double timeScale = mTimeStruct.timeScale;
387  if (timeScale > 0)
388  {
389  timeScale /= 2.;
390  if (timeScale < MIN_TIME_SCALE)
391  {
393  }
394  else
395  {
396  SetTimeScale(timeScale);
397  }
398  }
399  else
400  {
401  SetTimeScale(timeScale * 2.);
402  }
403 
404  LOG_D("Time Scale Decremented to: " << mTimeStruct.timeScale)
405  }
406 
409  {
410  if (mIsShuttingDown)
411  {
412  mSysMan->ShutDown();
413  }
414  }
415 
416 }
virtual void DecrementTimeScale()
Decrement the system time scale.
A timing structure for all sim loop variables.
static const SystemControls PAUSE
Pauses the system.
virtual void CheckForShutdown()
Checks for a shutdown, and cleares the System Manager if in process.
virtual void Frame(const trManager::TimingStructure &timeStruct)
Frame event function.
A message that is sent out on Frame Synchronization.
A message that is sent out on Camera Synchronization.
virtual const std::string & GetMessageType() const =0
Returns the Message type.
static const double MIN_TIME_SCALE
Hold the maximum time scale the system can use for positive and negaive time.
Smart pointer for handling referenced counted objects.
Definition: SmrtPtr.h:36
virtual void ShutDown()
Shuts down this object and frees any resources it is using.
virtual void SetTimeScale(const double timeScale)
Sets the system time scale.
TimeTicks Tick()
Get the timers tick value.
Definition: Timer.h:100
A message that is sent out on Frame Event.
A string wrapper that will make sure that all of the strings with the same value will point to the sa...
Definition: RefStr.h:50
A message that is sent out on Frame Event.
Definition: MessageFrame.h:40
virtual void IncrementTimeScale()
Increment the system time scale.
trManager::TimingStructure GetTimeStructure()
Gets a copy of the internal time structure.
virtual bool IsRunning()
Query if this object is running.
static const SystemControls UNPAUSE
Unpauses the system.
A message that is sent out on post event traversal.
static const SystemControls SPEED_UP
Speeds up the system.
This class is part of the internal garbage collection system.
Definition: SmrtClass.h:38
static const SystemEvents SHUTTING_DOWN
Gets sent out when the system is shutting down.
Definition: SystemEvents.h:71
static const SystemEvents POST_EVENT_TRAVERSAL
The post event traversal event.
Definition: SystemEvents.h:44
virtual double GetSystemValue() const
Gets system value.
This message carries all the inter-frame timing information.
Definition: MessageTick.h:40
trBase::ObsrvrPtr< trManager::SystemManager > mSysMan
Definition: EntityBase.h:351
virtual void PostEventTraversal(const trManager::TimingStructure &timeStruct)
Post event traversal event function.
virtual void OnMessage(const trManager::MessageBase &msg)
This function receives messages coming from the System Manager.
virtual void FrameSynch(const trManager::TimingStructure &timeStruct)
Frame synchronization event function.
static const SystemControls SPEED_DOWN
Slows down the system.
virtual void PreFrame(const trManager::TimingStructure &timeStruct)
Pre frame event function.
static const double MAX_TIME_SCALE
Holds the class type name for efficient comparisons.
virtual const std::string & GetType() const override
Gets the class type.
static const SystemEvents EVENT_TRAVERSAL
The event traversal event.
Definition: SystemEvents.h:41
virtual const trBase::UniqueId & GetUUID(void)
Returns the instances Universally Unique ID.
Definition: Base.cpp:67
double GetSecondsPerTick() const
Get the number of seconds per tick.
Definition: Timer.h:232
SystemDirector(const std::string name=CLASS_TYPE)
Hold the minimum time scale the system can use for positive and negaive time.
virtual const bool & IsRegistered()
Returns True if the Instance is registered with a System Manager.
Definition: EntityBase.h:107
~SystemDirector()
Destructor.
void SetStartTick()
Set the start tick.
Definition: Timer.h:112
static const SystemEvents TIME_SCALE_CHANGED
Indicates a change in the time scale.
Definition: SystemEvents.h:68
static const SystemEvents PRE_FRAME
The pre frame event.
Definition: SystemEvents.h:47
static const SystemEvents FRAME_SYNCH
The frame synchronization event.
Definition: SystemEvents.h:53
static const SystemControls SET_TIME_SCALE
The set speed of the system.
virtual void EventTraversal(const trManager::TimingStructure &timeStruct)
Event traversal event function.
virtual void UpdateTiming(trManager::TimingStructure &timeStruct, double dt)
Updates the system timing incrementing it by dt.
virtual void PostFrame(const trManager::TimingStructure &timeStruct)
Post frame event function.
trManager::TimingStructure mTimeStruct
virtual void Run()
Runs the systems game loop.
virtual const trCore::SystemControls & GetSysControlType() const
Gets system control type.
static const SystemControls SHUT_DOWN
Shuts down the system loop and exits the program.
A message that is sent out on event traversal.
static const trUtil::RefStr MESSAGE_TYPE
Adds an easy and swappable access to the base class.
virtual void CameraSynch(const trManager::TimingStructure &timeStruct)
Camera synchronization event function.
static const SystemEvents CAMERA_SYNCH
The camera synchronization event.
Definition: SystemEvents.h:50
static const trUtil::RefStr CLASS_TYPE
Adds an easy and swappable access to the base class.
trUtil::Timer mSystemTimer
static const SystemEvents FRAME
The frame event.
Definition: SystemEvents.h:56
A message that lets the system know what state to enable and setup.
This is the base class for all the messages in TR.
Definition: MessageBase.h:40
virtual bool SendMessage(const trManager::MessageBase &message)
Send a message to an Actor, Actor Module, or a Director.
Definition: ActorBase.cpp:136
#define LOG_D(msg)
Log a DEBUG message.
Definition: Log.h:138
static const SystemEvents POST_FRAME
The post frame event.
Definition: SystemEvents.h:59
virtual void RunOnce()
Advanced the game loop by one frame.