Browse Source

Create CommandBuilder

tags/v1.0.0
NGnius (Graham) 4 years ago
parent
commit
5cb27b05c0
5 changed files with 249 additions and 8 deletions
  1. +181
    -0
      GamecraftModdingAPI/Commands/CommandBuilder.cs
  2. +4
    -0
      GamecraftModdingAPI/Commands/CommandManager.cs
  3. +1
    -1
      GamecraftModdingAPI/GamecraftModdingAPI.csproj
  4. +62
    -6
      GamecraftModdingAPI/Tests/GamecraftModdingAPIPluginTest.cs
  5. +1
    -1
      doxygen.conf

+ 181
- 0
GamecraftModdingAPI/Commands/CommandBuilder.cs View File

@@ -0,0 +1,181 @@
using System;

using Svelto.ECS;

using GamecraftModdingAPI.Utility;

namespace GamecraftModdingAPI.Commands
{
/// <summary>
/// Custom Command builder.
/// </summary>
public class CommandBuilder
{
private string name;

private string description;

private short parameterCount;

private ICustomCommandEngine commandEngine;

/// <summary>
/// Create a new command builder.
/// </summary>
public CommandBuilder()
{
name = "";
description = null;
parameterCount = -1;
}

/// <summary>
/// Create and return a command builder.
/// </summary>
/// <returns>The builder.</returns>
public static CommandBuilder Builder()
{
return new CommandBuilder();
}

/// <summary>
/// Create a new command builder.
/// </summary>
/// <param name="name">The command name.</param>
/// <param name="description">The command description (shown in help).</param>
public CommandBuilder(string name, string description = null)
{
this.name = name;
this.description = description;
parameterCount = -1;
}

/// <summary>
/// Create and return a command builder.
/// If name and description are provided, this is equivalent to <code>Builder().Name(name).Description(description)</code>
/// </summary>
/// <param name="name">The command name.</param>
/// <param name="description">The command description (shown in help).</param>
/// <returns>The builder.</returns>
public static CommandBuilder Builder(string name, string description = null)
{
return new CommandBuilder(name, description);
}

/// <summary>
/// Name the command.
/// </summary>
/// <returns>The builder.</returns>
/// <param name="name">The command name.</param>
public CommandBuilder Name(string name)
{
this.name = name;
return this;
}

/// <summary>
/// Describe the command.
/// </summary>
/// <returns>The builder.</returns>
/// <param name="description">The command description (shown in help).</param>
public CommandBuilder Description(string description)
{
this.description = description;
return this;
}

/// <summary>
/// Set the action the command performs.
/// </summary>
/// <returns>The builder.</returns>
/// <param name="action">The action to perform when the command is called.</param>
public CommandBuilder Action(Action action)
{
parameterCount = 0;
commandEngine = new SimpleCustomCommandEngine(action, name, description);
return this;
}

/// <summary>
/// Set the action the command performs.
/// </summary>
/// <returns>The builder.</returns>
/// <param name="action">The action to perform when the command is called.</param>
/// <typeparam name="A">The 1st parameter's type.</typeparam>
public CommandBuilder Action<A>(Action<A> action)
{
parameterCount = 1;
commandEngine = new SimpleCustomCommandEngine<A>(action, name, description);
return this;
}

/// <summary>
/// Set the action the command performs.
/// </summary>
/// <returns>The builder.</returns>
/// <param name="action">The action to perform when the command is called.</param>
/// <typeparam name="A">The 1st parameter's type.</typeparam>
/// <typeparam name="B">The 2nd parameter's type.</typeparam>
public CommandBuilder Action<A,B>(Action<A,B> action)
{
parameterCount = 2;
commandEngine = new SimpleCustomCommandEngine<A,B>(action, name, description);
return this;
}

/// <summary>
/// Set the action the command performs.
/// </summary>
/// <returns>The builder.</returns>
/// <param name="action">The action to perform when the command is called.</param>
/// <typeparam name="A">The 1st parameter's type.</typeparam>
/// <typeparam name="B">The 2nd parameter's type.</typeparam>
/// <typeparam name="C">The 3rd parameter's type.</typeparam>
public CommandBuilder Action<A,B,C>(Action<A,B,C> action)
{
parameterCount = 3;
commandEngine = new SimpleCustomCommandEngine<A,B,C>(action, name, description);
return this;
}

/// <summary>
/// Build the command.
/// </summary>
/// <returns>The built command.</returns>
/// <param name="register">Automatically register the command with CommandManager.AddCommand()?</param>
public ICustomCommandEngine Build(bool register = true)
{
if (string.IsNullOrWhiteSpace(name))
{
throw new InvalidOperationException("Command name must be defined before Build() is called");
}
if (commandEngine == null)
{
throw new InvalidOperationException("Command action must be defined before Build() is called");
}
if (string.IsNullOrWhiteSpace(description))
{
Logging.LogWarning($"Command {name} was built without a description");
}
if (register)
{
CommandManager.AddCommand(commandEngine);
Logging.MetaDebugLog($"Command {FullName()} was automatically registered");
}
return commandEngine;
}

/// <summary>
/// Get the full command name, in the form [name]::[description]::[# of parameters]
/// </summary>
/// <returns>The name.</returns>
public string FullName()
{
if (string.IsNullOrWhiteSpace(description))
{
return name + "::" + parameterCount;
}
return name + "::" + description + "::" + parameterCount;
}
}
}

+ 4
- 0
GamecraftModdingAPI/Commands/CommandManager.cs View File

@@ -22,6 +22,10 @@ namespace GamecraftModdingAPI.Commands

public static void AddCommand(ICustomCommandEngine engine)
{
if (ExistsCommand(engine))
{
Logging.LogWarning($"Command {engine.Name} already exists!");
}
_customCommands[engine.Name] = engine;
if (_lastEngineRoot != null)
{


+ 1
- 1
GamecraftModdingAPI/GamecraftModdingAPI.csproj View File

@@ -3,7 +3,7 @@
<PropertyGroup>
<TargetFramework>net472</TargetFramework>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<Version>0.2.2</Version>
<Version>1.0.0</Version>
<Authors>Exmods</Authors>
<PackageLicenseExpression>GNU General Public Licence 3+</PackageLicenseExpression>
<PackageProjectUrl>https://git.exmods.org/modtainers/GamecraftModdingAPI</PackageProjectUrl>


+ 62
- 6
GamecraftModdingAPI/Tests/GamecraftModdingAPIPluginTest.cs View File

@@ -81,8 +81,67 @@ namespace GamecraftModdingAPI.Tests
// debug/test commands
if (Dependency.Hell("ExtraCommands"))
{
CommandManager.AddCommand(new SimpleCustomCommandEngine(() => { UnityEngine.Application.Quit(); },
"Exit", "Close Gamecraft without any prompts"));
CommandBuilder.Builder()
.Name("Exit")
.Description("Close Gamecraft immediately, without any prompts")
.Action(() => { UnityEngine.Application.Quit(); })
.Build();
CommandBuilder.Builder()
.Name("SetFOV")
.Description("Set the player camera's field of view")
.Action((float d) => { UnityEngine.Camera.main.fieldOfView = d; })
.Build();

CommandBuilder.Builder()
.Name("MoveLastBlock")
.Description("Move the most-recently-placed block, and any connected blocks by the given offset")
.Action((float x, float y, float z) => {
bool success = GamecraftModdingAPI.Blocks.Movement.MoveConnectedBlocks(
GamecraftModdingAPI.Blocks.BlockIdentifiers.LatestBlockID,
new Unity.Mathematics.float3(x, y, z));
if (!success)
{
GamecraftModdingAPI.Utility.Logging.CommandLogError("Blocks can only be moved in Build mode!");
}
}).Build();

CommandBuilder.Builder()
.Name("PlaceAluminium")
.Description("Place a block of aluminium at the given coordinates")
.Action((float x, float y, float z) => { Blocks.Placement.PlaceBlock(Blocks.BlockIDs.AluminiumCube, new Unity.Mathematics.float3(x, y, z)); })
.Build();

System.Random random = new System.Random(); // for command below
CommandBuilder.Builder()
.Name("RandomizeSignalsInputs")
.Description("Do the thing")
.Action(() => {
if (!GameState.IsSimulationMode())
{
Logging.CommandLogError("You must be in simulation mode for this to work!");
return;
}
Tasks.Repeatable task = new Tasks.Repeatable(
() => {
uint count = 0;
EGID[] eBlocks = Blocks.Signals.GetElectricBlocks();
for (uint i = 0u; i < eBlocks.Length; i++)
{
uint[] ids = Blocks.Signals.GetSignalIDs(eBlocks[i]);
for (uint j = 0u; j < ids.Length; j++)
{
Blocks.Signals.SetSignalByID(ids[j], (float)random.NextDouble());
count++;
}
}
Logging.MetaDebugLog($"Did the thing on {count} inputs");
},
() => { return GameState.IsSimulationMode(); });
Tasks.Scheduler.Schedule(task);
}).Build();

/*
CommandManager.AddCommand(new SimpleCustomCommandEngine<float>((float d) => { UnityEngine.Camera.main.fieldOfView = d; },
"SetFOV", "Set the player camera's field of view"));
CommandManager.AddCommand(new SimpleCustomCommandEngine<float, float, float>(
@@ -98,10 +157,6 @@ namespace GamecraftModdingAPI.Tests
CommandManager.AddCommand(new SimpleCustomCommandEngine<float, float, float>(
(x, y, z) => { Blocks.Placement.PlaceBlock(Blocks.BlockIDs.AluminiumCube, new Unity.Mathematics.float3(x, y, z)); },
"PlaceAluminium", "Place a block of aluminium at the given coordinates"));
Analytics.DeltaDNAHelper.PlayerLifetimeParameters plp = new Analytics.DeltaDNAHelper.PlayerLifetimeParameters();
CommandManager.AddCommand(new SimpleCustomCommandEngine<string>(
(s) => { Analytics.DeltaDNAHelper.SendActionCompletedEvent(in plp, s.Replace(", ", " ")); },
"SendAnalyticsAction", "Send an analytics action"));
System.Random random = new System.Random(); // for command below
CommandManager.AddCommand(new SimpleCustomCommandEngine(
() => {
@@ -127,6 +182,7 @@ namespace GamecraftModdingAPI.Tests
() => { return GameState.IsSimulationMode(); });
Tasks.Scheduler.Schedule(task);
}, "RandomizeSignalsInputs", "Do the thing"));
*/
}

// dependency test


+ 1
- 1
doxygen.conf View File

@@ -38,7 +38,7 @@ PROJECT_NAME = "GamecraftModdingAPI"
# could be handy for archiving the generated documentation or if some version
# control system is used.

PROJECT_NUMBER = "v0.2.2"
PROJECT_NUMBER = "v1.0.0"

# Using the PROJECT_BRIEF tag one can provide an optional one line description
# for a project that appears at the top of each page and should give viewer a


Loading…
Cancel
Save