Sign in to follow this  
Programmer16

MessageBox style function

Recommended Posts

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?

Share this post


Link to post
Share on other sites
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...

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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");
end

function OnYes()
StopEngine();
end

function OnNo()
-- continue gameplay
end



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.)

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
Quote:
Original post by Endurion
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.


Lol, one of us is misunderstanding the other (I'm not sure if its you me, or me you.) Forgetting the script part all together, I want to have a C++ function that works exactly like MessageBox (displays a message, handles messages, and returns the choice with a single function call.)

I guess the best solution would be to redesign my system to incorporate a more message based system, but I've restarted enough, it's time to finish a project.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this