Query API

Managing your UI data using identities

One of the main philosophies behind uiink's design is that you should be able to integrate your UI into your codebase however best suits you, be that an immediate mode design or your own system built on top the basic data API. One of the built-in methods you can use to manage data in uiink is the Query API.

A common way of managing UI state often looks something like this:

You maintain a data structure and function that maps between application data and the UI's representation of said data. There is nothing wrong with the approach, many times it's even preferable.

The query API is another option to give you flexibility in how you structure you application. It's a convenient way, for example, to decouple GUI code from your application.

For a query, uiink finds the first data object where each query field matches. If no matching data entry is found in the list ("entities" in our example) a new data entry is created. New data entries will automatically have their fields set to their respective queried values. In our example we're only matching against a single field, but you can match against as many as you like.

You could take this one step further in certain situations and skip application data structures altogether. When your code needs data it can use a query and read fields from the uiink data object directly. Although I don't recommend using this method for large datasets that needs to be processed frequently by code.

A list of "entries" is is provided by the source node. The find node searches through each item in the list to find an entry with a matching name. The "description" output on the find node is a field on the matching list entry.

Quill has an equivalent of the query API in the Find Node. This can be very handy for decoupling your UI's structure from code.

The most convenient way for your UI to structure data might significantly differ from how your code is organized. The find node lets the UI conveniently pull pieces of information from anywhere in the data hierarchy based off an identity (or "key" if you prefer.) This allows code to work with data in simple, flat lists. It doesn't need to worry about how the UI might want to nest pieces of information.

Query with rebuild

Queries work well in combination with the Rebuild API. Any data objects not queried during a rebuild will be automatically removed. This is effectivly an immediate mode API for your GUI.

On the surface rebuild works the same way as when using the basic data API: just calling Data.append for each entity. However, rebuilding the list using the basic data API gives the runtime no information about the identity of each item. This means the runtime can't know if a list entry is new or just rebuilding an existing item, which is problematic if the UI is set to run animations when items are added or removed. Using a query solves this issue by associating an identity with each list item based on the match qualifiers.