@@ -119,7 +119,6 @@ OBJECTS := \ | |||
$(OBJDIR)/juce_Primes_32e6603.o \ | |||
$(OBJDIR)/juce_RSAKey_b60982ae.o \ | |||
$(OBJDIR)/juce_ActionBroadcaster_7f997786.o \ | |||
$(OBJDIR)/juce_ActionListenerList_9e099ae4.o \ | |||
$(OBJDIR)/juce_AsyncUpdater_a7e1cb89.o \ | |||
$(OBJDIR)/juce_ChangeBroadcaster_3eb8fecc.o \ | |||
$(OBJDIR)/juce_InterprocessConnection_13086b6d.o \ | |||
@@ -763,11 +762,6 @@ $(OBJDIR)/juce_ActionBroadcaster_7f997786.o: ../../src/events/juce_ActionBroadca | |||
@echo "Compiling juce_ActionBroadcaster.cpp" | |||
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | |||
$(OBJDIR)/juce_ActionListenerList_9e099ae4.o: ../../src/events/juce_ActionListenerList.cpp | |||
-@mkdir -p $(OBJDIR) | |||
@echo "Compiling juce_ActionListenerList.cpp" | |||
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | |||
$(OBJDIR)/juce_AsyncUpdater_a7e1cb89.o: ../../src/events/juce_AsyncUpdater.cpp | |||
-@mkdir -p $(OBJDIR) | |||
@echo "Compiling juce_AsyncUpdater.cpp" | |||
@@ -88,7 +88,6 @@ | |||
12E3CC31875A202D6B30F778 = { isa = PBXBuildFile; fileRef = E9E692847C14AD33CD5FB40B; }; | |||
CF51988743ED2CD823DFE0B5 = { isa = PBXBuildFile; fileRef = 7AE9331938549244E27A5D0E; }; | |||
659D9CD58B6914EB420E6AEC = { isa = PBXBuildFile; fileRef = 31D985CB8646B78460E9D5A7; }; | |||
5BE4BAA99FDC6F1B3177096F = { isa = PBXBuildFile; fileRef = 5A46476E16BA4F9DA95E9E6A; }; | |||
55737E2F1817DE642AA7DA05 = { isa = PBXBuildFile; fileRef = 1617348BBF5D103619D76911; }; | |||
6D2C50B0A69855A7F8C062E7 = { isa = PBXBuildFile; fileRef = B80F8CD026033ACCCE11A1A4; }; | |||
70EE7A1273945B62B013DB43 = { isa = PBXBuildFile; fileRef = AE68ECB6E063BD8D4984C0B3; }; | |||
@@ -554,8 +553,6 @@ | |||
31D985CB8646B78460E9D5A7 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_ActionBroadcaster.cpp; path = ../../src/events/juce_ActionBroadcaster.cpp; sourceTree = SOURCE_ROOT; }; | |||
09F7685D1EFF472ECB1F5EF1 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_ActionBroadcaster.h; path = ../../src/events/juce_ActionBroadcaster.h; sourceTree = SOURCE_ROOT; }; | |||
4EF8BD4BF46C4BCB39F96609 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_ActionListener.h; path = ../../src/events/juce_ActionListener.h; sourceTree = SOURCE_ROOT; }; | |||
5A46476E16BA4F9DA95E9E6A = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_ActionListenerList.cpp; path = ../../src/events/juce_ActionListenerList.cpp; sourceTree = SOURCE_ROOT; }; | |||
8269D9DFAD7923EE13E7EEC7 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_ActionListenerList.h; path = ../../src/events/juce_ActionListenerList.h; sourceTree = SOURCE_ROOT; }; | |||
1617348BBF5D103619D76911 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_AsyncUpdater.cpp; path = ../../src/events/juce_AsyncUpdater.cpp; sourceTree = SOURCE_ROOT; }; | |||
44DB44953945417F76199479 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_AsyncUpdater.h; path = ../../src/events/juce_AsyncUpdater.h; sourceTree = SOURCE_ROOT; }; | |||
D04B6E43A037F985434B2F5A = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_CallbackMessage.h; path = ../../src/events/juce_CallbackMessage.h; sourceTree = SOURCE_ROOT; }; | |||
@@ -1282,8 +1279,6 @@ | |||
31D985CB8646B78460E9D5A7, | |||
09F7685D1EFF472ECB1F5EF1, | |||
4EF8BD4BF46C4BCB39F96609, | |||
5A46476E16BA4F9DA95E9E6A, | |||
8269D9DFAD7923EE13E7EEC7, | |||
1617348BBF5D103619D76911, | |||
44DB44953945417F76199479, | |||
D04B6E43A037F985434B2F5A, | |||
@@ -2008,7 +2003,6 @@ | |||
12E3CC31875A202D6B30F778, | |||
CF51988743ED2CD823DFE0B5, | |||
659D9CD58B6914EB420E6AEC, | |||
5BE4BAA99FDC6F1B3177096F, | |||
55737E2F1817DE642AA7DA05, | |||
6D2C50B0A69855A7F8C062E7, | |||
70EE7A1273945B62B013DB43, | |||
@@ -422,8 +422,6 @@ | |||
<File RelativePath="..\..\src\events\juce_ActionBroadcaster.cpp"/> | |||
<File RelativePath="..\..\src\events\juce_ActionBroadcaster.h"/> | |||
<File RelativePath="..\..\src\events\juce_ActionListener.h"/> | |||
<File RelativePath="..\..\src\events\juce_ActionListenerList.cpp"/> | |||
<File RelativePath="..\..\src\events\juce_ActionListenerList.h"/> | |||
<File RelativePath="..\..\src\events\juce_AsyncUpdater.cpp"/> | |||
<File RelativePath="..\..\src\events\juce_AsyncUpdater.h"/> | |||
<File RelativePath="..\..\src\events\juce_CallbackMessage.h"/> | |||
@@ -422,8 +422,6 @@ | |||
<File RelativePath="..\..\src\events\juce_ActionBroadcaster.cpp"/> | |||
<File RelativePath="..\..\src\events\juce_ActionBroadcaster.h"/> | |||
<File RelativePath="..\..\src\events\juce_ActionListener.h"/> | |||
<File RelativePath="..\..\src\events\juce_ActionListenerList.cpp"/> | |||
<File RelativePath="..\..\src\events\juce_ActionListenerList.h"/> | |||
<File RelativePath="..\..\src\events\juce_AsyncUpdater.cpp"/> | |||
<File RelativePath="..\..\src\events\juce_AsyncUpdater.h"/> | |||
<File RelativePath="..\..\src\events\juce_CallbackMessage.h"/> | |||
@@ -424,8 +424,6 @@ | |||
<File RelativePath="..\..\src\events\juce_ActionBroadcaster.cpp"/> | |||
<File RelativePath="..\..\src\events\juce_ActionBroadcaster.h"/> | |||
<File RelativePath="..\..\src\events\juce_ActionListener.h"/> | |||
<File RelativePath="..\..\src\events\juce_ActionListenerList.cpp"/> | |||
<File RelativePath="..\..\src\events\juce_ActionListenerList.h"/> | |||
<File RelativePath="..\..\src\events\juce_AsyncUpdater.cpp"/> | |||
<File RelativePath="..\..\src\events\juce_AsyncUpdater.h"/> | |||
<File RelativePath="..\..\src\events\juce_CallbackMessage.h"/> | |||
@@ -202,7 +202,6 @@ | |||
<ClCompile Include="..\..\src\cryptography\juce_Primes.cpp"/> | |||
<ClCompile Include="..\..\src\cryptography\juce_RSAKey.cpp"/> | |||
<ClCompile Include="..\..\src\events\juce_ActionBroadcaster.cpp"/> | |||
<ClCompile Include="..\..\src\events\juce_ActionListenerList.cpp"/> | |||
<ClCompile Include="..\..\src\events\juce_AsyncUpdater.cpp"/> | |||
<ClCompile Include="..\..\src\events\juce_ChangeBroadcaster.cpp"/> | |||
<ClCompile Include="..\..\src\events\juce_InterprocessConnection.cpp"/> | |||
@@ -550,7 +549,6 @@ | |||
<ClInclude Include="..\..\src\cryptography\juce_RSAKey.h"/> | |||
<ClInclude Include="..\..\src\events\juce_ActionBroadcaster.h"/> | |||
<ClInclude Include="..\..\src\events\juce_ActionListener.h"/> | |||
<ClInclude Include="..\..\src\events\juce_ActionListenerList.h"/> | |||
<ClInclude Include="..\..\src\events\juce_AsyncUpdater.h"/> | |||
<ClInclude Include="..\..\src\events\juce_CallbackMessage.h"/> | |||
<ClInclude Include="..\..\src\events\juce_ChangeBroadcaster.h"/> | |||
@@ -454,9 +454,6 @@ | |||
<ClCompile Include="..\..\src\events\juce_ActionBroadcaster.cpp"> | |||
<Filter>Juce\Source\events</Filter> | |||
</ClCompile> | |||
<ClCompile Include="..\..\src\events\juce_ActionListenerList.cpp"> | |||
<Filter>Juce\Source\events</Filter> | |||
</ClCompile> | |||
<ClCompile Include="..\..\src\events\juce_AsyncUpdater.cpp"> | |||
<Filter>Juce\Source\events</Filter> | |||
</ClCompile> | |||
@@ -1572,9 +1569,6 @@ | |||
<ClInclude Include="..\..\src\events\juce_ActionListener.h"> | |||
<Filter>Juce\Source\events</Filter> | |||
</ClInclude> | |||
<ClInclude Include="..\..\src\events\juce_ActionListenerList.h"> | |||
<Filter>Juce\Source\events</Filter> | |||
</ClInclude> | |||
<ClInclude Include="..\..\src\events\juce_AsyncUpdater.h"> | |||
<Filter>Juce\Source\events</Filter> | |||
</ClInclude> | |||
@@ -88,7 +88,6 @@ | |||
12E3CC31875A202D6B30F778 = { isa = PBXBuildFile; fileRef = E9E692847C14AD33CD5FB40B; }; | |||
CF51988743ED2CD823DFE0B5 = { isa = PBXBuildFile; fileRef = 7AE9331938549244E27A5D0E; }; | |||
659D9CD58B6914EB420E6AEC = { isa = PBXBuildFile; fileRef = 31D985CB8646B78460E9D5A7; }; | |||
5BE4BAA99FDC6F1B3177096F = { isa = PBXBuildFile; fileRef = 5A46476E16BA4F9DA95E9E6A; }; | |||
55737E2F1817DE642AA7DA05 = { isa = PBXBuildFile; fileRef = 1617348BBF5D103619D76911; }; | |||
6D2C50B0A69855A7F8C062E7 = { isa = PBXBuildFile; fileRef = B80F8CD026033ACCCE11A1A4; }; | |||
70EE7A1273945B62B013DB43 = { isa = PBXBuildFile; fileRef = AE68ECB6E063BD8D4984C0B3; }; | |||
@@ -554,8 +553,6 @@ | |||
31D985CB8646B78460E9D5A7 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_ActionBroadcaster.cpp; path = ../../src/events/juce_ActionBroadcaster.cpp; sourceTree = SOURCE_ROOT; }; | |||
09F7685D1EFF472ECB1F5EF1 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_ActionBroadcaster.h; path = ../../src/events/juce_ActionBroadcaster.h; sourceTree = SOURCE_ROOT; }; | |||
4EF8BD4BF46C4BCB39F96609 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_ActionListener.h; path = ../../src/events/juce_ActionListener.h; sourceTree = SOURCE_ROOT; }; | |||
5A46476E16BA4F9DA95E9E6A = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_ActionListenerList.cpp; path = ../../src/events/juce_ActionListenerList.cpp; sourceTree = SOURCE_ROOT; }; | |||
8269D9DFAD7923EE13E7EEC7 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_ActionListenerList.h; path = ../../src/events/juce_ActionListenerList.h; sourceTree = SOURCE_ROOT; }; | |||
1617348BBF5D103619D76911 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_AsyncUpdater.cpp; path = ../../src/events/juce_AsyncUpdater.cpp; sourceTree = SOURCE_ROOT; }; | |||
44DB44953945417F76199479 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_AsyncUpdater.h; path = ../../src/events/juce_AsyncUpdater.h; sourceTree = SOURCE_ROOT; }; | |||
D04B6E43A037F985434B2F5A = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_CallbackMessage.h; path = ../../src/events/juce_CallbackMessage.h; sourceTree = SOURCE_ROOT; }; | |||
@@ -1282,8 +1279,6 @@ | |||
31D985CB8646B78460E9D5A7, | |||
09F7685D1EFF472ECB1F5EF1, | |||
4EF8BD4BF46C4BCB39F96609, | |||
5A46476E16BA4F9DA95E9E6A, | |||
8269D9DFAD7923EE13E7EEC7, | |||
1617348BBF5D103619D76911, | |||
44DB44953945417F76199479, | |||
D04B6E43A037F985434B2F5A, | |||
@@ -2008,7 +2003,6 @@ | |||
12E3CC31875A202D6B30F778, | |||
CF51988743ED2CD823DFE0B5, | |||
659D9CD58B6914EB420E6AEC, | |||
5BE4BAA99FDC6F1B3177096F, | |||
55737E2F1817DE642AA7DA05, | |||
6D2C50B0A69855A7F8C062E7, | |||
70EE7A1273945B62B013DB43, | |||
@@ -491,10 +491,6 @@ | |||
file="src/events/juce_ActionBroadcaster.h"/> | |||
<FILE id="Ux4rL61r9" name="juce_ActionListener.h" compile="0" resource="0" | |||
file="src/events/juce_ActionListener.h"/> | |||
<FILE id="F703c1Yid" name="juce_ActionListenerList.cpp" compile="1" | |||
resource="0" file="src/events/juce_ActionListenerList.cpp"/> | |||
<FILE id="OTsKfiFYq" name="juce_ActionListenerList.h" compile="0" resource="0" | |||
file="src/events/juce_ActionListenerList.h"/> | |||
<FILE id="LgjeCwe5N" name="juce_AsyncUpdater.cpp" compile="1" resource="0" | |||
file="src/events/juce_AsyncUpdater.cpp"/> | |||
<FILE id="TABmiJS44" name="juce_AsyncUpdater.h" compile="0" resource="0" | |||
@@ -214,7 +214,6 @@ | |||
#include "../src/audio/synthesisers/juce_Sampler.cpp" | |||
#include "../src/audio/synthesisers/juce_Synthesiser.cpp" | |||
#include "../src/events/juce_ActionBroadcaster.cpp" | |||
#include "../src/events/juce_ActionListenerList.cpp" | |||
#include "../src/events/juce_AsyncUpdater.cpp" | |||
#include "../src/events/juce_ChangeBroadcaster.cpp" | |||
#include "../src/events/juce_InterprocessConnection.cpp" | |||
@@ -12159,7 +12159,7 @@ namespace NumberToStringConverters | |||
else | |||
{ | |||
#if JUCE_WINDOWS | |||
#if JUCE_VC8_OR_EARLIER || JUCE_MINGW | |||
#if JUCE_VC7_OR_EARLIER || JUCE_MINGW | |||
len = _snwprintf (buffer, numChars, L"%.9g", n); | |||
#else | |||
len = _snwprintf_s (buffer, numChars, _TRUNCATE, L"%.9g", n); | |||
@@ -38287,162 +38287,143 @@ END_JUCE_NAMESPACE | |||
/*** Start of inlined file: juce_ActionBroadcaster.cpp ***/ | |||
BEGIN_JUCE_NAMESPACE | |||
ActionBroadcaster::ActionBroadcaster() throw() | |||
{ | |||
// are you trying to create this object before or after juce has been intialised?? | |||
jassert (MessageManager::instance != 0); | |||
} | |||
ActionBroadcaster::~ActionBroadcaster() | |||
{ | |||
// all event-based objects must be deleted BEFORE juce is shut down! | |||
jassert (MessageManager::instance != 0); | |||
} | |||
void ActionBroadcaster::addActionListener (ActionListener* const listener) | |||
{ | |||
actionListenerList.addActionListener (listener); | |||
} | |||
void ActionBroadcaster::removeActionListener (ActionListener* const listener) | |||
{ | |||
jassert (actionListenerList.isValidMessageListener()); | |||
if (actionListenerList.isValidMessageListener()) | |||
actionListenerList.removeActionListener (listener); | |||
} | |||
void ActionBroadcaster::removeAllActionListeners() | |||
{ | |||
actionListenerList.removeAllActionListeners(); | |||
} | |||
void ActionBroadcaster::sendActionMessage (const String& message) const | |||
{ | |||
actionListenerList.sendActionMessage (message); | |||
} | |||
END_JUCE_NAMESPACE | |||
/*** End of inlined file: juce_ActionBroadcaster.cpp ***/ | |||
/*** Start of inlined file: juce_ActionListenerList.cpp ***/ | |||
BEGIN_JUCE_NAMESPACE | |||
// special message of our own with a string in it | |||
class ActionMessage : public Message | |||
{ | |||
public: | |||
const String message; | |||
ActionMessage (const String& messageText, void* const listener_) throw() | |||
ActionMessage (const String& messageText, ActionListener* const listener_) throw() | |||
: message (messageText) | |||
{ | |||
pointerParameter = listener_; | |||
} | |||
~ActionMessage() throw() | |||
{ | |||
} | |||
private: | |||
ActionMessage (const ActionMessage&); | |||
ActionMessage& operator= (const ActionMessage&); | |||
}; | |||
ActionListenerList::ActionListenerList() | |||
{ | |||
} | |||
ActionBroadcaster::CallbackReceiver::CallbackReceiver() {} | |||
ActionListenerList::~ActionListenerList() | |||
void ActionBroadcaster::CallbackReceiver::handleMessage (const Message& message) | |||
{ | |||
const ActionMessage& am = static_cast <const ActionMessage&> (message); | |||
ActionListener* const target = static_cast <ActionListener*> (am.pointerParameter); | |||
if (owner->actionListeners.contains (target)) | |||
target->actionListenerCallback (am.message); | |||
} | |||
void ActionListenerList::addActionListener (ActionListener* const listener) | |||
ActionBroadcaster::ActionBroadcaster() | |||
{ | |||
const ScopedLock sl (actionListenerLock_); | |||
jassert (listener != 0); | |||
jassert (! actionListeners_.contains (listener)); // trying to add a listener to the list twice! | |||
// are you trying to create this object before or after juce has been intialised?? | |||
jassert (MessageManager::instance != 0); | |||
if (listener != 0) | |||
actionListeners_.add (listener); | |||
callback.owner = this; | |||
} | |||
void ActionListenerList::removeActionListener (ActionListener* const listener) | |||
ActionBroadcaster::~ActionBroadcaster() | |||
{ | |||
const ScopedLock sl (actionListenerLock_); | |||
// all event-based objects must be deleted BEFORE juce is shut down! | |||
jassert (MessageManager::instance != 0); | |||
} | |||
jassert (actionListeners_.contains (listener)); // trying to remove a listener that isn't on the list! | |||
void ActionBroadcaster::addActionListener (ActionListener* const listener) | |||
{ | |||
const ScopedLock sl (actionListenerLock); | |||
actionListeners_.removeValue (listener); | |||
if (listener != 0) | |||
actionListeners.add (listener); | |||
} | |||
void ActionListenerList::removeAllActionListeners() | |||
void ActionBroadcaster::removeActionListener (ActionListener* const listener) | |||
{ | |||
const ScopedLock sl (actionListenerLock_); | |||
actionListeners_.clear(); | |||
const ScopedLock sl (actionListenerLock); | |||
actionListeners.removeValue (listener); | |||
} | |||
void ActionListenerList::sendActionMessage (const String& message) const | |||
void ActionBroadcaster::removeAllActionListeners() | |||
{ | |||
const ScopedLock sl (actionListenerLock_); | |||
for (int i = actionListeners_.size(); --i >= 0;) | |||
postMessage (new ActionMessage (message, static_cast <ActionListener*> (actionListeners_.getUnchecked(i)))); | |||
const ScopedLock sl (actionListenerLock); | |||
actionListeners.clear(); | |||
} | |||
void ActionListenerList::handleMessage (const Message& message) | |||
void ActionBroadcaster::sendActionMessage (const String& message) const | |||
{ | |||
const ActionMessage& am = (const ActionMessage&) message; | |||
const ScopedLock sl (actionListenerLock); | |||
if (actionListeners_.contains (am.pointerParameter)) | |||
static_cast <ActionListener*> (am.pointerParameter)->actionListenerCallback (am.message); | |||
for (int i = actionListeners.size(); --i >= 0;) | |||
callback.postMessage (new ActionMessage (message, actionListeners.getUnchecked(i))); | |||
} | |||
END_JUCE_NAMESPACE | |||
/*** End of inlined file: juce_ActionListenerList.cpp ***/ | |||
/*** End of inlined file: juce_ActionBroadcaster.cpp ***/ | |||
/*** Start of inlined file: juce_AsyncUpdater.cpp ***/ | |||
BEGIN_JUCE_NAMESPACE | |||
class AsyncUpdater::AsyncUpdaterMessage : public CallbackMessage | |||
{ | |||
public: | |||
AsyncUpdaterMessage (AsyncUpdater& owner_) | |||
: owner (owner_) | |||
{ | |||
} | |||
void messageCallback() | |||
{ | |||
if (owner.pendingMessage.compareAndSetBool (0, this)) | |||
owner.handleAsyncUpdate(); | |||
} | |||
AsyncUpdater& owner; | |||
}; | |||
AsyncUpdater::AsyncUpdater() throw() | |||
: asyncMessagePending (false) | |||
{ | |||
internalAsyncHandler.owner = 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::getInstance()->currentThreadHasLockedMessageManager()); | |||
pendingMessage = 0; | |||
} | |||
void AsyncUpdater::triggerAsyncUpdate() | |||
{ | |||
if (! asyncMessagePending) | |||
if (pendingMessage.value == 0) | |||
{ | |||
asyncMessagePending = true; | |||
internalAsyncHandler.postMessage (new Message()); | |||
ScopedPointer<AsyncUpdaterMessage> pending (new AsyncUpdaterMessage (*this)); | |||
if (pendingMessage.compareAndSetBool (pending, 0)) | |||
pending.release()->post(); | |||
} | |||
} | |||
void AsyncUpdater::cancelPendingUpdate() throw() | |||
{ | |||
asyncMessagePending = false; | |||
pendingMessage = 0; | |||
} | |||
void AsyncUpdater::handleUpdateNowIfNeeded() | |||
{ | |||
if (asyncMessagePending) | |||
{ | |||
asyncMessagePending = false; | |||
// This can only be called by the event thread. | |||
jassert (MessageManager::getInstance()->currentThreadHasLockedMessageManager()); | |||
if (pendingMessage.exchange (0) != 0) | |||
handleAsyncUpdate(); | |||
} | |||
} | |||
void AsyncUpdater::AsyncUpdaterInternal::handleMessage (const Message&) | |||
bool AsyncUpdater::isUpdatePending() const throw() | |||
{ | |||
owner->handleUpdateNowIfNeeded(); | |||
return pendingMessage.value != 0; | |||
} | |||
END_JUCE_NAMESPACE | |||
@@ -38452,40 +38433,24 @@ END_JUCE_NAMESPACE | |||
/*** Start of inlined file: juce_ChangeBroadcaster.cpp ***/ | |||
BEGIN_JUCE_NAMESPACE | |||
class ChangeBroadcaster::ChangeBroadcasterMessage : public CallbackMessage | |||
{ | |||
public: | |||
ChangeBroadcasterMessage (ChangeBroadcaster* const owner_) | |||
: owner (owner_) | |||
{ | |||
} | |||
void messageCallback() | |||
{ | |||
if (owner != 0 && owner->pendingMessage.value == this) | |||
owner->sendSynchronousChangeMessage(); | |||
} | |||
ChangeBroadcaster* owner; | |||
}; | |||
ChangeBroadcaster::ChangeBroadcaster() throw() | |||
{ | |||
// are you trying to create this object before or after juce has been intialised?? | |||
jassert (MessageManager::instance != 0); | |||
callback.owner = this; | |||
} | |||
ChangeBroadcaster::~ChangeBroadcaster() | |||
{ | |||
// all event-based objects must be deleted BEFORE juce is shut down! | |||
jassert (MessageManager::instance != 0); | |||
invalidatePendingMessage(); | |||
} | |||
void ChangeBroadcaster::addChangeListener (ChangeListener* const listener) | |||
{ | |||
// Listeners can only be safely added when the event thread is locked... | |||
// Listeners can only be safely added when the event thread is locked | |||
// You can use a MessageManagerLock if you need to call this from another thread. | |||
jassert (MessageManager::getInstance()->currentThreadHasLockedMessageManager()); | |||
changeListeners.add (listener); | |||
@@ -38493,7 +38458,8 @@ void ChangeBroadcaster::addChangeListener (ChangeListener* const listener) | |||
void ChangeBroadcaster::removeChangeListener (ChangeListener* const listener) | |||
{ | |||
// Listeners can only be safely added when the event thread is locked... | |||
// Listeners can only be safely added when the event thread is locked | |||
// You can use a MessageManagerLock if you need to call this from another thread. | |||
jassert (MessageManager::getInstance()->currentThreadHasLockedMessageManager()); | |||
changeListeners.remove (listener); | |||
@@ -38501,28 +38467,17 @@ void ChangeBroadcaster::removeChangeListener (ChangeListener* const listener) | |||
void ChangeBroadcaster::removeAllChangeListeners() | |||
{ | |||
// Listeners can only be safely added when the event thread is locked... | |||
// Listeners can only be safely added when the event thread is locked | |||
// You can use a MessageManagerLock if you need to call this from another thread. | |||
jassert (MessageManager::getInstance()->currentThreadHasLockedMessageManager()); | |||
changeListeners.clear(); | |||
} | |||
void ChangeBroadcaster::invalidatePendingMessage() | |||
{ | |||
ChangeBroadcasterMessage* const oldMessage = pendingMessage.exchange (0); | |||
if (oldMessage != 0) | |||
oldMessage->owner = 0; | |||
} | |||
void ChangeBroadcaster::sendChangeMessage() | |||
{ | |||
if (pendingMessage.value == 0 && changeListeners.size() > 0) | |||
{ | |||
ScopedPointer<ChangeBroadcasterMessage> pending (new ChangeBroadcasterMessage (this)); | |||
if (pendingMessage.compareAndSetBool (pending, 0)) | |||
pending.release()->post(); | |||
} | |||
if (changeListeners.size() > 0) | |||
callback.triggerAsyncUpdate(); | |||
} | |||
void ChangeBroadcaster::sendSynchronousChangeMessage() | |||
@@ -38530,14 +38485,29 @@ void ChangeBroadcaster::sendSynchronousChangeMessage() | |||
// This can only be called by the event thread. | |||
jassert (MessageManager::getInstance()->isThisTheMessageThread()); | |||
invalidatePendingMessage(); | |||
changeListeners.call (&ChangeListener::changeListenerCallback, this); | |||
callback.cancelPendingUpdate(); | |||
callListeners(); | |||
} | |||
void ChangeBroadcaster::dispatchPendingMessages() | |||
{ | |||
if (pendingMessage.get() != 0) | |||
sendSynchronousChangeMessage(); | |||
callback.handleUpdateNowIfNeeded(); | |||
} | |||
void ChangeBroadcaster::callListeners() | |||
{ | |||
changeListeners.call (&ChangeListener::changeListenerCallback, this); | |||
} | |||
ChangeBroadcaster::ChangeBroadcasterCallback::ChangeBroadcasterCallback() | |||
: owner (0) | |||
{ | |||
} | |||
void ChangeBroadcaster::ChangeBroadcasterCallback::handleAsyncUpdate() | |||
{ | |||
jassert (owner != 0); | |||
owner->callListeners(); | |||
} | |||
END_JUCE_NAMESPACE | |||
@@ -38955,7 +38925,8 @@ Message::Message() throw() | |||
: intParameter1 (0), | |||
intParameter2 (0), | |||
intParameter3 (0), | |||
pointerParameter (0) | |||
pointerParameter (0), | |||
messageRecipient (0) | |||
{ | |||
} | |||
@@ -38966,7 +38937,8 @@ Message::Message (const int intParameter1_, | |||
: intParameter1 (intParameter1_), | |||
intParameter2 (intParameter2_), | |||
intParameter3 (intParameter3_), | |||
pointerParameter (pointerParameter_) | |||
pointerParameter (pointerParameter_), | |||
messageRecipient (0) | |||
{ | |||
} | |||
@@ -39037,7 +39009,7 @@ MessageManager::MessageManager() throw() | |||
MessageManager::~MessageManager() throw() | |||
{ | |||
broadcastListeners = 0; | |||
broadcaster = 0; | |||
doPlatformSpecificShutdown(); | |||
@@ -39068,47 +39040,40 @@ void MessageManager::postMessageToQueue (Message* const message) | |||
delete message; | |||
} | |||
CallbackMessage::CallbackMessage() throw() {} | |||
CallbackMessage::~CallbackMessage() {} | |||
CallbackMessage::CallbackMessage() throw() {} | |||
CallbackMessage::~CallbackMessage() {} | |||
void CallbackMessage::post() | |||
{ | |||
if (MessageManager::instance != 0) | |||
MessageManager::instance->postCallbackMessage (this); | |||
} | |||
void MessageManager::postCallbackMessage (Message* const message) | |||
{ | |||
message->messageRecipient = 0; | |||
postMessageToQueue (message); | |||
MessageManager::instance->postMessageToQueue (this); | |||
} | |||
// not for public use.. | |||
void MessageManager::deliverMessage (Message* const message) | |||
{ | |||
const ScopedPointer <Message> messageDeleter (message); | |||
MessageListener* const recipient = message->messageRecipient; | |||
JUCE_TRY | |||
{ | |||
if (messageListeners.contains (recipient)) | |||
{ | |||
recipient->handleMessage (*message); | |||
} | |||
else if (recipient == 0) | |||
const ScopedPointer <Message> messageDeleter (message); | |||
MessageListener* const recipient = message->messageRecipient; | |||
if (recipient == 0) | |||
{ | |||
if (message->intParameter1 == quitMessageId) | |||
CallbackMessage* const callbackMessage = dynamic_cast <CallbackMessage*> (message); | |||
if (callbackMessage != 0) | |||
{ | |||
quitMessageReceived = true; | |||
callbackMessage->messageCallback(); | |||
} | |||
else | |||
else if (message->intParameter1 == quitMessageId) | |||
{ | |||
CallbackMessage* const cm = dynamic_cast <CallbackMessage*> (message); | |||
if (cm != 0) | |||
cm->messageCallback(); | |||
quitMessageReceived = true; | |||
} | |||
} | |||
else if (messageListeners.contains (recipient)) | |||
{ | |||
recipient->handleMessage (*message); | |||
} | |||
} | |||
JUCE_CATCH_EXCEPTION | |||
} | |||
@@ -39123,10 +39088,7 @@ void MessageManager::runDispatchLoop() | |||
void MessageManager::stopDispatchLoop() | |||
{ | |||
Message* const m = new Message (quitMessageId, 0, 0, 0); | |||
m->messageRecipient = 0; | |||
postMessageToQueue (m); | |||
postMessageToQueue (new Message (quitMessageId, 0, 0, 0)); | |||
quitMessagePosted = true; | |||
} | |||
@@ -39159,22 +39121,22 @@ bool MessageManager::runDispatchLoopUntil (int millisecondsToRunFor) | |||
void MessageManager::deliverBroadcastMessage (const String& value) | |||
{ | |||
if (broadcastListeners != 0) | |||
broadcastListeners->sendActionMessage (value); | |||
if (broadcaster != 0) | |||
broadcaster->sendActionMessage (value); | |||
} | |||
void MessageManager::registerBroadcastListener (ActionListener* const listener) | |||
{ | |||
if (broadcastListeners == 0) | |||
broadcastListeners = new ActionListenerList(); | |||
if (broadcaster == 0) | |||
broadcaster = new ActionBroadcaster(); | |||
broadcastListeners->addActionListener (listener); | |||
broadcaster->addActionListener (listener); | |||
} | |||
void MessageManager::deregisterBroadcastListener (ActionListener* const listener) | |||
{ | |||
if (broadcastListeners != 0) | |||
broadcastListeners->removeActionListener (listener); | |||
if (broadcaster != 0) | |||
broadcaster->removeActionListener (listener); | |||
} | |||
bool MessageManager::isThisTheMessageThread() const throw() | |||
@@ -39213,7 +39175,6 @@ class MessageManagerLock::SharedEvents : public ReferenceCountedObject | |||
{ | |||
public: | |||
SharedEvents() {} | |||
~SharedEvents() {} | |||
/* This class just holds a couple of events to communicate between the BlockingMessage | |||
and the MessageManagerLock. Because both of these objects may be deleted at any time, | |||
@@ -39229,7 +39190,6 @@ class MessageManagerLock::BlockingMessage : public CallbackMessage | |||
{ | |||
public: | |||
BlockingMessage (MessageManagerLock::SharedEvents* const events_) : events (events_) {} | |||
~BlockingMessage() throw() {} | |||
void messageCallback() | |||
{ | |||
@@ -64,7 +64,7 @@ | |||
*/ | |||
#define JUCE_MAJOR_VERSION 1 | |||
#define JUCE_MINOR_VERSION 52 | |||
#define JUCE_BUILDNUMBER 93 | |||
#define JUCE_BUILDNUMBER 94 | |||
/** Current Juce version number. | |||
@@ -12281,131 +12281,6 @@ private: | |||
#ifndef __JUCE_ASYNCUPDATER_JUCEHEADER__ | |||
#define __JUCE_ASYNCUPDATER_JUCEHEADER__ | |||
/*** Start of inlined file: juce_MessageListener.h ***/ | |||
#ifndef __JUCE_MESSAGELISTENER_JUCEHEADER__ | |||
#define __JUCE_MESSAGELISTENER_JUCEHEADER__ | |||
/*** Start of inlined file: juce_Message.h ***/ | |||
#ifndef __JUCE_MESSAGE_JUCEHEADER__ | |||
#define __JUCE_MESSAGE_JUCEHEADER__ | |||
class MessageListener; | |||
class MessageManager; | |||
/** The base class for objects that can be delivered to a MessageListener. | |||
The simplest Message object contains a few integer and pointer parameters | |||
that the user can set, and this is enough for a lot of purposes. For passing more | |||
complex data, subclasses of Message can also be used. | |||
@see MessageListener, MessageManager, ActionListener, ChangeListener | |||
*/ | |||
class JUCE_API Message | |||
{ | |||
public: | |||
/** Creates an uninitialised message. | |||
The class's variables will also be left uninitialised. | |||
*/ | |||
Message() throw(); | |||
/** Creates a message object, filling in the member variables. | |||
The corresponding public member variables will be set from the parameters | |||
passed in. | |||
*/ | |||
Message (int intParameter1, | |||
int intParameter2, | |||
int intParameter3, | |||
void* pointerParameter) throw(); | |||
/** Destructor. */ | |||
virtual ~Message(); | |||
// These values can be used for carrying simple data that the application needs to | |||
// pass around. For more complex messages, just create a subclass. | |||
int intParameter1; /**< user-defined integer value. */ | |||
int intParameter2; /**< user-defined integer value. */ | |||
int intParameter3; /**< user-defined integer value. */ | |||
void* pointerParameter; /**< user-defined pointer value. */ | |||
juce_UseDebuggingNewOperator | |||
private: | |||
friend class MessageListener; | |||
friend class MessageManager; | |||
MessageListener* messageRecipient; | |||
Message (const Message&); | |||
Message& operator= (const Message&); | |||
}; | |||
#endif // __JUCE_MESSAGE_JUCEHEADER__ | |||
/*** End of inlined file: juce_Message.h ***/ | |||
/** | |||
MessageListener subclasses can post and receive Message objects. | |||
@see Message, MessageManager, ActionListener, ChangeListener | |||
*/ | |||
class JUCE_API MessageListener | |||
{ | |||
protected: | |||
/** Creates a MessageListener. */ | |||
MessageListener() throw(); | |||
public: | |||
/** Destructor. | |||
When a MessageListener is deleted, it removes itself from a global list | |||
of registered listeners, so that the isValidMessageListener() method | |||
will no longer return true. | |||
*/ | |||
virtual ~MessageListener(); | |||
/** This is the callback method that receives incoming messages. | |||
This is called by the MessageManager from its dispatch loop. | |||
@see postMessage | |||
*/ | |||
virtual void handleMessage (const Message& message) = 0; | |||
/** Sends a message to the message queue, for asynchronous delivery to this listener | |||
later on. | |||
This method can be called safely by any thread. | |||
@param message the message object to send - this will be deleted | |||
automatically by the message queue, so don't keep any | |||
references to it after calling this method. | |||
@see handleMessage | |||
*/ | |||
void postMessage (Message* message) const throw(); | |||
/** Checks whether this MessageListener has been deleted. | |||
Although not foolproof, this method is safe to call on dangling or null | |||
pointers. A list of active MessageListeners is kept internally, so this | |||
checks whether the object is on this list or not. | |||
Note that it's possible to get a false-positive here, if an object is | |||
deleted and another is subsequently created that happens to be at the | |||
exact same memory location, but I can't think of a good way of avoiding | |||
this. | |||
*/ | |||
bool isValidMessageListener() const throw(); | |||
}; | |||
#endif // __JUCE_MESSAGELISTENER_JUCEHEADER__ | |||
/*** End of inlined file: juce_MessageListener.h ***/ | |||
/** | |||
Has a callback method that is triggered asynchronously. | |||
@@ -12454,9 +12329,15 @@ public: | |||
Use this as a kind of "flush" operation - if an update is pending, the | |||
handleAsyncUpdate() method will be called immediately; if no update is | |||
pending, then nothing will be done. | |||
Because this may invoke the callback, this method must only be called on | |||
the main event thread. | |||
*/ | |||
void handleUpdateNowIfNeeded(); | |||
/** Returns true if there's an update callback in the pipeline. */ | |||
bool isUpdatePending() const throw(); | |||
/** Called back to do whatever your class needs to do. | |||
This method is called by the message thread at the next convenient time | |||
@@ -12466,23 +12347,10 @@ public: | |||
private: | |||
class AsyncUpdaterInternal : public MessageListener | |||
{ | |||
public: | |||
AsyncUpdaterInternal() {} | |||
~AsyncUpdaterInternal() {} | |||
void handleMessage (const Message&); | |||
AsyncUpdater* owner; | |||
private: | |||
AsyncUpdaterInternal (const AsyncUpdaterInternal&); | |||
AsyncUpdaterInternal& operator= (const AsyncUpdaterInternal&); | |||
}; | |||
class AsyncUpdaterMessage; | |||
friend class AsyncUpdaterMessage; | |||
AsyncUpdaterInternal internalAsyncHandler; | |||
bool asyncMessagePending; | |||
Atomic<AsyncUpdaterMessage*> pendingMessage; | |||
}; | |||
#endif // __JUCE_ASYNCUPDATER_JUCEHEADER__ | |||
@@ -13099,13 +12967,20 @@ public: | |||
private: | |||
class ChangeBroadcasterMessage; | |||
friend class ChangeBroadcasterMessage; | |||
class ChangeBroadcasterCallback : public AsyncUpdater | |||
{ | |||
public: | |||
ChangeBroadcasterCallback(); | |||
void handleAsyncUpdate(); | |||
ChangeBroadcaster* owner; | |||
}; | |||
Atomic<ChangeBroadcasterMessage*> pendingMessage; | |||
friend class ChangeBroadcasterCallback; | |||
ChangeBroadcasterCallback callback; | |||
ListenerList <ChangeListener> changeListeners; | |||
void invalidatePendingMessage(); | |||
void callListeners(); | |||
ChangeBroadcaster (const ChangeBroadcaster&); | |||
ChangeBroadcaster& operator= (const ChangeBroadcaster&); | |||
@@ -28302,6 +28177,131 @@ struct JUCE_API ApplicationCommandInfo | |||
#endif // __JUCE_APPLICATIONCOMMANDINFO_JUCEHEADER__ | |||
/*** End of inlined file: juce_ApplicationCommandInfo.h ***/ | |||
/*** Start of inlined file: juce_MessageListener.h ***/ | |||
#ifndef __JUCE_MESSAGELISTENER_JUCEHEADER__ | |||
#define __JUCE_MESSAGELISTENER_JUCEHEADER__ | |||
/*** Start of inlined file: juce_Message.h ***/ | |||
#ifndef __JUCE_MESSAGE_JUCEHEADER__ | |||
#define __JUCE_MESSAGE_JUCEHEADER__ | |||
class MessageListener; | |||
class MessageManager; | |||
/** The base class for objects that can be delivered to a MessageListener. | |||
The simplest Message object contains a few integer and pointer parameters | |||
that the user can set, and this is enough for a lot of purposes. For passing more | |||
complex data, subclasses of Message can also be used. | |||
@see MessageListener, MessageManager, ActionListener, ChangeListener | |||
*/ | |||
class JUCE_API Message | |||
{ | |||
public: | |||
/** Creates an uninitialised message. | |||
The class's variables will also be left uninitialised. | |||
*/ | |||
Message() throw(); | |||
/** Creates a message object, filling in the member variables. | |||
The corresponding public member variables will be set from the parameters | |||
passed in. | |||
*/ | |||
Message (int intParameter1, | |||
int intParameter2, | |||
int intParameter3, | |||
void* pointerParameter) throw(); | |||
/** Destructor. */ | |||
virtual ~Message(); | |||
// These values can be used for carrying simple data that the application needs to | |||
// pass around. For more complex messages, just create a subclass. | |||
int intParameter1; /**< user-defined integer value. */ | |||
int intParameter2; /**< user-defined integer value. */ | |||
int intParameter3; /**< user-defined integer value. */ | |||
void* pointerParameter; /**< user-defined pointer value. */ | |||
juce_UseDebuggingNewOperator | |||
private: | |||
friend class MessageListener; | |||
friend class MessageManager; | |||
MessageListener* messageRecipient; | |||
Message (const Message&); | |||
Message& operator= (const Message&); | |||
}; | |||
#endif // __JUCE_MESSAGE_JUCEHEADER__ | |||
/*** End of inlined file: juce_Message.h ***/ | |||
/** | |||
MessageListener subclasses can post and receive Message objects. | |||
@see Message, MessageManager, ActionListener, ChangeListener | |||
*/ | |||
class JUCE_API MessageListener | |||
{ | |||
protected: | |||
/** Creates a MessageListener. */ | |||
MessageListener() throw(); | |||
public: | |||
/** Destructor. | |||
When a MessageListener is deleted, it removes itself from a global list | |||
of registered listeners, so that the isValidMessageListener() method | |||
will no longer return true. | |||
*/ | |||
virtual ~MessageListener(); | |||
/** This is the callback method that receives incoming messages. | |||
This is called by the MessageManager from its dispatch loop. | |||
@see postMessage | |||
*/ | |||
virtual void handleMessage (const Message& message) = 0; | |||
/** Sends a message to the message queue, for asynchronous delivery to this listener | |||
later on. | |||
This method can be called safely by any thread. | |||
@param message the message object to send - this will be deleted | |||
automatically by the message queue, so don't keep any | |||
references to it after calling this method. | |||
@see handleMessage | |||
*/ | |||
void postMessage (Message* message) const throw(); | |||
/** Checks whether this MessageListener has been deleted. | |||
Although not foolproof, this method is safe to call on dangling or null | |||
pointers. A list of active MessageListeners is kept internally, so this | |||
checks whether the object is on this list or not. | |||
Note that it's possible to get a false-positive here, if an object is | |||
deleted and another is subsequently created that happens to be at the | |||
exact same memory location, but I can't think of a good way of avoiding | |||
this. | |||
*/ | |||
bool isValidMessageListener() const throw(); | |||
}; | |||
#endif // __JUCE_MESSAGELISTENER_JUCEHEADER__ | |||
/*** End of inlined file: juce_MessageListener.h ***/ | |||
/** | |||
A command target publishes a list of command IDs that it can perform. | |||
@@ -28537,7 +28537,7 @@ private: | |||
Used by various classes, e.g. buttons when they are pressed, to tell listeners | |||
about something that's happened. | |||
@see ActionListenerList, ActionBroadcaster, ChangeListener | |||
@see ActionBroadcaster, ChangeListener | |||
*/ | |||
class JUCE_API ActionListener | |||
{ | |||
@@ -28548,7 +28548,7 @@ public: | |||
/** Overridden by your subclass to receive the callback. | |||
@param message the string that was specified when the event was triggered | |||
by a call to ActionListenerList::sendActionMessage() | |||
by a call to ActionBroadcaster::sendActionMessage() | |||
*/ | |||
virtual void actionListenerCallback (const String& message) = 0; | |||
}; | |||
@@ -43380,96 +43380,29 @@ private: | |||
#ifndef __JUCE_ACTIONBROADCASTER_JUCEHEADER__ | |||
#define __JUCE_ACTIONBROADCASTER_JUCEHEADER__ | |||
/*** Start of inlined file: juce_ActionListenerList.h ***/ | |||
#ifndef __JUCE_ACTIONLISTENERLIST_JUCEHEADER__ | |||
#define __JUCE_ACTIONLISTENERLIST_JUCEHEADER__ | |||
/** | |||
A set of ActionListeners. | |||
Listeners can be added and removed from the list, and messages can be | |||
broadcast to all the listeners. | |||
@see ActionListener, ActionBroadcaster | |||
*/ | |||
class JUCE_API ActionListenerList : public MessageListener | |||
{ | |||
public: | |||
/** Creates an empty list. */ | |||
ActionListenerList(); | |||
/** Destructor. */ | |||
~ActionListenerList(); | |||
/** Adds a listener to the list. | |||
(Trying to add a listener that's already on the list will have no effect). | |||
*/ | |||
void addActionListener (ActionListener* listener); | |||
/** Removes a listener from the list. | |||
If the listener isn't on the list, this won't have any effect. | |||
*/ | |||
void removeActionListener (ActionListener* listener); | |||
/** Removes all listeners from the list. */ | |||
void removeAllActionListeners(); | |||
/** Broadcasts a message to all the registered listeners. | |||
This sends the message asynchronously. | |||
If a listener is on the list when this method is called but is removed from | |||
the list before the message arrives, it won't receive the message. Similarly | |||
listeners that are added to the list after the message is sent but before it | |||
arrives won't get the message either. | |||
*/ | |||
void sendActionMessage (const String& message) const; | |||
/** @internal */ | |||
void handleMessage (const Message&); | |||
juce_UseDebuggingNewOperator | |||
private: | |||
SortedSet <void*> actionListeners_; | |||
CriticalSection actionListenerLock_; | |||
ActionListenerList (const ActionListenerList&); | |||
ActionListenerList& operator= (const ActionListenerList&); | |||
}; | |||
#endif // __JUCE_ACTIONLISTENERLIST_JUCEHEADER__ | |||
/*** End of inlined file: juce_ActionListenerList.h ***/ | |||
/** Manages a list of ActionListeners, and can send them messages. | |||
To quickly add methods to your class that can add/remove action | |||
listeners and broadcast to them, you can derive from this. | |||
@see ActionListenerList, ActionListener | |||
@see ActionListener, ChangeListener | |||
*/ | |||
class JUCE_API ActionBroadcaster | |||
{ | |||
public: | |||
/** Creates an ActionBroadcaster. */ | |||
ActionBroadcaster() throw(); | |||
ActionBroadcaster(); | |||
/** Destructor. */ | |||
virtual ~ActionBroadcaster(); | |||
/** Adds a listener to the list. | |||
(Trying to add a listener that's already on the list will have no effect). | |||
Trying to add a listener that's already on the list will have no effect. | |||
*/ | |||
void addActionListener (ActionListener* listener); | |||
/** Removes a listener from the list. | |||
If the listener isn't on the list, this won't have any effect. | |||
*/ | |||
void removeActionListener (ActionListener* listener); | |||
@@ -43478,14 +43411,25 @@ public: | |||
void removeAllActionListeners(); | |||
/** Broadcasts a message to all the registered listeners. | |||
@see ActionListenerList::sendActionMessage | |||
@see ActionListener::actionListenerCallback | |||
*/ | |||
void sendActionMessage (const String& message) const; | |||
private: | |||
ActionListenerList actionListenerList; | |||
class CallbackReceiver : public MessageListener | |||
{ | |||
public: | |||
CallbackReceiver(); | |||
void handleMessage (const Message&); | |||
ActionBroadcaster* owner; | |||
}; | |||
friend class CallbackReceiver; | |||
CallbackReceiver callback; | |||
SortedSet <ActionListener*> actionListeners; | |||
CriticalSection actionListenerLock; | |||
ActionBroadcaster (const ActionBroadcaster&); | |||
ActionBroadcaster& operator= (const ActionBroadcaster&); | |||
@@ -43498,9 +43442,6 @@ private: | |||
#endif | |||
#ifndef __JUCE_ACTIONLISTENER_JUCEHEADER__ | |||
#endif | |||
#ifndef __JUCE_ACTIONLISTENERLIST_JUCEHEADER__ | |||
#endif | |||
#ifndef __JUCE_ASYNCUPDATER_JUCEHEADER__ | |||
@@ -43980,7 +43921,7 @@ private: | |||
static MessageManager* instance; | |||
SortedSet <const MessageListener*> messageListeners; | |||
ScopedPointer <ActionListenerList> broadcastListeners; | |||
ScopedPointer <ActionBroadcaster> broadcaster; | |||
friend class JUCEApplication; | |||
bool quitMessagePosted, quitMessageReceived; | |||
@@ -43989,7 +43930,6 @@ private: | |||
static void* exitModalLoopCallback (void*); | |||
void postMessageToQueue (Message* message); | |||
void postCallbackMessage (Message* message); | |||
static void doPlatformSpecificInitialisation(); | |||
static void doPlatformSpecificShutdown(); | |||
@@ -28,6 +28,7 @@ | |||
#include "../gui/components/juce_Component.h" | |||
#include "juce_ApplicationCommandInfo.h" | |||
#include "../events/juce_MessageListener.h" | |||
//============================================================================== | |||
@@ -33,7 +33,7 @@ | |||
*/ | |||
#define JUCE_MAJOR_VERSION 1 | |||
#define JUCE_MINOR_VERSION 52 | |||
#define JUCE_BUILDNUMBER 93 | |||
#define JUCE_BUILDNUMBER 94 | |||
/** Current Juce version number. | |||
@@ -29,13 +29,45 @@ BEGIN_JUCE_NAMESPACE | |||
#include "juce_ActionBroadcaster.h" | |||
#include "juce_MessageManager.h" | |||
#include "../threads/juce_ScopedLock.h" | |||
//============================================================================== | |||
ActionBroadcaster::ActionBroadcaster() throw() | |||
// special message of our own with a string in it | |||
class ActionMessage : public Message | |||
{ | |||
public: | |||
const String message; | |||
ActionMessage (const String& messageText, ActionListener* const listener_) throw() | |||
: message (messageText) | |||
{ | |||
pointerParameter = listener_; | |||
} | |||
private: | |||
ActionMessage (const ActionMessage&); | |||
ActionMessage& operator= (const ActionMessage&); | |||
}; | |||
ActionBroadcaster::CallbackReceiver::CallbackReceiver() {} | |||
void ActionBroadcaster::CallbackReceiver::handleMessage (const Message& message) | |||
{ | |||
const ActionMessage& am = static_cast <const ActionMessage&> (message); | |||
ActionListener* const target = static_cast <ActionListener*> (am.pointerParameter); | |||
if (owner->actionListeners.contains (target)) | |||
target->actionListenerCallback (am.message); | |||
} | |||
//============================================================================== | |||
ActionBroadcaster::ActionBroadcaster() | |||
{ | |||
// are you trying to create this object before or after juce has been intialised?? | |||
jassert (MessageManager::instance != 0); | |||
callback.owner = this; | |||
} | |||
ActionBroadcaster::~ActionBroadcaster() | |||
@@ -46,25 +78,31 @@ ActionBroadcaster::~ActionBroadcaster() | |||
void ActionBroadcaster::addActionListener (ActionListener* const listener) | |||
{ | |||
actionListenerList.addActionListener (listener); | |||
const ScopedLock sl (actionListenerLock); | |||
if (listener != 0) | |||
actionListeners.add (listener); | |||
} | |||
void ActionBroadcaster::removeActionListener (ActionListener* const listener) | |||
{ | |||
jassert (actionListenerList.isValidMessageListener()); | |||
if (actionListenerList.isValidMessageListener()) | |||
actionListenerList.removeActionListener (listener); | |||
const ScopedLock sl (actionListenerLock); | |||
actionListeners.removeValue (listener); | |||
} | |||
void ActionBroadcaster::removeAllActionListeners() | |||
{ | |||
actionListenerList.removeAllActionListeners(); | |||
const ScopedLock sl (actionListenerLock); | |||
actionListeners.clear(); | |||
} | |||
void ActionBroadcaster::sendActionMessage (const String& message) const | |||
{ | |||
actionListenerList.sendActionMessage (message); | |||
const ScopedLock sl (actionListenerLock); | |||
for (int i = actionListeners.size(); --i >= 0;) | |||
callback.postMessage (new ActionMessage (message, actionListeners.getUnchecked(i))); | |||
} | |||
END_JUCE_NAMESPACE |
@@ -26,7 +26,9 @@ | |||
#ifndef __JUCE_ACTIONBROADCASTER_JUCEHEADER__ | |||
#define __JUCE_ACTIONBROADCASTER_JUCEHEADER__ | |||
#include "juce_ActionListenerList.h" | |||
#include "juce_ActionListener.h" | |||
#include "juce_MessageListener.h" | |||
#include "../containers/juce_SortedSet.h" | |||
//============================================================================== | |||
@@ -35,27 +37,25 @@ | |||
To quickly add methods to your class that can add/remove action | |||
listeners and broadcast to them, you can derive from this. | |||
@see ActionListenerList, ActionListener | |||
@see ActionListener, ChangeListener | |||
*/ | |||
class JUCE_API ActionBroadcaster | |||
{ | |||
public: | |||
//============================================================================== | |||
/** Creates an ActionBroadcaster. */ | |||
ActionBroadcaster() throw(); | |||
ActionBroadcaster(); | |||
/** Destructor. */ | |||
virtual ~ActionBroadcaster(); | |||
//============================================================================== | |||
/** Adds a listener to the list. | |||
(Trying to add a listener that's already on the list will have no effect). | |||
Trying to add a listener that's already on the list will have no effect. | |||
*/ | |||
void addActionListener (ActionListener* listener); | |||
/** Removes a listener from the list. | |||
If the listener isn't on the list, this won't have any effect. | |||
*/ | |||
void removeActionListener (ActionListener* listener); | |||
@@ -65,15 +65,26 @@ public: | |||
//============================================================================== | |||
/** Broadcasts a message to all the registered listeners. | |||
@see ActionListenerList::sendActionMessage | |||
@see ActionListener::actionListenerCallback | |||
*/ | |||
void sendActionMessage (const String& message) const; | |||
private: | |||
//============================================================================== | |||
ActionListenerList actionListenerList; | |||
class CallbackReceiver : public MessageListener | |||
{ | |||
public: | |||
CallbackReceiver(); | |||
void handleMessage (const Message&); | |||
ActionBroadcaster* owner; | |||
}; | |||
friend class CallbackReceiver; | |||
CallbackReceiver callback; | |||
SortedSet <ActionListener*> actionListeners; | |||
CriticalSection actionListenerLock; | |||
ActionBroadcaster (const ActionBroadcaster&); | |||
ActionBroadcaster& operator= (const ActionBroadcaster&); | |||
@@ -36,7 +36,7 @@ | |||
Used by various classes, e.g. buttons when they are pressed, to tell listeners | |||
about something that's happened. | |||
@see ActionListenerList, ActionBroadcaster, ChangeListener | |||
@see ActionBroadcaster, ChangeListener | |||
*/ | |||
class JUCE_API ActionListener | |||
{ | |||
@@ -47,7 +47,7 @@ public: | |||
/** Overridden by your subclass to receive the callback. | |||
@param message the string that was specified when the event was triggered | |||
by a call to ActionListenerList::sendActionMessage() | |||
by a call to ActionBroadcaster::sendActionMessage() | |||
*/ | |||
virtual void actionListenerCallback (const String& message) = 0; | |||
}; | |||
@@ -1,108 +0,0 @@ | |||
/* | |||
============================================================================== | |||
This file is part of the JUCE library - "Jules' Utility Class Extensions" | |||
Copyright 2004-10 by Raw Material Software Ltd. | |||
------------------------------------------------------------------------------ | |||
JUCE can be redistributed and/or modified under the terms of the GNU General | |||
Public License (Version 2), as published by the Free Software Foundation. | |||
A copy of the license is included in the JUCE distribution, or can be found | |||
online at www.gnu.org/licenses. | |||
JUCE is distributed in the hope that it will be useful, but WITHOUT ANY | |||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR | |||
A PARTICULAR PURPOSE. See the GNU General Public License for more details. | |||
------------------------------------------------------------------------------ | |||
To release a closed-source product which uses JUCE, commercial licenses are | |||
available: visit www.rawmaterialsoftware.com/juce for more information. | |||
============================================================================== | |||
*/ | |||
#include "../core/juce_StandardHeader.h" | |||
BEGIN_JUCE_NAMESPACE | |||
#include "juce_ActionListenerList.h" | |||
#include "../threads/juce_ScopedLock.h" | |||
//============================================================================== | |||
// special message of our own with a string in it | |||
class ActionMessage : public Message | |||
{ | |||
public: | |||
const String message; | |||
ActionMessage (const String& messageText, void* const listener_) throw() | |||
: message (messageText) | |||
{ | |||
pointerParameter = listener_; | |||
} | |||
~ActionMessage() throw() | |||
{ | |||
} | |||
private: | |||
ActionMessage (const ActionMessage&); | |||
ActionMessage& operator= (const ActionMessage&); | |||
}; | |||
//============================================================================== | |||
ActionListenerList::ActionListenerList() | |||
{ | |||
} | |||
ActionListenerList::~ActionListenerList() | |||
{ | |||
} | |||
void ActionListenerList::addActionListener (ActionListener* const listener) | |||
{ | |||
const ScopedLock sl (actionListenerLock_); | |||
jassert (listener != 0); | |||
jassert (! actionListeners_.contains (listener)); // trying to add a listener to the list twice! | |||
if (listener != 0) | |||
actionListeners_.add (listener); | |||
} | |||
void ActionListenerList::removeActionListener (ActionListener* const listener) | |||
{ | |||
const ScopedLock sl (actionListenerLock_); | |||
jassert (actionListeners_.contains (listener)); // trying to remove a listener that isn't on the list! | |||
actionListeners_.removeValue (listener); | |||
} | |||
void ActionListenerList::removeAllActionListeners() | |||
{ | |||
const ScopedLock sl (actionListenerLock_); | |||
actionListeners_.clear(); | |||
} | |||
void ActionListenerList::sendActionMessage (const String& message) const | |||
{ | |||
const ScopedLock sl (actionListenerLock_); | |||
for (int i = actionListeners_.size(); --i >= 0;) | |||
postMessage (new ActionMessage (message, static_cast <ActionListener*> (actionListeners_.getUnchecked(i)))); | |||
} | |||
void ActionListenerList::handleMessage (const Message& message) | |||
{ | |||
const ActionMessage& am = (const ActionMessage&) message; | |||
if (actionListeners_.contains (am.pointerParameter)) | |||
static_cast <ActionListener*> (am.pointerParameter)->actionListenerCallback (am.message); | |||
} | |||
END_JUCE_NAMESPACE |
@@ -1,96 +0,0 @@ | |||
/* | |||
============================================================================== | |||
This file is part of the JUCE library - "Jules' Utility Class Extensions" | |||
Copyright 2004-10 by Raw Material Software Ltd. | |||
------------------------------------------------------------------------------ | |||
JUCE can be redistributed and/or modified under the terms of the GNU General | |||
Public License (Version 2), as published by the Free Software Foundation. | |||
A copy of the license is included in the JUCE distribution, or can be found | |||
online at www.gnu.org/licenses. | |||
JUCE is distributed in the hope that it will be useful, but WITHOUT ANY | |||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR | |||
A PARTICULAR PURPOSE. See the GNU General Public License for more details. | |||
------------------------------------------------------------------------------ | |||
To release a closed-source product which uses JUCE, commercial licenses are | |||
available: visit www.rawmaterialsoftware.com/juce for more information. | |||
============================================================================== | |||
*/ | |||
#ifndef __JUCE_ACTIONLISTENERLIST_JUCEHEADER__ | |||
#define __JUCE_ACTIONLISTENERLIST_JUCEHEADER__ | |||
#include "juce_ActionListener.h" | |||
#include "juce_MessageListener.h" | |||
#include "../containers/juce_SortedSet.h" | |||
#include "../threads/juce_CriticalSection.h" | |||
//============================================================================== | |||
/** | |||
A set of ActionListeners. | |||
Listeners can be added and removed from the list, and messages can be | |||
broadcast to all the listeners. | |||
@see ActionListener, ActionBroadcaster | |||
*/ | |||
class JUCE_API ActionListenerList : public MessageListener | |||
{ | |||
public: | |||
//============================================================================== | |||
/** Creates an empty list. */ | |||
ActionListenerList(); | |||
/** Destructor. */ | |||
~ActionListenerList(); | |||
//============================================================================== | |||
/** Adds a listener to the list. | |||
(Trying to add a listener that's already on the list will have no effect). | |||
*/ | |||
void addActionListener (ActionListener* listener); | |||
/** Removes a listener from the list. | |||
If the listener isn't on the list, this won't have any effect. | |||
*/ | |||
void removeActionListener (ActionListener* listener); | |||
/** Removes all listeners from the list. */ | |||
void removeAllActionListeners(); | |||
/** Broadcasts a message to all the registered listeners. | |||
This sends the message asynchronously. | |||
If a listener is on the list when this method is called but is removed from | |||
the list before the message arrives, it won't receive the message. Similarly | |||
listeners that are added to the list after the message is sent but before it | |||
arrives won't get the message either. | |||
*/ | |||
void sendActionMessage (const String& message) const; | |||
//============================================================================== | |||
/** @internal */ | |||
void handleMessage (const Message&); | |||
juce_UseDebuggingNewOperator | |||
private: | |||
SortedSet <void*> actionListeners_; | |||
CriticalSection actionListenerLock_; | |||
ActionListenerList (const ActionListenerList&); | |||
ActionListenerList& operator= (const ActionListenerList&); | |||
}; | |||
#endif // __JUCE_ACTIONLISTENERLIST_JUCEHEADER__ |
@@ -28,45 +28,73 @@ | |||
BEGIN_JUCE_NAMESPACE | |||
#include "juce_AsyncUpdater.h" | |||
#include "juce_CallbackMessage.h" | |||
#include "../containers/juce_ScopedPointer.h" | |||
#include "juce_MessageManager.h" | |||
//============================================================================== | |||
class AsyncUpdater::AsyncUpdaterMessage : public CallbackMessage | |||
{ | |||
public: | |||
AsyncUpdaterMessage (AsyncUpdater& owner_) | |||
: owner (owner_) | |||
{ | |||
} | |||
void messageCallback() | |||
{ | |||
if (owner.pendingMessage.compareAndSetBool (0, this)) | |||
owner.handleAsyncUpdate(); | |||
} | |||
AsyncUpdater& owner; | |||
}; | |||
//============================================================================== | |||
AsyncUpdater::AsyncUpdater() throw() | |||
: asyncMessagePending (false) | |||
{ | |||
internalAsyncHandler.owner = 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::getInstance()->currentThreadHasLockedMessageManager()); | |||
pendingMessage = 0; | |||
} | |||
void AsyncUpdater::triggerAsyncUpdate() | |||
{ | |||
if (! asyncMessagePending) | |||
if (pendingMessage.value == 0) | |||
{ | |||
asyncMessagePending = true; | |||
internalAsyncHandler.postMessage (new Message()); | |||
ScopedPointer<AsyncUpdaterMessage> pending (new AsyncUpdaterMessage (*this)); | |||
if (pendingMessage.compareAndSetBool (pending, 0)) | |||
pending.release()->post(); | |||
} | |||
} | |||
void AsyncUpdater::cancelPendingUpdate() throw() | |||
{ | |||
asyncMessagePending = false; | |||
pendingMessage = 0; | |||
} | |||
void AsyncUpdater::handleUpdateNowIfNeeded() | |||
{ | |||
if (asyncMessagePending) | |||
{ | |||
asyncMessagePending = false; | |||
// This can only be called by the event thread. | |||
jassert (MessageManager::getInstance()->currentThreadHasLockedMessageManager()); | |||
if (pendingMessage.exchange (0) != 0) | |||
handleAsyncUpdate(); | |||
} | |||
} | |||
void AsyncUpdater::AsyncUpdaterInternal::handleMessage (const Message&) | |||
bool AsyncUpdater::isUpdatePending() const throw() | |||
{ | |||
owner->handleUpdateNowIfNeeded(); | |||
return pendingMessage.value != 0; | |||
} | |||
@@ -26,7 +26,7 @@ | |||
#ifndef __JUCE_ASYNCUPDATER_JUCEHEADER__ | |||
#define __JUCE_ASYNCUPDATER_JUCEHEADER__ | |||
#include "juce_MessageListener.h" | |||
#include "../core/juce_Atomic.h" | |||
//============================================================================== | |||
@@ -79,9 +79,15 @@ public: | |||
Use this as a kind of "flush" operation - if an update is pending, the | |||
handleAsyncUpdate() method will be called immediately; if no update is | |||
pending, then nothing will be done. | |||
Because this may invoke the callback, this method must only be called on | |||
the main event thread. | |||
*/ | |||
void handleUpdateNowIfNeeded(); | |||
/** Returns true if there's an update callback in the pipeline. */ | |||
bool isUpdatePending() const throw(); | |||
//============================================================================== | |||
/** Called back to do whatever your class needs to do. | |||
@@ -93,23 +99,10 @@ public: | |||
private: | |||
//============================================================================== | |||
class AsyncUpdaterInternal : public MessageListener | |||
{ | |||
public: | |||
AsyncUpdaterInternal() {} | |||
~AsyncUpdaterInternal() {} | |||
void handleMessage (const Message&); | |||
AsyncUpdater* owner; | |||
private: | |||
AsyncUpdaterInternal (const AsyncUpdaterInternal&); | |||
AsyncUpdaterInternal& operator= (const AsyncUpdaterInternal&); | |||
}; | |||
class AsyncUpdaterMessage; | |||
friend class AsyncUpdaterMessage; | |||
AsyncUpdaterInternal internalAsyncHandler; | |||
bool asyncMessagePending; | |||
Atomic<AsyncUpdaterMessage*> pendingMessage; | |||
}; | |||
@@ -31,42 +31,25 @@ BEGIN_JUCE_NAMESPACE | |||
#include "juce_MessageManager.h" | |||
//============================================================================== | |||
class ChangeBroadcaster::ChangeBroadcasterMessage : public CallbackMessage | |||
{ | |||
public: | |||
ChangeBroadcasterMessage (ChangeBroadcaster* const owner_) | |||
: owner (owner_) | |||
{ | |||
} | |||
void messageCallback() | |||
{ | |||
if (owner != 0 && owner->pendingMessage.value == this) | |||
owner->sendSynchronousChangeMessage(); | |||
} | |||
ChangeBroadcaster* owner; | |||
}; | |||
//============================================================================== | |||
ChangeBroadcaster::ChangeBroadcaster() throw() | |||
{ | |||
// are you trying to create this object before or after juce has been intialised?? | |||
jassert (MessageManager::instance != 0); | |||
callback.owner = this; | |||
} | |||
ChangeBroadcaster::~ChangeBroadcaster() | |||
{ | |||
// all event-based objects must be deleted BEFORE juce is shut down! | |||
jassert (MessageManager::instance != 0); | |||
invalidatePendingMessage(); | |||
} | |||
void ChangeBroadcaster::addChangeListener (ChangeListener* const listener) | |||
{ | |||
// Listeners can only be safely added when the event thread is locked... | |||
// Listeners can only be safely added when the event thread is locked | |||
// You can use a MessageManagerLock if you need to call this from another thread. | |||
jassert (MessageManager::getInstance()->currentThreadHasLockedMessageManager()); | |||
changeListeners.add (listener); | |||
@@ -74,7 +57,8 @@ void ChangeBroadcaster::addChangeListener (ChangeListener* const listener) | |||
void ChangeBroadcaster::removeChangeListener (ChangeListener* const listener) | |||
{ | |||
// Listeners can only be safely added when the event thread is locked... | |||
// Listeners can only be safely added when the event thread is locked | |||
// You can use a MessageManagerLock if you need to call this from another thread. | |||
jassert (MessageManager::getInstance()->currentThreadHasLockedMessageManager()); | |||
changeListeners.remove (listener); | |||
@@ -82,28 +66,17 @@ void ChangeBroadcaster::removeChangeListener (ChangeListener* const listener) | |||
void ChangeBroadcaster::removeAllChangeListeners() | |||
{ | |||
// Listeners can only be safely added when the event thread is locked... | |||
// Listeners can only be safely added when the event thread is locked | |||
// You can use a MessageManagerLock if you need to call this from another thread. | |||
jassert (MessageManager::getInstance()->currentThreadHasLockedMessageManager()); | |||
changeListeners.clear(); | |||
} | |||
void ChangeBroadcaster::invalidatePendingMessage() | |||
{ | |||
ChangeBroadcasterMessage* const oldMessage = pendingMessage.exchange (0); | |||
if (oldMessage != 0) | |||
oldMessage->owner = 0; | |||
} | |||
void ChangeBroadcaster::sendChangeMessage() | |||
{ | |||
if (pendingMessage.value == 0 && changeListeners.size() > 0) | |||
{ | |||
ScopedPointer<ChangeBroadcasterMessage> pending (new ChangeBroadcasterMessage (this)); | |||
if (pendingMessage.compareAndSetBool (pending, 0)) | |||
pending.release()->post(); | |||
} | |||
if (changeListeners.size() > 0) | |||
callback.triggerAsyncUpdate(); | |||
} | |||
void ChangeBroadcaster::sendSynchronousChangeMessage() | |||
@@ -111,14 +84,30 @@ void ChangeBroadcaster::sendSynchronousChangeMessage() | |||
// This can only be called by the event thread. | |||
jassert (MessageManager::getInstance()->isThisTheMessageThread()); | |||
invalidatePendingMessage(); | |||
changeListeners.call (&ChangeListener::changeListenerCallback, this); | |||
callback.cancelPendingUpdate(); | |||
callListeners(); | |||
} | |||
void ChangeBroadcaster::dispatchPendingMessages() | |||
{ | |||
if (pendingMessage.get() != 0) | |||
sendSynchronousChangeMessage(); | |||
callback.handleUpdateNowIfNeeded(); | |||
} | |||
void ChangeBroadcaster::callListeners() | |||
{ | |||
changeListeners.call (&ChangeListener::changeListenerCallback, this); | |||
} | |||
//============================================================================== | |||
ChangeBroadcaster::ChangeBroadcasterCallback::ChangeBroadcasterCallback() | |||
: owner (0) | |||
{ | |||
} | |||
void ChangeBroadcaster::ChangeBroadcasterCallback::handleAsyncUpdate() | |||
{ | |||
jassert (owner != 0); | |||
owner->callListeners(); | |||
} | |||
@@ -28,7 +28,7 @@ | |||
#include "juce_ChangeListener.h" | |||
#include "juce_ListenerList.h" | |||
#include "../core/juce_Atomic.h" | |||
#include "juce_AsyncUpdater.h" | |||
//============================================================================== | |||
@@ -88,13 +88,20 @@ public: | |||
private: | |||
//============================================================================== | |||
class ChangeBroadcasterMessage; | |||
friend class ChangeBroadcasterMessage; | |||
class ChangeBroadcasterCallback : public AsyncUpdater | |||
{ | |||
public: | |||
ChangeBroadcasterCallback(); | |||
void handleAsyncUpdate(); | |||
Atomic<ChangeBroadcasterMessage*> pendingMessage; | |||
ChangeBroadcaster* owner; | |||
}; | |||
friend class ChangeBroadcasterCallback; | |||
ChangeBroadcasterCallback callback; | |||
ListenerList <ChangeListener> changeListeners; | |||
void invalidatePendingMessage(); | |||
void callListeners(); | |||
ChangeBroadcaster (const ChangeBroadcaster&); | |||
ChangeBroadcaster& operator= (const ChangeBroadcaster&); | |||
@@ -35,7 +35,8 @@ Message::Message() throw() | |||
: intParameter1 (0), | |||
intParameter2 (0), | |||
intParameter3 (0), | |||
pointerParameter (0) | |||
pointerParameter (0), | |||
messageRecipient (0) | |||
{ | |||
} | |||
@@ -46,7 +47,8 @@ Message::Message (const int intParameter1_, | |||
: intParameter1 (intParameter1_), | |||
intParameter2 (intParameter2_), | |||
intParameter3 (intParameter3_), | |||
pointerParameter (pointerParameter_) | |||
pointerParameter (pointerParameter_), | |||
messageRecipient (0) | |||
{ | |||
} | |||
@@ -28,7 +28,7 @@ | |||
BEGIN_JUCE_NAMESPACE | |||
#include "juce_MessageManager.h" | |||
#include "juce_ActionListenerList.h" | |||
#include "juce_ActionBroadcaster.h" | |||
#include "../application/juce_Application.h" | |||
#include "../gui/components/juce_Component.h" | |||
#include "../threads/juce_Thread.h" | |||
@@ -56,7 +56,7 @@ MessageManager::MessageManager() throw() | |||
MessageManager::~MessageManager() throw() | |||
{ | |||
broadcastListeners = 0; | |||
broadcaster = 0; | |||
doPlatformSpecificShutdown(); | |||
@@ -88,48 +88,41 @@ void MessageManager::postMessageToQueue (Message* const message) | |||
} | |||
//============================================================================== | |||
CallbackMessage::CallbackMessage() throw() {} | |||
CallbackMessage::~CallbackMessage() {} | |||
CallbackMessage::CallbackMessage() throw() {} | |||
CallbackMessage::~CallbackMessage() {} | |||
void CallbackMessage::post() | |||
{ | |||
if (MessageManager::instance != 0) | |||
MessageManager::instance->postCallbackMessage (this); | |||
} | |||
void MessageManager::postCallbackMessage (Message* const message) | |||
{ | |||
message->messageRecipient = 0; | |||
postMessageToQueue (message); | |||
MessageManager::instance->postMessageToQueue (this); | |||
} | |||
//============================================================================== | |||
// not for public use.. | |||
void MessageManager::deliverMessage (Message* const message) | |||
{ | |||
const ScopedPointer <Message> messageDeleter (message); | |||
MessageListener* const recipient = message->messageRecipient; | |||
JUCE_TRY | |||
{ | |||
if (messageListeners.contains (recipient)) | |||
{ | |||
recipient->handleMessage (*message); | |||
} | |||
else if (recipient == 0) | |||
const ScopedPointer <Message> messageDeleter (message); | |||
MessageListener* const recipient = message->messageRecipient; | |||
if (recipient == 0) | |||
{ | |||
if (message->intParameter1 == quitMessageId) | |||
CallbackMessage* const callbackMessage = dynamic_cast <CallbackMessage*> (message); | |||
if (callbackMessage != 0) | |||
{ | |||
quitMessageReceived = true; | |||
callbackMessage->messageCallback(); | |||
} | |||
else | |||
else if (message->intParameter1 == quitMessageId) | |||
{ | |||
CallbackMessage* const cm = dynamic_cast <CallbackMessage*> (message); | |||
if (cm != 0) | |||
cm->messageCallback(); | |||
quitMessageReceived = true; | |||
} | |||
} | |||
else if (messageListeners.contains (recipient)) | |||
{ | |||
recipient->handleMessage (*message); | |||
} | |||
} | |||
JUCE_CATCH_EXCEPTION | |||
} | |||
@@ -145,10 +138,7 @@ void MessageManager::runDispatchLoop() | |||
void MessageManager::stopDispatchLoop() | |||
{ | |||
Message* const m = new Message (quitMessageId, 0, 0, 0); | |||
m->messageRecipient = 0; | |||
postMessageToQueue (m); | |||
postMessageToQueue (new Message (quitMessageId, 0, 0, 0)); | |||
quitMessagePosted = true; | |||
} | |||
@@ -182,22 +172,22 @@ bool MessageManager::runDispatchLoopUntil (int millisecondsToRunFor) | |||
//============================================================================== | |||
void MessageManager::deliverBroadcastMessage (const String& value) | |||
{ | |||
if (broadcastListeners != 0) | |||
broadcastListeners->sendActionMessage (value); | |||
if (broadcaster != 0) | |||
broadcaster->sendActionMessage (value); | |||
} | |||
void MessageManager::registerBroadcastListener (ActionListener* const listener) | |||
{ | |||
if (broadcastListeners == 0) | |||
broadcastListeners = new ActionListenerList(); | |||
if (broadcaster == 0) | |||
broadcaster = new ActionBroadcaster(); | |||
broadcastListeners->addActionListener (listener); | |||
broadcaster->addActionListener (listener); | |||
} | |||
void MessageManager::deregisterBroadcastListener (ActionListener* const listener) | |||
{ | |||
if (broadcastListeners != 0) | |||
broadcastListeners->removeActionListener (listener); | |||
if (broadcaster != 0) | |||
broadcaster->removeActionListener (listener); | |||
} | |||
//============================================================================== | |||
@@ -239,7 +229,6 @@ class MessageManagerLock::SharedEvents : public ReferenceCountedObject | |||
{ | |||
public: | |||
SharedEvents() {} | |||
~SharedEvents() {} | |||
/* This class just holds a couple of events to communicate between the BlockingMessage | |||
and the MessageManagerLock. Because both of these objects may be deleted at any time, | |||
@@ -255,7 +244,6 @@ class MessageManagerLock::BlockingMessage : public CallbackMessage | |||
{ | |||
public: | |||
BlockingMessage (MessageManagerLock::SharedEvents* const events_) : events (events_) {} | |||
~BlockingMessage() throw() {} | |||
void messageCallback() | |||
{ | |||
@@ -31,7 +31,7 @@ | |||
#include "../containers/juce_ScopedPointer.h" | |||
#include "../threads/juce_Thread.h" | |||
#include "../threads/juce_ThreadPool.h" | |||
#include "juce_ActionListenerList.h" | |||
#include "juce_ActionBroadcaster.h" | |||
#include "juce_CallbackMessage.h" | |||
class Component; | |||
class MessageManagerLock; | |||
@@ -175,7 +175,7 @@ private: | |||
static MessageManager* instance; | |||
SortedSet <const MessageListener*> messageListeners; | |||
ScopedPointer <ActionListenerList> broadcastListeners; | |||
ScopedPointer <ActionBroadcaster> broadcaster; | |||
friend class JUCEApplication; | |||
bool quitMessagePosted, quitMessageReceived; | |||
@@ -184,7 +184,6 @@ private: | |||
static void* exitModalLoopCallback (void*); | |||
void postMessageToQueue (Message* message); | |||
void postCallbackMessage (Message* message); | |||
static void doPlatformSpecificInitialisation(); | |||
static void doPlatformSpecificShutdown(); | |||
@@ -317,5 +316,4 @@ private: | |||
}; | |||
#endif // __JUCE_MESSAGEMANAGER_JUCEHEADER__ |
@@ -29,7 +29,6 @@ | |||
#include "../juce_Component.h" | |||
#include "../mouse/juce_MouseCursor.h" | |||
#include "../keyboard/juce_TextInputTarget.h" | |||
#include "../../../events/juce_MessageListener.h" | |||
#include "../../../text/juce_StringArray.h" | |||
#include "../../graphics/geometry/juce_RectangleList.h" | |||
@@ -230,9 +230,6 @@ | |||
#ifndef __JUCE_ACTIONLISTENER_JUCEHEADER__ | |||
#include "events/juce_ActionListener.h" | |||
#endif | |||
#ifndef __JUCE_ACTIONLISTENERLIST_JUCEHEADER__ | |||
#include "events/juce_ActionListenerList.h" | |||
#endif | |||
#ifndef __JUCE_ASYNCUPDATER_JUCEHEADER__ | |||
#include "events/juce_AsyncUpdater.h" | |||
#endif | |||
@@ -388,7 +388,7 @@ namespace NumberToStringConverters | |||
else | |||
{ | |||
#if JUCE_WINDOWS | |||
#if JUCE_VC8_OR_EARLIER || JUCE_MINGW | |||
#if JUCE_VC7_OR_EARLIER || JUCE_MINGW | |||
len = _snwprintf (buffer, numChars, L"%.9g", n); | |||
#else | |||
len = _snwprintf_s (buffer, numChars, _TRUNCATE, L"%.9g", n); | |||