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.IO;
using System.Collections.Generic; using System.Collections.Generic;
namespace PixelHub namespace PixelHub.Server
{ {
/// <summary> /// <summary>
/// Provides the server component of the Hull Pixelbot server that can be used to control any number of pixel bots at once. /// 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; int port;
TcpListener server; 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> /// <summary>
/// Whether the Hull Pixelbot serve is currently active and listening. /// Whether the Hull Pixelbot serve is currently active and listening.
/// </summary> /// </summary>
public bool Active { get; private set; } = false; 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 public IPAddress BindAddress
{ {
get { get {
@ -35,6 +46,7 @@ namespace PixelHub
bindAddress = value; bindAddress = value;
} }
} }
public int Port public int Port
{ {
get { get {
@ -80,21 +92,14 @@ namespace PixelHub
{ {
logger.WriteLine("Accepted connection from {0}.", client.Client.RemoteEndPoint); 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())) await pixelBot.Handle();
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());
}
}
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> <Platform Condition=" '$(Platform)' == '' ">x86</Platform>
<ProjectGuid>{B051D556-1D7A-48B0-8D4D-ABD2FBEBB6EF}</ProjectGuid> <ProjectGuid>{B051D556-1D7A-48B0-8D4D-ABD2FBEBB6EF}</ProjectGuid>
<OutputType>Exe</OutputType> <OutputType>Exe</OutputType>
<RootNamespace>PixelServer</RootNamespace> <RootNamespace>PixelHub.Server</RootNamespace>
<AssemblyName>PixelServer</AssemblyName> <AssemblyName>PixelServer</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion> <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
</PropertyGroup> </PropertyGroup>
@ -40,6 +40,8 @@
<Compile Include="SBRL.Utilities\ForgetTask.cs" /> <Compile Include="SBRL.Utilities\ForgetTask.cs" />
<Compile Include="SBRL.Utilities\Utilities.cs" /> <Compile Include="SBRL.Utilities\Utilities.cs" />
<Compile Include="SBRL.Utilities\PrefixedWriter.cs" /> <Compile Include="SBRL.Utilities\PrefixedWriter.cs" />
<Compile Include="PixelCommand.cs" />
<Compile Include="PixelBot.cs" />
</ItemGroup> </ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<ItemGroup> <ItemGroup>

View File

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