Skip to content

Commit 76de734

Browse files
revisited asset manager
1 parent af074de commit 76de734

29 files changed

+1612
-549
lines changed

Tetragrama/Components/DockspaceUIComponent.cpp

Lines changed: 145 additions & 80 deletions
Large diffs are not rendered by default.

Tetragrama/Components/DockspaceUIComponent.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,6 @@ namespace Tetragrama::Components
2121
virtual void Render(ZEngine::Rendering::Renderers::GraphicRenderer* const renderer, ZEngine::Hardwares::CommandBuffer* const command_buffer) override;
2222

2323
void RenderMenuBar();
24-
void RenderSaveScene();
25-
void RenderSaveSceneAs();
2624
void ResetSaveAsBuffers();
2725
void RenderExitPopup();
2826

@@ -31,18 +29,22 @@ namespace Tetragrama::Components
3129
*/
3230
void RenderImporter();
3331
void ResetImporterBuffers();
34-
static void OnAssetImporterComplete(void* const context, const char* result);
32+
static void OnAssetImporterComplete(void* const context, ZEngine::Core::Containers::ArrayView<Importers::AssetImporterOutput> result);
3533
static void OnAssetImporterProgress(void* const, float value);
3634
static void OnAssetImporterError(void* const, std::string_view);
3735
static void OnAssetImporterLog(void* const, std::string_view);
3836

3937
/*
4038
* Editor Scene Funcs
4139
*/
40+
void RenderLoadScene();
41+
void RenderSaveScene();
42+
void RenderSaveSceneAs();
4243
static void OnEditorSceneSerializerProgress(void* const, float value);
4344
static void OnEditorSceneSerializerComplete(void* const);
4445
static void OnEditorSceneSerializerDeserializeComplete(void* const, EditorScene&&);
4546
static void OnEditorSceneSerializerError(void* const, std::string_view);
47+
static void OnEditorSceneSerializerLog(void* const, std::string_view);
4648

4749
std::future<void> OnNewSceneAsync();
4850
std::future<void> OnOpenSceneAsync();

Tetragrama/Components/HierarchyViewUIComponent.cpp

Lines changed: 136 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include <glm/glm.hpp>
1414
#include <gtc/type_ptr.hpp>
1515
#include <imgui.h>
16+
#include <stack>
1617

1718
using namespace ZEngine;
1819
using namespace ZEngine::Helpers;
@@ -58,15 +59,15 @@ namespace Tetragrama::Components
5859

5960
void HierarchyViewUIComponent::Render(ZEngine::Rendering::Renderers::GraphicRenderer* const renderer, ZEngine::Hardwares::CommandBuffer* const command_buffer)
6061
{
61-
auto ctx = reinterpret_cast<EditorContext*>(ParentLayer->ParentContext);
62-
auto render_scene = ctx->CurrentScenePtr->RenderScene;
62+
auto ctx = reinterpret_cast<EditorContext*>(ParentLayer->ParentContext);
63+
auto current_scene = ctx->CurrentScenePtr;
6364

6465
ImGui::Begin(Name, (CanBeClosed ? &CanBeClosed : NULL), ImGuiWindowFlags_NoCollapse);
6566
if (ImGui::BeginPopupContextWindow(Name))
6667
{
6768
if (ImGui::MenuItem("Create Empty"))
6869
{
69-
render_scene->CreateEntityAsync();
70+
current_scene->CreateSceneNode();
7071
}
7172
ImGui::EndPopup();
7273
}
@@ -76,8 +77,8 @@ namespace Tetragrama::Components
7677
// 0 means left buttom
7778
if (ImGui::IsMouseDown(0) && ImGui::IsWindowHovered())
7879
{
79-
m_selected_node_identifier = -1;
80-
Messengers::IMessenger::SendAsync<Components::UIComponent, Messengers::EmptyMessage>(EDITOR_COMPONENT_HIERARCHYVIEW_NODE_UNSELECTED, Messengers::EmptyMessage{});
80+
ctx->SelectedSceneNode.store(-1, std::memory_order_release);
81+
// Messengers::IMessenger::SendAsync<Components::UIComponent, Messengers::EmptyMessage>(EDITOR_COMPONENT_HIERARCHYVIEW_NODE_UNSELECTED, Messengers::EmptyMessage{});
8182
}
8283

8384
RenderGuizmo();
@@ -87,37 +88,48 @@ namespace Tetragrama::Components
8788

8889
void HierarchyViewUIComponent::RenderTreeNodes()
8990
{
90-
auto ctx = reinterpret_cast<EditorContext*>(ParentLayer->ParentContext);
91-
auto render_scene = ctx->CurrentScenePtr->RenderScene;
91+
auto ctx = reinterpret_cast<EditorContext*>(ParentLayer->ParentContext);
92+
auto current_scene = ctx->CurrentScenePtr;
9293

93-
auto root_nodes = render_scene->GetRootSceneNodes();
94+
if (current_scene->IsDirty())
95+
{
96+
return;
97+
}
9498

95-
for (int node : root_nodes)
99+
for (int i = 0; i < (int) current_scene->Hierarchies.size(); ++i)
96100
{
97-
RenderSceneNodeTree(node);
101+
if (!current_scene->IsSceneNodeDeleted(i) && current_scene->Hierarchies[i].Parent == -1)
102+
{
103+
RenderNode(current_scene, i, ctx->SelectedSceneNode);
104+
}
98105
}
99106
}
100107

101108
void HierarchyViewUIComponent::RenderGuizmo()
102109
{
103-
if (m_selected_node_identifier <= -1)
110+
auto ctx = reinterpret_cast<EditorContext*>(ParentLayer->ParentContext);
111+
auto current_scene = ctx->CurrentScenePtr;
112+
113+
if (current_scene->IsDirty())
104114
{
105115
return;
106116
}
107117

108-
// auto entity_wrapper = GraphicScene::GetSceneNodeEntityWrapper(m_selected_node_identifier);
109-
auto ctx = reinterpret_cast<EditorContext*>(ParentLayer->ParentContext);
110-
auto render_scene = ctx->CurrentScenePtr->RenderScene;
118+
int selected_node = ctx->SelectedSceneNode.load(std::memory_order_acquire);
119+
if (selected_node == -1)
120+
{
121+
return;
122+
}
111123

112124
if (auto active_editor_camera = ctx->CameraControllerPtr)
113125
{
114126
auto camera = active_editor_camera->GetCamera();
115127
const auto camera_projection = camera->GetPerspectiveMatrix();
116128
const auto camera_view_matrix = camera->GetViewMatrix();
117129

118-
auto& global_transform = render_scene->GetSceneNodeGlobalTransform(m_selected_node_identifier);
130+
auto& global_transform = current_scene->GlobalTransforms[selected_node];
119131
auto initial_transform = global_transform;
120-
auto& local_transform = render_scene->GetSceneNodeLocalTransform(m_selected_node_identifier);
132+
auto& local_transform = current_scene->LocalTransforms[selected_node];
121133

122134
if (camera && IDevice::As<Keyboard>()->IsKeyPressed(ZENGINE_KEY_F, Engine::GetWindow()))
123135
{
@@ -140,7 +152,7 @@ namespace Tetragrama::Components
140152

141153
auto delta_transform = glm::inverse(initial_transform) * global_transform;
142154
local_transform = local_transform * delta_transform;
143-
render_scene->MarkSceneNodeAsChanged(m_selected_node_identifier);
155+
// current_scene->MarkSceneNodeAsChanged(m_selected_node_identifier);
144156

145157
if (ImGuizmo::IsUsing())
146158
{
@@ -154,72 +166,139 @@ namespace Tetragrama::Components
154166
}
155167
}
156168

157-
void HierarchyViewUIComponent::RenderSceneNodeTree(int node_identifier)
169+
void HierarchyViewUIComponent::RenderNode(EditorScene* scene, int root_id, std::atomic_int& selected_node)
158170
{
159-
if (node_identifier < 0)
171+
struct StackEntry
160172
{
161-
return;
162-
}
173+
int node_id;
174+
bool open;
175+
};
163176

164-
auto ctx = reinterpret_cast<EditorContext*>(ParentLayer->ParentContext);
165-
auto render_scene = ctx->CurrentScenePtr->RenderScene;
177+
std::stack<StackEntry> stack;
178+
stack.push({root_id, false});
166179

167-
const auto& node_hierarchy = render_scene->GetSceneNodeHierarchy(node_identifier);
168-
auto node_name = render_scene->GetSceneNodeName(node_identifier);
169-
auto node_identifier_string = fmt::format("SceneNode_{0}", node_identifier);
170-
auto flags = (node_hierarchy.FirstChild < 0) ? (ImGuiTreeNodeFlags_Leaf | ImGuiTreeNodeFlags_Bullet | m_node_flag) : m_node_flag;
171-
flags |= (m_selected_node_identifier == node_identifier) ? ImGuiTreeNodeFlags_Selected : 0;
172-
auto label = (!node_name.empty()) ? std::string(node_name) : fmt::format("Node_{0}", node_identifier);
173-
bool is_node_opened = ImGui::TreeNodeEx(node_identifier_string.c_str(), flags, "%s", label.c_str());
174-
175-
if (ImGui::IsItemClicked())
180+
while (!stack.empty())
176181
{
177-
m_selected_node_identifier = node_identifier;
182+
auto entry = stack.top();
183+
stack.pop();
178184

179-
auto entity = render_scene->GetSceneNodeEntityWrapper(m_selected_node_identifier);
180-
Messengers::IMessenger::SendAsync<Components::UIComponent, Messengers::GenericMessage<SceneEntity>>(EDITOR_COMPONENT_HIERARCHYVIEW_NODE_SELECTED, Messengers::GenericMessage<SceneEntity>{std::move(entity)});
181-
}
185+
// Handle manual TreePop marker
186+
if (entry.node_id == -1)
187+
{
188+
ImGui::TreePop();
189+
continue;
190+
}
182191

183-
if (is_node_opened)
184-
{
185-
/*
186-
* Popup features
187-
*/
188-
bool request_entity_removal = false;
189-
if (ImGui::BeginPopupContextItem(node_identifier_string.c_str()))
192+
if (scene->IsSceneNodeDeleted(entry.node_id))
193+
{
194+
continue;
195+
}
196+
const auto& node = scene->Hierarchies[entry.node_id];
197+
198+
auto name_id = scene->NodeNames[entry.node_id];
199+
200+
bool is_selected = (selected_node == entry.node_id);
201+
bool has_children = (node.FirstChild != -1);
202+
203+
ImGuiTreeNodeFlags flags = ImGuiTreeNodeFlags_OpenOnArrow | ImGuiTreeNodeFlags_SpanFullWidth;
204+
if (!has_children)
205+
flags |= ImGuiTreeNodeFlags_Leaf | ImGuiTreeNodeFlags_NoTreePushOnOpen;
206+
if (is_selected)
207+
flags |= ImGuiTreeNodeFlags_Selected;
208+
209+
auto node_id = fmt::format("SceneNode_{0}", entry.node_id);
210+
bool open = ImGui::TreeNodeEx(node_id.c_str(), flags, "%s", scene->Names[name_id].c_str());
211+
212+
if (ImGui::IsItemClicked(ImGuiMouseButton_Left))
213+
{
214+
selected_node.store(entry.node_id, std::memory_order_release);
215+
}
216+
217+
// === Drag source ===
218+
if (ImGui::BeginDragDropSource())
219+
{
220+
ImGui::SetDragDropPayload("NODE_DRAG", &entry.node_id, sizeof(int));
221+
ImGui::EndDragDropSource();
222+
}
223+
224+
// === Drop target ===
225+
if (ImGui::BeginDragDropTarget())
226+
{
227+
if (const ImGuiPayload* payload = ImGui::AcceptDragDropPayload("NODE_DRAG"))
228+
{
229+
int dragged_id = *(const int*) payload->Data;
230+
if (dragged_id != entry.node_id && !scene->IsSceneNodeDeleted(dragged_id))
231+
{
232+
// prevent making it a child of itself or its descendants
233+
int test = entry.node_id;
234+
bool is_descendant = false;
235+
while (test != -1)
236+
{
237+
if (test == dragged_id)
238+
{
239+
is_descendant = true;
240+
break;
241+
}
242+
test = scene->Hierarchies[test].Parent;
243+
}
244+
245+
if (!is_descendant)
246+
{
247+
scene->ReparentNode(dragged_id, entry.node_id);
248+
}
249+
}
250+
}
251+
ImGui::EndDragDropTarget();
252+
}
253+
254+
if (ImGui::BeginPopupContextItem(node_id.c_str()))
190255
{
191256
if (ImGui::MenuItem("Create Empty child"))
192257
{
193-
render_scene->CreateEntityAsync("Empty Entity", m_selected_node_identifier, node_hierarchy.DepthLevel + 1);
258+
scene->CreateSceneNode(entry.node_id, node.DepthLevel + 1);
194259
}
195260

196261
if (ImGui::MenuItem("Rename"))
197262
{
198263
}
264+
199265
if (ImGui::MenuItem("Delete"))
200266
{
201-
Messengers::IMessenger::SendAsync<Components::UIComponent, Messengers::EmptyMessage>(EDITOR_COMPONENT_HIERARCHYVIEW_NODE_DELETED, Messengers::EmptyMessage{});
202-
request_entity_removal = true;
267+
scene->RemoveSceneNode(entry.node_id);
203268
}
204269
ImGui::EndPopup();
205270
}
206271

207-
if (request_entity_removal)
272+
if (open && has_children)
208273
{
209-
render_scene->RemoveNodeAsync(node_identifier);
210-
}
274+
// Push TreePop manually
275+
stack.push({-1, 0}); // Marker for TreePop
211276

212-
if (node_hierarchy.FirstChild > -1)
213-
{
214-
auto sibling_scene_node_collection = render_scene->GetSceneNodeSiblingCollection(node_hierarchy.FirstChild);
215-
// We consider first child as sibling node
216-
sibling_scene_node_collection.emplace(std::begin(sibling_scene_node_collection), node_hierarchy.FirstChild);
217-
for (auto sibling_identifier : sibling_scene_node_collection)
277+
// Push children in reverse order
278+
auto scratch = ZGetScratch(&ParentLayer->LayerArena);
279+
ZEngine::Core::Containers::Array<int> children;
280+
children.init(scratch.Arena, 5);
281+
282+
for (int child = node.FirstChild; child != -1; child = scene->Hierarchies[child].RightSibling)
218283
{
219-
RenderSceneNodeTree(sibling_identifier);
284+
if (!scene->IsSceneNodeDeleted(child))
285+
{
286+
children.push(child);
287+
}
220288
}
289+
290+
for (int i = static_cast<int>(children.size()) - 1; i >= 0; --i)
291+
{
292+
stack.push({children[i], false});
293+
}
294+
295+
ZReleaseScratch(scratch);
296+
}
297+
else if (!has_children && !(flags & ImGuiTreeNodeFlags_NoTreePushOnOpen))
298+
{
299+
// Only pop if not marked as Leaf
300+
ImGui::TreePop();
221301
}
222-
ImGui::TreePop();
223302
}
224303
}
225304
} // namespace Tetragrama::Components

Tetragrama/Components/HierarchyViewUIComponent.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,11 @@ namespace Tetragrama::Components
2222

2323
void RenderTreeNodes();
2424
void RenderGuizmo();
25-
void RenderSceneNodeTree(int node_identifier);
25+
void RenderNode(EditorScene* scene, int root_id, std::atomic_int& selected);
2626

2727
private:
2828
ImGuiTreeNodeFlags m_node_flag;
2929
bool m_is_node_opened{false};
30-
int m_selected_node_identifier{-1};
3130
int m_gizmo_operation{-1};
3231
};
3332
} // namespace Tetragrama::Components

0 commit comments

Comments
 (0)