I solved this problem by replacing all pointers by instance_id.
Then, I added a manager that returns pointer by instance_id if object is still alive or nullptr if not.
Now, everything works excellent
// SceneObjectsManager.h
#pragma once
#include "Core/Types.h"
#include "GameAgent.h"
#include <Dictionary.hpp>
#include <Node.hpp>
class SceneObjectsManager
{
public:
SceneObjectsManager();
template <class T>
void registerObject(T* gameAgent);
void destroyObject(int instance_id);
bool isInstanceExists(int instance_id);
void registerAgent(godot::GameAgent* gameAgent);
void registerNode(godot::Node* node);
godot::GameAgent* getAgentByInstanceId(int instance_id);
godot::Node* getNodeByInstanceId(int instance_id);
public:
static constexpr s64 NULL_REFERENCE = -1;
protected:
godot::Dictionary sceneObjects;
};
template<class T>
inline void SceneObjectsManager::registerObject(T* object)
{
if (object) {
sceneObjects[object->get_instance_id()] = object;
}
}
// SceneObjectsManager.cpp
#include "SceneObjectsManager.h"
SceneObjectsManager::SceneObjectsManager()
{
sceneObjects.clear();
}
void SceneObjectsManager::registerAgent(godot::GameAgent* gameAgent)
{
registerObject<godot::GameAgent>(gameAgent);
}
void SceneObjectsManager::registerNode(godot::Node* node)
{
registerObject<godot::Node>(node);
}
void SceneObjectsManager::destroyObject(int instance_id)
{
if (sceneObjects.has(instance_id)) {
sceneObjects[instance_id].call("queue_free", nullptr, 0);
sceneObjects.erase(instance_id);
}
}
godot::GameAgent* SceneObjectsManager::getAgentByInstanceId(int instance_id)
{
if (!sceneObjects.has(instance_id)) {
return nullptr;
} else {
return sceneObjects[instance_id];
}
}
godot::Node* SceneObjectsManager::getNodeByInstanceId(int instance_id)
{
if (!sceneObjects.has(instance_id)) {
return nullptr;
}
else {
return sceneObjects[instance_id];
}
}
bool SceneObjectsManager::isInstanceExists(int instance_id)
{
return sceneObjects.has(instance_id);
}