Skip to content

Commit 6004c76

Browse files
committed
feat: Implement a BuildSystem - Pack assets
1 parent 5dff774 commit 6004c76

15 files changed

Lines changed: 420 additions & 34 deletions

include/Editor/AssetDatabase.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,8 @@ namespace sh::editor
107107
SH_EDITOR_API void LoadAllAssets(EditorWorld& world, const std::filesystem::path& dir, bool recursive);
108108
SH_EDITOR_API auto ImportAsset(EditorWorld& world, const std::filesystem::path& dir) -> core::SObject*;
109109
SH_EDITOR_API bool CreateAsset(EditorWorld& world, const std::filesystem::path& dir, const core::ISerializable& serializable);
110+
SH_EDITOR_API auto GetAsset(const core::UUID& uuid) -> std::unique_ptr<core::Asset>;
111+
SH_EDITOR_API auto GetAssetOriginalPath(const core::UUID& uuid) const -> std::optional<std::filesystem::path>;
110112
/// @brief 해당 경로의 파일의 에셋의 UUID를 반환한다.
111113
/// @param assetPath 에셋 경로
112114
/// @return 에셋이 로드 돼 있지 않다면 nullopt반환, 로드 돼 있다면 UUID를 반환

include/Editor/BuildSystem.h

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
#pragma once
2+
#include "Export.h"
3+
4+
#include "Core/ISerializable.h"
5+
6+
#include <string>
7+
#include <vector>
8+
#include <unordered_set>
9+
#include <regex>
10+
#include <filesystem>
11+
namespace sh::game
12+
{
13+
class World;
14+
}
15+
namespace sh::editor
16+
{
17+
class Project;
18+
19+
class BuildSystem
20+
{
21+
private:
22+
Project* currentProject = nullptr;
23+
24+
std::regex uuidRegex;
25+
26+
std::unordered_set<std::string> uuids;
27+
28+
void ExtractUUIDs(const core::Json& world);
29+
void ExtractUUID(const core::Json& node);
30+
void PackingAssets(const std::filesystem::path& outputPath);
31+
public:
32+
SH_EDITOR_API BuildSystem();
33+
34+
SH_EDITOR_API void Build(Project& project, game::World& world, const std::filesystem::path& outputPath);
35+
};
36+
}//namespace

include/Editor/Meta.h

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@ namespace sh::editor
1515
class Meta
1616
{
1717
private:
18+
constexpr static int VERSION = 1;
19+
20+
std::string name;
21+
std::size_t typeHash;
1822
core::UUID uuid;
1923
std::filesystem::path path;
2024
core::Json json;
@@ -27,11 +31,16 @@ namespace sh::editor
2731
SH_EDITOR_API auto Load(const std::filesystem::path& path) -> bool;
2832
SH_EDITOR_API auto DeserializeSObject(core::SObject& obj) const -> bool;
2933

34+
SH_EDITOR_API void SaveWithObj(const core::SObject& obj, const std::filesystem::path& path, bool bCalcHash = true);
3035
SH_EDITOR_API void Save(const core::SObject& obj, const std::filesystem::path& path, bool bCalcHash = true);
3136

3237
SH_EDITOR_API auto IsLoad() const -> bool;
38+
SH_EDITOR_API auto IsChanged() const -> bool;
39+
SH_EDITOR_API auto HasObjData() const -> bool;
3340

3441
SH_EDITOR_API auto GetUUID() const -> const core::UUID&;
35-
SH_EDITOR_API auto IsChanged() const -> bool;
42+
SH_EDITOR_API auto GetTypeHash() const -> std::size_t;
43+
SH_EDITOR_API auto GetName() const -> const std::string&;
44+
SH_EDITOR_API auto GetObjJson() const -> const core::Json*;
3645
};
3746
}//namespace

include/Editor/ProjectSetting.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
#pragma once
2+
#include "Export.h"
3+
4+
#include "Core/ISerializable.h"
5+
6+
#include <filesystem>
7+
#include <string>
8+
namespace sh::editor
9+
{
10+
class ProjectSetting : public core::ISerializable
11+
{
12+
private:
13+
int version;
14+
public:
15+
std::filesystem::path startingWorldPath;
16+
public:
17+
SH_EDITOR_API ProjectSetting();
18+
19+
SH_EDITOR_API auto Serialize() const -> core::Json override;
20+
SH_EDITOR_API void Deserialize(const core::Json& json) override;
21+
};
22+
}//namespace

include/Editor/UI/AssetExplorer.h

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
#pragma once
2+
#include "Export.h"
3+
4+
namespace sh::editor
5+
{
6+
class EditorWorld;
7+
class AssetExplorer
8+
{
9+
private:
10+
const EditorWorld& world;
11+
public:
12+
enum class AssetType
13+
{
14+
Mesh,
15+
Texture
16+
} type;
17+
public:
18+
SH_EDITOR_API AssetExplorer(const EditorWorld& world);
19+
20+
SH_EDITOR_API void SetAssetType(AssetType type);
21+
22+
SH_EDITOR_API void Update();
23+
SH_EDITOR_API void Render();
24+
};
25+
}//namespace

include/Editor/UI/Project.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#pragma once
22
#include "Export.h"
3+
#include "ProjectSetting.h"
34

45
#include "Core/Reflection.hpp"
56
#include "Core/SContainer.hpp"
@@ -27,6 +28,8 @@ namespace sh::editor
2728

2829
AssetDatabase& assetDatabase;
2930

31+
ProjectSetting setting;
32+
3033
std::vector<std::filesystem::path> foldersPath;
3134
std::vector<std::filesystem::path> filesPath;
3235
std::vector<std::string> invisibleExtensions;
@@ -39,6 +42,7 @@ namespace sh::editor
3942

4043
static bool bInitResource;
4144
bool isOpen = false;
45+
bool bSettingUI = false;
4246
public:
4347
static constexpr const char* name = "Project";
4448
EditorWorld& world;
@@ -59,7 +63,12 @@ namespace sh::editor
5963

6064
void LoadUserModule();
6165

66+
void SaveProjectSetting();
67+
void LoadProjectSetting();
68+
6269
void CopyProjectTemplate(const std::filesystem::path& targetDir);
70+
71+
void RenderSettingUI();
6372
public:
6473
SH_EDITOR_API Project(EditorWorld& world);
6574
SH_EDITOR_API ~Project();
@@ -79,7 +88,13 @@ namespace sh::editor
7988

8089
SH_EDITOR_API void ReloadModule();
8190

91+
SH_EDITOR_API auto GetProjectPath() const -> const std::filesystem::path&;
8292
SH_EDITOR_API auto GetAssetPath() const -> const std::filesystem::path&;
8393
SH_EDITOR_API auto GetBinPath() const -> const std::filesystem::path&;
94+
SH_EDITOR_API auto GetProjectSetting() const -> ProjectSetting&;
95+
96+
SH_EDITOR_API void OpenSettingUI();
97+
98+
SH_EDITOR_API void Build();
8499
};
85100
}

src/Core/AssetBundle.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ namespace sh::core
6565
bundleStream.open(path, std::ios::binary | std::ios::out | std::ios::trunc);
6666
if (!bundleStream.is_open())
6767
{
68-
SH_ERROR_FORMAT("Could not open file for writing: {}", path.u8string());
68+
SH_ERROR_FORMAT(u8"Could not open file for writing: {}", path.u8string());
6969
return false;
7070
}
7171

src/Editor/AssetDatabase.cpp

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,9 @@ namespace sh::editor
5858

5959
uuids.insert_or_assign(relativePath, matPtr->GetUUID());
6060
paths.insert_or_assign(matPtr->GetUUID(), AssetInfo{ relativePath, relativePath });
61+
62+
Meta meta{};
63+
meta.Save(*matPtr, GetMetaDirectory(projectPath / relativePath));
6164
return matPtr;
6265
}
6366
void AssetDatabase::SaveMaterial(render::Material* mat, const std::filesystem::path& dir)
@@ -144,7 +147,7 @@ namespace sh::editor
144147
{
145148
render::Texture* texture = reinterpret_cast<render::Texture*>(obj);
146149
Meta meta{};
147-
meta.Save(*texture, GetMetaDirectory(projectPath / originalPath), false);
150+
meta.SaveWithObj(*texture, GetMetaDirectory(projectPath / originalPath), false);
148151
}
149152
}
150153
dirtyObjs.clear();
@@ -231,7 +234,7 @@ namespace sh::editor
231234
uuids.insert_or_assign(relativePath, objPtr->GetUUID());
232235
paths.insert_or_assign(objPtr->GetUUID(), AssetInfo{ relativePath, std::filesystem::relative(cachePath, projectPath) });
233236

234-
meta.Save(*objPtr, metaDir);
237+
meta.SaveWithObj(*objPtr, metaDir);
235238
return objPtr;
236239
}
237240
AssetDatabase::AssetDatabase()
@@ -336,7 +339,25 @@ namespace sh::editor
336339
return true;
337340
}
338341

339-
SH_EDITOR_API auto AssetDatabase::GetAssetUUID(const std::filesystem::path& assetPath) -> std::optional<core::UUID>
342+
SH_EDITOR_API auto AssetDatabase::GetAsset(const core::UUID& uuid) -> std::unique_ptr<core::Asset>
343+
{
344+
auto it = paths.find(uuid);
345+
if (it == paths.end())
346+
return nullptr;
347+
348+
return core::AssetImporter::Load(projectPath / it->second.cachePath);
349+
}
350+
351+
auto AssetDatabase::GetAssetOriginalPath(const core::UUID& uuid) const -> std::optional<std::filesystem::path>
352+
{
353+
auto it = paths.find(uuid);
354+
if (it == paths.end())
355+
return std::nullopt;
356+
357+
return it->second.originalPath;
358+
}
359+
360+
auto AssetDatabase::GetAssetUUID(const std::filesystem::path& assetPath) -> std::optional<core::UUID>
340361
{
341362
std::filesystem::path relativePath = std::filesystem::relative(assetPath, projectPath);
342363
auto it = uuids.find(relativePath);

src/Editor/BuildSystem.cpp

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
#include "BuildSystem.h"
2+
#include "AssetDatabase.h"
3+
#include "Meta.h"
4+
#include "UI/Project.h"
5+
6+
#include "Core/AssetBundle.h"
7+
#include "Core/FileSystem.h"
8+
9+
#include "Game/World.h"
10+
11+
namespace sh::editor
12+
{
13+
void BuildSystem::ExtractUUIDs(const core::Json& data)
14+
{
15+
if (data.is_object())
16+
{
17+
for (auto const& [key, val] : data.items())
18+
{
19+
ExtractUUIDs(val);
20+
}
21+
}
22+
else if (data.is_array())
23+
{
24+
for (const auto& item : data)
25+
{
26+
ExtractUUIDs(item);
27+
}
28+
}
29+
else if (data.is_string())
30+
{
31+
const std::string& value = data.get<std::string>();
32+
if (std::regex_match(value, uuidRegex))
33+
{
34+
if (uuids.find(value) == uuids.end())
35+
{
36+
uuids.insert(value);
37+
core::SObject* obj = core::SObjectManager::GetInstance()->GetSObject(core::UUID{ value });
38+
if (core::IsValid(obj))
39+
ExtractUUIDs(obj->Serialize());
40+
}
41+
}
42+
}
43+
}
44+
45+
void BuildSystem::PackingAssets(const std::filesystem::path& outputPath)
46+
{
47+
core::AssetBundle bundle;
48+
for (const auto& uuid : uuids)
49+
{
50+
auto asset = AssetDatabase::GetInstance()->GetAsset(core::UUID{ uuid });
51+
if (asset)
52+
{
53+
bundle.AddAsset(*asset, true);
54+
}
55+
}
56+
bundle.SaveBundle(outputPath);
57+
}
58+
59+
BuildSystem::BuildSystem() :
60+
uuidRegex("^[0-9a-f]{32}$", std::regex::optimize)
61+
{
62+
}
63+
64+
void BuildSystem::Build(Project& project, game::World& world, const std::filesystem::path& outputPath)
65+
{
66+
currentProject = &project;
67+
68+
uuids.clear();
69+
core::Json worldJson = world.Serialize();
70+
ExtractUUIDs(worldJson);
71+
PackingAssets(outputPath / "assets.bundle");
72+
}
73+
}//namespace

src/Editor/Component/EditorUI.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,10 @@ namespace sh::editor
113113
}
114114
else
115115
{
116+
if (ImGui::MenuItem("Project setting"))
117+
{
118+
project->OpenSettingUI();
119+
}
116120
if (ImGui::MenuItem("Reload module"))
117121
{
118122
project->ReloadModule();
@@ -127,7 +131,7 @@ namespace sh::editor
127131
}
128132
if (ImGui::MenuItem("Build"))
129133
{
130-
//project->Build();
134+
project->Build();
131135
}
132136
if (!bPlaying)
133137
{

0 commit comments

Comments
 (0)