While

From GECK
Jump to: navigation, search


A function added by the New Vegas Script Extender.

Description

Whilst a specified condition is met, the code section below, until the loop command, will repeat. Within while loops, the command continue may be used to skip remaining loop code and return to the while line. In the same context, the command break may be used to end the loop immediately, regardless of the while condition.

The same effect could be achieved using label, goto, if and endif statements, but this method allows for fewer lines and improved readability. Care must be taken to avoid the possibility of infinite loops- a while condition that never becomes false will immediately crash the game.

Syntax

[help]
while Condition:expression 

Examples

while SomeCondition  ; * this is similar to an 'if' statement
    ; do something
loop ; * this is similar to an 'endif' statement

The code below will print the numbers 1, 2, 3, 4 and 5 to the console:

int iCount
let iCount := 0      ; * 'set iCount to 0...'

while iCount < 5     ; * 'if iCount is less than 5...'
    let iCount += 1  ; * 'add 1 to iCount...'
    Print $iCount    ; * 'then print it to the console...'
loop                 ; * 'then go back to the while line.'

The code below will print the numbers 1 and 3 to the console. The number 2 is skipped due to the continue, whilst numbers 4 and 5 are skipped because of the break.

set iCount to 0
while iCount < 5
    let iCount += 1
    if iCount == 2
        continue ; go back to the loop start
    elseif iCount == 4
        break ; end the loop immediately
    endif
    Print $iCount
loop

While allows NVSE expressions, including assignments, in the expression that follows it, so a shorter alternative for the example above is:

set iCount to 0
while 5 > (iCount += 1)
   if iCount == 2
     continue
   elseif iCount == 4
     break
   endif
   Print $iCount
loop

NOTE: for `while myNumber > (iCount += 1)`, if this while loop is checked repeatedly (i.e. is placed in a `begin GameMode block`, iCount will keep increasing even after the loop is done, unless it's reset like in the example. If left unattended, this could lead to the iCount variable store a really high numbers. However, this does not cause savebloat, as internally it will use the same amount of space.

While is often used to loop through a regular array, formlist or string var - all types of data that use consecutive integer indices starting at 0 and ending at (total size - 1). The most efficient forwards loop for those is written like

let iSize := ar_size aArray  ; use ListGetCount for formlists, and sv_length for string vars
let iKey := -1
while iSize > (iKey += 1)
  ; do stuff with the value held at aArray[iKey]
loop

However, all those data types also automatically shift their indices when an element is erased, so erasing an element during a forwards loop will not only skip the next element if you perform it on the element being currently iterated, but will also end up with errors as the iSize variable will be no longer up to date.

You can avoid that by using a backwards loop, since any shifting of the indices will not affect the next elements that will be iterated:

let iKey := ar_size aArray
while -1 < (iKey -= 1)
  if somecondition
    ar_erase aArray, iKey
  endif
loop

See Also

External Links