Skip to content

Stw/liquidsfz api export - #82

Open
swesterfeld wants to merge 101 commits into
trunkfrom
stw/liquidsfz-api-export
Open

Stw/liquidsfz api export#82
swesterfeld wants to merge 101 commits into
trunkfrom
stw/liquidsfz-api-export

Conversation

@swesterfeld

Copy link
Copy Markdown
Collaborator

I tried to do a language binding to be able to load .sfz files from JavaScript.

  • I had to rename LiquidSFZPlugin to LiquidSFZTracktionPlugin, not sure if that is the right thing to do, we could also use a different name for the plugin interface class (like ILiquidSFZ being the wrapper for LiquidSFZPlugin)
  • I had to make plugin.cc use different code for liquidsfz plugins than for normal plugins (so in the end we would have a list of plugins to be wrapped there), but I see no way around it
  • we have to wrap everything twice, so we need to forward load() from LiquidSFZPlugin to LiquidSFZTracktionPlugin
  • if this way of doing it is reviewed as ok, we can then finally move the LiquidSFZTracktionPlugin to the liquidsfzplugin.cc file and avoid including PCH in the header

So please review and let me know if that is ok to merge like I did it.

User and others added 30 commits April 20, 2026 02:01
* Branch commit log:
  ui/b/trackview.js: add 'Add MIDI Clip' menu item to track context menu
  ase/project.cc: emit all_tracks notification on track add/remove
  ase/track.cc: emit launcher_clips notification on clip added/removal
  ase/track.cc: only collect MIDI clips when listing launcher_clips
  ui/startup.js: include exception stack trace in test error logging
  ui/wrapper.js: expand JSDoc for wrap_ase_object to document reactive caching behavior
  electron/main.js: refactor trycatch & tryelse to handle sync and async errors
  electron/main.js: resolve source code locations in exception stack traces
Move the remove_self() method from Device to Gadget so that all
gadget types (Device, Clip, Monitor, etc.) can be removed from
their parent container.
…rectly

- Remove Project::remove_track() from the API interface
- Update UI caller (trackview.js) to use track.remove_self() directly
- Auto-generated IPC bindings updated accordingly
…s/test-setup.cc

- Moved load_audio_file_as_clip, loop_around_clip, and test_setup
  from project.cc to ase/tests/test-setup.cc
- Removed test_setup call from ProjectImpl constructor
- Added friend declaration for test_audio_sample_load in project.hh
- Added test to TestList.g.mk
- Add register_ase_obj, unregister_ase_obj and find_ase_obj helpers to use ase_obj_ field
- Replace SelectableHandle with ase_obj_ pointer registration
- Update ClipImpl, ProjectImpl, and TrackImpl to use new registration helpers
- Remove SelectableHandle class and its associated map-based lookup logic
* Branch commit log:
  ase/: refactor Ase object registration with trkn objects
	- Add register_ase_obj, unregister_ase_obj and find_ase_obj helpers to use ase_obj_ field
	- Replace SelectableHandle with ase_obj_ pointer registration
	- Update ClipImpl, ProjectImpl, and TrackImpl to use new registration helpers
	- Remove SelectableHandle class and its associated map-based lookup logic
  trkn/tracktion_engine/selection/tracktion_Selectable.h: add Ase::VirtualBase*ase_obj_; pointer
  trkn/tracktion_decls.hh: add Ase::VirtualBase forward declaration
  ase/project.cc: move test_setup test code from project.cc to ase/tests/test-setup.cc
	- Moved load_audio_file_as_clip, loop_around_clip, and test_setup
	  from project.cc to ase/tests/test-setup.cc
	- Removed test_setup call from ProjectImpl constructor
	- Added friend declaration for test_audio_sample_load in project.hh
	- Added test to TestList.g.mk
  ase/clip.cc: simplify, use clip->removeFromParent()
  ase/track.cc: simplify, use edit.deleteTrack() directly
  ui/tests/project_test.ts: add test for track removal
  ase/api.hh: remove Track::remove_track(), use Track::remove_self() directly
	- Remove Project::remove_track() from the API interface
	- Update UI caller (trackview.js) to use track.remove_self() directly
	- Auto-generated IPC bindings updated accordingly
  ase/track.cc: make TrackImpl::remove_self() self-contained like ClipImpl::remove_self()
  ase/: move remove_self() from Device to Gadget
	Move the remove_self() method from Device to Gadget so that all
	gadget types (Device, Clip, Monitor, etc.) can be removed from
	their parent container.
Signed-off-by: Stefan Westerfeld <stefan@space.twc.de>
Signed-off-by: Stefan Westerfeld <stefan@space.twc.de>
Signed-off-by: Stefan Westerfeld <stefan@space.twc.de>
* Branch commit log:
  ase/Makefile.mk: use libsndfile dependencies from SNDFILEDEPS_PACKAGES
  misc/config-checks.mk: use pkg-config for SNDFILEDEPS_PACKAGES
  ase/Makefile.mk: fix libsndfile support for flac, ogg and opus files
Signed-off-by: Stefan Westerfeld <stefan@space.twc.de>
Signed-off-by: Stefan Westerfeld <stefan@space.twc.de>
Signed-off-by: Stefan Westerfeld <stefan@space.twc.de>
Signed-off-by: Stefan Westerfeld <stefan@space.twc.de>
* Branch commit log:
  ase/liquidsfz.cc: update liquidsfz to 0.4.1
  external/Makefile.mk: update liquidsfz to 0.4.1
  external/Makefile.mk: update liquidsfz to 0.4.0
tim-janik and others added 27 commits May 8, 2026 01:52
Replace the Lit <b-aboutdialog> custom element with a SolidJS
AboutDialog component. The component uses createSignal for reactive
info pairs, onMount for async data loading, and Dom.show_modal()
for imperative dialog control.

Shell template now imports AboutDialog directly instead of using
the <b-aboutdialog> element.

onMount: Defer dialog show until version data is loaded.
Await about_pairs() before calling Dom.show_modal() so the dialog
appears at full size immediately instead of starting small and
growing when async IPC data arrives.
…fecycle

Per SolidJS best practices (solid-modal, solid-dialog, solid-blocks):
- onCleanup runs synchronously before DOM removal, ensuring dialogRef.close()
  fires the native 'close' event for Dom.show_modal() listener cleanup
- cancelled flag guards against showModal() after unmount during async load
- Dom.show_modal() gets idempotency guard to prevent double closefunc()
  when onCleanup and native close event both trigger
Replace the Lit <b-statusbar> custom element with a SolidJS
StatusBar component. Uses createSignal for kbd/status state,
onMount/onCleanup for zmove subscription, and a DOM ref for
imperative Dom.markdown_to_html() rendering.

Shell template now imports StatusBar directly instead of using
the <b-statusbar> element.
* Branch commit log:
  ui/b/statusbar: port from Lit to SolidJS
	Replace the Lit <b-statusbar> custom element with a SolidJS
	StatusBar component. Uses createSignal for kbd/status state,
	onMount/onCleanup for zmove subscription, and a DOM ref for
	imperative Dom.markdown_to_html() rendering.
	Shell template now imports StatusBar directly instead of using
	the <b-statusbar> element.
  ui/b/statusbar.jsx: rename .js to .jsx
  ui/b/aboutdialog: add onCleanup + cancelled-flag for robust dialog lifecycle
	Per SolidJS best practices (solid-modal, solid-dialog, solid-blocks):
	- onCleanup runs synchronously before DOM removal, ensuring dialogRef.close()
	  fires the native 'close' event for Dom.show_modal() listener cleanup
	- cancelled flag guards against showModal() after unmount during async load
	- Dom.show_modal() gets idempotency guard to prevent double closefunc()
	  when onCleanup and native close event both trigger
  ui/b/aboutdialog: port from Lit to SolidJS
	Replace the Lit <b-aboutdialog> custom element with a SolidJS
	AboutDialog component. The component uses createSignal for reactive
	info pairs, onMount for async data loading, and Dom.show_modal()
	for imperative dialog control.
	Shell template now imports AboutDialog directly instead of using
	the <b-aboutdialog> element.
	onMount: Defer dialog show until version data is loaded.
	Await about_pairs() before calling Dom.show_modal() so the dialog
	appears at full size immediately instead of starting small and
	growing when async IPC data arrives.
  ui/b/aboutdialog.jsx: rename .js to .jsx
* Branch commit log:
  ui/b/shell: use SolidJS TreeBrowser component
  ui/b/treebrowser: migrate from Lit to SolidJS
  ui/b/treebrowser: rename .js -> .jsx (pre-migration rename for clear diff)
  ui/b/shell: use SolidJS Noticeboard component
  ui/b/noticeboard: migrate from Lit to SolidJS
  ui/b/noticeboard: rename .js -> .jsx (pre-migration rename for clear diff)
* Branch commit log:
  ui/b/preferencesdialog: port from Lit to SolidJS
  ui/b/preferencesdialog: rename .js to .jsx in preparation for SolidJS port
  ui/b/menubar: port from Lit to SolidJS
  ui/b/menubar: rename .js to .jsx in preparation for SolidJS migration
- Replaced LitComponent class with function component returning JSX
- track prop drives async device fetching via createEffect
- devicetypes/chain stored as createSignal for reactive updates
- menu_sibling as createSignal for context menu sibling tracking
- activate/isactive/menuopen as local functions (no longer class methods)
- b-contextmenu activate/isactive callbacks set via ref (function props
  don't flow through JSX to web components)
- shell.jsx: import DevicePanel, wrap in <Show> for hidden control
- Replaced LitComponent class with function component returning JSX
- project prop drives track fetching via createEffect
- all_tracks stored in createSignal, fetched on project change
- notify:all_tracks listener for reactive track list updates
- For directive replaces Lit repeat() for track iteration
- Scroll sync (3 columns) via refs + createEffect
- dblclick handler for create_track on trackviews column
- wrap_ase_object pattern replaced with direct signal + notification
  listener (SolidJS native reactivity)
* Branch commit log:
  ui/b/tracklist: port from Lit to SolidJS
	- Replaced LitComponent class with function component returning JSX
	- project prop drives track fetching via createEffect
	- all_tracks stored in createSignal, fetched on project change
	- notify:all_tracks listener for reactive track list updates
	- For directive replaces Lit repeat() for track iteration
	- Scroll sync (3 columns) via refs + createEffect
	- dblclick handler for create_track on trackviews column
	- wrap_ase_object pattern replaced with direct signal + notification
	  listener (SolidJS native reactivity)
  ui/b/tracklist: rename .js to .jsx in preparation for SolidJS port
  ui/b/devicepanel: port from Lit to SolidJS
	- Replaced LitComponent class with function component returning JSX
	- track prop drives async device fetching via createEffect
	- devicetypes/chain stored as createSignal for reactive updates
	- menu_sibling as createSignal for context menu sibling tracking
	- activate/isactive/menuopen as local functions (no longer class methods)
	- b-contextmenu activate/isactive callbacks set via ref (function props
	  don't flow through JSX to web components)
	- shell.jsx: import DevicePanel, wrap in <Show> for hidden control
  ui/b/devicepanel: rename .js to .jsx in preparation for SolidJS port
Signed-off-by: Stefan Westerfeld <stefan@space.twc.de>
Signed-off-by: Stefan Westerfeld <stefan@space.twc.de>
Signed-off-by: Stefan Westerfeld <stefan@space.twc.de>

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces the LiquidSFZPlugin interface and its implementation, LiquidSFZPluginImpl, to support SFZ file loading within the ASE framework. It renames the existing Tracktion-specific class to LiquidSFZTracktionPlugin for clarity and updates the JSON-IPC layer to expose the load functionality. A critical issue was identified in the LiquidSFZPluginImpl::load method where a potential null pointer dereference could occur when accessing the underlying plugin, necessitating a safety check for the result of plugin_.get() and the subsequent cast.

Comment thread devices/liquidsfz/liquidsfzplugin.hh Outdated
Signed-off-by: Stefan Westerfeld <stefan@space.twc.de>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants