这个类同样是基于 CallbackMessage, 主要目的是为了在主线程中进行回调,只不过在收到消息的时候进行检测,检测消息发送对象是否已经删除,如果消息发送对象已经没了。消息回调最终调用了调用者的 handleAsyncUpdate, 只是这样的话应当还是存在问题,主线程在处理,后台线程在删除,这样问题就大了,看来作者是没把这个问题给解决掉。
void messageCallback() override
{
if (shouldDeliver.compareAndSetBool (0, 1))
owner.handleAsyncUpdate();
}
源码码如下:
class AsyncUpdater::AsyncUpdaterMessage : public CallbackMessage
{
public:
AsyncUpdaterMessage (AsyncUpdater& au) : owner (au) {}
void messageCallback() override
{
if (shouldDeliver.compareAndSetBool (0, 1))
owner.handleAsyncUpdate();
}
AsyncUpdater& owner;
Atomic<int> shouldDeliver;
JUCE_DECLARE_NON_COPYABLE (AsyncUpdaterMessage)
};
//==============================================================================
AsyncUpdater::AsyncUpdater()
{
activeMessage = new AsyncUpdaterMessage (*this);
}
AsyncUpdater::~AsyncUpdater()
{
// You're deleting this object with a background thread while there's an update
// pending on the main event thread - that's pretty dodgy threading, as the callback could
// happen after this destructor has finished. You should either use a MessageManagerLock while
// deleting this object, or find some other way to avoid such a race condition.
jassert ((! isUpdatePending())
|| MessageManager::getInstanceWithoutCreating() == nullptr
|| MessageManager::getInstanceWithoutCreating()->currentThreadHasLockedMessageManager());
activeMessage->shouldDeliver.set (0);
}
void AsyncUpdater::triggerAsyncUpdate()
{
// If you're calling this before (or after) the MessageManager is
// running, then you're not going to get any callbacks!
jassert (MessageManager::getInstanceWithoutCreating() != nullptr);
if (activeMessage->shouldDeliver.compareAndSetBool (1, 0))
if (! activeMessage->post())
cancelPendingUpdate(); // if the message queue fails, this avoids getting
// trapped waiting for the message to arrive
}
void AsyncUpdater::cancelPendingUpdate() noexcept
{
activeMessage->shouldDeliver.set(0);
}
void AsyncUpdater::handleUpdateNowIfNeeded()
{
// This can only be called by the event thread.
jassert (MessageManager::getInstance()->currentThreadHasLockedMessageManager());
if (activeMessage->shouldDeliver.exchange (0) != 0)
handleAsyncUpdate();
}
bool AsyncUpdater::isUpdatePending() const noexcept
{
return activeMessage->shouldDeliver.value != 0;
}