# asset_label.h ## Overview
API for managing *Asset Labels* -- labels that can be added to assets for filtering. The Machinery distinguishes between two types of labels: *System* labels and *User* labels. *System* or *Engine* labels are added to assets automatically by the engine. For example, the creation graph system will automatically add a `Material` label to creation graphs that output materials. System labels cannot be added or removed by the user. Instead, you can add them to the engine by implementing the `tm_asset_label_t` interface. *User* labels are created by the `create()` function and live in the project as assets of type `TM_TT_TYPE__ASSET_LABEL`. Each user label has a permanent unique identifier `TM_TT_PROP__ASSET_LABEL__UUID`. The name of a user label is retrieved from the asset's `TM_TT_PROP__ASSET__NAME` property. You change the name of the label by changing the name of the asset. A project cannot have more than `TM_ASSET_LABEL_MAX` (256) labels (we treat the labels as bitmasks). ### Example The following example shows how to use this API to get a list of all assets with a certain set of labels: ~~~c TM_INIT_TEMP_ALLOCATOR(ta); tm_asset_labels_t all_labels; tm_asset_label_api->get_labels(&all_labels, tt, asset_root); tm_asset_label_bitflag_t filter = tm_asset_label_api->toggle_bitflags(&all_labels, &uuids, 4); tm_tt_id_t *assets = tm_asset_label_api->assets_with_all_labels(tt, asset_root, filter, ta); TM_SHUTDOWN_TEMP_ALLOCATOR(ta); ~~~
## Index
`TM_ASSET_LABEL_MAX`
`TM_ASSET_LABEL_BITFLAG_UINT64_COUNT`
`struct tm_asset_labels_t`
`struct tm_asset_label_bitflag_t`

`struct tm_asset_label_api`
`all_labels()`
`labels_of_asset()`
`label_uuids_of_asset()`
`create()`
`add()`
`remove()`
`rename()`
`assets_with_label()`
`assets_with_all_labels()`
`assets_with_any_label()`
`toggle_bitflags()`
`matches_all()`
`matches_any()`

`tm_asset_label_api_version`
## API
### `TM_ASSET_LABEL_MAX`
~~~c #define TM_ASSET_LABEL_MAX 256 ~~~ Maximum number of Asset Labels. (Used to size bitflags.)
### `TM_ASSET_LABEL_BITFLAG_UINT64_COUNT`
~~~c #define TM_ASSET_LABEL_BITFLAG_UINT64_COUNT ~~~ Size of bitflag (number of `uint64_t`).
### `struct tm_asset_labels_t`
Used to represent a set of Asset Labels with names and UUIDs. ~~~c typedef struct tm_asset_labels_t { // UUIDs of all asset labels in the set. tm_asset_label_uuid_t uuids[TM_ASSET_LABEL_MAX]; // Names of all asset labels in the set. const char *names[TM_ASSET_LABEL_MAX]; // Icons of all asset labels in the set, see `enum tm_ui_icon` uint32_t icons[TM_ASSET_LABEL_MAX]; // Colors of the icons to use. uint32_t icon_colors[TM_ASSET_LABEL_MAX]; // Number of asset labels (entries in `uuids` and `names`). uint32_t num_labels; // Number of system labels in the `uuids` and `names` arrays. The system labels are always stored // at the start of the arrays. Note that `num_system_labels <= num_labels`. uint32_t num_system_labels; } tm_asset_labels_t; ~~~
### `struct tm_asset_label_bitflag_t`
Used to represent a set of asset labels as a bitflag array. The indices in the bitflag array typically refer to the global `tm_asset_labels_t` array returned by `all_labels()`. You could theoretically use the bitflags with other arrays, but if you do, you must be careful not to compare two bitflags using different arrays. ~~~c typedef struct tm_asset_label_bitflag_t { uint64_t bitflag[TM_ASSET_LABEL_BITFLAG_UINT64_COUNT]; } tm_asset_label_bitflag_t; ~~~
### `struct tm_asset_label_api`
API used to manipulate asset labels. #### `all_labels()` ~~~c void (*all_labels)(tm_asset_labels_t *labels, const tm_the_truth_o *const tt, tm_tt_id_t asset_root); ~~~ Returns all registered asset labels (system and user) in `labels`. #### `labels_of_asset()` ~~~c void (*labels_of_asset)(tm_the_truth_o *tt, tm_tt_id_t asset, const tm_asset_labels_t *const asset_labels, tm_asset_labels_t *out_labels); ~~~ Returns the labels of the `TM_TT_TYPE__ASSET` `asset` in `out_labels`. `asset_labels` should be the labels returned by `all_labels()`. This is used to lookup the names of labels. If a label UUID is not found in `asset_labels` the corresponding `names` entry will be `NULL` in `out_labels`. #### `label_uuids_of_asset()` ~~~c uint64_t *(*label_uuids_of_asset)(const struct tm_the_truth_o *tt, tm_tt_id_t asset, struct tm_temp_allocator_i *ta); ~~~ Fetches the UUIDs of asset labels stored within the asset and returns them in a carray. #### `create()` ~~~c tm_asset_label_uuid_t (*create)(tm_the_truth_o *tt, tm_tt_id_t asset_root, tm_tt_id_t directory, const char *label, tm_tt_undo_scope_t undo_scope); ~~~ Creates a user Asset Label with name `label` in the project `tt`. The asset for the Asset Label will be stored in the `TM_TT_TYPE__ASSET_DIRECTORY`. Returns the randomly assigned UUID of the new asset label. If you try to create a label that already exists, an error message will be printed and the function will return `{0}`. (Asset label name compare is case insensitive.) !!! TODO: API-REVIEW * Instead of giving an error, should we return the UUID of the existing label if it already exists? * What happens if you rename a label to an existing label name in the asset browser after creation? Do we have/need protection against that? #### `add()` ~~~c void (*add)(tm_the_truth_o *tt, tm_tt_id_t asset, tm_asset_label_uuid_t label, tm_tt_undo_scope_t undo_scope); ~~~ Adds the `label` to the `TM_TT_TYPE__ASSET` `asset`. If the asset already has the label, this function does nothing. You cannot add System labels o the asset using this call, system labels are added automatically. #### `remove()` ~~~c void (*remove)(tm_the_truth_o *tt, tm_tt_id_t asset, tm_asset_label_uuid_t label, tm_tt_undo_scope_t undo_scope); ~~~ Removes the `label` from the `TM_TT_TYPE__ASSET` `asset`. If the asset doesn't have the label, the call is ignored. This function will never remove the Asset Label asset `.label` from the project, even if there are no other assets using the `label`. #### `rename()` ~~~c void (*rename)(tm_the_truth_o *tt, tm_tt_id_t asset_root, tm_asset_label_uuid_t label, const char *new_label_name, tm_tt_undo_scope_t undo_scope); ~~~ Convenience function for changing a label's name. !!! NOTE: Remark The `new_label_name` must be unique, i.e. it cannot be used by any existing system or user label. Label compare is case insensitive. If you try to change the name to an existing name, an error message will be printed and the name will remain unchanged. #### `assets_with_label()` ~~~c /* carray */ tm_tt_id_t *(*assets_with_label)(tm_the_truth_o *tt, tm_tt_id_t asset_root, tm_asset_label_uuid_t label, struct tm_temp_allocator_i *ta); ~~~ Returns a `carray.inl` of all assets in the `asset_root` with the `label`. #### `assets_with_all_labels()` ~~~c /* carray */ tm_tt_id_t *(*assets_with_all_labels)(tm_the_truth_o *tt, tm_tt_id_t asset_root, const tm_asset_label_bitflag_t *const labels, struct tm_temp_allocator_i *ta); ~~~ Returns a `carray.inl` of all assets in the `asset_root` that have *all* the labels in the `labels` bitflag. Use `toggle_bitflags()` to build the bit flag array. #### `assets_with_any_label()` ~~~c /* carray */ tm_tt_id_t *(*assets_with_any_label)(tm_the_truth_o *tt, tm_tt_id_t asset_root, const tm_asset_label_bitflag_t *const labels, struct tm_temp_allocator_i *ta); ~~~ Returns a `carray.inl` of all assets in the `asset_root` that have *any* of the labels in the `labels` bitflag. Use `toggle_bitflags()` to build the bit flag array. #### `toggle_bitflags()` ~~~c void (*toggle_bitflags)(const tm_asset_labels_t *labels, tm_asset_label_bitflag_t *bitflag, const tm_asset_label_uuid_t *labels_uuid, uint32_t num_labels); ~~~ Toggles the items in the `labels_uuid` array in the bitflag `bitflag`. `labels` is the context for the bitflags. UUIDs not found in the `labels` array are ignored. To build a bitflag from scratch you can initialize the bitflag with `= {0}` and then toggle the bits you want to set with `toggle_bitflags()`. #### `matches_all()` ~~~c bool (*matches_all)(const tm_asset_label_bitflag_t *asset_bitflag, const tm_asset_label_bitflag_t *filter_bitflag); ~~~ Returns `true` if `asset_bitflag` has all the bits that are set in `filter_bitflag`. #### `matches_any()` ~~~c bool (*matches_any)(const tm_asset_label_bitflag_t *asset_bitflag, const tm_asset_label_bitflag_t *filter_bitflag); ~~~ Returns `true` if `asset_bitflag` has any of the bits that are set in `filter_bitflag`.
### `tm_asset_label_api_version`
~~~c #define tm_asset_label_api_version ~~~