using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using TechbloxModdingAPI.Blocks; using Svelto.DataStructures; using Svelto.ECS; namespace TechbloxModdingAPI { public ref struct OptionalRef where T : unmanaged, IEntityComponent { private bool exists; private NB array; private uint index; private EntityInitializer initializer; public OptionalRef(NB array, uint index) { exists = true; this.array = array; this.index = index; initializer = default; } /// /// Wraps the initializer data, if present. /// /// The object with the initializer public OptionalRef(EcsObjectBase obj) { if (obj.InitData.Valid) { initializer = obj.InitData.Initializer(obj.Id); exists = true; } else { initializer = default; exists = false; } array = default; index = default; } /// /// Returns the value or a default value if empty. Supports objects that are being initialized. /// /// The value or the default value public ref T Get() { if (!exists) return ref CompRefCache.Default; if (initializer.EGID == EGID.Empty) return ref array[index]; return ref initializer.GetOrCreate(); } public bool Exists => exists; public static implicit operator T(OptionalRef opt) => opt.Get(); public static implicit operator bool(OptionalRef opt) => opt.exists; /*public delegate ref TR Mapper(ref T component) where TR : unmanaged; public unsafe delegate TR* PMapper(T* component) where TR : unmanaged; public unsafe OptionalRef Map(PMapper mapper) where TR : unmanaged => exists ? new OptionalRef(ref *mapper(pointer)) : new OptionalRef();*/ /// /// Creates an instance of a struct T that can be referenced. /// /// The struct type to cache private struct CompRefCache where TR : unmanaged { public static TR Default; } } }