Initial commit
This commit is contained in:
@@ -0,0 +1,227 @@
|
||||
using Microsoft.AspNetCore.SignalR;
|
||||
using RobotNet10.ScriptEngine.Shared;
|
||||
using RobotNet10.Shared;
|
||||
|
||||
namespace RobotNet10.ScriptEngine.Hubs;
|
||||
|
||||
/// <summary>
|
||||
/// SignalR hub for ScriptEngine management operations.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Initializes a new instance of ScriptManagerHub.
|
||||
/// </remarks>
|
||||
public class ScriptManagerHub(ScriptEngine _scriptEngine) : Hub
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the current state of the ScriptEngine.
|
||||
/// </summary>
|
||||
public Task<ScriptEngineState> GetState()
|
||||
{
|
||||
return Task.FromResult(_scriptEngine.State);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Builds scripts from all files. Only allowed when state is Idle or BuildError.
|
||||
/// </summary>
|
||||
public Task<MessageResult> Build()
|
||||
{
|
||||
return Task.FromResult(_scriptEngine.Build());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Starts the ScriptEngine. Only allowed when state is Ready.
|
||||
/// </summary>
|
||||
public Task<MessageResult> Start()
|
||||
{
|
||||
return Task.FromResult(_scriptEngine.Start());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stops the ScriptEngine. Only allowed when state is Running.
|
||||
/// </summary>
|
||||
public Task<MessageResult> Stop()
|
||||
{
|
||||
return Task.FromResult(_scriptEngine.Stop());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets the ScriptEngine. Allowed from Idle, Ready, BuildError, Running, or Fault.
|
||||
/// </summary>
|
||||
public Task<MessageResult> Reset()
|
||||
{
|
||||
return Task.FromResult(_scriptEngine.Reset());
|
||||
}
|
||||
|
||||
#region VariableManager Methods
|
||||
|
||||
/// <summary>
|
||||
/// Gets all script variables.
|
||||
/// </summary>
|
||||
public Task<ScriptVariableDto[]> GetScriptVariables()
|
||||
{
|
||||
return Task.FromResult(_scriptEngine.VariableManager.GetVariables().ToArray());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Finds specific script variables by names.
|
||||
/// </summary>
|
||||
public Task<ScriptVariableDto[]> FindScriptVariables(string[] names)
|
||||
{
|
||||
return Task.FromResult(_scriptEngine.VariableManager.GetVariables(names).ToArray());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the value of a script variable by name.
|
||||
/// </summary>
|
||||
public Task<MessageResult> SetValue(string name, string value)
|
||||
{
|
||||
return Task.FromResult(_scriptEngine.VariableManager.SetValue(name, value));
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region TaskManager Methods
|
||||
|
||||
/// <summary>
|
||||
/// Gets all script tasks.
|
||||
/// </summary>
|
||||
public Task<ScriptTaskDto[]> GetScriptTasks()
|
||||
{
|
||||
return Task.FromResult(_scriptEngine.TaskManager.GetScriptTasks());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Finds specific script tasks by names.
|
||||
/// </summary>
|
||||
public Task<ScriptTaskDto[]> FindScriptTasks(string[] names)
|
||||
{
|
||||
return Task.FromResult(_scriptEngine.TaskManager.FindScriptTasks(names));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Enables a task (resumes if paused, starts if stopped).
|
||||
/// </summary>
|
||||
public Task<MessageResult> EnableTask(string name)
|
||||
{
|
||||
return Task.FromResult(_scriptEngine.TaskManager.EnableTask(name));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Disables a task (pauses if running).
|
||||
/// </summary>
|
||||
public Task<MessageResult> DisableTask(string name)
|
||||
{
|
||||
return Task.FromResult(_scriptEngine.TaskManager.DisableTask(name));
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region MissionManager Methods
|
||||
|
||||
/// <summary>
|
||||
/// Gets all script missions.
|
||||
/// </summary>
|
||||
public Task<ScriptMissionDto[]> GetScriptMissions()
|
||||
{
|
||||
return Task.FromResult(_scriptEngine.MissionManager.GetScriptMissions());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Finds specific script missions by names.
|
||||
/// </summary>
|
||||
public Task<ScriptMissionDto[]> FindScriptMissions(string[] names)
|
||||
{
|
||||
return Task.FromResult(_scriptEngine.MissionManager.FindScriptMissions(names));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a mission instance with parameters provided as a dictionary.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of the mission model.</param>
|
||||
/// <param name="args">Dictionary of parameter values keyed by parameter name (as strings).</param>
|
||||
/// <returns>MessageResult containing the mission ID if successful.</returns>
|
||||
public async Task<MessageResult<Guid>> CreateMission(string name, IDictionary<string, string> args)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(name))
|
||||
return new MessageResult<Guid>(false, default, "Mission name cannot be null or empty");
|
||||
|
||||
if (args == null)
|
||||
return new MessageResult<Guid>(false, default, "Parameters cannot be null");
|
||||
|
||||
// Convert string dictionary to object dictionary
|
||||
var missionModel = _scriptEngine.MissionManager.GetMissionModel(name);
|
||||
if (missionModel == null)
|
||||
return new MessageResult<Guid>(false, default, $"Mission model '{name}' not found");
|
||||
|
||||
var parameters = new Dictionary<string, object?>();
|
||||
foreach (var paramModel in missionModel.Parameters)
|
||||
{
|
||||
// Skip CancellationToken parameters
|
||||
if (paramModel.Type == typeof(CancellationToken))
|
||||
continue;
|
||||
|
||||
if (args.TryGetValue(paramModel.Name, out var stringValue))
|
||||
{
|
||||
try
|
||||
{
|
||||
object? convertedValue = null;
|
||||
if (!string.IsNullOrEmpty(stringValue) && stringValue != "null")
|
||||
{
|
||||
if (paramModel.Type == typeof(string))
|
||||
{
|
||||
convertedValue = stringValue;
|
||||
}
|
||||
else if (paramModel.Type.IsEnum)
|
||||
{
|
||||
convertedValue = Enum.Parse(paramModel.Type, stringValue, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
convertedValue = Convert.ChangeType(stringValue, paramModel.Type);
|
||||
}
|
||||
}
|
||||
parameters[paramModel.Name] = convertedValue;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
var errorMessage = $"Failed to convert parameter '{paramModel.Name}' value '{stringValue}' to type '{paramModel.Type.Name}': {ex.Message}";
|
||||
// Log error via ConsoleHubContext if available
|
||||
// Note: We don't have direct access to ConsoleHubContext here, but error is returned to client
|
||||
return new MessageResult<Guid>(false, default, errorMessage);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Use default value if not provided
|
||||
parameters[paramModel.Name] = paramModel.DefaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
return await Task.FromResult(_scriptEngine.MissionManager.CreateMission(name, parameters));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Cancels a running or paused mission.
|
||||
/// </summary>
|
||||
/// <param name="id">The ID of the mission instance to cancel.</param>
|
||||
/// <param name="reason">The reason for cancellation.</param>
|
||||
/// <returns>True if the mission was canceled successfully, false otherwise.</returns>
|
||||
public Task<bool> CancelMission(Guid id, string reason)
|
||||
{
|
||||
var mission = _scriptEngine.MissionManager.GetMission(id);
|
||||
if (mission == null)
|
||||
return Task.FromResult(false);
|
||||
|
||||
try
|
||||
{
|
||||
mission.Cancel(reason);
|
||||
return Task.FromResult(true);
|
||||
}
|
||||
catch
|
||||
{
|
||||
return Task.FromResult(false);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
Reference in New Issue
Block a user