2015-07-22 4 views
4

У меня есть приложение 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) обновлять pViewer любыми обновлениями, доступными из mViewer, или наоборот. Мне кажется, что он должен быть первым - mViewer должен знать, какие обновления распространяются, а не pViewer.

Следует отметить, что PatternViewer и MeshViewer наследуются от абстрактного суперкласса Viewer.

Есть ли способ решить эту круговую зависимость? Есть ли принятый шаблон пути/дизайна для обработки этого случая?

+0

Не могли бы вы создать вспомогательный класс, который выполняет как обновления, так и когда вам нужно будет обновить, вы вызываете его объект. В конструкторе он будет иметь указатель на два других объекта и делать обновления в соответствии с последовательностью. – v010dya

+0

Вы можете попробовать подход, основанный на событиях: Поместить взаимодействие пользователя в событие и отправить его всем зрителям, и каждый просмотрщик фильтрует интересующие события. –

ответ

2

Разве информация не должна делиться между зрителями, видимыми в Viewer, то есть в базовом классе? Если да, то абстрактное Viewer должно знать, как обновить из другого абстрактного Viewer, но нет необходимости в каждом конкретном Viewer, таком как PatternViewer или MeshViewer, чтобы узнать о другом конкретном Viewer - другими словами, нет необходимости в круговой зависимости.

2

Стандартный шаблон для этого случая - MVC (модель, вид, контроллер).

С помощью этого шаблона ни один зритель не знает о другом вообще. Данные, которые разделяются между представлениями, находятся в Модели. Когда зрителю необходимо что-то обновить, он обновляет модель (хотя, если вы действительно следуете за MVC, представления должны просто отображать вывод, а вход должен поступать от контроллеров).

Наряду с исходными данными модель хранит список всех текущих видов данных. Когда модель обновляется, она распространяет изменения (изменения) на все виды.

Обратите внимание, что существует много вариаций на MVC. Несколько исключают часть «контроллера» в пользу чего-то более близкого к тому, что вы делаете: с представлениями, делающими как входные, так и выходные данные (но все же перемещение общих данных в модель).

Смежные вопросы