From b29daefeef5ebfb0d8ea9e4bb90af33353b8f91f Mon Sep 17 00:00:00 2001 From: Pedro Gomes Date: Tue, 30 Sep 2025 21:23:52 +0100 Subject: [PATCH] bugfix + c#object pooling manager --- .../BasicStatAmplificationCalculator.cs | 4 +- .../EventDrivenHooks/EventBrokerArgs.cs | 61 ++++++++- Assets/Scripts/PureObjectPool.meta | 8 ++ Assets/Scripts/PureObjectPool/CObjectPool.cs | 118 ++++++++++++++++++ .../PureObjectPool/CObjectPool.cs.meta | 2 + 5 files changed, 185 insertions(+), 8 deletions(-) create mode 100644 Assets/Scripts/PureObjectPool.meta create mode 100644 Assets/Scripts/PureObjectPool/CObjectPool.cs create mode 100644 Assets/Scripts/PureObjectPool/CObjectPool.cs.meta diff --git a/Assets/Scripts/EntityBroker/BasicStatAmplificationCalculator.cs b/Assets/Scripts/EntityBroker/BasicStatAmplificationCalculator.cs index 4cac7fcf..12f7bbe2 100644 --- a/Assets/Scripts/EntityBroker/BasicStatAmplificationCalculator.cs +++ b/Assets/Scripts/EntityBroker/BasicStatAmplificationCalculator.cs @@ -32,8 +32,8 @@ public class BasicStatAmplificationCalculator : BrokerInterceptor { finalValue += secondaryStat.Value * statInfluence.percentInfluence; } - if (statInfluence.statTag.name.ToLower().Contains("Attack")) args.damageType = DamageType.Attack; - else if (statInfluence.statTag.name.ToLower().Contains("Spell")) args.damageType = DamageType.Spell; + if (statInfluence.statTag.name.ToLower().Contains("attack")) args.damageType = DamageType.Attack; + else if (statInfluence.statTag.name.ToLower().Contains("spell")) args.damageType = DamageType.Spell; } if (IsCrit(stats)) { diff --git a/Assets/Scripts/EventDrivenHooks/EventBrokerArgs.cs b/Assets/Scripts/EventDrivenHooks/EventBrokerArgs.cs index 9f9df90a..bb40822d 100644 --- a/Assets/Scripts/EventDrivenHooks/EventBrokerArgs.cs +++ b/Assets/Scripts/EventDrivenHooks/EventBrokerArgs.cs @@ -3,7 +3,7 @@ using UnityEngine; using UnityEngine.Events; -public class DamageArgs +public class DamageArgs : IResettable { public BaseAbility source; public BaseEffect effect; @@ -15,9 +15,23 @@ public class DamageArgs public bool isCrit; public int totalTargetsHit; public bool targetDead; + + public void Reset() + { + source = null; + effect = null; + user = null; + target = null; + currentValue = 0f; + isCrit = false; + targetDead = false; + applicationMethod = default; + totalTargetsHit = 0; + damageType = default; + } } -public class HealArgs +public class HealArgs : IResettable { public BaseAbility source; public BaseEffect effect; @@ -27,29 +41,64 @@ public class HealArgs public EffectApplicationMethod applicationMethod; public bool isCrit; public int totalTargetsHit; + + public void Reset() + { + source = null; + effect = null; + user = null; + target = null; + currentValue = 0f; + isCrit = false; + applicationMethod = default; + totalTargetsHit = 0; + } } -public class InvulnerabilityArgs +public class InvulnerabilityArgs : IResettable { public Taggable user; public bool isImmune; + + public void Reset() + { + user = null; + isImmune = false; + } } -public class DodgeArgs +public class DodgeArgs : IResettable { public Taggable user; public bool dodgedSuccessfully; + + public void Reset() + { + user = null; + dodgedSuccessfully = false; + } } -public class BlockArgs +public class BlockArgs : IResettable { public Taggable user; public bool blockedSuccessfully; + public void Reset() + { + user = null; + blockedSuccessfully = false; + } } -public class AbsorbArgs +public class AbsorbArgs : IResettable { public Taggable user; public bool absorbedDamage; public bool absorbDepleted; + public void Reset() + { + user = null; + absorbedDamage = false; + absorbDepleted = false; + } } \ No newline at end of file diff --git a/Assets/Scripts/PureObjectPool.meta b/Assets/Scripts/PureObjectPool.meta new file mode 100644 index 00000000..8287076c --- /dev/null +++ b/Assets/Scripts/PureObjectPool.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: b9c8b874014386f4b814b304d682d01f +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/PureObjectPool/CObjectPool.cs b/Assets/Scripts/PureObjectPool/CObjectPool.cs new file mode 100644 index 00000000..18610187 --- /dev/null +++ b/Assets/Scripts/PureObjectPool/CObjectPool.cs @@ -0,0 +1,118 @@ +using System; +using System.Collections.Generic; +using UnityEngine; + +/// +/// Generic object pool for pure C# objects (DamageArgs, HealArgs, etc.) +/// Uses the same pattern as GameObjectPoolManager but for non-MonoBehaviour types. +/// +/// USAGE: +/// - ObjectPool.Get() to get from pool +/// - ObjectPool.Release(args) to return to pool +/// +/// REQUIREMENTS: +/// - Type T must have a parameterless constructor +/// - Type T should implement IResettable for proper cleanup (optional) +/// +public static class CObjectPool where T : class, new() +{ + private static Stack _pool = new Stack(); + private static int _defaultCapacity = 32; + private static int _maxSize = 128; + private static bool _showDebugLogs = false; + + static CObjectPool() + { + // Pre-warm the pool + for (int i = 0; i < _defaultCapacity; i++) + { + _pool.Push(new T()); + } + + if (_showDebugLogs) + Debug.Log($"ObjectPool<{typeof(T).Name}>: Initialized with {_defaultCapacity} objects"); + } + + /// + /// Get an object from the pool. Creates new if pool is empty. + /// + public static T Get() + { + T obj = _pool.Count > 0 ? _pool.Pop() : new T(); + + // Reset if implements IResettable + if (obj is IResettable resettable) + { + resettable.Reset(); + } + + if (_showDebugLogs) + Debug.Log($"ObjectPool<{typeof(T).Name}>: Get (pool size: {_pool.Count})"); + + return obj; + } + + /// + /// Return an object to the pool. + /// + public static void Release(T obj) + { + if (obj == null) + { + Debug.LogError($"ObjectPool<{typeof(T).Name}>: Cannot release null object"); + return; + } + + // Reset before returning to pool + if (obj is IResettable resettable) + { + resettable.Reset(); + } + + // Don't exceed max size + if (_pool.Count < _maxSize) + { + _pool.Push(obj); + } + + if (_showDebugLogs) + Debug.Log($"ObjectPool<{typeof(T).Name}>: Release (pool size: {_pool.Count})"); + } + + /// + /// Clear all pooled objects. + /// + public static void Clear() + { + _pool.Clear(); + if (_showDebugLogs) + Debug.Log($"ObjectPool<{typeof(T).Name}>: Cleared"); + } + + /// + /// Get current pool statistics. + /// + public static (int pooled, int capacity, int maxSize) GetStats() + { + return (_pool.Count, _defaultCapacity, _maxSize); + } + + /// + /// Configure pool settings. Call before first use. + /// + public static void Configure(int defaultCapacity = 32, int maxSize = 128, bool showDebugLogs = false) + { + _defaultCapacity = defaultCapacity; + _maxSize = maxSize; + _showDebugLogs = showDebugLogs; + } +} + +/// +/// Interface for objects that need to reset their state when returned to pool. +/// Similar to IPoolable but for pure C# objects. +/// +public interface IResettable +{ + void Reset(); +} \ No newline at end of file diff --git a/Assets/Scripts/PureObjectPool/CObjectPool.cs.meta b/Assets/Scripts/PureObjectPool/CObjectPool.cs.meta new file mode 100644 index 00000000..94052002 --- /dev/null +++ b/Assets/Scripts/PureObjectPool/CObjectPool.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 2dc8af7fb7b949940ae09d9ddc0fca6d \ No newline at end of file