using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.SignalR.Client;
using RobotNet10.Components.Clients;
using RobotNet10.ScriptEngine.Shared;
using RobotNet10.Shared;
namespace RobotNet10.ScriptEditor.Clients;
///
/// SignalR HubClient for ScriptManagerHub - handles ScriptEngine management operations.
///
public class ScriptManagerHubClient : HubClient
{
public event Action? StateChanged;
///
/// Gets the current ScriptEngine state. Updated when connected.
///
public ScriptEngineState State { get; private set; }
public ScriptManagerHubClient(NavigationManager navigationManager)
: base(navigationManager.ToAbsoluteUri(HubEndpoints.ScriptManagerHubPath))
{
Connection.On("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);
}
}
}
///
/// Gets the current state of the ScriptEngine.
///
public Task GetStateAsync() => Connection.InvokeAsync("GetState");
///
/// Builds scripts from all files. Only allowed when state is Idle or BuildError.
///
public Task BuildAsync() => Connection.InvokeAsync("Build");
///
/// Starts the ScriptEngine. Only allowed when state is Ready.
///
public Task StartEingineAsync() => Connection.InvokeAsync("Start");
///
/// Stops the ScriptEngine. Only allowed when state is Running.
///
public Task StopEingineAsync() => Connection.InvokeAsync("Stop");
///
/// Resets the ScriptEngine. Allowed from Idle, Ready, BuildError, Running, or Fault.
///
public Task ResetAsync() => Connection.InvokeAsync("Reset");
#region VariableManager Methods
///
/// Gets all script variables.
///
public Task GetScriptVariablesAsync() =>
Connection.InvokeAsync("GetScriptVariables");
///
/// Finds specific script variables by names.
///
public Task FindScriptVariablesAsync(string[] names) =>
Connection.InvokeAsync("FindScriptVariables", names);
///
/// Sets the value of a script variable by name.
///
public Task SetValueAsync(string name, string value) =>
Connection.InvokeAsync("SetValue", name, value);
#endregion
#region TaskManager Methods
///
/// Gets all script tasks.
///
public Task GetScriptTasksAsync() =>
Connection.InvokeAsync("GetScriptTasks");
///
/// Finds specific script tasks by names.
///
public Task FindScriptTasksAsync(string[] names) =>
Connection.InvokeAsync("FindScriptTasks", names);
///
/// Enables a task (resumes if paused, starts if stopped).
///
public Task EnableTaskAsync(string name) =>
Connection.InvokeAsync("EnableTask", name);
///
/// Disables a task (pauses if running).
///
public Task DisableTaskAsync(string name) =>
Connection.InvokeAsync("DisableTask", name);
#endregion
#region MissionManager Methods
///
/// Gets all script missions.
///
public Task GetScriptMissionsAsync() =>
Connection.InvokeAsync("GetScriptMissions");
///
/// Finds specific script missions by names.
///
public Task FindScriptMissionsAsync(string[] names) =>
Connection.InvokeAsync("FindScriptMissions", names);
///
/// Creates a mission instance with parameters provided as a dictionary.
///
/// The name of the mission model.
/// Dictionary of parameter values keyed by parameter name (as strings).
/// MessageResult containing the mission ID if successful.
public Task> CreateMissionAsync(string name, IDictionary args) =>
Connection.InvokeAsync>("CreateMission", name, args);
///
/// Cancels a running or paused mission.
///
/// The ID of the mission instance to cancel.
/// The reason for cancellation.
/// True if the mission was canceled successfully, false otherwise.
public Task CancelMissionAsync(Guid id, string reason) =>
Connection.InvokeAsync("CancelMission", id, reason);
#endregion
}