|
|
@@ -0,0 +1,99 @@ |
|
|
|
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<T> where T : unmanaged |
|
|
|
{ |
|
|
|
private bool exists; |
|
|
|
private NB<T> array; |
|
|
|
private uint index; |
|
|
|
|
|
|
|
private unsafe T* pointer; |
|
|
|
|
|
|
|
public OptionalRef(NB<T> 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<T> opt) => opt.Value; |
|
|
|
|
|
|
|
public static implicit operator bool(OptionalRef<T> opt) => opt.exists; |
|
|
|
|
|
|
|
public delegate ref TR Mapper<TR>(ref T component) where TR : unmanaged; |
|
|
|
public unsafe delegate TR* PMapper<TR>(T* component) where TR : unmanaged; |
|
|
|
|
|
|
|
/*public OptionalRef<TR> Map<TR>(Mapper<TR> mapper) where TR : unmanaged => |
|
|
|
exists ? new OptionalRef<TR>(ref mapper(ref Get())) : new OptionalRef<TR>();*/ |
|
|
|
|
|
|
|
/*public OptionalRef<TR> Map<TR>(Expression<Func<T, TR>> expression) where TR : unmanaged |
|
|
|
{ |
|
|
|
if (expression.Body.NodeType == ExpressionType.MemberAccess) |
|
|
|
Console.WriteLine(((MemberExpression) expression.Body).Member); |
|
|
|
}*/ |
|
|
|
|
|
|
|
public unsafe OptionalRef<TR> Map<TR>(PMapper<TR> mapper) where TR : unmanaged => |
|
|
|
exists ? new OptionalRef<TR>(ref *mapper(pointer)) : new OptionalRef<TR>(); |
|
|
|
} |
|
|
|
} |