| @@ -38422,6 +38422,7 @@ public: | |||
| AsyncUpdaterMessage (AsyncUpdater& owner_) | |||
| : owner (owner_) | |||
| { | |||
| setMessageIsDeletedOnDelivery (false); | |||
| } | |||
| void messageCallback() | |||
| @@ -38430,10 +38431,12 @@ public: | |||
| owner.handleAsyncUpdate(); | |||
| } | |||
| private: | |||
| AsyncUpdater& owner; | |||
| }; | |||
| AsyncUpdater::AsyncUpdater() throw() | |||
| AsyncUpdater::AsyncUpdater() | |||
| : message (new AsyncUpdaterMessage (*this)) | |||
| { | |||
| } | |||
| @@ -38445,18 +38448,14 @@ AsyncUpdater::~AsyncUpdater() | |||
| // deleting this object, or find some other way to avoid such a race condition. | |||
| jassert ((! isUpdatePending()) || MessageManager::getInstance()->currentThreadHasLockedMessageManager()); | |||
| pendingMessage = 0; | |||
| if (pendingMessage.exchange (0) != 0) | |||
| message.release()->setMessageIsDeletedOnDelivery (true); | |||
| } | |||
| void AsyncUpdater::triggerAsyncUpdate() | |||
| { | |||
| if (pendingMessage.value == 0) | |||
| { | |||
| ScopedPointer<AsyncUpdaterMessage> pending (new AsyncUpdaterMessage (*this)); | |||
| if (pendingMessage.compareAndSetBool (pending, 0)) | |||
| pending.release()->post(); | |||
| } | |||
| if (pendingMessage.compareAndSetBool (message, 0)) | |||
| message->post(); | |||
| } | |||
| void AsyncUpdater::cancelPendingUpdate() throw() | |||
| @@ -39092,7 +39091,7 @@ void MessageManager::postMessageToQueue (Message* const message) | |||
| delete message; | |||
| } | |||
| CallbackMessage::CallbackMessage() throw() {} | |||
| CallbackMessage::CallbackMessage() throw() : deleteOnDelivery (true) {} | |||
| CallbackMessage::~CallbackMessage() {} | |||
| void CallbackMessage::post() | |||
| @@ -39106,7 +39105,7 @@ void MessageManager::deliverMessage (Message* const message) | |||
| { | |||
| JUCE_TRY | |||
| { | |||
| const ScopedPointer <Message> messageDeleter (message); | |||
| ScopedPointer <Message> messageDeleter (message); | |||
| MessageListener* const recipient = message->messageRecipient; | |||
| if (recipient == 0) | |||
| @@ -39116,6 +39115,9 @@ void MessageManager::deliverMessage (Message* const message) | |||
| if (callbackMessage != 0) | |||
| { | |||
| callbackMessage->messageCallback(); | |||
| if (! callbackMessage->isMessageDeletedOnDelivery()) | |||
| messageDeleter.release(); | |||
| } | |||
| else if (message->intParameter1 == quitMessageId) | |||
| { | |||
| @@ -12490,7 +12490,7 @@ class JUCE_API AsyncUpdater | |||
| public: | |||
| /** Creates an AsyncUpdater object. */ | |||
| AsyncUpdater() throw(); | |||
| AsyncUpdater(); | |||
| /** Destructor. | |||
| @@ -12544,7 +12544,8 @@ private: | |||
| class AsyncUpdaterMessage; | |||
| friend class AsyncUpdaterMessage; | |||
| friend class ScopedPointer<AsyncUpdaterMessage>; | |||
| ScopedPointer<AsyncUpdaterMessage> message; | |||
| Atomic<AsyncUpdaterMessage*> pendingMessage; | |||
| }; | |||
| @@ -43823,8 +43824,22 @@ public: | |||
| */ | |||
| void post(); | |||
| /** This can be used to indicate whether the MessageManager should delete the | |||
| message after it has been delivered. | |||
| By default, messages will be deleted, but you might want to disable this so that you | |||
| can re-use the same message. | |||
| */ | |||
| void setMessageIsDeletedOnDelivery (bool shouldBeDeleted) throw() { deleteOnDelivery = shouldBeDeleted; } | |||
| /** Returns true if the message should be deleted after is has been delivered. | |||
| @see setMessageIsDeletedOnDelivery | |||
| */ | |||
| bool isMessageDeletedOnDelivery() const throw() { return deleteOnDelivery; } | |||
| private: | |||
| bool deleteOnDelivery; | |||
| JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (CallbackMessage); | |||
| }; | |||
| @@ -29,7 +29,6 @@ BEGIN_JUCE_NAMESPACE | |||
| #include "juce_AsyncUpdater.h" | |||
| #include "juce_CallbackMessage.h" | |||
| #include "../containers/juce_ScopedPointer.h" | |||
| #include "juce_MessageManager.h" | |||
| @@ -40,6 +39,7 @@ public: | |||
| AsyncUpdaterMessage (AsyncUpdater& owner_) | |||
| : owner (owner_) | |||
| { | |||
| setMessageIsDeletedOnDelivery (false); | |||
| } | |||
| void messageCallback() | |||
| @@ -48,11 +48,13 @@ public: | |||
| owner.handleAsyncUpdate(); | |||
| } | |||
| private: | |||
| AsyncUpdater& owner; | |||
| }; | |||
| //============================================================================== | |||
| AsyncUpdater::AsyncUpdater() throw() | |||
| AsyncUpdater::AsyncUpdater() | |||
| : message (new AsyncUpdaterMessage (*this)) | |||
| { | |||
| } | |||
| @@ -64,18 +66,14 @@ AsyncUpdater::~AsyncUpdater() | |||
| // deleting this object, or find some other way to avoid such a race condition. | |||
| jassert ((! isUpdatePending()) || MessageManager::getInstance()->currentThreadHasLockedMessageManager()); | |||
| pendingMessage = 0; | |||
| if (pendingMessage.exchange (0) != 0) | |||
| message.release()->setMessageIsDeletedOnDelivery (true); | |||
| } | |||
| void AsyncUpdater::triggerAsyncUpdate() | |||
| { | |||
| if (pendingMessage.value == 0) | |||
| { | |||
| ScopedPointer<AsyncUpdaterMessage> pending (new AsyncUpdaterMessage (*this)); | |||
| if (pendingMessage.compareAndSetBool (pending, 0)) | |||
| pending.release()->post(); | |||
| } | |||
| if (pendingMessage.compareAndSetBool (message, 0)) | |||
| message->post(); | |||
| } | |||
| void AsyncUpdater::cancelPendingUpdate() throw() | |||
| @@ -27,6 +27,7 @@ | |||
| #define __JUCE_ASYNCUPDATER_JUCEHEADER__ | |||
| #include "../core/juce_Atomic.h" | |||
| #include "../containers/juce_ScopedPointer.h" | |||
| //============================================================================== | |||
| @@ -44,7 +45,7 @@ class JUCE_API AsyncUpdater | |||
| public: | |||
| //============================================================================== | |||
| /** Creates an AsyncUpdater object. */ | |||
| AsyncUpdater() throw(); | |||
| AsyncUpdater(); | |||
| /** Destructor. | |||
| @@ -101,7 +102,8 @@ private: | |||
| //============================================================================== | |||
| class AsyncUpdaterMessage; | |||
| friend class AsyncUpdaterMessage; | |||
| friend class ScopedPointer<AsyncUpdaterMessage>; | |||
| ScopedPointer<AsyncUpdaterMessage> message; | |||
| Atomic<AsyncUpdaterMessage*> pendingMessage; | |||
| }; | |||
| @@ -73,8 +73,22 @@ public: | |||
| */ | |||
| void post(); | |||
| /** This can be used to indicate whether the MessageManager should delete the | |||
| message after it has been delivered. | |||
| By default, messages will be deleted, but you might want to disable this so that you | |||
| can re-use the same message. | |||
| */ | |||
| void setMessageIsDeletedOnDelivery (bool shouldBeDeleted) throw() { deleteOnDelivery = shouldBeDeleted; } | |||
| /** Returns true if the message should be deleted after is has been delivered. | |||
| @see setMessageIsDeletedOnDelivery | |||
| */ | |||
| bool isMessageDeletedOnDelivery() const throw() { return deleteOnDelivery; } | |||
| private: | |||
| //============================================================================== | |||
| bool deleteOnDelivery; | |||
| JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (CallbackMessage); | |||
| }; | |||
| @@ -88,7 +88,7 @@ void MessageManager::postMessageToQueue (Message* const message) | |||
| } | |||
| //============================================================================== | |||
| CallbackMessage::CallbackMessage() throw() {} | |||
| CallbackMessage::CallbackMessage() throw() : deleteOnDelivery (true) {} | |||
| CallbackMessage::~CallbackMessage() {} | |||
| void CallbackMessage::post() | |||
| @@ -103,7 +103,7 @@ void MessageManager::deliverMessage (Message* const message) | |||
| { | |||
| JUCE_TRY | |||
| { | |||
| const ScopedPointer <Message> messageDeleter (message); | |||
| ScopedPointer <Message> messageDeleter (message); | |||
| MessageListener* const recipient = message->messageRecipient; | |||
| if (recipient == 0) | |||
| @@ -113,6 +113,9 @@ void MessageManager::deliverMessage (Message* const message) | |||
| if (callbackMessage != 0) | |||
| { | |||
| callbackMessage->messageCallback(); | |||
| if (! callbackMessage->isMessageDeletedOnDelivery()) | |||
| messageDeleter.release(); | |||
| } | |||
| else if (message->intParameter1 == quitMessageId) | |||
| { | |||