Fix model manager. It's version stable for model manager
This commit is contained in:
@@ -1,5 +1,7 @@
|
|||||||
#include "ModelManager.hpp"
|
#include "ModelManager.hpp"
|
||||||
|
|
||||||
|
#include "Log/Log.hpp"
|
||||||
|
|
||||||
ModelManager::StaticModel::StaticModel(const std::vector<Voxel>& voxels, std::string name):
|
ModelManager::StaticModel::StaticModel(const std::vector<Voxel>& voxels, std::string name):
|
||||||
name_(std::move(name)),
|
name_(std::move(name)),
|
||||||
voxels_(voxels)
|
voxels_(voxels)
|
||||||
@@ -30,6 +32,10 @@ ModelManager::StaticModel::~StaticModel()
|
|||||||
OnDestroy.Call(name_);
|
OnDestroy.Call(name_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ModelManager::owner_counter::owner_counter(const owner_counter& other) : counter(other.counter.load()), model(other.model)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
unsigned int ModelManager::FNV1aHash(const char* buf)
|
unsigned int ModelManager::FNV1aHash(const char* buf)
|
||||||
{
|
{
|
||||||
unsigned int h_val = 0x811c9dc5;
|
unsigned int h_val = 0x811c9dc5;
|
||||||
@@ -45,29 +51,57 @@ unsigned int ModelManager::FNV1aHash(const char* buf)
|
|||||||
|
|
||||||
void ModelManager::OnDestroySometimeModelCaller(const std::string& name)
|
void ModelManager::OnDestroySometimeModelCaller(const std::string& name)
|
||||||
{
|
{
|
||||||
|
Log("Free model: " + name);
|
||||||
OnDestroySometimeModel.Call(name);
|
OnDestroySometimeModel.Call(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
ModelManager::~ModelManager()
|
ModelManager::~ModelManager()
|
||||||
{
|
{
|
||||||
for (const auto& [it, model] : models)
|
for (const auto& [it, counter] : models)
|
||||||
{
|
{
|
||||||
model->OnDestroy.unbind(this, &ModelManager::OnDestroySometimeModelCaller);
|
counter.model->OnDestroy.unbind(this, &ModelManager::OnDestroySometimeModelCaller);
|
||||||
}
|
}
|
||||||
models.clear();
|
models.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<ModelManager::StaticModel> ModelManager::LoadModel(const std::string& name)
|
ModelManager::StaticModel* ModelManager::LoadModel(const std::string& name)
|
||||||
{
|
{
|
||||||
|
if (name.empty())
|
||||||
|
return nullptr;
|
||||||
unsigned int hash = FNV1aHash(name.c_str());
|
unsigned int hash = FNV1aHash(name.c_str());
|
||||||
auto model = models.find(hash);
|
auto counter = models.find(hash);
|
||||||
if (model != models.cend())
|
if (counter != models.cend())
|
||||||
return model->second;
|
{
|
||||||
|
++counter->second.counter;
|
||||||
|
return counter->second.model;
|
||||||
|
}
|
||||||
|
|
||||||
|
Log("Load new model: " + name);
|
||||||
|
|
||||||
std::vector<Voxel> model_data;
|
std::vector<Voxel> model_data;
|
||||||
// Load model_data
|
// Load model_data
|
||||||
auto newModel = std::make_shared<StaticModel>(model_data, name);
|
owner_counter new_counter;
|
||||||
newModel->OnDestroy.bind(this, &ModelManager::OnDestroySometimeModelCaller);
|
new_counter.counter.store(1);
|
||||||
models[hash] = newModel;
|
new_counter.model = new StaticModel(model_data, name);
|
||||||
return models[hash];
|
new_counter.model->OnDestroy.bind(this, &ModelManager::OnDestroySometimeModelCaller);
|
||||||
|
models.try_emplace(hash, new_counter);
|
||||||
|
|
||||||
|
return new_counter.model;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ModelManager::FreeModel(const std::string& name)
|
||||||
|
{
|
||||||
|
if (name.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
unsigned int hash = FNV1aHash(name.c_str());
|
||||||
|
auto counter = models.find(hash);
|
||||||
|
--counter->second.counter;
|
||||||
|
|
||||||
|
StaticModel* model = counter->second.model;
|
||||||
|
if (counter->second.counter.load() == 0)
|
||||||
|
{
|
||||||
|
models.erase(hash);
|
||||||
|
delete model;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,9 +30,18 @@ public:
|
|||||||
const std::string& GetName() const { return name_; }
|
const std::string& GetName() const { return name_; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct owner_counter
|
||||||
|
{
|
||||||
|
std::atomic_ullong counter;
|
||||||
|
StaticModel* model;
|
||||||
|
|
||||||
|
owner_counter() = default;
|
||||||
|
owner_counter(const owner_counter& other);
|
||||||
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
std::unordered_map<unsigned int, std::shared_ptr<StaticModel>> models;
|
std::unordered_map<unsigned int, owner_counter> models;
|
||||||
|
|
||||||
static unsigned int FNV1aHash (const char *buf);
|
static unsigned int FNV1aHash (const char *buf);
|
||||||
|
|
||||||
@@ -43,5 +52,6 @@ public:
|
|||||||
|
|
||||||
~ModelManager();
|
~ModelManager();
|
||||||
|
|
||||||
std::shared_ptr<StaticModel> LoadModel(const std::string& name);
|
StaticModel* LoadModel(const std::string& name);
|
||||||
|
void FreeModel(const std::string& name);
|
||||||
};
|
};
|
||||||
@@ -1,7 +1,11 @@
|
|||||||
#include "StaticMesh.hpp"
|
#include "StaticMesh.hpp"
|
||||||
|
|
||||||
|
#include "Core/CoreInstance.hpp"
|
||||||
|
#include "Core/RenderEngine/RenderEngine.hpp"
|
||||||
|
#include "Game/GameInstance.hpp"
|
||||||
#include "Log/Log.hpp"
|
#include "Log/Log.hpp"
|
||||||
#include "Game/SaveMap/SaveMap.hpp"
|
#include "Game/SaveMap/SaveMap.hpp"
|
||||||
|
#include "Game/World/World.hpp"
|
||||||
|
|
||||||
StaticMesh::StaticMesh()
|
StaticMesh::StaticMesh()
|
||||||
{
|
{
|
||||||
@@ -20,7 +24,13 @@ void StaticMesh::load(std::shared_ptr<SaveMap> save)
|
|||||||
|
|
||||||
void StaticMesh::load_model(const std::string& model_name)
|
void StaticMesh::load_model(const std::string& model_name)
|
||||||
{
|
{
|
||||||
|
model_name_ = model_name;
|
||||||
SetModelName(model_name);
|
SetModelName(model_name);
|
||||||
// TODO
|
model_ = GetWorld()->GetGameInstance().GetCore().GetRenderEngine()->GetActiveModelManager()->LoadModel(model_name);
|
||||||
Message("Load mesh: " + model_name);
|
}
|
||||||
|
|
||||||
|
void StaticMesh::OnDestroy()
|
||||||
|
{
|
||||||
|
Mesh::OnDestroy();
|
||||||
|
GetWorld()->GetGameInstance().GetCore().GetRenderEngine()->GetActiveModelManager()->FreeModel(model_name_);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,14 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "Mesh.hpp"
|
#include "Mesh.hpp"
|
||||||
|
#include "Core/RenderEngine/ModelManager.hpp"
|
||||||
|
|
||||||
GENERATE_META(StaticMesh)
|
GENERATE_META(StaticMesh)
|
||||||
|
|
||||||
class StaticMesh : public Mesh
|
class StaticMesh : public Mesh
|
||||||
{
|
{
|
||||||
|
std::string model_name_;
|
||||||
|
ModelManager::StaticModel* model_ = nullptr;
|
||||||
public:
|
public:
|
||||||
StaticMesh();
|
StaticMesh();
|
||||||
|
|
||||||
@@ -14,4 +18,5 @@ public:
|
|||||||
#pragma endregion
|
#pragma endregion
|
||||||
|
|
||||||
void load_model(const std::string& model_name) override;
|
void load_model(const std::string& model_name) override;
|
||||||
|
void OnDestroy() override;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -8,6 +8,8 @@ World::World(GameInstance& game_instance) : game_instance(game_instance)
|
|||||||
|
|
||||||
World::~World()
|
World::~World()
|
||||||
{
|
{
|
||||||
|
for (auto& i : actors_map)
|
||||||
|
i.second->OnDestroy();
|
||||||
actors_map.clear();
|
actors_map.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
"dtime": 5.000000,
|
"dtime": 5.000000,
|
||||||
"Parent parameters": {
|
"Parent parameters": {
|
||||||
"Class name":"World",
|
"Class name":"World",
|
||||||
"vsActorsIDs": ["TestMesh1"],
|
"vsActorsIDs": ["TestMesh1","TestMesh2"],
|
||||||
"loActors": [
|
"loActors": [
|
||||||
{
|
{
|
||||||
"Class name": "StaticMesh",
|
"Class name": "StaticMesh",
|
||||||
@@ -33,6 +33,35 @@
|
|||||||
"tags":[]
|
"tags":[]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Class name": "StaticMesh",
|
||||||
|
"Parent parameters": {
|
||||||
|
"Class name": "Mesh",
|
||||||
|
"smodel_name_": "TestModel",
|
||||||
|
"Parent parameters": {
|
||||||
|
"Class name":"Actor",
|
||||||
|
"oloc": {
|
||||||
|
"Class name":"Vector3D",
|
||||||
|
"dx":0.0,
|
||||||
|
"dy":-1.0,
|
||||||
|
"dz":1.0
|
||||||
|
},
|
||||||
|
"orot": {
|
||||||
|
"Class name":"Vector3D",
|
||||||
|
"dx":0.0,
|
||||||
|
"dy":0.0,
|
||||||
|
"dz":0.0
|
||||||
|
},
|
||||||
|
"oscale": {
|
||||||
|
"Class name": "Vector3D",
|
||||||
|
"dx": 1.0,
|
||||||
|
"dy": 1.0,
|
||||||
|
"dz": 1.0
|
||||||
|
},
|
||||||
|
"tags":[]
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user