Accessing Resources
Disguise uses a concept called Resources to represent everything from a Layer to a Feed Rectangle in Designer. It is often useful to reference fields on various Resources within the system inside expressions.
Once a specific Resource has been identified, it can be referenced in order to access fields (and sub-fields) of that Resource, allowing the user to access almost all aspects of the designer system.
It should be noted that not all fields are documented, nor can they be definitely relied upon to continue to use the same name over versions of the software. This is because expressions expose a raw access to the internal data model used in designer, and it is possible that new features and improvements change the name of fields. It is rare that a feature is totally lost, and this document provides some guidelines on how a user can find the fields they require.
Once a value has been accessed from one or more Resources, then the values can be combined or modified futher using the functions and operators of the expression system. The text which makes up the reference to the Resource can be treated as any other variable held by the expression system.
In summary, the general flow of accessing other part of Designer using expressions goes as follows:
- Identify a piece of information in the designer user interface.
- Create a connection to an expression field by using Alt + Left mouse drag from the element in the user interface.
- Understand the reference expression that Designer builds.
- Continue to add other expressions referencing other data needed to build the desired result.
- Edit the expression to build the desired value from the various expressions noted earlier in the process.
Creating a connection using mouse drag
Often simply linking a value from another part of the user interface is enough for the expression writer to accomplish their goal.
There is a shortcut to build the expression using the user interface, accessed by holding the alt key and left-dragging the mouse from the field of interest to the field which can accept expressions.
Identifying Resources
In order for the expression to use whichever Resource the user wishes to, we first need to identify the Resource in question. There are two methods for doing this:
- By type and name
- By UID
Accessing Resources by name
The simplest and most readable method for building a reference to a known Resource in the system is to use the type:name
syntax to refer to a Resource.
This is the technique used by Designer when the user asks it to write an expression for them by holding Alt and dragging the mouse from a field of interest to the expression. This is the recommended method used to learn the names of Resources and the general naming convention for fields of interest to the user.
For example, to refererence a Projector, the expression projector:projector_1
is used to refer to the Projector itself.
Accessing Resources by UID
UID stands for Unique IDentifier. The identifier is unique across the project and does not change when renaming the Resource. It is also used when the Resource is “unnamed” - this is when the Resource is embedded within another, larger Resource.
One use case for this technique is to have a persistent method for creating a reference to a Layer, even if that Layer were to be renamed. Note this will not follow any duplication or copying of Resources referenced this way.
In order to build a reference in this way, the user must follow the steps outlined here:
- Open the editor for the Resource in question (e.g. click on a Layer.)
- Right-click on the titlebar of the editor window which pops up.
- Click “Copy UID” in the menu which appears.
- Create an expression using the following function call:
getByUID(<paste the copied number here>)
The end result is an expression which looks like getByUID(0x123875234)
- this is an immutable reference to the Resource the editor was opened, and will only fail if the Resource in question is deleted.
Using this technique, it is useful to store these difficult to read expression in a function-type variable, instead of using them directly. The user can create an expression variables device or layer to hold the difficult to read getByUID(...)
text. This allows easier named references to the Resource in the users other expressions. This is especially useful if the user wishes to refer to the same Resource in multiple locations.
Accessing Resource fields
Once the user has found the Resource they wish to reference for data, then accessing fields is accomplished by using the .
operator. This operator acesses a named field on a Resource or most other objects in the system.
For example, all Resources have a description
field, which is sometimes useful to validate that the user has accessed the Resource they intended to. In that case, the user would type the expression projector:projector_1.description
- this produces a text result which contains the real name of the Resource (without the _
character decoration.) i.e. “projector 1”.
Common Resource fields include:
offset
- the position of an object in the stage, relative to its parent. Further specify the x, y or z coordinates by using the.
operator again e.g.projector:projector_1.offset.x
rotation
- the rotation of an object in the stage, relative to its parent. Available as individual euler angles e.g.projector.projector_1.rotation.y
Many other fields exist on Resources in the system, and while no guarantee can be given to their long-term stability, the data provided is exactly what designer uses internally, so there can be no doubt as to its accuracy.
Accessing fields set to None
In some cases, it is possible to access fields which are set to None in the user interface. This means that there is no object to find in that field. Attempting to access properties when there is no object will fail and the expression will not evaluate. It is recommended to ensure this does not occur.
It is possible to test if an object is valid by using an if
, for example if(transportmanager:default.timecode, "has timecode", "no timecode")
but there is no method to conditionally access fields - i.e. the expression if(transportmanager:default.timecode, transportmanager.default.timecode.description, "no timecode")
would fail.