using System;
using Svelto.ECS;
using GamecraftModdingAPI.Utility;
namespace GamecraftModdingAPI.Commands
{
///
/// Custom Command builder.
///
public class CommandBuilder
{
private string name;
private string description;
private short parameterCount;
private ICustomCommandEngine commandEngine;
private bool fromExisting = false;
///
/// Create a new command builder.
///
public CommandBuilder()
{
name = "";
description = null;
parameterCount = -1;
}
///
/// Create and return a command builder.
///
/// The builder.
public static CommandBuilder Builder()
{
return new CommandBuilder();
}
///
/// Create a new command builder.
///
/// The command name.
/// The command description (shown in help).
public CommandBuilder(string name, string description = null)
{
this.name = name;
this.description = description;
parameterCount = -1;
}
///
/// Create and return a command builder.
/// If name and description are provided, this is equivalent to Builder().Name(name).Description(description)
///
/// The command name.
/// The command description (shown in help).
/// The builder.
public static CommandBuilder Builder(string name, string description = null)
{
return new CommandBuilder(name, description);
}
///
/// Name the command.
///
/// The builder.
/// The command name.
public CommandBuilder Name(string name)
{
this.name = name;
return this;
}
///
/// Describe the command.
///
/// The builder.
/// The command description (shown in help).
public CommandBuilder Description(string description)
{
this.description = description;
return this;
}
///
/// Set the action the command performs.
///
/// The builder.
/// The action to perform when the command is called.
public CommandBuilder Action(Action action)
{
parameterCount = 0;
commandEngine = new SimpleCustomCommandEngine(action, name, description);
return this;
}
///
/// Set the action the command performs.
///
/// The builder.
/// The action to perform when the command is called.
/// The 1st parameter's type.
public CommandBuilder Action(Action action)
{
parameterCount = 1;
commandEngine = new SimpleCustomCommandEngine(action, name, description);
return this;
}
///
/// Set the action the command performs.
///
/// The builder.
/// The action to perform when the command is called.
/// The 1st parameter's type.
/// The 2nd parameter's type.
public CommandBuilder Action(Action action)
{
parameterCount = 2;
commandEngine = new SimpleCustomCommandEngine(action, name, description);
return this;
}
///
/// Set the action the command performs.
///
/// The builder.
/// The action to perform when the command is called.
/// The 1st parameter's type.
/// The 2nd parameter's type.
/// The 3rd parameter's type.
public CommandBuilder Action(Action action)
{
parameterCount = 3;
commandEngine = new SimpleCustomCommandEngine(action, name, description);
return this;
}
///
/// Build the command from an existing command.
///
/// The command. Use Invoke() to execute it.
public SimpleCustomCommandEngine FromExisting()
{
if (string.IsNullOrWhiteSpace(name))
{
throw new InvalidOperationException("Command name must be defined before FromExisting() is called");
}
if (!ExistingCommands.Exists(name))
{
throw new InvalidOperationException("Command cannot be built from existing because it does not exist.");
}
fromExisting = true;
return new SimpleCustomCommandEngine(
() => { ExistingCommands.Call(name); },
name,
description);
}
///
/// Build the command from an existing command.
///
/// The command. Use Invoke() to execute it.
/// The 1st parameter's type.
public SimpleCustomCommandEngine FromExisting()
{
if (string.IsNullOrWhiteSpace(name))
{
throw new InvalidOperationException("Command name must be defined before FromExisting() is called");
}
if (!ExistingCommands.Exists(name))
{
throw new InvalidOperationException("Command cannot be built from existing because it does not exist.");
}
fromExisting = true;
return new SimpleCustomCommandEngine(
(A a) => { ExistingCommands.Call(name, a); },
name,
description);
}
///
/// Build the command from an existing command.
///
/// The command. Use Invoke() to execute it.
/// The 1st parameter's type.
/// The 2nd parameter's type.
public SimpleCustomCommandEngine FromExisting()
{
if (string.IsNullOrWhiteSpace(name))
{
throw new InvalidOperationException("Command name must be defined before FromExisting() is called");
}
if (!ExistingCommands.Exists(name))
{
throw new InvalidOperationException("Command cannot be built from existing because it does not exist.");
}
fromExisting = true;
return new SimpleCustomCommandEngine(
(A a, B b) => { ExistingCommands.Call(name, a, b); },
name,
description);
}
///
/// Build the command from an existing command.
///
/// The command. Use Invoke() to execute it.
/// The 1st parameter's type.
/// The 2nd parameter's type.
/// The 3rd parameter's type.
public SimpleCustomCommandEngine FromExisting()
{
if (string.IsNullOrWhiteSpace(name))
{
throw new InvalidOperationException("Command name must be defined before FromExisting() is called");
}
if (!ExistingCommands.Exists(name))
{
throw new InvalidOperationException("Command cannot be built from existing because it does not exist.");
}
fromExisting = true;
return new SimpleCustomCommandEngine(
(A a, B b, C c) => { ExistingCommands.Call(name, a, b, c); },
name,
description);
}
///
/// Build the command.
///
/// The built command.
/// Automatically register the command with CommandManager.AddCommand()?
public ICustomCommandEngine Build(bool register = true)
{
if (string.IsNullOrWhiteSpace(name))
{
throw new InvalidOperationException("Command name must be defined before Build() is called");
}
if (fromExisting)
{
throw new InvalidOperationException("Command was already built by FromExisting()");
}
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;
}
///
/// Get the full command name, in the form [name]::[description]::[# of parameters]
///
/// The name.
public string FullName()
{
if (string.IsNullOrWhiteSpace(description))
{
return name + "::" + parameterCount;
}
return name + "::" + description + "::" + parameterCount;
}
}
}