Browse Source

Removed need for std::function in order to use MessageManager::callAsync(). Used it to modernise a few bits of old code.

tags/2021-05-28
jules 8 years ago
parent
commit
60e9231fb1
10 changed files with 105 additions and 181 deletions
  1. +3
    -5
      modules/juce_audio_utils/gui/juce_MidiKeyboardComponent.cpp
  2. +7
    -7
      modules/juce_core/network/juce_URL.h
  3. +4
    -1
      modules/juce_events/messages/juce_CallbackMessage.h
  4. +7
    -29
      modules/juce_events/messages/juce_MessageManager.cpp
  5. +18
    -8
      modules/juce_events/messages/juce_MessageManager.h
  6. +19
    -41
      modules/juce_gui_basics/components/juce_Component.cpp
  7. +13
    -30
      modules/juce_gui_basics/mouse/juce_DragAndDropContainer.cpp
  8. +3
    -7
      modules/juce_gui_basics/widgets/juce_TreeView.cpp
  9. +28
    -50
      modules/juce_gui_basics/windows/juce_ComponentPeer.cpp
  10. +3
    -3
      modules/juce_gui_basics/windows/juce_ComponentPeer.h

+ 3
- 5
modules/juce_audio_utils/gui/juce_MidiKeyboardComponent.cpp View File

@@ -853,11 +853,9 @@ void MidiKeyboardComponent::timerCallback()
if (shouldCheckMousePos)
{
const Array<MouseInputSource>& mouseSources = Desktop::getInstance().getMouseSources();
for (MouseInputSource* mi = mouseSources.begin(), * const e = mouseSources.end(); mi != e; ++mi)
if (mi->getComponentUnderMouse() == this || isParentOf (mi->getComponentUnderMouse()))
updateNoteUnderMouse (getLocalPoint (nullptr, mi->getScreenPosition()).roundToInt(), mi->isDragging(), mi->getIndex());
for (auto& ms : Desktop::getInstance().getMouseSources())
if (ms.getComponentUnderMouse() == this || isParentOf (ms.getComponentUnderMouse()))
updateNoteUnderMouse (getLocalPoint (nullptr, ms.getScreenPosition()).roundToInt(), ms.isDragging(), ms.getIndex());
}
}


+ 7
- 7
modules/juce_core/network/juce_URL.h View File

@@ -393,14 +393,14 @@ public:
/** Download the URL to a file.
This method attempts to download the URL to a given file location.
This method attempts to download the URL to a given file location.
Using this method to download files on mobile is less flexible but more reliable
than using createInputStream or WebInputStreams as it will attempt to download the file
using a native OS background network task. Such tasks automatically deal with
network re-connections and continuing your download while your app is suspended but are
limited to simple GET requests.
*/
Using this method to download files on mobile is less flexible but more reliable
than using createInputStream or WebInputStreams as it will attempt to download the file
using a native OS background network task. Such tasks automatically deal with
network re-connections and continuing your download while your app is suspended but are
limited to simple GET requests.
*/
DownloadTask* downloadToFile (const File& targetLocation,
String extraHeaders = String(),
DownloadTask::Listener* listener = nullptr);


+ 4
- 1
modules/juce_events/messages/juce_CallbackMessage.h View File

@@ -46,7 +46,10 @@
Always create a new instance of a CallbackMessage on the heap, as it will be
deleted automatically after the message has been delivered.
@see MessageManager, MessageListener, ActionListener, ChangeListener
Note that this class was essential back in the days before C++11, but in modern
times you may prefer to use MessageManager::callAsync() with a lambda.
@see MessageManager::callAsync, MessageListener, ActionListener, ChangeListener
*/
class JUCE_API CallbackMessage : public MessageManager::MessageBase
{


+ 7
- 29
modules/juce_events/messages/juce_MessageManager.cpp View File

@@ -29,10 +29,7 @@
*/
MessageManager::MessageManager() noexcept
: quitMessagePosted (false),
quitMessageReceived (false),
messageThreadId (Thread::getCurrentThreadId()),
threadWithLock (0)
: messageThreadId (Thread::getCurrentThreadId())
{
if (JUCEApplicationBase::isStandaloneApp())
Thread::setCurrentThreadName ("Juce Message Thread");
@@ -74,7 +71,7 @@ void MessageManager::deleteInstance()
//==============================================================================
bool MessageManager::MessageBase::post()
{
MessageManager* const mm = MessageManager::instance;
auto* mm = MessageManager::instance;
if (mm == nullptr || mm->quitMessagePosted || ! postMessageToSystemQueue (this))
{
@@ -118,7 +115,7 @@ public:
void messageCallback() override
{
if (MessageManager* const mm = MessageManager::instance)
if (auto* mm = MessageManager::instance)
mm->quitMessageReceived = true;
}
@@ -148,31 +145,12 @@ void MessageManager::stopDispatchLoop()
#endif
//==============================================================================
#if JUCE_COMPILER_SUPPORTS_LAMBDAS
struct AsyncFunction : private MessageManager::MessageBase
{
AsyncFunction (std::function<void(void)> f) : fn (f) { post(); }
private:
std::function<void(void)> fn;
void messageCallback() override { fn(); }
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AsyncFunction)
};
void MessageManager::callAsync (std::function<void(void)> f)
{
new AsyncFunction (f);
}
#endif
//==============================================================================
class AsyncFunctionCallback : public MessageManager::MessageBase
{
public:
AsyncFunctionCallback (MessageCallbackFunction* const f, void* const param)
: result (nullptr), func (f), parameter (param)
: func (f), parameter (param)
{}
void messageCallback() override
@@ -182,7 +160,7 @@ public:
}
WaitableEvent finished;
void* volatile result;
void* volatile result = nullptr;
private:
MessageCallbackFunction* const func;
@@ -306,7 +284,7 @@ MessageManagerLock::MessageManagerLock (BailOutChecker& bailOutChecker)
bool MessageManagerLock::attemptLock (BailOutChecker* bailOutChecker)
{
MessageManager* const mm = MessageManager::instance;
auto* mm = MessageManager::instance;
if (mm == nullptr)
return false;
@@ -358,7 +336,7 @@ MessageManagerLock::~MessageManagerLock() noexcept
{
if (blockingMessage != nullptr)
{
MessageManager* const mm = MessageManager::instance;
auto* mm = MessageManager::instance;
jassert (mm == nullptr || mm->currentThreadHasLockedMessageManager());


+ 18
- 8
modules/juce_events/messages/juce_MessageManager.h View File

@@ -99,12 +99,12 @@ public:
#endif
//==============================================================================
#if JUCE_COMPILER_SUPPORTS_LAMBDAS
/** Asynchronously invokes a function or C++11 lambda on the message thread.
Internally this uses the CallbackMessage class to invoke the callback.
*/
static void callAsync (std::function<void(void)>);
#endif
/** Asynchronously invokes a function or C++11 lambda on the message thread. */
template <typename FunctionType>
static void callAsync (FunctionType functionToCall)
{
new AsyncCallInvoker<FunctionType> (functionToCall);
}
/** Calls a function using the message-thread.
@@ -211,9 +211,9 @@ private:
friend class MessageManagerLock;
ScopedPointer<ActionBroadcaster> broadcaster;
bool quitMessagePosted, quitMessageReceived;
bool quitMessagePosted = false, quitMessageReceived = false;
Thread::ThreadID messageThreadId;
Thread::ThreadID volatile threadWithLock;
Thread::ThreadID volatile threadWithLock = {};
CriticalSection lockingLock;
static bool postMessageToSystemQueue (MessageBase*);
@@ -222,6 +222,16 @@ private:
static void doPlatformSpecificShutdown();
static bool dispatchNextMessageOnSystemQueue (bool returnIfNoPendingMessages);
template <typename FunctionType>
struct AsyncCallInvoker : public MessageBase
{
AsyncCallInvoker (FunctionType f) : callback (f) { post(); }
void messageCallback() override { callback(); }
FunctionType callback;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AsyncCallInvoker)
};
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MessageManager)
};


+ 19
- 41
modules/juce_gui_basics/components/juce_Component.cpp View File

@@ -1731,7 +1731,7 @@ void Component::enterModalState (const bool shouldTakeKeyboardFocus,
if (! isCurrentlyModal (false))
{
ModalComponentManager& mcm = *ModalComponentManager::getInstance();
auto& mcm = *ModalComponentManager::getInstance();
mcm.startModal (this, deleteWhenDismissed);
mcm.attachCallback (this, callback);
@@ -1753,36 +1753,24 @@ void Component::exitModalState (const int returnValue)
{
if (MessageManager::getInstance()->isThisTheMessageThread())
{
ModalComponentManager& mcm = *ModalComponentManager::getInstance();
auto& mcm = *ModalComponentManager::getInstance();
mcm.endModal (this, returnValue);
mcm.bringModalComponentsToFront();
// If any of the mouse sources are over another Component when we exit the modal state then send a mouse enter event
const Array<MouseInputSource>& mouseSources = Desktop::getInstance().getMouseSources();
for (MouseInputSource* mi = mouseSources.begin(), * const e = mouseSources.end(); mi != e; ++mi)
{
if (Component* c = mi->getComponentUnderMouse())
c->internalMouseEnter (*mi, mi->getScreenPosition(), Time::getCurrentTime());
}
for (auto& ms : Desktop::getInstance().getMouseSources())
if (auto* c = ms.getComponentUnderMouse())
c->internalMouseEnter (ms, ms.getScreenPosition(), Time::getCurrentTime());
}
else
{
struct ExitModalStateMessage : public CallbackMessage
{
ExitModalStateMessage (Component* c, int res) : target (c), result (res) {}
WeakReference<Component> target (this);
void messageCallback() override
{
if (Component* c = target)
c->exitModalState (result);
}
WeakReference<Component> target;
int result;
};
(new ExitModalStateMessage (this, returnValue))->post();
MessageManager::callAsync ([=]()
{
if (auto* c = target.get())
c->exitModalState (returnValue);
});
}
}
}
@@ -1792,7 +1780,7 @@ bool Component::isCurrentlyModal (bool onlyConsiderForemostModalComponent) const
const int n = onlyConsiderForemostModalComponent ? 1 : getNumCurrentlyModalComponents();
for (int i = 0; i < n; ++i)
if (getCurrentlyModalComponent (i) == this)
if (getCurrentlyModalComponent(i) == this)
return true;
return false;
@@ -2333,25 +2321,15 @@ void Component::internalModalInputAttempt()
}
//==============================================================================
void Component::postCommandMessage (const int commandId)
void Component::postCommandMessage (const int commandID)
{
struct CustomCommandMessage : public CallbackMessage
{
CustomCommandMessage (Component* const c, const int command)
: target (c), commandId (command) {}
void messageCallback() override
{
if (auto* c = target.get())
c->handleCommandMessage (commandId);
}
WeakReference<Component> target (this);
private:
WeakReference<Component> target;
int commandId;
};
(new CustomCommandMessage (this, commandId))->post();
MessageManager::callAsync ([=]()
{
if (auto* c = target.get())
c->handleCommandMessage (commandID);
});
}
void Component::handleCommandMessage (int)


+ 13
- 30
modules/juce_gui_basics/mouse/juce_DragAndDropContainer.cpp View File

@@ -40,8 +40,7 @@ public:
: sourceDetails (desc, sourceComponent, Point<int>()),
image (im), owner (ddc),
mouseDragSource (mouseSource),
imageOffset (offset),
hasCheckedForExternalDrag (false)
imageOffset (offset)
{
updateSize();
@@ -211,7 +210,7 @@ private:
DragAndDropContainer& owner;
WeakReference<Component> mouseDragSource, currentlyOverComp;
const Point<int> imageOffset;
bool hasCheckedForExternalDrag;
bool hasCheckedForExternalDrag = false;
Time lastTimeOverTarget;
void updateSize()
@@ -294,27 +293,6 @@ private:
target->itemDragMove (details);
}
struct ExternalDragAndDropMessage : public CallbackMessage
{
ExternalDragAndDropMessage (const StringArray& f, bool canMove)
: files (f), canMoveFiles (canMove)
{}
ExternalDragAndDropMessage (const String& t) : text (t), canMoveFiles() {}
void messageCallback() override
{
if (text.isEmpty())
DragAndDropContainer::performExternalDragDropOfFiles (files, canMoveFiles);
else
DragAndDropContainer::performExternalDragDropOfText (text);
}
String text;
StringArray files;
bool canMoveFiles;
};
void checkForExternalDrag (DragAndDropTarget::SourceDetails& details, Point<int> screenPos)
{
if (! hasCheckedForExternalDrag)
@@ -322,21 +300,26 @@ private:
if (Desktop::getInstance().findComponentAt (screenPos) == nullptr)
{
hasCheckedForExternalDrag = true;
StringArray files;
String text;
bool canMoveFiles = false;
if (ModifierKeys::getCurrentModifiersRealtime().isAnyMouseButtonDown())
{
StringArray files;
bool canMoveFiles = false;
if (owner.shouldDropFilesWhenDraggedExternally (details, files, canMoveFiles) && ! files.isEmpty())
{
(new ExternalDragAndDropMessage (files, canMoveFiles))->post();
MessageManager::callAsync ([=]() { DragAndDropContainer::performExternalDragDropOfFiles (files, canMoveFiles); });
deleteSelf();
return;
}
else if (owner.shouldDropTextWhenDraggedExternally (details, text) && text.isNotEmpty())
String text;
if (owner.shouldDropTextWhenDraggedExternally (details, text) && text.isNotEmpty())
{
(new ExternalDragAndDropMessage (text))->post();
MessageManager::callAsync ([=]() { DragAndDropContainer::performExternalDragDropOfText (text); });
deleteSelf();
return;
}
}
}


+ 3
- 7
modules/juce_gui_basics/widgets/juce_TreeView.cpp View File

@@ -367,15 +367,11 @@ private:
static bool isMouseDraggingInChildCompOf (Component* const comp)
{
const Array<MouseInputSource>& mouseSources = Desktop::getInstance().getMouseSources();
for (MouseInputSource* mi = mouseSources.begin(), * const e = mouseSources.end(); mi != e; ++mi)
{
if (mi->isDragging())
if (Component* const underMouse = mi->getComponentUnderMouse())
for (auto& ms : Desktop::getInstance().getMouseSources())
if (ms.isDragging())
if (auto* underMouse = ms.getComponentUnderMouse())
if (comp == underMouse || comp->isParentOf (underMouse))
return true;
}
return false;
}


+ 28
- 50
modules/juce_gui_basics/windows/juce_ComponentPeer.cpp View File

@@ -28,17 +28,14 @@ static uint32 lastUniquePeerID = 1;
ComponentPeer::ComponentPeer (Component& comp, const int flags)
: component (comp),
styleFlags (flags),
constrainer (nullptr),
lastDragAndDropCompUnderMouse (nullptr),
uniqueID (lastUniquePeerID += 2), // increment by 2 so that this can never hit 0
isWindowMinimised (false)
uniqueID (lastUniquePeerID += 2) // increment by 2 so that this can never hit 0
{
Desktop::getInstance().peers.add (this);
}
ComponentPeer::~ComponentPeer()
{
Desktop& desktop = Desktop::getInstance();
auto& desktop = Desktop::getInstance();
desktop.peers.removeFirstMatchingValue (this);
desktop.triggerFocusCallback();
}
@@ -56,15 +53,9 @@ ComponentPeer* ComponentPeer::getPeer (const int index) noexcept
ComponentPeer* ComponentPeer::getPeerFor (const Component* const component) noexcept
{
const Array<ComponentPeer*>& peers = Desktop::getInstance().peers;
for (int i = peers.size(); --i >= 0;)
{
ComponentPeer* const peer = peers.getUnchecked(i);
for (auto* peer : Desktop::getInstance().peers)
if (&(peer->getComponent()) == component)
return peer;
}
return nullptr;
}
@@ -169,7 +160,7 @@ Component* ComponentPeer::getTargetForKeyPress()
c = &component;
if (c->isCurrentlyBlockedByAnotherModalComponent())
if (Component* const currentModalComp = Component::getCurrentlyModalComponent())
if (auto* currentModalComp = Component::getCurrentlyModalComponent())
c = currentModalComp;
return c;
@@ -193,7 +184,7 @@ bool ComponentPeer::handleKeyPress (const KeyPress& keyInfo)
{
const WeakReference<Component> deletionChecker (target);
if (const Array<KeyListener*>* const keyListeners = target->keyListeners)
if (auto* keyListeners = target->keyListeners.get())
{
for (int i = keyListeners->size(); --i >= 0;)
{
@@ -211,7 +202,7 @@ bool ComponentPeer::handleKeyPress (const KeyPress& keyInfo)
if (keyWasUsed || deletionChecker == nullptr)
break;
if (Component* const currentlyFocused = Component::getCurrentlyFocusedComponent())
if (auto* currentlyFocused = Component::getCurrentlyFocusedComponent())
{
const bool isTab = (keyInfo == KeyPress::tabKey);
const bool isShiftTab = (keyInfo == KeyPress (KeyPress::tabKey, ModifierKeys::shiftModifier, 0));
@@ -265,7 +256,7 @@ void ComponentPeer::handleModifierKeysChange()
{
ModifierKeys::updateCurrentModifiers();
Component* target = Desktop::getInstance().getMainMouseSource().getComponentUnderMouse();
auto* target = Desktop::getInstance().getMainMouseSource().getComponentUnderMouse();
if (target == nullptr)
target = Component::getCurrentlyFocusedComponent();
@@ -279,7 +270,7 @@ void ComponentPeer::handleModifierKeysChange()
TextInputTarget* ComponentPeer::findCurrentTextInputTarget()
{
Component* const c = Component::getCurrentlyFocusedComponent();
auto* c = Component::getCurrentlyFocusedComponent();
if (c == &component || component.isParentOf (c))
if (TextInputTarget* const ti = dynamic_cast<TextInputTarget*> (c))
@@ -313,8 +304,8 @@ void ComponentPeer::handleMovedOrResized()
{
const WeakReference<Component> deletionChecker (&component);
Rectangle<int> newBounds (Component::ComponentHelpers::rawPeerPositionToLocal (component, getBounds()));
Rectangle<int> oldBounds (component.getBounds());
auto newBounds = Component::ComponentHelpers::rawPeerPositionToLocal (component, getBounds());
auto oldBounds = component.getBounds();
const bool wasMoved = (oldBounds.getPosition() != newBounds.getPosition());
const bool wasResized = (oldBounds.getWidth() != newBounds.getWidth() || oldBounds.getHeight() != newBounds.getHeight());
@@ -452,31 +443,6 @@ namespace DragHelpers
return nullptr;
}
// We'll use an async message to deliver the drop, because if the target decides
// to run a modal loop, it can gum-up the operating system..
class AsyncDropMessage : public CallbackMessage
{
public:
AsyncDropMessage (Component* c, const ComponentPeer::DragInfo& d) : target (c), info (d) {}
void messageCallback() override
{
if (Component* const c = target.get())
{
if (isFileDrag (info))
dynamic_cast<FileDragAndDropTarget*> (c)->filesDropped (info.files, info.position.x, info.position.y);
else
dynamic_cast<TextDragAndDropTarget*> (c)->textDropped (info.text, info.position.x, info.position.y);
}
}
private:
WeakReference<Component> target;
const ComponentPeer::DragInfo info;
JUCE_DECLARE_NON_COPYABLE (AsyncDropMessage)
};
}
bool ComponentPeer::handleDragMove (const ComponentPeer::DragInfo& info)
@@ -508,7 +474,7 @@ bool ComponentPeer::handleDragMove (const ComponentPeer::DragInfo& info)
if (DragHelpers::isSuitableTarget (info, newTarget))
{
dragAndDropTargetComponent = newTarget;
const Point<int> pos (newTarget->getLocalPoint (&component, info.position));
auto pos = newTarget->getLocalPoint (&component, info.position);
if (DragHelpers::isFileDrag (info))
dynamic_cast<FileDragAndDropTarget*> (newTarget)->fileDragEnter (info.files, pos.x, pos.y);
@@ -525,7 +491,7 @@ bool ComponentPeer::handleDragMove (const ComponentPeer::DragInfo& info)
if (! DragHelpers::isSuitableTarget (info, newTarget))
return false;
const Point<int> pos (newTarget->getLocalPoint (&component, info.position));
auto pos = newTarget->getLocalPoint (&component, info.position);
if (DragHelpers::isFileDrag (info))
dynamic_cast<FileDragAndDropTarget*> (newTarget)->fileDragMove (info.files, pos.x, pos.y);
@@ -550,7 +516,7 @@ bool ComponentPeer::handleDragDrop (const ComponentPeer::DragInfo& info)
{
handleDragMove (info);
if (Component* const targetComp = dragAndDropTargetComponent)
if (WeakReference<Component> targetComp = dragAndDropTargetComponent)
{
dragAndDropTargetComponent = nullptr;
lastDragAndDropCompUnderMouse = nullptr;
@@ -565,10 +531,22 @@ bool ComponentPeer::handleDragDrop (const ComponentPeer::DragInfo& info)
return true;
}
ComponentPeer::DragInfo info2 (info);
info2.position = targetComp->getLocalPoint (&component, info.position);
ComponentPeer::DragInfo infoCopy (info);
infoCopy.position = targetComp->getLocalPoint (&component, info.position);
// We'll use an async message to deliver the drop, because if the target decides
// to run a modal loop, it can gum-up the operating system..
MessageManager::callAsync ([=]()
{
if (auto* c = targetComp.get())
{
if (DragHelpers::isFileDrag (info))
dynamic_cast<FileDragAndDropTarget*> (c)->filesDropped (infoCopy.files, infoCopy.position.x, infoCopy.position.y);
else
dynamic_cast<TextDragAndDropTarget*> (c)->textDropped (infoCopy.text, infoCopy.position.x, infoCopy.position.y);
}
});
(new DragHelpers::AsyncDropMessage (targetComp, info2))->post();
return true;
}
}


+ 3
- 3
modules/juce_gui_basics/windows/juce_ComponentPeer.h View File

@@ -364,14 +364,14 @@ protected:
Component& component;
const int styleFlags;
Rectangle<int> lastNonFullscreenBounds;
ComponentBoundsConstrainer* constrainer;
ComponentBoundsConstrainer* constrainer = nullptr;
private:
//==============================================================================
WeakReference<Component> lastFocusedComponent, dragAndDropTargetComponent;
Component* lastDragAndDropCompUnderMouse;
Component* lastDragAndDropCompUnderMouse = nullptr;
const uint32 uniqueID;
bool isWindowMinimised;
bool isWindowMinimised = false;
Component* getTargetForKeyPress();
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ComponentPeer)


Loading…
Cancel
Save