Non-Blocking Wait() Command

Started by greg, Tue 01/07/2008 14:49:40

Previous topic - Next topic

greg

Can a function wait in a way that doesn't prevent other functions from running?  Here's what I'm trying to do.

Code: ags

// show icons, allow the player to choose one, and return the choice
function ReturnIconChoice() {
  // Display a list of icon buttons.
  // When the player selects a button, the button's script stores the button ID in global integer CHOICE.
  // The GUI is normal (as opposed to pop-up modal), so that the ambient actions (animations, sounds, etc) continue even when the GUI is showing.
  ShowIconsGUI();

  // wait for the player to make a selection
  while (GetGlobalInt(CHOICE) != NO_CHOICE_MADE) Wait(5);

  // return the selection
  return GetGlobalInt(CHOICE);
}


This hangs at present because Wait() doesn't allow any scripts to run in the background.  I'm looking for a way of putting ReturnIconChoice() to sleep for a couple cycles so that the player can make a selection from the GUI and then we can continue executing ReturnIconChoice().  Is this possible?  If not, are there any suggested workarounds?

Thanks!
Greg

Khris

#1
1. At the beginning of on_mouse_click(), put
Code: ags
  if (IconsGUI.Visible) return;

This will catch clicks outside the GUI while it's displayed.

2. In each of the buttons' OnClick event, enter ChoiceClick, then add this to the global script:
Code: ags
function ChoiceClick(GUIControl*c, MouseButton b) {
  if (b == eMouseLeft) {
    IconsGUI.Visible = false;
    SetGlobalInt(CHOICE, c.ID + 1);
  }
}


3. Inside rep_ex, check if GetGlobalInt(CHOICE) isn't 0, then react.

greg

Thanks for your help!

So this works around the problem by using one of the built-in daemon scripts (repeatedly_execute).  I assume that, aside from some of its built-in functions, AGS doesn't support non-blocking scripts?  (Namely, I can't put a function to sleep for a couple cycles and then come back to it?)

Khris

No, object-oriented programming doesn't allow this.

There's another way, though:

Code: ags
  int emw = mouse.GetModeGraphic(eModeWait);
  Mouse.ChangeModeGraphic(eModeWait, mouse.GetModeGraphic(eModePointer));
  SetGlobalInt(CHOICE, NO_CHOICE_MADE);
  while (GetGlobalInt(CHOICE) == NO_CHOICE_MADE) {
    while(!mouse.IsButtonDown(eMouseLeft)) {
      mouse.Update();
      Wait(1);
    }
    GUIControl*gc = GUIControl.GetAtScreenXY(mouse.x, mouse.y);
    if (gc != null) SetGlobalInt(CHOICE, gc.ID+1);
  }
  Mouse.ChangeModeGraphic(eModeWait, emw);


(Btw, I've noticed that your while loop checked for the GlobalInt not being equal to NO_CHOICE_MADE.)

SMF spam blocked by CleanTalk