Files
Denso/srcs/RobotNet10/Components/RobotNet10.ScriptEditor/Clients/ScriptManagerHubClient.cs
2026-07-03 16:31:37 +07:00

188 lines
6.6 KiB
C#

using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.SignalR.Client;
using RobotNet10.Components.Clients;
using RobotNet10.ScriptEngine.Shared;
using RobotNet10.Shared;
namespace RobotNet10.ScriptEditor.Clients;
/// <summary>
/// SignalR HubClient for ScriptManagerHub - handles ScriptEngine management operations.
/// </summary>
public class ScriptManagerHubClient : HubClient
{
public event Action<ScriptEngineState>? StateChanged;
/// <summary>
/// Gets the current ScriptEngine state. Updated when connected.
/// </summary>
public ScriptEngineState State { get; private set; }
public ScriptManagerHubClient(NavigationManager navigationManager)
: base(navigationManager.ToAbsoluteUri(HubEndpoints.ScriptManagerHubPath))
{
Connection.On<ScriptEngineState>("StateChanged", state =>
{
State = state;
StateChanged?.Invoke(state);
});
// Reload state when reconnected
Connection.Reconnected += async _ =>
{
if (IsConnected)
{
try
{
var newState = await GetStateAsync();
if (State != newState)
{
State = newState;
StateChanged?.Invoke(newState);
}
else
{
// Even if state hasn't changed, trigger event to update UI
StateChanged?.Invoke(newState);
}
}
catch (Exception)
{
// Ignore errors when reloading state on reconnect
}
}
};
}
public override async Task StartAsync()
{
await base.StartAsync();
// Lưu state khi connected và trigger StateChanged event
if (IsConnected)
{
var newState = await GetStateAsync();
if (State != newState)
{
State = newState;
StateChanged?.Invoke(newState);
}
else
{
// Even if state hasn't changed, trigger event to update UI
StateChanged?.Invoke(newState);
}
}
}
/// <summary>
/// Gets the current state of the ScriptEngine.
/// </summary>
public Task<ScriptEngineState> GetStateAsync() => Connection.InvokeAsync<ScriptEngineState>("GetState");
/// <summary>
/// Builds scripts from all files. Only allowed when state is Idle or BuildError.
/// </summary>
public Task<MessageResult> BuildAsync() => Connection.InvokeAsync<MessageResult>("Build");
/// <summary>
/// Starts the ScriptEngine. Only allowed when state is Ready.
/// </summary>
public Task<MessageResult> StartEingineAsync() => Connection.InvokeAsync<MessageResult>("Start");
/// <summary>
/// Stops the ScriptEngine. Only allowed when state is Running.
/// </summary>
public Task<MessageResult> StopEingineAsync() => Connection.InvokeAsync<MessageResult>("Stop");
/// <summary>
/// Resets the ScriptEngine. Allowed from Idle, Ready, BuildError, Running, or Fault.
/// </summary>
public Task<MessageResult> ResetAsync() => Connection.InvokeAsync<MessageResult>("Reset");
#region VariableManager Methods
/// <summary>
/// Gets all script variables.
/// </summary>
public Task<ScriptVariableDto[]> GetScriptVariablesAsync() =>
Connection.InvokeAsync<ScriptVariableDto[]>("GetScriptVariables");
/// <summary>
/// Finds specific script variables by names.
/// </summary>
public Task<ScriptVariableDto[]> FindScriptVariablesAsync(string[] names) =>
Connection.InvokeAsync<ScriptVariableDto[]>("FindScriptVariables", names);
/// <summary>
/// Sets the value of a script variable by name.
/// </summary>
public Task<MessageResult> SetValueAsync(string name, string value) =>
Connection.InvokeAsync<MessageResult>("SetValue", name, value);
#endregion
#region TaskManager Methods
/// <summary>
/// Gets all script tasks.
/// </summary>
public Task<ScriptTaskDto[]> GetScriptTasksAsync() =>
Connection.InvokeAsync<ScriptTaskDto[]>("GetScriptTasks");
/// <summary>
/// Finds specific script tasks by names.
/// </summary>
public Task<ScriptTaskDto[]> FindScriptTasksAsync(string[] names) =>
Connection.InvokeAsync<ScriptTaskDto[]>("FindScriptTasks", names);
/// <summary>
/// Enables a task (resumes if paused, starts if stopped).
/// </summary>
public Task<MessageResult> EnableTaskAsync(string name) =>
Connection.InvokeAsync<MessageResult>("EnableTask", name);
/// <summary>
/// Disables a task (pauses if running).
/// </summary>
public Task<MessageResult> DisableTaskAsync(string name) =>
Connection.InvokeAsync<MessageResult>("DisableTask", name);
#endregion
#region MissionManager Methods
/// <summary>
/// Gets all script missions.
/// </summary>
public Task<ScriptMissionDto[]> GetScriptMissionsAsync() =>
Connection.InvokeAsync<ScriptMissionDto[]>("GetScriptMissions");
/// <summary>
/// Finds specific script missions by names.
/// </summary>
public Task<ScriptMissionDto[]> FindScriptMissionsAsync(string[] names) =>
Connection.InvokeAsync<ScriptMissionDto[]>("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 Task<MessageResult<Guid>> CreateMissionAsync(string name, IDictionary<string, string> args) =>
Connection.InvokeAsync<MessageResult<Guid>>("CreateMission", name, args);
/// <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> CancelMissionAsync(Guid id, string reason) =>
Connection.InvokeAsync<bool>("CancelMission", id, reason);
#endregion
}