Simplified and optimized bullet pooling

This commit is contained in:
Marco 2025-07-01 13:55:30 +02:00
commit da73823ac8
2 changed files with 39 additions and 31 deletions

View file

@ -12,14 +12,15 @@ public partial class PoolingManager : Node
{ {
public static PoolingManager Instance { get; private set; } public static PoolingManager Instance { get; private set; }
[Export] public StringName ActiveBulletsGroupName { get; private set; } = "ActiveBullets";
[Export] public StringName InactiveBulletsGroupName { get; private set; } = "InactiveBullets";
[Export] public Array<PooledBulletInfo> PoolOnStart { get; private set; } [Export] public Array<PooledBulletInfo> PoolOnStart { get; private set; }
[Export] public bool DebugView { get; private set; } = false; [Export] public bool DebugView { get; private set; } = false;
private readonly System.Collections.Generic.Dictionary<BulletResource, System.Collections.Generic.List<IBullet>>
_activeBullets = new();
private readonly System.Collections.Generic.Dictionary<BulletResource, System.Collections.Generic.List<IBullet>> private readonly System.Collections.Generic.Dictionary<BulletResource, System.Collections.Generic.Stack<IBullet>>
_inactiveBullets = new(); _inactiveBullets = new();
public override void _Ready() public override void _Ready()
@ -45,21 +46,26 @@ public partial class PoolingManager : Node
// If present move it to active, set it as active and return it // If present move it to active, set it as active and return it
// Otherwise spawn it and add it to active and return it // Otherwise spawn it and add it to active and return it
var activeBullets = GetActiveBulletsList(bulletResource); // var activeBullets = GetActiveBulletsList(bulletResource);
var inactiveBullets = GetInactiveBulletsList(bulletResource); var inactiveBullets = GetInactiveBulletsList(bulletResource);
var bullet = inactiveBullets.Count > 0 ? inactiveBullets.First() : InstantiateBullet(bulletResource); var bullet = inactiveBullets.Count > 0 ? inactiveBullets.Pop() : InstantiateBullet(bulletResource);
if (active) if (active)
{ {
inactiveBullets.Remove(bullet); //inactiveBullets.Remove(bullet);
activeBullets.Add(bullet); //activeBullets.Add(bullet);
bullet.RemoveFromGroup(InactiveBulletsGroupName);
bullet.AddToGroup(ActiveBulletsGroupName);
bullet.Enable(); bullet.Enable();
} }
else else
{ {
activeBullets.Add(bullet); //activeBullets.Add(bullet);
inactiveBullets.Remove(bullet); //inactiveBullets.Remove(bullet);
bullet.AddToGroup(InactiveBulletsGroupName);
bullet.RemoveFromGroup(ActiveBulletsGroupName);
inactiveBullets.Push(bullet);
bullet.Disable(); bullet.Disable();
} }
@ -73,35 +79,32 @@ public partial class PoolingManager : Node
public IEnumerable<IBullet> GetAllActiveBullets() public IEnumerable<IBullet> GetAllActiveBullets()
{ {
return _activeBullets.Values.SelectMany(list => list); return GetTree().GetNodesInGroup(ActiveBulletsGroupName).Cast<IBullet>();
//return _activeBullets.Values.SelectMany(list => list);
} }
public IEnumerable<IBullet> GetAllInActiveBullets() // public List<IBullet> GetActiveBulletsList(BulletResource resource)
{ // {
return _activeBullets.Values.SelectMany(list => list); // return GetOrCreateList(_activeBullets, resource);
} // }
public List<IBullet> GetActiveBulletsList(BulletResource resource) private Stack<IBullet> GetInactiveBulletsList(BulletResource resource)
{
return GetOrCreateList(_activeBullets, resource);
}
private List<IBullet> GetInactiveBulletsList(BulletResource resource)
{ {
return GetOrCreateList(_inactiveBullets, resource); return GetOrCreateList(_inactiveBullets, resource);
} }
public void DisableBullet(IBullet bullet) public void DisableBullet(IBullet bullet)
{ {
var activeBulletsList = GetActiveBulletsList(bullet.BulletInfo.OriginalBulletResource); //var activeBulletsList = GetActiveBulletsList(bullet.BulletInfo.OriginalBulletResource);
var inactiveBulletsList = GetInactiveBulletsList(bullet.BulletInfo.OriginalBulletResource); var inactiveBulletsList = GetInactiveBulletsList(bullet.BulletInfo.OriginalBulletResource);
bullet.Disable(!DebugView); bullet.Disable(!DebugView);
activeBulletsList.Remove(bullet); //activeBulletsList.Remove(bullet);
bullet.AddToGroup(InactiveBulletsGroupName);
inactiveBulletsList.Add(bullet); bullet.RemoveFromGroup(ActiveBulletsGroupName);
inactiveBulletsList.Push(bullet);
} }
public void DisableAllBullets() public void DisableAllBullets()
@ -114,17 +117,19 @@ public partial class PoolingManager : Node
bullet.Disable(!DebugView); bullet.Disable(!DebugView);
inactiveBulletsList.Add(bullet); bullet.AddToGroup(InactiveBulletsGroupName);
bullet.RemoveFromGroup(ActiveBulletsGroupName);
inactiveBulletsList.Push(bullet);
} }
foreach (var activeBulletsList in _activeBullets) // foreach (var activeBulletsList in _activeBullets)
{ // {
activeBulletsList.Value.Clear(); // activeBulletsList.Value.Clear();
} // }
} }
private List<IBullet> GetOrCreateList(System.Collections.Generic.Dictionary<BulletResource, List<IBullet>> dict, BulletResource resource) private Stack<IBullet> GetOrCreateList(System.Collections.Generic.Dictionary<BulletResource, Stack<IBullet>> dict, BulletResource resource)
{ {
if (dict.TryGetValue(resource, out var list)) return list; if (dict.TryGetValue(resource, out var list)) return list;
list = []; list = [];

View file

@ -31,4 +31,7 @@ public interface IBullet
public bool CanHit(BulletOwner bulletOwner, BulletOwner targetGroup); public bool CanHit(BulletOwner bulletOwner, BulletOwner targetGroup);
public void RequestCollisionDestruction(); public void RequestCollisionDestruction();
public void Freeze(); public void Freeze();
public void AddToGroup(StringName group, bool persistent = false);
public void RemoveFromGroup(StringName group);
} }