PDA

View Full Version : Chrono



qtoptus
25th October 2011, 16:57
Any idea why QTimer clashes with boost::chrono clock? When using both in the same function they cause undesired behavior such as locking part of the GUI making it not responsive or dead.

qtoptus
28th October 2011, 05:37
I tried another timer, Intel TBB timer: tick_count::now() and the same is still there. Any idea about possible competing timer functions trying to access the same system resources/calls?

wysota
28th October 2011, 08:27
Hard to say without knowing how you use these classes.

qtoptus
28th October 2011, 21:22
// Inside the main window class constructor
...

timer.setInterval(0);

connect(...)

t0 = tbb::tick_count::now();

...

MyMainWindow::OnIdle()
{
t1 = tbb::tick_count::now();
if ((t1 - t0).seconds() < ...) {
// do nothing
} else {
// do something...
}
pApp->processEvents();
}

wysota
28th October 2011, 21:31
Is there any reason why you are using tbb::tick_count::now() instead of QDateTime, QTime or QElapsedTimer? Furthermore processing events from within the call to OnIdle() (which I assume is the result of the timer's timeout) doesn't make any sense since the events has just been processed. You might be falling into an endless loop here.

qtoptus
28th October 2011, 22:05
Is there any reason why you are using tbb::tick_count::now() instead of QDateTime, QTime or QElapsedTimer?

Good question since both are valid platform-portable solutions. The answer is framework portability. I'm intending to implement the entire game engine/logic as a decoupled module from the GUI/Qt framework so that I can just plug it into other frameworks more easily, such as SDL, Glut, or any other kits. I could just say: gameInstance->DoFrame(); from within OnIdle() function, which I assume in this case, works exactly like a idle event block in conventional win32 api non-blocking GetMessage even loop.

Now my question, is there any strong argument why I should not use any other 3rd party libraries in Qt?


Furthermore processing events from within the call to OnIdle() (which I assume is the result of the timer's timeout) doesn't make any sense since the events has just been processed.

pApp->processEvents() was suggested by someone for solving the same issue, but it was a different thread.

wysota
29th October 2011, 08:58
Good question since both are valid platform-portable solutions. The answer is framework portability. I'm intending to implement the entire game engine/logic as a decoupled module from the GUI/Qt framework so that I can just plug it into other frameworks more easily, such as SDL, Glut, or any other kits. I could just say: gameInstance->DoFrame(); from within OnIdle() function, which I assume in this case, works exactly like a idle event block in conventional win32 api non-blocking GetMessage even loop.
I don't think a game loop speed should depend on the number of idle calls of the machine. You should setup a proper timer with a predefined interval to get a constant iterations per second of the game loop. As for the timer itself, you can abstract it as well and have it implemented by the GUI framework.


Now my question, is there any strong argument why I should not use any other 3rd party libraries in Qt?
Right now I am trying to find the problem, not suggesting any permanent solutions. Try removing the boost call and see if it changes anything. There shouldn't be any clashes so first let's make sure this really is the problem.



pApp->processEvents() was suggested by someone for solving the same issue, but it was a different thread.
And obviously it didn't work :)

How about you tell us what is the ultimate goal you are trying to achieve here and we suggest an approach for it?

qtoptus
29th October 2011, 20:03
What I'm trying to achieve is simply a game loop. I could use a QTimer set to the desired frame rate. But I chosed to try existing approach I already use with Win32 API. I will post my code here so it can be tested:


tbb::tick_count t0, t1;

MyGame2::MyGame2(QWidget *parent, Qt::WFlags flags)
: QMainWindow(parent, flags)
{
ui.setupUi(this);

ui.textEditMainConsole->appendPlainText("Hello!");
//ui.textEditMainConsole->setDisabled(true);
//ui.textEditMainConsole->clear();

//hiResTimerStart = boost::chrono::steady_clock::now();
t0 = tbb::tick_count::now();

timer.setInterval(0);
timer.start();

connect(&timer, SIGNAL(timeout()), this, SLOT(OnIdle()));
}

MyGame2::~MyGame2()
{
timer.stop();
}

extern QApplication *pApp;

void MyGame2::OnIdle()
{
tbb::tick_count t1 = tbb::tick_count::now();
float dt = (t1 - t0).seconds();
//boost::chrono::steady_clock::time_point hiResTimerEnd = boost::chrono::steady_clock::now();
//boost::chrono::microseconds msecs = boost::chrono::duration_cast<boost::chrono::microseconds>(hiResTimerEnd - hiResTimerStart);

//unsigned long p = 1000000/60;
//unsigned long p = 1000000/85;
//if (msecs.count() < p) {
if (dt < 1.0f/60) {

} else {
//============

std::stringstream ss;
//ss << "~~~ dCount: " << msecs.count();
ss << "~~~ dCount: " << dt;
std::string s = ss.str();

//ui.textEditMainConsole->clear();
//ui.textEditMainConsole->appendPlainText(s.c_str());
ui.textEditMainConsole->setPlainText(s.c_str());
//============

//hiResTimerStart = hiResTimerEnd;
t0 = t1;
}

pApp->processEvents();
}

qtoptus
28th November 2011, 18:21
Anybody tried this code and experienced the same problem? Any idea what the problem is?

Thanks.

d_stranz
28th November 2011, 21:22
I have no idea what setting a timer interval to 0 will do, but since the docs say that it will cause the timer to fire immediately, this implies that the timer is choking the event loop with continuous timeout events. I think your assumption that a timeout slot for a timer with 0 interval is like a Windows idle loop might be a flawed assumption. Your OnIdle() slot isn't idling at all - it is constantly responding to timeout events.

qtoptus
28th November 2011, 21:26
Well that's what they told me on this forum, that a substitution of Windows' on-idle would be a timer with interval set to 0.

Anyway reading posts about timer, and after trying several approaches, I have suspicions that the QTimer has some issues in the current version. Hope they find it and fix it.

qtoptus
29th November 2011, 23:28
Ok let me reword what I want to do. Simply a game loop using a 3rd party high frequency counter, such as Chrono or TBB's.

QTimer is the only way I can do background work (as an idle event) but it does not really seem to like other counters...???

qtoptus
22nd December 2011, 19:15
Tried 4.8, did not solve the problem.

Any thoughts on making a continuous rendering loop without using QTimer?