|
Ultralight C++ API 2.0.0
|
Data-binding API that connects native C++ data to HTML and CSS markup.
#include <Ultralight/dom/data/Context.h>
Data bindings connect native C++ objects directly to page markup. Your HTML and CSS declare where values appear and which elements dispatch actions, while your data and application logic remain in native code.
You update your native objects during your normal update loop and call dom::data::Context::Sync() once per frame. The library reads every bound instance through its schema and sends only the values that changed in a single batch.
A data context binds native instances and synchronizes their fields with an attached View:
The page markup displays those values using placeholder syntax:
Select a type based on the task you need to perform:
| Task | Type |
|---|---|
| Bind instances and sync pages | dom::data::Context |
| Describe a type for markup | dom::data::TypeTraits |
| Handle actions and edits | dom::data::Binding |
| Skip unchanged data during sync | dom::data::Model |
| Support custom value types | dom::data::ValueTraits |
The data-binding types live in <Ultralight/dom/data/Context.h> and aren't included by <Ultralight/DOM.h>. Including this header provides the full data-binding API.
The library provides dd as a namespace alias for ultralight::dom::data. Reference documentation and code examples use this alias for brevity (dd::Context, dd::Binding).
Classes | |
| class | ActionInfo |
| Details of a delivered action (its name and the list row it fired from). More... | |
| struct | ActionToken |
| An action entry (the value Action() returns). More... | |
| struct | AttachOptions |
| Options for Context::AttachTo(). More... | |
| class | Binding |
| A handle that keeps an instance bound to pages and registers its input handlers. More... | |
| class | Context |
| Data-binding context for attached Views. More... | |
| struct | EditableTag |
| Marks a field the page may request changes to. More... | |
| struct | EnumRange |
| The range of values searched for an enum's enumerator names. More... | |
| struct | FieldToken |
| A field entry (the value Field() returns). More... | |
| struct | InternalTag |
| Marks a field or list that pages can't reach. More... | |
| struct | ListToken |
| A list entry (the value List() returns). More... | |
| class | Model |
| Handle passed to a type's static Sync function to control which fields are read during synchronization. More... | |
| struct | OnlyLatestTag |
| Marks an action whose pending emissions collapse into the newest one. More... | |
| class | Snapshot |
| Read-only access to the synchronized values of a described type. More... | |
| struct | TypeTraits |
| Traits template for describing a type to data bindings. More... | |
| class | Value |
| A generic value passed to data-binding formatters and handlers. More... | |
| struct | ValueTraits |
| Conversion rules that expose a C++ type as a primitive value in data bindings. More... | |
| struct | VarToken |
| A CSS custom property entry (the value Var() returns). More... | |
Concepts | |
| concept | Bindable |
| Whether or not T binds as a leaf value (ignoring const, volatile, and references), ie. | |
| concept | BindableHolder |
| Whether or not Context::Bind() can bind an instance through H. | |
| concept | Described |
| Whether or not T has a schema (ignoring const, volatile, and references), ie. | |
| concept | ScalarPayload |
| Whether or not P can be an action's payload without a payload struct (ignoring const, volatile, and references). | |
Enumerations | |
| enum class | DumpAt { NextSync , Now } |
| When Context::DumpSchema() writes its file. More... | |
| enum class | AttachFlags : unsigned { None = 0 } |
| The flags for Context::AttachTo() (the typed form of ULDOMDataContextAttachFlags). More... | |
| enum | EntryFlags : uint8_t { kEntryFlags_Editable = 1 << 0 , kEntryFlags_Internal = 1 << 1 , kEntryFlags_OnlyLatest = 1 << 2 , kEntryFlags_Keyed = 1 << 3 , kEntryFlags_Var = 1 << 4 , kEntryFlags_Nullable = 1 << 5 } |
| Flags on a schema entry. More... | |
| enum class | ValueKind : uint8_t { Bool = 0 , Int64 , Double , String , StyleValue , Color , Object , List , Action } |
| The kinds of value a schema entry holds. More... | |
Functions | |
| template<typename Fn> requires std::is_class_v<Fn> | |
| consteval ValidateWith< Fn > | Validate (Fn fn) |
| Attach a validator to a field (a Field() tag). | |
| template<typename Fn> requires std::is_class_v<Fn> | |
| consteval ValidateEntry< Fn > | Validate (const char *name, Fn fn) |
| Attach a validator to an already-declared field (a Schema() entry). | |
| template<detail::IsAccessor A, typename... Tags> | |
| consteval auto | Field (const char *name, A accessor, Tags... tags) |
| Declare a field. | |
| template<typename Value, typename... Tags> requires (!detail::IsAccessor<Value>) | |
| consteval auto | Field (const char *name, Tags... tags) |
| Declare a field without an accessor. | |
| template<detail::IsAccessor A, typename KeyPtr, typename... Tags> requires std::is_member_object_pointer_v<KeyPtr> | |
| consteval auto | List (const char *name, A accessor, KeyPtr key, Tags... tags) |
| Declare a keyed list. | |
| template<detail::IsAccessor A, typename... Tags> requires (!std::is_member_object_pointer_v<Tags> && ...) | |
| consteval auto | List (const char *name, A accessor, Tags... tags) |
| Declare a list whose rows are matched by position. | |
| template<typename Payload = void, typename... Tags> | |
| consteval ActionToken< Payload > | Action (const char *name, Tags... tags) |
| Declare an action (a request the page sends to your code). | |
| template<detail::IsAccessor A> | |
| consteval auto | Var (const char *name, A accessor) |
| Declare a CSS custom property that follows your data. | |
| template<typename... Entries> | |
| consteval auto | Schema (Entries... entries) |
| Declare a type's schema. | |
| template<typename T> requires std::is_default_constructible_v<T> | |
| T | OrEmpty (Result< T > result) |
| Get a Result's value or a default-constructed T if it holds an error (see dom::OrEmpty()). | |
Variables | |
| constexpr EditableTag | Editable {} |
| constexpr InternalTag | Internal {} |
| constexpr OnlyLatestTag | OnlyLatest {} |
|
strong |
The flags for Context::AttachTo() (the typed form of ULDOMDataContextAttachFlags).
None are defined yet.
| Enumerator | |
|---|---|
| None | No options. |
|
strong |
When Context::DumpSchema() writes its file.
| Enumerator | |
|---|---|
| NextSync | At the end of the next Context::Sync(). |
| Now | Right away. |
| enum EntryFlags : uint8_t |
Flags on a schema entry.
You set Editable on fields, Internal on fields and lists, and OnlyLatest on actions. The library sets Keyed, Var, and Nullable from the entry's declaration. Tools read the flags from the schema JSON (see Context::schema()).
| Enumerator | |
|---|---|
| kEntryFlags_Editable | The page may request changes to this field. |
| kEntryFlags_Internal | Pages can't reach this entry (see dd::Internal). |
| kEntryFlags_OnlyLatest | Only the newest pending action is delivered. |
| kEntryFlags_Keyed | A list whose rows have a key member. |
| kEntryFlags_Var | A CSS custom property (see Var()). |
| kEntryFlags_Nullable | A nested object that may be absent. |
|
strong |
The kinds of value a schema entry holds.
A leaf field (one that holds a value, not a nested object or a list) has one of the first six kinds (see ValueTraits). Object, List, and Action entries hold no value of their own.
| Enumerator | |
|---|---|
| Bool | A boolean. |
| Int64 | A signed 64-bit integer (from any integer type). |
| Double | A double-precision float (from any floating-point type). |
| String | UTF-8 text (from strings and enums). |
| StyleValue | A CSS number with a unit (see dom::StyleValue). |
| Color | A color (see ultralight::Color). |
| Object | A nested object (no value of its own). |
| List | A list of rows (no value of its own). |
| Action | An action (no value of its own). |
|
consteval |
Declare an action (a request the page sends to your code).
Pages fire an action from markup (eg, ul-on:click="hud.respawn"), and your code can send one with Binding::PostAction(). Handlers registered with Binding::OnAction() receive it inside Context::Sync().
To send a payload with each action, give its type as the template argument:
In the schema JSON, a single-value payload is a struct with one field, value. Handlers receive the value itself.
| name | The action's name. |
| tags | Optional tags (dd::OnlyLatest). |
|
consteval |
Declare a field.
The accessor reads the value from a const instance. It can be a data member pointer, a const member function pointer, or a lambda with no captures that takes a const reference to the instance. The field's type decides what the entry is:
Any other type fails to compile (eg, std::vector<float> or std::optional<int>).
| name | The field's name (pages use it in paths like hud.health). |
| accessor | How to read the value from a const instance. |
| tags | Optional tags (dd::Editable, dd::Internal, and one Validate()). |
|
consteval |
Declare a field without an accessor.
Give the value type as the template argument, since there's no accessor to take it from (eg, dd::Field<int>("score")). The type's Sync function writes the value with Model::Set().
| name | The field's name. |
| tags | Optional tags, as in the accessor form. |
|
consteval |
Declare a keyed list.
The accessor returns an iterable container of rows (by reference or by value), and each row is a described type. The key is the row member that identifies a row. When the list reorders, each row keeps its elements in the page:
| name | The list's name. |
| accessor | How to read the container from a const instance. |
| key | A pointer to the row member that identifies each row. The member must be an integer, an enum, or a string. |
| tags | Optional tags (dd::Internal). |
|
consteval |
Declare a list whose rows are matched by position.
This suits a list that only grows at the end. When rows reorder, each position keeps its elements and shows the new row's values. Use the keyed form when rows move.
| name | The list's name. |
| accessor | How to read the container from a const instance. |
| tags | Optional tags (dd::Internal). |
|
nodiscard |
Get a Result's value or a default-constructed T if it holds an error (see dom::OrEmpty()).
|
consteval |
Declare a type's schema.
A schema lists what pages can show and do with a type. Store it in the type as static constexpr auto schema, or in a TypeTraits specialization for a type you can't edit:
Entries keep the order you declare them in (Reflect() adds its fields in member order).
Schema() runs at compile time, and these mistakes fail to compile:
Look for a function like SchemaErrorDuplicateEntryName in the compiler's error. It states the rule the schema breaks.
| entries | The entries in order (Field(), List(), Action(), Var(), and Reflect()), plus any annotations for declared entries (dd::Editable("name"), dd::Internal("name"), and dd::Validate("name", fn)). |
|
consteval |
|
consteval |
Attach a validator to a field (a Field() tag).
A validator checks or corrects a value the page requests before the request is queued for your handler. It takes the requested value and returns the value to accept:
Return a std::optional to reject a request (an empty optional). The control then shows the last accepted value again.
To check the value against other fields, take a second parameter. It gets a Snapshot of the values the page shows. Declare it auto when you write the validator inside the schema, since the type isn't complete there:
The value parameter can use the field's own type or the library's form of it (int64_t or double for numbers, const String& for strings). An enum field gets the enum value. A request for a name that isn't one of its enumerators is rejected before your validator runs.
| fn | The validator (a lambda or function object with no captures). A function pointer doesn't compile. |
|
consteval |
Declare a CSS custom property that follows your data.
The page needs no markup for it. On the bound type itself, the property is set on the page's root element, so the whole document can use it. On a row type, it's set on each row's root element:
The accessor returns a number (a value without a unit), a StyleValue (a value with a unit), or a Color (written as hex, eg #ff8000).
| name | The property's name, starting with two hyphens. |
| accessor | How to read the value from a const instance. |
|
inlineconstexpr |
|
inlineconstexpr |
|
inlineconstexpr |