The scripting system of Synthesizer V Studio uses a reference-counting technique to share objects and safely transfer the ownership between the host (which runs native code with hard-coded memory management) and the client (which uses garbage collection).
In most cases, script authors do not need to know the underlying mechanism to write working and memory-safe code as most misuses will be detected by the script environment, causing error messages to pop up, e.g. "failed to access a deleted object". There however could be edge cases that go undetected, and in very rare cases, causing crashes.
Managed and Unmanaged Objects
- A
NestedObject
can be garbage-collected (managed) by the client environment if it has no parent, unless it is a top-level host-owned object (e.g. the main project). - If a
NestedObject
has a parent, then it is always unmanaged.
For example, if a NoteGroup
is created from a
script with a few notes added to it,
- NoteGroup (managed)
- Note 1 (unmanaged)
- Note 2 (unmanaged)
- Note 3 (unmanaged)
- Automation 1 (unmanaged)
- Automation 2 (unmanaged)
- ...
If the parent NoteGroup
gets garbage-collected
by the client, the host-side destructor for NoteGroup
will be triggered,
cleaning up all of its unmanaged children.
If the client environment has a reference to one of the
unmanaged notes in the NoteGroup
, the reference will be
marked as deleted when the unmanaged note gets deleted, that is,
either when the parent NoteGroup
gets garbage-collected,
or when the user explicitly deletes the note. Any attempt to access
the invalid reference will be detected and result in an error
message "failed to access a deleted 'Note' object".
When the managed NoteGroup
is added to a Project
, it gets converted into an
unmanaged object. This conversion is a simple state change that
signals the bypass of garbage collection and does not involve any
memory allocation/free/copy.