我有一个OpenGL应用程序,它有两个主要部分(查看器),主循环如下:
int main(int argc, char* argv[])
{
gp::viewers::PatternViewer pViewer;
gp::viewers::MeshViewer mViewer;
while (!pViewer.shouldClose() && !mViewer.shouldClose())
{
pViewer.makeCurrent();
pViewer.mainLoop();
pViewer.swap();
mViewer.makeCurrent();
mViewer.mainLoop();
mViewer.swap();
glfwWaitEvents();
}
glfwTerminate();
return 0;
}
用户与一个观看者的交互应该将更改传播到另一个观看者。我的直觉本能说如下更新循环:
int main(int argc, char* argv[])
{
gp::viewers::PatternViewer pViewer;
gp::viewers::MeshViewer mViewer;
while (!pViewer.shouldClose() && !mViewer.shouldClose())
{
pViewer.makeCurrent();
pViewer.mainLoop();
pViewer.swap();
mViewer.makeCurrent();
mViewer.mainLoop();
mViewer.swap();
// UPDATE HERE
mViewer.update(pViewer);
pViewer.update(mViewer);
glfwWaitEvents();
}
glfwTerminate();
return 0;
}
但在这种情况下,PatternViewer需要了解MeshViewer,而MeshViewer需要了解PatternViewer - 循环依赖。此外,还不清楚mViewer.update(pViewer)是否应该使用mViewer提供的任何更新来更新pViewer,反之亦然。在我看来它应该是前者 - mViewer应该知道要传播的更新,而不是pViewer。
应该提到的是,PatternViewer和MeshViewer都是从抽象超类Viewer继承的。
有没有办法解决这个循环依赖?处理这种情况是否有可接受的方式/设计模式?
答案 0 :(得分:2)
是否在Viewer
中可见的观众之间共享信息,即在基类中?如果是这样,那么摘要Viewer
需要知道如何从另一个摘要Viewer
更新,但不需要每个具体Viewer
,例如PatternViewer
或{ {1}}了解另一个具体的MeshViewer
- 换句话说,不需要循环依赖。
答案 1 :(得分:2)
此案例的标准模式是MVC(模型,视图,控制器)。
有了这种模式,观众根本不知道对方。视图之间共享的数据位于模型中。当观看者需要更新某些内容时,它会更新模型(但如果您真的关注MVC,则视图应该只显示输出,输入应来自控制器)。
与原始数据一起,模型会保留数据的所有当前视图的列表。当模型更新时,它会将更改传播到所有视图。
请注意,MVC有很多变化。一些消除了“控制器”部分,支持更接近你正在做的事情:使用视图同时执行输入和输出(但仍然将公共数据移动到模型中)。