Skip to content

Commit

Permalink
Work on undo example and remove the remote gui
Browse files Browse the repository at this point in the history
  • Loading branch information
abique committed Sep 16, 2024
1 parent 9a29a32 commit a5a9c0a
Show file tree
Hide file tree
Showing 23 changed files with 212 additions and 1,386 deletions.
33 changes: 0 additions & 33 deletions CMakePresets.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,6 @@
"type": "FILEPATH",
"value": "${sourceDir}/vcpkg/scripts/buildsystems/vcpkg.cmake"
},
"CLAP_PLUGINS_REMOTE_GUI": {
"type": "BOOL",
"value": false
},
"CLAP_PLUGINS_EMBED_QML": {
"type": "BOOL",
"value": true
Expand All @@ -63,24 +59,6 @@
"vcpkg"
]
},
{
"name": "ninja-system",
"description": "Ninja + System Libraries",
"binaryDir": "${sourceDir}/builds/${presetName}",
"inherits": [
"base"
],
"cacheVariables": {
"CLAP_PLUGINS_REMOTE_GUI": {
"type": "BOOL",
"value": true
},
"CLAP_PLUGINS_EMBED_QML": {
"type": "BOOL",
"value": false
}
}
},
{
"name": "ninja-headless",
"description": "Ninja + System Libraries + Headless",
Expand Down Expand Up @@ -121,12 +99,6 @@
"configurePreset": "ninja-vcpkg",
"inherits": "base"
},
{
"name": "ninja-system",
"inherits": "base",
"description": "Build using Ninja and system libraries",
"configurePreset": "ninja-system"
},
{
"name": "ninja-headless",
"inherits": "base",
Expand All @@ -152,11 +124,6 @@
"description": "Test using Ninja and VCPKG",
"configurePreset": "ninja-vcpkg"
},
{
"name": "ninja-system",
"description": "Test using Ninja and system libraries",
"configurePreset": "ninja-system"
},
{
"name": "ninja-headless",
"description": "Test using Ninja and system libraries (headless)",
Expand Down
53 changes: 4 additions & 49 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,10 @@
- [Notes on GUI, static build vs dynamic build and symbols](#notes-on-gui-static-build-vs-dynamic-build-and-symbols)
- [Building on various platforms](#building-on-various-platforms)
- [Headless](#headless)
- [macOS, dynamic build with brew](#macos-dynamic-build-with-brew)
- [macOS with vcpkg](#macos-with-vcpkg)
- [Windows](#windows)
- [Enable long path support](#enable-long-path-support)
- [Build](#build)
- [Linux, using system libraries (dynamic)](#linux-using-system-libraries-dynamic)
- [Linux, using vcpkg (static)](#linux-using-vcpkg-static)

# Example Clap Plugins
Expand All @@ -33,33 +31,14 @@ Objective-C classes but with the same, they will clash which will result in unde

Qt uses a few Objective-C classes on macOS. So it is crucial to use `QT_NAMESPACE`.

We have two different strategies to work with that.
1. **local**: statically link every thing
2. **remote**: start the gui in a child process

**1.** has the advantage of being simple to deploy.
**2.** is more complex due to its inter-process nature. It has a few advantages:
- if the GUI crash, the audio engine does not
- the GUI can use any libraries, won't be subject to symbol or library clash etc...

We abstracted the relation between the plugin and the GUI:
[`AbstractGui`](plugins/gui/abstract-gui.hh) and [`AbstractGuiListener`](plugins/gui/abstract-gui-listener.hh)
which lets us transparently insert proxies to support the **remote** model.
which lets us transparently insert proxies.

The GUI itself work with proxy objects to the parameters, transport info, ...
They are then bound into QML objects.
See [`Knob.qml`](plugins/gui/qml/clap/Knob.qml) and [`parameter-proxy.hh`](plugins/gui/parameter-proxy.hh).

We offer two options:
- static build, cmake preset: `ninja-vcpkg` or `vs-vcpkg` on Windows.
- dynamic builg, cmake preset: `ninja-system`

Static builds are convenient for deployment as they are self containded. They use the **local** gui model.

Dynamic builds will get your started quickly if your system provides Qt6,
and you have an host that do not expose the Qt symbols.
Static builds will require more time and space.

# Building on various platforms

## Headless
Expand All @@ -73,21 +52,6 @@ cmake --preset ninja-headless
cmake --build --preset ninja-headless
```

## macOS, dynamic build with brew

```shell
# Install dependencies
brew install qt6 boost ninja cmake

# Checkout the code
git clone --recurse-submodules https://github.com/free-audio/clap-plugins
cd clap-plugins

# Build
cmake --preset ninja-system
cmake --build --preset ninja-system
```

## macOS with vcpkg

```shell
Expand Down Expand Up @@ -126,24 +90,15 @@ cd c-p
scripts/build-gui.sh
```

## Linux, using system libraries (dynamic)
## Linux, using vcpkg (static)

```bash
# on unbuntu, adapt to your distribution and package manager
sudo apt install qt6-declarative-dev git ninja-build cmake
sudo apt install git ninja-build cmake

# on archlinux, adapt to your distribution and package manager
sudo pacman -S qt boost git ninja cmake
sudo pacman -S git ninja cmake

git clone --recurse-submodules https://github.com/free-audio/clap-plugins
cd clap-plugins
cmake --preset ninja-system
cmake --build --preset ninja-system
```

## Linux, using vcpkg (static)

```bash
git clone --recurse-submodules https://github.com/free-audio/clap-plugins
cd clap-plugins
scripts/build-gui.sh
Expand Down
16 changes: 2 additions & 14 deletions plugins/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
set(CLAP_PLUGINS_REMOTE_GUI TRUE CACHE BOOL "Should the GUI be ran from another process?")
set(CLAP_PLUGINS_EMBED_QML TRUE CACHE BOOL "Embed QML resources into the plugin")
set(CLAP_PLUGINS_HEADLESS FALSE CACHE BOOL "Compile the plugins without a GUI")

Expand Down Expand Up @@ -99,21 +98,10 @@ set_target_properties(clap-plugins-core PROPERTIES CXX_STANDARD 20)
set_target_properties(clap-plugins-core PROPERTIES POSITION_INDEPENDENT_CODE TRUE)

if(NOT CLAP_PLUGINS_HEADLESS)
if(CLAP_PLUGINS_REMOTE_GUI)
target_compile_definitions(clap-plugins-core PUBLIC CLAP_REMOTE_GUI)
target_link_libraries(clap-plugins-core PUBLIC clap-plugin-remote-gui)
add_dependencies(clap-plugins-core clap-gui)
else()
target_compile_definitions(clap-plugins-core PUBLIC CLAP_LOCAL_GUI)
target_link_libraries(clap-plugins-core PUBLIC clap-plugin-local-gui)
endif()

target_link_libraries(clap-plugins-core PUBLIC clap-io)
target_compile_definitions(clap-plugins-core PUBLIC CLAP_LOCAL_GUI)
target_link_libraries(clap-plugins-core PUBLIC clap-plugin-local-gui clap-io clap-plugin-gui-common)
endif()

if (NOT CLAP_PLUGINS_HEADLESS)
target_link_libraries(clap-plugins-core PUBLIC clap-plugin-gui-common)
endif()
target_link_libraries(clap-plugins-core PUBLIC clap-helpers)

add_library(clap-plugins MODULE clap-entry.cc)
Expand Down
19 changes: 17 additions & 2 deletions plugins/core-plugin.cc
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ namespace clap {
try {
ClapOStream os(stream);
yas::binary_oarchive ar(os);
ar &_parameters;
ar & _parameters;
} catch (...) {
return false;
}
Expand All @@ -141,7 +141,7 @@ namespace clap {
ClapIStream is(stream);
#endif
yas::binary_iarchive ar(is);
ar &_parameters;
ar & _parameters;
} catch (...) {
return false;
}
Expand Down Expand Up @@ -341,6 +341,21 @@ namespace clap {
void CorePlugin::onGuiWindowClosed(bool wasDestroyed) {
runOnMainThread([this, wasDestroyed] { _host.guiClosed(wasDestroyed); });
}

void CorePlugin::onGuiUndo() {
runOnMainThread([this] {
if (_host.canUseUndo())
_host.undoUndo();
});
}

void CorePlugin::onGuiRedo() {
runOnMainThread([this] {
if (_host.canUseUndo())
_host.undoRedo();
});
}

#endif // CLAP_PLUGINS_HEADLESS

//------------------//
Expand Down
2 changes: 2 additions & 0 deletions plugins/core-plugin.hh
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,8 @@ namespace clap {
void onGuiParamEndAdjust(clap_id paramId) override;
void onGuiSetTransportIsSubscribed(bool isSubscribed) override;
void onGuiWindowClosed(bool wasDestroyed) override;
void onGuiUndo() override;
void onGuiRedo() override;
#endif

//------------------------//
Expand Down
62 changes: 21 additions & 41 deletions plugins/gui/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@ add_library(
track-info-proxy.hh
track-info-proxy.cc
transport-proxy.hh
transport-proxy.cc)
transport-proxy.cc
undo-proxy.hh
undo-proxy.cc)
set_property(TARGET clap-plugin-gui PROPERTY CXX_STANDARD 20)
target_link_libraries(clap-plugin-gui PUBLIC clap-io clap-plugin-gui-common)
target_link_libraries(clap-plugin-gui PUBLIC Qt6::Quick)
Expand All @@ -36,43 +38,21 @@ if(CLAP_PLUGINS_EMBED_QML)
target_link_libraries(clap-plugin-gui PUBLIC clap-qml-skins clap-qml-lib clap-qml-libplugin)
endif()

if(CLAP_PLUGINS_REMOTE_GUI)
# Code for having the GUI in a child process
add_library(
clap-plugin-remote-gui
remote-gui-factory-proxy.hh remote-gui-factory-proxy.cc remote-gui-proxy.hh
remote-gui-proxy.cc)
set_property(TARGET clap-plugin-remote-gui PROPERTY CXX_STANDARD 20)
set_property(TARGET clap-plugin-remote-gui PROPERTY POSITION_INDEPENDENT_CODE true)
target_link_libraries(clap-plugin-remote-gui PUBLIC clap-plugin-gui-common clap-io)
if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
target_link_libraries(clap-plugin-remote-gui PUBLIC pthread)
endif()

add_executable(
clap-gui gui-main.cc remote-gui-factory.hh remote-gui-factory.cc
remote-gui-listener.hh remote-gui-listener.cc)
target_link_libraries(clap-gui PUBLIC clap-plugin-gui)
set_target_properties(clap-gui PROPERTIES CXX_STANDARD 20)

install(TARGETS clap-gui DESTINATION "bin")
else()
# Code for having the GUI with the plugin
add_library(
clap-plugin-local-gui
local-gui-factory.hh
local-gui-factory.cc
threaded-gui-factory.hh
threaded-gui-factory.cc
threaded-gui-proxy.hh
threaded-gui-proxy.cc
timer.hh
timer.cc
cf-timer.hh
cf-timer.cc
win32-timer.hh
win32-timer.cc)
set_property(TARGET clap-plugin-local-gui PROPERTY CXX_STANDARD 20)
set_property(TARGET clap-plugin-local-gui PROPERTY POSITION_INDEPENDENT_CODE true)
target_link_libraries(clap-plugin-local-gui PUBLIC clap-plugin-gui)
endif()
# Code for having the GUI with the plugin
add_library(
clap-plugin-local-gui
local-gui-factory.hh
local-gui-factory.cc
threaded-gui-factory.hh
threaded-gui-factory.cc
threaded-gui-proxy.hh
threaded-gui-proxy.cc
timer.hh
timer.cc
cf-timer.hh
cf-timer.cc
win32-timer.hh
win32-timer.cc)
set_property(TARGET clap-plugin-local-gui PROPERTY CXX_STANDARD 20)
set_property(TARGET clap-plugin-local-gui PROPERTY POSITION_INDEPENDENT_CODE true)
target_link_libraries(clap-plugin-local-gui PUBLIC clap-plugin-gui)
3 changes: 3 additions & 0 deletions plugins/gui/abstract-gui-listener.hh
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,8 @@ namespace clap {
virtual void onGuiSetTransportIsSubscribed(bool isSubscribed) = 0;

virtual void onGuiWindowClosed(bool wasDestroyed) = 0;

virtual void onGuiUndo() = 0;
virtual void onGuiRedo() = 0;
};
} // namespace clap
5 changes: 5 additions & 0 deletions plugins/gui/abstract-gui.hh
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,11 @@ namespace clap {

virtual void destroy() = 0;

virtual void setCanUndo(bool can_undo) = 0;
virtual void setCanRedo(bool can_redo) = 0;
virtual void setUndoName(std::string name) = 0;
virtual void setRedoName(std::string name) = 0;

AbstractGuiListener& listener() const { return _listener; }

protected:
Expand Down
18 changes: 17 additions & 1 deletion plugins/gui/gui.cc
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ namespace clap {
_pluginProxy = std::make_unique<PluginProxy>(*this);
_transportProxy = std::make_unique<TransportProxy>(*this);
_trackInfoProxy = std::make_unique<TrackInfoProxy>(*this);
_undoProxy = std::make_unique<UndoProxy>(*this);

////////////////////////
// QML initialization //
Expand All @@ -35,6 +36,7 @@ namespace clap {
qmlContext->setContextProperty("plugin", _pluginProxy.get());
qmlContext->setContextProperty("transport", _transportProxy.get());
qmlContext->setContextProperty("trackInfo", _trackInfoProxy.get());
qmlContext->setContextProperty("undo", _undoProxy.get());
setRootScale(1);

connect(
Expand Down Expand Up @@ -83,7 +85,9 @@ namespace clap {
p->setMappingIndication(color, label, description);
}

void Gui::setParameterAutomationIndication(clap_id paramId, uint32_t automationState, clap_color color) {
void Gui::setParameterAutomationIndication(clap_id paramId,
uint32_t automationState,
clap_color color) {
qDebug() << "clap-gui: setParameterAutomationIndication(" << paramId << ")";
auto p = _pluginProxy->param(paramId);
assert(p);
Expand Down Expand Up @@ -308,4 +312,16 @@ namespace clap {
_pluginProxy.reset();
_isFloating = false;
}

void Gui::setCanUndo(bool can_undo) { _undoProxy->setCanUndo(can_undo); }

void Gui::setCanRedo(bool can_redo) { _undoProxy->setCanRedo(can_redo); }

void Gui::setUndoName(std::string name) {
_undoProxy->setUndoName(QString::fromStdString(name));
}

void Gui::setRedoName(std::string name) {
_undoProxy->setRedoName(QString::fromStdString(name));
}
} // namespace clap
Loading

0 comments on commit a5a9c0a

Please sign in to comment.