Add general purpose engine management & cleanup

This commit is contained in:
NGnius (Graham) 2019-12-15 16:35:59 -08:00
parent 047f0bb344
commit c55454e4a3
31 changed files with 269 additions and 39 deletions

View file

@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using Svelto.ECS; using Svelto.ECS;
namespace GamecraftModdingAPI.Commands namespace GamecraftModdingAPI.Commands
@ -35,9 +36,9 @@ namespace GamecraftModdingAPI.Commands
return _customCommands[name]; return _customCommands[name];
} }
public static Dictionary<string, ICustomCommandEngine> GetCommands() public static string[] GetCommandNames()
{ {
return _customCommands; return _customCommands.Keys.ToArray();
} }
public static void RemoveCommand(string name) public static void RemoveCommand(string name)

View file

@ -4,6 +4,7 @@ using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Reflection; using System.Reflection;
using Harmony; using Harmony;
using Svelto.Context; using Svelto.Context;
using Svelto.ECS; using Svelto.ECS;

View file

@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using uREPL; using uREPL;
using RobocraftX.CommandLine.Custom; using RobocraftX.CommandLine.Custom;

View file

@ -3,20 +3,18 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using Svelto.ECS; using Svelto.ECS;
using GamecraftModdingAPI.Utility;
namespace GamecraftModdingAPI.Commands namespace GamecraftModdingAPI.Commands
{ {
/// <summary> /// <summary>
/// Engine interface to handle command operations /// Engine interface to handle command operations
/// </summary> /// </summary>
public interface ICustomCommandEngine : IEngine, IQueryingEntitiesEngine, IDisposable public interface ICustomCommandEngine :IApiEngine
{ {
/// <summary>
/// The name of the command
/// </summary>
string Name { get; }
/// <summary> /// <summary>
/// The command's description, shown in command help messages /// The command's description, shown in command help messages
/// </summary> /// </summary>

View file

@ -1,10 +1,11 @@
using Svelto.ECS; using System;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using Svelto.ECS;
namespace GamecraftModdingAPI.Commands namespace GamecraftModdingAPI.Commands
{ {
/// <summary> /// <summary>

View file

@ -1,10 +1,11 @@
using Svelto.ECS; using System;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using Svelto.ECS;
namespace GamecraftModdingAPI.Commands namespace GamecraftModdingAPI.Commands
{ {
/// <summary> /// <summary>

View file

@ -1,10 +1,11 @@
using Svelto.ECS; using System;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using Svelto.ECS;
namespace GamecraftModdingAPI.Commands namespace GamecraftModdingAPI.Commands
{ {
/// <summary> /// <summary>

View file

@ -1,10 +1,11 @@
using Svelto.ECS; using System;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using Svelto.ECS;
namespace GamecraftModdingAPI.Commands namespace GamecraftModdingAPI.Commands
{ {
/// <summary> /// <summary>

View file

@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using Svelto.ECS; using Svelto.ECS;
namespace GamecraftModdingAPI.Events namespace GamecraftModdingAPI.Events

View file

@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using Svelto.ECS; using Svelto.ECS;
namespace GamecraftModdingAPI.Events namespace GamecraftModdingAPI.Events
@ -39,9 +40,9 @@ namespace GamecraftModdingAPI.Events
return _eventHandlers[name]; return _eventHandlers[name];
} }
public static Dictionary<string, IEventHandlerEngine> GetEventHandlers() public static string[] GetEventHandlerNames()
{ {
return _eventHandlers; return _eventHandlers.Keys.ToArray();
} }
public static void RemoveEventHandler(string name) public static void RemoveEventHandler(string name)
@ -71,9 +72,9 @@ namespace GamecraftModdingAPI.Events
return _eventEmitters[name]; return _eventEmitters[name];
} }
public static Dictionary<string, IEventEmitterEngine> GetEventEmitters() public static string[] GetEventEmitterNames()
{ {
return _eventEmitters; return _eventEmitters.Keys.ToArray();
} }
public static void RemoveEventEmitter(string name) public static void RemoveEventEmitter(string name)

View file

@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using Harmony; using Harmony;
using RobocraftX; using RobocraftX;
using Svelto.ECS; using Svelto.ECS;
@ -19,6 +20,8 @@ namespace GamecraftModdingAPI.Events
{ {
public static void Postfix(ref EnginesRoot ____mainGameEnginesRoot) public static void Postfix(ref EnginesRoot ____mainGameEnginesRoot)
{ {
// register custom game engines
GameEngineManager.RegisterEngines(____mainGameEnginesRoot);
// A new EnginesRoot is always created when ActivateGame is called // A new EnginesRoot is always created when ActivateGame is called
// so all event emitters and handlers must be re-registered. // so all event emitters and handlers must be re-registered.
EventManager.RegisterEngines(____mainGameEnginesRoot); EventManager.RegisterEngines(____mainGameEnginesRoot);

View file

@ -3,9 +3,9 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using Harmony; using Harmony;
using RobocraftX; using RobocraftX;
using Svelto.ECS;
using GamecraftModdingAPI.Utility; using GamecraftModdingAPI.Utility;

View file

@ -3,9 +3,9 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using Harmony; using Harmony;
using RobocraftX; using RobocraftX;
using Svelto.ECS;
using GamecraftModdingAPI.Utility; using GamecraftModdingAPI.Utility;

View file

@ -3,20 +3,18 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using Svelto.ECS; using Svelto.ECS;
using GamecraftModdingAPI.Utility;
namespace GamecraftModdingAPI.Events namespace GamecraftModdingAPI.Events
{ {
/// <summary> /// <summary>
/// Engine interface to create a ModEventEntityStruct in entitiesDB when Emit() is called. /// Engine interface to create a ModEventEntityStruct in entitiesDB when Emit() is called.
/// </summary> /// </summary>
public interface IEventEmitterEngine : IEngine, IQueryingEntitiesEngine, IDisposable public interface IEventEmitterEngine : IApiEngine
{ {
/// <summary>
/// The name of the IEventEmitterEngine
/// </summary>
string Name { get; }
/// <summary> /// <summary>
/// The type of event emitted /// The type of event emitted
/// </summary> /// </summary>

View file

@ -3,19 +3,18 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using Svelto.ECS; using Svelto.ECS;
using Svelto.ECS.Internal; using Svelto.ECS.Internal;
using GamecraftModdingAPI.Utility;
namespace GamecraftModdingAPI.Events namespace GamecraftModdingAPI.Events
{ {
/// <summary> /// <summary>
/// Engine interface to handle ModEventEntityStruct events emitted by IEventEmitterEngines. /// Engine interface to handle ModEventEntityStruct events emitted by IEventEmitterEngines.
/// </summary> /// </summary>
public interface IEventHandlerEngine : IEngine, IQueryingEntitiesEngine, IReactOnAddAndRemove<ModEventEntityStruct>, IReactOnAddAndRemove, IDisposable public interface IEventHandlerEngine : IApiEngine, IReactOnAddAndRemove<ModEventEntityStruct>, IReactOnAddAndRemove
{ {
/// <summary>
/// The name of the IEventHandlerEngine
/// </summary>
string Name { get; }
} }
} }

View file

@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using Harmony; using Harmony;
using RobocraftX; using RobocraftX;
using Svelto.ECS; using Svelto.ECS;
@ -21,6 +22,8 @@ namespace GamecraftModdingAPI.Events
private static bool firstLoad = true; private static bool firstLoad = true;
public static void Postfix(ref EnginesRoot ____frontEndEnginesRoot) public static void Postfix(ref EnginesRoot ____frontEndEnginesRoot)
{ {
// register custom menu engines
MenuEngineManager.RegisterEngines(____frontEndEnginesRoot);
// A new EnginesRoot is always created when ActivateMenu is called // A new EnginesRoot is always created when ActivateMenu is called
// so all event emitters and handlers must be re-registered. // so all event emitters and handlers must be re-registered.
EventManager.RegisterEngines(____frontEndEnginesRoot); EventManager.RegisterEngines(____frontEndEnginesRoot);

View file

@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using Harmony; using Harmony;
using RobocraftX; using RobocraftX;
using Svelto.ECS; using Svelto.ECS;

View file

@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using Svelto.ECS; using Svelto.ECS;
namespace GamecraftModdingAPI.Events namespace GamecraftModdingAPI.Events

View file

@ -3,8 +3,8 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using Svelto.ECS; using Svelto.ECS;
using Svelto.ECS.Hybrid;
namespace GamecraftModdingAPI.Events namespace GamecraftModdingAPI.Events
{ {

View file

@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using Svelto.ECS; using Svelto.ECS;
using GamecraftModdingAPI.Utility; using GamecraftModdingAPI.Utility;

View file

@ -1,10 +1,11 @@
using Svelto.ECS; using System;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using Svelto.ECS;
namespace GamecraftModdingAPI.Events namespace GamecraftModdingAPI.Events
{ {
/// <summary> /// <summary>

View file

@ -3,16 +3,28 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using Harmony;
using System.Reflection; using System.Reflection;
using Harmony;
using GamecraftModdingAPI.Utility; using GamecraftModdingAPI.Utility;
using GamecraftModdingAPI.Events; using GamecraftModdingAPI.Events;
namespace GamecraftModdingAPI namespace GamecraftModdingAPI
{ {
/// <summary>
/// The main class of the GamecraftModdingAPI.
/// Use this to initialize the API before calling it.
/// </summary>
static class Main static class Main
{ {
private static HarmonyInstance harmony; private static HarmonyInstance harmony;
/// <summary>
/// Initializes the GamecraftModdingAPI.
/// This should be called ASAP after Gamecraft starts up.
/// Ideally, this should be called from your main Plugin class's OnApplicationStart() method.
/// </summary>
public static void Init() public static void Init()
{ {
var currentAssembly = Assembly.GetExecutingAssembly(); var currentAssembly = Assembly.GetExecutingAssembly();
@ -31,6 +43,11 @@ namespace GamecraftModdingAPI
Logging.Log($"{currentAssembly.GetName().Name} {currentAssembly.GetName().Version} init & patch complete"); Logging.Log($"{currentAssembly.GetName().Name} {currentAssembly.GetName().Version} init & patch complete");
} }
/// <summary>
/// Shuts down & cleans up the GamecraftModdingAPI.
/// This should be called ASAP before Gamecraft quits.
/// Ideally, this should be called from your main Plugin class's OnApplicationQuit() method.
/// </summary>
public static void Shutdown() public static void Shutdown()
{ {
var currentAssembly = Assembly.GetExecutingAssembly(); var currentAssembly = Assembly.GetExecutingAssembly();

View file

@ -1,5 +1,6 @@
using System; using System;
using System.Reflection; using System.Reflection;
using Harmony; using Harmony;
using GamecraftModdingAPI.Commands; using GamecraftModdingAPI.Commands;

View file

@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using Svelto.ECS; using Svelto.ECS;
namespace GamecraftModdingAPI.Utility namespace GamecraftModdingAPI.Utility

View file

@ -0,0 +1,53 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Svelto.ECS;
namespace GamecraftModdingAPI.Utility
{
public static class GameEngineManager
{
private static Dictionary<string, IApiEngine> _gameEngines = new Dictionary<string, IApiEngine>();
public static void AddGameEngine(IApiEngine engine)
{
_gameEngines[engine.Name] = engine;
}
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)
{
_gameEngines.Remove(name);
}
public static void RegisterEngines(EnginesRoot enginesRoot)
{
foreach (var key in _gameEngines.Keys)
{
enginesRoot.AddEngine(_gameEngines[key]);
}
}
}
}

View file

@ -0,0 +1,21 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Svelto.ECS;
namespace GamecraftModdingAPI.Utility
{
/// <summary>
/// Base engine interface used by all GamecraftModdingAPI engines
/// </summary>
public interface IApiEngine : IEngine, IQueryingEntitiesEngine, IDisposable
{
/// <summary>
/// The name of the engine
/// </summary>
string Name { get; }
}
}

View file

@ -145,6 +145,8 @@ namespace GamecraftModdingAPI.Utility
Svelto.Console.SystemLog(obj.ToString()); Svelto.Console.SystemLog(obj.ToString());
} }
// descriptive logging
/// <summary> /// <summary>
/// Write a descriptive message to Gamecraft's log only when the API is a Debug build /// Write a descriptive message to Gamecraft's log only when the API is a Debug build
/// </summary> /// </summary>
@ -167,5 +169,56 @@ namespace GamecraftModdingAPI.Utility
var method = (new StackTrace()).GetFrame(1).GetMethod(); var method = (new StackTrace()).GetFrame(1).GetMethod();
Log($"[{DateTime.Now.ToString()}][{method.DeclaringType.Name}.{method.Name}]{obj.ToString()}"); Log($"[{DateTime.Now.ToString()}][{method.DeclaringType.Name}.{method.Name}]{obj.ToString()}");
} }
// CLI logging
/// <summary>
/// Write a message to Gamecraft's command line
/// </summary>
/// <param name="obj">The object to log</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void CommandLog(object obj)
{
CommandLog(obj.ToString());
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void CommandLog(string msg)
{
uREPL.Log.Output(msg);
}
/// <summary>
/// Write an error message to Gamecraft's command line
/// </summary>
/// <param name="obj">The object to log</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void CommandLogError(object obj)
{
CommandLogError(obj.ToString());
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void CommandLogError(string msg)
{
uREPL.Log.Error(msg);
}
/// <summary>
/// Write a warning message to Gamecraft's command line
/// </summary>
/// <param name="obj">The object to log</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void CommandLogWarning(object obj)
{
CommandLogWarning(obj.ToString());
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void CommandLogWarning(string msg)
{
uREPL.Log.Warn(msg);
}
} }
} }

View file

@ -0,0 +1,57 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Svelto.ECS;
namespace GamecraftModdingAPI.Utility
{
/// <summary>
/// Keeps track of custom menu-modifying engines
/// </summary>
public static class MenuEngineManager
{
private static Dictionary<string, IApiEngine> _menuEngines = new Dictionary<string, IApiEngine>();
// menu engine management
public static void AddMenuEngine(IApiEngine engine)
{
_menuEngines[engine.Name] = engine;
}
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)
{
_menuEngines.Remove(name);
}
public static void RegisterEngines(EnginesRoot enginesRoot)
{
foreach (var key in _menuEngines.Keys)
{
enginesRoot.AddEngine(_menuEngines[key]);
}
}
}
}

View file

@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using Harmony; using Harmony;
using RobocraftX.FrontEnd; using RobocraftX.FrontEnd;

View file

@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using Harmony; using Harmony;
using RobocraftX.Common; using RobocraftX.Common;

View file

@ -1,5 +1,16 @@
# GamecraftModdingAPI # GamecraftModdingAPI
Gamecraft modding API for a stable interface between Gamecraft and mods Unofficial Gamecraft modding API for interfacing Gamecraft from mods.
The GamecraftModdingAPI aims to simplify the mods in two ways:
- *Ease-of-Use* The API provides many easy methods to call to do common tasks such as moving blocks and adding commands.
All of the Harmony patchings are done for you, so you can focus on writing your mod instead of reading swathes of undocumented code.
- *Stability* The API aims to be reliable and consistent between versions.
This means your code won't break when the GamecraftModdingAPI or Gamecraft updates.
For more info & support, please join the ExMods Discord: https://discord.gg/xjnFxQV
# Disclaimer
This API is an unofficial modification of Gamecraft software, and is not endorsed or supported by FreeJam or Gamecraft.
The GamecraftModdingAPI developer(s) claim no rights on the Gamecraft code referenced within this project.
For more information, join the ExMods Discord: https://discord.gg/xjnFxQV