| 1051 | } |
| 1052 | |
| 1053 | void VisualizerImpl::update() { |
| 1054 | update_work_processed_ = false; |
| 1055 | window_manager_->updateWindowSize(); |
| 1056 | |
| 1057 | // Process MCP work queue |
| 1058 | { |
| 1059 | std::vector<WorkItem> work; |
| 1060 | { |
| 1061 | std::lock_guard lock(work_queue_mutex_); |
| 1062 | work.swap(work_queue_); |
| 1063 | } |
| 1064 | update_work_processed_ = !work.empty(); |
| 1065 | for (size_t i = 0; i < work.size(); ++i) { |
| 1066 | try { |
| 1067 | if (work[i].run) |
| 1068 | work[i].run(); |
| 1069 | } catch (...) { |
| 1070 | for (size_t j = i + 1; j < work.size(); ++j) { |
| 1071 | if (work[j].cancel) |
| 1072 | work[j].cancel(); |
| 1073 | } |
| 1074 | throw; |
| 1075 | } |
| 1076 | } |
| 1077 | } |
| 1078 | |
| 1079 | if (gui_manager_) { |
| 1080 | const auto& size = gui_manager_->getViewportSize(); |
| 1081 | viewport_.windowSize = {static_cast<int>(size.x), static_cast<int>(size.y)}; |
| 1082 | } else { |
| 1083 | viewport_.windowSize = window_manager_->getWindowSize(); |
| 1084 | } |
| 1085 | viewport_.frameBufferSize = window_manager_->getFramebufferSize(); |
| 1086 | |
| 1087 | // Update editor context state from scene/trainer |
| 1088 | editor_context_.update(scene_manager_.get(), trainer_manager_.get()); |
| 1089 | |
| 1090 | if (selection_tool_ && selection_tool_->isEnabled() && tool_context_) { |
| 1091 | selection_tool_->update(*tool_context_); |
| 1092 | } |
| 1093 | |
| 1094 | if (pending_new_project_ && trainer_manager_ && |
| 1095 | trainer_manager_->canPerform(TrainingAction::ClearScene)) { |
| 1096 | pending_new_project_ = false; |
| 1097 | trainer_manager_->waitForCompletion(); |
| 1098 | performNewProject(); |
| 1099 | } |
| 1100 | |
| 1101 | if (pending_reset_ && trainer_manager_ && !trainer_manager_->isTrainingActive()) { |
| 1102 | pending_reset_ = false; |
| 1103 | trainer_manager_->waitForCompletion(); |
| 1104 | performReset(); |
| 1105 | } |
| 1106 | |
| 1107 | if (!gui_frame_rendered_) { |
| 1108 | // Wait for at least one GUI frame to render before loading data |
| 1109 | } else if (!pending_view_paths_.empty()) { |
| 1110 | auto paths = std::exchange(pending_view_paths_, {}); |
no test coverage detected