Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
242 changes: 151 additions & 91 deletions Tetragrama/Components/ProjectViewUIComponent.cpp

Large diffs are not rendered by default.

71 changes: 41 additions & 30 deletions Tetragrama/Components/ProjectViewUIComponent.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#include <Tetragrama/Components/ProjectViewUIComponent.h>
#include <Tetragrama/Components/UIComponent.h>
#include <ZEngine/Core/Memory/Allocator.h>
#include <ZEngine/Core/VFS/VFSScanner.h>
#include <ZEngine/Importers/AssetTypes.h>
#include <filesystem>

Expand All @@ -19,11 +20,11 @@ namespace Tetragrama::Components
{
None,
CreateFolder,
CreateFile,
NewFile,
RenameFolder,
RenameFile,
DeleteFolder,
DeleteFile,
RemoveFile,
};

class ProjectViewUIComponent : public UIComponent
Expand All @@ -32,43 +33,53 @@ namespace Tetragrama::Components
ProjectViewUIComponent();
virtual ~ProjectViewUIComponent();

void Initialize(Layers::ImguiLayer* parent = nullptr, const char* name = "Project", bool visibility = true, bool closed = false) override;
void Initialize(Layers::ImguiLayer* parent = nullptr, const char* name = "Project", bool visibility = true, bool closed = false) override;

void Update(ZEngine::Core::TimeStep dt) override;
void Update(ZEngine::Core::TimeStep dt) override;

virtual void Render(ZEngine::Rendering::Renderers::GraphicRenderer* const renderer, ZEngine::Hardwares::CommandBuffer* const command_buffer) override;
virtual void Render(ZEngine::Rendering::Renderers::GraphicRenderer* const renderer, ZEngine::Hardwares::CommandBuffer* const command_buffer) override;

// Render Panes
void RenderContentBrowser(ZEngine::Rendering::Renderers::GraphicRenderer* const renderer);
void RenderFilteredContent(ZEngine::Rendering::Renderers::GraphicRenderer* const renderer, const char* searchTerm);
void RenderDirectoryNode(const std::filesystem::path& directory);
void RenderContentTile(ZEngine::Rendering::Renderers::GraphicRenderer* const renderer, const std::filesystem::directory_entry& entry);
void RenderBackButton();
void RenderTreeBrowser();
void RenderContentBrowser(ZEngine::Rendering::Renderers::GraphicRenderer* const renderer);
void RenderFilteredContent(ZEngine::Rendering::Renderers::GraphicRenderer* const renderer, const char* searchTerm);
void RenderDirectoryNode(const ZEngine::Core::VFS::VFSPath& directory);
void RenderContentTile(ZEngine::Rendering::Renderers::GraphicRenderer* const renderer, const ZEngine::Core::VFS::VFSDirEntry& entry);
void RenderBackButton();
void RenderTreeBrowser();

// Popup helpers
void RenderContextMenu(ContextMenuType type, const std::filesystem::path& targetPath);
void RenderPopUpMenu();
void HandleCreateFolderPopup(const std::filesystem::path& path);
void HandleCreateFilePopup(const std::filesystem::path& path);
void RenderContextMenu(ContextMenuType type, const std::filesystem::path& targetPath);
void RenderPopUpMenu();
void HandleCreateFolderPopup(const std::filesystem::path& path);
void HandleCreateFilePopup(const std::filesystem::path& path);

void HandleRenameFolderPopup(const std::filesystem::path& path);
void HandleDeleteFolderPopup(const std::filesystem::path& path);
void HandleRenameFilePopup(const std::filesystem::path& path);
void HandleDeleteFilePopup(const std::filesystem::path& path);
void HandleRenameFolderPopup(const std::filesystem::path& path);
void HandleDeleteFolderPopup(const std::filesystem::path& path);
void HandleRenameFilePopup(const std::filesystem::path& path);
void HandleDeleteFilePopup(const std::filesystem::path& path);

void MakeRelative(const std::filesystem::path& path, const std::filesystem::path& base, char* output);
void MakeRelative(const std::filesystem::path& path, const std::filesystem::path& base, char* output);

void TriggerScan();
std::filesystem::path VfsToNative(const ZEngine::Core::VFS::VFSPath& path) const;

private:
ZEngine::Core::Memory::ArenaAllocator m_local_arena = {};
std::filesystem::path m_assets_directory;
std::filesystem::path m_current_directory;
PopupType m_active_popup = PopupType::None;
std::filesystem::path m_popup_target_path;

ZEngine::Importers::AssetTexture* m_directory_icon;
ZEngine::Importers::AssetTexture* m_file_icon;
static constexpr float m_thumbnail_size = 64.0f;
char m_search_buffer[MAX_FILE_PATH_COUNT] = "";
ZEngine::Core::Memory::ArenaAllocator m_local_arena = {};

ZEngine::Core::VFS::IVFSContext* m_vfs_context = nullptr;
ZEngine::Core::VFS::VFSDirectoryCache* m_directory_cache = nullptr;
ZEngine::Core::VFS::VFSScanner* m_scanner = nullptr;

ZEngine::Core::VFS::VFSPath m_assets_vfs_root = {};
ZEngine::Core::VFS::VFSPath m_current_vfs_dir = {};
char m_root_label[MAX_FILE_PATH_COUNT] = "";

PopupType m_active_popup = PopupType::None;
std::filesystem::path m_popup_target_path;

ZEngine::Importers::AssetTexture* m_directory_icon;
ZEngine::Importers::AssetTexture* m_file_icon;
static constexpr float m_thumbnail_size = 64.0f;
char m_search_buffer[MAX_FILE_PATH_COUNT] = "";
};
} // namespace Tetragrama::Components
8 changes: 8 additions & 0 deletions Tetragrama/Editor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,14 @@ namespace Tetragrama
Configuration->ActiveSceneName.append(active_scene);
}
WorkingSpacePath = Configuration->WorkingSpacePath.c_str();
if (WorkingSpacePath && WorkingSpacePath[0] != '\0')
{
WorkingSpaceBackend.Initialize(WorkingSpacePath, ZEngine::Core::VFS::VFSBackendCaps::Read | ZEngine::Core::VFS::VFSBackendCaps::List, Arena);
if (GetVFSContext()->Mount(&WorkingSpaceBackend, ZEngine::Core::VFS::VFSPath::Root(), 0).Failed())
{
ZENGINE_CORE_ERROR("Failed to mount working space '{}' into the VFS", WorkingSpacePath)
}
}
}

void Editor::OverrideWindowConfiguration()
Expand Down
25 changes: 14 additions & 11 deletions Tetragrama/Editor.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include <Tetragrama/Layers/ImguiLayer.h>
#include <ZEngine/Applications/GameApplication.h>
#include <ZEngine/Core/Memory/Allocator.h>
#include <ZEngine/Core/VFS/VFSDiskBackend.h>
#include <ZEngine/Managers/AssetManager.h>

namespace Tetragrama::Serializers
Expand Down Expand Up @@ -34,21 +35,23 @@ namespace Tetragrama

virtual ~Editor() {}

ZRawPtr(Layers::ImguiLayer) UILayer = nullptr;
ZRawPtr(Layers::ImguiLayer) UILayer = nullptr;

virtual void OnInitializing() override;
virtual void OverrideWindowConfiguration() override;
virtual void OnInitialized() override;
ZEngine::Core::VFS::VFSDiskBackend WorkingSpaceBackend = {};

virtual void OnUpdate(float dt) override;
virtual void OnEvent(ZEngine::Core::CoreEvent&) override;
virtual void OnInitializing() override;
virtual void OverrideWindowConfiguration() override;
virtual void OnInitialized() override;

virtual void OnPreRender() override;
virtual void OnPostRender() override;
virtual void OnRenderUI() override;
virtual void OnUpdate(float dt) override;
virtual void OnEvent(ZEngine::Core::CoreEvent&) override;

virtual void OnClosing() override;
virtual void OnClosed() override;
virtual void OnPreRender() override;
virtual void OnPostRender() override;
virtual void OnRenderUI() override;

virtual void OnClosing() override;
virtual void OnClosed() override;
};
ZDEFINE_PTR(Editor);

Expand Down
3 changes: 3 additions & 0 deletions Tetragrama/Layers/ImguiLayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ namespace Tetragrama::Layers
CurrentApp = app;
arena->CreateSubArena(ZMega(10), &LocalArena);

Scanner.Initialize(arena);
Cache.Initialize(arena);

NodeHierarchies.init(arena, 10, 0);
NodeUIComponents.init(arena);
NodeToRender.init(arena, 10);
Expand Down
4 changes: 4 additions & 0 deletions Tetragrama/Layers/ImguiLayer.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include <ZEngine/Core/Containers/Strings.h>
#include <ZEngine/Core/Containers/UnorderedHashMap.h>
#include <ZEngine/Core/Memory/Allocator.h>
#include <ZEngine/Core/VFS/VFSScanner.h>
#include <ZEngine/Helpers/NodeHierarchyHelper.h>
#include <ZEngine/Windows/Inputs/IInputEventCallback.h>

Expand All @@ -25,6 +26,9 @@ namespace Tetragrama::Layers
ZEngine::Core::Containers::UnorderedHashMap<uint32_t, Components::UIComponent*> NodeUIComponents = {};
ZEngine::Core::Containers::UnorderedHashMap<ZEngine::Windows::Inputs::GlfwKeyCode, int> KeyEntries = {};

ZEngine::Core::VFS::VFSScanner Scanner = {};
ZEngine::Core::VFS::VFSDirectoryCache Cache = {};

virtual void Initialize(ZEngine::Core::Memory::ArenaAllocator* arena, ZEngine::Applications::GameApplicationPtr app) override;
virtual void Deinitialize() override;

Expand Down
6 changes: 6 additions & 0 deletions ZEngine/ZEngine/Applications/GameApplication.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ namespace ZEngine::Applications

State = ZPushStructCtor(Arena, ApplicationState);

VFS.Initialize(Arena);
OnInitializing();
OverrideWindowConfiguration();

Expand All @@ -17,6 +18,11 @@ namespace ZEngine::Applications
OnInitialized();
}

Core::VFS::IVFSContext* GameApplication::GetVFSContext()
{
return &VFS;
}

void GameApplication::Run()
{
Engine::Run();
Expand Down
4 changes: 4 additions & 0 deletions ZEngine/ZEngine/Applications/GameApplication.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include <ZEngine/Controllers/ICameraController.h>
#include <ZEngine/Core/Memory/Allocator.h>
#include <ZEngine/Core/TimeStep.h>
#include <ZEngine/Core/VFS/VFSContext.h>
#include <ZEngine/Rendering/Scenes/GraphicScene.h>
#include <ZEngine/Windows/CoreWindow.h>
#include <ZEngine/Windows/WindowConfiguration.h>
Expand Down Expand Up @@ -38,6 +39,9 @@ namespace ZEngine::Applications
Controllers::ICameraControllerPtr CameraController = nullptr;
Rendering::Scenes::RenderScenePtr CurrentScene = nullptr;

Core::VFS::VFSContext VFS = {};
Core::VFS::IVFSContext* GetVFSContext();

void Initialize(Core::Memory::ArenaAllocator* arena);
void Update(Core::TimeStep dt);
void ProcessEvent(Core::CoreEvent&);
Expand Down
4 changes: 3 additions & 1 deletion ZEngine/ZEngine/Core/VFS/VFSContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,9 @@ namespace ZEngine::Core::VFS

VFSResult<Containers::Array<VFSDirEntry>> VFSContext::List(const VFSPath& absolute_dir, Memory::ArenaAllocator* out_arena)
{
using ResultT = VFSResult<Containers::Array<VFSDirEntry>>;
using ResultT = VFSResult<Containers::Array<VFSDirEntry>>;

std::lock_guard<std::mutex> arena_lock(m_arena_mutex);
auto scratch = ZGetScratch(m_arena);

Containers::Array<ResolveResult> matches;
Expand Down Expand Up @@ -187,6 +188,7 @@ namespace ZEngine::Core::VFS

VFSResult<ResolveResult> VFSContext::ResolveWritable(const VFSPath& path) const
{
std::lock_guard<std::mutex> arena_lock(m_arena_mutex);
auto scratch = ZGetScratch(m_arena);

Containers::Array<ResolveResult> matches;
Expand Down
2 changes: 2 additions & 0 deletions ZEngine/ZEngine/Core/VFS/VFSContext.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#pragma once
#include <ZEngine/Core/VFS/IVFSContext.h>
#include <ZEngine/Core/VFS/VFSMountTable.h>
#include <mutex>

namespace ZEngine::Core::VFS
{
Expand Down Expand Up @@ -32,6 +33,7 @@ namespace ZEngine::Core::VFS

VFSMountTable m_mount_table = {};
Memory::ArenaAllocator* m_arena = nullptr;
mutable std::mutex m_arena_mutex;
};

} // namespace ZEngine::Core::VFS
80 changes: 80 additions & 0 deletions ZEngine/ZEngine/Core/VFS/VFSDirectoryCache.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
#include <ZEngine/Core/VFS/VFSDirectoryCache.h>
#include <mutex>

namespace ZEngine::Core::VFS
{

void VFSDirectoryCache::Initialize(Memory::ArenaAllocator* arena)
{
m_arena = arena;
m_entries.init(arena, 64);
}

Core::Containers::ArrayView<const VFSDirEntry> VFSDirectoryCache::GetListing(const VFSPath& dir) const
{
std::shared_lock<std::shared_mutex> lock(m_mutex);
const CacheEntry* entry = m_entries.find(dir.Hash());
if (!entry)
{
return Core::Containers::ArrayView<const VFSDirEntry>(nullptr, 0);
}
return Core::Containers::ArrayView<const VFSDirEntry>(entry->Entries.data(), entry->Entries.size());
}

void VFSDirectoryCache::SetListing(const VFSPath& dir, Core::Containers::Array<VFSDirEntry>&& entries)
{
std::unique_lock<std::shared_mutex> lock(m_mutex);

CacheEntry& entry = m_entries[dir.Hash()];
entry.Entries = std::move(entries);
entry.Stale = false;
entry.Dir = dir;
}

bool VFSDirectoryCache::IsStale(const VFSPath& dir) const
{
std::shared_lock<std::shared_mutex> lock(m_mutex);
const auto entry = m_entries.find(dir.Hash());

if (!entry)
{
return true;
}

return entry->Stale;
}

void VFSDirectoryCache::Clear()
{
std::unique_lock<std::shared_mutex> lock(m_mutex);
m_entries.clear();
}

size_t VFSDirectoryCache::Size() const
{
std::shared_lock<std::shared_mutex> lock(m_mutex);
return m_entries.size();
}

void VFSDirectoryCache::ForEachDir(std::function<void(const VFSPath&, Core::Containers::ArrayView<const VFSDirEntry>)> visitor) const
{
std::shared_lock<std::shared_mutex> lock(m_mutex);

for (const auto& kv : m_entries)
{
visitor(kv.second.Dir, {kv.second.Entries.data(), kv.second.Entries.size()});
}
}

void VFSDirectoryCache::Invalidate(const VFSPath& dir)
{
std::unique_lock<std::shared_mutex> lock(m_mutex);
CacheEntry* entry = m_entries.find(dir.Hash());
if (!entry)
{
return;
}
entry->Stale = true;
}

} // namespace ZEngine::Core::VFS
46 changes: 46 additions & 0 deletions ZEngine/ZEngine/Core/VFS/VFSDirectoryCache.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@

#pragma once
#include <ZEngine/Core/Containers/Array.h>
#include <ZEngine/Core/Containers/UnorderedHashMap.h>
#include <ZEngine/Core/Memory/Allocator.h>
#include <ZEngine/Core/VFS/IVFSBackend.h>
#include <ZEngine/ZEngineDef.h>
#include <functional>
#include <shared_mutex>

namespace ZEngine::Core::VFS
{
struct VFSDirectoryCache
{
VFSDirectoryCache() = default;
~VFSDirectoryCache() = default;

void Initialize(Memory::ArenaAllocator* arena);
Core::Containers::ArrayView<const VFSDirEntry> GetListing(const VFSPath& dir) const;

void SetListing(const VFSPath& dir, Core::Containers::Array<VFSDirEntry>&& entries);

void Invalidate(const VFSPath& dir);

bool IsStale(const VFSPath& dir) const;

void Clear();

size_t Size() const;

void ForEachDir(std::function<void(const VFSPath&, Core::Containers::ArrayView<const VFSDirEntry>)> visitor) const;

private:
struct CacheEntry
{
VFSPath Dir = {};
Core::Containers::Array<VFSDirEntry> Entries = {};
bool Stale = true;
};

Core::Containers::UnorderedHashMap<uint64_t, CacheEntry> m_entries;
mutable std::shared_mutex m_mutex;
Memory::ArenaAllocator* m_arena = nullptr;
};

} // namespace ZEngine::Core::VFS
Loading
Loading