Added 2 block events and removed BDNEException

Added an event for placing and removing blocks
Added a class to wrap event calls in a try-catch
Removed BlockDoesNotExistException
Made Block.GetSimBody() return null if block doesn't exist
This commit is contained in:
Norbi Peti 2020-06-02 03:12:40 +02:00
parent 98c7e624f8
commit dba7c0a46f
No known key found for this signature in database
GPG key ID: DBA4C4549A927E56
5 changed files with 98 additions and 22 deletions

View file

@ -25,6 +25,7 @@ namespace GamecraftModdingAPI
protected static readonly RotationEngine RotationEngine = new RotationEngine(); protected static readonly RotationEngine RotationEngine = new RotationEngine();
protected static readonly RemovalEngine RemovalEngine = new RemovalEngine(); protected static readonly RemovalEngine RemovalEngine = new RemovalEngine();
protected static readonly SignalEngine SignalEngine = new SignalEngine(); protected static readonly SignalEngine SignalEngine = new SignalEngine();
protected static readonly BlockEventsEngine BlockEventsEngine = new BlockEventsEngine();
protected internal static readonly BlockEngine BlockEngine = new BlockEngine(); protected internal static readonly BlockEngine BlockEngine = new BlockEngine();
@ -109,17 +110,27 @@ namespace GamecraftModdingAPI
return new Block(BlockIdentifiers.LatestBlockID); return new Block(BlockIdentifiers.LatestBlockID);
} }
/// <summary>
/// An event that fires each time a block is placed.
/// </summary>
public static event EventHandler<BlockPlacedRemovedEventArgs> Placed
{
add => BlockEventsEngine.Placed += value;
remove => BlockEventsEngine.Placed -= value;
}
/// <summary>
/// An event that fires each time a block is removed.
/// </summary>
public static event EventHandler<BlockPlacedRemovedEventArgs> Removed
{
add => BlockEventsEngine.Removed += value;
remove => BlockEventsEngine.Removed -= value;
}
public Block(EGID id) public Block(EGID id)
{ {
Id = id; Id = id;
if (!BlockEngine.BlockExists(Id))
{
/*Sync();
if (!BlockEngine.BlockExists(Id))
{
throw new BlockDoesNotExistException($"Block {Id.entityID} must be placed using PlaceNew(...) since it does not exist yet");
}*/
}
} }
public Block(uint id) : this(new EGID(id, CommonExclusiveGroups.OWNED_BLOCKS_GROUP)) public Block(uint id) : this(new EGID(id, CommonExclusiveGroups.OWNED_BLOCKS_GROUP))
@ -264,11 +275,11 @@ namespace GamecraftModdingAPI
/// Returns the rigid body of the cluster of blocks this one belongs to during simulation. /// Returns the rigid body of the cluster of blocks this one belongs to during simulation.
/// Can be used to apply forces or move the block around while the simulation is running. /// Can be used to apply forces or move the block around while the simulation is running.
/// </summary> /// </summary>
/// <returns>The SimBody of the cluster</returns> /// <returns>The SimBody of the cluster or null if the block doesn't exist.</returns>
public SimBody GetSimBody() public SimBody GetSimBody()
{ {
uint id = BlockEngine.GetBlockInfo<GridConnectionsEntityStruct>(Id).machineRigidBodyId; uint id = BlockEngine.GetBlockInfo<GridConnectionsEntityStruct>(Id, out var exists).machineRigidBodyId;
return new SimBody(id); return exists ? new SimBody(id) : null;
} }
public override string ToString() public override string ToString()
@ -283,6 +294,7 @@ namespace GamecraftModdingAPI
GameEngineManager.AddGameEngine(RotationEngine); GameEngineManager.AddGameEngine(RotationEngine);
GameEngineManager.AddGameEngine(RemovalEngine); GameEngineManager.AddGameEngine(RemovalEngine);
GameEngineManager.AddGameEngine(BlockEngine); GameEngineManager.AddGameEngine(BlockEngine);
GameEngineManager.AddGameEngine(BlockEventsEngine);
} }
/// <summary> /// <summary>

View file

@ -0,0 +1,42 @@
using System;
using GamecraftModdingAPI.Engines;
using GamecraftModdingAPI.Utility;
using RobocraftX.Common;
using Svelto.ECS;
namespace GamecraftModdingAPI.Blocks
{
public class BlockEventsEngine : IReactionaryEngine<DBEntityStruct>
{
public event EventHandler<BlockPlacedRemovedEventArgs> Placed;
public event EventHandler<BlockPlacedRemovedEventArgs> Removed;
public void Ready()
{
}
public EntitiesDB entitiesDB { get; set; }
public void Dispose()
{
}
public string Name { get; } = "GamecraftModdingAPIBlockEventsEngine";
public bool isRemovable { get; } = false;
public void Add(ref DBEntityStruct entityComponent, EGID egid)
{
ExceptionUtil.InvokeEvent(Placed, this, new BlockPlacedRemovedEventArgs {ID = egid, Type = (BlockIDs) entityComponent.DBID});
}
public void Remove(ref DBEntityStruct entityComponent, EGID egid)
{
ExceptionUtil.InvokeEvent(Removed, this, new BlockPlacedRemovedEventArgs {ID = egid, Type = (BlockIDs) entityComponent.DBID});
}
}
public struct BlockPlacedRemovedEventArgs
{
public EGID ID;
public BlockIDs Type;
}
}

View file

@ -40,15 +40,4 @@ namespace GamecraftModdingAPI.Blocks
{ {
} }
} }
public class BlockDoesNotExistException : BlockException
{
public BlockDoesNotExistException()
{
}
public BlockDoesNotExistException(string message) : base(message)
{
}
}
} }

View file

@ -226,6 +226,10 @@ namespace GamecraftModdingAPI.Tests
GameClient.SetDebugInfo("lookedAt", LookedAt); GameClient.SetDebugInfo("lookedAt", LookedAt);
GameClient.SetDebugInfo("InstalledMods", InstalledMods); GameClient.SetDebugInfo("InstalledMods", InstalledMods);
Block.Placed += (sender, args) =>
Logging.MetaDebugLog("Placed block " + args.Type + " with ID " + args.ID);
Block.Removed += (sender, args) =>
Logging.MetaDebugLog("Removed block " + args.Type + " with ID " + args.ID);
/* /*
CommandManager.AddCommand(new SimpleCustomCommandEngine<float>((float d) => { UnityEngine.Camera.main.fieldOfView = d; }, CommandManager.AddCommand(new SimpleCustomCommandEngine<float>((float d) => { UnityEngine.Camera.main.fieldOfView = d; },

View file

@ -0,0 +1,29 @@
using System;
using GamecraftModdingAPI.Events;
namespace GamecraftModdingAPI.Utility
{
public static class ExceptionUtil
{
/// <summary>
/// Invokes an event in a try-catch block to avoid propagating exceptions.
/// </summary>
/// <param name="handler">The event to emit, can be null</param>
/// <param name="sender">Event sender</param>
/// <param name="args">Event arguments</param>
/// <typeparam name="T">Type of the event arguments</typeparam>
public static void InvokeEvent<T>(EventHandler<T> handler, object sender, T args)
{
try
{
handler?.Invoke(sender, args);
}
catch (Exception e)
{
EventRuntimeException wrappedException =
new EventRuntimeException($"EventHandler with arg type {typeof(T).Name} threw an exception", e);
Logging.LogWarning(wrappedException.ToString());
}
}
}
}