Loading...
Searching...
No Matches
Project.cpp
Go to the documentation of this file.
1//
2// Created by denzel on 29/10/2025.
3//
4
5#include "Project.h"
6
7#include <fstream>
8#include <iostream>
9#include <glm/gtc/matrix_transform.hpp>
10
11#include "imgui_internal.h"
12#include "json.hpp"
13#include "hellfire/assets/AssetManager.h"
14#include "hellfire/assets/importers/AssetImportManager.h"
15#include "hellfire/graphics/renderer/Renderer.h"
16#include "hellfire/scene/Scene.h"
17#include "hellfire/serializers/ProjectSerializer.h"
18#include "hellfire/utilities/ServiceLocator.h"
19
20namespace hellfire {
21 Project::Project(const std::string &name) {
22 metadata_.name = name;
23 metadata_.version = "1.0.0";
24 metadata_.engine_version = "0.1.0";
25 metadata_.created_at = get_current_timestamp();
26 metadata_.last_opened = metadata_.created_at;
27 metadata_.default_scene = "assets/default_scene.hfscene";
28 metadata_.renderer_settings = "settings/renderer.json";
29 }
30
32
35 }
36
37 std::unique_ptr<Project> Project::create(const std::string &name, const std::filesystem::path &location) {
38 ProjectMetadata metadata;
39 metadata.name = name;
40 metadata.version = "1.0.0";
41 metadata.engine_version = "0.1.0";
42
43 // Get timestamp
45 metadata.last_opened = metadata.created_at;
46
47 auto project = std::make_unique<Project>(metadata);
48 project->project_root_path_ = location / name;
49 project->project_file_path_ = project->project_root_path_ / "project.hfproj";
50
51 project->create_directory_structure();
52
53 if (!project->save()) {
54 std::cerr << "Failed to save new project" << std::endl;
55 return nullptr;
56 }
57
58 return project;
59 }
60
61 std::unique_ptr<Project> Project::load_data(const std::filesystem::path &project_file) {
62 if (!exists(project_file)) {
63 std::cerr << "ERROR::PROJECT::LOAD:: Project file doesnt exist at " << project_file.string() << std::endl;
64 return nullptr;
65 }
66
67 try {
68 std::ifstream file(project_file);
69 if (!file.is_open()) {
70 std::cerr << "ERROR::PROJECT::LOAD:: Failed to open project file" << std::endl;
71 return nullptr;
72 }
73
74 ProjectMetadata metadata;
76 std::cerr << "Failed to deserialize project metadata" << std::endl;
77 return nullptr;
78 }
79
80 // Create project with metadata
81 auto project = std::make_unique<Project>(metadata);
82 project->project_file_path_ = project_file;
83 project->project_root_path_ = project_file.parent_path();
84
85 return project;
86 } catch (const nlohmann::json::parse_error& e) {
87 std::cerr << "ERROR::PROJECT::LOAD:: JSON parse error: " << e.what() << std::endl;
88 }
89 catch (const std::exception &e) {
90 std::cout << "ERROR::PROJECT::LOAD:: Exception: " << e.what() << std::endl;
91 return nullptr;
92 }
93 return nullptr;
94 }
95
96 bool Project::save() {
97 // Update last_opened timestamp
98 metadata_.last_opened = get_current_timestamp();
99
100 std::ofstream file(project_file_path_);
101 if (!file.is_open()) return false;
102
103 // Save asset registry
104 if (asset_registry_) {
105 asset_registry_->save();
106 }
107
108 // Save current scene if loaded
109 if (scene_manager_ && scene_manager_->has_active_scene()) {
110 scene_manager_->save_current_scene();
111 metadata_.last_scene = scene_manager_->get_active_scene_asset_id();
112 }
113
114
115 return Serializer<ProjectMetadata>::serialize(file, &metadata_);
116 }
117
118 void Project::close() {
119 save();
120
121 if (scene_manager_) {
122 scene_manager_->clear();
123 }
124
125 if (asset_registry_) {
126 asset_registry_->clear();
127 }
128
130 }
131
132 std::filesystem::path Project::get_project_root() const {
133 return project_root_path_;
134 }
135
136 std::filesystem::path Project::get_assets_path() const {
137 return project_root_path_ / "assets";
138 }
139
140 std::filesystem::path Project::get_scenes_path() const {
141 return project_root_path_ / "assets/scenes";
142 }
143
144 std::filesystem::path Project::get_settings_path() const {
145 return project_root_path_ / "settings";
146 }
147
149 create_directories(project_root_path_ / "settings");
150 create_directories(project_root_path_ / "assets");
151 create_directories(project_root_path_ / "assets" / "scenes");
152 create_directories(project_root_path_ / "assets" / "textures");
153 create_directories(project_root_path_ / "assets" / "models");
154 create_directories(project_root_path_ / "assets" / "scripts");
155 }
156
158 }
159
160
162 ServiceLocator::unregister_service<SceneManager>();
163 ServiceLocator::unregister_service<AssetRegistry>();
164 ServiceLocator::unregister_service<Renderer>();
165
166 // Initialize managers with project root context
167 auto registry_path = project_root_path_ / "settings/assetregistry.json";
168 asset_registry_ = std::make_unique<AssetRegistry>(registry_path, project_root_path_);
169 ServiceLocator::register_service<AssetRegistry>(asset_registry_.get());
170 asset_registry_->register_directory(get_assets_path(), true);
171
172 asset_manager_ = std::make_unique<AssetManager>(*asset_registry_.get());
173 ServiceLocator::register_service<AssetManager>(asset_manager_.get());
174
175 scene_renderer_ = std::make_unique<Renderer>();
176 scene_renderer_->init(); // Make sure OpenGL is initialized!
177 ServiceLocator::register_service<Renderer>(scene_renderer_.get());
178
179 AssetImportManager import_manager(*asset_registry_, *asset_manager_, project_root_path_);
180 import_manager.import_all_pending();
181 asset_registry_->save();
182
183 scene_manager_ = std::make_unique<SceneManager>();
184 ServiceLocator::register_service<SceneManager>(scene_manager_.get());
185
186 // Load last scene if exists
187 if (metadata_.last_scene) {
188 if (auto asset_info = asset_registry_->get_asset(metadata_.last_scene.value())) {
189 auto path = asset_registry_->get_absolute_path(asset_info->uuid);
190 auto scene = scene_manager_->load_scene(asset_info->uuid, path);
191 scene_manager_->set_active_scene(scene);
192 }
193 }
194 }
195
197 ServiceLocator::unregister_service<SceneManager>();
198 ServiceLocator::unregister_service<AssetRegistry>();
199 ServiceLocator::unregister_service<AssetManager>();
200 scene_manager_.reset();
201 asset_registry_.reset();
202 }
203
205 auto now = std::chrono::system_clock::now();
206 auto time_t_now = std::chrono::system_clock::to_time_t(now);
207 std::stringstream ss;
208 ss << std::put_time(std::gmtime(&time_t_now), "%Y-%m-%dT%H:%M:%SZ");
209 return ss.str();
210 }
211}
void import_all_pending()
Import all unprocessed assets in registry.
Registry for storing assets.
std::filesystem::path get_assets_path() const
Definition Project.cpp:136
std::filesystem::path get_settings_path() const
Definition Project.cpp:144
void cleanup_managers()
Definition Project.cpp:196
void initialize_default_assets()
Definition Project.cpp:157
Project(const ProjectMetadata &metadata)
Definition Project.cpp:31
void create_directory_structure() const
Definition Project.cpp:148
std::filesystem::path project_root_path_
Definition Project.h:57
Project(const std::string &name)
Definition Project.cpp:21
void initialize_managers()
Definition Project.cpp:161
std::filesystem::path get_scenes_path() const
Definition Project.cpp:140
std::filesystem::path get_project_root() const
Definition Project.cpp:132
static std::string get_current_timestamp()
Definition Project.cpp:204
std::string created_at
Definition Project.h:19
std::string last_opened
Definition Project.h:20
std::string engine_version
Definition Project.h:18
static bool deserialize(std::istream &input, ProjectMetadata *obj)