1

I have been trying to get my head around this problem for the last week and can't seem to find a solution that doesn't either require a singleton or tight coupling. I am developing a 3D space game, an early demo of which is here...
www.sugarspook.com/darkmatters/demo.html
... and I'm getting to the point of adding Missions which the player will be able to select from the heads up display (Hud class).

The structure of the game is:
The Game class contains the Hud and the ObjectsList class.
The ObjectsList class contains various game Objects, including the Player, the various kinds of ship, planets, and Orbitals (space stations).
Missions get instantiated when the Player gets to within a certain distance of an Orbital.
Missions are added to a MissionsList class, itself within the ObjectsList.
Missions can become unavailable and expire without warning (as if they are selected by another pilot) so the list displayed on the Hud is dynamic and updated regularly.
Previously I've had the Missions dispatching events up to Game which in turn informs Hud of the change. This seems a little clunky to me, as there are various deeper 'levels' to the Hud that the information needs to be passed down to. I end up with a lot of the same functions all the way down the chain.

The solution I was thinking of involved injecting a reference to the MissionsList class into the Hud, enabling it to listen for updates from the Missonslist. I've heard that it's bad practise to mix the state of something with its display, but I don't see how else to get the 'live' list of Missions to the Hud. In contrast, if the Hud contains only display details without reference to the Mission object that generated those details, when a player selects a Mission from the Hud how can I determine which Mission has been chosen? Is tight coupling in this case OK? Or should I use a singleton to communicate to the Hud? If there is something fundamentally wrong with anything I'm suggesting I welcome being told what that is and what is the best solution. Thanks.

moosefetcher
  • 1,841
  • 2
  • 23
  • 39

1 Answers1

0

Well the simple answer is why not couple via an intermediate interface?

interface IMissionList
{
    ObservableCollection<IMission> Missions{get;}
}

Then in your Dependency Injection bind that to something that can resolve to a instance, singleton or constant or etc...

then inject it into your Hud's constructor

Hud(IMissionList missionList){}

Now you are loosely coupled to a contract, the implementation of-which can be changed at any point, so long as the implementation adheres to the contract. Also, due to injection your Hud only has to concern it self with using IMissionList rather than also finding it.

[Edit] Sorry, this is C#, but hopefully the idea is of use. See for actionscript interfaces and Dependency Injection for Actionscript

Meirion Hughes
  • 24,994
  • 12
  • 71
  • 122
  • Thanks for the reply. It does sound useful, but I don't quite follow the 'in your DI...' part, sorry. This may be obvious to some but what is 'DI'? Thanks. – moosefetcher Feb 28 '13 at 15:12
  • Dependency Injection. It really is awesome once you get the lightbulb moment. Google: Inversion of Control. Actionscript DI: http://www.adobe.com/devnet/flex/articles/dependency_injection.html – Meirion Hughes Feb 28 '13 at 15:17
  • Thanks again. I recall reading about that a while ago. Looks like I have some more reading to do. – moosefetcher Feb 28 '13 at 15:37
  • Just to be clear - passing the MissionsList in the constructor of the Hud is DI, right? It just wouldn't be as flexible as using an interface... – moosefetcher Feb 28 '13 at 15:48
  • No, passing the MissionsList in the constructor of the Hud is "Inversion of Control". Dependency Injection is when it is automatically passed into the constructor for you, when you ask for an object of type Hud. You'll have to look at a sample to see what it does. But basically, you have a Dependency Injector called IoC and then you say Bind.Type(IMissionControl).To(new MissionControl()), then you say IoC.Get(Hud) and it will automatically work out that hud wants a IMissionControl parameter. – Meirion Hughes Feb 28 '13 at 15:53
  • Ai ai ai. OK. I will continue the research. – moosefetcher Feb 28 '13 at 16:05
  • Nope. I can safely say I do not understand this. If DI creates the dependencies FOR you, how would both the Hud and the ObjectsList end up with a reference to the SAME MissionsList object? Also I'm not aware of the AS3 equivalent to Bind.Type(...), so I don't really know what to make of that. – moosefetcher Feb 28 '13 at 16:25
  • You can bind types to constants. So anything that wants IMissions will get the same instance. check out: http://www.as3dp.com/2010/10/bend-over-this-wont-hurt-a-bit-actionscript-3-0-dependency-injection/ But I guess for now, you can ignore DI if you wish. Make an interface for IMissionList that has the very basic logic you need in HUD. Implement it and pass it into your hud. – Meirion Hughes Feb 28 '13 at 16:34