延迟函数使 openFrameworks window 冻结,直到指定的时间过去
Delay function makes openFrameworks window freeze until specified time passes
我有顶点网络,我想每秒更改它们的颜色。我尝试使用 Sleep() 函数并且当前使用不同的延迟函数但两者都给出相同的结果 - 可以说我想用 1 秒的暂停将 10 个顶点着色为红色。当我开始项目时,window 似乎冻结了 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 响应。然后,第二个线程将管理更繁重的计算或更新数据。
如果你想运行一个时间间隔内的任务,你不只是循环直到时间结束,但本质上"tell the OS"第二个线程应该在一段时间内不活动。 OS 将比实施主动等待更有效地管理这种方式。
但这是一个很大的话题,所以我建议您继续阅读有关多线程的内容。自 C++11 以来,C++ 有一个 small thread library。可能值得一看。
// .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;
}
}
按照这个例子,我设法解决了我的问题。