Commit 14e97ee
Changed files (13)
product
project
common
domain
presentation
product/project/common/ActionCommand.cs
@@ -0,0 +1,19 @@
+using System;
+
+namespace mars.rover.common
+{
+ public class ActionCommand : Command
+ {
+ readonly Action command;
+
+ public ActionCommand(Action command)
+ {
+ this.command = command;
+ }
+
+ public void run()
+ {
+ command();
+ }
+ }
+}
\ No newline at end of file
product/project/domain/NASA.cs
@@ -0,0 +1,20 @@
+using System.Collections.Generic;
+
+namespace mars.rover.domain
+{
+ public class NASA
+ {
+ readonly Queue<Rover> rovers = new Queue<Rover>();
+ public Mars plateau { get; set; }
+
+ public void deploy(Rover rover)
+ {
+ rovers.Enqueue(rover);
+ }
+
+ public Rover waiting()
+ {
+ return rovers.Dequeue();
+ }
+ }
+}
\ No newline at end of file
product/project/presentation/infrastructure/CommandFactory.cs
@@ -0,0 +1,13 @@
+using System;
+using mars.rover.common;
+
+namespace mars.rover.presentation.infrastructure
+{
+ public class CommandFactory
+ {
+ public virtual Command create_for(Action action)
+ {
+ return new ActionCommand(action);
+ }
+ }
+}
\ No newline at end of file
product/project/presentation/infrastructure/CommandPump.cs
@@ -0,0 +1,9 @@
+using mars.rover.common;
+
+namespace mars.rover.presentation.infrastructure
+{
+ public interface CommandPump<Input> : Command
+ {
+ void run<Command>(Input input) where Command : ParameterizedCommand<Input>;
+ }
+}
\ No newline at end of file
product/project/presentation/infrastructure/SynchronousCommandProcessor.cs
@@ -0,0 +1,21 @@
+using System.Collections.Generic;
+using mars.rover.common;
+
+namespace mars.rover.presentation.infrastructure
+{
+ public class SynchronousCommandProcessor : CommandProcessor
+ {
+ readonly Queue<Command> commands = new Queue<Command>();
+
+ public void add(Command command)
+ {
+ commands.Enqueue(command);
+ }
+
+ public void run()
+ {
+ while (commands.Count > 0)
+ commands.Dequeue().run();
+ }
+ }
+}
\ No newline at end of file
product/project/presentation/infrastructure/SynchronousCommandPump.cs
@@ -0,0 +1,34 @@
+using System.Linq;
+using mars.rover.common;
+
+namespace mars.rover.presentation.infrastructure
+{
+ public class SynchronousCommandPump : CommandPump<string>
+ {
+ readonly Registry<ParameterizedCommand<string>> commands;
+ readonly CommandProcessor processor;
+ readonly CommandFactory factory;
+
+ public SynchronousCommandPump(Registry<ParameterizedCommand<string>> commands, CommandProcessor processor, CommandFactory factory)
+ {
+ this.commands = commands;
+ this.processor = processor;
+ this.factory = factory;
+ }
+
+ public virtual void run<Command>(string input) where Command : ParameterizedCommand<string>
+ {
+ processor.add(factory.create_for(() => get<Command>().run_against(input)));
+ }
+
+ ParameterizedCommand<string> get<T>()
+ {
+ return commands.First(y => y is T);
+ }
+
+ public virtual void run()
+ {
+ processor.run();
+ }
+ }
+}
\ No newline at end of file
product/project/presentation/CaptureUserInstructionsConsoleView.cs
@@ -15,7 +15,7 @@ namespace mars.rover.presentation
public void attach_to(CaptureUserInstructionsPresenter presenter)
{
- writer.WriteLine("Enter upper right coordinates:");
+ writer.WriteLine("enter upper right coordinates:");
presenter.provide_upper_right_coordinates(reader.ReadLine());
for (var i = 0; i < 2; i++)
@@ -26,6 +26,7 @@ namespace mars.rover.presentation
writer.WriteLine("enter commands to navigate rover:");
presenter.navigate_rover_using(reader.ReadLine());
}
+ presenter.go();
}
public void display(string location)
product/project/presentation/CaptureUserInstructionsPresenter.cs
@@ -1,25 +1,16 @@
-using System;
-using System.Linq;
-using mars.rover.common;
-using mars.rover.domain;
-using mars.rover.presentation.model;
+using mars.rover.presentation.infrastructure;
namespace mars.rover.presentation
{
public class CaptureUserInstructionsPresenter : Presenter
{
readonly CaptureUserInstructionsView view;
- readonly Registry<HeadingFactory> factories;
- readonly Registry<Navigation> navigations;
- Mars plateau;
- Rover rover;
+ readonly CommandPump<string> pump;
- public CaptureUserInstructionsPresenter(CaptureUserInstructionsView view, Registry<HeadingFactory> factories,
- Registry<Navigation> navigations)
+ public CaptureUserInstructionsPresenter(CaptureUserInstructionsView view, CommandPump<string> pump)
{
this.view = view;
- this.factories = factories;
- this.navigations = navigations;
+ this.pump = pump;
}
public virtual void run()
@@ -29,26 +20,22 @@ namespace mars.rover.presentation
public virtual void provide_upper_right_coordinates(string line)
{
- var coordinates = line.Split(new[] {' '});
- plateau = new Mars(Convert.ToUInt32(coordinates[0]), Convert.ToUInt32(coordinates[1]));
+ pump.run<CreateMarsCommand>(line);
}
public virtual void deploy_rover_to(string deployment_coordinates)
{
- var coordinates = deployment_coordinates.Split(new[] {' '});
- rover = new Rover(Convert.ToUInt32(coordinates[0]), Convert.ToUInt32(coordinates[1]),
- find_heading_for(coordinates[2]));
+ pump.run<DeployRoverCommand>(deployment_coordinates);
}
public virtual void navigate_rover_using(string navigation_commands)
{
- navigation_commands.each(x => navigations.First(y => y.is_satisfied_by(x)).run_against(rover));
- view.display(rover.ToString());
+ pump.run<NavigateRoverCommand>(navigation_commands);
}
- Heading find_heading_for(string heading)
+ public void go()
{
- return factories.First(x => x.is_satisfied_by(heading)).create(plateau);
+ pump.run();
}
}
}
\ No newline at end of file
product/project/presentation/CreateMarsCommand.cs
@@ -0,0 +1,23 @@
+using System;
+using mars.rover.common;
+using mars.rover.domain;
+
+namespace mars.rover.presentation
+{
+ public class CreateMarsCommand : ParameterizedCommand<string>
+ {
+ NASA nasa;
+
+ public CreateMarsCommand(NASA nasa)
+ {
+ this.nasa = nasa;
+ }
+
+ public void run_against(string item)
+ {
+ var coordinates = item.Split(new[] {' '});
+ var plateau = new Mars(Convert.ToUInt32(coordinates[0]), Convert.ToUInt32(coordinates[1]));
+ nasa.plateau = plateau;
+ }
+ }
+}
\ No newline at end of file
product/project/presentation/DeployRoverCommand.cs
@@ -0,0 +1,34 @@
+using System;
+using System.Linq;
+using mars.rover.common;
+using mars.rover.domain;
+using mars.rover.presentation.model;
+
+namespace mars.rover.presentation
+{
+ public class DeployRoverCommand : ParameterizedCommand<string>
+ {
+ readonly Registry<HeadingFactory> factories;
+ readonly NASA nasa;
+
+ public DeployRoverCommand(Registry<HeadingFactory> factories, NASA nasa)
+ {
+ this.factories = factories;
+ this.nasa = nasa;
+ }
+
+ public virtual void run_against(string deployment_coordinates)
+ {
+ var coordinates = deployment_coordinates.Split(new[] {' '});
+ var rover = new Rover(Convert.ToUInt32(coordinates[0]), Convert.ToUInt32(coordinates[1]),
+ find_heading_for(coordinates[2]));
+ nasa.deploy(rover);
+ }
+
+ Heading find_heading_for(string heading)
+ {
+ var plateau = nasa.plateau;
+ return factories.First(x => x.is_satisfied_by(heading)).create(plateau);
+ }
+ }
+}
\ No newline at end of file
product/project/Program.cs
@@ -4,6 +4,7 @@ using System.Linq;
using mars.rover.common;
using mars.rover.domain;
using mars.rover.presentation;
+using mars.rover.presentation.infrastructure;
using mars.rover.presentation.model;
namespace mars.rover
@@ -24,25 +25,35 @@ namespace mars.rover
static void Main(string[] args)
{
+ var nasa = new NASA();
+ var view = new CaptureUserInstructionsConsoleView(Console.In, Console.Out);
var program = new Program(
new CaptureUserInstructionsPresenter(
- new CaptureUserInstructionsConsoleView(Console.In, Console.Out),
- new DefaultRegistry<HeadingFactory>
- {
- new HeadingFactory("N", x => new North(x)),
- new HeadingFactory("E", x => new East(x)),
- new HeadingFactory("W", x => new West(x)),
- new HeadingFactory("S", x => new South(x)),
- new UnknownHeadingFactory(),
- },
- new DefaultRegistry<Navigation>
- {
- new Navigation('L', x => x.turn_left()),
- new Navigation('R', x => x.turn_right()),
- new Navigation('M', x => x.move_forward()),
- new UnknownNavigation(),
- }
- ));
+ view,
+ new SynchronousCommandPump(new DefaultRegistry<ParameterizedCommand<string>>
+ {
+ new CreateMarsCommand(nasa),
+ new DeployRoverCommand(
+ new DefaultRegistry<HeadingFactory>
+ {
+ new HeadingFactory("N", x => new North(x)),
+ new HeadingFactory("E", x => new East(x)),
+ new HeadingFactory("W", x => new West(x)),
+ new HeadingFactory("S", x => new South(x)),
+ new UnknownHeadingFactory(),
+ },
+ nasa),
+ new NavigateRoverCommand(
+ new DefaultRegistry<Navigation>
+ {
+ new Navigation('L', x => x.turn_left()),
+ new Navigation('R', x => x.turn_right()),
+ new Navigation('M', x => x.move_forward()),
+ new UnknownNavigation(),
+ }
+ ,
+ view, nasa)
+ }, new SynchronousCommandProcessor(), new CommandFactory())));
program.run_against(args.Select(x => (CommandLineArgument) x));
}
}
product/project/project.csproj
@@ -48,6 +48,13 @@
<Compile Include="common\DefaultRegistry.cs" />
<Compile Include="common\EnumerableExtensions.cs" />
<Compile Include="common\Registry.cs" />
+ <Compile Include="common\ActionCommand.cs" />
+ <Compile Include="presentation\infrastructure\CommandFactory.cs" />
+ <Compile Include="presentation\infrastructure\CommandPump.cs" />
+ <Compile Include="presentation\infrastructure\SynchronousCommandPump.cs" />
+ <Compile Include="presentation\CreateMarsCommand.cs" />
+ <Compile Include="presentation\DeployRoverCommand.cs" />
+ <Compile Include="presentation\infrastructure\SynchronousCommandProcessor.cs" />
<Compile Include="presentation\model\HeadingFactory.cs" />
<Compile Include="common\CallbackCommand.cs" />
<Compile Include="presentation\CaptureUserInstructionsConsoleView.cs" />
@@ -64,6 +71,8 @@
<Compile Include="domain\Mars.cs" />
<Compile Include="domain\Plateau.cs" />
<Compile Include="presentation\model\Navigation.cs" />
+ <Compile Include="domain\NASA.cs" />
+ <Compile Include="presentation\NavigateRoverCommand.cs" />
<Compile Include="presentation\Presenter.cs" />
<Compile Include="presentation\CaptureUserInstructionsPresenter.cs" />
<Compile Include="common\Specification.cs" />