Skip to content

Commit b1d2074

Browse files
committed
Add filepath hashing function
1 parent 57b8628 commit b1d2074

File tree

13 files changed

+103
-75
lines changed

13 files changed

+103
-75
lines changed

Mahakam/src/Mahakam/Asset/Asset.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
#include "Mahakam/Core/Allocator.h"
44
#include "Mahakam/Core/Log.h"
5+
#include "Mahakam/Core/FileUtility.h"
56

67
#include "AssetDatabase.h"
78
#include "AssetDataFunctions.h"
@@ -32,6 +33,16 @@ namespace Mahakam
3233
static constexpr bool IsBaseOrVoid = std::is_void_v<T> || std::is_void_v<T2> || std::is_base_of_v<T, T2> || std::is_base_of_v<T2, T>;
3334

3435
public:
36+
struct HashedID
37+
{
38+
AssetID ID;
39+
const char* Path;
40+
41+
inline consteval HashedID(const char* filepath) :
42+
ID(FileUtility::Hash(filepath)),
43+
Path(filepath) { }
44+
};
45+
3546
Asset() :
3647
m_Control(nullptr) {}
3748

@@ -54,6 +65,17 @@ namespace Mahakam
5465
m_Control = nullptr;
5566
}
5667

68+
explicit Asset(HashedID value)
69+
{
70+
// Register if the ID is valid
71+
m_Control = AssetDatabase::IncrementAsset(value.ID);
72+
73+
if (!m_Control)
74+
{
75+
MH_WARN("Attempt to load asset with invalid hashed ID ({}) from path: {}", value.ID, value.Path);
76+
}
77+
}
78+
5779
#pragma region Copy & Move constructors
5880
Asset(const Asset& other) noexcept :
5981
m_Control(other.m_Control)

Mahakam/src/Mahakam/Asset/AssetLookup.h

Lines changed: 0 additions & 40 deletions
This file was deleted.

Mahakam/src/Mahakam/Core/FileUtility.cpp

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
namespace Mahakam
99
{
10-
void FileUtility::SetProjectDirectory(const Filepath& filepath)
10+
void FileUtility::SetProjectDirectory(const Filepath& filepath) noexcept
1111
{
1212
// Only reload if the path has changed
1313
if (filepath != PROJECT_PATH)
@@ -26,17 +26,17 @@ namespace Mahakam
2626
}
2727
}
2828

29-
void FileUtility::SetWorkingDirectory(const Filepath& filepath)
29+
void FileUtility::SetWorkingDirectory(const Filepath& filepath) noexcept
3030
{
3131
std::filesystem::current_path(filepath);
3232
}
3333

34-
Filepath FileUtility::GetWorkingDirectory()
34+
Filepath FileUtility::GetWorkingDirectory() noexcept
3535
{
3636
return std::filesystem::current_path();
3737
}
3838

39-
bool FileUtility::ReadFile(const Filepath& filepath, TrivialVector<char>& buffer)
39+
bool FileUtility::ReadFile(const Filepath& filepath, TrivialVector<char>& buffer) noexcept
4040
{
4141
std::ifstream ifs(filepath, std::ios::binary | std::ios::ate);
4242

@@ -59,23 +59,30 @@ namespace Mahakam
5959
return true;
6060
}
6161

62-
bool FileUtility::Exists(const Filepath& src)
62+
size_t FileUtility::Hash(const Filepath& filepath) noexcept
63+
{
64+
std::string filepathStr = filepath.generic_string();
65+
66+
return Hash(filepathStr.c_str(), filepathStr.size());
67+
}
68+
69+
bool FileUtility::Exists(const Filepath& src) noexcept
6370
{
6471
return std::filesystem::exists(src);
6572
}
6673

67-
void FileUtility::CreateDirectories(const Filepath& src)
74+
void FileUtility::CreateDirectories(const Filepath& src) noexcept
6875
{
6976
if (!std::filesystem::exists(src))
7077
std::filesystem::create_directories(src);
7178
}
7279

73-
Filepath FileUtility::Relative(const Filepath& filepath)
80+
Filepath FileUtility::Relative(const Filepath& filepath) noexcept
7481
{
7582
return std::filesystem::relative(filepath, PROJECT_PATH);
7683
}
7784

78-
Filepath FileUtility::GetCachePath(const Filepath& filepath)
85+
Filepath FileUtility::GetCachePath(const Filepath& filepath) noexcept
7986
{
8087
Filepath importDirectory = CACHE_PATH / filepath.parent_path();
8188

@@ -84,7 +91,7 @@ namespace Mahakam
8491
return CACHE_PATH / Filepath(filepath.string() + ".cache");
8592
}
8693

87-
Filepath FileUtility::GetImportPath(const Filepath& filepath, const std::string& extension)
94+
Filepath FileUtility::GetImportPath(const Filepath& filepath, const std::string& extension) noexcept
8895
{
8996
Filepath importPath = std::filesystem::relative(filepath, RESOURCE_PATH);
9097

Mahakam/src/Mahakam/Core/FileUtility.h

Lines changed: 40 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -20,22 +20,50 @@ namespace Mahakam
2020

2121
inline static const std::string AssetExtension = ".asset";
2222

23-
static void SetProjectDirectory(const Filepath& filepath);
23+
static void SetProjectDirectory(const Filepath& filepath) noexcept;
2424

25-
static void SetWorkingDirectory(const Filepath& filepath);
26-
static Filepath GetWorkingDirectory();
25+
static void SetWorkingDirectory(const Filepath& filepath) noexcept;
26+
static Filepath GetWorkingDirectory() noexcept;
2727

28-
static bool ReadFile(const Filepath& filepath, TrivialVector<char>& buffer);
28+
static bool ReadFile(const Filepath& filepath, TrivialVector<char>& buffer) noexcept;
2929

30-
static bool Exists(const Filepath& src);
31-
static void CreateDirectories(const Filepath& src);
32-
static Filepath Relative(const Filepath& filepath);
33-
static Filepath GetCachePath(const Filepath& filepath);
34-
static Filepath GetImportPath(const Filepath& filepath, const std::string& extension);
30+
static constexpr size_t Hash(const char* filepath, size_t length) noexcept
31+
{
32+
constexpr uint64_t fnv_prime = 1099511628211ULL;
33+
constexpr uint64_t fnv_offset_basis = 14695981039346656037ULL;
34+
35+
uint64_t hash = fnv_offset_basis;
36+
37+
for (size_t i = 0; i < length; ++i)
38+
{
39+
char c = filepath[i];
40+
41+
if (c == '/' || c == '\\')
42+
continue;
43+
44+
hash ^= c;
45+
hash *= fnv_prime;
46+
}
47+
48+
return hash;
49+
}
50+
51+
static consteval size_t Hash(const char* filepath) noexcept
52+
{
53+
return Hash(filepath, std::char_traits<char>::length(filepath));
54+
}
55+
56+
static size_t Hash(const Filepath& filepath) noexcept;
57+
58+
static bool Exists(const Filepath& src) noexcept;
59+
static void CreateDirectories(const Filepath& src) noexcept;
60+
static Filepath Relative(const Filepath& filepath) noexcept;
61+
static Filepath GetCachePath(const Filepath& filepath) noexcept;
62+
static Filepath GetImportPath(const Filepath& filepath, const std::string& extension) noexcept;
3563

3664
// Defined by each platform
37-
static Filepath OpenFile(const char* filter, const Filepath& basePath);
38-
static Filepath SaveFile(const char* filter, const Filepath& basePath);
39-
static Filepath OpenDirectory();
65+
static Filepath OpenFile(const char* filter, const Filepath& basePath) noexcept;
66+
static Filepath SaveFile(const char* filter, const Filepath& basePath) noexcept;
67+
static Filepath OpenDirectory() noexcept;
4068
};
4169
}

Mahakam/src/Mahakam/Editor/Windows/ImportWizardPanel.cpp

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -80,17 +80,28 @@ namespace Mahakam::Editor
8080

8181
ImGui::Separator();
8282

83-
// TODO: Draw AssetID so it can be easily changed
83+
// Draw AssetID so it can be easily changed
8484
// Could also warn if an asset already exists with that ID
8585
int step = 1;
8686
int step_fast = 100;
8787
ImGui::InputScalar("ID", ImGuiDataType_U64, &m_AssetID, nullptr, nullptr, "%llu", 0);
8888

8989
if (ImGui::Button("Regenerate ID"))
90+
m_AssetID = FileUtility::Hash(m_ImportPath);
91+
92+
if (ImGui::Button("Generate new ID"))
9093
m_AssetID = Random::GetRandomID64();
9194

9295
if (AssetDatabase::AssetExists(m_AssetID))
96+
{
9397
ImGui::Text("An asset with this ID already exists");
98+
size_t useCount = AssetDatabase::GetAssetReferences(m_AssetID);
99+
if (useCount > 0)
100+
{
101+
ImGui::Text("The asset is currently in use %llu places", useCount);
102+
ImGui::Text("It might not be a good idea to regenerate the ID");
103+
}
104+
}
94105

95106
// Draw filename input without path/**.extension.import
96107
std::string nameString = m_ImportPath.stem().stem().string();
@@ -149,7 +160,7 @@ namespace Mahakam::Editor
149160
window->m_Open = true;
150161
window->m_Importer = importer;
151162
window->m_ImportPath = FileUtility::Relative(FileUtility::GetImportPath(filepath, importer->GetImporterProps().Extension));
152-
window->m_AssetID = Random::GetRandomID64();
163+
window->m_AssetID = FileUtility::Hash(window->m_ImportPath);
153164

154165
// Open the wizard with the filepath
155166
importer->OnResourceOpen(filepath);
@@ -185,7 +196,7 @@ namespace Mahakam::Editor
185196
window->m_Open = true;
186197
window->m_Importer = importer;
187198
window->m_ImportPath = FileUtility::Relative(importPath);
188-
window->m_AssetID = Random::GetRandomID64();
199+
window->m_AssetID = FileUtility::Hash(window->m_ImportPath);
189200

190201
// Read the import file and open the wizard
191202
ryml::Tree tree = ReadImport(importPath);

Mahakam/src/Platform/Linux/LinuxUtility.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
namespace Mahakam
1212
{
13-
static bool FileDialogsUtilityCheck()
13+
static bool FileDialogsUtilityCheck() noexcept
1414
{
1515
FILE* fp;
1616
char path[LINUX_PATH_MAX];
@@ -30,7 +30,7 @@ namespace Mahakam
3030
return true;
3131
}
3232

33-
Filepath FileUtility::OpenFile(const char* filter, const Filepath& basePath)
33+
Filepath FileUtility::OpenFile(const char* filter, const Filepath& basePath) noexcept
3434
{
3535
if (!FileDialogsUtilityCheck())
3636
return Filepath();
@@ -61,7 +61,7 @@ namespace Mahakam
6161
return file_choice;
6262
}
6363

64-
Filepath FileUtility::SaveFile(const char* filter, const Filepath& basePath)
64+
Filepath FileUtility::SaveFile(const char* filter, const Filepath& basePath) noexcept
6565
{
6666
if (!FileDialogsUtilityCheck())
6767
return Filepath();
@@ -94,7 +94,7 @@ namespace Mahakam
9494
return file_choice;
9595
}
9696

97-
Filepath FileUtility::OpenDirectory()
97+
Filepath FileUtility::OpenDirectory() noexcept
9898
{
9999
if (!FileDialogsUtilityCheck())
100100
return Filepath();

Mahakam/src/Platform/Windows/WindowsFileUtility.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ namespace Mahakam
2121
~ComInit() { CoUninitialize(); }
2222
};
2323

24-
Filepath FileUtility::OpenFile(const char* filter, const Filepath& basePath)
24+
Filepath FileUtility::OpenFile(const char* filter, const Filepath& basePath) noexcept
2525
{
2626
std::string pathString = (FileUtility::GetWorkingDirectory() / basePath).string();
2727

@@ -47,7 +47,7 @@ namespace Mahakam
4747
return Filepath();
4848
}
4949

50-
Filepath FileUtility::SaveFile(const char* filter, const Filepath& basePath)
50+
Filepath FileUtility::SaveFile(const char* filter, const Filepath& basePath) noexcept
5151
{
5252
std::string pathString = (FileUtility::GetWorkingDirectory() / basePath).string();
5353

@@ -76,7 +76,7 @@ namespace Mahakam
7676
return Filepath();
7777
}
7878

79-
Filepath FileUtility::OpenDirectory()
79+
Filepath FileUtility::OpenDirectory() noexcept
8080
{
8181
std::wstring pathString = FileUtility::GetWorkingDirectory().wstring();
8282

-31 Bytes
Binary file not shown.
31 Bytes
Binary file not shown.

Sandbox/import/materials/Skybox.material.import

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@ Shader: 5640725257607554339
22
Properties:
33
u_Environment: 15966881194349846934
44
Extension: .material
5-
ID: 1413214623375882268
5+
ID: 4365865613719578542

0 commit comments

Comments
 (0)