Main Page | Class Hierarchy | Alphabetical List | Class List | File List | Class Members | File Members

SimulatorThread.cpp

Go to the documentation of this file.
00001 #include "SimulatorThread.h"
00002 #include "ThyrixApplication.h"
00003 #include "ThyrixMainFrame.h"
00004 #include "World.h"
00005 
00006 SimulatorThread::SimulatorThread(ThyrixMainFrame *iniFrame) :
00007    wxThread(wxTHREAD_JOINABLE),
00008    frame(iniFrame),
00009    timeFactor(1000),
00010    paused(false),
00011    expectedTime(0){        
00012    setTimeFactor(1);
00013    setFramesPerSecond(30);
00014 }
00015 
00016 SimulatorThread::~SimulatorThread(){
00017 }
00018 
00019 void SimulatorThread::step() {
00020       //this is called directly by the parent frame, following a command
00021     //needs mutex sincronization with the thread.
00022     world->advanceTime();
00023 }
00024 
00025 void SimulatorThread::setPause() {
00026     paused = true;
00027 }
00028 
00029 void SimulatorThread::setTimeFactor(float newFactor) {
00030     timeFactor = newFactor;
00031     paused = false;
00032     expectedTime = 0;
00033     simulationTimer.Start();
00034 }
00035 
00036 void SimulatorThread::setFramesPerSecond(int fps) {
00037     frameInterval = 1000 / fps;
00038 }
00039 
00040 void SimulatorThread::sleepIfAhead() {
00041    
00042     //sleep when more than 5ms ahead
00043     static const int kSleepThreshold = 5;
00044 
00045     unsigned expectedTimeMs = (unsigned)(expectedTime * 1000);
00046     unsigned realMs = (unsigned)simulationTimer.Time();
00047     int aheadMs = 0;
00048     if ( expectedTimeMs > realMs) {
00049         aheadMs = expectedTimeMs - realMs;
00050     }
00051     if (aheadMs > kSleepThreshold) {
00052         Sleep(aheadMs);
00053     }
00054     //to avoid timer overflow, reset it once in a while
00055     if (realMs > 100000) {
00056         setTimeFactor(timeFactor);
00057     }
00058 }
00059 
00060 void* SimulatorThread::Entry(){
00061    wxStopWatch displayTimer;
00062    simulationTimer.Start(); //starts the timing of the running time of the simulator
00063    while(!TestDestroy()){
00064       displayTimer.Start(); //starts the timing of the duration of a frame   
00065       frame->paint(); //draws the image
00066       if (paused) {
00067          Sleep(frameInterval);
00068       } else {
00069 
00070          //advance simulator time, in a loop, as long a refresh of the display is not needed
00071          do {
00072             
00073             //wait if the simulation should not advance yet
00074             sleepIfAhead();
00075 
00076             //advance simulator time
00077             world->advanceTime();
00078             
00079             //computes the real time at which the next simulator timestep should be executed,
00080             //given the desired acceleration factor between real time and simulator time
00081             expectedTime += world->getDt() / timeFactor;
00082 
00083          } while (displayTimer.Time() < frameInterval);
00084 
00085       }
00086    }
00087    return NULL;
00088 }
00089 
00090 void SimulatorThread::OnExit(){
00091 }

Thyrix homepageUsers' guide

(C) Arxia 2004-2005