MessageBox style function

Started by
9 comments, last by Programmer16 16 years, 1 month ago
I'm working on a MessageBox style function for my game. Here's an example:

void OnActivate()
{
    std::string Choices[] = {"Yes", "No"};
    std::string Choice = dft::ShowChoiceBox("Do you want to continue?", Choices, sizeof(Choices) / sizeof(std::string) /* other stuff here */);
    if(Choice == "No")
        MyApp.Running = false;
}

The problem I'm having is the message loop. I've got it working by copying the main window's message pump. My question is: is this an ok solution? Or is there a better solution I should be looking for?
Advertisement
Is the message box going to be a dialog of the main window or a new window or something rendered within your framework? The last seems like the most plausible (otherwise you'd just use MessageBox...). But if that were the case you shouldn't need a new message pump, it's just a new renderable with its own input listeners (if you do composite input handling) or a new state pushed on a stack...
The problem is I need it to stay in the function until the user makes a choice, but it still needs to update input and render.

And yes, you're right; it's for an in-game system.
Its hard to comment without seeing additional code and a fuller description of what you want to do.

If by render you mean the game running behind the message box continues to render, then staying inside the function (with its current signature) won't suffice. I'm not sure why your game would continue to "update input" while a message box is present, these usually steal the input focus (unless your game is one where you could have lots of dialogue boxes open, something not unlike Transport Tycoon).

I'll describe a system present in my game, as it shows how I have interfaces that appear to "block" for input but allow other processing elsewhere.

The system my game uses a state stack. When the program starts, it pushes a background state onto the stack (the game is Asteroids, the background state is just a game of asteroids without a player object). It pushes a menu on top of that. Each state takes a reference (boost::shared_ptr) to the background to update and render it. However, only the current state reacts to input. When the new game option is chosen, the background and menu are removed and a new game is placed on the stack. The game ends and the old game instance (which now lacks a player object) becomes the "background", and a new menu instance is pushed.

Were I to implement a message box, the "current game" instance could be the background for that object. This allows rendering "beneath" the message box to continue while "waiting" for input.

This solution is obviously vastly more complex, and may be difficult to implement (depending on where you want to call ShowChoiceBox, as you'll need a reference to the state stack to push it onto). If you could explain in more detail what kind of input needs handling we might come up with another (possibly easier) alternative.
Ok, I have a little more time to explain stuff now.

Input needs to be updated so that messages are still delegated to the message box.

And the rendering part is one of my problems. At the moment, I'm just having the message box's message loop call the application's last state's frame function.

I have pretty much the same setup as you; I have a stack based state system and input is only used on the top state.

The choice box will be displayed via script. What I'm looking for is a way to have a choice box system without having to have a ton of handling just to use it. And I also don't want to need a callback function or something to check the result. So, what I'm looking for is pretty much a way to show the choice box and get the result in the same line.

I guess a different way to handle it would be using in-script handlers ala:
function OnActivate()    ChoiceBox(Width, CenterText, "Would you like to quit?", "Yes", "OnYes", "No", "OnNo");endfunction OnYes()    StopEngine();endfunction OnNo()    -- continue gameplayend


The only reason I've really been using this exact system is because it works in-script without having to implement co-routines (at the moment this is the only thing I need co-routines for.)
Why don't you make the MessageBox its own state. Whenever invoked push it on the game stack, thus making it the only object looking for input. Once you get the input you need, pop the state.
Quote:Original post by newera
Why don't you make the MessageBox its own state. Whenever invoked push it on the game stack, thus making it the only object looking for input. Once you get the input you need, pop the state.


I could do that, but it'd be the same as if I was just showing it like a normal dialog and it doesn't give me the desired results.
Coroutine support is the most user-friendly way to implement that kind of functionality into a scripting language.
"Walk not the trodden path, for it has borne it's burden." -John, Flying Monk
Quote:Original post by Extrarius
Coroutine support is the most user-friendly way to implement that kind of functionality into a scripting language.


I know, that's just my main reason for keeping this exact solution. I also want to use this setup for in-game editors and other dx based tools.
But there's your problem.

Coroutines don't support yielding while the lua code is calling into C code again.

You really have to let the script set some gamestate variables and call yield. On every frame you call resume on your coroutine and pass in any changed states of the message box. Once that happened the script can continue on its merry way.

You can mask that yield loop in a script function but you won't be able to have a Message Box style function call from C code.

Fruny: Ftagn! Ia! Ia! std::time_put_byname! Mglui naflftagn std::codecvt eY'ha-nthlei!,char,mbstate_t>

This topic is closed to new replies.

Advertisement