A stable modding interface between Techblox and mods https://mod.exmods.org/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

99 lines
2.7KB

  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. using System.Linq.Expressions;
  6. using GamecraftModdingAPI.Blocks;
  7. using Svelto.DataStructures;
  8. using Svelto.ECS;
  9. namespace GamecraftModdingAPI
  10. {
  11. public struct OptionalRef<T> where T : unmanaged
  12. {
  13. private bool exists;
  14. private NB<T> array;
  15. private uint index;
  16. private unsafe T* pointer;
  17. public OptionalRef(NB<T> array, uint index)
  18. {
  19. exists = true;
  20. this.array = array;
  21. this.index = index;
  22. unsafe
  23. {
  24. pointer = null;
  25. }
  26. }
  27. public OptionalRef(ref T value)
  28. {
  29. unsafe
  30. {
  31. fixed(T* p = &value) pointer = p;
  32. }
  33. exists = true;
  34. array = default;
  35. index = default;
  36. }
  37. public ref T Get()
  38. {
  39. unsafe
  40. {
  41. if (pointer != null && exists)
  42. return ref *pointer;
  43. }
  44. if (exists)
  45. return ref array[index];
  46. throw new InvalidOperationException("Calling Get() on an empty OptionalRef");
  47. }
  48. public T Value
  49. {
  50. get
  51. {
  52. unsafe
  53. {
  54. if (pointer != null && exists)
  55. return *pointer;
  56. }
  57. if (exists)
  58. return array[index];
  59. return default;
  60. }
  61. }
  62. public unsafe void Set(T value) //Can't use properties because it complains that you can't set struct members
  63. {
  64. if (pointer != null && exists)
  65. *pointer = value;
  66. }
  67. public bool Exists => exists;
  68. public static implicit operator T(OptionalRef<T> opt) => opt.Value;
  69. public static implicit operator bool(OptionalRef<T> opt) => opt.exists;
  70. public delegate ref TR Mapper<TR>(ref T component) where TR : unmanaged;
  71. public unsafe delegate TR* PMapper<TR>(T* component) where TR : unmanaged;
  72. /*public OptionalRef<TR> Map<TR>(Mapper<TR> mapper) where TR : unmanaged =>
  73. exists ? new OptionalRef<TR>(ref mapper(ref Get())) : new OptionalRef<TR>();*/
  74. /*public OptionalRef<TR> Map<TR>(Expression<Func<T, TR>> expression) where TR : unmanaged
  75. {
  76. if (expression.Body.NodeType == ExpressionType.MemberAccess)
  77. Console.WriteLine(((MemberExpression) expression.Body).Member);
  78. }*/
  79. public unsafe OptionalRef<TR> Map<TR>(PMapper<TR> mapper) where TR : unmanaged =>
  80. exists ? new OptionalRef<TR>(ref *mapper(pointer)) : new OptionalRef<TR>();
  81. }
  82. }