3using System.Collections.Generic;
6using System.Threading.Tasks;
19 public SequencerType SequencerType;
20 public ulong TaskCount;
27 public TaskState State;
28 public ulong LineNumber;
50 public ulong HostAddress;
51 public uint FirmwareAddress;
74 private Grpc.Core.Channel channel;
75 private RapidSequencerService.RapidSequencerServiceClient client;
76 private string _grpcAddr;
77 private int _grpcPort;
78 private CompileSuccess lastCompileSuccess =
null;
79 private string warnings =
"";
90 channel =
new Grpc.Core.Channel(_grpcAddr, _grpcPort, Grpc.Core.ChannelCredentials.Insecure);
92 channel.ConnectAsync(DateTime.Now);
93 System.Threading.Thread.Sleep(1);
96 while (attempts < connectAttempts && channel.State != Grpc.Core.ChannelState.Ready)
98 channel.TryWaitForStateChangedAsync(channel.State, DateTime.UtcNow.AddMilliseconds(connectTimeoutMs)).Wait();
100 if (attempts >= connectAttempts)
102 throw new Exception(
"RapidSequencer failed to transition to ready state");
106 client =
new RapidSequencerService.RapidSequencerServiceClient(channel);
123 public static string ParseRepeatedString(Google.Protobuf.Collections.RepeatedField<
string> result)
126 foreach (var str
in result)
128 output += str +
"\n";
138 var request =
new CommandLineRequest { Command = command };
139 var reply = client.CommandLine(request);
140 return ParseRepeatedString(reply.Result);
151 var request =
new CompileRequest { Path = path, EntryPoint = entryPoint, ExceptionHandler = exceptionHandler };
152 var reply = client.Compile(request,
null, DateTime.UtcNow.AddSeconds(10));
153 string errorMessage =
"Unknown compilation error!";
155 foreach (var str
in reply.Warnings)
157 warnings += str +
"\n";
160 switch (reply.ResultCase)
162 case CompileResponse.ResultOneofCase.CompileSuccess:
163 lastCompileSuccess = reply.CompileSuccess;
165 case CompileResponse.ResultOneofCase.CompileFailure:
166 var failInfo = reply.CompileFailure;
168 "Compilation Failure: " + failInfo.CompilerText +
169 "\n Message: " + failInfo.CompilerMessage +
170 "\n Line: " + failInfo.CompilerLine +
", character: " + failInfo.CompilerStart;
171 throw new Exception(errorMessage);
172 case CompileResponse.ResultOneofCase.GeneralFailure:
173 errorMessage =
"Compilation General Failure: " + reply.GeneralFailure;
174 throw new Exception(errorMessage);
176 throw new Exception(errorMessage);
179 return reply.CompileSuccess;
189 private string RunCore(CompileSuccess compileSuccess, ulong[] breakpoints,
bool block)
191 if (compileSuccess ==
null)
193 throw new Exception(
"No previously successful compilation found!");
195 var request =
new RunRequest { Block = block, Compiled = compileSuccess, };
196 if (breakpoints !=
null)
198 foreach (var breakpoint
in breakpoints)
200 request.Breakpoints.Add(breakpoint);
203 var reply = client.Run(request);
204 return reply.Task.Id;
210 public string Run(ulong[] breakpoints =
null)
212 return RunCore(lastCompileSuccess, breakpoints,
true);
219 public string Run(CompileSuccess compileSuccess, ulong[] breakpoints =
null)
221 return RunCore(compileSuccess, breakpoints,
true);
229 return RunCore(lastCompileSuccess, breakpoints,
false);
236 public string RunAsync(CompileSuccess compileSuccess, ulong[] breakpoints =
null)
238 return RunCore(compileSuccess, breakpoints,
false);
244 var serverControlClient =
new RapidServer.ServerControlService.ServerControlServiceClient(channel);
245 serverControlClient.Shutdown(
new RapidServer.ServerShutdownRequest());
251 public void EngineStart(
string rmpNode =
"NodeA",
string rmpPath =
"")
253 client.EngineStart(
new EngineStartRequest { RmpNode = rmpNode, RmpPath = rmpPath });
259 client.EngineStop(
new EngineStopRequest());
266 var reply = client.EngineStatusGet(
new EngineStatusRequest());
267 return new EngineStatus { Running = reply.Running, SequencerType = reply.Type, TaskCount = reply.TaskCount, };
275 return new TaskID { Id = taskId };
306 throw new Exception($
"Failed to remove task: {taskId}. Ensure that task is stopped before removing.");
316 return new TaskStatus { State = reply.State, LineNumber = reply.LineNumber, Counter = reply.Counter, };
325 return ParseRepeatedString(reply.Result);
332 client.DebugCommand(
new DebugRequest { Task =
TaskIDFromString(taskId), Action = DebugAction.ResumeUnspecified });
339 client.DebugCommand(
new DebugRequest { Task =
TaskIDFromString(taskId), Action = DebugAction.Pause });
346 client.DebugCommand(
new DebugRequest { Task =
TaskIDFromString(taskId), Action = DebugAction.Step });
353 client.DebugCommand(
new DebugRequest { Task =
TaskIDFromString(taskId), Action = DebugAction.StepIn });
360 client.DebugCommand(
new DebugRequest { Task =
TaskIDFromString(taskId), Action = DebugAction.StepOut });
369 client.DebugCommand(
new DebugRequest { Task =
TaskIDFromString(taskId), Action = DebugAction.BreakpointSet, LineNumber = (int)lineNumber });
377 client.DebugCommand(
new DebugRequest { Task =
TaskIDFromString(taskId), Action = DebugAction.BreakpointUnset, LineNumber = (int)lineNumber });
380 private SequencerGlobal ParseGlobalVariableGetResponse(GlobalVariableGetResponse reply)
384 HostAddress = reply.HostAddress,
385 FirmwareAddress = reply.FirmwareAddress,
389 switch (reply.ValueCase)
391 case GlobalVariableGetResponse.ValueOneofCase.Bool:
393 globalVar.Value = reply.Bool;
395 case GlobalVariableGetResponse.ValueOneofCase.Char:
397 globalVar.Value = reply.Char;
399 case GlobalVariableGetResponse.ValueOneofCase.Int16:
401 globalVar.Value = reply.Int16;
403 case GlobalVariableGetResponse.ValueOneofCase.Uint16:
405 globalVar.Value = reply.Uint16;
407 case GlobalVariableGetResponse.ValueOneofCase.Int32:
409 globalVar.Value = reply.Int32;
411 case GlobalVariableGetResponse.ValueOneofCase.Uint32:
413 globalVar.Value = reply.Uint32;
415 case GlobalVariableGetResponse.ValueOneofCase.Int64:
417 globalVar.Value = reply.Int64;
419 case GlobalVariableGetResponse.ValueOneofCase.Uint64:
421 globalVar.Value = reply.Uint64;
423 case GlobalVariableGetResponse.ValueOneofCase.Double:
425 globalVar.Value = reply.Double;
428 throw new Exception(
"Unknown data type in GlobalVariableGetResponse.");
438 var request =
new GlobalVariableGetRequest { Name = name };
439 var reply = client.GlobalVariableGet(request);
440 var global = ParseGlobalVariableGetResponse(reply);
445 private SequencerGlobal ParseGlobalVariableData(GlobalVariableData data)
450 HostAddress = data.HostAddress,
451 FirmwareAddress = data.FirmwareAddress,
456 switch (data.ValueCase)
458 case GlobalVariableData.ValueOneofCase.Bool:
460 globalVar.Value = data.Bool;
462 case GlobalVariableData.ValueOneofCase.Char:
464 globalVar.Value = data.Char;
466 case GlobalVariableData.ValueOneofCase.Int16:
468 globalVar.Value = data.Int16;
470 case GlobalVariableData.ValueOneofCase.Uint16:
472 globalVar.Value = data.Uint16;
474 case GlobalVariableData.ValueOneofCase.Int32:
476 globalVar.Value = data.Int32;
478 case GlobalVariableData.ValueOneofCase.Uint32:
480 globalVar.Value = data.Uint32;
482 case GlobalVariableData.ValueOneofCase.Int64:
484 globalVar.Value = data.Int64;
486 case GlobalVariableData.ValueOneofCase.Uint64:
488 globalVar.Value = data.Uint64;
490 case GlobalVariableData.ValueOneofCase.Double:
492 globalVar.Value = data.Double;
495 throw new Exception(
"Unkown data type in GlobalVariableData.");
505 var request =
new GlobalVariableListGetRequest { SkipValues = skipValues };
506 var reply = client.GlobalVariableListGet(request);
507 List<SequencerGlobal> globals =
new List<SequencerGlobal>();
508 foreach (var globalData
in reply.Data)
510 globals.Add(ParseGlobalVariableData(globalData));
512 return globals.ToArray();
521 var request =
new GlobalVariableSetRequest { Name = name };
525 request.Bool = Convert.ToBoolean(value);
528 request.Char = Convert.ToChar(value);
531 request.Int16 = Convert.ToInt16(value);
534 request.Uint16 = Convert.ToUInt16(value);
537 request.Int32 = Convert.ToInt32(value);
540 request.Uint32 = Convert.ToUInt32(value);
543 request.Int64 = Convert.ToInt64(value);
546 request.Uint64 = Convert.ToUInt64(value);
549 request.Double = Convert.ToDouble(value);
552 throw new Exception(
"Unkown data type given in GlobalVariableSet().");
554 client.GlobalVariableSet(request);
562 public const string DEFAULT_SEQUENCER_NODE_NAME =
"NodeB";
563 public const string DEFAULT_RMP_NODE_NAME =
"NodeA";
564 public const string DEFAULT_IP =
"localhost";
565 public const string DEFAULT_MCAST_GROUP =
"224.0.0.0";
566 public const int DEFAULT_GRPC_PORT = 50051;
567 public const ulong DEFAULT_TIMEOUT_MS = 1000;
568 public const int DEFAULT_DISCOVER_PORT = 60061;
577 public static RapidSequencer[]
Discover(DiscoveryType discoveryType, ushort numExpectedSequencers = 0,
string sequencerNodeName = DEFAULT_SEQUENCER_NODE_NAME, ulong timeoutMs = DEFAULT_TIMEOUT_MS,
int discoveryPort = DEFAULT_DISCOVER_PORT)
579 ServerInfoCollection result;
580 if (discoveryType == DiscoveryType.All)
582 result = API.DiscoverBroadcast(discoveryType, numExpectedSequencers, sequencerNodeName, timeoutMs, discoveryPort);
584 else if (discoveryType == DiscoveryType.Local_Intime)
586 result = API.DiscoverLocalINtime(sequencerNodeName);
588 else if (discoveryType == DiscoveryType.Local_Windows)
590 result = API.DiscoverLocalWindows();
594 result = API.DiscoverLocal(sequencerNodeName);
598 var foundSequencers =
new List<RapidSequencer>();
599 for (uint index = 0; index < result.ServerCount(); index++)
605 var sequencerInfo = result.ServerInfoGet(index);
606 foundSequencers.Add(
new RapidSequencer(sequencerInfo.AddressGet(), sequencerInfo.PortGet()));
615 return foundSequencers.ToArray();
629 public static RapidSequencer Create(Platform platform,
string sequencerNodeName,
string rmpNodeName,
string executablePath,
630 int grpcPort = DEFAULT_GRPC_PORT,
string friendlyName =
"RapidServer", ulong timeoutMs = DEFAULT_TIMEOUT_MS,
int discoveryPort = DEFAULT_DISCOVER_PORT)
672 var result =
RSI.
RapidSequencer.
API.Start(platform, sequencerNodeName, rmpNodeName, executablePath, grpcPort, friendlyName, timeoutMs, discoveryPort);
687 string friendlyName =
"RapidServer", ulong timeoutMs = DEFAULT_TIMEOUT_MS,
int discoveryPort = DEFAULT_DISCOVER_PORT)
689 return Create(Platform.Windows, sequencerNodeName, rmpNodeName, executablePath, grpcPort, friendlyName, timeoutMs, discoveryPort);
702 public static RapidSequencer CreateRT(
string sequencerNodeName,
string rmpNodeName,
string executablePath,
int grpcPort = DEFAULT_GRPC_PORT,
703 string friendlyName =
"RapidServer", ulong timeoutMs = DEFAULT_TIMEOUT_MS,
int discoveryPort = DEFAULT_DISCOVER_PORT)
705 return Create(Platform.INtime, sequencerNodeName, rmpNodeName, executablePath, grpcPort, friendlyName, timeoutMs, discoveryPort);
SequencerGlobal[] GlobalVariableListGet(bool skipValues=false)
Gets the status of the global variables.
void DebugResume(string taskId)
Resumes the specified task.
void TaskRemove(string taskId)
Removes the specified task. Task must be stopped to be removed, throws an exception if the removal fa...
string TaskOutputGet(string taskId)
Gets the string output of the specified task.
void DebugBreakpointSet(string taskId, ulong lineNumber)
Places a breakpoint at the given line number in the specified task.
string RunAsync(ulong[] breakpoints=null)
Run the last compiled script. Does not wait for the script to finish excecution. Returns the ID of th...
TaskStatus TaskStatusGet(string taskId)
Gets the status of the specified task as a TaskStatus struct.
string CommandLineRun(string command)
Command the RapidSequencer to execute a given line and return the output.
void TaskStop(string taskId)
Stops the specified task.
void DebugBreakpointRemove(string taskId, ulong lineNumber)
Removes any breakpoints at the given line number in the specified task.
CompileSuccess Compile(string path, string entryPoint=DEFAULT_ENTRY_POINT, string exceptionHandler="")
Compiles the script at the given path. If successful, saves this compilation result to run at a later...
void DebugPause(string taskId)
Pauses the specified task.
void GlobalVariableSet(string name, SequencerGlobal.DataType type, dynamic value)
Sets the value of the specified global variable.
RapidSequencer(string grpcAddr, int grpcPort, uint connectTimeoutMs=CONNECT_TIMEOUT_MS, uint connectAttempts=CONNECT_ATTEMPTS)
Constructs a RapidSequencer object.
static TaskID TaskIDFromString(string taskId)
Creates a TaskID object from the given string.
string Run(ulong[] breakpoints=null)
Run the last compiled script. Waits for the script to finish execution. Returns the ID of the resulti...
string IpGet()
Returns the IPv4 address the RapidSequencer process is located at.
void TaskPause(string taskId)
Pauses the specified task.
void DebugStep(string taskId)
Proceeds to the next line of the specified task and pauses.
void EngineStart(string rmpNode="NodeA", string rmpPath="")
Starts the runtime of the RapidSequencer process.
string Run(CompileSuccess compileSuccess, ulong[] breakpoints=null)
Run the script using the given compilation result. Waits for the script to finish execution....
int PortGet()
Returns the port the RapidSequencer proecess is listening on.
string RunAsync(CompileSuccess compileSuccess, ulong[] breakpoints=null)
Run the script using the given compilation result. Does not wait for the script to finish excecution....
void TaskResume(string taskId)
Resumes the specified task.
string WarningsGet()
Returns the warnings from the last compilation the RapidSequencer performed.
void DebugStepIn(string taskId)
Enters the called function at the current line of the specified task. If unable to enter a function,...
EngineStatus EngineStatusGet()
Gets the status of the RapidSequencer process.
void DebugStepOut(string taskId)
Exits the execution of the currently executing function in the specified task. Pauses at the line the...
SequencerGlobal GlobalVariableGet(string name)
Gets the value of the global variable with the given name.
static RapidSequencer Create(Platform platform, string sequencerNodeName, string rmpNodeName, string executablePath, int grpcPort=DEFAULT_GRPC_PORT, string friendlyName="RapidServer", ulong timeoutMs=DEFAULT_TIMEOUT_MS, int discoveryPort=DEFAULT_DISCOVER_PORT)
Creates a RapidSequencer process on the given platform at the specified port if one does not already ...
static RapidSequencer CreateRT(string sequencerNodeName, string rmpNodeName, string executablePath, int grpcPort=DEFAULT_GRPC_PORT, string friendlyName="RapidServer", ulong timeoutMs=DEFAULT_TIMEOUT_MS, int discoveryPort=DEFAULT_DISCOVER_PORT)
Creates a real-time RapidSequencer process at the specified port if one does not already exist....
static RapidSequencer CreateWindows(string sequencerNodeName, string rmpNodeName, string executablePath, int grpcPort=DEFAULT_GRPC_PORT, string friendlyName="RapidServer", ulong timeoutMs=DEFAULT_TIMEOUT_MS, int discoveryPort=DEFAULT_DISCOVER_PORT)
Creates a Windows RapidSequencer process at the specified port if one does not already exist....
static RapidSequencer[] Discover(DiscoveryType discoveryType, ushort numExpectedSequencers=0, string sequencerNodeName=DEFAULT_SEQUENCER_NODE_NAME, ulong timeoutMs=DEFAULT_TIMEOUT_MS, int discoveryPort=DEFAULT_DISCOVER_PORT)
Discovers existing RapidSequencer processes and returns an array of RapidSequencer objects to interfa...
The RapidSequencerFactory provides static methods for creating RapidSequencer processes or discoverin...
An object for interacting with a RapidSequencer process.
const uint CONNECT_TIMEOUT_MS
The default timeout for creating a connection is 1000 milliseconds.
const uint CONNECT_ATTEMPTS
The default number of connection attempts to make during object construction.
void Shutdown()
Shuts down the RapidSequencer process.
const string DEFAULT_ENTRY_POINT
The name of the default function the RapidSequencer will use when running a script.
void EngineStop()
Stops the runtime of the RapidSequencer process.
Structure for describing the status of the RapidSequencer proccess. Describes whether the process is ...
Structure for describing a global tag. Contains information about the type, name, and value of the ta...
Structure for describing the status of a task. Describes what state the task is in,...