Browse Source

ComboBox focus fix. OpenGLComponent fixes. Result class safety tweaks.

tags/2021-05-28
Julian Storer 14 years ago
parent
commit
9301d072e3
8 changed files with 110 additions and 93 deletions
  1. +43
    -38
      juce_amalgamated.cpp
  2. +12
    -8
      juce_amalgamated.h
  3. +5
    -16
      src/core/juce_Result.cpp
  4. +9
    -0
      src/core/juce_Result.h
  5. +1
    -1
      src/core/juce_StandardHeader.h
  6. +1
    -0
      src/gui/components/controls/juce_ComboBox.cpp
  7. +37
    -23
      src/gui/components/special/juce_OpenGLComponent.cpp
  8. +2
    -7
      src/gui/components/special/juce_OpenGLComponent.h

+ 43
- 38
juce_amalgamated.cpp View File

@@ -1726,26 +1726,16 @@ const Result Result::fail (const String& errorMessage) noexcept
return Result (errorMessage.isEmpty() ? "Unknown Error" : errorMessage); return Result (errorMessage.isEmpty() ? "Unknown Error" : errorMessage);
} }


bool Result::wasOk() const noexcept
{
return errorMessage.isEmpty();
}

bool Result::failed() const noexcept
{
return errorMessage.isNotEmpty();
}

Result::operator bool() const noexcept
{
return errorMessage.isEmpty();
}

const String Result::getErrorMessage() const noexcept const String Result::getErrorMessage() const noexcept
{ {
return errorMessage; return errorMessage;
} }


bool Result::wasOk() const noexcept { return errorMessage.isEmpty(); }
Result::operator bool() const noexcept { return errorMessage.isEmpty(); }
bool Result::failed() const noexcept { return errorMessage.isNotEmpty(); }
bool Result::operator!() const noexcept { return errorMessage.isNotEmpty(); }

END_JUCE_NAMESPACE END_JUCE_NAMESPACE
/*** End of inlined file: juce_Result.cpp ***/ /*** End of inlined file: juce_Result.cpp ***/


@@ -48506,6 +48496,7 @@ void ComboBox::lookAndFeelChanged()
} }


addAndMakeVisible (label); addAndMakeVisible (label);
setWantsKeyboardFocus (! label->isEditable());


label->addListener (this); label->addListener (this);
label->addMouseListener (this, false); label->addMouseListener (this, false);
@@ -76902,6 +76893,14 @@ public:
while (owner.renderAndSwapBuffers() && ! threadShouldExit()) while (owner.renderAndSwapBuffers() && ! threadShouldExit())
owner.waitAfterSwapping(); owner.waitAfterSwapping();


owner.releaseOpenGLContext();

#if JUCE_LINUX
owner.deleteContext();
#else
owner.makeCurrentContextInactive();
#endif

triggerAsyncUpdate(); triggerAsyncUpdate();
} }


@@ -76933,17 +76932,13 @@ public:


void componentPeerChanged() void componentPeerChanged()
{ {
const ScopedLock sl (owner->getContextLock());
owner->stopRendering(); owner->stopRendering();
} }


void componentVisibilityChanged() void componentVisibilityChanged()
{ {
if (! owner->isShowing()) if (! owner->isShowing())
{
const ScopedLock sl (owner->getContextLock());
owner->stopRendering(); owner->stopRendering();
}
} }


private: private:
@@ -76955,7 +76950,8 @@ private:
OpenGLComponent::OpenGLComponent (const OpenGLType type_) OpenGLComponent::OpenGLComponent (const OpenGLType type_)
: type (type_), : type (type_),
contextToShareListsWith (nullptr), contextToShareListsWith (nullptr),
needToUpdateViewport (true)
needToUpdateViewport (true),
useThread (false)
{ {
setOpaque (true); setOpaque (true);
componentWatcher = new OpenGLComponentWatcher (this); componentWatcher = new OpenGLComponentWatcher (this);
@@ -76963,7 +76959,8 @@ OpenGLComponent::OpenGLComponent (const OpenGLType type_)


OpenGLComponent::~OpenGLComponent() OpenGLComponent::~OpenGLComponent()
{ {
deleteContext();
stopRendering();
renderThread = nullptr;
componentWatcher = nullptr; componentWatcher = nullptr;
} }


@@ -77079,14 +77076,29 @@ void OpenGLComponent::paint (Graphics&)
renderThread = new OpenGLComponentRenderThread (*this); renderThread = new OpenGLComponentRenderThread (*this);


if (! renderThread->isThreadRunning()) if (! renderThread->isThreadRunning())
{
renderThread->handleUpdateNowIfNeeded(); // may still be shutting down as well

#if ! JUCE_LINUX
// Except for Linux, create the context etc. first
const ScopedLock sl (contextLock);

if (makeCurrentContextActive()) // Make active just to create
makeCurrentContextInactive();
#endif

renderThread->startThread (6); renderThread->startThread (6);
}


// fall-through and update the masking region // fall-through and update the masking region
} }
else else
{ {
if (renderThread != nullptr && renderThread->isThreadRunning())
renderThread->stopThread (5000);
if (renderThread != nullptr)
{
stopRendering();
renderThread = nullptr;
}


if (! renderAndSwapBuffers()) if (! renderAndSwapBuffers())
return; return;
@@ -77127,26 +77139,19 @@ void OpenGLComponent::waitAfterSwapping()
Thread::sleep (20); Thread::sleep (20);
} }


bool OpenGLComponent::stopRendering()
void OpenGLComponent::stopRendering()
{ {
const ScopedLock sl (contextLock);
if (renderThread != nullptr)
renderThread->stopThread (5000);


if (! makeCurrentContextActive())
return false;

releaseOpenGLContext(); // callback to allow for shutdown

if (renderThread != nullptr && Thread::getCurrentThread() == renderThread)
if (context != nullptr && makeCurrentContextActive())
{ {
// make the context inactive - if we're on a thread, this will release the context,
// so the main thread can take it and do shutdown
// On Linux, when threaded, context will have already been cleared
const ScopedLock sl (contextLock);


makeCurrentContextInactive();
releaseOpenGLContext();
deleteContext();
} }
else if (context != nullptr)
context->deleteContext();

return true;
} }


void OpenGLComponent::internalRepaint (int x, int y, int w, int h) void OpenGLComponent::internalRepaint (int x, int y, int w, int h)


+ 12
- 8
juce_amalgamated.h View File

@@ -73,7 +73,7 @@ namespace JuceDummyNamespace {}
*/ */
#define JUCE_MAJOR_VERSION 1 #define JUCE_MAJOR_VERSION 1
#define JUCE_MINOR_VERSION 53 #define JUCE_MINOR_VERSION 53
#define JUCE_BUILDNUMBER 77
#define JUCE_BUILDNUMBER 78


/** Current Juce version number. /** Current Juce version number.


@@ -12059,6 +12059,11 @@ public:
*/ */
operator bool() const noexcept; operator bool() const noexcept;


/** Returns true if this result indicates a failure.
This is equivalent to calling failed().
*/
bool operator!() const noexcept;

/** Returns the error message that was set when this result was created. /** Returns the error message that was set when this result was created.
For a successful result, this will be an empty string; For a successful result, this will be an empty string;
*/ */
@@ -12074,6 +12079,10 @@ private:
String errorMessage; String errorMessage;


explicit Result (const String& errorMessage) noexcept; explicit Result (const String& errorMessage) noexcept;

// These casts are private to prevent people trying to use the Result object in numeric contexts
operator int() const;
operator void*() const;
}; };


#endif // __JUCE_RESULT_JUCEHEADER__ #endif // __JUCE_RESULT_JUCEHEADER__
@@ -63926,15 +63935,9 @@ public:


Used when rendering is running on a thread. The default is 20 millseconds, giving Used when rendering is running on a thread. The default is 20 millseconds, giving
a nominal frame rate of just under 50 fps. a nominal frame rate of just under 50 fps.
*/
*/
virtual void waitAfterSwapping(); virtual void waitAfterSwapping();


/** Stop Rendering.

Use to shut down an openGLComponent properly, whether on a thread or not.
*/
virtual bool stopRendering();

/** This returns a critical section that can be used to lock the current context. /** This returns a critical section that can be used to lock the current context.


Because the context that is used by this component can change, e.g. when the Because the context that is used by this component can change, e.g. when the
@@ -63980,6 +63983,7 @@ private:
OpenGLContext* createContext(); OpenGLContext* createContext();
void updateContextPosition(); void updateContextPosition();
void internalRepaint (int x, int y, int w, int h); void internalRepaint (int x, int y, int w, int h);
void stopRendering();


JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (OpenGLComponent); JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (OpenGLComponent);
}; };


+ 5
- 16
src/core/juce_Result.cpp View File

@@ -67,26 +67,15 @@ const Result Result::fail (const String& errorMessage) noexcept
return Result (errorMessage.isEmpty() ? "Unknown Error" : errorMessage); return Result (errorMessage.isEmpty() ? "Unknown Error" : errorMessage);
} }
//==============================================================================
bool Result::wasOk() const noexcept
{
return errorMessage.isEmpty();
}
bool Result::failed() const noexcept
{
return errorMessage.isNotEmpty();
}
Result::operator bool() const noexcept
{
return errorMessage.isEmpty();
}
const String Result::getErrorMessage() const noexcept const String Result::getErrorMessage() const noexcept
{ {
return errorMessage; return errorMessage;
} }
bool Result::wasOk() const noexcept { return errorMessage.isEmpty(); }
Result::operator bool() const noexcept { return errorMessage.isEmpty(); }
bool Result::failed() const noexcept { return errorMessage.isNotEmpty(); }
bool Result::operator!() const noexcept { return errorMessage.isNotEmpty(); }
END_JUCE_NAMESPACE END_JUCE_NAMESPACE

+ 9
- 0
src/core/juce_Result.h View File

@@ -85,6 +85,11 @@ public:
*/ */
operator bool() const noexcept; operator bool() const noexcept;
/** Returns true if this result indicates a failure.
This is equivalent to calling failed().
*/
bool operator!() const noexcept;
/** Returns the error message that was set when this result was created. /** Returns the error message that was set when this result was created.
For a successful result, this will be an empty string; For a successful result, this will be an empty string;
*/ */
@@ -101,6 +106,10 @@ private:
String errorMessage; String errorMessage;
explicit Result (const String& errorMessage) noexcept; explicit Result (const String& errorMessage) noexcept;
// These casts are private to prevent people trying to use the Result object in numeric contexts
operator int() const;
operator void*() const;
}; };


+ 1
- 1
src/core/juce_StandardHeader.h View File

@@ -33,7 +33,7 @@
*/ */
#define JUCE_MAJOR_VERSION 1 #define JUCE_MAJOR_VERSION 1
#define JUCE_MINOR_VERSION 53 #define JUCE_MINOR_VERSION 53
#define JUCE_BUILDNUMBER 77
#define JUCE_BUILDNUMBER 78
/** Current Juce version number. /** Current Juce version number.


+ 1
- 0
src/gui/components/controls/juce_ComboBox.cpp View File

@@ -432,6 +432,7 @@ void ComboBox::lookAndFeelChanged()
} }
addAndMakeVisible (label); addAndMakeVisible (label);
setWantsKeyboardFocus (! label->isEditable());
label->addListener (this); label->addListener (this);
label->addMouseListener (this, false); label->addMouseListener (this, false);


+ 37
- 23
src/gui/components/special/juce_OpenGLComponent.cpp View File

@@ -148,6 +148,14 @@ public:
while (owner.renderAndSwapBuffers() && ! threadShouldExit()) while (owner.renderAndSwapBuffers() && ! threadShouldExit())
owner.waitAfterSwapping(); owner.waitAfterSwapping();
owner.releaseOpenGLContext();
#if JUCE_LINUX
owner.deleteContext();
#else
owner.makeCurrentContextInactive();
#endif
triggerAsyncUpdate(); triggerAsyncUpdate();
} }
@@ -184,17 +192,13 @@ public:
void componentPeerChanged() void componentPeerChanged()
{ {
const ScopedLock sl (owner->getContextLock());
owner->stopRendering(); owner->stopRendering();
} }
void componentVisibilityChanged() void componentVisibilityChanged()
{ {
if (! owner->isShowing()) if (! owner->isShowing())
{
const ScopedLock sl (owner->getContextLock());
owner->stopRendering(); owner->stopRendering();
}
} }
//============================================================================== //==============================================================================
@@ -208,7 +212,8 @@ private:
OpenGLComponent::OpenGLComponent (const OpenGLType type_) OpenGLComponent::OpenGLComponent (const OpenGLType type_)
: type (type_), : type (type_),
contextToShareListsWith (nullptr), contextToShareListsWith (nullptr),
needToUpdateViewport (true)
needToUpdateViewport (true),
useThread (false)
{ {
setOpaque (true); setOpaque (true);
componentWatcher = new OpenGLComponentWatcher (this); componentWatcher = new OpenGLComponentWatcher (this);
@@ -216,7 +221,8 @@ OpenGLComponent::OpenGLComponent (const OpenGLType type_)
OpenGLComponent::~OpenGLComponent() OpenGLComponent::~OpenGLComponent()
{ {
deleteContext();
stopRendering();
renderThread = nullptr;
componentWatcher = nullptr; componentWatcher = nullptr;
} }
@@ -332,14 +338,29 @@ void OpenGLComponent::paint (Graphics&)
renderThread = new OpenGLComponentRenderThread (*this); renderThread = new OpenGLComponentRenderThread (*this);
if (! renderThread->isThreadRunning()) if (! renderThread->isThreadRunning())
{
renderThread->handleUpdateNowIfNeeded(); // may still be shutting down as well
#if ! JUCE_LINUX
// Except for Linux, create the context etc. first
const ScopedLock sl (contextLock);
if (makeCurrentContextActive()) // Make active just to create
makeCurrentContextInactive();
#endif
renderThread->startThread (6); renderThread->startThread (6);
}
// fall-through and update the masking region // fall-through and update the masking region
} }
else else
{ {
if (renderThread != nullptr && renderThread->isThreadRunning())
renderThread->stopThread (5000);
if (renderThread != nullptr)
{
stopRendering();
renderThread = nullptr;
}
if (! renderAndSwapBuffers()) if (! renderAndSwapBuffers())
return; return;
@@ -380,26 +401,19 @@ void OpenGLComponent::waitAfterSwapping()
Thread::sleep (20); Thread::sleep (20);
} }
bool OpenGLComponent::stopRendering()
void OpenGLComponent::stopRendering()
{ {
const ScopedLock sl (contextLock);
if (! makeCurrentContextActive())
return false;
if (renderThread != nullptr)
renderThread->stopThread (5000);
releaseOpenGLContext(); // callback to allow for shutdown
if (renderThread != nullptr && Thread::getCurrentThread() == renderThread)
if (context != nullptr && makeCurrentContextActive())
{ {
// make the context inactive - if we're on a thread, this will release the context,
// so the main thread can take it and do shutdown
// On Linux, when threaded, context will have already been cleared
const ScopedLock sl (contextLock);
makeCurrentContextInactive();
releaseOpenGLContext();
deleteContext();
} }
else if (context != nullptr)
context->deleteContext();
return true;
} }
void OpenGLComponent::internalRepaint (int x, int y, int w, int h) void OpenGLComponent::internalRepaint (int x, int y, int w, int h)


+ 2
- 7
src/gui/components/special/juce_OpenGLComponent.h View File

@@ -346,15 +346,9 @@ public:
Used when rendering is running on a thread. The default is 20 millseconds, giving Used when rendering is running on a thread. The default is 20 millseconds, giving
a nominal frame rate of just under 50 fps. a nominal frame rate of just under 50 fps.
*/
*/
virtual void waitAfterSwapping(); virtual void waitAfterSwapping();
/** Stop Rendering.
Use to shut down an openGLComponent properly, whether on a thread or not.
*/
virtual bool stopRendering();
/** This returns a critical section that can be used to lock the current context. /** This returns a critical section that can be used to lock the current context.
Because the context that is used by this component can change, e.g. when the Because the context that is used by this component can change, e.g. when the
@@ -403,6 +397,7 @@ private:
OpenGLContext* createContext(); OpenGLContext* createContext();
void updateContextPosition(); void updateContextPosition();
void internalRepaint (int x, int y, int w, int h); void internalRepaint (int x, int y, int w, int h);
void stopRendering();
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (OpenGLComponent); JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (OpenGLComponent);
}; };


Loading…
Cancel
Save