This commit is contained in:
ouczbs 2024-07-11 06:37:28 +08:00
parent e555a6e709
commit 7ef0bfad0e
20 changed files with 134 additions and 60 deletions

View File

@ -6,9 +6,9 @@ metadatas:
__class__: engineapi::Shader
__data__:
mVert:
guid: 9419e2a5-ddc4-414f-aa76-d08e9b162492
guid: 020486aa-8987-4bd1-9de9-eeb7ab82c437
mFrag:
guid: eb1c9b43-a86b-40cb-9b3d-a3296d168c70
guid: a4064a70-89d5-4d8f-b3c3-6486dcf786c0
- guid: 7a01231c-c35d-4b74-b20f-4ca6823995d9
name: ""
t_hash: engineapi::Asset
@ -17,3 +17,7 @@ metadatas:
__data__:
mShader:
guid: 0a2ef3e8-db70-4d3f-94b1-09f9f92519cd
includes:
- /engine/assets/asset/mesh1.asset
- /engine/assets/shader/simple.frag
- /engine/assets/shader/simple.vert

View File

@ -1,10 +1,10 @@
/engine/assets/shader/simple.vert:
- 9419e2a5-ddc4-414f-aa76-d08e9b162492
- 020486aa-8987-4bd1-9de9-eeb7ab82c437
/engine/assets/asset/mesh1.asset:
- 0a2ef3e8-db70-4d3f-94b1-09f9f92519cd
- 7a01231c-c35d-4b74-b20f-4ca6823995d9
/engine/assets/shader/simple.frag:
- eb1c9b43-a86b-40cb-9b3d-a3296d168c70
- 0a2ef3e8-db70-4d3f-94b1-09f9f92519cd
/engine/assets/models/cube.obj:
- 619d2750-cedc-40cc-8781-fbdd116ded89
- 6c60e6b2-2ae6-4508-8117-8e797b9ac4bd
- 3f6a5afc-2f21-47c4-86ba-9ddb9852d8f4
- b91ca918-6b3c-4647-8773-d93d2807cb98
/engine/assets/shader/simple.frag:
- a4064a70-89d5-4d8f-b3c3-6486dcf786c0

View File

@ -1,9 +1,9 @@
metadatas:
- guid: 6c60e6b2-2ae6-4508-8117-8e797b9ac4bd
- guid: 3f6a5afc-2f21-47c4-86ba-9ddb9852d8f4
name: ""
t_hash: engineapi::Model
meta: ~
- guid: 619d2750-cedc-40cc-8781-fbdd116ded89
- guid: b91ca918-6b3c-4647-8773-d93d2807cb98
name: defaultobject
t_hash: engineapi::Asset
meta:
@ -11,3 +11,5 @@ metadatas:
__data__:
mMaterial:
guid: 7a01231c-c35d-4b74-b20f-4ca6823995d9
includes:
- /engine/assets/asset/mesh1.asset

View File

@ -1,5 +1,6 @@
metadatas:
- guid: eb1c9b43-a86b-40cb-9b3d-a3296d168c70
- guid: a4064a70-89d5-4d8f-b3c3-6486dcf786c0
name: ""
t_hash: engineapi::ShaderProgram
metadata: ""
meta: ~
includes: ~

View File

@ -1,5 +1,6 @@
metadatas:
- guid: 9419e2a5-ddc4-414f-aa76-d08e9b162492
- guid: 020486aa-8987-4bd1-9de9-eeb7ab82c437
name: ""
t_hash: engineapi::ShaderProgram
metadata: ""
meta: ~
includes: ~

View File

@ -6,11 +6,37 @@
#include "object/loader/assimp_loader.h"
#include "yaml/yaml.h"
namespace engineapi {
void FindIncludes(MetaBundle& bundle, Asset* asset) {
auto fieldList = asset->meta->GetFields(refl::FIND_ALL_MEMBER, FName(""));
refl::Any any(asset, asset->meta);
auto cls = &refl::TypeInfo<RscHandleBase>::StaticClass;
for (auto field : fieldList) {
if (field.type == cls) {
RscHandleBase* base = any.Member(field).CastTo<RscHandleBase*>();
FileBlock* file = ResourceManager::GetSingleton().GetResourceFile(base->guid);
if (file) {
bundle.includes.push_back(file->path);
}
}
}
}
MetaBundle ResourceManager::GetVisitMeta(const ResourceBundle& bundle)
{
MetaBundle new_meta = MetaBundle{};
for (auto& elem : bundle.GetAll())
std::visit([&](auto& handle) { new_meta.Add(handle); }, elem);
std::visit([&](auto& handle) {
using T = std::decay_t<decltype(*handle)>;
new_meta.Add(handle);
if constexpr (std::is_same_v<T, Asset>) {
FindIncludes(new_meta, &*handle);
}
}, elem);
auto& v = new_meta.includes;
if (v.size() > 1) {
std::sort(v.begin(), v.end()); // 首先排序
auto end_unique = std::unique(v.begin(), v.end()); // 去除重复元素
v.erase(end_unique, v.end());
}
return new_meta;
}
void Asset::__Init__()

View File

@ -3,8 +3,6 @@
#include "yaml/yaml.h"
#include <fstream>
#include "file_handle.h"
#include "render/asset/material.h"
namespace engineapi {
void AssetLoader::Init() {
ResourceManager::GetSingleton().RegisterLoader<AssetLoader>(".asset");
@ -16,22 +14,6 @@ namespace engineapi {
if (!meta.meta)
continue;
auto rsc = ResourceManager::GetSingleton().LoadFromMeta<Asset>(meta.guid, meta);
if (meta.meta.cls == &refl::TypeInfo<Shader>::StaticClass) {
Shader* asset = (Shader*)& *rsc;
Guid g1 = asset->GetGuid();
Guid g2 = meta.guid;
bool isame = g1 == g2;
g1 = meta.guid;
g2 = asset->GetGuid();
}
else if (meta.meta.cls == &refl::TypeInfo<Material>::StaticClass) {
Material* asset = (Material*)&*rsc;
Guid g1 = asset->GetGuid();
Guid g2 = meta.guid;
bool isame = g1 == g2;
g1 = meta.guid;
g2 = asset->GetGuid();
}
bundle.Add(rsc);
}
return bundle;

View File

@ -3,9 +3,18 @@
namespace engineapi
{
const SerializedMeta* MetaBundle::FetchMeta(const Guid& guid) const
{
for (auto& elem : metadatas)
{
if (elem.guid == guid)
return &elem;
}
return nullptr;
}
bool MetaBundle::operator==(const MetaBundle& other)const
{
return metadatas == other.metadatas;
return metadatas == other.metadatas && includes == other.includes;
}
bool MetaBundle::operator!=(const MetaBundle& other)const
{

View File

@ -11,7 +11,7 @@ namespace engineapi
UPROPERTY({})
string name;
UPROPERTY({})
string t_hash{};
string t_hash;
UPROPERTY({})
refl::Any meta;
bool operator==(const SerializedMeta& other)const{
@ -23,9 +23,11 @@ namespace engineapi
{
UPROPERTY({})
vector<SerializedMeta> metadatas;
UPROPERTY({})
vector<string> includes;
MetaBundle() = default;
const SerializedMeta* FetchMeta(const Guid& guid) const;
template<typename T>
const SerializedMeta* FetchMeta() const;
template<typename T>

View File

@ -21,7 +21,7 @@ namespace engineapi
};
//占位符浪费了四个字节
struct FileBlock {
uint32_t flag;
uint32_t flag{0};
string path;
string addr;
operator bool() {

View File

@ -19,6 +19,7 @@ namespace engineapi {
RscHandle<Res> mHandle;
std::string mName;
friend class RscHandle<Res>;
friend class ResourceManager;
};
using Resources = std::tuple<
class ShaderProgram

View File

@ -8,7 +8,7 @@ namespace engineapi
struct RscHandleBase {
UPROPERTY({})
Guid guid;
void* res;
void* res{nullptr};
};
template<typename Res>
struct RscHandle : public RscHandleBase
@ -17,7 +17,7 @@ namespace engineapi
constexpr RscHandle() noexcept = default;
template<typename T>
constexpr RscHandle(const RscHandle<T>& other) noexcept : RscHandleBase(other.guid, other.res) {};
constexpr RscHandle(const Guid& guid, Res* res) noexcept : RscHandleBase(guid, res) { ((Resource<Res>*)res)->mHandle = *this; }
constexpr RscHandle(const Guid& guid, Res* res) noexcept : RscHandleBase(guid, res) {}
void Init();
void Clear() { res = nullptr; };
Res* operator->() { if (!res && guid) Init(); return (Res*)res; }

View File

@ -31,16 +31,14 @@ namespace engineapi {
return nullptr;
return itr->second;
}
ResourceBundle& ResourceManager::Load(const PackagePath& path, bool reload_resource)
ResourceBundle& ResourceManager::Load(const PackagePath& path, bool reload_resource, int deep)
{
NameID name = path();
auto it = mFileBlock.find(name);
if (it != mFileBlock.end()) {
if (!reload_resource) {
return it->second.bundle;
}
}
auto& res = mFileBlock[name];
if (deep > 5 || (!reload_resource && res && it != mFileBlock.end())) {
return res.bundle;
}
Name ext = path.GetExtension();
IFileLoader* loader = GetLoader(ext);
MetaBundle meta = GetMeta(path);
@ -54,13 +52,18 @@ namespace engineapi {
mResourceFile[handle.guid] = FileManager::FindPathBlock(path);
}, elem);
}
if (is_dirty_meta || res.is_dirty) {
if (is_dirty_meta || res.IsDirty()) {
mDirtyBlock.push_back(&res);
}
res.path = path.SafePath();
res.bundle = bundle;
res.is_meta_dirty = is_dirty_meta;
res.Loaded(true).MetaDirty(is_dirty_meta);
res.bundle = bundle;
if (!new_meta.includes.empty()) {
for (auto include : new_meta.includes) {
Load(include, false, deep + 1);
}
}
return res.bundle;
}
@ -97,13 +100,13 @@ namespace engineapi {
void ResourceManager::SaveDirtyFile()
{
for (auto block : mDirtyBlock) {
if (block->is_meta_dirty) {
block->is_meta_dirty = false;
if (block->IsMetaDirty()) {
block->MetaDirty(false);
MetaBundle new_meta = GetVisitMeta(block->bundle);
SaveMeta(block->path, new_meta);
}
if (block->is_dirty) {
block->is_dirty = false;
if (block->IsDirty()) {
block->Dirty(false);
auto loader = GetLoader(block->path.GetExtension());
loader->SaveFile(block->path, block->bundle);
}

View File

@ -17,6 +17,22 @@ namespace engineapi {
FileDoesNotExist,
FailedToLoadResource,
};
struct ResourceFileFlag{
enum Value : uint32_t {
File_Default = 0,
File_Dirty = 1 << 0,
File_Meta_Dirty = 1 << 1,
File_Loaded = 1 << 2,
};
Value val{ File_Default };
// 构造函数和操作符重载,使类实例像整数一样使用
ResourceFileFlag(Value v = File_Default) : val(v) {}
operator uint32_t() const { return val; }
ResourceFileFlag& operator=(Value v) {
val = v;
return *this;
}
};
template<typename Res>
using LoadResult = result<Res, ResourceLoadError>;
class ResourceManager : public ISingleton<ResourceManager>
@ -69,7 +85,7 @@ namespace engineapi {
template<typename Res>
RscHandle<Res> Load(const PackagePath& path, bool reload_resource = true);
ResourceBundle& Load(const PackagePath& path, bool reload_resource = true);
ResourceBundle& Load(const PackagePath& path, bool reload_resource = true, int deep = 0);
MetaBundle GetMeta(const PackagePath& path);
MetaBundle GetVisitMeta(const ResourceBundle& bundle);
void SaveMeta(const PackagePath& path, const MetaBundle& bundle);
@ -86,14 +102,29 @@ namespace engineapi {
{
ResourceBundle bundle;
PackagePath path;
bool is_dirty{ false };
bool is_meta_dirty{ false };
uint32_t flag{0};
ResourceFileBlock& SetFlag(bool is, ResourceFileFlag _flag) {
if (is)
flag |= _flag;
else
flag &= ~_flag;
return *this;
}
operator bool() {
return IsLoaded();
}
ResourceFileBlock& Loaded(bool is) { return SetFlag(is, ResourceFileFlag::File_Loaded); }
ResourceFileBlock& Dirty(bool is) { return SetFlag(is, ResourceFileFlag::File_Dirty); }
ResourceFileBlock& MetaDirty(bool is) { return SetFlag(is, ResourceFileFlag::File_Meta_Dirty); }
bool IsLoaded() { return flag & ResourceFileFlag::File_Loaded; }
bool IsDirty() { return flag & ResourceFileFlag::File_Dirty; }
bool IsMetaDirty() { return flag & ResourceFileFlag::File_Meta_Dirty; }
};
template<typename R>
struct ResourceManager::ResourceBlock
{
R* resource;
ResourceFileBlock* file;
R* resource{nullptr};
ResourceFileBlock* file{ nullptr };
bool valid() const { return resource; }
};
}

View File

@ -55,6 +55,7 @@ namespace engineapi {
}
else {
control_block.resource = res;
res->mHandle.guid = guid;
}
res->Name(meta.name);
return RscHandle<Res>{guid, res};
@ -66,6 +67,7 @@ namespace engineapi {
auto& control_block = table[guid]; // don't care just replace
// attempt to put on other thread
Res* res = new Res(std::forward<Args>(args)...);
res->mHandle.guid = guid;
control_block.resource = res;
return RscHandle<Res>{guid, res};
}

View File

@ -131,7 +131,7 @@ namespace engineapi {
RscHandle<Mesh> asset = m ? ResourceManager::GetSingleton().LoadEmplaceResource<Mesh>(m->guid, vertices, indices)
: ResourceManager::GetSingleton().LoadEmplaceResource<Mesh>(vertices, indices);
if (m && m->meta) {
void* ptr = &*asset;
Mesh* ptr = &*asset;
m->meta.MoveTo(ptr);
}
asset->Name(mesh->mName.C_Str());

View File

@ -11,6 +11,9 @@ namespace engineapi {
public:
Material();
~Material();
void BeginLoad() {
mShader->BeginLoad();
}
RscHandle<Shader> GetShader() {
return mShader;
}

View File

@ -6,6 +6,7 @@ namespace engineapi {
}
void Mesh::BeginLoad()
{
mMaterial->BeginLoad();
RenderAPI::GetSingletonPtr()->SetStaticMesh(*this);
}
}

View File

@ -1,4 +1,5 @@
#include "shader.h"
#include "render/renderapi.h"
namespace engineapi {
Shader::Shader() : Asset(&refl::TypeInfo<Shader>::StaticClass)
{
@ -7,4 +8,8 @@ namespace engineapi {
Shader::~Shader()
{
}
void Shader::BeginLoad()
{
RenderAPI::GetSingletonPtr()->LoadShader(*this);
}
}

View File

@ -5,7 +5,7 @@ namespace engineapi {
class Shader : public Asset {
private:
REFL_FRIEND(Shader)
uint32_t mId;
uint32_t mId{0};
ShaderInfo mInfo;
UPROPERTY()
RscHandle<ShaderProgram> mVert;
@ -15,6 +15,7 @@ namespace engineapi {
public:
Shader();
~Shader();
void BeginLoad();
uint32_t& GetID() {
return mId;
}