• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

Shared variable across functions

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

If I a shared boolean variable as the condition of a while loop and only in another function/trigger can its value get changed, will that while loop receive the update and terminate? Or does it loop forever?

JASS:
set A.bool = true
function foo takes nothing returns nothing
  loop
    exitwhen A.bool == false
    ...
  endloop
endfunction

function bar takes nothing returns nothing
  set A.bool = true
endfunction

...
call foo()
call bar()

Question is, will foo() then terminate, or will it loop forever, even after calling bar()?
 
Level 15
Joined
Aug 7, 2013
Messages
1,337
If foo and bar were asynchronous the loop would terminate, but they're not (and jass is globally not)

This could work if bar was called from a separate virtual thread and your loop contained TriggerSleepAction

Right so basically I would need to put "foo" to sleep and then "wake" it up? So the warcraft scheduler just runs every thread to completion rather than do any context switching in the middle of code. That feature has been most useful (makes everything deterministic) but I'd like the sleeping feature too...Could you give a quick example of how it could be done as you described?
 
Well, you can have a separate function, perhaps timed loops / timer based that will run bar() at some time...

then make foo() run inside a trigger so that it can use TSA...

with that, when bar() is called while foo() is "waiting", then foo() will end on it's next run (after the wait)

you can maybe try something like

JASS:
#This is a trigger condition

function foo takes nothing returns nothing
    loop
        exitwhen a = false
        call TriggerSleepAction(1)
    endloop
endfunction

function seth takes nothing returns boolean
    call TimerStart(CreateTimer(),10.0,function bar())
    call foo()
    return false
endfunction

Take note though, that it isn't really recommended to put a wait inside a loop...
 

Dr Super Good

Spell Reviewer
Level 64
Joined
Jan 18, 2005
Messages
27,201
Yes if the loop uses TriggerSleepAction to suspend the thread between cycles or cycle bunches. No if the loop is immediate since it will either run until op limit before the other thread is run or the other thread is run first and the loop never iterates.

JASS is not a hardware description language. All code is executed sequentially by a single JASS processing unit (no multi-threaded execution) with no pre-emptive schedualling occurring. A thread will run until completion or it hands over control (runs something else) or suspends pending wakeup (TriggerSleepAction, synchronization natives etc).
 

Cokemonkey11

Spell Reviewer
Level 30
Joined
May 9, 2006
Messages
3,537
Right so basically I would need to put "foo" to sleep and then "wake" it up? So the warcraft scheduler just runs every thread to completion rather than do any context switching in the middle of code. That feature has been most useful (makes everything deterministic) but I'd like the sleeping feature too...Could you give a quick example of how it could be done as you described?

Just going to respond as well since the question is worthy of multiple examples.

JASS:
globals
    private boolean done = false
endglobals

private function looper takes nothing returns nothing
    loop
        exitwhen done
        call TriggerSleepAction(0.) //even a wait time of 0. will work, since the minimum wait time is closer to 0.1 anyway.
        // do stuff
    endloop
endfunction

private function after takes nothing returns nothing
    set done = true
    //leaks a timer
endfunction

private function init takes nothing returns nothing //initializer
    call ExecuteFunc(SCOPE_PRIVATE+"looper") //starts a new virtual thread (with wait permissions), similar to a trigger action
    call TimerStart(CreateTimer(),5.,false,function after)
endfunction

There is probably a better way to do whatever it is that you're trying to do, but technically this will work.
 
Status
Not open for further replies.
Top