2025-06-08 16:33:38 +02:00
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
|
using System.Collections.Immutable;
|
|
|
|
|
|
using System.Linq;
|
|
|
|
|
|
using Cirno.Scripts.Resources;
|
2025-06-17 11:57:59 +02:00
|
|
|
|
using Cirno.Scripts.Weapons;
|
2025-06-08 16:33:38 +02:00
|
|
|
|
using Godot;
|
|
|
|
|
|
using Godot.Collections;
|
|
|
|
|
|
|
|
|
|
|
|
namespace Cirno.Scripts.Controllers;
|
|
|
|
|
|
|
2025-06-17 11:57:59 +02:00
|
|
|
|
public partial class PoolingManager : Node
|
2025-06-08 16:33:38 +02:00
|
|
|
|
{
|
|
|
|
|
|
public static PoolingManager Instance { get; private set; }
|
|
|
|
|
|
|
|
|
|
|
|
[Export] public Array<PooledBulletInfo> PoolOnStart { get; private set; }
|
|
|
|
|
|
|
|
|
|
|
|
[Export] public bool DebugView { get; private set; } = false;
|
|
|
|
|
|
|
2025-06-17 11:57:59 +02:00
|
|
|
|
private readonly System.Collections.Generic.Dictionary<BulletResource, System.Collections.Generic.List<IBullet>>
|
2025-06-08 16:33:38 +02:00
|
|
|
|
_activeBullets = new();
|
|
|
|
|
|
|
2025-06-17 11:57:59 +02:00
|
|
|
|
private readonly System.Collections.Generic.Dictionary<BulletResource, System.Collections.Generic.List<IBullet>>
|
2025-06-08 16:33:38 +02:00
|
|
|
|
_inactiveBullets = new();
|
|
|
|
|
|
|
|
|
|
|
|
public override void _Ready()
|
|
|
|
|
|
{
|
|
|
|
|
|
Instance = this;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-06-17 11:57:59 +02:00
|
|
|
|
public IBullet SpawnBullet(BulletResource bulletResource, bool active = true)
|
2025-06-08 16:33:38 +02:00
|
|
|
|
{
|
|
|
|
|
|
// Look for bullet among the inactive ones
|
|
|
|
|
|
// If present move it to active, set it as active and return it
|
|
|
|
|
|
// Otherwise spawn it and add it to active and return it
|
|
|
|
|
|
|
|
|
|
|
|
var activeBullets = GetActiveBulletsList(bulletResource);
|
|
|
|
|
|
var inactiveBullets = GetInactiveBulletsList(bulletResource);
|
|
|
|
|
|
|
|
|
|
|
|
var bullet = inactiveBullets.Count > 0 ? inactiveBullets.First() : InstantiateBullet(bulletResource);
|
|
|
|
|
|
|
|
|
|
|
|
if (active)
|
|
|
|
|
|
{
|
|
|
|
|
|
inactiveBullets.Remove(bullet);
|
|
|
|
|
|
activeBullets.Add(bullet);
|
|
|
|
|
|
bullet.Enable();
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
activeBullets.Add(bullet);
|
|
|
|
|
|
inactiveBullets.Remove(bullet);
|
|
|
|
|
|
bullet.Disable();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return bullet;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-06-17 11:57:59 +02:00
|
|
|
|
public T SpawnBullet<T>(BulletResource bulletResource, bool active = true) where T : IBullet
|
|
|
|
|
|
{
|
|
|
|
|
|
return (T)SpawnBullet(bulletResource, active);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public IEnumerable<IBullet> GetAllActiveBullets()
|
2025-06-08 16:33:38 +02:00
|
|
|
|
{
|
|
|
|
|
|
return _activeBullets.Values.SelectMany(list => list);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-06-17 11:57:59 +02:00
|
|
|
|
public IEnumerable<IBullet> GetAllInActiveBullets()
|
2025-06-08 16:33:38 +02:00
|
|
|
|
{
|
|
|
|
|
|
return _activeBullets.Values.SelectMany(list => list);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-06-17 11:57:59 +02:00
|
|
|
|
public List<IBullet> GetActiveBulletsList(BulletResource resource)
|
2025-06-08 16:33:38 +02:00
|
|
|
|
{
|
|
|
|
|
|
return GetOrCreateList(_activeBullets, resource);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-06-17 11:57:59 +02:00
|
|
|
|
private List<IBullet> GetInactiveBulletsList(BulletResource resource)
|
2025-06-08 16:33:38 +02:00
|
|
|
|
{
|
|
|
|
|
|
return GetOrCreateList(_inactiveBullets, resource);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-06-17 11:57:59 +02:00
|
|
|
|
public void DisableBullet(IBullet bullet)
|
2025-06-08 16:33:38 +02:00
|
|
|
|
{
|
|
|
|
|
|
var activeBulletsList = GetActiveBulletsList(bullet.BulletInfo.OriginalBulletResource);
|
|
|
|
|
|
|
|
|
|
|
|
var inactiveBulletsList = GetInactiveBulletsList(bullet.BulletInfo.OriginalBulletResource);
|
|
|
|
|
|
|
|
|
|
|
|
bullet.Disable(!DebugView);
|
|
|
|
|
|
|
|
|
|
|
|
activeBulletsList.Remove(bullet);
|
|
|
|
|
|
|
|
|
|
|
|
inactiveBulletsList.Add(bullet);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void DisableAllBullets()
|
|
|
|
|
|
{
|
|
|
|
|
|
var allActiveBullets = GetAllActiveBullets().ToImmutableList();
|
|
|
|
|
|
|
|
|
|
|
|
foreach (var bullet in allActiveBullets)
|
|
|
|
|
|
{
|
|
|
|
|
|
var inactiveBulletsList = GetInactiveBulletsList(bullet.BulletInfo.OriginalBulletResource);
|
|
|
|
|
|
|
|
|
|
|
|
bullet.Disable(!DebugView);
|
|
|
|
|
|
|
|
|
|
|
|
inactiveBulletsList.Add(bullet);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
foreach (var activeBulletsList in _activeBullets)
|
|
|
|
|
|
{
|
|
|
|
|
|
activeBulletsList.Value.Clear();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-06-17 11:57:59 +02:00
|
|
|
|
private List<IBullet> GetOrCreateList(System.Collections.Generic.Dictionary<BulletResource, List<IBullet>> dict, BulletResource resource)
|
2025-06-08 16:33:38 +02:00
|
|
|
|
{
|
|
|
|
|
|
if (dict.TryGetValue(resource, out var list)) return list;
|
|
|
|
|
|
list = [];
|
|
|
|
|
|
dict[resource] = list;
|
|
|
|
|
|
return list;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2025-06-17 11:57:59 +02:00
|
|
|
|
private IBullet InstantiateBullet(BulletResource bulletData)
|
2025-06-08 16:33:38 +02:00
|
|
|
|
{
|
2025-06-18 18:09:30 +02:00
|
|
|
|
var bullet = bulletData.BulletScene.Instantiate<Node>();
|
2025-06-17 11:57:59 +02:00
|
|
|
|
this.AddChild(bullet);
|
|
|
|
|
|
//this.CreateChild<Bullet>(bulletData.BulletScene);
|
2025-06-18 18:09:30 +02:00
|
|
|
|
return bullet as IBullet;
|
2025-06-08 16:33:38 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public partial class PooledBulletInfo : Resource
|
|
|
|
|
|
{
|
|
|
|
|
|
public BulletResource Bullet { get; private set; }
|
|
|
|
|
|
public int Amount { get; private set; }
|
|
|
|
|
|
}
|