Добавил shared_from_this как основной способ создать умный указатель на "себя". Добавил пример работы с ним
This commit is contained in:
@@ -13,7 +13,7 @@ GENERATE_META(Actor)
|
||||
|
||||
class Actor : public ISave, public IRTTI
|
||||
{
|
||||
World* world_;
|
||||
std::shared_ptr<World> world_;
|
||||
std::string name_;
|
||||
|
||||
std::shared_ptr<Vector3D> loc_, rot_, scale_;
|
||||
@@ -54,7 +54,7 @@ public:
|
||||
void RemoveTag(const std::string& tag) noexcept;
|
||||
const std::list<std::string>& GetTags() const { return tags; }
|
||||
|
||||
World* GetWorld() const { return world_; }
|
||||
std::shared_ptr<World> GetWorld() const { return world_; }
|
||||
const std::string& GetName() const { return name_; }
|
||||
|
||||
friend class World;
|
||||
|
||||
@@ -7,10 +7,11 @@
|
||||
#include "Core/CoreInstance.hpp"
|
||||
#include "Game/WorldFactory.hpp"
|
||||
#include "Game/World/World.hpp"
|
||||
#include "Log/Log.hpp"
|
||||
|
||||
extern std::vector<WorldFactory> world_factories;
|
||||
|
||||
GameInstance::GameInstance(CoreInstance& core) : core(core)
|
||||
GameInstance::GameInstance(CoreInstance& core) : core_(core)
|
||||
{
|
||||
const std::string& base_world = core.getBaseWorldName();
|
||||
|
||||
@@ -21,33 +22,28 @@ GameInstance::GameInstance(CoreInstance& core) : core(core)
|
||||
{
|
||||
if (factories.world_name == base_world)
|
||||
{
|
||||
world = factories.factory(*this);
|
||||
world_ = factories.factory(*this);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (world == nullptr)
|
||||
if (world_ == nullptr)
|
||||
throw std::runtime_error("Can't find world");
|
||||
|
||||
}
|
||||
|
||||
GameInstance::~GameInstance()
|
||||
{
|
||||
delete world;
|
||||
}
|
||||
|
||||
void GameInstance::start()
|
||||
{
|
||||
world->BeginPlay();
|
||||
world_->BeginPlay();
|
||||
|
||||
auto first = std::chrono::steady_clock::now();
|
||||
|
||||
|
||||
while (is_running)
|
||||
while (is_running_)
|
||||
{
|
||||
auto second = std::chrono::steady_clock::now();
|
||||
std::chrono::milliseconds delta_time = std::chrono::duration_cast<std::chrono::milliseconds>(second - first);
|
||||
world->Tick(delta_time.count() / 1000.0);
|
||||
world_->Tick(delta_time.count() / 1000.0);
|
||||
first = second;
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(10));
|
||||
}
|
||||
@@ -55,11 +51,11 @@ void GameInstance::start()
|
||||
|
||||
void GameInstance::stop()
|
||||
{
|
||||
is_running = false;
|
||||
is_running_ = false;
|
||||
}
|
||||
|
||||
void GameInstance::quit()
|
||||
{
|
||||
stop();
|
||||
core.quit();
|
||||
core_.quit();
|
||||
}
|
||||
|
||||
@@ -11,10 +11,10 @@ GameInstance* GameFactory(CoreInstance& core) { return new Class(core); }
|
||||
|
||||
class GameInstance
|
||||
{
|
||||
CoreInstance& core;
|
||||
World* world = nullptr;
|
||||
CoreInstance& core_;
|
||||
std::shared_ptr<World> world_;
|
||||
|
||||
std::atomic<bool> is_running = true;
|
||||
std::atomic<bool> is_running_ = true;
|
||||
|
||||
void start();
|
||||
// Stop call from the core
|
||||
@@ -25,10 +25,10 @@ public:
|
||||
|
||||
// Init vulkan
|
||||
GameInstance(CoreInstance& core);
|
||||
virtual ~GameInstance();
|
||||
virtual ~GameInstance() = default;
|
||||
|
||||
World* GetWorld() const { return world; }
|
||||
CoreInstance& GetCore() const { return core; }
|
||||
std::shared_ptr<World> GetWorld() const { return world_; }
|
||||
CoreInstance& GetCore() const { return core_; }
|
||||
|
||||
friend class CoreInstance;
|
||||
};
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
class SaveMap;
|
||||
|
||||
class ISave
|
||||
class ISave : public std::enable_shared_from_this<ISave>
|
||||
{
|
||||
public:
|
||||
virtual ~ISave() = default;
|
||||
|
||||
@@ -56,14 +56,14 @@ SaveMap::SaveMap(const std::string& json_data)
|
||||
size_t end = i = json_data_blank.find_first_of(",}", i);
|
||||
i++;
|
||||
std::string value = json_data_blank.substr(begin, end - begin);
|
||||
save_long[name.c_str() + 1] = std::stoll(value);
|
||||
save_long[name.c_str() + 1] = std::stoll(value); // (name.c_str() + 1) - отсекаем метаданные
|
||||
} else if (name[0] == 'd')
|
||||
{
|
||||
size_t begin = json_data_blank.find(':', i) + 1;
|
||||
size_t end = i = json_data_blank.find_first_of(",}", i);
|
||||
i++;
|
||||
std::string value = json_data_blank.substr(begin, end - begin);
|
||||
save_double[name.c_str() + 1] = std::stod(value);
|
||||
save_double[name.c_str() + 1] = std::stod(value); // (name.c_str() + 1) - отсекаем метаданные
|
||||
} else if (name[0] == 's')
|
||||
{
|
||||
size_t begin = json_data_blank.find(':', i) + 2;
|
||||
@@ -74,7 +74,7 @@ SaveMap::SaveMap(const std::string& json_data)
|
||||
value = json_data_blank.substr(begin, end - begin);
|
||||
else
|
||||
value = "";
|
||||
save_string[name.c_str() + 1] = value;
|
||||
save_string[name.c_str() + 1] = value; // (name.c_str() + 1) - отсекаем метаданные
|
||||
} else if (name[0] == 'o')
|
||||
{
|
||||
size_t begin = i = json_data_blank.find('{', i);
|
||||
@@ -100,10 +100,10 @@ SaveMap::SaveMap(const std::string& json_data)
|
||||
std::shared_ptr<ISave> object_ptr(MakeObjectByName(object_name));
|
||||
|
||||
object_ptr->load(std::make_shared<SaveMap>(object_json));
|
||||
save_objects[name.c_str() + 1] = object_ptr;
|
||||
save_objects[name.c_str() + 1] = object_ptr; // (name.c_str() + 1) - отсекаем метаданные
|
||||
} else if (name[0] == 'v')
|
||||
{
|
||||
std::string key = name.substr(2, name.length() - 2);
|
||||
std::string key = name.substr(2, name.length() - 2); // (off = 2) - отсечение метаданных; (name.length() - 2) - отсечение кавычки и перевод в индексы
|
||||
|
||||
size_t begin_arr = i = json_data_blank.find('[', i);
|
||||
int open = 1, close = 0;
|
||||
|
||||
@@ -46,13 +46,13 @@ std::shared_ptr<SaveMap> World::save()
|
||||
void World::load(std::shared_ptr<SaveMap> save)
|
||||
{
|
||||
std::vector<std::string> actors_IDs = save->GetVectorString("ActorsIDs");
|
||||
std::list<std::shared_ptr<Actor>> act = std::move(reinterpret_cast<std::list<std::shared_ptr<Actor>>&>(save->GetListObject("Actors")));
|
||||
std::list<std::shared_ptr<ISave>> act = save->GetListObject("Actors");
|
||||
|
||||
size_t i_id = 0;
|
||||
for (auto& i : act)
|
||||
{
|
||||
auto[it, flag] = actors_map.try_emplace(actors_IDs[i_id], i);
|
||||
it->second->world_ = this;
|
||||
auto[it, flag] = actors_map.try_emplace(actors_IDs[i_id], std::static_pointer_cast<Actor>(i));
|
||||
it->second->world_ = std::static_pointer_cast<World>(shared_from_this());
|
||||
it->second->name_ = it->first;
|
||||
i_id++;
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ class World;
|
||||
struct WorldFactory
|
||||
{
|
||||
const char* world_name;
|
||||
World*(*factory)(GameInstance&);
|
||||
std::shared_ptr<World>(*factory)(GameInstance&);
|
||||
};
|
||||
|
||||
// Создаёт ассоцеативный список
|
||||
@@ -20,8 +20,8 @@ struct WorldFactory
|
||||
|
||||
// Генерирует элемент списка
|
||||
#define GENERATE_WORLD_FACTORY(Class, WorldName) WorldFactory{#WorldName,\
|
||||
[](GameInstance& game_insance)->World* {\
|
||||
Class* world = new Class(game_insance);\
|
||||
[](GameInstance& game_insance)->std::shared_ptr<World> {\
|
||||
std::shared_ptr<Class> world = std::make_shared<Class>(game_insance);\
|
||||
std::ifstream config_file("./Worlds/" #WorldName ".world");\
|
||||
if (config_file.fail())\
|
||||
throw std::runtime_error("Can't open world file");\
|
||||
@@ -32,7 +32,7 @@ struct WorldFactory
|
||||
data.resize(file_size);\
|
||||
config_file.read(data.data(), file_size);\
|
||||
world->load(std::make_shared<SaveMap>(data));\
|
||||
return world;\
|
||||
return std::static_pointer_cast<World>(world);\
|
||||
}},
|
||||
|
||||
/*
|
||||
|
||||
Reference in New Issue
Block a user