From 853e2052ff597a8051edec950f78c11f6ef09f3c Mon Sep 17 00:00:00 2001 From: attila Date: Fri, 23 Aug 2024 10:08:01 +0200 Subject: [PATCH] Use WebViewLifetimeListener in WebControlRelays --- BREAKING_CHANGES.md | 26 ++++++++ examples/Plugins/WebViewPluginDemo.h | 6 +- .../misc/juce_WebControlRelays.cpp | 66 ++++++++++++++----- .../misc/juce_WebControlRelays.h | 27 +++++--- 4 files changed, 98 insertions(+), 27 deletions(-) diff --git a/BREAKING_CHANGES.md b/BREAKING_CHANGES.md index 3cc2b27e4e..bc3161d739 100644 --- a/BREAKING_CHANGES.md +++ b/BREAKING_CHANGES.md @@ -2,6 +2,32 @@ # develop +## Change + +The constructors of the WebSliderRelay, WebToggleButtonRelay and +WebComboBoxRelay classes were changed and they no longer accept a reference +parameter to a WebBrowserComponent object. + +**Possible Issues** + +Code that uses these classes will fail to compile. + +**Workaround** + +Omit the WebBrowserComponent parameter when constructing the relay objects. + +**Rationale** + +The relay classes use a new underlying mechanism to obtain a pointer to the +WebBrowserComponent object. When calling the +WebBrowserComponent::Options::withOptionsFrom() function with the relay as a +parameter, the corresponding WebBrowserComponent object will notify the relay +about its creation and destruction. + +This avoids the anti-pattern where the relay class required a reference to a +yet uninitialised WebBrowserComponent object. + + ## Change The coefficients of LadderFilter::Mode::BPF12 have been changed, causing a diff --git a/examples/Plugins/WebViewPluginDemo.h b/examples/Plugins/WebViewPluginDemo.h index 17a9f36b60..7f56ca1471 100644 --- a/examples/Plugins/WebViewPluginDemo.h +++ b/examples/Plugins/WebViewPluginDemo.h @@ -438,9 +438,9 @@ public: private: WebViewPluginAudioProcessor& processorRef; - WebSliderRelay cutoffSliderRelay { webComponent, "cutoffSlider" }; - WebToggleButtonRelay muteToggleRelay { webComponent, "muteToggle" }; - WebComboBoxRelay filterTypeComboRelay { webComponent, "filterTypeCombo" }; + WebSliderRelay cutoffSliderRelay { "cutoffSlider" }; + WebToggleButtonRelay muteToggleRelay { "muteToggle" }; + WebComboBoxRelay filterTypeComboRelay { "filterTypeCombo" }; WebControlParameterIndexReceiver controlParameterIndexReceiver; diff --git a/modules/juce_gui_extra/misc/juce_WebControlRelays.cpp b/modules/juce_gui_extra/misc/juce_WebControlRelays.cpp index 0a2b8b09c6..e67c1590e2 100644 --- a/modules/juce_gui_extra/misc/juce_WebControlRelays.cpp +++ b/modules/juce_gui_extra/misc/juce_WebControlRelays.cpp @@ -37,9 +37,8 @@ namespace juce #if JUCE_WEB_BROWSER -WebSliderRelay::WebSliderRelay (WebBrowserComponent& browserIn, StringRef nameIn) - : browser (browserIn), - name (nameIn) +WebSliderRelay::WebSliderRelay (StringRef nameIn) + : name (nameIn) { } @@ -75,12 +74,25 @@ WebBrowserComponent::Options WebSliderRelay::buildOptions (const WebBrowserCompo { return initialOptions .withEventListener (eventId, [this] (auto object) { handleEvent (object); }) - .withInitialisationData ("__juce__sliders", name); + .withInitialisationData ("__juce__sliders", name) + .withWebViewLifetimeListener (this); } void WebSliderRelay::emitEvent (const var& payload) { - browser.emitEventIfBrowserIsVisible (eventId, payload); + if (browser != nullptr) + browser->emitEventIfBrowserIsVisible (eventId, payload); +} + +void WebSliderRelay::webViewConstructed (WebBrowserComponent* browserIn) +{ + browser = browserIn; + listeners.call (&Listener::initialUpdateRequested, this); +} + +void WebSliderRelay::webViewDestructed (WebBrowserComponent*) +{ + browser = nullptr; } void WebSliderRelay::handleEvent (const var& event) @@ -122,9 +134,8 @@ void WebSliderRelay::handleEvent (const var& event) } //============================================================================== -WebToggleButtonRelay::WebToggleButtonRelay ([[maybe_unused]] WebBrowserComponent& browserIn, StringRef nameIn) - : browser (browserIn), - name (nameIn) +WebToggleButtonRelay::WebToggleButtonRelay (StringRef nameIn) + : name (nameIn) { } @@ -154,12 +165,25 @@ WebBrowserComponent::Options WebToggleButtonRelay::buildOptions (const WebBrowse { return initialOptions .withEventListener (eventId, [this] (auto object) { handleEvent (object); }) - .withInitialisationData ("__juce__toggles", name); + .withInitialisationData ("__juce__toggles", name) + .withWebViewLifetimeListener (this); } void WebToggleButtonRelay::emitEvent (const var& payload) { - browser.emitEventIfBrowserIsVisible (eventId, payload); + if (browser != nullptr) + browser->emitEventIfBrowserIsVisible (eventId, payload); +} + +void WebToggleButtonRelay::webViewConstructed (WebBrowserComponent* browserIn) +{ + browser = browserIn; + listeners.call (&Listener::initialUpdateRequested); +} + +void WebToggleButtonRelay::webViewDestructed (WebBrowserComponent*) +{ + browser = nullptr; } void WebToggleButtonRelay::handleEvent (const var& event) @@ -187,9 +211,8 @@ void WebToggleButtonRelay::handleEvent (const var& event) } //============================================================================== -WebComboBoxRelay::WebComboBoxRelay ([[maybe_unused]] WebBrowserComponent& browserIn, StringRef nameIn) - : browser (browserIn), - name (nameIn) +WebComboBoxRelay::WebComboBoxRelay (StringRef nameIn) + : name (nameIn) { } @@ -219,12 +242,25 @@ WebBrowserComponent::Options WebComboBoxRelay::buildOptions (const WebBrowserCom { return initialOptions .withEventListener (eventId, [this] (auto object) { handleEvent (object); }) - .withInitialisationData ("__juce__comboBoxes", name); + .withInitialisationData ("__juce__comboBoxes", name) + .withWebViewLifetimeListener (this); } void WebComboBoxRelay::emitEvent (const var& payload) { - browser.emitEventIfBrowserIsVisible (eventId, payload); + if (browser != nullptr) + browser->emitEventIfBrowserIsVisible (eventId, payload); +} + +void WebComboBoxRelay::webViewConstructed (WebBrowserComponent* browserIn) +{ + browser = browserIn; + listeners.call (&Listener::initialUpdateRequested); +} + +void WebComboBoxRelay::webViewDestructed (WebBrowserComponent*) +{ + browser = nullptr; } void WebComboBoxRelay::handleEvent (const var& event) diff --git a/modules/juce_gui_extra/misc/juce_WebControlRelays.h b/modules/juce_gui_extra/misc/juce_WebControlRelays.h index 77ca8210da..9c0668ab98 100644 --- a/modules/juce_gui_extra/misc/juce_WebControlRelays.h +++ b/modules/juce_gui_extra/misc/juce_WebControlRelays.h @@ -62,14 +62,15 @@ namespace juce @tags{GUI} */ -class JUCE_API WebSliderRelay : public OptionsBuilder +class JUCE_API WebSliderRelay : public OptionsBuilder, + private WebViewLifetimeListener { public: /** Creating a relay will ensure that a Javascript object under the provided name will be available in the specified WebBrowserComponent's context. Use the frontend framework's getSliderState function with the same name to get a hold of this object. */ - WebSliderRelay (WebBrowserComponent& browserIn, StringRef nameIn); + WebSliderRelay (StringRef nameIn); //============================================================================== /** @internal */ @@ -98,8 +99,10 @@ public: private: void handleEvent (const var& event); + void webViewConstructed (WebBrowserComponent*) override; + void webViewDestructed (WebBrowserComponent*) override; - WebBrowserComponent& browser; + WebBrowserComponent* browser = nullptr; String name; float value{}; Identifier eventId { "__juce__slider" + name }; @@ -134,14 +137,15 @@ private: @tags{GUI} */ -class JUCE_API WebToggleButtonRelay : public OptionsBuilder +class JUCE_API WebToggleButtonRelay : public OptionsBuilder, + private WebViewLifetimeListener { public: /** Creating a relay will ensure that a Javascript object under the provided name will be available in the specified WebBrowserComponent's context. Use the frontend framework's getToggleState function with the same name to get a hold of this object. */ - WebToggleButtonRelay (WebBrowserComponent& browserIn, StringRef nameIn); + WebToggleButtonRelay (StringRef nameIn); //============================================================================== /** @internal */ @@ -169,8 +173,10 @@ public: private: void handleEvent (const var& event); + void webViewConstructed (WebBrowserComponent*) override; + void webViewDestructed (WebBrowserComponent*) override; - WebBrowserComponent& browser; + WebBrowserComponent* browser = nullptr; String name; Identifier eventId { "__juce__toggle" + name }; ListenerList listeners; @@ -204,14 +210,15 @@ private: @tags{GUI} */ -class JUCE_API WebComboBoxRelay : public OptionsBuilder +class JUCE_API WebComboBoxRelay : public OptionsBuilder, + private WebViewLifetimeListener { public: /** Creating a relay will ensure that a Javascript object under the provided name will be available in the specified WebBrowserComponent's context. Use the frontend framework's getComboBoxState function with the same name to get a hold of this object. */ - WebComboBoxRelay (WebBrowserComponent& browserIn, StringRef nameIn); + WebComboBoxRelay (StringRef nameIn); //============================================================================== /** @internal */ @@ -239,8 +246,10 @@ public: private: void handleEvent (const var& event); + void webViewConstructed (WebBrowserComponent*) override; + void webViewDestructed (WebBrowserComponent*) override; - WebBrowserComponent& browser; + WebBrowserComponent* browser = nullptr; String name; Identifier eventId { "__juce__comboBox" + name }; ListenerList listeners;