rebuild asset manager

This commit is contained in:
ouczbs 2024-05-20 00:02:58 +08:00
parent bce38fe13e
commit 0cdc1d1948
16 changed files with 187 additions and 101 deletions

View File

@ -1,17 +1,12 @@
#pragma once #pragma once
#include <cstdint> #include <cstdint>
#include <string>
#include <vector> #include <vector>
#include <map> #include <map>
#include "zstd/table.h" #include "package_path.h"
#include "UTemplate/Type.hpp"
namespace engineapi namespace engineapi
{ {
using std::string;
using std::vector; using std::vector;
using std::map; using std::map;
using zstd::table;
using Ubpa::Name;
class Asset { class Asset {
public: public:
friend class AssetManager; friend class AssetManager;
@ -26,9 +21,9 @@ namespace engineapi
}; };
protected: protected:
uint32_t mFlags; uint32_t mFlags;
string mName; string_view mName;
public: public:
Asset(string name, uint32_t flags):mName(name),mFlags(flags) {}; Asset(string_view name, uint32_t flags):mName(name),mFlags(flags) {};
~Asset(); ~Asset();
virtual void BeginLoad() { virtual void BeginLoad() {
mFlags |= ASSET_LOADING_FLAG; mFlags |= ASSET_LOADING_FLAG;
@ -37,7 +32,7 @@ namespace engineapi
mFlags &= ~ASSET_LOADING_FLAG; mFlags &= ~ASSET_LOADING_FLAG;
mFlags |= ASSET_LOADED_FLAG; mFlags |= ASSET_LOADED_FLAG;
}; };
string& GetName() { string_view& GetName() {
return mName; return mName;
} }
public: public:

View File

@ -10,78 +10,16 @@ namespace engineapi {
} }
void AssetManager::ClearAsset(Asset* asset) void AssetManager::ClearAsset(Asset* asset)
{ {
auto it = mAssetMap.find(asset->mName); auto it = AssetMap.find(asset->mName);
if (!asset->IsShared()) { if (!asset->IsShared()) {
delete asset; delete asset;
} }
if (it != mAssetMap.end()) { if (it != AssetMap.end()) {
it->second.count--; it->second.count--;
if (it->second.count < 1) { if (it->second.count < 1) {
delete it->second.asset; delete it->second.asset;
mAssetMap.erase(it); AssetMap.erase(it);
} }
} }
} }
string AssetManager::LoadTextFile(const string& path)
{
string text = "";
ifstream file;
file.exceptions(ifstream::failbit | ifstream::badbit);
try
{
file.open(path);
stringstream stream;
stream << file.rdbuf();
file.close();
text = stream.str();
}
catch (ifstream::failure e)
{
zlog::info("Failed to load text file: {}", path);
}
return text;
}
vector<char> AssetManager::LoadBinaryFile(const string& path)
{
// ate:在文件末尾开始读取,从文件末尾开始读取的优点是我们可以使用读取位置来确定文件的大小并分配缓冲区
ifstream file(path, std::ios::ate | std::ios::binary);
if (!file.is_open()) {
zlog::info("Failed to load binary file: {}", path);
return vector<char>();
}
// 使用读取位置来确定文件的大小并分配缓冲区
size_t fileSize = (size_t)file.tellg();
vector<char> data(fileSize);
// 返回文件开头,真正读取内容
file.seekg(0);
file.read(data.data(), fileSize);
file.close();
return data;
}
json AssetManager::LoadJsonFile(const string& path)
{
std::ifstream f(path);
if (!f.is_open())
{
zlog::error("Load asset failed: {}", path);
return NULL;
}
json data;
try
{
data = json::parse(f);
}
catch (json::exception& e)
{
zlog::error("Asset format error: {}", path);
string msg = e.what();
zlog::error("Error detail: {}", msg);
}
return data;
}
} }

View File

@ -1,12 +1,6 @@
#pragma once #pragma once
#include <filesystem>
#include <fstream>
#include <functional>
#include <sstream>
#include "asset.h" #include "asset.h"
#include "singleton.h" #include "singleton.h"
#include <nlohmann/json.hpp>
using json = nlohmann::json;
namespace engineapi namespace engineapi
{ {
class AssetManager : public ISingleton<AssetManager> class AssetManager : public ISingleton<AssetManager>
@ -19,9 +13,6 @@ namespace engineapi
} }
}; };
private:
map<const string, AssetWrap> mAssetMap;
public: public:
void Init() override; void Init() override;
void Shutdown() override; void Shutdown() override;
@ -30,8 +21,9 @@ namespace engineapi
template<typename TAsset> template<typename TAsset>
TAsset* LoadAsset(const string& name, uint32_t flags) TAsset* LoadAsset(const string& name, uint32_t flags)
{ {
auto it = mAssetMap.find(name); string_view view = PackagePath::StringView(name);
bool isFind = it != mAssetMap.end(); auto it = AssetMap.find(view);
bool isFind = it != AssetMap.end();
if (isFind) { if (isFind) {
it->second.count++; it->second.count++;
if (it->second.asset->IsShared()) { if (it->second.asset->IsShared()) {
@ -45,16 +37,14 @@ namespace engineapi
} }
TAsset* asset = new TAsset(name, flags); TAsset* asset = new TAsset(name, flags);
if (!isFind && (asset->IsShared() || asset->IsCopyed())) { if (!isFind && (asset->IsShared() || asset->IsCopyed())) {
mAssetMap.emplace(name, asset); AssetMap.emplace(name, asset);
} }
asset->BeginLoad(); asset->BeginLoad();
return asset; return asset;
} }
AssetManager() = default; AssetManager() = default;
public: private:
static string LoadTextFile(const string& path); inline static table<string_view, AssetWrap> AssetMap;
static vector<char> LoadBinaryFile(const string& path);
static json LoadJsonFile(const string& path);
}; };
} }

View File

@ -0,0 +1,75 @@
#include "file_manager.h"
#include <fstream>
#include "zlog.h"
using namespace std;
namespace engineapi {
void FileManager::Init()
{
}
void FileManager::Shutdown()
{
}
string FileManager::LoadTextFile(const string& path)
{
string text = "";
ifstream file;
file.exceptions(ifstream::failbit | ifstream::badbit);
try
{
file.open(path);
stringstream stream;
stream << file.rdbuf();
file.close();
text = stream.str();
}
catch (ifstream::failure e)
{
zlog::info("Failed to load text file: {}", path);
}
return text;
}
vector<char> FileManager::LoadBinaryFile(const string& path)
{
// ate:在文件末尾开始读取,从文件末尾开始读取的优点是我们可以使用读取位置来确定文件的大小并分配缓冲区
ifstream file(path, std::ios::ate | std::ios::binary);
if (!file.is_open()) {
zlog::info("Failed to load binary file: {}", path);
return vector<char>();
}
// 使用读取位置来确定文件的大小并分配缓冲区
size_t fileSize = (size_t)file.tellg();
vector<char> data(fileSize);
// 返回文件开头,真正读取内容
file.seekg(0);
file.read(data.data(), fileSize);
file.close();
return data;
}
json FileManager::LoadJsonFile(const string& path)
{
std::ifstream f(path);
if (!f.is_open())
{
zlog::error("Load asset failed: {}", path);
return NULL;
}
json data;
try
{
data = json::parse(f);
}
catch (json::exception& e)
{
zlog::error("Asset format error: {}", path);
string msg = e.what();
zlog::error("Error detail: {}", msg);
}
return data;
}
}

View File

@ -0,0 +1,27 @@
#pragma once
#include "package_path.h".
#include "singleton.h"
#include <nlohmann/json.hpp>
namespace engineapi
{
using json = nlohmann::json;
class FileManager : public ISingleton<FileManager>
{
public:
void Init() override;
void Shutdown() override;
public:
static string FindMount(NameID id) {
auto it = MountMap.find(id);
if (it == MountMap.end()) {
return it->second;
}
return "";
}
inline static table<NameID, string> MountMap;
public:
static string LoadTextFile(const string& path);
static vector<char> LoadBinaryFile(const string& path);
static json LoadJsonFile(const string& path);
};
}

View File

@ -0,0 +1,12 @@
#include "package_path.h"
#include "file_manager.h"
namespace engineapi {
string PackagePath::AbsolutePath()
{
if (CheckPackage()) {
return FileManager::FindMount(name) + string(path);
}
return string(path);
}
}

View File

@ -0,0 +1,48 @@
#pragma once
#include <string>
#include "zstd/table.h"
#include "UTemplate/Type.hpp"
namespace engineapi
{
using std::string;
using std::string_view;
using zstd::table;
using Ubpa::Name;
using Ubpa::NameID;
struct PackagePath {
string_view name;
string_view path;
PackagePath(const string_view& path) : path(path) {}
PackagePath(const string& path) : path(StringView(path)) {};
PackagePath(const string&& path) : path(path) {}
bool CheckPackage() {
if (name.empty()) {
return true;
}
if (path[0] == '/') {
size_t pos = path.find('/', 1);
if (pos != string::npos) {
name = path.substr(1, pos - 1);
path = path.substr(pos);
return true;
}
}
return false;
}
string AbsolutePath();
static string AbsolutePath(string_view path) {
return PackagePath(path).AbsolutePath();
};
static string_view StringView(const string& str) {
NameID id = NameID(str);
auto it = StringTable.find(id);
if (it == StringTable.end()) {
it = StringTable.emplace_hint(it, id, str);
}
return it->second;
}
private:
inline static table<NameID, string> StringTable;
};
}

View File

@ -38,7 +38,7 @@ namespace engineapi {
} }
else else
{ {
zlog::info("Attempt to delete a nonexistent scene: {}", name); zlog::info("Attempt to delete a nonexistent scene: {}", name.GetView());
} }
} }

View File

@ -3,7 +3,7 @@
#include "asset/asset_manager.h" #include "asset/asset_manager.h"
#include "../renderapi.h" #include "../renderapi.h"
namespace engineapi { namespace engineapi {
Material::Material(string name, uint32_t flags) Material::Material(string_view name, uint32_t flags)
:Asset(name, flags) :Asset(name, flags)
{ {
mShader = new Shader(name, flags); mShader = new Shader(name, flags);

View File

@ -8,7 +8,7 @@ namespace engineapi {
uint32_t mId{0}; uint32_t mId{0};
Shader* mShader; Shader* mShader;
public: public:
Material(string name, uint32_t flags); Material(string_view name, uint32_t flags);
~Material(); ~Material();
}; };

View File

@ -14,7 +14,7 @@ namespace engineapi {
public: public:
template<typename T> template<typename T>
requires std::is_base_of_v<Vertex, T> requires std::is_base_of_v<Vertex, T>
Mesh(string name, uint32_t flags,vector<T>& vertices, vector<uint32_t>& indices) Mesh(string_view name, uint32_t flags,vector<T>& vertices, vector<uint32_t>& indices)
:Asset(name, flags) :Asset(name, flags)
, mVertices(vertices) , mVertices(vertices)
, mIndices(indices) , mIndices(indices)

View File

@ -10,7 +10,7 @@ namespace engineapi {
Asset::BeginLoad(); Asset::BeginLoad();
// 用ASSIMP加载模型文件 // 用ASSIMP加载模型文件
Assimp::Importer importer; Assimp::Importer importer;
const aiScene* scene = importer.ReadFile(mName, aiProcess_Triangulate | aiProcess_FlipUVs | aiProcess_CalcTangentSpace const aiScene* scene = importer.ReadFile(PackagePath::AbsolutePath(mName), aiProcess_Triangulate | aiProcess_FlipUVs | aiProcess_CalcTangentSpace
| aiProcess_FixInfacingNormals | aiProcess_FlipWindingOrder | aiProcess_LimitBoneWeights); | aiProcess_FixInfacingNormals | aiProcess_FlipWindingOrder | aiProcess_LimitBoneWeights);
// 检查异常 // 检查异常

View File

@ -2,7 +2,7 @@
#include "asset/asset_manager.h" #include "asset/asset_manager.h"
#include "../renderapi.h" #include "../renderapi.h"
namespace engineapi { namespace engineapi {
Shader::Shader(string name, uint32_t flags) Shader::Shader(string_view name, uint32_t flags)
:Asset(name, flags) :Asset(name, flags)
{ {
BeginLoad(); BeginLoad();
@ -12,17 +12,17 @@ namespace engineapi {
} }
void Shader::BeginLoad() void Shader::BeginLoad()
{ {
json data = AssetManager::LoadJsonFile(mName + ".json"); json data = AssetManager::LoadJsonFile(string(mName) + ".json");
RenderAPI::GetSingletonPtr()->LoadShader(this); RenderAPI::GetSingletonPtr()->LoadShader(this);
//ShaderProperty //ShaderProperty
//mInfo.vertProperties.baseProperties.push_back //mInfo.vertProperties.baseProperties.push_back
} }
vector<char> Shader::GetVertData() vector<char> Shader::GetVertData()
{ {
return AssetManager::LoadBinaryFile(mName + ".vert.spv"); return AssetManager::LoadBinaryFile(string(mName) + ".vert.spv");
} }
vector<char> Shader::GetFragData() vector<char> Shader::GetFragData()
{ {
return AssetManager::LoadBinaryFile(mName + ".frag.spv"); return AssetManager::LoadBinaryFile(string(mName) + ".frag.spv");
} }
} }

View File

@ -7,7 +7,7 @@ namespace engineapi {
uint32_t mId; uint32_t mId;
ShaderInfo mInfo; ShaderInfo mInfo;
public: public:
Shader(string name, uint32_t flags); Shader(string_view name, uint32_t flags);
~Shader(); ~Shader();
void BeginLoad()override; void BeginLoad()override;

View File

@ -38,7 +38,7 @@ namespace vulkanapi {
#endif // Z_USE_GRAPHIC_DEBUG #endif // Z_USE_GRAPHIC_DEBUG
VkResult result = vkCreateDevice(mPhysical, &device_create_info, nullptr, &mPtr); VkResult result = vkCreateDevice(mPhysical, &device_create_info, nullptr, &mPtr);
if ((result != VK_SUCCESS) || (mPtr == VK_NULL_HANDLE)) { if ((result != VK_SUCCESS) || (mPtr == VK_NULL_HANDLE)) {
zlog::error("Could not create logical device. VkResult {}", result); zlog::error("Could not create logical device. VkResult {}", (int)result);
} }
volkLoadDevice(mPtr); volkLoadDevice(mPtr);
for (auto& queue : Creator.desiredQueues) { for (auto& queue : Creator.desiredQueues) {

View File

@ -1,3 +1,4 @@
add_repositories("local_repo F:\\xmake.repo")
add_rules("mode.debug", "mode.release") add_rules("mode.debug", "mode.release")
set_arch("x64") set_arch("x64")
set_languages("cxx20") set_languages("cxx20")