GUI Scripting: Evaluating Expressions & Variables
This page is part of a series. See GUI Scripting Language for overview.
Overview of Unusual Rules
This page is based largely on stgatilov's analysis.
The GUI scripting language differs from most scripting languages, regarding when expressions are evaluated and how values of properties and user variables can change. These rules affect:
- Property Auto-Updating and its Deactivation
- Early Evaluation of Expressions within Event Handlers
These rules greatly impact how program control logic in GUI scripts, like if statements, can be written.
Property Auto-Updating and its Deactivation
Consider the case where you declare a register property, initialized on the right-side with an expression that is potentially non-constant, because it could be updated externally by a .script. The "expression" might just be a single GUI:: parameter, which might be thought of as "bound". Two simple examples:
visible "gui::myvar" visible 1 – "gui::myvar"
Normally, at runtime, when the non-constant value changes, the property is reevaluated automatically. However, this auto-updating of a property may be deactivated (or disabled or unbound; pick your favorite term) during runtime in some circumstances:
- In TDM 2.11+, if the property is assigned an explicit value with a "set" or "transition" command.
- In Doom 3 and TDM before 2.11, similar, but perhaps too inconsistent and "weird" to be easily explained.
Clearly, deactivation can cause you trouble if you are unaware of it. You may run into this if you try to use a single GUI:: Parameter to communicate bi-directionally between .gui and .script. Better to use two separate parameters. In other situations, introducing a user variable may help.
It is likely (but could benefit from confirmation) that this deactivation description applies also to an expression using a GUI:: parameter whose external updates come from C++ code, instead of .script
Early Evaluation of Expressions within Event Handlers
In typical computer languages, expressions are evaluated sequentially as they are encountered. This is not the case with our GUI scripting inside an event block! When an event handler is about to execute, all the expressions within it are in effect evaluated beforehand and remembered. By "expressions" here we include simple user variables, register properties, and gui parameters, and any math expressions that use them. Such expressions occur in:
- If conditions
- In TDM 2.11+, the "right-hand" side of "set" commands, wrapped in parentheses.
Considering an "if" example, let's say your event handler body includes this code:
set "gui::myvar" 1; // from original value of 0 if("gui::myvar") { ... // We won't get here, because if-condition still evaluates to 0 (false) }
It is only after the event handler completes that the new value of gui::myvar takes effect.
So, while you can write sequential ifs and nested ifs within an event block, early evaluation will often limit their usefulness. See also: Just-Changed Value Not Immediately Known to "If" Expression.