|
- 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 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
- }
- }
- }
|