mirror of
https://github.com/Heretek-AI/GDevelop.git
synced 2026-07-19 22:23:35 -04:00
Add memory tracking to additional container classes (#8392)
Only show in developer changelog
This commit is contained in:
+1
-1
@@ -55,7 +55,7 @@ install:
|
||||
script:
|
||||
# GDCore tests:
|
||||
- cd .build-tests
|
||||
- Core/GDCore_tests
|
||||
- for i in {1..20}; do echo "Run $i"; Core/GDCore_tests; done
|
||||
- cd ..
|
||||
# GDevelop.js tests
|
||||
- cd GDevelop.js
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
|
||||
#include "GDCore/Project/Behavior.h"
|
||||
#include "GDCore/Project/EffectsContainer.h"
|
||||
#include "GDCore/Project/MemoryTrackedRegistry.h"
|
||||
#include "GDCore/Project/ObjectConfiguration.h"
|
||||
#include "GDCore/Project/VariablesContainer.h"
|
||||
#include "GDCore/String.h"
|
||||
@@ -153,6 +154,9 @@ protected:
|
||||
* behaviors and it must be a deep copy.
|
||||
*/
|
||||
void Init(const gd::BehaviorsContainer &behaviorsContainer);
|
||||
|
||||
private:
|
||||
gd::MemoryTracked _memoryTracked{this, "BehaviorsContainer"};
|
||||
};
|
||||
|
||||
} // namespace gd
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
#include "GDCore/String.h"
|
||||
#include "GDCore/Project/BehaviorConfigurationContainer.h"
|
||||
#include "GDCore/Project/MemoryTrackedRegistry.h"
|
||||
|
||||
namespace gd {
|
||||
|
||||
@@ -25,8 +26,19 @@ class GD_CORE_API BehaviorsSharedData: public BehaviorConfigurationContainer {
|
||||
BehaviorsSharedData(): BehaviorConfigurationContainer() {};
|
||||
BehaviorsSharedData(const gd::String& name_, const gd::String& type_)
|
||||
: BehaviorConfigurationContainer(name_, type_) {};
|
||||
BehaviorsSharedData(const BehaviorsSharedData& other)
|
||||
: BehaviorConfigurationContainer(other) {};
|
||||
BehaviorsSharedData& operator=(const BehaviorsSharedData& other) {
|
||||
if (this != &other) {
|
||||
BehaviorConfigurationContainer::operator=(other);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
virtual ~BehaviorsSharedData();
|
||||
virtual BehaviorsSharedData* Clone() const { return new BehaviorsSharedData(*this); }
|
||||
|
||||
private:
|
||||
gd::MemoryTracked _memoryTracked{this, "BehaviorsSharedData"};
|
||||
};
|
||||
|
||||
} // namespace gd
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
||||
#include "GDCore/Project/MemoryTrackedRegistry.h"
|
||||
#include "GDCore/String.h"
|
||||
|
||||
namespace gd {
|
||||
@@ -119,6 +120,7 @@ class GD_CORE_API EffectsContainer {
|
||||
std::vector<std::shared_ptr<gd::Effect>> effects;
|
||||
static Effect badEffect;
|
||||
void Init(const EffectsContainer& other);
|
||||
gd::MemoryTracked _memoryTracked{this, "EffectsContainer"};
|
||||
};
|
||||
} // namespace gd
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
#include <list>
|
||||
#include "GDCore/Project/InitialInstance.h"
|
||||
#include "GDCore/Project/MemoryTrackedRegistry.h"
|
||||
#include "GDCore/String.h"
|
||||
namespace gd {
|
||||
class InitialInstanceFunctor;
|
||||
@@ -38,6 +39,14 @@ namespace gd {
|
||||
class GD_CORE_API InitialInstancesContainer {
|
||||
public:
|
||||
InitialInstancesContainer(){};
|
||||
InitialInstancesContainer(const InitialInstancesContainer& other)
|
||||
: initialInstances(other.initialInstances) {};
|
||||
InitialInstancesContainer& operator=(const InitialInstancesContainer& other) {
|
||||
if (this != &other) {
|
||||
initialInstances = other.initialInstances;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
virtual ~InitialInstancesContainer();
|
||||
|
||||
/**
|
||||
@@ -198,6 +207,7 @@ private:
|
||||
std::list<gd::InitialInstance> initialInstances;
|
||||
|
||||
static gd::InitialInstance badPosition;
|
||||
gd::MemoryTracked _memoryTracked{this, "InitialInstancesContainer"};
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <vector>
|
||||
|
||||
#include "GDCore/Project/Layer.h"
|
||||
#include "GDCore/Project/MemoryTrackedRegistry.h"
|
||||
#include "GDCore/String.h"
|
||||
|
||||
namespace gd {
|
||||
@@ -21,6 +22,13 @@ namespace gd {
|
||||
class GD_CORE_API LayersContainer {
|
||||
public:
|
||||
LayersContainer();
|
||||
LayersContainer(const LayersContainer& other) : layers(other.layers) {};
|
||||
LayersContainer& operator=(const LayersContainer& other) {
|
||||
if (this != &other) {
|
||||
layers = other.layers;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Return true if the layer called "name" exists.
|
||||
@@ -104,6 +112,7 @@ class GD_CORE_API LayersContainer {
|
||||
static gd::Layer badLayer; ///< Null object, returned when GetLayer can not
|
||||
///< find an appropriate layer.
|
||||
std::vector<gd::Layer> layers; ///< Layers
|
||||
gd::MemoryTracked _memoryTracked{this, "LayersContainer"};
|
||||
};
|
||||
|
||||
} // namespace gd
|
||||
@@ -30,16 +30,19 @@ class MemoryTrackedRegistry {
|
||||
public:
|
||||
// Internal C++ API (used by MemoryTracked).
|
||||
static void add(const void* ptr, const char* className) {
|
||||
if (!className) return;
|
||||
dead()[className].erase(ptr);
|
||||
alive()[className].insert(ptr);
|
||||
}
|
||||
|
||||
static void remove(const void* ptr, const char* className) {
|
||||
if (!className) return;
|
||||
alive()[className].erase(ptr);
|
||||
dead()[className].insert(ptr);
|
||||
}
|
||||
|
||||
static bool isDead(const void* ptr, const char* className) {
|
||||
if (!className) return false;
|
||||
auto it = dead().find(className);
|
||||
return it != dead().end() && it->second.count(ptr) > 0;
|
||||
}
|
||||
@@ -116,15 +119,21 @@ class MemoryTrackedRegistry {
|
||||
* MemoryTracked _memoryTracked{this, "Layout"};
|
||||
* };
|
||||
* \endcode
|
||||
*
|
||||
* When adding a new tracked class, also update:
|
||||
* - GDevelop.js/Bindings/postjs.js (trackedClassNames set in
|
||||
* patchClassesForUseAfterFreeDetection)
|
||||
* - newIDE/app/src/MainFrame/MemoryTrackedRegistryDialog.js (trackedClasses
|
||||
* array)
|
||||
*/
|
||||
class MemoryTracked {
|
||||
public:
|
||||
MemoryTracked(const void* owner, const char* className)
|
||||
: owner_(owner), className_(className) {
|
||||
MemoryTrackedRegistry::add(owner_, className_);
|
||||
if (className_) MemoryTrackedRegistry::add(owner_, className_);
|
||||
}
|
||||
|
||||
~MemoryTracked() { MemoryTrackedRegistry::remove(owner_, className_); }
|
||||
~MemoryTracked() { if (className_) MemoryTrackedRegistry::remove(owner_, className_); }
|
||||
|
||||
// Non-copyable, non-movable.
|
||||
MemoryTracked(const MemoryTracked&) = delete;
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "GDCore/Project/MemoryTrackedRegistry.h"
|
||||
#include "GDCore/Project/ObjectGroup.h"
|
||||
#include "GDCore/String.h"
|
||||
namespace gd {
|
||||
@@ -189,6 +190,7 @@ class GD_CORE_API ObjectGroupsContainer {
|
||||
private:
|
||||
std::vector<std::unique_ptr<gd::ObjectGroup>> objectGroups;
|
||||
static ObjectGroup badGroup;
|
||||
gd::MemoryTracked _memoryTracked{this, "ObjectGroupsContainer"};
|
||||
};
|
||||
|
||||
} // namespace gd
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <set>
|
||||
#include "GDCore/Project/MemoryTrackedRegistry.h"
|
||||
#include "GDCore/String.h"
|
||||
#include "GDCore/Project/ObjectGroupsContainer.h"
|
||||
#include "GDCore/Project/ObjectFolderOrObject.h"
|
||||
@@ -252,6 +253,7 @@ class GD_CORE_API ObjectsContainer {
|
||||
private:
|
||||
SourceType sourceType = Unknown;
|
||||
std::unique_ptr<gd::ObjectFolderOrObject> rootFolder;
|
||||
gd::MemoryTracked _memoryTracked{this, "ObjectsContainer"};
|
||||
|
||||
/**
|
||||
* Initialize from another variables container, copying elements. Used by
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#pragma once
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include "GDCore/Project/MemoryTrackedRegistry.h"
|
||||
#include "GDCore/Project/Variable.h"
|
||||
#include "GDCore/String.h"
|
||||
namespace gd {
|
||||
@@ -195,6 +196,7 @@ class GD_CORE_API VariablesContainer {
|
||||
///< useful for computing changesets.
|
||||
static gd::Variable badVariable;
|
||||
static gd::String badName;
|
||||
gd::MemoryTracked _memoryTracked{this, "VariablesContainer"};
|
||||
|
||||
/**
|
||||
* Initialize from another variables container, copying elements. Used by
|
||||
|
||||
@@ -78,9 +78,9 @@ TEST_CASE("EventsList", "[common][events]") {
|
||||
size_t endMemory = gd::SystemStats::GetUsedVirtualMemory();
|
||||
INFO("Memory used: " << endMemory - startMemory << "KB");
|
||||
#if defined(WINDOWS)
|
||||
REQUIRE(3000 >= endMemory - startMemory);
|
||||
REQUIRE(3800 >= endMemory - startMemory);
|
||||
#else
|
||||
REQUIRE(1650 >= endMemory - startMemory);
|
||||
REQUIRE(2000 >= endMemory - startMemory);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -421,7 +421,20 @@ function patchClassesForUseAfterFreeDetection(
|
||||
|
||||
patchClassesForUseAfterFreeDetection(Module, {
|
||||
skippedClassNames: new Set([]),
|
||||
// If adding new classes, also add them to `MemoryTrackedRegistryDialog`.
|
||||
trackedClassNames: new Set(['Project', 'Layout', 'gdObject', 'Behavior']),
|
||||
// If adding new classes, also add them to `MemoryTrackedRegistryDialog`
|
||||
// and to the MemoryTracked member in the C++ class header.
|
||||
trackedClassNames: new Set([
|
||||
'Project',
|
||||
'Layout',
|
||||
'gdObject',
|
||||
'Behavior',
|
||||
'BehaviorsSharedData',
|
||||
'EffectsContainer',
|
||||
'InitialInstancesContainer',
|
||||
'LayersContainer',
|
||||
'ObjectGroupsContainer',
|
||||
'ObjectsContainer',
|
||||
'VariablesContainer',
|
||||
]),
|
||||
verbose: false,
|
||||
});
|
||||
|
||||
@@ -15,8 +15,21 @@ import {
|
||||
|
||||
const gd: libGDevelop = global.gd;
|
||||
|
||||
// If adding new classes, also add them to `patchClassesForUseAfterFreeDetection`.
|
||||
const trackedClasses = ['Project', 'Layout', 'gdObject', 'Behavior'];
|
||||
// If adding new classes, also add them to `patchClassesForUseAfterFreeDetection`
|
||||
// in postjs.js and to the MemoryTracked member in the C++ class header.
|
||||
const trackedClasses = [
|
||||
'Project',
|
||||
'Layout',
|
||||
'gdObject',
|
||||
'Behavior',
|
||||
'BehaviorsSharedData',
|
||||
'EffectsContainer',
|
||||
'InitialInstancesContainer',
|
||||
'LayersContainer',
|
||||
'ObjectGroupsContainer',
|
||||
'ObjectsContainer',
|
||||
'VariablesContainer',
|
||||
];
|
||||
|
||||
type Stats = {|
|
||||
className: string,
|
||||
|
||||
Reference in New Issue
Block a user