Refactor to add PixelBot & PixelCommand classes.

This commit is contained in:
Starbeamrainbowlabs 2016-10-16 17:26:13 +01:00
parent 950d7aafa1
commit fe97d617ce
5 changed files with 160 additions and 17 deletions

View file

@ -0,0 +1,61 @@
using System;
using System.Net.Sockets;
using System.Threading.Tasks;
using System.IO;
namespace PixelHub.Server
{
/// <summary>
/// Provides an interface through which you can communicate with and control a Hull PixelBot.
/// </summary>
public class PixelBot
{
public bool Connected { get; private set; } = false;
TcpClient client;
StreamReader incoming;
StreamWriter outgoing;
/// <summary>
/// Initializes a new <see cref="PixelHub.Server.PixelBot"/> instance and connects it to a Hull Pixelbot.
/// </summary>
/// <param name="inClient">The Tcp connection between the PixelHub server and the Hull PixelBot.</param>
public PixelBot(TcpClient inClient)
{
client = inClient;
}
/// <summary>
/// Starts listening for and handling messages that come from the remote PixelBot.
/// </summary>
/// <param name="client">Client.</param>
public async Task Handle(TcpClient client)
{
if (Connected)
throw new InvalidOperationException("Only one connection handling loop can be active at once!");
Connected = true;
incoming = new StreamReader(client.GetStream());
outgoing = new StreamWriter(client.GetStream()) { AutoFlush = true };
string nextLine;
while((nextLine = await incoming.ReadLineAsync()) != null)
{
Console.WriteLine("Got message from client: '{0}'", nextLine.Trim());
}
Connected = false;
}
/// <summary>
/// Sends the given command to the remote PixelBot.
/// </summary>
/// <param name="command">The command to send.</param>
public async Task Send(PixelCommand command)
{
await outgoing.WriteLineAsync(command.AsCompiledCommand());
}
}
}

View file

@ -0,0 +1,75 @@
using System;
namespace PixelHub
{
public enum PixelWheel
{
None,
Left,
Right,
Both
}
/// <summary>
/// Specifies a single command that is to be sent to a PixelBot.
/// </summary>
class PixelCommand
{
/// <summary>
/// The wheel(s) that should be operated upon.
/// </summary>
public PixelWheel Wheel { get; set; }
/// <summary>
/// The duration, in milliseconds, that the left wheel should turn for.
/// </summary>
public int DurationLeft { get; set; }
/// <summary>
/// The duration, in milliseconds, that the right wheel should turn for.
/// </summary>
/// <value>The duration right.</value>
public int DurationRight { get; set; }
/// <summary>
/// The duration, in milliseconds, that the wheels should turn for.
/// </summary>
/// <description>
/// This property sets both the <see cref="DurationLeft" /> and <see cref="DurationRight" /> properties.
/// The getter returns the maximum of the two durations.
/// </description>
public int Duration {
get {
return Math.Max(DurationLeft, DurationRight);
}
set {
DurationLeft = value;
DurationRight = value;
}
}
/// <summary>
/// Creates a new <see cref="PixelCommand" /> instance.
/// </summary>
/// <param name="inWheel">The wheel to turn.</param>
/// <param name="inDuration">The duration , in milliseconds, to turn the wheels for.</param>
public PixelCommand(PixelWheel inWheel, int inDuration)
{
Wheel = inWheel;
Duration = inDuration;
}
/// <summary>
/// Compiles the PixelCommand into a raw command string that cna be understood by the PixelBot.
/// </summary>
/// <returns>The compiled command, ready to be sent over the wire to the PixelBot.</returns>
public string AsCompiledCommand()
{
return $"Move:L={DurationLeft},Right={DurationRight}";
}
public override string ToString()
{
return string.Format("PixelCommand: Targets Wheel={0} for Duration={1}ms", Wheel, Duration);
}
}
}

View file

@ -6,7 +6,7 @@ using SBRL.Utilities;
using System.IO;
using System.Collections.Generic;
namespace PixelHub
namespace PixelHub.Server
{
/// <summary>
/// Provides the server component of the Hull Pixelbot server that can be used to control any number of pixel bots at once.
@ -18,12 +18,23 @@ namespace PixelHub
int port;
TcpListener server;
List<TcpClient> clients = new List<TcpClient>();
/// <summary>
/// A list of PixelBots that are currently connected to the PixelHub.
/// </summary>
public List<PixelBot> ConnectedBots = new List<PixelBot>();
/// <summary>
/// Whether the Hull Pixelbot serve is currently active and listening.
/// </summary>
public bool Active { get; private set; } = false;
/// <summary>
/// The IPAddress that the PixelHub is (or should be) bound to.
/// </summary>
/// <remarks>
/// You can only set this Property with generating an exception if the server
/// hasn't already been started with List().
/// </remarks>
public IPAddress BindAddress
{
get {
@ -35,6 +46,7 @@ namespace PixelHub
bindAddress = value;
}
}
public int Port
{
get {
@ -80,21 +92,14 @@ namespace PixelHub
{
logger.WriteLine("Accepted connection from {0}.", client.Client.RemoteEndPoint);
clients.Add(client);
PixelBot pixelBot = new PixelBot(client);
ConnectedBots.Add(pixelBot);
using (StreamReader incoming = new StreamReader(client.GetStream()))
using (StreamWriter outgoing = new StreamWriter(client.GetStream()) { AutoFlush = true })
{
string nextLine;
while((nextLine = await incoming.ReadLineAsync()) != null)
{
Console.WriteLine("Got message from client: '{0}'", nextLine.Trim());
}
}
await pixelBot.Handle();
clients.Remove(client);
ConnectedBots.Remove(pixelBot);
Console.WriteLine("Lost connection from {0}.", client.Client.RemoteEndPoint);
logger.WriteLine("Lost connection from {0}.", client.Client.RemoteEndPoint);
}
}
}

View file

@ -5,7 +5,7 @@
<Platform Condition=" '$(Platform)' == '' ">x86</Platform>
<ProjectGuid>{B051D556-1D7A-48B0-8D4D-ABD2FBEBB6EF}</ProjectGuid>
<OutputType>Exe</OutputType>
<RootNamespace>PixelServer</RootNamespace>
<RootNamespace>PixelHub.Server</RootNamespace>
<AssemblyName>PixelServer</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
</PropertyGroup>
@ -40,6 +40,8 @@
<Compile Include="SBRL.Utilities\ForgetTask.cs" />
<Compile Include="SBRL.Utilities\Utilities.cs" />
<Compile Include="SBRL.Utilities\PrefixedWriter.cs" />
<Compile Include="PixelCommand.cs" />
<Compile Include="PixelBot.cs" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<ItemGroup>

View file

@ -6,9 +6,9 @@ using System.Threading.Tasks;
using SBRL.Utilities;
using PixelHub.Net;
namespace PixelHub
namespace PixelHub.Server
{
static class Program
static class ServerProgram
{
private static int port = 5050;
private static PrefixedWriter systemWriter = new PrefixedWriter(Console.Out) { Prefix = "[System] " };