Browse Source

Fix an issue with the new generator, switch to using entity references

feature/refactor.v3
NorbiPeti 7 months ago
parent
commit
bf08b61788
Signed by: NorbiPeti <szatmari.norbert.peter@gmail.com> GPG Key ID: DBA4C4549A927E56
33 changed files with 132 additions and 100 deletions
  1. +1
    -1
      CodeGenerator/CodeGenerator.csproj
  2. +5
    -3
      CodeGenerator/ECSAnalyzer.cs
  3. +2
    -1
      CodeGenerator/Program.cs
  4. +1
    -1
      TechbloxModdingAPI/App/GameBuildSimEventEngine.cs
  5. +1
    -1
      TechbloxModdingAPI/Block.cs
  6. +1
    -1
      TechbloxModdingAPI/BlockGroup.cs
  7. +1
    -3
      TechbloxModdingAPI/Blocks/Engines/BlockCloneEngine.cs
  8. +1
    -2
      TechbloxModdingAPI/Blocks/Engines/BlockEngine.cs
  9. +1
    -1
      TechbloxModdingAPI/Blocks/Engines/MovementEngine.cs
  10. +1
    -1
      TechbloxModdingAPI/Blocks/Engines/PlacementEngine.cs
  11. +1
    -3
      TechbloxModdingAPI/Blocks/Engines/RemovalEngine.cs
  12. +1
    -3
      TechbloxModdingAPI/Blocks/Engines/RotationEngine.cs
  13. +1
    -3
      TechbloxModdingAPI/Blocks/Engines/ScalingEngine.cs
  14. +1
    -5
      TechbloxModdingAPI/Blocks/Wire.cs
  15. +1
    -1
      TechbloxModdingAPI/Client/App/ClientEngine.cs
  16. +1
    -1
      TechbloxModdingAPI/Client/Game/ClientMachine.cs
  17. +1
    -0
      TechbloxModdingAPI/Cluster.cs
  18. +1
    -1
      TechbloxModdingAPI/Commands/ICustomCommandEngine.cs
  19. +70
    -56
      TechbloxModdingAPI/Common/EcsObjectBase.cs
  20. +26
    -0
      TechbloxModdingAPI/Common/EcsObjectBaseEngine.cs
  21. +1
    -1
      TechbloxModdingAPI/Common/Engines/IApiEngine.cs
  22. +1
    -1
      TechbloxModdingAPI/Common/Engines/INamedApiEngine.cs
  23. +1
    -1
      TechbloxModdingAPI/Common/Engines/IReactionaryEngine.cs
  24. +1
    -1
      TechbloxModdingAPI/Common/Utils/AsyncUtilsEngine.cs
  25. +1
    -1
      TechbloxModdingAPI/Input/FakeInputEngine.cs
  26. +1
    -1
      TechbloxModdingAPI/Player.cs
  27. +1
    -1
      TechbloxModdingAPI/Players/PlayerEventsEngine.cs
  28. +1
    -2
      TechbloxModdingAPI/SimBody.cs
  29. +1
    -1
      TechbloxModdingAPI/Utility/DebugInterfaceEngine.cs
  30. +1
    -0
      TechbloxModdingAPI/Utility/ECS/ManagedApiExtensions.cs
  31. +1
    -1
      TechbloxModdingAPI/Utility/ECS/NativeApiExtensions.cs
  32. +1
    -1
      TechbloxModdingAPI/Utility/GameStateEngine.cs
  33. +1
    -0
      TechbloxModdingAPI/Utility/OptionalRef.cs

+ 1
- 1
CodeGenerator/CodeGenerator.csproj View File

@@ -8,7 +8,7 @@
<PackageProjectUrl>https://git.exmods.org/modtainers/GamecraftModdingAPI</PackageProjectUrl>
<NeutralLanguage>en-CA</NeutralLanguage>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<LangVersion>9</LangVersion>
<LangVersion>latest</LangVersion>
<OutputType>Exe</OutputType>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">


+ 5
- 3
CodeGenerator/ECSAnalyzer.cs View File

@@ -5,21 +5,23 @@ using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using Gamecraft.Tweaks;
using HarmonyLib;
using Svelto.ECS;

namespace CodeGenerator
{
public class ECSAnalyzer
public static class ECSAnalyzer
{
public static ECSClassInfo AnalyzeEntityDescriptor(Type entityDescriptorType)
{
// TODO: Add support for creating/deleting entities (getting an up to date server/client engines root)
var templateType = typeof(EntityDescriptorTemplate<>).MakeGenericType(entityDescriptorType);
var getTemplateClass = Expression.Constant(templateType);
var getDescriptorExpr = Expression.PropertyOrField(getTemplateClass, "descriptor");
var templateDescriptor = AccessTools.Property(templateType, "descriptor");
var getDescriptorExpr = Expression.MakeMemberAccess(null, templateDescriptor ?? throw new InvalidOperationException());
var getTemplateDescriptorExpr =
Expression.Lambda<Func<IEntityDescriptor>>(getDescriptorExpr);
var getTemplateDescriptor = getTemplateDescriptorExpr.Compile();
// TODO: Crashes on constructing the descriptor type. Maybe move the analysis part to a mod.
var builders = getTemplateDescriptor().componentsToBuild;
return new ECSClassInfo
{


+ 2
- 1
CodeGenerator/Program.cs View File

@@ -15,7 +15,8 @@ namespace CodeGenerator
{
public static void Main(string[] args)
{
GenerateBlockClasses();
//GenerateBlockClasses();
ECSClassGenerator.Generate(typeof(EngineBlockEntityDescriptor));
}

private static void GenerateBlockClasses()


+ 1
- 1
TechbloxModdingAPI/App/GameBuildSimEventEngine.cs View File

@@ -1,6 +1,6 @@
using RobocraftX.StateSync;
using Svelto.ECS;
using TechbloxModdingAPI.Common;
using TechbloxModdingAPI.Common.Engines;
using Unity.Jobs;
using TechbloxModdingAPI.Utility;



+ 1
- 1
TechbloxModdingAPI/Block.cs View File

@@ -8,13 +8,13 @@ using Svelto.ECS.EntityStructs;
using RobocraftX.Common;
using RobocraftX.Blocks;
using Unity.Mathematics;
using HarmonyLib;
using RobocraftX.PilotSeat;
using RobocraftX.Rendering;
using Techblox.BlockLabelsServer;
using TechbloxModdingAPI.Blocks;
using TechbloxModdingAPI.Blocks.Engines;
using TechbloxModdingAPI.Client.App;
using TechbloxModdingAPI.Common;
using TechbloxModdingAPI.Common.Engines;
using TechbloxModdingAPI.Tests;
using TechbloxModdingAPI.Utility;


+ 1
- 1
TechbloxModdingAPI/BlockGroup.cs View File

@@ -9,8 +9,8 @@ using UnityEngine;

using TechbloxModdingAPI.Blocks;
using TechbloxModdingAPI.Blocks.Engines;
using TechbloxModdingAPI.Common;
using TechbloxModdingAPI.Common.Engines;
using TechbloxModdingAPI.Utility;

namespace TechbloxModdingAPI
{


+ 1
- 3
TechbloxModdingAPI/Blocks/Engines/BlockCloneEngine.cs View File

@@ -5,11 +5,9 @@ using Gamecraft.Wires;
using HarmonyLib;
using RobocraftX.Blocks;
using RobocraftX.Character;
using RobocraftX.Common;
using Svelto.DataStructures;
using Svelto.ECS;
using TechbloxModdingAPI.Common;
using TechbloxModdingAPI.Engines;
using TechbloxModdingAPI.Common.Engines;

namespace TechbloxModdingAPI.Blocks.Engines
{


+ 1
- 2
TechbloxModdingAPI/Blocks/Engines/BlockEngine.cs View File

@@ -18,9 +18,8 @@ using Svelto.ECS.Hybrid;
using Techblox.BuildingDrone;
using Techblox.ObjectIDBlockServer;
using TechbloxModdingAPI.Common;
using TechbloxModdingAPI.Common.Engines;
using Unity.Mathematics;

using TechbloxModdingAPI.Engines;
using TechbloxModdingAPI.Utility;
using TechbloxModdingAPI.Utility.ECS;
using PrefabsID = RobocraftX.Common.PrefabsID;


+ 1
- 1
TechbloxModdingAPI/Blocks/Engines/MovementEngine.cs View File

@@ -2,7 +2,7 @@
using RobocraftX.DOTS;
using Svelto.ECS;
using Svelto.ECS.EntityStructs;
using TechbloxModdingAPI.Common;
using TechbloxModdingAPI.Common.Engines;
using Unity.Mathematics;
using Unity.Transforms;
using TechbloxModdingAPI.Utility;


+ 1
- 1
TechbloxModdingAPI/Blocks/Engines/PlacementEngine.cs View File

@@ -12,7 +12,7 @@ using RobocraftX.Rendering;
using RobocraftX.Rendering.GPUI;
using Svelto.ECS;
using Svelto.ECS.EntityStructs;
using TechbloxModdingAPI.Common;
using TechbloxModdingAPI.Common.Engines;
using Unity.Mathematics;
using TechbloxModdingAPI.Utility;
using TechbloxModdingAPI.Utility.ECS;


+ 1
- 3
TechbloxModdingAPI/Blocks/Engines/RemovalEngine.cs View File

@@ -9,12 +9,10 @@ using RobocraftX.StateSync;
using Svelto.ECS;
using Svelto.ECS.Native;
using Techblox.Blocks.Connections;
using TechbloxModdingAPI.Common;
using TechbloxModdingAPI.Common.Engines;
using Unity.Collections;
using Unity.Jobs;
using Allocator = Unity.Collections.Allocator;

using TechbloxModdingAPI.Engines;
using TechbloxModdingAPI.Utility;

namespace TechbloxModdingAPI.Blocks.Engines


+ 1
- 3
TechbloxModdingAPI/Blocks/Engines/RotationEngine.cs View File

@@ -2,11 +2,9 @@
using RobocraftX.DOTS;
using Svelto.ECS;
using Svelto.ECS.EntityStructs;
using TechbloxModdingAPI.Common;
using TechbloxModdingAPI.Common.Engines;
using Unity.Mathematics;
using UnityEngine;

using TechbloxModdingAPI.Engines;
using TechbloxModdingAPI.Utility;
using TechbloxModdingAPI.Utility.ECS;



+ 1
- 3
TechbloxModdingAPI/Blocks/Engines/ScalingEngine.cs View File

@@ -4,10 +4,8 @@ using HarmonyLib;
using RobocraftX.Common;
using RobocraftX.DOTS;
using Svelto.ECS;
using TechbloxModdingAPI.Common;
using TechbloxModdingAPI.Common.Engines;
using Unity.Entities;

using TechbloxModdingAPI.Engines;
using TechbloxModdingAPI.Utility;

namespace TechbloxModdingAPI.Blocks.Engines


+ 1
- 5
TechbloxModdingAPI/Blocks/Wire.cs View File

@@ -1,11 +1,7 @@
using System;

using Gamecraft.Wires;
using Svelto.ECS;
using Svelto.ECS.Experimental;

using TechbloxModdingAPI.Blocks.Engines;
using TechbloxModdingAPI.Utility;
using TechbloxModdingAPI.Common;

namespace TechbloxModdingAPI.Blocks
{


+ 1
- 1
TechbloxModdingAPI/Client/App/ClientEngine.cs View File

@@ -3,7 +3,7 @@ using RobocraftX.Multiplayer;
using Svelto.ECS;
using Techblox.GameSelection;
using TechbloxModdingAPI.Client.Game;
using TechbloxModdingAPI.Common;
using TechbloxModdingAPI.Common.Engines;
using TechbloxModdingAPI.Utility;

namespace TechbloxModdingAPI.Client.App;


+ 1
- 1
TechbloxModdingAPI/Client/Game/ClientMachine.cs View File

@@ -1,6 +1,6 @@
using System;
using RobocraftX.GUI.MyGamesScreen;
using Svelto.ECS;
using TechbloxModdingAPI.Common;

namespace TechbloxModdingAPI.Client.Game;



+ 1
- 0
TechbloxModdingAPI/Cluster.cs View File

@@ -1,6 +1,7 @@
using Svelto.ECS;
using Techblox.Destruction;
using Techblox.TimeRunning.Clusters;
using TechbloxModdingAPI.Common;

namespace TechbloxModdingAPI
{


+ 1
- 1
TechbloxModdingAPI/Commands/ICustomCommandEngine.cs View File

@@ -1,4 +1,4 @@
using TechbloxModdingAPI.Common;
using TechbloxModdingAPI.Common.Engines;

namespace TechbloxModdingAPI.Commands
{


+ 70
- 56
TechbloxModdingAPI/Common/EcsObjectBase.cs View File

@@ -1,81 +1,95 @@
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using Svelto.DataStructures;
using Svelto.ECS;
using Svelto.ECS.Internal;
using TechbloxModdingAPI.Common.Engines;
using TechbloxModdingAPI.Common.Utils;
using TechbloxModdingAPI.Utility;

namespace TechbloxModdingAPI
namespace TechbloxModdingAPI.Common;

public abstract class EcsObjectBase
{
public abstract class EcsObjectBase
{
public EGID Id { get; }
public EGID Id => _engine.GetEgid(Reference);
/// <summary>
/// A reference to a specific entity that persists through group swaps and such.
/// May be an invalid reference, in that case operations do not have any effect.
/// </summary>
public EntityReference Reference { get; }
private static readonly Dictionary<Type, WeakDictionary<EGID, EcsObjectBase>> _instances = new();
private static readonly Dictionary<Type, WeakDictionary<EntityReference, EcsObjectBase>> _instances = new();
private static readonly EcsObjectBaseEngine _engine = new();

internal static WeakDictionary<EGID, EcsObjectBase> GetInstances(Type type)
{
return _instances.TryGetValue(type, out var dict) ? dict : null;
}
private static WeakDictionary<EntityReference, EcsObjectBase> GetInstances(Type type)
{
return _instances.TryGetValue(type, out var dict) ? dict : null;
}

/// <summary>
/// Returns a cached instance if there's an actively used instance of the object already.
/// Objects still get garbage collected and then they will be removed from the cache.
/// </summary>
/// <param name="egid">The EGID of the entity</param>
/// <param name="constructor">The constructor to construct the object</param>
/// <typeparam name="T">The object type</typeparam>
/// <returns></returns>
internal static T GetInstance<T>(EGID egid, Func<EGID, T> constructor, Type type = null) where T : EcsObjectBase
{
var instances = GetInstances(type ?? typeof(T));
if (instances == null || !instances.TryGetValue(egid, out var instance))
return constructor(egid); // It will be added by the constructor
return (T)instance;
}
/// <summary>
/// Returns a cached instance if there's an actively used instance of the object already.
/// Objects still get garbage collected and then they will be removed from the cache.
/// </summary>
/// <param name="egid">The EGID of the entity</param>
/// <param name="constructor">The constructor to construct the object</param>
/// <typeparam name="T">The object type</typeparam>
/// <returns></returns>
internal static T GetInstance<T>(EGID egid, Func<EGID, T> constructor, Type type = null) where T : EcsObjectBase
{
var instances = GetInstances(type ?? typeof(T));
if (instances == null || !instances.TryGetValue(_engine.GetEntityReference(egid), out var instance))
return constructor(egid); // It will be added by the constructor
return (T)instance;
}

protected EcsObjectBase(EGID id, Type entityDescriptorType)
protected EcsObjectBase(EGID id, Type entityDescriptorType) : this(_engine.GetEntityReference(id), entityDescriptorType)
{
}

protected EcsObjectBase(EntityReference reference, Type entityDescriptorType)
{
if (!_instances.TryGetValue(GetType(), out var dict))
{
if (!_instances.TryGetValue(GetType(), out var dict))
{
dict = new WeakDictionary<EGID, EcsObjectBase>();
_instances.Add(GetType(), dict);
}
if (!dict.ContainsKey(id)) // Multiple instances may be created
dict.Add(id, this);
Id = id;
dict = new();
_instances.Add(GetType(), dict);
}
if (!dict.ContainsKey(reference)) // Multiple instances may be created
dict.Add(reference, this);
Reference = reference;
}

#region ECS initializer stuff
#region ECS initializer stuff

protected internal EcsInitData InitData;
protected internal EcsInitData InitData;

/// <summary>
/// Holds information needed to construct a component initializer.
/// Necessary because the initializer is a ref struct which cannot be assigned to a field.
/// </summary>
protected internal struct EcsInitData
{
private FasterDictionary<RefWrapperType, ITypeSafeDictionary> group;
private EntityReference reference;
/// <summary>
/// Holds information needed to construct a component initializer.
/// Necessary because the initializer is a ref struct which cannot be assigned to a field.
/// </summary>
protected internal struct EcsInitData
{
private FasterDictionary<RefWrapperType, ITypeSafeDictionary> group;
private EntityReference reference;

public static implicit operator EcsInitData(EntityInitializer initializer) => new()
{ group = GetInitGroup(initializer), reference = initializer.reference };
public static implicit operator EcsInitData(EntityInitializer initializer) => new()
{ group = GetInitGroup(initializer), reference = initializer.reference };

public EntityInitializer Initializer(EGID id) => new(id, group, reference);
public bool Valid => group != null;
}
public EntityInitializer Initializer(EGID id) => new(id, group, reference);
public bool Valid => group != null;
}

private delegate FasterDictionary<RefWrapperType, ITypeSafeDictionary> GetInitGroupFunc(
EntityInitializer initializer);
private delegate FasterDictionary<RefWrapperType, ITypeSafeDictionary> GetInitGroupFunc(
EntityInitializer initializer);

/// <summary>
/// Accesses the group field of the initializer
/// </summary>
private static readonly GetInitGroupFunc GetInitGroup = Reflections.CreateAccessor<GetInitGroupFunc>("_group");
/// <summary>
/// Accesses the group field of the initializer
/// </summary>
private static readonly GetInitGroupFunc GetInitGroup = Reflections.CreateAccessor<GetInitGroupFunc>("_group");

#endregion
#endregion

public static void Init()
{
EngineManager.AddEngine(_engine, ApiEngineType.Build, ApiEngineType.Menu, ApiEngineType.PlayClient, ApiEngineType.PlayServer);
}
}

+ 26
- 0
TechbloxModdingAPI/Common/EcsObjectBaseEngine.cs View File

@@ -0,0 +1,26 @@
using Svelto.ECS;
using TechbloxModdingAPI.Common.Engines;

namespace TechbloxModdingAPI.Common;

public class EcsObjectBaseEngine : IApiEngine
{
public void Ready()
{
}

public EntitiesDB entitiesDB { get; set; }
public void Dispose()
{
}

public EntityReference GetEntityReference(EGID egid)
{
return entitiesDB is not null && egid != default ? egid.ToEntityReference(entitiesDB) : EntityReference.Invalid;
}

public EGID GetEgid(EntityReference reference)
{
return entitiesDB is not null && reference.ToEGID(entitiesDB, out var egid) ? egid : default;
}
}

TechbloxModdingAPI/Common/IApiEngine.cs → TechbloxModdingAPI/Common/Engines/IApiEngine.cs View File

@@ -1,7 +1,7 @@
using System;
using Svelto.ECS;

namespace TechbloxModdingAPI.Common;
namespace TechbloxModdingAPI.Common.Engines;

/// <summary>
/// Base engine interface used by all TechbloxModdingAPI engines

TechbloxModdingAPI/Common/INamedApiEngine.cs → TechbloxModdingAPI/Common/Engines/INamedApiEngine.cs View File

@@ -1,4 +1,4 @@
namespace TechbloxModdingAPI.Common;
namespace TechbloxModdingAPI.Common.Engines;

public interface INamedApiEngine : IApiEngine
{

+ 1
- 1
TechbloxModdingAPI/Common/Engines/IReactionaryEngine.cs View File

@@ -1,5 +1,5 @@
using Svelto.ECS;
using TechbloxModdingAPI.Common;
using TechbloxModdingAPI.Common.Engines;

namespace TechbloxModdingAPI.Engines
{


+ 1
- 1
TechbloxModdingAPI/Common/Utils/AsyncUtilsEngine.cs View File

@@ -1,9 +1,9 @@
using System.Collections;
using System.Threading.Tasks;
using RobocraftX.Schedulers;
using Svelto.ECS;
using Svelto.Tasks;
using Svelto.Tasks.ExtraLean;
using TechbloxModdingAPI.Common.Engines;

namespace TechbloxModdingAPI.Common.Utils;



+ 1
- 1
TechbloxModdingAPI/Input/FakeInputEngine.cs View File

@@ -2,7 +2,7 @@
using RobocraftX.Common.Input;
using RobocraftX.Players;
using Svelto.ECS;
using TechbloxModdingAPI.Common;
using TechbloxModdingAPI.Common.Engines;

namespace TechbloxModdingAPI.Input
{


+ 1
- 1
TechbloxModdingAPI/Player.cs View File

@@ -13,9 +13,9 @@ using Techblox.Camera;
using Techblox.Character;
using TechbloxModdingAPI.Blocks;
using TechbloxModdingAPI.Client.App;
using TechbloxModdingAPI.Common;
using TechbloxModdingAPI.Common.Engines;
using TechbloxModdingAPI.Players;
using TechbloxModdingAPI.Utility;
using UnityEngine;

namespace TechbloxModdingAPI


+ 1
- 1
TechbloxModdingAPI/Players/PlayerEventsEngine.cs View File

@@ -2,7 +2,7 @@ using RobocraftX.Character;
using RobocraftX.Character.Movement;
using RobocraftX.Common.Input;
using Svelto.ECS;
using TechbloxModdingAPI.Common;
using TechbloxModdingAPI.Common.Engines;

namespace TechbloxModdingAPI.Players
{


+ 1
- 2
TechbloxModdingAPI/SimBody.cs View File

@@ -2,11 +2,10 @@
using Svelto.ECS;
using Unity.Mathematics;
using UnityEngine;

using Gamecraft.Damage;
using RobocraftX.Common;
using RobocraftX.Physics;
using Techblox.TimeRunning.Clusters;
using TechbloxModdingAPI.Common;

namespace TechbloxModdingAPI
{


+ 1
- 1
TechbloxModdingAPI/Utility/DebugInterfaceEngine.cs View File

@@ -5,7 +5,7 @@ using System.Reflection.Emit;
using System.Text;
using HarmonyLib;
using Svelto.ECS;
using TechbloxModdingAPI.Common;
using TechbloxModdingAPI.Common.Engines;

namespace TechbloxModdingAPI.Utility
{


+ 1
- 0
TechbloxModdingAPI/Utility/ECS/ManagedApiExtensions.cs View File

@@ -1,5 +1,6 @@
using Svelto.ECS;
using Svelto.ECS.Hybrid;
using TechbloxModdingAPI.Common;

namespace TechbloxModdingAPI.Utility.ECS
{


+ 1
- 1
TechbloxModdingAPI/Utility/ECS/NativeApiExtensions.cs View File

@@ -1,9 +1,9 @@
using System;
using System.Collections.Generic;
using Svelto.DataStructures;
using Svelto.ECS;
using Svelto.Tasks;
using Svelto.Tasks.Lean;
using TechbloxModdingAPI.Common;
using TechbloxModdingAPI.Tasks;

namespace TechbloxModdingAPI.Utility.ECS


+ 1
- 1
TechbloxModdingAPI/Utility/GameStateEngine.cs View File

@@ -1,6 +1,6 @@
using Svelto.ECS;
using RobocraftX.SimulationModeState;
using TechbloxModdingAPI.Common;
using TechbloxModdingAPI.Common.Engines;

namespace TechbloxModdingAPI.Utility
{


+ 1
- 0
TechbloxModdingAPI/Utility/OptionalRef.cs View File

@@ -1,6 +1,7 @@
using System;
using Svelto.DataStructures;
using Svelto.ECS;
using TechbloxModdingAPI.Common;

namespace TechbloxModdingAPI.Utility
{


Loading…
Cancel
Save