tags:

views:

73

answers:

3

I'm making a game in Java, and I think I have a good idea of how to handle events. Does this sound right?

A Window class--the view. It's a representation of the World at the current moment. There's also a Game class -- the controller. (The model's implementation is irrelevant for this question).

The Window class doesn't care about events. Therefore, the event listener simply dispatches them to the Game class (via something like game.notifyEvent(Event e);.

The Game class, upon receipt of this event, will start updating values and the like, and some variables (like the location of the player) will be changed. At this point, it uses its class variable Window w to notify it of the changes (via various methods such as w.movePlayer(Position p), etc.

SO, does this sound like something that would make sense to you?

A: 

I never worked with Java (working with ASP.NET MVC), but the idea makes sense to me.

Get nofication to the Backend (Controller) -> Update values in backend -> Notify/Push those changes to the view

Mahesh Velaga
A: 

I think you should implement the Observer design pattern (http://en.wikipedia.org/wiki/Observer_pattern) without using .NET's events. In my approach, you need to define a couple of interfaces and add a little bit of code. For each different kind of event, create a pair of symmetric interfaces

public interface IEventXDispatcher
{
    void Register(IEventXHandler handler);

    void Unregister(IEventXHandler handler) throws NotSupportedException;
}

public interface IEventXHandler
{
    void Handle(Object sender, Object args);
}

X denotes the specific name of event (Click, KeyPress, EndApplication, WhateverYouWant). Then make your observed class implement IEventDispatcher and your observer class(es) implement IEventHandler

public class Dispatcher implements IEventXDispatcher, IEventYDispatcher ...
{
    private List<IEventXHandler> _XHandlers;
    private List<IEventYHandler> _YHandlers;

    void Register(IEventXHandler handler)
    {
        _XHandlers.Add(handler);
    }

    void Unregister(IEventHandler handler) throws NotSupportedException
    {
        //Simplified code
        _XHandlers.Remove(handler);
    }

    private MyMethod()
    {
        [...]
        for(IEventXHandler handler: _XHandlers)
            handler.Handle(this, new AnyNeededClass())
        [...]
    }
    //Same for event Y

All the code is hand-written. I have little experience with Java but I believe this pattern may help you!

djechelon
MVC is based on the Observer design pattern anyway- that's what `game.notifyEvent(...)` is doing.
Lunivore
+1  A: 

Hi Christian,

Yes, what you're doing makes some sense. I find it much more intuitive to have the Window listen to the Game than the other way round. I've also found that Java is much more maintainable if you separate out the different areas of the GUI and pass the Game into each of them through a fine-grained interface. I normally get the GUI elements to listen to changes in the model, and request any interactions to be dealt with. This way round makes for easier unit testing, and you can replace the GUI with a fake for acceptance testing if you don't have a decent automation suite, or even just for logging.

Usually splitting up the GUI results in some panels purely listening, and some panels purely interacting. It makes for a really lovely separation of concerns. I represent the panels with their own classes extending JPanel, and let the Window pass the Game to them on construction.

So for instance, if I have two panels, one of which displays the results and one of which has an "Update" button, I can define two interfaces: INotifyListenersOfResults and IPerformUpdates. (Please note that I'm making role-based interfaces here using the IDoThisForYou pattern; you can call them whatever you like).

The Game controller then implements both these interfaces, and the two panels each take the respective interface. The Update interface will have a method called RequestUpdate and the Results interface will have AddResultsListener. Both these methods then appear on the Game class.

Regardless of whether you get the Game to listen to the Window or the Window to the Game, by separating things through interfaces this way you make it much easier to split the Game controller later on and delegate its responsibilities, once things start getting really complicated, which they always do!

Lunivore
So after I call `game.pushEvent(e)` I should call `ChangeObject changes = game.getChanges()` or something? Seems strange to make a class just for information passing.
Christian Mann
I normally just create a small interface rather than creating a ChangeObject class, then put that interface directly on the Game. If it gets too complicated you can split out another class later and use Dependency Injection to pass it to both the Game and the Window.
Lunivore