NorbiPeti
033ebdb86d
Also added two port name properties directly to the wires Also added support for converting OptionalRefs to Nullables
94 lines
No EOL
3 KiB
C#
94 lines
No EOL
3 KiB
C#
using System;
|
|
using Svelto.DataStructures;
|
|
using Svelto.ECS;
|
|
|
|
namespace TechbloxModdingAPI.Utility
|
|
{
|
|
public ref struct OptionalRef<T> where T : struct, IEntityComponent
|
|
{
|
|
private readonly State state;
|
|
private readonly uint index;
|
|
private NB<T> array;
|
|
private MB<T> managedArray;
|
|
private readonly EntityInitializer initializer;
|
|
//The possible fields are: (index && (array || managedArray)) || initializer
|
|
|
|
public OptionalRef(NB<T> array, uint index)
|
|
{
|
|
state = State.Native;
|
|
this.array = array;
|
|
this.index = index;
|
|
initializer = default;
|
|
}
|
|
|
|
public OptionalRef(MB<T> array, uint index)
|
|
{
|
|
state = State.Managed;
|
|
managedArray = array;
|
|
this.index = index;
|
|
initializer = default;
|
|
this.array = default;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Wraps the initializer data, if present.
|
|
/// </summary>
|
|
/// <param name="obj">The object with the initializer</param>
|
|
/// <param name="unmanaged">Whether the struct is unmanaged</param>
|
|
public OptionalRef(EcsObjectBase obj, bool unmanaged)
|
|
{
|
|
if (obj.InitData.Valid)
|
|
{
|
|
initializer = obj.InitData.Initializer(obj.Id);
|
|
state = (unmanaged ? State.Native : State.Managed) | State.Initializer;
|
|
}
|
|
else
|
|
{
|
|
initializer = default;
|
|
state = State.Empty;
|
|
}
|
|
array = default;
|
|
index = default;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns the value or a default value if empty. Supports objects that are being initialized.
|
|
/// </summary>
|
|
/// <returns>The value or the default value</returns>
|
|
public ref T Get()
|
|
{
|
|
CompRefCache.Default = default; //The default value can be changed by mods
|
|
if (state == State.Empty) return ref CompRefCache.Default;
|
|
if ((state & State.Initializer) != State.Empty) return ref initializer.GetOrCreate<T>();
|
|
if ((state & State.Native) != State.Empty) return ref array[index];
|
|
return ref managedArray[index];
|
|
}
|
|
|
|
public bool Exists => state != State.Empty;
|
|
public T? Nullable() => this ? Get() : default;
|
|
|
|
public static implicit operator T(OptionalRef<T> opt) => opt.Get();
|
|
|
|
public static implicit operator bool(OptionalRef<T> opt) => opt.state != State.Empty;
|
|
|
|
/// <summary>
|
|
/// Creates an instance of a struct T that can be referenced.
|
|
/// </summary>
|
|
private struct CompRefCache
|
|
{
|
|
public static T Default;
|
|
}
|
|
|
|
/// <summary>
|
|
/// A byte that holds state in its bits.
|
|
/// </summary>
|
|
[Flags]
|
|
private enum State : byte
|
|
{
|
|
Empty,
|
|
Native,
|
|
Managed,
|
|
Initializer = 4
|
|
}
|
|
}
|
|
} |