Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix bad interrupt handling in Javascript #1447

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
d49fee0
Add support for types int64, double, T, F, Nil and Impulse
benkuper Jun 22, 2024
d2cf768
Add IP and Port detection option in OSCReceiver
benkuper Jun 22, 2024
669ac2c
added allow special chars in address
benkuper Jun 22, 2024
4f98d0e
added broadcast and binding options
benkuper Jun 22, 2024
7972d8f
respect text alignment
benkuper Jun 22, 2024
d1d2778
Virtual functions in viewport to be fully overridable from child class
benkuper Jun 22, 2024
61e3678
Merge branch 'juce8_feature/Viewport_Virtual_Functions' into juce8_local
benkuper Jun 22, 2024
cd04042
Merge branch 'juce8_feature/OSCTypes_improvements' into juce8_local
benkuper Jun 22, 2024
18937da
Merge branch 'juce8_feature/OSC_Extra_Options' into juce8_local
benkuper Jun 22, 2024
5bb41f0
fix double declaration getBool()
benkuper Jun 22, 2024
619251e
Merge branch 'juce8_feature/OSCTypes_improvements' into juce8_local
benkuper Jun 22, 2024
747d788
add variant.isVoid() check in fromVar function
benkuper Jun 23, 2024
c3b5304
Merge branch 'juce8_feature/Javascript_fromVar_Void_support' into juc…
benkuper Jun 23, 2024
fe16f51
restructure to avoid warning when using allow special chars option
benkuper Jun 23, 2024
8261d8c
Merge branch 'juce8_feature/OSC_Extra_Options' into juce8_local
benkuper Jun 23, 2024
15ea766
Merge remote-tracking branch 'juce-framework/develop' into juce8_local
benkuper Jun 25, 2024
10471b3
Revert "add variant.isVoid() check in fromVar function"
benkuper Jul 5, 2024
3ed25d4
Merge branch 'develop' into juce8_local
benkuper Jul 5, 2024
a63f1b4
Merge remote-tracking branch 'juce-framework/develop' into juce8_local
benkuper Jul 9, 2024
7b48d3a
Merge remote-tracking branch 'juce-framework/develop' into juce8_local
benkuper Aug 28, 2024
2c68aad
Merge remote-tracking branch 'juce-framework/develop' into juce8_local
benkuper Oct 8, 2024
504288f
Merge remote-tracking branch 'juce-framework/develop' into juce8_local
benkuper Oct 9, 2024
9bf02b2
remove JS_GPN_ENUM_ONLY to the flags when retrieving properties.
benkuper Oct 9, 2024
13d9150
Merge branch 'bugfix/javascriptIgnoredProperties' into juce8_local
benkuper Oct 9, 2024
9ad0724
Merge remote-tracking branch 'juce-framework/develop' into juce8_local
benkuper Oct 11, 2024
3b3fd72
Merge remote-tracking branch 'juce-framework/develop' into juce8_local
benkuper Oct 16, 2024
2d5ee0f
keep track of last callFunction time to avoid bad interrupt
benkuper Oct 17, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 14 additions & 5 deletions modules/juce_core/javascript/juce_Javascript.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -364,7 +364,7 @@ static var tryQuickJSToJuce (const qjs::QuickJSContext::ValuePtr& ptr,
JSPropertyEnum* properties = nullptr;
uint32_t numProps = 0;

if (JS_GetOwnPropertyNames (ptr.context, &properties, &numProps, obj.get(), JS_GPN_STRING_MASK | JS_GPN_ENUM_ONLY) != 0
if (JS_GetOwnPropertyNames (ptr.context, &properties, &numProps, obj.get(), JS_GPN_STRING_MASK) != 0
|| properties == nullptr)
{
return new DynamicObject;
Expand Down Expand Up @@ -692,12 +692,14 @@ class JavascriptEngine::Impl
{
shouldStop = false;

engine.setInterruptHandler ([this, maxExecTime, started = Time::getMillisecondCounterHiRes()]()
timeAtLastStart = Time::getMillisecondCounterHiRes();

engine.setInterruptHandler ([this, maxExecTime]()
{
if (shouldStop)
return 1;

const auto elapsed = RelativeTime::milliseconds ((int64) (Time::getMillisecondCounterHiRes() - started));
const auto elapsed = RelativeTime::milliseconds ((int64) (Time::getMillisecondCounterHiRes() - timeAtLastStart));
return elapsed > maxExecTime ? 1 : 0;
});

Expand All @@ -723,8 +725,10 @@ class JavascriptEngine::Impl
return result;
}

var callFunction (const Identifier& function, const var::NativeFunctionArgs& args, Result* errorMessage)
var callFunction (const Identifier& function, const var::NativeFunctionArgs& args, Result* errorMessage, RelativeTime maxExecTime)
{
timeAtLastStart = Time::getMillisecondCounterHiRes();

auto* ctx = engine.getQuickJSContext();
const auto functionStr = function.toString();

Expand Down Expand Up @@ -771,6 +775,11 @@ class JavascriptEngine::Impl
//==============================================================================
detail::QuickJSWrapper engine;
std::atomic<bool> shouldStop = false;

/** This value stores the last time a execute, eval or callFunction has been started.
This allows to update the interrupt check when using callFunction() after execute() without having to always override the interrupt handler
*/
double timeAtLastStart = 0;
};

//==============================================================================
Expand Down Expand Up @@ -801,7 +810,7 @@ var JavascriptEngine::callFunction (const Identifier& function,
const var::NativeFunctionArgs& args,
Result* errorMessage)
{
return impl->callFunction (function, args, errorMessage);
return impl->callFunction (function, args, errorMessage, maximumExecutionTime);
}

void JavascriptEngine::stop() noexcept
Expand Down
84 changes: 42 additions & 42 deletions modules/juce_gui_basics/layout/juce_Viewport.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ class JUCE_API Viewport : public Component,
explicit Viewport (const String& componentName = String());

/** Destructor. */
~Viewport() override;
virtual ~Viewport() override;

//==============================================================================
/** Sets the component that this viewport will contain and scroll around.
Expand All @@ -82,14 +82,14 @@ class JUCE_API Viewport : public Component,
of the component
@see getViewedComponent
*/
void setViewedComponent (Component* newViewedComponent,
virtual void setViewedComponent (Component* newViewedComponent,
bool deleteComponentWhenNoLongerNeeded = true);

/** Returns the component that's currently being used inside the Viewport.

@see setViewedComponent
*/
Component* getViewedComponent() const noexcept { return contentComp.get(); }
virtual Component* getViewedComponent() const noexcept { return contentComp.get(); }

//==============================================================================
/** Changes the position of the viewed component.
Expand All @@ -102,7 +102,7 @@ class JUCE_API Viewport : public Component,

@see getViewPositionX, getViewPositionY, setViewPositionProportionately
*/
void setViewPosition (int xPixelsOffset, int yPixelsOffset);
virtual void setViewPosition (int xPixelsOffset, int yPixelsOffset);

/** Changes the position of the viewed component.

Expand All @@ -114,7 +114,7 @@ class JUCE_API Viewport : public Component,

@see getViewPositionX, getViewPositionY, setViewPositionProportionately
*/
void setViewPosition (Point<int> newPosition);
virtual void setViewPosition (Point<int> newPosition);

/** Changes the view position as a proportion of the distance it can move.

Expand All @@ -123,7 +123,7 @@ class JUCE_API Viewport : public Component,
to the right as it's possible to go whilst keeping the child component
on-screen.
*/
void setViewPositionProportionately (double proportionX, double proportionY);
virtual void setViewPositionProportionately (double proportionX, double proportionY);

/** If the specified position is at the edges of the viewport, this method scrolls
the viewport to bring that position nearer to the centre.
Expand All @@ -140,51 +140,51 @@ class JUCE_API Viewport : public Component,
to scroll by.
@returns true if the viewport was scrolled
*/
bool autoScroll (int mouseX, int mouseY, int distanceFromEdge, int maximumSpeed);
virtual bool autoScroll (int mouseX, int mouseY, int distanceFromEdge, int maximumSpeed);

/** Returns the position within the child component of the top-left of its visible area. */
Point<int> getViewPosition() const noexcept { return lastVisibleArea.getPosition(); }
virtual Point<int> getViewPosition() const noexcept { return lastVisibleArea.getPosition(); }

/** Returns the visible area of the child component, relative to its top-left */
Rectangle<int> getViewArea() const noexcept { return lastVisibleArea; }
virtual Rectangle<int> getViewArea() const noexcept { return lastVisibleArea; }

/** Returns the position within the child component of the top-left of its visible area.
@see getViewWidth, setViewPosition
*/
int getViewPositionX() const noexcept { return lastVisibleArea.getX(); }
virtual int getViewPositionX() const noexcept { return lastVisibleArea.getX(); }

/** Returns the position within the child component of the top-left of its visible area.
@see getViewHeight, setViewPosition
*/
int getViewPositionY() const noexcept { return lastVisibleArea.getY(); }
virtual int getViewPositionY() const noexcept { return lastVisibleArea.getY(); }

/** Returns the width of the visible area of the child component.

This may be less than the width of this Viewport if there's a vertical scrollbar
or if the child component is itself smaller.
*/
int getViewWidth() const noexcept { return lastVisibleArea.getWidth(); }
virtual int getViewWidth() const noexcept { return lastVisibleArea.getWidth(); }

/** Returns the height of the visible area of the child component.

This may be less than the height of this Viewport if there's a horizontal scrollbar
or if the child component is itself smaller.
*/
int getViewHeight() const noexcept { return lastVisibleArea.getHeight(); }
virtual int getViewHeight() const noexcept { return lastVisibleArea.getHeight(); }

/** Returns the width available within this component for the contents.

This will be the width of the viewport component minus the width of a
vertical scrollbar (if visible).
*/
int getMaximumVisibleWidth() const;
virtual int getMaximumVisibleWidth() const;

/** Returns the height available within this component for the contents.

This will be the height of the viewport component minus the space taken up
by a horizontal scrollbar (if visible).
*/
int getMaximumVisibleHeight() const;
virtual int getMaximumVisibleHeight() const;

//==============================================================================
/** Callback method that is called when the visible area changes.
Expand All @@ -207,7 +207,7 @@ class JUCE_API Viewport : public Component,
mouse-wheel scrolling even when there the scrollbars are hidden. When the
scrollbars are visible, these parameters are ignored.
*/
void setScrollBarsShown (bool showVerticalScrollbarIfNeeded,
virtual void setScrollBarsShown (bool showVerticalScrollbarIfNeeded,
bool showHorizontalScrollbarIfNeeded,
bool allowVerticalScrollingWithoutScrollbar = false,
bool allowHorizontalScrollingWithoutScrollbar = false);
Expand All @@ -222,63 +222,63 @@ class JUCE_API Viewport : public Component,
will appear at the bottom of the view port's content (this is the default),
otherwise it will be at the top.
*/
void setScrollBarPosition (bool verticalScrollbarOnRight,
virtual void setScrollBarPosition (bool verticalScrollbarOnRight,
bool horizontalScrollbarAtBottom);

/** True if the vertical scrollbar will appear on the right side of the content */
bool isVerticalScrollbarOnTheRight() const noexcept { return vScrollbarRight; }
virtual bool isVerticalScrollbarOnTheRight() const noexcept { return vScrollbarRight; }

/** True if the horizontal scrollbar will appear at the bottom of the content */
bool isHorizontalScrollbarAtBottom() const noexcept { return hScrollbarBottom; }
virtual bool isHorizontalScrollbarAtBottom() const noexcept { return hScrollbarBottom; }

/** True if the vertical scrollbar is enabled.
@see setScrollBarsShown
*/
bool isVerticalScrollBarShown() const noexcept { return showVScrollbar; }
virtual bool isVerticalScrollBarShown() const noexcept { return showVScrollbar; }

/** True if the horizontal scrollbar is enabled.
@see setScrollBarsShown
*/
bool isHorizontalScrollBarShown() const noexcept { return showHScrollbar; }
virtual bool isHorizontalScrollBarShown() const noexcept { return showHScrollbar; }

/** Changes the width of the scrollbars.
If this isn't specified, the default width from the LookAndFeel class will be used.
@see LookAndFeel::getDefaultScrollbarWidth
*/
void setScrollBarThickness (int thickness);
virtual void setScrollBarThickness (int thickness);

/** Returns the thickness of the scrollbars.
@see setScrollBarThickness
*/
int getScrollBarThickness() const;
virtual int getScrollBarThickness() const;

/** Changes the distance that a single-step click on a scrollbar button
will move the viewport.
*/
void setSingleStepSizes (int stepX, int stepY);
virtual void setSingleStepSizes (int stepX, int stepY);

/** Returns a reference to the scrollbar component being used.
Handy if you need to customise the bar somehow.
*/
ScrollBar& getVerticalScrollBar() noexcept { return *verticalScrollBar; }
virtual ScrollBar& getVerticalScrollBar() noexcept { return *verticalScrollBar; }

/** Returns a reference to the scrollbar component being used.
Handy if you need to customise the bar somehow.
*/
ScrollBar& getHorizontalScrollBar() noexcept { return *horizontalScrollBar; }
virtual ScrollBar& getHorizontalScrollBar() noexcept { return *horizontalScrollBar; }

/** Re-instantiates the scrollbars, which is only really useful if you've overridden createScrollBarComponent(). */
void recreateScrollbars();
virtual void recreateScrollbars();

/** True if there's any off-screen content that could be scrolled vertically,
or false if everything is currently visible.
*/
bool canScrollVertically() const noexcept;
virtual bool canScrollVertically() const noexcept;

/** True if there's any off-screen content that could be scrolled horizontally,
or false if everything is currently visible.
*/
bool canScrollHorizontally() const noexcept;
virtual bool canScrollHorizontally() const noexcept;

/** Enables or disables drag-to-scroll functionality for mouse sources in the viewport.

Expand All @@ -287,14 +287,14 @@ class JUCE_API Viewport : public Component,
method.
*/
[[deprecated ("Use setScrollOnDragMode instead.")]]
void setScrollOnDragEnabled (bool shouldScrollOnDrag)
virtual void setScrollOnDragEnabled (bool shouldScrollOnDrag)
{
setScrollOnDragMode (shouldScrollOnDrag ? ScrollOnDragMode::all : ScrollOnDragMode::never);
}

/** Returns true if drag-to-scroll functionality is enabled for mouse input sources. */
[[deprecated ("Use getScrollOnDragMode instead.")]]
bool isScrollOnDragEnabled() const noexcept { return getScrollOnDragMode() == ScrollOnDragMode::all; }
virtual bool isScrollOnDragEnabled() const noexcept { return getScrollOnDragMode() == ScrollOnDragMode::all; }

enum class ScrollOnDragMode
{
Expand All @@ -309,33 +309,33 @@ class JUCE_API Viewport : public Component,
user is drag-scrolling, you can disable this with the Component::setViewportIgnoreDragFlag()
method.
*/
void setScrollOnDragMode (ScrollOnDragMode scrollOnDragMode);
virtual void setScrollOnDragMode (ScrollOnDragMode scrollOnDragMode);

/** Returns the current scroll-on-drag mode. */
ScrollOnDragMode getScrollOnDragMode() const { return scrollOnDragMode; }
virtual ScrollOnDragMode getScrollOnDragMode() const { return scrollOnDragMode; }

/** Returns true if the user is currently dragging-to-scroll.
@see setScrollOnDragEnabled
*/
bool isCurrentlyScrollingOnDrag() const noexcept;
virtual bool isCurrentlyScrollingOnDrag() const noexcept;

//==============================================================================
/** @internal */
void resized() override;
virtual void resized() override;
/** @internal */
void scrollBarMoved (ScrollBar*, double newRangeStart) override;
virtual void scrollBarMoved (ScrollBar*, double newRangeStart) override;
/** @internal */
void mouseWheelMove (const MouseEvent&, const MouseWheelDetails&) override;
virtual void mouseWheelMove (const MouseEvent&, const MouseWheelDetails&) override;
/** @internal */
void mouseDown (const MouseEvent& e) override;
virtual void mouseDown (const MouseEvent& e) override;
/** @internal */
bool keyPressed (const KeyPress&) override;
virtual bool keyPressed (const KeyPress&) override;
/** @internal */
void componentMovedOrResized (Component&, bool wasMoved, bool wasResized) override;
virtual void componentMovedOrResized (Component&, bool wasMoved, bool wasResized) override;
/** @internal */
void lookAndFeelChanged() override;
virtual void lookAndFeelChanged() override;
/** @internal */
bool useMouseWheelMoveIfNeeded (const MouseEvent&, const MouseWheelDetails&);
virtual bool useMouseWheelMoveIfNeeded (const MouseEvent&, const MouseWheelDetails&);
/** @internal */
static bool respondsToKey (const KeyPress&);

Expand Down
29 changes: 29 additions & 0 deletions modules/juce_osc/juce_osc.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,35 @@
#pragma once
#define JUCE_OSC_H_INCLUDED

/** Config: JUCE_ALLOW_SPECIAL_CHARS_IN_ADDRESS
Enables the use of characters in adress that are not allowed by the OSC specifications (like spaces), but that are used
by some applications anyway (e.g. /my spaced/address)
*/
#ifndef JUCE_ALLOW_SPECIAL_CHARS_IN_ADDRESS
#define JUCE_ALLOW_SPECIAL_CHARS_IN_ADDRESS 0
#endif

/** Config: JUCE_ENABLE_BROADCAST_BY_DEFAULT
Automatically enables broadcast on bound port in OSCReceiver
*/
#ifndef JUCE_ENABLE_BROADCAST_BY_DEFAULT
#define JUCE_ENABLE_BROADCAST_BY_DEFAULT 0
#endif

/** Config: JUCE_EXCLUSIVE_BINDING_BY_DEFAULT
If enabled, this will make the binding of this port exclusive, so no other process can bind it.
*/
#ifndef JUCE_EXCLUSIVE_BINDING_BY_DEFAULT
#define JUCE_EXCLUSIVE_BINDING_BY_DEFAULT 0
#endif

/** Config: JUCE_IP_AND_PORT_DETECTION
If enabled, this will add remoteIP and remotePort variables to osc packets, corresponding to the sender's ip and port when receiving messages.
*/
#ifndef JUCE_IP_AND_PORT_DETECTION
#define JUCE_IP_AND_PORT_DETECTION 0
#endif

#include <juce_core/juce_core.h>
#include <juce_events/juce_events.h>

Expand Down
11 changes: 9 additions & 2 deletions modules/juce_osc/osc/juce_OSCAddress.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -283,10 +283,17 @@ namespace
return c >= ' ' && c <= '~';
}

static bool isDisallowedChar (juce_wchar c) noexcept
#if JUCE_ALLOW_SPECIAL_CHARS_IN_ADDRESS
static bool isDisallowedChar (juce_wchar) noexcept
{
return CharPointer_ASCII (Traits::getDisallowedChars()).indexOf (c, false) >= 0;
return false;
}
#else
static bool isDisallowedChar(juce_wchar c) noexcept
{
return CharPointer_ASCII(Traits::getDisallowedChars()).indexOf(c, false) >= 0;
}
#endif

static bool containsOnlyAllowedPrintableASCIIChars (const String& string) noexcept
{
Expand Down
Loading