mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-10 23:44:24 +00:00
Cleaned up the AsyncUpdater and ChangeBroadcaster classes internally - these now have less overhead when creating and deleting them. Removed the ActionListenerList class, as all its functionality is already provided by ActionBroadcaster.
This commit is contained in:
parent
4cfdcb69fd
commit
75ff0c5e7e
29 changed files with 505 additions and 795 deletions
|
|
@ -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,10 +38287,40 @@ END_JUCE_NAMESPACE
|
|||
/*** Start of inlined file: juce_ActionBroadcaster.cpp ***/
|
||||
BEGIN_JUCE_NAMESPACE
|
||||
|
||||
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()
|
||||
|
|
@ -38301,148 +38331,99 @@ 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
|
||||
/*** 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()
|
||||
: 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
|
||||
/*** End of inlined file: juce_ActionListenerList.cpp ***/
|
||||
|
||||
|
||||
/*** Start of inlined file: juce_AsyncUpdater.cpp ***/
|
||||
BEGIN_JUCE_NAMESPACE
|
||||
|
||||
AsyncUpdater::AsyncUpdater() throw()
|
||||
: asyncMessagePending (false)
|
||||
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()
|
||||
{
|
||||
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,46 +39040,39 @@ 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))
|
||||
const ScopedPointer <Message> messageDeleter (message);
|
||||
MessageListener* const recipient = message->messageRecipient;
|
||||
|
||||
if (recipient == 0)
|
||||
{
|
||||
recipient->handleMessage (*message);
|
||||
}
|
||||
else if (recipient == 0)
|
||||
{
|
||||
if (message->intParameter1 == quitMessageId)
|
||||
CallbackMessage* const callbackMessage = dynamic_cast <CallbackMessage*> (message);
|
||||
|
||||
if (callbackMessage != 0)
|
||||
{
|
||||
callbackMessage->messageCallback();
|
||||
}
|
||||
else if (message->intParameter1 == quitMessageId)
|
||||
{
|
||||
quitMessageReceived = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
CallbackMessage* const cm = dynamic_cast <CallbackMessage*> (message);
|
||||
|
||||
if (cm != 0)
|
||||
cm->messageCallback();
|
||||
}
|
||||
}
|
||||
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() {}
|
||||
class AsyncUpdaterMessage;
|
||||
friend class AsyncUpdaterMessage;
|
||||
|
||||
void handleMessage (const Message&);
|
||||
|
||||
AsyncUpdater* owner;
|
||||
|
||||
private:
|
||||
AsyncUpdaterInternal (const AsyncUpdaterInternal&);
|
||||
AsyncUpdaterInternal& operator= (const AsyncUpdaterInternal&);
|
||||
};
|
||||
|
||||
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();
|
||||
|
||||
Atomic<ChangeBroadcasterMessage*> pendingMessage;
|
||||
ChangeBroadcaster* owner;
|
||||
};
|
||||
|
||||
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"
|
||||
|
||||
|
||||
//==============================================================================
|
||||
AsyncUpdater::AsyncUpdater() throw()
|
||||
: asyncMessagePending (false)
|
||||
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()
|
||||
{
|
||||
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() {}
|
||||
class AsyncUpdaterMessage;
|
||||
friend class AsyncUpdaterMessage;
|
||||
|
||||
void handleMessage (const Message&);
|
||||
|
||||
AsyncUpdater* owner;
|
||||
|
||||
private:
|
||||
AsyncUpdaterInternal (const AsyncUpdaterInternal&);
|
||||
AsyncUpdaterInternal& operator= (const AsyncUpdaterInternal&);
|
||||
};
|
||||
|
||||
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,47 +88,40 @@ 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))
|
||||
const ScopedPointer <Message> messageDeleter (message);
|
||||
MessageListener* const recipient = message->messageRecipient;
|
||||
|
||||
if (recipient == 0)
|
||||
{
|
||||
recipient->handleMessage (*message);
|
||||
}
|
||||
else if (recipient == 0)
|
||||
{
|
||||
if (message->intParameter1 == quitMessageId)
|
||||
CallbackMessage* const callbackMessage = dynamic_cast <CallbackMessage*> (message);
|
||||
|
||||
if (callbackMessage != 0)
|
||||
{
|
||||
callbackMessage->messageCallback();
|
||||
}
|
||||
else if (message->intParameter1 == quitMessageId)
|
||||
{
|
||||
quitMessageReceived = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
CallbackMessage* const cm = dynamic_cast <CallbackMessage*> (message);
|
||||
|
||||
if (cm != 0)
|
||||
cm->messageCallback();
|
||||
}
|
||||
}
|
||||
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);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue