/*
* (c) Copyright, Real-Time Innovations, 2021. All rights reserved.
* RTI grants Licensee a license to use, modify, compile, and create derivative
* works of the software solely for use with RTI Connext DDS. Licensee may
* redistribute copies of the software provided that all such copies are subject
* to this license. The software is provided "as is", with no warranty of any
* type, including any warranty for fitness for any purpose. RTI is under no
* obligation to maintain or support the software. RTI shall not be liable for
* any incidental or consequential damages arising out of the use or inability
* to use the software.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Rti.Config;
namespace BuiltinTopicsExample
{
///
/// Interface shared by HelloWorldPublisher and HelloWorldSubscriber.
///
public interface IHelloWorldApplication : IDisposable
{
///
/// Returns a task that writes or reads a number of samples before
/// completing. The task can be cancelled.
///
Task Run(int sampleCount, CancellationToken cancellationToken);
}
///
/// Runs HelloWorldPublisher or HelloWorldSubscriber.
///
public static class HelloWorldProgram
{
///
/// The Main function runs the publisher or the subscriber.
///
public static async Task Main(string[] args)
{
var arguments = ParseArguments(args);
if (arguments == null)
{
return;
}
if (arguments.Verbose)
{
Logger.Instance.SetVerbosity(Verbosity.Warning);
}
// Run the publisher, the subscriber, or both.
var applications = new List();
if (arguments.Pub)
{
Console.WriteLine($"Running HelloWorldPublisher on domain {arguments.Domain}");
applications.Add(new HelloWorldPublisher(
domainId: arguments.Domain,
expectedPassword: arguments.Password,
topicName: arguments.Topic));
}
if (arguments.Sub)
{
Console.WriteLine($"Running HelloWorldSubscriber on domain {arguments.Domain}");
applications.Add(new HelloWorldSubscriber(
domainId: arguments.Domain,
password: arguments.Password,
topicName: arguments.Topic));
}
// Set up signal handler to Dispose the DDS entities
var cancellationSource = new CancellationTokenSource();
Console.CancelKeyPress += (_, eventArgs) =>
{
Console.WriteLine("Shutting down...");
eventArgs.Cancel = true;
cancellationSource.Cancel();
};
try
{
// Run the applications and await until they finish.
await Task.WhenAll(
applications.Select(
app => app.Run(arguments.SampleCount, cancellationSource.Token)
).ToArray()
);
}
catch (TaskCanceledException)
{
// ignore
}
finally
{
foreach (var app in applications)
{
app.Dispose();
}
}
}
private class Arguments
{
public bool Pub { get; set; }
public bool Sub { get; set; }
public string Password { get; set; }
public string Topic { get; set; }
public int Domain { get; set; }
public int SampleCount { get; set; } = int.MaxValue;
public bool Verbose { get; set; }
public bool Version { get; set; }
}
// Uses the System.CommandLine package to parse the program arguments.
private static Arguments ParseArguments(string[] args)
{
// Create a root command with some options
var rootCommand = new System.CommandLine.RootCommand
{
new System.CommandLine.Option(
new string[] { "--pub", "-p" },
description: "Whether to run the publisher application"),
new System.CommandLine.Option(
new string[] { "--sub", "-s" },
description: "Whether to run the subscriber application"),
new System.CommandLine.Option(
"--password",
description: "Example password used to authenticate [required] (see the example README)"),
new System.CommandLine.Option(
"--topic",
getDefaultValue: () => "Example msg",
description: "The topic name to publish or subscribe to"),
new System.CommandLine.Option(
new string[] { "--domain", "-d" },
getDefaultValue: () => 0,
description: "Domain ID used to create the DomainParticipant"),
new System.CommandLine.Option(
new string[] { "--sample-count", "-c" },
getDefaultValue: () => int.MaxValue,
description: "Number of samples to publish or subscribe to"),
new System.CommandLine.Option(
"--verbose",
description: "Increases the RTI Connext logging verbosity"),
new System.CommandLine.Option(
"--version",
description: "Displays the RTI Connext version")
};
rootCommand.Description = "Builtin Topics Example";
Arguments result = null;
rootCommand.Handler = System.CommandLine.Invocation.CommandHandler.Create(
(Arguments arguments) => result = arguments);
System.CommandLine.CommandExtensions.Invoke(rootCommand, args);
if (result == null)
{
return null;
}
if (result.Version)
{
Console.WriteLine(Rti.Dds.Core.ServiceEnvironment.Instance.Version);
return null;
}
if (result.Password == null)
{
Console.WriteLine("The option --password is required");
Console.WriteLine("Enter for example: dotnet run -- --pub --password ");
return null;
}
if (!result.Pub && !result.Sub)
{
Console.WriteLine(rootCommand.Description);
Console.WriteLine("\nYou can specify --pub or --sub to choose which application to run (or -h for help).");
Console.WriteLine("For example:\n dotnet run -- --pub --password \n");
Console.Write("Which one do you want to run? Enter 'pub' or 'sub' > ");
var choice = Console.ReadLine();
if (choice.StartsWith("p", StringComparison.OrdinalIgnoreCase))
{
result.Pub = true;
}
else
{
result.Sub = true;
}
}
if (result.SampleCount < 0)
{
result.SampleCount = int.MaxValue;
}
return result;
}
}
} // namespace BuiltinTopicsExample