using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using GamecraftModdingAPI.Blocks; using Svelto.DataStructures; using Svelto.ECS; namespace GamecraftModdingAPI { public struct OptionalRef where T : unmanaged { private bool exists; private NB array; private uint index; private unsafe T* pointer; public OptionalRef(NB array, uint index) { exists = true; this.array = array; this.index = index; unsafe { pointer = null; } } public OptionalRef(ref T value) { unsafe { fixed(T* p = &value) pointer = p; } exists = true; array = default; index = default; } public ref T Get() { unsafe { if (pointer != null && exists) return ref *pointer; } if (exists) return ref array[index]; throw new InvalidOperationException("Calling Get() on an empty OptionalRef"); } public T Value { get { unsafe { if (pointer != null && exists) return *pointer; } if (exists) return array[index]; return default; } } public unsafe void Set(T value) //Can't use properties because it complains that you can't set struct members { if (pointer != null && exists) *pointer = value; } public bool Exists => exists; public static implicit operator T(OptionalRef opt) => opt.Value; 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 OptionalRef Map(Mapper mapper) where TR : unmanaged => exists ? new OptionalRef(ref mapper(ref Get())) : new OptionalRef();*/ /*public OptionalRef Map(Expression> expression) where TR : unmanaged { if (expression.Body.NodeType == ExpressionType.MemberAccess) Console.WriteLine(((MemberExpression) expression.Body).Member); }*/ public unsafe OptionalRef Map(PMapper mapper) where TR : unmanaged => exists ? new OptionalRef(ref *mapper(pointer)) : new OptionalRef(); } }