-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathDataSystem.h
More file actions
217 lines (196 loc) · 8.04 KB
/
Copy pathDataSystem.h
File metadata and controls
217 lines (196 loc) · 8.04 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
#pragma once
#include "Texture.h"
#include "AssetMetaRegistry.h"
#include "AssetJob.h"
#include "ClassProperty.h"
#include "AssetBundle.h"
#include "ShaderMetaHandle.h"
#include <cstddef>
#include <iosfwd>
#include <mutex>
#include <unordered_set>
#include <vector>
template <typename T>
using DataContainer = std::unordered_map<std::string, std::shared_ptr<T>>;
// Main system for storing runtime data
class ModelLoader;
class Model;
class Material;
struct ShaderMeta;
namespace YAML { class Node; }
enum class RuntimeAssetType
{
Auto,
CatalogOnly,
Model,
Material,
Texture,
UITexture,
SpriteSheet,
ShaderMeta,
};
enum class RuntimeAssetChangeKind
{
CatalogUpsert,
ContentReload,
Removed,
};
// Editor 같은 authoring Host가 완전히 게시한 파일의 결과만 이 계약으로 넘긴다.
// Runtime은 source/meta 작성 방법을 알지 않고 catalog와 cache generation만 갱신한다.
struct RuntimeAssetChange
{
RuntimeAssetChangeKind kind{ RuntimeAssetChangeKind::CatalogUpsert };
RuntimeAssetType assetType{ RuntimeAssetType::Auto };
FileGuid guid{};
file::path path{};
};
class DataSystem : public Singleton<DataSystem>
{
public:
enum class TextureFileType
{
Texture,
MaterialTexture,
TerrainTexture,
HDR,
UITexture,
SpriteSheet,
};
enum class AssetType
{
Model,
Material,
Skeleton,
};
private:
friend class Singleton<DataSystem>;
DataSystem() = default;
~DataSystem();
public:
// C4 이후 Model/Material의 장기 소비자는 shared_ptr를 보유한다. Texture 계열은
// TerrainLayer와 legacy Material raw 별칭이 남아 있어 별도 이행 전까지 이전
// cache generation을 runtime 종료까지 보존한다.
static constexpr bool RequiresLegacyRetiredGeneration(
RuntimeAssetType assetType) noexcept
{
return assetType == RuntimeAssetType::Texture
|| assetType == RuntimeAssetType::UITexture
|| assetType == RuntimeAssetType::SpriteSheet;
}
void Initialize();
void Finalize();
// Asset bundle operations
void LoadAssetBundle(const AssetBundle& bundle);
void RetainAssets(const AssetBundle& bundle);
void ClearRetainedAssets();
void UnloadUnusedAssets();
//Resource Model
Model* LoadModelGUID(FileGuid guid);
void LoadModel(std::string_view filePath);
std::shared_ptr<Model> LoadCachedModelShared(std::string_view filePath);
// 즉시 사용 legacy 호출부 호환. 참조를 보관하는 쪽은 위 shared API를 쓴다.
Model* LoadCashedModel(std::string_view filePath);
std::shared_ptr<Model> FindCachedModel(std::string_view name);
std::vector<std::pair<std::string, std::shared_ptr<Model>>> SnapshotModels();
//Resource Texture
Texture* LoadTextureGUID(FileGuid guid);
Texture* LoadTexture(std::string_view filePath, TextureFileType type = TextureFileType::Texture);
std::shared_ptr<Texture> LoadSharedTexture(std::string_view filePath, TextureFileType type = TextureFileType::Texture);
std::vector<std::pair<std::string, std::shared_ptr<Texture>>> SnapshotTextures();
//Resource Material
void InsertMaterial(std::shared_ptr<Material> material);
std::shared_ptr<Material> FindCachedMaterial(std::string_view name);
std::vector<std::pair<std::string, std::shared_ptr<Material>>> SnapshotMaterials();
std::shared_ptr<Material> RegisterImportedMaterial(
std::shared_ptr<Material> material, std::string_view baseName);
// M5-B1: standalone Material YAML의 단일 codec. scene embedded material은
// typed reflection이 값을 복원한 뒤 같은 runtime finalize 규약을 공유한다.
YAML::Node SerializeMaterialPayload(Material& material) const;
bool DeserializeMaterialPayload(Material& material, const YAML::Node& node);
// Model cache는 이 versioned envelope 안에 위 YAML payload를 넣는다. 기존
// 무버전 binary record 판별은 probe 뒤 ModelLoader의 read-only 호환 경로가 맡는다.
bool HasVersionedMaterialBinaryPayload(std::istream& input) const;
bool SerializeMaterialBinaryPayload(Material& material, std::ostream& output) const;
bool DeserializeMaterialBinaryPayload(Material& material, std::istream& input);
void FinalizeMaterialRuntime(Material& material);
Material* LoadMaterial(std::string_view name);
// 소유권을 공유하는 조회. 컴포넌트처럼 참조를 보관하는 쪽은 이것을 써야
// 캐시에서 제거되어도 사용 중인 머티리얼이 파괴되지 않는다.
std::shared_ptr<Material> LoadMaterialShared(std::string_view name);
Texture* LoadMaterialTexture(std::string_view filePath, bool isCompress = false);
std::shared_ptr<Texture> LoadSharedMaterialTexture(std::string_view filePath, bool isCompress);
Material* CreateMaterial();
// Asset Metadata
FileGuid GetFileGuid(const file::path& filepath) const;
// catalog GUID를 정본으로 DataSystem 소유 cache slot을 얻는다. resolve가 반환한
// shared snapshot은 호출자가 보유하는 동안 안전하지만 reload 뒤 옛 handle은
// resolve되지 않는다. 값 복사 API는 기존 호출 호환 경계다.
ShaderMetaHandle LoadShaderMetaHandle(FileGuid guid, std::string& outError);
std::shared_ptr<const ShaderMeta> ResolveShaderMeta(ShaderMetaHandle handle) const;
bool LoadShaderMetaGUID(FileGuid guid, ShaderMeta& outMeta,
std::string& outError);
// Authoring Host가 파일/meta 게시를 끝낸 뒤 전달하는 유일한 변경 경계다.
// Player는 생산자를 설치하지 않고 startup catalog만 읽는다.
void ApplyAssetChange(const RuntimeAssetChange& change);
// Watcher I/O thread는 cache/catalog를 직접 바꾸지 않고 이 큐에 게시한다.
// Editor game thread가 프레임 경계에서 DrainQueuedAssetChanges를 호출해
// generation 변경과 이후 load의 관측 순서를 직렬화한다.
void QueueAssetChange(RuntimeAssetChange change);
std::size_t DrainQueuedAssetChanges();
FileGuid GetFilenameToGuid(const std::string& filename) const;
FileGuid GetStemToGuid(const std::string& stem) const;
file::path GetFilePath(FileGuid fileguid) const;
DataContainer<Model> Models;
DataContainer<Material> Materials;
DataContainer<Texture> Textures;
DataContainer<Texture> UITextures;
DataContainer<Texture> SpriteSheets;
std::unordered_map<int, std::unordered_set<std::string>> m_retainedAssets;
std::string m_trasfarShader{};
// 캐시별 보호 규약.
// m_modelMutex : Models
// m_materialMutex : Materials
// m_textureMutex : Textures / UITextures / SpriteSheets
// m_fontMutex : SFonts
// 이 맵들은 LoadAssetBundle이 스레드풀로 병렬 로딩하므로,
// 조회·삽입 시 반드시 해당 뮤텍스를 잡아야 한다.
std::mutex m_textureMutex;
std::mutex m_materialMutex;
std::mutex m_modelMutex;
std::mutex m_fontMutex;
private:
void AddModel(const file::path& filepath, const file::path& dir);
void LoadAssetCatalog(const file::path& root);
void RetireCachedAsset(RuntimeAssetType assetType, const file::path& path,
FileGuid guid, bool remove);
void InvalidateShaderMeta(FileGuid guid, bool remove);
void SynchronizeLegacyMaterialProperties(Material& material) const;
private:
//--------- current file count
uint32 currModelFileCount = 0;
uint32 currShaderFileCount = 0;
uint32 currTextureFileCount = 0;
uint32 currMaterialFileCount = 0;
//--------- Data Thread and Editor Payload
std::thread m_DataThread{};
file::path m_dragDropPath{};
std::shared_ptr<AssetMetaRegistry> m_assetMetaRegistry{};
// Texture 계열의 legacy raw 별칭만을 위한 한시적 보존 목록. Model/Material은
// cache 분리 뒤 실제 shared consumer가 없으면 즉시 파괴된다.
std::mutex m_retiredTextureMutex;
std::vector<std::shared_ptr<void>> m_retiredTextureGenerations;
struct ShaderMetaCacheSlot
{
FileGuid guid{};
std::uint32_t generation{ 1 };
bool occupied{};
std::shared_ptr<const ShaderMeta> value{};
};
mutable std::mutex m_shaderMetaMutex;
std::unordered_map<FileGuid, std::uint32_t> m_shaderMetaSlotByGuid;
std::vector<ShaderMetaCacheSlot> m_shaderMetaSlots;
std::vector<std::uint32_t> m_shaderMetaFreeSlots;
std::mutex m_pendingAssetChangeMutex;
std::vector<RuntimeAssetChange> m_pendingAssetChanges;
};
static auto DataSystems = DataSystem::GetInstance();