153 lines
6.6 KiB
C++
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
|