• Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.

[General] Generic "Wait" -- no thrills or overhead

Status
Not open for further replies.
Level 15
Joined
Aug 7, 2013
Messages
1,338
Hi,

I would like to know how to make a generic wait function that does exactly what it should do--waits X seconds before moving onto the next line / part of a function.

It has to be portable and bug free, and high level--I do not need to know its internals one bit.

JASS:
function wait takes real seconds returns nothing
…
endfunction

function foo takes nothing returns nothing
  call DisplayTimedTextToPlayer(…, "Showing 'hello world' in three seconds")
  call wait(3.0)
  call DisplayTimedTextToPlayer(…, "hello world")
endfunction
 
Level 12
Joined
Mar 13, 2012
Messages
1,121
To do this in a simple way you would have to halt and continue a function which is impossible to my knowledge.

Use a timer and a new function and save local values to a hashtable if required.
 
Level 19
Joined
Aug 8, 2007
Messages
2,765
To do this in a simple way you would have to halt and continue a function which is impossible to my knowledge.

Use a timer and a new function and save local values to a hashtable if required.

pretty much. JASS offers no such option.

you have

JASS:
native TriggerSleepAction takes real duration returns nothing

but

  • it will crash if its a conditional thread
  • the total amount of time waited is actually duration + ping * 2
  • most event responses are cleared
 
Level 15
Joined
Aug 7, 2013
Messages
1,338
Is there no way to do a busy wait, e.g. have JASS perform some useless action which happens to take that number of seconds, e.g., how many loop iterations in JASS is equal to a single second?

JASS:
loop
  exitwhen i = 1000000
  set i = i + 1
endloop
//how much time did that take?
set i = 0
loop
  exit when i = 10000
  set i = i + 1
endloop
//this second loop should finish much quicker (hopefully 10x faster?)

Any benchmarks on this stuff?

it will crash if its a conditional thread
the total amount of time waited is actually duration + ping * 2
most event responses are cleared

What do you mean in your last bullet: most event responses are cleared?

So this would crash?

JASS:
function A …
…
call TriggerSleepAction(3.0) //thread crashes here
…
endfunction

funcition condition takes nothing returns boolean
…
call A()
…
return false
endfunction
 
Level 12
Joined
Feb 22, 2010
Messages
1,115
Is there no way to do a busy wait, e.g. have JASS perform some useless action which happens to take that number of seconds, e.g., how many loop iterations in JASS is equal to a single second?

This will freeze game completely, but sure you will get your wait time.
 
Level 15
Joined
Aug 7, 2013
Messages
1,338
What do you mean it will freeze the game completely? Will it crash the thread if I do a hundred thousand loop iterations? Or will it also stop all other code until that loop is finished?
 
Level 12
Joined
Feb 22, 2010
Messages
1,115
What do you mean it will freeze the game completely? Will it crash the thread if I do a hundred thousand loop iterations? Or will it also stop all other code until that loop is finished?

It will also stop all other things yes.
 
Level 15
Joined
Aug 7, 2013
Messages
1,338
Alright I guess I give up then on a high level wait.

So how would I do this with a timer? Suppose I have an event that fires off every time a player presses the ESC key. I need to do a wait somewhere in that condition.
 
Level 19
Joined
Aug 8, 2007
Messages
2,765
Alright I guess I give up then on a high level wait.

So how would I do this with a timer? Suppose I have an event that fires off every time a player presses the ESC key. I need to do a wait somewhere in that condition.

JASS:
library WaitOnEsc initializer init requires Table
     globals
          private Table triggerUnit
     endglobals

     private function afterWait takes nothing returns nothing
          call KillUnit(triggerUnit.unit[GetHandleId(GetExpiredTimer())])
          call triggerUnit.remove(GetHandleId(GetExpiredTimer()))
          call DestroyTimer(GetExpiredTimer())
     endfunction

     private function onEsc takes nothing returns boolean
         local timer t = CreateTimer()
         set triggerUnit.unit[GetHandleId(t)] = GetTriggerUnit()
         call TimerStart(t, 5.00, false, function afterWait)
         set t = null
     endfunction

     private function init takes nothing returns nothing
         local trigger t = CreateTrigger()
         call TriggerAddCondition(t, Filter(function onEsc))
         //add "esc" function to t"
         set t = null
         set triggerUnit = Table.create()
     endfunction
endlibrary

did that in text editor. few things

1) GetExpiredTimer should be cached
2) if you do this alot, you should use a TimerAttach system


oh thats kinda cool. decieves the user like crazy though
 
Level 12
Joined
May 20, 2009
Messages
822
Use a Boolean as the condition for everything before the wait. If the Boolean is set to false, then run everything before the wait. If it's set to true, then nothing before the wait should fire.

Use a periodic event, every .03 seconds. Have another variable that every time the trigger runs, it does +1 to that variable. When the variable reaches ~297, it has been three seconds.

So, everything after the wait will just have a condition "If Variable == 297 then"

Here is a GUI example -

  • Untitled Trigger 006
    • Events
      • Time - Every 0.03 seconds of game time
    • Conditions
    • Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • Boolean to False
        • Then - Actions
          • Actions...
          • Set Boolean = True
        • Else - Actions
      • Set Timer = (Timer + 1)
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • Timer Equal to 297
        • Then - Actions
          • Actions...
          • Set Timer = 0
          • Set Boolean = False
        • Else - Actions
EDIT: I'm pretty sure this still has inaccuracies but it's suppose to work MUCH better then a normal wait.
 
Last edited:
Status
Not open for further replies.
Top