Home AMX User Forum NetLinx Studio

WAIT 0

While writing a function that called a WAIT with a variable for the time it occurred to me I didn't know what would happen if that time was 0. I hypothesized that it would evaluate to "don't wait and run the code now" but it does in fact get placed on the WAIT list. Since it has a timeout of 0 it always runs immediately following the event that called it.

Here's a hastily written and untested example using it to insert a line between each event's diagnostic text:
DEFINE_DEVICE
   dvTP        = 10001:1:0;
   vdvTest     = 33001:1:0;


DEFINE_FUNCTION Debug(CHAR sText[])
{
   SEND_STRING 0, "sText";

   WAIT 0 'DEBUG_BREAK'
   {
      SEND_STRING 0, "'----------------'";
   }
}

DEFINE_EVENT
BUTTON_EVENT[dvTP, 1]
{
   RELEASE:
   {
      ON[vdvTest, 1];
      ON[vdvTest, 2];
   }
}

CHANNEL_EVENT[vdvTest, 0]
{
   ON:
   {
      Debug("'Channel ',ITOA (CHANNEL.CHANNEL)");
      Debug("'Another line'");
   }
}
Diagnostics:
01: Channel 1
02: Another line
03: ----------------
04: Channel 2
05: Another line
06: ----------------

Comments

  • mpullinmpullin Posts: 949
    Cool. Thanks for posting.
  • tomktomk Posts: 24
    This is occasionally also useful as a "yield" operation.

    For example if you want to set a channel high on a virtual device (and cause something to happen) before you go and run some long function you're out of luck. The long-running function has to complete before the event handler ends. Then your vd event handler can go ahead and do its thing.

    So a short wait does the trick here too:
    EVENT HANDLER {
    PUSH: {
      ON[vd, 123];
      WAIT 1 {
        SomeFunctionThatTakesAges();
      }
    }
    }
    
  • a_riot42a_riot42 Posts: 1,624
    Have you tried WAIT -1? This comes in handy when you need to run some code in the recent past.
    Paul
  • PhreaKPhreaK Posts: 966
    Hahaha.

    Unfortunately though, from the NetLinx help file:
    The NetLinx interpreter accepts any type of number (including Floats and Doubles) for WAIT times but it casts them to an unsigned 32-bit number, i.e. a long.

    So it may actually loop round and run in ~1.3 years. Wouldn't that be a fun bug to diagnose.
  • mushmush Posts: 287
    When I Axcess my old memory I seem to recall that WAIT 0 is equivalent to 1 pass of MainLine.
    Don't know what that means if the wait is in an event?
  • ericmedleyericmedley Posts: 4,177
    a_riot42 wrote: »
    Have you tried WAIT -1? This comes in handy when you need to run some code in the recent past.
    Paul
    I used it to stop global warming.
    wait -45000{
      set_outdoor_temperature(current_temp*0.85)
      }
    

    You're welcome.
  • ericmedley wrote: »
    I used it to stop global warming.
    wait -45000{
      set_outdoor_temperature(current_temp*0.85)
      }
    

    You're welcome.

    Don't forget....
    wait -45000{
      set_outdoor_tempature(current_temp*0.85)
      }
    

    // How do you spell temperature???
    DEFINE_LIBRARY_FUNCTION SET_OUTDOOR_TEMPATURE(CONSTANT LONG A) = $F06
  • DHawthorneDHawthorne Posts: 4,584
    mush wrote: »
    When I Axcess my old memory I seem to recall that WAIT 0 is equivalent to 1 pass of MainLine.
    Don't know what that means if the wait is in an event?

    That's correct. WAITs jsut pass their code block into a holding area which is checked every pass of mainline. When the timer has expired for a particular WAIT, that pass of mainline will execute the code. Since WAIT 0 is essentially expired immediately, the very next pass of mainline fires it.

    Putting a WAIT in an event does the same thing. WHen the event fires, the WAIT goes into holding until it's timer expires. That's why you can't use STACK variables in a WAIT inside and event; the variable is meaningless outside the event, and the WAIT does all it's actual functioning in mainline, not in the event itself.
  • DHawthorne wrote: »
    mush wrote: »
    When I Axcess my old memory I seem to recall that WAIT 0 is equivalent to 1 pass of MainLine.
    Don't know what that means if the wait is in an event?
    That's correct. WAITs jsut pass their code block into a holding area which is checked every pass of mainline. When the timer has expired for a particular WAIT, that pass of mainline will execute the code. Since WAIT 0 is essentially expired immediately, the very next pass of mainline fires it.

    Putting a WAIT in an event does the same thing. WHen the event fires, the WAIT goes into holding until it's timer expires. That's why you can't use STACK variables in a WAIT inside and event; the variable is meaningless outside the event, and the WAIT does all it's actual functioning in mainline, not in the event itself.

    Just to be clear, the WAIT list (including any other timed event) is checked between each event in the queue, as well as each time mainline runs.

    FIG. 1 Message and Mainline Processing in the NetLinx System [size=-2](page 2 of the NetLinx Language Reference Guide)[/size]

    So, referring to my example at the top, if I also added this:
    DEFINE_PROGRAM
          Debug("'Mainline'");
          Debug("'Another line'");
    

    my output (which I just realized was not correct in the first example) would be something like:
    01: Channel 1
    02: Another line
    03: ----------------
    04: Channel 2
    05: Another line
    06: ----------------
    07: Mainline
    08: Another line
    09: ----------------
    
  • All Handlers First!

    While refining/testing logging using this feature, I discovered something interesting. My WAIT 0 new line wasn't occurring after each event handler like I assumed from that graphic above, but after every handler for each event.

    I had multiple UI modules for one COMM and I expected to see this:
    01: Module 1: Channel 1
    02: Another line
    03: ----------------
    04: Module 2: Channel 1
    05: Another line
    06: ----------------
    07: Module 1: Channel 2
    08: Another line
    09: ----------------
    10: Module 2: Channel 2
    11: Another line
    12: ----------------
    

    But instead got this:
    01: Module 1: Channel 1
    02: Another line
    03: Module 2: Channel 1
    04: Another line
    05: ----------------
    06: ----------------
    07: Module 1: Channel 2
    08: Another line
    09: Module 2: Channel 2
    10: Another line
    11: ----------------
    12: ----------------
    

    So when an event fires, NetLinx runs ALL handlers for that specific event and then checks the waiting list, running any waits that may have expired while running each of those events. Knowing that isn't a game changer, but it could help explain any odd "synchronization" issues between modules.
  • mushmush Posts: 287

    So when an event fires, NetLinx runs ALL handlers for that specific event and then checks the waiting list, running any waits that may have expired while running each of those events. Knowing that isn't a game changer, but it could help explain any odd "synchronization" issues between modules.

    Interesting, thanks for the info.
Sign In or Register to comment.