using System; using System.Collections.Generic; using System.Linq; using Chickensoft.AutoInject; using Chickensoft.Introspection; using Godot; namespace Movementtests.managers; [GlobalClass, Meta(typeof(IAutoNode))] public partial class TokenManager : Node { public override void _Notification(int what) => this.Notify(what); public record struct Token(ulong InstanceId, Action OnUse); private Dictionary Tokens { get; set; } = []; public int TokenCount => Tokens.Count; private Queue RequestQueue { get; set; } = []; public int MaxTokens { get; set;} public void Initialize(int maxTokens) { MaxTokens = maxTokens; } public Token? RequestToken(Node owner) { if (Tokens.ContainsKey(owner.GetInstanceId())) { GD.Print("Already has a token"); return null; // Already has a token } if (TokenCount >= MaxTokens) { GD.Print($"Max tokens reached: {TokenCount}"); return null; // Max tokens reached } if (!RequestQueue.Contains(owner.GetInstanceId())) { RequestQueue.Enqueue(owner.GetInstanceId()); } if (RequestQueue.First() != owner.GetInstanceId()) { GD.Print("Waiting its turn"); return null; // Next in line is not the requester } var ownerInstanceId = RequestQueue.Dequeue(); var token = new Token(ownerInstanceId, () => UseToken(ownerInstanceId)); Tokens.Add(token.InstanceId, token); return token; } public void UseToken(ulong instanceId) { Tokens.Remove(instanceId); } }