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

View File

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

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
{
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 "../renderapi.h"
namespace engineapi {
Material::Material(string name, uint32_t flags)
Material::Material(string_view name, uint32_t flags)
:Asset(name, flags)
{
mShader = new Shader(name, flags);

View File

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

View File

@ -14,7 +14,7 @@ namespace engineapi {
public:
template<typename 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)
, mVertices(vertices)
, mIndices(indices)

View File

@ -10,7 +10,7 @@ namespace engineapi {
Asset::BeginLoad();
// 用ASSIMP加载模型文件
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);
// 检查异常

View File

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

View File

@ -38,7 +38,7 @@ namespace vulkanapi {
#endif // Z_USE_GRAPHIC_DEBUG
VkResult result = vkCreateDevice(mPhysical, &device_create_info, nullptr, &mPtr);
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);
for (auto& queue : Creator.desiredQueues) {

View File

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