rebuild asset manager
This commit is contained in:
parent
bce38fe13e
commit
0cdc1d1948
@ -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:
|
||||||
|
|||||||
@ -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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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);
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
75
engine/src/engine/asset/file_manager.cpp
Normal file
75
engine/src/engine/asset/file_manager.cpp
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
27
engine/src/engine/asset/file_manager.h
Normal file
27
engine/src/engine/asset/file_manager.h
Normal 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);
|
||||||
|
};
|
||||||
|
}
|
||||||
12
engine/src/engine/asset/package_path.cpp
Normal file
12
engine/src/engine/asset/package_path.cpp
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
48
engine/src/engine/asset/package_path.h
Normal file
48
engine/src/engine/asset/package_path.h
Normal 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;
|
||||||
|
};
|
||||||
|
}
|
||||||
@ -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());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -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);
|
||||||
|
|||||||
@ -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();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|||||||
@ -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)
|
||||||
|
|||||||
@ -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);
|
||||||
|
|
||||||
// 检查异常
|
// 检查异常
|
||||||
|
|||||||
@ -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");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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;
|
||||||
|
|
||||||
|
|||||||
@ -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) {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user