Ix Dev 8 - Effects 2 - Conditions
Conditions
Conditions make effects... conditional.
Conditions can have sourceConditions and targetConditions, each an array of SimpleIxCondition. These lightweight types are part of the core ix-script library, and share logic for checking conditions, ensuring compatibility between the lighter (and faster-to-parse/run) condition subset and the full scripting language.
They use simple type-value pairs SerializedValueSource to store the left and right side of the operation. These support most ValueSource types, including primitives, arrays, objects, and $var variables.
Variables are passed in as a simple PartialRecord<string, ValueSourceRawValue>, and referred to in the condition by their $prefixed form. Objects and arrays can be indexed with dot-form, supporting strings and numbers as indexers.
Loading syntax highlighter...
Conditions support simple variable interpolation, including indexed expressions - eg $person.name ~~ "bo" will check that the provided condition
Evaluating
The overall flow of the function:
Loading syntax highlighter...
Most operations use a single "compare" function that returns the equivalent of left - right for various types - 0 if the two are equal, negative if the left is "less than" the right, and positive similarly.
The remaining logic is in resolving concrete values from the serialized valuesources. Most raw values (primitives, arrays, objects) can be returned directly from the tuple's second element.
Variables are returned from the passed-in variables object using an exact name match - $bo is fetched from {'$bo': 123}.
Indexed expressions are serialized to a nested form; the value is an array with the first element being the root serialized value source, and the remaining chained indexers. We then run a simple loop over the indexers, updating the current object with the result of indexing and returning undefined if a value is missing along the way.
Loading syntax highlighter...
Scripted Conditions
Conditions can be constructed by hand or with helpers, but this tends to be fairly wordy - much preferable to use a more natural construct like $val > 5 than a JSON blob. However, running a full script eval (even if fast) for every condition felt wasteful, as it involved creating a new script context and evaluating a lot of unused values.
I instead reused IxScript's language and parsing to allow compiling simple expressions from IxScript to JSON. A specialized parseSimpleCondition:
- runs a standard IxScript parse via
parseScript(and checks for errors) - tries to extract a full
IxConditionnode from the first/only statement - converts the
IxCondtionto aSimpleIxCondition, including converting the fullIxValueSourceinstances to lightweightSerializedValueSourceobjects
Loading syntax highlighter...
This saves a good deal of typing, reads more naturally, and can still be validated/compiled ahead of time to provide an OK developer experience. It's easy enough to extend to support more simple expressions, and down the road can be seamlessly upgraded to support full IxScript scripts for conditions - templates can specify a string, and on load it can try to parse a simple condition, falling back to a full script (or an error).