Patch - Adds component shutdown functionality - V13.6.1

Implements a shutdown mechanism for components and entities,
ensuring proper resource release and preventing memory leaks.

This change introduces a virtual `Shutdown` method to the
`Component` class, allowing derived components to release
specific resources when they are removed from an entity or
when the entity is destroyed. The `Entity` class now calls
the `Shutdown` method on all its components during its own
release process. The `EntityManager` now calls the
`release()` method when destroying an entity.

This enhancement ensures that resources, such as FMOD sound
objects and channels in the `AudioComponent`, are properly
released, preventing potential resource leaks and improving
the stability of the engine.
This commit is contained in:
2025-09-17 16:47:01 +02:00
parent 7fc4b08808
commit 76fdd3c76e
5 changed files with 62 additions and 19 deletions

View File

@@ -62,26 +62,26 @@
<option name="hideEmptyMiddlePackages" value="true" />
<option name="showLibraryContents" value="true" />
</component>
<component name="PropertiesComponent"><![CDATA[{
"keyToString": {
"ASKED_SHARE_PROJECT_CONFIGURATION_FILES": "true",
"C++ Project.enginecustom.executor": "Run",
"C/C++ Project.KhaoticDemo.executor": "Run",
"C/C++ Project.enginecustom.executor": "Run",
"RunOnceActivity.ShowReadmeOnStart": "true",
"RunOnceActivity.git.unshallow": "true",
"SHARE_PROJECT_CONFIGURATION_FILES": "true",
"git-widget-placeholder": "main",
"ignore.virus.scanning.warn.message": "true",
"node.js.detected.package.eslint": "true",
"node.js.detected.package.tslint": "true",
"node.js.selected.package.eslint": "(autodetect)",
"node.js.selected.package.tslint": "(autodetect)",
"nodejs_package_manager_path": "npm",
"settings.editor.selected.configurable": "preferences.pluginManager",
"vue.rearranger.settings.migration": "true"
<component name="PropertiesComponent">{
&quot;keyToString&quot;: {
&quot;ASKED_SHARE_PROJECT_CONFIGURATION_FILES&quot;: &quot;true&quot;,
&quot;C++ Project.enginecustom.executor&quot;: &quot;Run&quot;,
&quot;C/C++ Project.KhaoticDemo.executor&quot;: &quot;Run&quot;,
&quot;C/C++ Project.enginecustom.executor&quot;: &quot;Run&quot;,
&quot;RunOnceActivity.ShowReadmeOnStart&quot;: &quot;true&quot;,
&quot;RunOnceActivity.git.unshallow&quot;: &quot;true&quot;,
&quot;SHARE_PROJECT_CONFIGURATION_FILES&quot;: &quot;true&quot;,
&quot;git-widget-placeholder&quot;: &quot;main&quot;,
&quot;ignore.virus.scanning.warn.message&quot;: &quot;true&quot;,
&quot;node.js.detected.package.eslint&quot;: &quot;true&quot;,
&quot;node.js.detected.package.tslint&quot;: &quot;true&quot;,
&quot;node.js.selected.package.eslint&quot;: &quot;(autodetect)&quot;,
&quot;node.js.selected.package.tslint&quot;: &quot;(autodetect)&quot;,
&quot;nodejs_package_manager_path&quot;: &quot;npm&quot;,
&quot;settings.editor.selected.configurable&quot;: &quot;preferences.pluginManager&quot;,
&quot;vue.rearranger.settings.migration&quot;: &quot;true&quot;
}
}]]></component>
}</component>
<component name="RunManager" selected="C/C++ Project.enginecustom">
<configuration name="KhaoticDemo" type="CppProject" factoryName="C++ Project">
<configuration_1 setup="1">

View File

@@ -32,6 +32,11 @@ public:
*/
virtual void Initialize() {}
/**
*Virtual function to shutdown the component.
*/
virtual void Shutdown() {}
/**
* Virtual function to update the component.
* @param deltaTime Time since the last update.

View File

@@ -30,6 +30,27 @@ public:
// Ne pas lib<69>rer m_system ici car il peut <20>tre partag<61>
}
/**
* Shutdown the audio component by releasing the sound and channel.
* This method is called when the component is removed from an entity or when the entity is destroyed.
*/
void Shutdown() override {
if (m_channel) {
bool isPlaying = false;
m_channel->isPlaying(&isPlaying);
if (isPlaying) {
m_channel->stop();
}
m_channel = nullptr;
}
if (m_sound) {
m_sound->release();
m_sound = nullptr;
}
m_system = nullptr; // Ne pas lib<69>rer m_system ici car il peut <20>tre partag<61>
m_camera = nullptr;
}
/**
* Initialize the audio component by setting up the FMOD system and camera from the parent entity.
* This method is called when the component is added to an entity.

View File

@@ -163,6 +163,22 @@ public:
*/
FMOD::System* GetSoundSystem() const { return m_soundSystem; }
/**
* Release all data associated with the entity.
* This includes clearing all components and resetting the camera and sound system pointers.
*/
void release()
{
// call shutdown on all components if needed
for (auto& [typeID, component] : m_Components) {
// If components had a shutdown method, we would call it here
component->Shutdown();
}
m_Components.clear();
m_camera = nullptr;
m_soundSystem = nullptr;
}
void SetDevice (ID3D11Device* dev) { device = dev; }
void SetContext(ID3D11DeviceContext* ctx) { context = ctx; }
ID3D11Device* GetDevice() const { return device; }

View File

@@ -48,6 +48,7 @@ public:
void DestroyEntity(EntityID id) {
auto it = m_Entities.find(id);
if (it != m_Entities.end()) {
it->second->release();
m_Entities.erase(it);
m_FreeIDs.push(id); // Recycler l'ID
}