1
\$\begingroup\$

Right now I'm implementing my modal dialogs in windows with a separate message loop after popping up the dialog.

This straightforward an approach won't work with other systems that don't have message loops.

Obviously if I'd designed from scratch assuming one message loop I wouldn't have this problem.

In Unity3D (C#) I believe I could use a coroutine for this.

Aside from manually unrolling the code after the message loop so I can put it into a separate state or lambda to be called on close of the dialog, does anyone have any brilliant ideas on ways to make the code work with only one message loop?

I've tried googling but nothing obvious comes up.

EDIT: I know how to write modal dialogs from scratch, the question is whether there's a simpler way to update older code to remove the message loops.

Let me see if I can write a better example of the pseudcode. This is the best I've come up with.

//DoAlert has a while doAlert is up processmessage loop in it
int i = doAlert("title", "Choice1", Choice2", "Choice3")
switch (i) { 
  Case 1 : do something; 
}

do something else and return to the routine that called you which does something else before returning, etc.

would become

auto alert = doAlert("title", "Choice1", Choice2", "Choice3");
alert.addChoice(1, [](){ do something; });
alert.addChoice(2, [](){ do something; });
alert.addPostProcess([](){});
... return from routine
alert.addPostProcess([](){});
... when finally at message pump...
alert.process();

...

Clumsy but at least it's simple to read and understand.

If I were writing from scratch, I would not have written it this way for new code.

I'd rather not decipher all these in order to get rid of the multiple message loops. The only way seems to be to trace what happens when the message loop exits, and put that into a lambda or possibly put the whole mess into a state machine. The lambda seems to be the simplest but it still means tracing through all of them and creating a stack of onexit routines from doAlert.

Thanks, Ralph

\$\endgroup\$
  • 1
    \$\begingroup\$ alternatively, tiny file dialogs on sourceforge has several native modal function calls. it's a simple C C++ cross-platform file to add to your project. \$\endgroup\$ – tinyfiledialogs Jun 29 '16 at 6:24
1
\$\begingroup\$

Just have one message loop with a state or stack of modal dialogs that override your usual control flow:

handle message():
  if is input message:
    if has modal dialog:
      handle modal input message
    else:
      handle main input message

If you have a window stack, this might be made a bit simple:

handle message():
  get top of window stack
  dispatch message to window

When you open a modal dialog, just add it to the GUI/Window manager. Now the system that processes input knows where the input goes.

If you're using polling input systems somewhere, also add a flag or check in those, e.g.

is button down():
  if has modal dialog:
    return false
  else:
    return is_down[button]

That will make it so any polling systems like gameplay just stop responding to input when the modal dialog pops up. You should probably just pause all those systems when said dialog is up, though:

update game:
  update graphics
  if no modal dialog is open:
    update physics
    update AI
    update other gameplay

that way you won't keep falling or getting attacked or anything while a modal dialog is open.

So far as code organization, you likely either have a WindowManager of some sort that you pass around everywhere or you just use a global/singleton and carry on.

\$\endgroup\$
  • \$\begingroup\$ I'm basically doing that now. \$\endgroup\$ – Ralph Trickey Aug 28 '15 at 12:20
  • \$\begingroup\$ I'm doing something like that now. My main windows loop runs through all the dialogs to give them a chance to process messages. Pushing a modal dialog onto the stack is like this. self->isDirty = false; self->MainControl->DisplaySelf(); Wait(); //Message Loop DisplayActivePanels(); CheckForDisplayIsDirty(); In some cases I need to do stuff after the dialog has closed, it's not always the same stuff, especially my alert (multiple choice) boxes. I can provide a lambda to the push method to be called on exit, but it's not always easy to puzzle out through the layers of calling code. \$\endgroup\$ – Ralph Trickey Aug 28 '15 at 12:32
  • \$\begingroup\$ Sean, That's a good answer and thanks for taking the time to write it. Unfortunately, it's a lot like what I'm doing now. The problem is that I'm using message loops to keep the modal dialogs open, and I'd rather do something besides add Lambdas to process the code that happens after the dialog closes. C# has something to do that while C++ doesn't as far as I know and I was hoping that there would be some elegant solution I couldn't find. \$\endgroup\$ – Ralph Trickey Aug 28 '15 at 12:35
  • \$\begingroup\$ @RalphTrickey: I guess I don't fully understand your problem. Good GUI (and game) programming is going to be pretty heavily event-based, so making things respond to events (via lambdas, derived dialog impl classes, or some other message-handling system) seems super natural to me. \$\endgroup\$ – Sean Middleditch Aug 28 '15 at 15:31
  • \$\begingroup\$ Let me see if I can write a better example of the pseudcode. //DoAlert has a while doAlert is up processmessage loop in it int i = doAlert("title", "Choice1", Choice2", "Choice3") switch (i) { Case 1 : do something; } do something else and return to the routine that called you which does something else before returning, etc. If I were writing from scratch, I would not have written it this way, I'd rather not decipher all these in order to get rid of the multiple message loops, but it seems like the only way I've seen other than a state machine. \$\endgroup\$ – Ralph Trickey Aug 28 '15 at 19:28

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.