mirror of
https://github.com/zhenyan121/Cubed.git
synced 2026-08-08 17:57:02 +08:00
feat(render): add model ID system with concurrent lookup and namespace-based loading
- Extract `ModelID` and `Model` struct to new `model.hpp` - Replace `std::unordered_map` with `tbb::concurrent_hash_map` for thread safety - Add `get_model(ModelID)`, `get_model_id`, `get_model_name` methods - Parse model names in `namespace:name` format to construct asset paths - Update `load_model` to accept `string_view` and use ID-based management
This commit is contained in:
@@ -6,8 +6,6 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
namespace Cubed {
|
namespace Cubed {
|
||||||
|
|
||||||
using ModelID = uint32_t;
|
|
||||||
|
|
||||||
struct Position {
|
struct Position {
|
||||||
glm::vec3 value{0.0f};
|
glm::vec3 value{0.0f};
|
||||||
};
|
};
|
||||||
@@ -25,10 +23,6 @@ struct EntityInfo {
|
|||||||
std::string uuid;
|
std::string uuid;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Model {
|
|
||||||
ModelID id;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Health {
|
struct Health {
|
||||||
float hp = 20;
|
float hp = 20;
|
||||||
float max_hp = 20;
|
float max_hp = 20;
|
||||||
|
|||||||
7
include/Cubed/gameplay/model.hpp
Normal file
7
include/Cubed/gameplay/model.hpp
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
using ModelID = uint32_t;
|
||||||
|
struct Model {
|
||||||
|
ModelID id;
|
||||||
|
};
|
||||||
@@ -1,6 +1,9 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
#include "Cubed/gameplay/model.hpp"
|
||||||
#include "Cubed/render/model_node.hpp"
|
#include "Cubed/render/model_node.hpp"
|
||||||
#include "Cubed/tools/model_loader.hpp"
|
#include "Cubed/tools/model_loader.hpp"
|
||||||
|
|
||||||
|
#include <tbb/concurrent_hash_map.h>
|
||||||
namespace Cubed {
|
namespace Cubed {
|
||||||
class ModelManager {
|
class ModelManager {
|
||||||
public:
|
public:
|
||||||
@@ -11,11 +14,20 @@ public:
|
|||||||
ModelManager& operator=(ModelManager&&) = delete;
|
ModelManager& operator=(ModelManager&&) = delete;
|
||||||
~ModelManager();
|
~ModelManager();
|
||||||
const ModelNode& get_model(const std::string& model_name);
|
const ModelNode& get_model(const std::string& model_name);
|
||||||
|
const ModelNode& get_model(ModelID id);
|
||||||
|
ModelID get_model_id(const std::string& name);
|
||||||
|
const std::string& get_model_name(ModelID id);
|
||||||
void init();
|
void init();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ModelLoader m_loader;
|
ModelLoader m_loader;
|
||||||
std::unordered_map<std::string, ModelNode> m_models;
|
ModelID m_next = 0;
|
||||||
const ModelNode& load_model(const std::string& model_name);
|
using ModelMap = tbb::concurrent_hash_map<ModelID, ModelNode>;
|
||||||
|
using IDMap = tbb::concurrent_hash_map<std::string, ModelID>;
|
||||||
|
using NameMap = tbb::concurrent_hash_map<ModelID, std::string>;
|
||||||
|
ModelMap m_models;
|
||||||
|
IDMap m_id_map;
|
||||||
|
NameMap m_name_map;
|
||||||
|
const ModelNode& load_model(std::string_view model_name);
|
||||||
};
|
};
|
||||||
} // namespace Cubed
|
} // namespace Cubed
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
#include "Cubed/render/model_manager.hpp"
|
#include "Cubed/render/model_manager.hpp"
|
||||||
|
|
||||||
|
#include "Cubed/tools/cubed_assert.hpp"
|
||||||
#include "Cubed/tools/log.hpp"
|
#include "Cubed/tools/log.hpp"
|
||||||
namespace Cubed {
|
namespace Cubed {
|
||||||
|
|
||||||
@@ -12,21 +13,68 @@ void ModelManager::init() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const ModelNode& ModelManager::get_model(const std::string& model_name) {
|
const ModelNode& ModelManager::get_model(const std::string& model_name) {
|
||||||
auto it = m_models.find(model_name);
|
return get_model(get_model_id(model_name));
|
||||||
if (it == m_models.end()) {
|
|
||||||
return load_model(model_name);
|
|
||||||
}
|
|
||||||
return it->second;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const ModelNode& ModelManager::load_model(const std::string& model_name) {
|
const ModelNode& ModelManager::get_model(ModelID id) {
|
||||||
std::string path = ASSETS_PATH + model_name;
|
|
||||||
auto model = m_loader.load(path);
|
ModelMap::const_accessor cacc;
|
||||||
auto [it, instert] = m_models.try_emplace(model_name, std::move(model));
|
if (!m_models.find(cacc, id)) {
|
||||||
if (!instert) {
|
return cacc->second;
|
||||||
Logger::error("Model Key {} already exist!", model_name);
|
|
||||||
}
|
}
|
||||||
return it->second;
|
return load_model(get_model_name(id));
|
||||||
|
}
|
||||||
|
|
||||||
|
const ModelNode& get_model(const std::string& model_name);
|
||||||
|
const ModelNode& get_model(ModelID id);
|
||||||
|
ModelID ModelManager::get_model_id(const std::string& name) {
|
||||||
|
IDMap::const_accessor cacc;
|
||||||
|
if (m_id_map.find(cacc, name)) {
|
||||||
|
return cacc->second;
|
||||||
|
}
|
||||||
|
ASSERT_MSG(false, std::format("ModelManager: Can't find {}", name));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string& ModelManager::get_model_name(ModelID id) {
|
||||||
|
NameMap::const_accessor cacc;
|
||||||
|
if (m_name_map.find(cacc, id)) {
|
||||||
|
return cacc->second;
|
||||||
|
}
|
||||||
|
ASSERT_MSG(false, std::format("ModelManager: Can't find {}", id));
|
||||||
|
static std::string n = "";
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
const ModelNode& ModelManager::load_model(std::string_view model_name) {
|
||||||
|
auto p = model_name.find(':');
|
||||||
|
if (p == std::string::npos) {
|
||||||
|
Logger::error("Can't Parse Model name {}", model_name);
|
||||||
|
ASSERT(false);
|
||||||
|
}
|
||||||
|
auto name = model_name.substr(p + 1);
|
||||||
|
auto space = model_name.substr(0, p);
|
||||||
|
if (name.empty()) {
|
||||||
|
Logger::error("Can't Parse Model name {}", model_name);
|
||||||
|
ASSERT(false);
|
||||||
|
}
|
||||||
|
std::string path;
|
||||||
|
if (space == "cubed") {
|
||||||
|
path = std::format("{}model/creature/{}", ASSETS_PATH, name);
|
||||||
|
} else {
|
||||||
|
path = std::format("./{}/model/creature/{}", space, name);
|
||||||
|
}
|
||||||
|
auto model = m_loader.load(path);
|
||||||
|
ModelMap::accessor acc;
|
||||||
|
if (m_models.insert(acc, m_next++)) {
|
||||||
|
acc->second = std::move(model);
|
||||||
|
} else {
|
||||||
|
Logger::error("Can't Insert Model {}", model_name);
|
||||||
|
ASSERT(false);
|
||||||
|
}
|
||||||
|
m_id_map.emplace(model_name, acc->first);
|
||||||
|
m_name_map.emplace(acc->first, model_name);
|
||||||
|
return acc->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Cubed
|
} // namespace Cubed
|
||||||
Reference in New Issue
Block a user