using System.Collections; using System.Collections.Generic; using Dalamud.Game.ClientState.Objects; using Dalamud.IoC; using Dalamud.IoC.Internal; using Dalamud.Plugin.Services; using Dalamud.Utility; using FFXIVClientStructs.FFXIV.Client.Game.UI; using Serilog; namespace Dalamud.Game.ClientState.Aetherytes; /// /// This collection represents the list of available Aetherytes in the Teleport window. /// [PluginInterface] [ServiceManager.EarlyLoadedService] #pragma warning disable SA1015 [ResolveVia] #pragma warning restore SA1015 internal sealed unsafe partial class AetheryteList : IServiceType, IAetheryteList { [ServiceManager.ServiceDependency] private readonly ObjectTable objectTable = Service.Get(); private readonly Telepo* telepoInstance = Telepo.Instance(); [ServiceManager.ServiceConstructor] private AetheryteList() { Log.Verbose($"Teleport address {Util.DescribeAddress(this.telepoInstance)}"); } /// public int Length { get { if (this.objectTable.LocalPlayer == null) return 0; this.Update(); if (this.telepoInstance->TeleportList.First == this.telepoInstance->TeleportList.Last) return 0; return this.telepoInstance->TeleportList.Count; } } /// public IAetheryteEntry? this[int index] { get { if (index < 0 || index >= this.Length) { return null; } if (this.objectTable.LocalPlayer == null) return null; return new AetheryteEntry(this.telepoInstance->TeleportList[index]); } } private void Update() { // this is very very important as otherwise it crashes if (this.objectTable.LocalPlayer == null) return; this.telepoInstance->UpdateAetheryteList(); } } /// /// This collection represents the list of available Aetherytes in the Teleport window. /// internal sealed partial class AetheryteList { /// public int Count => this.Length; /// public IEnumerator GetEnumerator() { return new Enumerator(this); } /// IEnumerator IEnumerable.GetEnumerator() { return this.GetEnumerator(); } private struct Enumerator(AetheryteList aetheryteList) : IEnumerator { private int index = -1; public IAetheryteEntry Current { get; private set; } object IEnumerator.Current => this.Current; public bool MoveNext() { if (++this.index < aetheryteList.Length) { this.Current = aetheryteList[this.index]; return true; } this.Current = default; return false; } public void Reset() { this.index = -1; } public void Dispose() { } } }