Browse Source

Re-add async stuff, use new engine manager everywhere

feature/refactor.v3
NorbiPeti 7 months ago
parent
commit
27218aeb8d
Signed by: NorbiPeti <szatmari.norbert.peter@gmail.com> GPG Key ID: DBA4C4549A927E56
20 changed files with 264 additions and 298 deletions
  1. +2
    -2
      TechbloxModdingAPI/App/AppCallbacksTest.cs
  2. +5
    -5
      TechbloxModdingAPI/App/ClientAlertTest.cs
  3. +5
    -4
      TechbloxModdingAPI/App/Game.cs
  4. +13
    -11
      TechbloxModdingAPI/Block.cs
  5. +2
    -1
      TechbloxModdingAPI/BlockGroup.cs
  6. +54
    -35
      TechbloxModdingAPI/Blocks/Engine.cs
  7. +37
    -0
      TechbloxModdingAPI/Client/App/GameClient.cs
  8. +23
    -1
      TechbloxModdingAPI/Client/App/GameState.cs
  9. +3
    -3
      TechbloxModdingAPI/Common/Engines/EnginePatches.cs
  10. +38
    -0
      TechbloxModdingAPI/Common/Utils/AsyncUtils.cs
  11. +56
    -0
      TechbloxModdingAPI/Common/Utils/AsyncUtilsEngine.cs
  12. +2
    -2
      TechbloxModdingAPI/Input/FakeInput.cs
  13. +0
    -3
      TechbloxModdingAPI/Main.cs
  14. +1
    -3
      TechbloxModdingAPI/Persistence/SimpleEntitySerializer.cs
  15. +15
    -12
      TechbloxModdingAPI/Player.cs
  16. +2
    -1
      TechbloxModdingAPI/Players/PlayerEngine.cs
  17. +6
    -10
      TechbloxModdingAPI/Tests/TestRoot.cs
  18. +0
    -82
      TechbloxModdingAPI/Utility/GameEngineManager.cs
  19. +0
    -48
      TechbloxModdingAPI/Utility/GameState.cs
  20. +0
    -75
      TechbloxModdingAPI/Utility/MenuEngineManager.cs

+ 2
- 2
TechbloxModdingAPI/App/AppCallbacksTest.cs View File

@@ -20,8 +20,8 @@ namespace TechbloxModdingAPI.App
Game.Exit += Assert.CallsBack<GameEventArgs>("GameExit");
Game.Simulate += Assert.CallsBack<GameEventArgs>("GameSimulate");
Game.Edit += Assert.CallsBack<GameEventArgs>("GameEdit");
Client.EnterMenu += Assert.CallsBack<MenuEventArgs>("MenuEnter");
Client.ExitMenu += Assert.CallsBack<MenuEventArgs>("MenuExit");
/*Client.EnterMenu += Assert.CallsBack<MenuEventArgs>("MenuEnter");
Client.ExitMenu += Assert.CallsBack<MenuEventArgs>("MenuExit");*/
}

[APITestCase(TestType.Game)]


+ 5
- 5
TechbloxModdingAPI/App/ClientAlertTest.cs View File

@@ -2,7 +2,7 @@ using System;
using HarmonyLib;

using RobocraftX.Services;
using TechbloxModdingAPI.Client.App;
using TechbloxModdingAPI.Tests;

namespace TechbloxModdingAPI.App
@@ -42,25 +42,25 @@ namespace TechbloxModdingAPI.App
[APITestCase(TestType.Menu)]
public static void TestPopUp2()
{
Client.Instance.PromptUser(popup2);
Popup.PromptUser(popup2);
}
[APITestCase(TestType.Menu)]
public static void TestPopUp1()
{
Client.Instance.PromptUser(popup1);
Popup.PromptUser(popup1);
}

[APITestCase(TestType.Menu)]
public static void TestPopUpClose1()
{
Client.Instance.CloseCurrentPrompt();
Popup.CloseCurrentPrompt();
}
[APITestCase(TestType.Menu)]
public static void TestPopUpClose2()
{
Client.Instance.CloseCurrentPrompt();
Popup.CloseCurrentPrompt();
}
}
#endif

+ 5
- 4
TechbloxModdingAPI/App/Game.cs View File

@@ -7,6 +7,7 @@ using Svelto.ECS;
using Techblox.GameSelection;

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

@@ -481,10 +482,10 @@ namespace TechbloxModdingAPI.App

internal static void Init()
{
GameEngineManager.AddGameEngine(gameEngine);
GameEngineManager.AddGameEngine(debugOverlayEngine);
GameEngineManager.AddGameEngine(buildSimEventEngine);
MenuEngineManager.AddMenuEngine(menuEngine);
EngineManager.AddEngine(gameEngine, ApiEngineType.Build, ApiEngineType.PlayClient, ApiEngineType.PlayServer);
EngineManager.AddEngine(debugOverlayEngine, ApiEngineType.Build, ApiEngineType.PlayClient, ApiEngineType.PlayServer);
EngineManager.AddEngine(buildSimEventEngine, ApiEngineType.Build, ApiEngineType.PlayClient, ApiEngineType.PlayServer);
EngineManager.AddEngine(menuEngine, ApiEngineType.Menu);
}
}
}

+ 13
- 11
TechbloxModdingAPI/Block.cs View File

@@ -14,6 +14,8 @@ using RobocraftX.Rendering;
using Techblox.BlockLabelsServer;
using TechbloxModdingAPI.Blocks;
using TechbloxModdingAPI.Blocks.Engines;
using TechbloxModdingAPI.Client.App;
using TechbloxModdingAPI.Common.Engines;
using TechbloxModdingAPI.Tests;
using TechbloxModdingAPI.Utility;

@@ -48,7 +50,7 @@ namespace TechbloxModdingAPI
/// <returns>The placed block or null if failed</returns>
public static Block PlaceNew(BlockIDs block, float3 position, bool autoWire = false, Player player = null)
{
if (PlacementEngine.IsInGame && GameState.IsBuildMode())
if (PlacementEngine.IsInGame && GameClient.IsBuildMode)
{
var initializer = PlacementEngine.PlaceBlock(block, position, player, autoWire);
var egid = initializer.EGID;
@@ -346,7 +348,7 @@ namespace TechbloxModdingAPI
get
{
if (blockGroup != null) return blockGroup;
if (!GameState.IsBuildMode()) return null; // Breaks in simulation
if (!GameClient.IsBuildMode) return null; // Breaks in simulation
var bgec = BlockEngine.GetBlockInfo<BlockGroupEntityComponent>(this);
return blockGroup = bgec.currentBlockGroup == -1
? null
@@ -484,15 +486,15 @@ namespace TechbloxModdingAPI

public static void Init()
{
GameEngineManager.AddGameEngine(PlacementEngine);
GameEngineManager.AddGameEngine(MovementEngine);
GameEngineManager.AddGameEngine(RotationEngine);
GameEngineManager.AddGameEngine(RemovalEngine);
GameEngineManager.AddGameEngine(BlockEngine);
GameEngineManager.AddGameEngine(BlockEventsEngine);
GameEngineManager.AddGameEngine(ScalingEngine);
GameEngineManager.AddGameEngine(SignalEngine);
GameEngineManager.AddGameEngine(BlockCloneEngine);
EngineManager.AddEngine(PlacementEngine, ApiEngineType.Build);
EngineManager.AddEngine(MovementEngine, ApiEngineType.Build);
EngineManager.AddEngine(RotationEngine, ApiEngineType.Build);
EngineManager.AddEngine(RemovalEngine, ApiEngineType.Build);
EngineManager.AddEngine(BlockEngine, ApiEngineType.Build, ApiEngineType.PlayServer, ApiEngineType.PlayClient);
EngineManager.AddEngine(BlockEventsEngine, ApiEngineType.Build);
EngineManager.AddEngine(ScalingEngine, ApiEngineType.Build);
EngineManager.AddEngine(SignalEngine, ApiEngineType.Build);
EngineManager.AddEngine(BlockCloneEngine, ApiEngineType.Build);
Wire.signalEngine = SignalEngine; // requires same functionality, no need to duplicate the engine
}
}

+ 2
- 1
TechbloxModdingAPI/BlockGroup.cs View File

@@ -9,6 +9,7 @@ using UnityEngine;

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

namespace TechbloxModdingAPI
@@ -149,7 +150,7 @@ namespace TechbloxModdingAPI

internal static void Init()
{
GameEngineManager.AddGameEngine(_engine);
EngineManager.AddEngine(_engine, ApiEngineType.Build);
}

public IEnumerator<Block> GetEnumerator() => blocks.GetEnumerator();


+ 54
- 35
TechbloxModdingAPI/Blocks/Engine.cs View File

@@ -23,18 +23,18 @@ namespace TechbloxModdingAPI.Blocks
{
}
/*/// <summary> - TODO: Internal struct access
/// <summary>
/// Gets or sets the Engine's On property. May not be saved.
/// </summary>
public bool On
{
get
{
return BlockEngine.GetBlockInfo<Techblox.EngineBlock.EngineBlockComponent>(this).engineOn;
return ((bool)(BlockEngine.GetBlockInfo(this, HarmonyLib.AccessTools.TypeByName("Techblox.EngineBlock.EngineBlockComponent"), "engineOn")));
}
set
{
BlockEngine.GetBlockInfo<Techblox.EngineBlock.EngineBlockComponent>(this).engineOn = value;
BlockEngine.SetBlockInfo(this, HarmonyLib.AccessTools.TypeByName("Techblox.EngineBlock.EngineBlockComponent"), "engineOn", value);
}
}
@@ -45,11 +45,11 @@ namespace TechbloxModdingAPI.Blocks
{
get
{
return BlockEngine.GetBlockInfo<Techblox.EngineBlock.EngineBlockComponent>(this).currentGear;
return ((int)(BlockEngine.GetBlockInfo(this, HarmonyLib.AccessTools.TypeByName("Techblox.EngineBlock.EngineBlockComponent"), "currentGear")));
}
set
{
BlockEngine.GetBlockInfo<Techblox.EngineBlock.EngineBlockComponent>(this).currentGear = value;
BlockEngine.SetBlockInfo(this, HarmonyLib.AccessTools.TypeByName("Techblox.EngineBlock.EngineBlockComponent"), "currentGear", value);
}
}
@@ -60,11 +60,11 @@ namespace TechbloxModdingAPI.Blocks
{
get
{
return BlockEngine.GetBlockInfo<Techblox.EngineBlock.EngineBlockComponent>(this).gearChangeCountdown;
return ((float)(BlockEngine.GetBlockInfo(this, HarmonyLib.AccessTools.TypeByName("Techblox.EngineBlock.EngineBlockComponent"), "gearChangeCountdown")));
}
set
{
BlockEngine.GetBlockInfo<Techblox.EngineBlock.EngineBlockComponent>(this).gearChangeCountdown = value;
BlockEngine.SetBlockInfo(this, HarmonyLib.AccessTools.TypeByName("Techblox.EngineBlock.EngineBlockComponent"), "gearChangeCountdown", value);
}
}
@@ -75,11 +75,11 @@ namespace TechbloxModdingAPI.Blocks
{
get
{
return BlockEngine.GetBlockInfo<Techblox.EngineBlock.EngineBlockComponent>(this).currentRpmAV;
return ((float)(BlockEngine.GetBlockInfo(this, HarmonyLib.AccessTools.TypeByName("Techblox.EngineBlock.EngineBlockComponent"), "currentRpmAV")));
}
set
{
BlockEngine.GetBlockInfo<Techblox.EngineBlock.EngineBlockComponent>(this).currentRpmAV = value;
BlockEngine.SetBlockInfo(this, HarmonyLib.AccessTools.TypeByName("Techblox.EngineBlock.EngineBlockComponent"), "currentRpmAV", value);
}
}
@@ -90,11 +90,11 @@ namespace TechbloxModdingAPI.Blocks
{
get
{
return BlockEngine.GetBlockInfo<Techblox.EngineBlock.EngineBlockComponent>(this).currentRpmLV;
return ((float)(BlockEngine.GetBlockInfo(this, HarmonyLib.AccessTools.TypeByName("Techblox.EngineBlock.EngineBlockComponent"), "currentRpmLV")));
}
set
{
BlockEngine.GetBlockInfo<Techblox.EngineBlock.EngineBlockComponent>(this).currentRpmLV = value;
BlockEngine.SetBlockInfo(this, HarmonyLib.AccessTools.TypeByName("Techblox.EngineBlock.EngineBlockComponent"), "currentRpmLV", value);
}
}
@@ -105,11 +105,11 @@ namespace TechbloxModdingAPI.Blocks
{
get
{
return BlockEngine.GetBlockInfo<Techblox.EngineBlock.EngineBlockComponent>(this).targetRpmAV;
return ((float)(BlockEngine.GetBlockInfo(this, HarmonyLib.AccessTools.TypeByName("Techblox.EngineBlock.EngineBlockComponent"), "targetRpmAV")));
}
set
{
BlockEngine.GetBlockInfo<Techblox.EngineBlock.EngineBlockComponent>(this).targetRpmAV = value;
BlockEngine.SetBlockInfo(this, HarmonyLib.AccessTools.TypeByName("Techblox.EngineBlock.EngineBlockComponent"), "targetRpmAV", value);
}
}
@@ -120,11 +120,11 @@ namespace TechbloxModdingAPI.Blocks
{
get
{
return BlockEngine.GetBlockInfo<Techblox.EngineBlock.EngineBlockComponent>(this).targetRpmLV;
return ((float)(BlockEngine.GetBlockInfo(this, HarmonyLib.AccessTools.TypeByName("Techblox.EngineBlock.EngineBlockComponent"), "targetRpmLV")));
}
set
{
BlockEngine.GetBlockInfo<Techblox.EngineBlock.EngineBlockComponent>(this).targetRpmLV = value;
BlockEngine.SetBlockInfo(this, HarmonyLib.AccessTools.TypeByName("Techblox.EngineBlock.EngineBlockComponent"), "targetRpmLV", value);
}
}
@@ -135,11 +135,11 @@ namespace TechbloxModdingAPI.Blocks
{
get
{
return BlockEngine.GetBlockInfo<Techblox.EngineBlock.EngineBlockComponent>(this).currentTorque;
return ((float)(BlockEngine.GetBlockInfo(this, HarmonyLib.AccessTools.TypeByName("Techblox.EngineBlock.EngineBlockComponent"), "currentTorque")));
}
set
{
BlockEngine.GetBlockInfo<Techblox.EngineBlock.EngineBlockComponent>(this).currentTorque = value;
BlockEngine.SetBlockInfo(this, HarmonyLib.AccessTools.TypeByName("Techblox.EngineBlock.EngineBlockComponent"), "currentTorque", value);
}
}
@@ -150,11 +150,11 @@ namespace TechbloxModdingAPI.Blocks
{
get
{
return BlockEngine.GetBlockInfo<Techblox.EngineBlock.EngineBlockComponent>(this).totalWheelVelocityAV;
return ((float)(BlockEngine.GetBlockInfo(this, HarmonyLib.AccessTools.TypeByName("Techblox.EngineBlock.EngineBlockComponent"), "totalWheelVelocityAV")));
}
set
{
BlockEngine.GetBlockInfo<Techblox.EngineBlock.EngineBlockComponent>(this).totalWheelVelocityAV = value;
BlockEngine.SetBlockInfo(this, HarmonyLib.AccessTools.TypeByName("Techblox.EngineBlock.EngineBlockComponent"), "totalWheelVelocityAV", value);
}
}
@@ -165,11 +165,11 @@ namespace TechbloxModdingAPI.Blocks
{
get
{
return BlockEngine.GetBlockInfo<Techblox.EngineBlock.EngineBlockComponent>(this).totalWheelVelocityLV;
return ((float)(BlockEngine.GetBlockInfo(this, HarmonyLib.AccessTools.TypeByName("Techblox.EngineBlock.EngineBlockComponent"), "totalWheelVelocityLV")));
}
set
{
BlockEngine.GetBlockInfo<Techblox.EngineBlock.EngineBlockComponent>(this).totalWheelVelocityLV = value;
BlockEngine.SetBlockInfo(this, HarmonyLib.AccessTools.TypeByName("Techblox.EngineBlock.EngineBlockComponent"), "totalWheelVelocityLV", value);
}
}
@@ -180,11 +180,11 @@ namespace TechbloxModdingAPI.Blocks
{
get
{
return BlockEngine.GetBlockInfo<Techblox.EngineBlock.EngineBlockComponent>(this).totalWheelCount;
return ((int)(BlockEngine.GetBlockInfo(this, HarmonyLib.AccessTools.TypeByName("Techblox.EngineBlock.EngineBlockComponent"), "totalWheelCount")));
}
set
{
BlockEngine.GetBlockInfo<Techblox.EngineBlock.EngineBlockComponent>(this).totalWheelCount = value;
BlockEngine.SetBlockInfo(this, HarmonyLib.AccessTools.TypeByName("Techblox.EngineBlock.EngineBlockComponent"), "totalWheelCount", value);
}
}
@@ -195,11 +195,11 @@ namespace TechbloxModdingAPI.Blocks
{
get
{
return BlockEngine.GetBlockInfo<Techblox.EngineBlock.EngineBlockComponent>(this).lastGearUpInput;
return ((bool)(BlockEngine.GetBlockInfo(this, HarmonyLib.AccessTools.TypeByName("Techblox.EngineBlock.EngineBlockComponent"), "lastGearUpInput")));
}
set
{
BlockEngine.GetBlockInfo<Techblox.EngineBlock.EngineBlockComponent>(this).lastGearUpInput = value;
BlockEngine.SetBlockInfo(this, HarmonyLib.AccessTools.TypeByName("Techblox.EngineBlock.EngineBlockComponent"), "lastGearUpInput", value);
}
}
@@ -210,11 +210,11 @@ namespace TechbloxModdingAPI.Blocks
{
get
{
return BlockEngine.GetBlockInfo<Techblox.EngineBlock.EngineBlockComponent>(this).lastGearDownInput;
return ((bool)(BlockEngine.GetBlockInfo(this, HarmonyLib.AccessTools.TypeByName("Techblox.EngineBlock.EngineBlockComponent"), "lastGearDownInput")));
}
set
{
BlockEngine.GetBlockInfo<Techblox.EngineBlock.EngineBlockComponent>(this).lastGearDownInput = value;
BlockEngine.SetBlockInfo(this, HarmonyLib.AccessTools.TypeByName("Techblox.EngineBlock.EngineBlockComponent"), "lastGearDownInput", value);
}
}
@@ -225,11 +225,11 @@ namespace TechbloxModdingAPI.Blocks
{
get
{
return BlockEngine.GetBlockInfo<Techblox.EngineBlock.EngineBlockComponent>(this).manualToAutoGearCoolOffCounter;
return ((float)(BlockEngine.GetBlockInfo(this, HarmonyLib.AccessTools.TypeByName("Techblox.EngineBlock.EngineBlockComponent"), "manualToAutoGearCoolOffCounter")));
}
set
{
BlockEngine.GetBlockInfo<Techblox.EngineBlock.EngineBlockComponent>(this).manualToAutoGearCoolOffCounter = value;
BlockEngine.SetBlockInfo(this, HarmonyLib.AccessTools.TypeByName("Techblox.EngineBlock.EngineBlockComponent"), "manualToAutoGearCoolOffCounter", value);
}
}
@@ -240,11 +240,11 @@ namespace TechbloxModdingAPI.Blocks
{
get
{
return BlockEngine.GetBlockInfo<Techblox.EngineBlock.EngineBlockComponent>(this).load;
return ((float)(BlockEngine.GetBlockInfo(this, HarmonyLib.AccessTools.TypeByName("Techblox.EngineBlock.EngineBlockComponent"), "load")));
}
set
{
BlockEngine.GetBlockInfo<Techblox.EngineBlock.EngineBlockComponent>(this).load = value;
BlockEngine.SetBlockInfo(this, HarmonyLib.AccessTools.TypeByName("Techblox.EngineBlock.EngineBlockComponent"), "load", value);
}
}
@@ -324,13 +324,17 @@ namespace TechbloxModdingAPI.Blocks
}
/// <summary>
/// Gets the Engine's GearDownRpms property. May not be saved.
/// Gets or sets the Engine's GearDownRpms property. May not be saved.
/// </summary>
public float[] GearDownRpms
public Svelto.ECS.DataStructures.NativeDynamicArray GearDownRpms
{
get
{
return BlockEngine.GetBlockInfo<Techblox.EngineBlock.EngineBlockReadonlyComponent>(this).gearDownRpms.ToManagedArray<float>();
return BlockEngine.GetBlockInfo<Techblox.EngineBlock.EngineBlockReadonlyComponent>(this).gearDownRpms;
}
set
{
BlockEngine.GetBlockInfo<Techblox.EngineBlock.EngineBlockReadonlyComponent>(this).gearDownRpms = value;
}
}
@@ -377,6 +381,21 @@ namespace TechbloxModdingAPI.Blocks
{
BlockEngine.GetBlockInfo<Techblox.EngineBlock.EngineBlockReadonlyComponent>(this).manualToAutoGearCoolOffTime = value;
}
}*/
}
/// <summary>
/// Gets or sets the Engine's EngineBlockDataId property. May not be saved.
/// </summary>
public int EngineBlockDataId
{
get
{
return BlockEngine.GetBlockInfo<Techblox.EngineBlock.EngineBlockReadonlyComponent>(this).engineBlockDataId;
}
set
{
BlockEngine.GetBlockInfo<Techblox.EngineBlock.EngineBlockReadonlyComponent>(this).engineBlockDataId = value;
}
}
}
}

+ 37
- 0
TechbloxModdingAPI/Client/App/GameClient.cs View File

@@ -1,4 +1,7 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Svelto.Tasks;
using TechbloxModdingAPI.Client.Game;
using TechbloxModdingAPI.Common.Engines;
using TechbloxModdingAPI.Utility;
@@ -26,6 +29,11 @@ public static class GameClient

private static GameState _currentState;

public static bool IsBuildMode =>
CurrentState is GameState.InMachineEditor or GameState.InWorldEditor;

public static bool IsSimulationMode =>
CurrentState is GameState.InTestMode or GameState.InWorldTestMode or GameState.InOnlineMatch;

/// <summary>
/// An event that fires whenever the game's state changes
@@ -62,10 +70,39 @@ public static class GameClient

public static void EnterBuildMode(ClientEnvironment environment, ClientMachine machine)
{
if (CurrentState == GameState.InMenu)
throw new InvalidOperationException($"Can only enter test mode from build mode! Current mode: {CurrentState}");
var env = new ClientEnvironment("GAMEID_Road_Track"); // TODO: The options are hardcoded
_engine.EnterBuildMode(env, machine);
}

public static IEnumerator<TaskContract> EnterTestMode()
{
if (!IsBuildMode)
throw new InvalidOperationException($"Can only enter test mode from build mode! Current mode: {CurrentState}");
// TODO
//return Task.CompletedTask;
yield break;
}

public static IEnumerator<TaskContract> ExitSimulationMode()
{ // TODO: Separate these based on the current game state?
if (!IsSimulationMode)
throw new InvalidOperationException($"Can only exit test mode when in it! Current mode: {CurrentState}");
// TODO
//return Task.CompletedTask;
yield break;
}

public static IEnumerator<TaskContract> ExitBuildMode()
{
if (!IsBuildMode)
throw new InvalidOperationException($"Can only exit test mode when in it! Current mode: {CurrentState}");
// TODO
//return Task.CompletedTask;
yield break;
}

public static void Init()
{
EngineManager.AddEngine(_engine, ApiEngineType.Menu);


+ 23
- 1
TechbloxModdingAPI/Client/App/GameState.cs View File

@@ -2,10 +2,32 @@ namespace TechbloxModdingAPI.Client.App;

public enum GameState
{
/// <summary>
/// In the environment/game selection menu.
/// </summary>
InMenu,
/// <summary>
/// In machine editor mode in a selected environment.
/// </summary>
InMachineEditor,
/// <summary>
/// In world editor mode.
/// </summary>
InWorldEditor,
/// <summary>
/// In test mode in a selected environment.
/// </summary>
InTestMode,
InMatch,
/// <summary>
/// In world test mode.
/// </summary>
InWorldTestMode,
/// <summary>
/// In an online match as a client.
/// </summary>
InOnlineMatch,
/// <summary>
/// The loading screen is active or otherwise transitioning between modes.
/// </summary>
Loading
}

+ 3
- 3
TechbloxModdingAPI/Common/Engines/EnginePatches.cs View File

@@ -18,7 +18,7 @@ namespace TechbloxModdingAPI.Common.Engines
{
Client.App.GameClient.CurrentState = GameState.InMachineEditor; // TODO: World editor
// register all game engines, including deterministic
GameEngineManager.RegisterEngines(stateSyncReg);
EngineManager.RegisterEngines(stateSyncReg, stateSyncReg.enginesRoot, ApiEngineType.Build);
// register command engines
CommandManager.RegisterEngines(stateSyncReg.enginesRoot);
}
@@ -35,7 +35,7 @@ namespace TechbloxModdingAPI.Common.Engines
public static void Postfix(StateSyncRegistrationHelper stateSyncReg)
{
Client.App.GameClient.CurrentState = GameState.InTestMode; // TODO: Client/server
GameEngineManager.RegisterEngines(stateSyncReg);
EngineManager.RegisterEngines(stateSyncReg, stateSyncReg.enginesRoot, ApiEngineType.PlayClient); // TODO: Client/server
CommandManager.RegisterEngines(stateSyncReg.enginesRoot);
}

@@ -89,7 +89,7 @@ namespace TechbloxModdingAPI.Common.Engines
{
Client.App.GameClient.CurrentState = GameState.InMenu; // TODO: Loaded states
// register menu engines
MenuEngineManager.RegisterEngines(enginesRoot);
EngineManager.RegisterEngines(null, enginesRoot, ApiEngineType.Menu);
}

public static MethodBase TargetMethod()


+ 38
- 0
TechbloxModdingAPI/Common/Utils/AsyncUtils.cs View File

@@ -0,0 +1,38 @@
using System.Threading.Tasks;
using RobocraftX.Schedulers;
using Svelto.ECS;
using Techblox.Server.Schedulers;
using TechbloxModdingAPI.Common.Engines;
using TechbloxModdingAPI.Utility;

namespace TechbloxModdingAPI.Common.Utils;

public static class AsyncUtils
{
private static AsyncUtilsEngine gameEngine = new();

/// <summary>
/// Waits for entity submission asynchronously.
/// Use after placing a block or otherwise creating things in the game to access their properties.
/// </summary>
public static async Task WaitForSubmission()
{
await gameEngine.WaitForSubmission();
}

public static async Task WaitForNextFrame()
{
await gameEngine.WaitForNextFrame();
}

public static void Setup(EnginesRoot enginesRoot, bool clientside)
{
gameEngine.Setup(enginesRoot,
clientside ? ClientExtraLean.UIScheduler : ServerExtraLean.DeterministicTimeRunningStepRunner);
}

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

+ 56
- 0
TechbloxModdingAPI/Common/Utils/AsyncUtilsEngine.cs View File

@@ -0,0 +1,56 @@
using System.Collections;
using System.Threading.Tasks;
using RobocraftX.Schedulers;
using Svelto.ECS;
using Svelto.Tasks;
using Svelto.Tasks.ExtraLean;

namespace TechbloxModdingAPI.Common.Utils;

public class AsyncUtilsEngine : IApiEngine
{
private EnginesRoot _enginesRoot;
private IRunner<ExtraLeanSveltoTask<IEnumerator>> _runner;
private IEnumerator WaitForSubmissionInternal(TaskCompletionSource<object> task)
{
var waitEnumerator = new WaitForSubmissionEnumerator(_enginesRoot.scheduler);
while (waitEnumerator.MoveNext())
yield return null;
task.SetResult(null);
}

private IEnumerator WaitForNextFrameInternal(TaskCompletionSource<object> task)
{
yield return null;
task.SetResult(null);
}

public Task WaitForSubmission()
{
var task = new TaskCompletionSource<object>();
WaitForSubmissionInternal(task).RunOn(_runner);
return task.Task;
}

public Task WaitForNextFrame()
{
var task = new TaskCompletionSource<object>();
WaitForNextFrameInternal(task).RunOn(_runner);
return task.Task;
}

public void Setup(EnginesRoot enginesRoot, IRunner<ExtraLeanSveltoTask<IEnumerator>> runner)
{ // TODO: Different engines roots for different sides
_enginesRoot = enginesRoot;
_runner = runner;
}

public void Ready()
{
}

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

+ 2
- 2
TechbloxModdingAPI/Input/FakeInput.cs View File

@@ -1,6 +1,7 @@
using RobocraftX.Common.Input;

using TechbloxModdingAPI.App;
using TechbloxModdingAPI.Common.Engines;
using TechbloxModdingAPI.Utility;

namespace TechbloxModdingAPI.Input
@@ -138,8 +139,7 @@ namespace TechbloxModdingAPI.Input

public static void Init()
{
GameEngineManager.AddGameEngine(inputEngine);
MenuEngineManager.AddMenuEngine(inputEngine);
EngineManager.AddEngine(inputEngine, ApiEngineType.Build, ApiEngineType.Menu, ApiEngineType.PlayClient, ApiEngineType.PlayServer);
}
}
}

+ 0
- 3
TechbloxModdingAPI/Main.cs View File

@@ -56,9 +56,6 @@ namespace TechbloxModdingAPI

try
{
// init utility
Logging.MetaDebugLog($"Initializing Utility");
Utility.GameState.Init();
// init block implementors
Logging.MetaDebugLog($"Initializing Blocks");
// init input


+ 1
- 3
TechbloxModdingAPI/Persistence/SimpleEntitySerializer.cs View File

@@ -1,6 +1,4 @@
using System;

using Svelto.ECS;
using Svelto.ECS;
using Svelto.ECS.Serialization;

using RobocraftX.Common;


+ 15
- 12
TechbloxModdingAPI/Player.cs View File

@@ -12,6 +12,8 @@ using Techblox.BuildingDrone;
using Techblox.Camera;
using Techblox.Character;
using TechbloxModdingAPI.Blocks;
using TechbloxModdingAPI.Client.App;
using TechbloxModdingAPI.Common.Engines;
using TechbloxModdingAPI.Players;
using TechbloxModdingAPI.Utility;
using UnityEngine;
@@ -131,10 +133,10 @@ namespace TechbloxModdingAPI
/// <value>The rotation.</value>
public float3 Rotation
{
get => ((Quaternion) (GameState.IsBuildMode()
get => ((Quaternion) (GameClient.IsBuildMode
? playerEngine.GetCameraStruct<CameraEntityStruct>(Id).Get().rotation
: playerEngine.GetCharacterStruct<RigidBodyEntityStruct>(Id).Get().rotation)).eulerAngles;
set => _ = GameState.IsBuildMode()
set => _ = GameClient.IsBuildMode
? playerEngine.GetCameraStruct<CameraEntityStruct>(Id).Get().rotation = quaternion.Euler(value)
: playerEngine.GetCharacterStruct<RigidBodyEntityStruct>(Id).Get().rotation = quaternion.Euler(value);
}
@@ -344,10 +346,10 @@ namespace TechbloxModdingAPI
/// </summary>
public bool Sprinting
{
get => GameState.IsBuildMode()
get => GameClient.IsBuildMode
? playerEngine.GetCharacterStruct<BuildingDroneMovementComponent>(Id).Get().sprinting
: playerEngine.GetCharacterStruct<CharacterMovementEntityStruct>(Id).Get().isSprinting;
set => _ = GameState.IsBuildMode()
set => _ = GameClient.IsBuildMode
? playerEngine.GetCharacterStruct<BuildingDroneMovementComponent>(Id).Get().sprinting = value
: playerEngine.GetCharacterStruct<CharacterMovementEntityStruct>(Id).Get().isSprinting = value;
}
@@ -357,10 +359,10 @@ namespace TechbloxModdingAPI
/// </summary>
public float SpeedSetting
{
get => GameState.IsBuildMode()
get => GameClient.IsBuildMode
? playerEngine.GetCharacterStruct<BuildingDroneMovementSettingsComponent>(Id).Get().speed
: playerEngine.GetCharacterStruct<CharacterMovementSettingsEntityStruct>(Id).Get().moveSpeed;
set => _ = GameState.IsBuildMode()
set => _ = GameClient.IsBuildMode
? playerEngine.GetCharacterStruct<BuildingDroneMovementSettingsComponent>(Id).Get().speed = value
: playerEngine.GetCharacterStruct<CharacterMovementSettingsEntityStruct>(Id).Get().moveSpeed = value;
}
@@ -370,10 +372,10 @@ namespace TechbloxModdingAPI
/// </summary>
public float SpeedSprintMultiplierSetting
{
get => GameState.IsBuildMode()
get => GameClient.IsBuildMode
? playerEngine.GetCharacterStruct<BuildingDroneMovementSettingsComponent>(Id).Get().speedSprintMultiplier
: playerEngine.GetCharacterStruct<CharacterMovementSettingsEntityStruct>(Id).Get().sprintSpeedMultiplier;
set => _ = GameState.IsBuildMode()
set => _ = GameClient.IsBuildMode
? playerEngine.GetCharacterStruct<BuildingDroneMovementSettingsComponent>(Id).Get().speedSprintMultiplier = value
: playerEngine.GetCharacterStruct<CharacterMovementSettingsEntityStruct>(Id).Get().sprintSpeedMultiplier = value;
}
@@ -383,10 +385,10 @@ namespace TechbloxModdingAPI
/// </summary>
public float AccelerationSetting
{
get => GameState.IsBuildMode()
get => GameClient.IsBuildMode
? playerEngine.GetCharacterStruct<BuildingDroneMovementSettingsComponent>(Id).Get().acceleration
: playerEngine.GetCharacterStruct<CharacterMovementSettingsEntityStruct>(Id).Get().acceleration;
set => _ = GameState.IsBuildMode()
set => _ = GameClient.IsBuildMode
? playerEngine.GetCharacterStruct<BuildingDroneMovementSettingsComponent>(Id).Get().acceleration = value
: playerEngine.GetCharacterStruct<CharacterMovementSettingsEntityStruct>(Id).Get().acceleration = value;
}
@@ -539,8 +541,9 @@ namespace TechbloxModdingAPI

internal static void Init()
{
Utility.GameEngineManager.AddGameEngine(playerEngine);
Utility.GameEngineManager.AddGameEngine(playerEventsEngine);
// TODO: Separate build mode, client and server into separate classes
EngineManager.AddEngine(playerEngine, ApiEngineType.Build, ApiEngineType.PlayClient, ApiEngineType.PlayServer);
EngineManager.AddEngine(playerEventsEngine, ApiEngineType.Build, ApiEngineType.PlayClient, ApiEngineType.PlayServer);
}
}
}

+ 2
- 1
TechbloxModdingAPI/Players/PlayerEngine.cs View File

@@ -16,6 +16,7 @@ using Techblox.Camera;
using Unity.Mathematics;
using Techblox.BuildingDrone;
using Techblox.Character;
using TechbloxModdingAPI.Client.App;
using TechbloxModdingAPI.Common.Engines;
using TechbloxModdingAPI.Input;
using TechbloxModdingAPI.Utility;
@@ -129,7 +130,7 @@ namespace TechbloxModdingAPI.Players
public OptionalRef<T> GetCharacterStruct<T>(uint playerId, out ExclusiveGroupStruct group) where T : unmanaged, IEntityComponent
{
group = default;
if (GameState.IsBuildMode())
if (GameClient.IsBuildMode)
return entitiesDB.QueryEntityOptional<T>(new EGID(playerId, LocalBuildingDrone.BuildGroup));

var characterGroups = CharacterExclusiveGroups.AllCharacters;


+ 6
- 10
TechbloxModdingAPI/Tests/TestRoot.cs View File

@@ -9,6 +9,7 @@ using Svelto.Tasks.Lean;
using Svelto.Tasks.Enumerators;
using Svelto.Tasks.Lean.Unity;
using TechbloxModdingAPI.Client.App;
using TechbloxModdingAPI.Client.Game;
using UnityEngine;

using TechbloxModdingAPI.Tasks;
@@ -155,7 +156,7 @@ namespace TechbloxModdingAPI.Tests
yield return Yield.It;
try
{
GameClient.Machines[0].EnterGame();
GameClient.EnterBuildMode(new ClientEnvironment("GAMEID_Road_Track"), GameClient.Machines[0]);
}
catch (Exception e)
{
@@ -170,7 +171,6 @@ namespace TechbloxModdingAPI.Tests
private static IEnumerator<TaskContract> GameTests()
{
yield return Yield.It;
Game currentGame = Game.CurrentGame();
// in-game tests
yield return new WaitForSecondsEnumerator(5).Continue(); // wait for game to finish loading
var testTypesToRun = new[]
@@ -225,13 +225,9 @@ namespace TechbloxModdingAPI.Tests

if (index + 1 < testTypesToRun.Length) //Don't toggle on the last test
{
bool running = currentGame.IsTimeRunning;
currentGame.ToggleTimeMode();
while (running ? !currentGame.IsTimeStopped : !currentGame.IsTimeRunning)
{
Logging.MetaLog($"Waiting for time to {(running?"stop":"start")}...");
yield return new WaitForSecondsEnumerator(1).Continue();
}
bool running = GameClient.IsSimulationMode;
if (running) yield return GameClient.EnterTestMode().Continue();
else yield return GameClient.ExitSimulationMode().Continue();
}

yield return new WaitForSecondsEnumerator(5).Continue();
@@ -244,7 +240,7 @@ namespace TechbloxModdingAPI.Tests
{
Logging.MetaLog("Returning to main menu");
yield return Yield.It;
Game.CurrentGame().ExitGame();
yield return GameClient.ExitSimulationMode().Continue();
}

private static IEnumerator<TaskContract> TearDown()


+ 0
- 82
TechbloxModdingAPI/Utility/GameEngineManager.cs View File

@@ -1,82 +0,0 @@
using System.Collections.Generic;
using System.Linq;

using RobocraftX.StateSync;
using Svelto.ECS;
using TechbloxModdingAPI.Common;
using TechbloxModdingAPI.Common.Engines;

namespace TechbloxModdingAPI.Utility
{
/// <summary>
/// Keeps track of custom game-modifying engines
/// </summary>
public static class GameEngineManager
{
private static Dictionary<string, IApiEngine> _gameEngines = new();

private static EnginesRoot _lastEngineRoot;

public static void AddGameEngine(IApiEngine engine)
{
_gameEngines[engine.Name] = engine;
if (_lastEngineRoot != null)
{
Logging.MetaDebugLog($"Registering Game IApiEngine {engine.Name}");
_lastEngineRoot.AddEngine(engine);
if (engine is IFactoryEngine factoryEngine)
factoryEngine.Factory = _lastEngineRoot.GenerateEntityFactory();
if (engine is IFunEngine funEngine)
funEngine.Functions = _lastEngineRoot.GenerateEntityFunctions();
}
}

public static bool ExistsGameEngine(string name)
{
return _gameEngines.ContainsKey(name);
}

public static bool ExistsGameEngine(IApiEngine engine)
{
return ExistsGameEngine(engine.Name);
}

public static IApiEngine GetGameEngine(string name)
{
return _gameEngines[name];
}

public static string[] GetGameEngineNames()
{
return _gameEngines.Keys.ToArray();
}

public static void RemoveGameEngine(string name)
{
if (_gameEngines[name].isRemovable)
{
_gameEngines.Remove(name);
}
}

public static void RegisterEngines(StateSyncRegistrationHelper helper)
{
var enginesRoot = helper.enginesRoot;
_lastEngineRoot = enginesRoot;
IEntityFactory factory = enginesRoot.GenerateEntityFactory();
IEntityFunctions functions = enginesRoot.GenerateEntityFunctions();
foreach (var key in _gameEngines.Keys)
{
Logging.MetaDebugLog($"Registering Game IApiEngine {_gameEngines[key].Name}");
if (_gameEngines[key] is IDeterministicEngine detEngine)
helper.AddDeterministicEngine(detEngine);
else
enginesRoot.AddEngine(_gameEngines[key]);
if (_gameEngines[key] is IFactoryEngine factEngine)
factEngine.Factory = factory;
if (_gameEngines[key] is IFunEngine funEngine)
funEngine.Functions = functions;
}
}
}
}

+ 0
- 48
TechbloxModdingAPI/Utility/GameState.cs View File

@@ -1,48 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace TechbloxModdingAPI.Utility
{
/// <summary>
/// Utility to get the state of the current Techblox game
/// </summary>
public static class GameState
{
private static GameStateEngine gameEngine = new();

/// <summary>
/// Is the game in edit mode?
/// </summary>
/// <returns>Whether the game is in build mode</returns>
public static bool IsBuildMode()
{
return gameEngine.IsBuildMode();
}

/// <summary>
/// Is the game in simulation mode?
/// </summary>
/// <returns>Whether the game is in simulation mode</returns>
public static bool IsSimulationMode()
{
return gameEngine.IsSimulationMode();
}

/// <summary>
/// Is a game loaded?
/// </summary>
/// <returns>Whether Techblox has a game open (false = Main Menu)</returns>
public static bool IsInGame()
{
return gameEngine.IsInGame;
}

public static void Init()
{
GameEngineManager.AddGameEngine(gameEngine);
}
}
}

+ 0
- 75
TechbloxModdingAPI/Utility/MenuEngineManager.cs View File

@@ -1,75 +0,0 @@
using System.Collections.Generic;
using System.Linq;
using Svelto.ECS;
using TechbloxModdingAPI.Common;
using TechbloxModdingAPI.Common.Engines;

namespace TechbloxModdingAPI.Utility
{
/// <summary>
/// Keeps track of custom menu-modifying engines
/// </summary>
public static class MenuEngineManager
{
private static Dictionary<string, IApiEngine> _menuEngines = new();

private static EnginesRoot _lastEngineRoot;

// menu engine management
public static void AddMenuEngine(IApiEngine engine)
{
_menuEngines[engine.Name] = engine;
if (_lastEngineRoot != null)
{
Logging.MetaDebugLog($"Registering Menu IApiEngine {engine.Name}");
_lastEngineRoot.AddEngine(engine);
if (engine is IFactoryEngine factoryEngine)
factoryEngine.Factory = _lastEngineRoot.GenerateEntityFactory();
if (engine is IFunEngine funEngine)
funEngine.Functions = _lastEngineRoot.GenerateEntityFunctions();
}
}

public static bool ExistsMenuEngine(string name)
{
return _menuEngines.ContainsKey(name);
}

public static bool ExistsMenuEngine(IApiEngine engine)
{
return ExistsMenuEngine(engine.Name);
}

public static IApiEngine GetMenuEngine(string name)
{
return _menuEngines[name];
}

public static string[] GetMenuEngineNames()
{
return _menuEngines.Keys.ToArray();
}

public static void RemoveMenuEngine(string name)
{
if (_menuEngines[name].isRemovable)
{
_menuEngines.Remove(name);
}
}

public static void RegisterEngines(EnginesRoot enginesRoot)
{
_lastEngineRoot = enginesRoot;
IEntityFactory factory = enginesRoot.GenerateEntityFactory();
IEntityFunctions functions = enginesRoot.GenerateEntityFunctions();
foreach (var key in _menuEngines.Keys)
{
Logging.MetaDebugLog($"Registering Menu IApiEngine {_menuEngines[key].Name}");
enginesRoot.AddEngine(_menuEngines[key]);
if (_menuEngines[key] is IFactoryEngine factEngine) factEngine.Factory = factory;
if(_menuEngines[key] is IFunEngine funEngine) funEngine.Functions = functions;
}
}
}
}

Loading…
Cancel
Save