LavishScript is an iterative, single-entry language (as opposed to event-based). This means that script functions cannot be executed from outside of a script, and that scripts are designed such that all commands are executed in a very specific order. Execution of commands that were not a part of the original script must therefore be done at a designated point in the script, via a command queue.
The LavishScript Engine allowing multiple scripts to run at once adds the additional problem of context switching. A context switch occurs when the engine determines that a script's execution time is up for a given frame, and allows the next script to perform its duties. Between this and "wait" commands, no two consecutive lines of a script are guaranteed to execute in the same frame. This means that scripts and script functions can only be executed under the assumption that they will require multiple frames to complete.
Enter the Atom
An atom in LavishScript is a complete function that is guaranteed to execute to completion immediately. This makes them atomic, meaning they are not broken down, whereas a function is not atomic and is broken down. Commands that could be completed on a successive frame (such as wait, waitframe, and so on) are not allowed within an atom, and no context switching will occur during atom execution. An atom is not required to be associated with a script, but may be.
Because atoms are effectively synchronous, they can fill many gaps:
- Callback functions
- Custom commands can be created without an extension or module
- Embedded scripts (LavishGUI)
- Function hooks implemented completely within scripts (Inner Space)
- Method definitions for script-defined object types
- Smarter hotkeys or key "binds" (Inner Space)
- Synchronous Text "Triggers"
Proper Usage of Atoms
Atoms are good for certain purposes, including those listed in the previous section, but bad for others. For example, a script may need to loop through a list that contains hundreds of items. With a non-atomic function, this operation can take several frames to execute. With an atom, this operation is guaranteed to execute in the same frame, and any performance hits are taken immediately, rather than spread over several frames. In certain situations, this is preferable, but in many cases this is simply unacceptable.
Atoms can be executed via the ExecuteAtom command, by using the atom as a command, through lavishscript:ExecuteAtom or script:ExecuteAtom. Atoms can only be used within scope -- atoms defined within a script without the global keyword, for example, can only be used within the context of that script.
For example, a global atom may be defined with the name Foo, and two integer parameters named Bar and FooBar. This atom may be executed like so:
ExecuteAtom Foo 1 2 Foo 1 2 LavishScript:ExecuteAtom[Foo,1,2]
Atoms can be removed via DeleteAtom.