1

This is kind of a follow up question to this https://stackoverflow.com/questions/23743285/model-view-controller-and-callbacks, but I wanted to post it separately, because its kind of a different topic.

I'm working on a multiplayer cardgame for the Android platform. I split the project into MVC which fits the needs pretty good, but I'm currently stuck because I can't figure out a good way to communicate between the different parts.

I have everything setup and working with the controller being a big state machine, which is called over and over from the gameloop, and calls getter methods from the GUI and the android/network part to get the input. The input itself in the GUI and network is set by inputlisteners that set a local variable which I read in the getter method.

So far so good, this is working. But my problem is, the controller has to check every input separately,so if I want to add an input I have to check in which states its valid and call the getter method from all these states. This is not good, and lets the code look pretty ugly, makes additions uncomfortable and adds redundance.

So what I've got from the question I mentioned above is that some kind of command or event pattern will fit my needs. What I want to do is to create a shared and threadsafe queue in the controller and instead of calling all these getter methods, I just check the queue for new input and proceed it. On the other side, the GUI and network don't have all these getters, but instead create an event or command and send it to the controller through, for example, observer/observable.

Now my problem: I can't figure out a way, for these commands/events to fit a common interface (which the queue can store) and still transport different kind of data (button clicks, cards that are played, the player id the command comes from, synchronization data etc.).

If I design the communication as command pattern, I have to stick all the information that is needed to execute the command into it when its created, that's impossible because the GUI or network has no knowledge of all the things the controller needs to execute stuff that needs to be done when for example a card is played.

I thought about getting this stuff into the command when executing it. But over all the different commands I have, I would need all the information the controller has, and thus give the command a reference to the controller which would make everything in it public, which is real bad design I guess.

So, I could try some kind of event pattern. I have to transport data in the event. So, like the command, I would have an interface, which all events have in common, and can be stored in the shared queue. I could create a big enum with all the different events that a are possible, save one of these enums in the actual event, and build a big switch case for the events, to proceed different stuff for different events.

The problem here: I have different data for all the events. But I need a common interface, to store the events in a queue. How do I get the specific data, if I can only access the event through the interface?

Even if that wouldn't be a problem, I'm creating another big switch case, which looks ugly, and when i want to add a new event, I have to create the event itself, the case, the enum, and the method that's called with the data.

I could of course check the event with the enum and cast it to its type, so I can call event type specific methods that give me the data I need, but that looks like bad design too.

1

It seems to me like you are missing the Model portion of your MVC pattern.

Your controller would be generally be responsible for gathering any relevant input for making a request to the model.. IE:

I want to draw a card.. I'm going to discard a card.. I want to bet 250 dollars.

Then the model then would be responsible for making sure they are valid requests, processing them, and notifying the clients that state has been updated. The model shouldn't need to know anything about specific clicks, or the player since that should be inferred from the connection the request comes from. The controller won't actually do anything other than ship a well formed request to the model.

Once you are at the model it is up to you want to encapsulate each request handler into a different object, or if you just want to do a big case statement, but any code that actually changes the game state will belong to the model.

As far as storing the requests in some sort of queue, you will generally just use a tag interface with no implementation. The handler for each request will check the type, doing any casting and handle all of the implementation dependent logic.

  • My model currently stores all game specific data and implements the game logic. I designed an interface which the controller uses to to control the steps of the game, like startGame(), startTurn(), dealCards() and all the interactions like playCard(Card card). The states are saved in the controller, who fetches the currently needed data from the given source, calls the model interface with the data, and changes state if needed. My problem is that i check the needed data, over and over in every gameloop, instead of just checking a queue which is filled by the network/gui when data arrives – Kedu May 29 '14 at 21:23
  • So, if i understand correctly, u r saying, i should keep the gamestate in the model, and the controller just sends the data. That seems reasonable and i will look into that. But its not gonna change my current problem. I'll still get differnt events/commands, that i want to save in a shared queue of one type. Is casting the event depening on an eventEnum the only way i can get the the event data ? besides the command pattern ofc, which i think i cant use, cause of the missing data when creating the command in the gui for example. – Kedu May 29 '14 at 21:34
  • Yes, the gamestate belongs in the model. – user129779 May 29 '14 at 22:13
  • 1
    Casting isn't the only way to get the data, but it tends to be the most effective way to to let the compiler help you. One alternative is to use an associative array/map/dictionary, but it amounts to the same thing. To work with the data effectively at some point an event handler has to understand implementation details of the event. The point of using a command pattern is limit that dependency to a single place. – user129779 May 29 '14 at 22:20
  • Just to complete this: After some more research i think the best solution is a combination of events and commands. I register a listener for every event in the controller, be it through the java event stuff or an external eventbus. The Event is triggered immediatly, and a command is build in the event listener and saved in a queue. Thats possible now, cause i know all the data in the controller. This queue is executed later where it fits in the gameloop. – Kedu May 31 '14 at 17:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.