MetaCore/MetaEditor/EditorApplication.cpp

153 lines
6.6 KiB
C++

#include "MetaEditor/EditorApplication.h"
#include "MetaEditor/DearImGuiEditorShell.h"
#include "MetaCore/foundation/Log.h"
#include <algorithm>
namespace metacore::editor {
EditorApplication::EditorApplication() = default;
bool EditorApplication::initialize(const std::filesystem::path& project_root) {
project_root_ = project_root;
editor_shell_ = create_default_editor_shell();
const auto shell_debug_path = project_root_ / "Library" / "Layout" / (editor_shell_->shell_name() + std::string("_snapshot.txt"));
editor_shell_->set_debug_export_path(shell_debug_path);
if (!platform_.initialize("MetaEditor")) {
return false;
}
render_backend_.initialize();
editor_shell_->initialize();
if (!std::filesystem::exists(project_root_ / "MetaCore.project.json")) {
project_service_.create_project(project_root_, "MetaCoreSample");
}
project_service_.load_project(project_root_ / "MetaCore.project.json", project_);
scene_ = scene_service_.create_default_scene();
scene_serializer_.load_scene(project_root_ / "Scenes" / "Main.mcscene.json", scene_);
asset_database_.load(project_root_ / "Library" / "AssetDB.json");
layout_service_.load(project_root_ / "Library" / "Layout" / "editor_layout.json", layout_state_);
session_.apply_layout_state(layout_state_);
if (!scene_.objects.empty()) {
selection_service_.select(scene_.objects.front().id);
}
session_.set_status_text("Editor initialized");
session_.add_console_message("System", "MetaEditor initialized");
gizmo_service_.set_operation(metacore::engine::editor_core::TransformGizmoService::Operation::Translate);
gizmo_service_.set_space(metacore::engine::editor_core::TransformGizmoService::Space::Local);
gizmo_service_.set_snap_enabled(false);
foundation::log(foundation::LogLevel::Info, "MetaEditor initialized");
foundation::log(foundation::LogLevel::Info, "Editor shell export path: " + shell_debug_path.generic_string());
foundation::log(foundation::LogLevel::Info, "Platform backend: " + platform_.backend_name().generic_string());
if (!platform_.panda_version().empty()) {
foundation::log(
foundation::LogLevel::Info,
"Panda3D runtime: " + platform_.panda_version() + " | platform=" + platform_.panda_platform() + " | build=" + platform_.panda_build_date()
);
}
foundation::log(
foundation::LogLevel::Info,
"Panda window bootstrap: enabled=" + std::string(platform_.window_enabled() ? "true" : "false") +
" opened=" + std::string(platform_.window_opened() ? "true" : "false")
);
return true;
}
int EditorApplication::run() {
foundation::log(foundation::LogLevel::Info, "MetaEditor skeleton run loop started");
const bool has_runtime_ui_object = std::any_of(
scene_.objects.begin(),
scene_.objects.end(),
[](const metacore::engine::scene::SceneObject& object) {
return object.has_ui_document;
}
);
if (!has_runtime_ui_object) {
metacore::engine::editor_core::SceneCommands::create_empty_object(
command_service_,
session_,
selection_service_,
scene_service_,
scene_,
"UI Root"
);
if (selection_service_.selection().has_value()) {
if (const auto object = scene_service_.find_object(scene_, *selection_service_.selection())) {
object->get().has_ui_document = true;
object->get().ui_document.document_path = "Assets/UI/main_menu.rml";
object->get().ui_document.stylesheet_path = "Assets/UI/main_menu.rcss";
}
}
}
metacore::engine::editor_core::SceneCommands::focus_selected_object(
session_,
selection_service_,
viewport_service_
);
if (const auto selected = inspector_service_.current_selection(scene_, selection_service_)) {
foundation::log(foundation::LogLevel::Info, "Current selection: " + selected->get().name);
}
auto snapshot = presenter_.build_snapshot(scene_, asset_database_, selection_service_, gizmo_service_, viewport_service_, session_);
editor_shell_->consume_snapshot(snapshot);
const PendingShellEdits shell_edits = editor_shell_->consume_pending_edits();
if (shell_edits.transform_edit.has_value() &&
shell_edits.transform_edit->entity_id == snapshot.viewport.selected_object_id) {
const auto requested_transform = metacore::engine::scene::TransformComponent{
shell_edits.transform_edit->position,
shell_edits.transform_edit->rotation,
shell_edits.transform_edit->scale
};
metacore::engine::editor_core::SceneCommands::apply_transform_to_selected_object(
command_service_,
session_,
selection_service_,
scene_service_,
scene_,
requested_transform
);
snapshot = presenter_.build_snapshot(scene_, asset_database_, selection_service_, gizmo_service_, viewport_service_, session_);
editor_shell_->consume_snapshot(snapshot);
}
layout_service_.save(project_root_ / "Library" / "Layout" / "editor_layout.json", session_.to_layout_state());
scene_serializer_.save_scene(project_root_ / "Scenes" / "Main.mcscene.json", scene_);
asset_database_.save(project_root_ / "Library" / "AssetDB.json");
platform_.pump_frame();
foundation::log(foundation::LogLevel::Info, "Hierarchy items: " + std::to_string(snapshot.hierarchy.size()));
foundation::log(foundation::LogLevel::Info, "Project assets: " + std::to_string(snapshot.assets.size()));
foundation::log(foundation::LogLevel::Info, "Inspector target: " + snapshot.inspector.object_name);
foundation::log(foundation::LogLevel::Info, "Scene object count: " + std::to_string(snapshot.scene_object_count));
foundation::log(foundation::LogLevel::Info, "Session status: " + snapshot.status_text);
foundation::log(foundation::LogLevel::Info, "Editor shell: " + editor_shell_->shell_name());
foundation::log(foundation::LogLevel::Info, "Editor shell summary: " + editor_shell_->summarize_snapshot());
foundation::log(foundation::LogLevel::Info, editor_shell_->describe_workspace());
for (const auto& message : snapshot.console) {
foundation::log(foundation::LogLevel::Info, "[" + message.category + "] " + message.text);
}
return 0;
}
void EditorApplication::shutdown() {
if (editor_shell_) {
editor_shell_->shutdown();
}
render_backend_.shutdown();
platform_.shutdown();
foundation::log(foundation::LogLevel::Info, "MetaEditor shutdown complete");
}
} // namespace metacore::editor