Introduction
Zrythm uses libcyaml to save projects into YAML. Cyaml can serialize C structs, given that you provide it with the schemas of each struct. This page has some tips on writing schemas.
- Note
- Some examples are no longer in the code base and are used only for demonstration purposes
Fields
For all fields, use the
flag to indicate that a variable can be NULL.
Ints
Use
with the
flag.
Example, having an 'enabled' flag inside a Plugin:
CYAML_FIELD_INT (
"enabled", CYAML_FLAG_DEFAULT,
The base plugin Inheriting plugins must have this as a child.
Enums
Use
with the
flag.
Example, RegionType inside a Region:
CYAML_FIELD_ENUM (
"type", CYAML_FLAG_DEFAULT,
Region, type, region_type_strings,
CYAML_ARRAY_LEN (region_type_strings)),
A region (clip) is an object on the timeline that contains either MidiNote's or AudioClip's.
Enums also need a cyaml_strval_t argument:
static const cyaml_strval_t
region_type_strings[] =
{
{ "Midi", REGION_TYPE_MIDI },
{ "Audio", REGION_TYPE_AUDIO },
};
String Pointers (char *)
Use
with the
flag.
Example, Region name:
CYAML_FIELD_STRING_PTR (
"name", CYAML_FLAG_POINTER,
0, CYAML_UNLIMITED),
Direct struct (not pointer) inside
another struct
Use
with the
flag.
Example, having a plain Position inside a MidiNote:
CYAML_FIELD_MAPPING (
"start_pos",
CYAML_FLAG_DEFAULT,
MidiNote, start_pos, position_fields_schema)
A MIDI note inside a Region shown in the piano roll.
Pointer to Struct
Use
with the
flag.
Example, having a pointer to an Lv2Plugin inside a Plugin:
CYAML_FIELD_MAPPING_PTR (
"lv2", CYAML_FLAG_POINTER,
lv2_plugin_fields_schema),
Array of primitives
For fixed-size arrays without a counter,
CYAML_FIELD_SEQUENCE_FIXED (
"midi_channels", CYAML_FLAG_DEFAULT,
&int_schema, 16),
A Channel is part of a Track (excluding Tracks that don't have Channels) and contains information rel...
Arrays of Pointers (variable
count)
There are two cases. Fixed-width arrays, like below. In this case, use the
flag.
MyStruct * my_structs[MAX_STRUCTS];
int num_my_structs;
The other case is dynamic arrays, like below. In this case use
.
int num_ats;
int ats_size;
Use
CYAML_FIELD_SEQUENCE_COUNT
with the
or
flag as described above.
Use
when declaring the schema of the child struct.
Example, fixed-size array of MidiNote pointers inside a Region:
CYAML_FIELD_SEQUENCE_COUNT (
"midi_notes", CYAML_FLAG_DEFAULT,
Region, midi_notes, num_midi_notes,
&midi_note_schema, 0, CYAML_UNLIMITED),
Example, dynamic array of AutomationTrack pointers in AutomationTracklist:
CYAML_FIELD_SEQUENCE_COUNT (
"ats", CYAML_FLAG_POINTER,
&automation_track_schema, 0, CYAML_UNLIMITED),
Each track has an automation tracklist with automation tracks to be generated at runtime,...
Arrays of Pointers (fixed count)
MyStruct * my_structs[9];
Use
CYAML_FIELD_SEQUENCE_FIXED
with the
flag.
Example:
CYAML_FIELD_SEQUENCE_FIXED (
"plugins", CYAML_FLAG_DEFAULT,
#define STRIP_SIZE
Number of plugin slots per channel.
Arrays of Structs (variable
count)
MyStruct my_structs[MAX_MY_STRUCTS];
int num_my_structs;
Use
CYAML_FIELD_SEQUENCE_COUNT
with the
flag.
Use
when declaring the schema of the child struct.
Example, destination PortIdentifier's of a Port:
static const cyaml_schema_value_t
port_identifier_schema_default = {
CYAML_VALUE_MAPPING (
CYAML_FLAG_DEFAULT,
port_identifier_fields_schema),
};
CYAML_FIELD_SEQUENCE_COUNT (
"dest_ids", CYAML_FLAG_DEFAULT,
Port, dest_ids, num_dests,
&port_identifier_schema_default,
0, CYAML_UNLIMITED),
Struct used to identify Ports in the project.
Must ONLY be created via port_new()
Bitfields
typedef enum PortFlags
{
PORT_FLAG_STEREO_L = 0x01,
PORT_FLAG_STEREO_R = 0x02,
PORT_FLAG_PIANO_ROLL = 0x04,
PORT_FLAG_SIDECHAIN = 0x08,
PORT_FLAG_MAIN_PORT = 0x10,
OPT_F = 0x20,
} PortFlags;
First, declare the bitfield definitions.
static const cyaml_bitdef_t
flags_bitvals[] =
{
{ .name = "stereo_l", .offset = 0, .bits = 1 },
{ .name = "stereo_r", .offset = 1, .bits = 1 },
{ .name = "piano_roll", .offset = 2, .bits = 1 },
{ .name = "sidechain", .offset = 3, .bits = 1 },
{ .name = "main_port", .offset = 4, .bits = 1 },
{ .name = "opt_f", .offset = 5, .bits = 1 },
};
Use
with the
flag.
Example, PortFlags:
CYAML_FIELD_BITFIELD (
"flags", CYAML_FLAG_DEFAULT,
CYAML_ARRAY_LEN (flags_bitvals)),
Schema Values
Schemas will normally be
with a
flag. Use the
if the struct will be used directly in another struct (not as a pointer).