making manipulation possible for my robocode implementation

More robocode again and I'm attempting to introduce an observer that will ensure my robot looks for enemies at the start of the battle, replacing the one I have discarded since I went down the domain driven route. At the moment, my robot is inanimate, so it is essential I get some manipulation in place.

Here's what I look at in this post:

  • the creation of a new manipulation state keeper using the generic state keeper
  • implement the context translator to turn the world state into the manipulation state
  • look at obtaining the robot engine from the service locator
  • pass this robot engine to all manipulation observers

So I start with the creation of a new manipulation state keeper and using the generic state keeper from my last post, it should be very easy to manage manipulation state and the observable situation. I'll start with a specification for my manipulation state keeper in the new manipulation namespace:

namespace Specifications.Model.Manipulation
{
    [Subject(typeof(ManipulationStateKeeper))]
    public class when_provided_with_a_state_update
    {
        Establish context = () =>
        {
            manipulationObserver = MockRepository.GenerateStub<IObserverToManipulate>();
            manipulationStateKeeper = new ManipulationStateKeeper(
                                 new List<IObserverToManipulate> {manipulationObserver});

            manipulationStateKeeper.Situation.Subscribe(s =>
                {
                    observedManipulationState = s.EventArgs;
                });

            manipulationStateUpdate = s => s.WeAreFocusedOnAnything = true;
        };

        Because of = () => 
            manipulationStateKeeper.UpdateState(manipulationStateUpdate);

        It should_update_the_situation_observable = () => 
            observedManipulationState.ShouldNotBeNull();

        It should_have_the_correct_manipulation_state_after_the_update = () =>
            observedManipulationState.WeAreFocusedOnAnything.ShouldBeTrue();

        static IObserverToManipulate manipulationObserver;
        static ManipulationStateKeeper manipulationStateKeeper;
        static ManipulationState observedManipulationState;
        static Action<ManipulationState> manipulationStateUpdate;
    }
}

Implementing this is very easy now that most of the behaviour is in the base generic state keeper:

    public class ManipulationStateKeeper : StateKeeper<ManipulationState, IObserverToManipulate>
    {
        public ManipulationStateKeeper(IEnumerable<IObserverToManipulate> observers) : 
                                                                      base(observers)
        {
        }

        protected override ManipulationState EnsureThatStateHasBeenCreated()
        {
            return new ManipulationState();
        }

        protected override IObservable<IEvent<ManipulationState>> 
                                         EnsureThatTheObservableHasBeenCreated()
        {
            return Observable.FromEvent<ManipulationState>(
                ev => this.StateHasUpdated += ev,
                ev => this.StateHasUpdated -= ev);
        }
    }

The next thing to write is my context translator - this will push the state from the world state into my manipulation state. At the moment I have no state to push, so this is going to be the bare bones implementation for the time being:

    [Subject(typeof(ManipulationContextTranslator))]
    public class when_publishing_a_state_change
    {
        Establish context = () =>
        {
            worldState = MockRepository.GenerateStub<IWorldState>();
            manipulationStateUpdater = MockRepository.GenerateStub<IUpdateManipulationState>();
            manipulationContextTranslator = 
                               new ManipulationContextTranslator(manipulationStateUpdater);
        };

        Because of = () => manipulationContextTranslator.PublishAStateChange(worldState);

        It should_update_state_via_the_manipulation_state_updater = () =>
            manipulationStateUpdater.AssertWasCalled(m => 
                                   m.UpdateState(Arg<Action<ManipulationState>>.Is.NotNull));

        static ManipulationContextTranslator manipulationContextTranslator;
        static IUpdateState<ManipulationState> manipulationStateUpdater;
        static IWorldState worldState;
    }

This specification ensures that the manipulation state keeper is sent an action to update the manipulation state. This will then fire the event and thus the situation observable. Here's the implementation for now to meet this specification:

    public class ManipulationContextTranslator : IContextTranslator
    {
        IUpdateState<ManipulationState> manipulationStateUpdater;

        public ManipulationContextTranslator(IUpdateState<ManipulationState> 
                                                              manipulationStateUpdater)
        {
            this.manipulationStateUpdater = manipulationStateUpdater;
        }

        public void PublishAStateChange(IWorldState worldState)
        {
            manipulationStateUpdater.UpdateState(m => { });
        }
    }

Next, I want to revisit the state keeper - when it is created, I want it to to have a copy of the robot engine so that it can pass it to all the manipulation observers. They will then be able to issue manipulation commands appropriately.

Unfortunately, if it comes in on the constructor then Autofac gives ma a circular dependency problem as the robot engine is at the root of all my dependency resolution already.
So how should I provide this via the service locator? This is currently an instance class that the robot itself creates and uses to resolve the engine and thus hook into IOC and the resolving of all dependencies when robocode activates the robot.
I'll have to have a static that returns the robot engine and though this is not ideal, it will serve my needs for the time being until I come up with a better plan.

There's one problem though, how do I test that the state keeper obtains the robot engine via a new static method or member?  Using delegates, I should be able to sort this out. So first, let me go back to the service locator specs and add a second specification:

    public class when_told_to_provide_a_robot_engine
    {
        Establish context = () => serviceLocator = new ServiceLocator();

        Because of = () => robotEngine = serviceLocator.ProvideRobotEngine();

        It should_return_a_valid_robot_engine = () => 
            robotEngine.ShouldNotBeNull();

        It should_ensure_we_are_able_to_obtain_the_same_robot_engine_by_another_route = () =>
            ServiceLocator.ObtainThePreviouslyRequestedRobotEngine().ShouldEqual(robotEngine);

        static ILocateServices serviceLocator;
        static ImARobotEngine robotEngine;
    }

I have a new specification here that ensures that when a robot engine is obtained statically from the service, that it is the same robot engine instance that the robot obtains from the instance method ProvideRobotEngine().
Here's the implementation for that:

    public class ServiceLocator : ILocateServices
    {
        static IContainer _container;

        public ServiceLocator()
        {
            RegisterEverything();
        }

        void RegisterEverything()
        {
            var builder = new ContainerBuilder();

            builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly())
                .AsImplementedInterfaces();

            builder.RegisterType<RobotEngine>().As<ImARobotEngine>().SingleInstance();

            _container = builder.Build();
        }

        public ImARobotEngine ProvideRobotEngine()
        {
            return _container.Resolve<ImARobotEngine>();
        }

        public static Func<ImARobotEngine> ObtainThePreviouslyRequestedRobotEngine = 
                                  () => _container.Resolve<ImARobotEngine>(); 
    }

I now have the robot engine registered as a single instance in Autofac and the delegate at the foot of the class ensures the same robot engine can be provided. I can also use this as a hook for testing the manipulation state keeper:

    [Subject(typeof(ManipulationStateKeeper))]
    public class when_created
    {
        Establish context = () =>
        {
            firstManipulationObserver = MockRepository.GenerateStub<IObserveToManipulate>();
            secondManipulationObserver = MockRepository.GenerateStub<IObserveToManipulate>();
            robotEngine = MockRepository.GenerateStub<ImARobotEngine>();
            ServiceLocator.ObtainThePreviouslyRequestedRobotEngine = () => robotEngine;
        };

        Because of = () => manipulationStateKeeper =
                              new ManipulationStateKeeper(new List<IObserveToManipulate> 
                                { firstManipulationObserver, secondManipulationObserver });

        It should_pass_the_robot_engine_from_the_service_locator_to_the_first_observer =
      () => firstManipulationObserver.AssertWasCalled(o => o.UseTheRobotEngine(robotEngine));

        It should_pass_the_robot_engine_from_the_service_locator_to_the_second_observer =
      () => secondManipulationObserver.AssertWasCalled(o => o.UseTheRobotEngine(robotEngine));

        static ManipulationStateKeeper manipulationStateKeeper;
        static IObserveToManipulate firstManipulationObserver;
        static IObserveToManipulate secondManipulationObserver;
        static ImARobotEngine robotEngine;
    }

In the context I am replacing the delegate on the service locator so that it returns a stubbed robot engine.
Then I can observe that is passes this robot engine to each observer.
Here's the result:

    public class ManipulationStateKeeper : StateKeeper<ManipulationState, IObserveToManipulate>
    {
        public ManipulationStateKeeper(IEnumerable<IObserveToManipulate> observers) 
                                                                          : base(observers)
        {
            var robotEngine = ServiceLocator.ObtainThePreviouslyRequestedRobotEngine();
            foreach (var observer in observers)
            {
                observer.UseTheRobotEngine(robotEngine);
            }
        }

        protected override ManipulationState EnsureThatStateHasBeenCreated()
        {
            return new ManipulationState();
        }

        protected override IObservable<IEvent<ManipulationState>> 
                                               EnsureThatTheObservableHasBeenCreated()
        {
            return Observable.FromEvent<ManipulationState>(
                ev => this.StateHasUpdated += ev,
                ev => this.StateHasUpdated -= ev);
        }
    }

    public interface IObserveToManipulate : IContextObserver<ManipulationState>
    {
        void UseTheRobotEngine(ImARobotEngine robotEngine);
    }

This hasn't been an ideal situation as I now have a public static delegate member on my service locator and this abstraction is now leaking, but I spent a long time trying to find a solution to the circular dependency issue, and this is the only real alternative I have at present.
In my next post I'll finally be writing the observer and making some commands to my robot.



0 comments: