延迟函数使打开的框架窗口冻结,直到指定的时间过去



我有顶点网络,我想每秒更改它们的颜色。我尝试使用 Sleep(( 函数,目前使用不同的延迟函数,但两者都给出了相同的结果 - 假设我想将 10 个顶点涂成红色并暂停 1 秒。当我启动项目时,窗口似乎冻结了 10 秒,然后以红色显示每个顶点。

这是我的更新功能。

void ofApp::update(){
for (int i = 0; i < vertices.size(); i++) {
ofColor red(255, 0, 0);
vertices[i].setColor(red);
delay(1);
}
}

这是绘制函数

void ofApp::draw(){
for (int i = 0; i < vertices.size(); i++) {
for (int j = 0; j < G[i].size(); j++) {
ofDrawLine(vertices[i].getX(), vertices[i].getY(), vertices[G[i][j]].getX(), vertices[G[i][j]].getY());
}
vertices[i].drawBFS();
}
}
void vertice::drawBFS() {
ofNoFill();
ofSetColor(_color);
ofDrawCircle(_x, _y, 20);
ofDrawBitmapString(_id, _x - 3, _y + 3);
ofColor black(0, 0, 0);
ofSetColor(black);
}

这是我的 delay(( 函数

void ofApp::delay(int number_of_seconds) {
// Converting time into milli_seconds 
int milli_seconds = 1000 * number_of_seconds;
// Stroing start time 
clock_t start_time = clock();
// looping till required time is not acheived 
while (clock() < start_time + milli_seconds)
;
}

你的代码中没有错误,只是对等待的误解。所以这不是明确的答案,只是对正确方向的暗示。

您可能只有一个线程。一个线程一次只能做一件事。当您调用delay时,一个线程所做的只是一遍又一遍地检查时间,直到一段时间过去。

在此期间,线程不能执行任何其他操作(它不能神奇地跳过指令或检测到您的意图(。因此,它不能发出绘图命令或交换某些缓冲区以在屏幕上显示矢量。这就是您的应用程序似乎冻结的原因 - 99.9% 的时间它会检查间隔是否已过。这也给 CPU 带来了沉重的负载。

解决方案可能有点棘手,需要线程。通常你有一个UI-Thread,它定期绘制内容,刷新显示,可能接受输入等等。此线程不应执行繁重的计算以保持 UI 响应。然后,第二个线程将管理较繁重的计算或更新数据。

如果你想在一个时间间隔内运行一个任务,你不只是循环直到时间结束,而是基本上"告诉操作系统"第二个线程应该在一段时间内处于非活动状态。操作系统将以比实现主动等待更有效的方式进行管理。

但这是一个相当大的话题,所以我建议你继续阅读多线程。自 C++11 以来,C++有一个小型线程库。可能值得一看。

// .h
float nextEventSeconds = 0;
// .cpp
void ofApp::draw(){
float now = ofGetElapsedTimef();
if(now > nextEventSeconds) {
// do something here that should only happen
// every 3 seconds
nextEventSeconds = now + 3;
}
}

按照这个例子,我设法解决了我的问题。

最新更新