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.

80 lines
4.0KB

  1. using System.Linq;
  2. using Svelto.ECS;
  3. using Svelto.ECS.Hybrid;
  4. using TechbloxModdingAPI.Common;
  5. namespace TechbloxModdingAPI.Utility.ECS
  6. {
  7. public static class ManagedApiExtensions
  8. {
  9. /// <summary>
  10. /// Attempts to query an entity and returns an optional that contains the result if succeeded.
  11. /// <b>This overload does not take initializer data into account.</b>
  12. /// </summary>
  13. /// <param name="entitiesDB">The entities DB</param>
  14. /// <param name="egid">The EGID to query</param>
  15. /// <typeparam name="T">The component type to query</typeparam>
  16. /// <returns>An optional that contains the result on success or is empty if not found</returns>
  17. public static OptionalRef<T> QueryEntityOptional<T>(this EntitiesDB entitiesDB, EGID egid)
  18. where T : struct, IEntityViewComponent
  19. {
  20. return entitiesDB.TryQueryEntitiesAndIndex<T>(egid, out uint index, out var array)
  21. ? new OptionalRef<T>(array, index)
  22. : new OptionalRef<T>();
  23. }
  24. /// <summary>
  25. /// Attempts to query an entity and returns the result in an optional reference.
  26. /// </summary>
  27. /// <param name="entitiesDB">The entities DB to query from</param>
  28. /// <param name="obj">The ECS object to query</param>
  29. /// <param name="group">The group of the entity if the object can have multiple</param>
  30. /// <typeparam name="T">The component to query</typeparam>
  31. /// <returns>A reference to the component or a dummy value</returns>
  32. public static OptionalRef<T> QueryEntityOptional<T>(this EntitiesDB entitiesDB, EcsObjectBase obj,
  33. ExclusiveGroupStruct group = default)
  34. where T : struct, IEntityViewComponent
  35. {
  36. EGID id = group == ExclusiveGroupStruct.Invalid ? obj.Id : new EGID(obj.Id.entityID, group);
  37. var opt = QueryEntityOptional<T>(entitiesDB, id);
  38. return opt ? opt : new OptionalRef<T>(obj, false);
  39. }
  40. /// <summary>
  41. /// Attempts to query an entity and returns the result or a dummy value that can be modified.
  42. /// </summary>
  43. /// <param name="entitiesDB">The entities DB to query from</param>
  44. /// <param name="obj">The ECS object to query</param>
  45. /// <param name="group">The group of the entity if the object can have multiple</param>
  46. /// <typeparam name="T">The component to query</typeparam>
  47. /// <returns>A reference to the component or a dummy value</returns>
  48. public static ref T QueryEntityOrDefault<T>(this EntitiesDB entitiesDB, EcsObjectBase obj,
  49. ExclusiveGroupStruct group = default)
  50. where T : struct, IEntityViewComponent
  51. {
  52. EGID id = group == ExclusiveGroupStruct.Invalid ? obj.Id : new EGID(obj.Id.entityID, group);
  53. var opt = QueryEntityOptional<T>(entitiesDB, id);
  54. if (opt) return ref opt.Get();
  55. // If initializing the entity, check if the component is allowed by the descriptor, otherwise it could cause
  56. // issues in the game with Add() calls running unexpectedly
  57. if (obj.InitData.Valid && obj.AllowedEntityComponents.Contains(typeof(T)))
  58. return ref obj.InitData.Initializer(id).GetOrAdd<T>();
  59. return ref opt.Get(); //Default value
  60. }
  61. /// <summary>
  62. /// Query entities as OptionalRefs. The elements always exist, it's just a nice way to encapsulate the data.
  63. /// </summary>
  64. /// <param name="entitiesDB"></param>
  65. /// <param name="group"></param>
  66. /// <param name="select"></param>
  67. /// <typeparam name="T"></typeparam>
  68. /// <typeparam name="TR"></typeparam>
  69. /// <returns></returns>
  70. public static RefCollection<T> QueryEntitiesOptional<T>(this EntitiesDB entitiesDB, ExclusiveGroupStruct group) where T : struct, IEntityViewComponent
  71. {
  72. var (buffer, ids, count) = entitiesDB.QueryEntities<T>(group);
  73. return new RefCollection<T>(count, buffer, ids, group);
  74. }
  75. }
  76. }