Data API

Data is passed from code to the UI through 'data objects'. Since most application code is through these data objects, we use 'inkd' as a shorthand for 'ink data object'.

Root objects#

The most common way to provide data to the UI is through a Global Source Node.

To get a reference to a global source node:

inkd ink_global_source(struct ink* ink, ink_ident name);
Data Ink::global_source(ink_ident name);
ink: ink context object. if null, the first context object created is used
name: Matches the 'Source Name' option of the Global Source Node.

Value Fields#

Values can be set on fields with setter functions:

void inkd_float    (inkd, ink_ident field, float value);
void inkd_int      (inkd, ink_ident field, int value);
void inkd_bool     (inkd, ink_ident field, char value);
void inkd_string   (inkd, ink_ident field, ink_str value);
void inkd_ident    (inkd, ink_ident field, ink_ident value);
void inkd_image    (inkd, ink_ident field, struct ink_image* value);
void inkd_color    (inkd, ink_ident field, uint32_t value);
void inkd_charp    (inkd, ink_ident field, const char* value);
    void Data::set_float   (ink_ident field, float value);
    void Data::set_int     (ink_ident field, int value);
    void Data::set_bool    (ink_ident field, bool value);
    void Data::set_string  (ink_ident field, const std::string& value);
    void Data::set_string  (ink_ident field, const char* value);
    void Data::set_ident   (ink_ident field, ink_ident value);
    void Data::set_image   (ink_ident field, ink_image* value);
    void Data::set_color   (ink_ident field, uint32_t value);

The value can be read back with corresponding getter functions:

float              inkd_get_float  (inkd, ink_ident field);
int                inkd_get_int    (inkd, ink_ident field);
char               inkd_get_bool   (inkd, ink_ident field);
ink_str            inkd_get_string (inkd, ink_ident field);
ink_ident          inkd_get_ident  (inkd, ink_ident field);
struct ink_image*  inkd_get_image  (inkd, ink_ident field);
uint32_t           inkd_get_color  (inkd, ink_ident field);
const char*        inkd_get_charp  (inkd, ink_ident field);
    float       Data::get_float(ink_ident field);
    int         Data::get_int(ink_ident field);
    bool        Data::get_bool(ink_ident field);
    String      Data::get_string(ink_ident field);
    std::string Data::get_std_string(ink_ident field);
    const char* Data::get_c_string(ink_ident field);
    ink_image*  Data::get_image(ink_ident field);
    uint32_t    Data::get_color(ink_ident field);

Note that inkd_charp and ink_get_charp are convenience functions that wrap inkd_string/inkd_get_string, allowing you to read and write strings without dealing with the ink_str API. The ink_str versions are mostly useful for optimizing heap allocations.

Lists#

Lists allow you to build nested data structures. Lists are not referenced directly, instead they are referenced by the inkd and the field name.

To create a new data object in a list use inkd_append

inkd inkd_append(inkd parent, ink_ident field)
Data Data::append(ink_ident field);
parent: the data object that holds the list
field: the name of the list in the parent data object
return value: new inkd that was added to the end of the list

To remove an inkd from a list:

void inkd_remove(inkd child)
void Data::remove()
child: the inkd that should be removed from its parent's list

To remove all contents of a list:

void inkd_clear(inkd d, ink_ident field);
void Data::clear(ink_ident field);

To rearrange children in a list:

void inkd_move(inkd child, int new_index);
void Data::move(int new_index);

To get a reference to an existing child in a list by index:

inkd inkd_get_child(inkd parent, ink_ident field, int index);
Data Data::get_child(ink_ident field, int index);

To get the index of a child in its parent's list:

int inkd_get_index(inkd child);
int Data::get_index();

To get the parent of a child:

inkd inkd_get_parent(inkd child);
Data Data::get_parent();

Lists need not be homogeneous. If the entries in a list vary significantly in their presentation and data, consider using template variants.

To specify which template variant an inkd should be mapped to:

void inkd_variant(inkd d, ink_ident variant);
void Data::set_variant(ink_ident variant);

Data Events#

enum ink_data_event_type {
    INK_DATA_EVENT_NONE = 0,
    INK_DATA_EVENT_NEW_SOURCE,
    INK_DATA_EVENT_REMOVE_SOURCE,
    INK_DATA_EVENT_CHANGE,
    INK_DATA_EVENT_IMPULSE,
    INK_DATA_EVENT_REMOVE,
};

struct ink_data_event {
    enum ink_data_event_type type;

    // Valid for NEW_SOURCE, REMOVE_SOURCE, CHANGE, IMPULSE, REMOVE
    ink_ident source_name;

    // Valid for NEW_SOURCE, REMOVE_SOURCE, CHANGE, IMPULSE, REMOVE
    struct ink_data* source_data;

    // Valid for CHANGE, IMPULSE, REMOVE
    struct ink_data* data;

    // Valid for CHANGE, IMPULSE
    ink_ident field;

    // Valid for IMPULSE, but may still be null
    const struct ink_event_info* event_info;
};

INK_EXPORTED
enum ink_data_event_type
ink_data_event_poll(struct ink* ink, struct ink_data_event* out);

// Blocks until an event is available.
INK_EXPORTED
enum ink_data_event_type
ink_data_event_wait(struct ink* ink, struct ink_data_event* out);