Browse Source

tags/2021-05-28
jules 18 years ago
parent
commit
eb5b9a7ac9
17 changed files with 880 additions and 697 deletions
  1. +9
    -9
      build/macosx/platform_specific_code/juce_mac_Windowing.cpp
  2. +2
    -2
      docs/JUCE changelist.txt
  3. +28
    -21
      extras/audio plugins/How to use this framework.txt
  4. +8
    -8
      extras/audio plugins/demo/build/RTAS_Win32/juce_RTAS.vcproj
  5. +0
    -4
      extras/audio plugins/demo/src/JucePluginCharacteristics.h
  6. +14
    -1
      extras/audio plugins/wrapper/formats/AudioUnit/juce_AudioUnitWrapper.cpp
  7. +9
    -1
      extras/audio plugins/wrapper/formats/RTAS/juce_RTASUtilities.cpp
  8. +10
    -1
      extras/audio plugins/wrapper/formats/RTAS/juce_RTASWrapper.cpp
  9. +0
    -2
      extras/audio plugins/wrapper/formats/RTAS/juce_RTAS_dlldefs.def
  10. +12
    -1
      extras/audio plugins/wrapper/formats/VST/juce_VstWrapper.cpp
  11. +10
    -0
      extras/audio plugins/wrapper/juce_AudioFilterBase.cpp
  12. +16
    -9
      extras/audio plugins/wrapper/juce_AudioFilterBase.h
  13. +0
    -7
      extras/audio plugins/wrapper/juce_AudioFilterEditor.h
  14. +2
    -2
      extras/audio plugins/wrapper/juce_IncludeCharacteristics.h
  15. +605
    -605
      extras/juce demo/src/MainDemoWindow.cpp
  16. +147
    -18
      src/juce_core/containers/juce_ReferenceCountedArray.h
  17. +8
    -6
      src/juce_core/containers/juce_ReferenceCountedObject.h

+ 9
- 9
build/macosx/platform_specific_code/juce_mac_Windowing.cpp View File

@@ -1937,15 +1937,15 @@ bool juce_isHIViewCreatedByJuce (HIViewRef view)
&& HIObjectIsOfClass ((HIObjectRef) view, juceHiViewClassNameCFString);
}
bool juce_isWindowCreatedByJuce (WindowRef window)
{
for (int i = ComponentPeer::getNumPeers(); --i >= 0;)
if (ComponentPeer::getPeer(i)->getNativeHandle() == window)
return true;
return false;
}
bool juce_isWindowCreatedByJuce (WindowRef window)
{
for (int i = ComponentPeer::getNumPeers(); --i >= 0;)
if (ComponentPeer::getPeer(i)->getNativeHandle() == window)
return true;
return false;
}
static void trackNextMouseEvent()
{
UInt32 mods;


+ 2
- 2
docs/JUCE changelist.txt View File

@@ -8,11 +8,11 @@ Changelist for version 1.45

- big new project in the "extras" folder - a basic audio plugin host! Currently it loads VSTs on PC/Mac, and lets you put them together in a filter graph, which it plays. Hosting functionality is very basic at the moment, but I'm laying down a good architecture to hopefully develop into a full cross-platform plugin host.
- audio plugins: I've simplified the processBlock() call in AudioFilterBase. It now just takes a single buffer for all input and output channels, and the accumulate parameter has gone. This will mean tweaking your plugin code, but will probably make it much less complicated.
- audio plugins: AudioFilterBase now requires a few extra methods to be implemented by your plugin: getInputChannelName, getOutputChannelName, isInputChannelStereoPair, isOutputChannelStereoPair.
- audio plugins: AudioFilterBase now requires a few extra methods to be implemented by your plugin: getInputChannelName, getOutputChannelName, isInputChannelStereoPair, isOutputChannelStereoPair, getLatencySamples (which supersedes the old macro for setting the latency)
- audio plugins: new method AudioFilterBase::updateHostDisplay() to tell the host that something about your plugin has changed and that it should refresh its display.
- audio plugins: new methods AudioFilterBase::beginParameterChangeGesture() and endParameterChangeGesture() let you tell the host when a parameter-change action starts and finishes.
- new class: FileSearchPathListComponent, for letting the user edit a FileSearchPath.
- added a critical section option to ReferenceCountedArray

==============================================================================
Changelist for version 1.44


+ 28
- 21
extras/audio plugins/How to use this framework.txt View File

@@ -151,27 +151,28 @@ Compiling the juce demo RTAS on the PC:

- In Visual Studio, add all of this lot to your include path:

c:\yourdirectory\PT_711_SDK\AlturaPorts\TDMPlugins\PluginLibrary\EffectClasses
c:\yourdirectory\PT_711_SDK\AlturaPorts\TDMPlugins\PluginLibrary\ProcessClasses
c:\yourdirectory\PT_711_SDK\AlturaPorts\TDMPlugins\PluginLibrary\ProcessClasses\Interfaces
c:\yourdirectory\PT_711_SDK\AlturaPorts\TDMPlugins\PluginLibrary\Utilities
c:\yourdirectory\PT_711_SDK\AlturaPorts\TDMPlugins\PluginLibrary\RTASP_Adapt
c:\yourdirectory\PT_711_SDK\AlturaPorts\TDMPlugins\PluginLibrary\CoreClasses
c:\yourdirectory\PT_711_SDK\AlturaPorts\TDMPlugins\PluginLibrary\Controls
c:\yourdirectory\PT_711_SDK\AlturaPorts\TDMPlugins\PluginLibrary\Meters
c:\yourdirectory\PT_711_SDK\AlturaPorts\TDMPlugins\PluginLibrary\ViewClasses
c:\yourdirectory\PT_711_SDK\AlturaPorts\TDMPlugins\PluginLibrary\DSPClasses
c:\yourdirectory\PT_711_SDK\AlturaPorts\TDMPlugins\PluginLibrary\Interfaces
c:\yourdirectory\PT_711_SDK\AlturaPorts\TDMPlugins\common
c:\yourdirectory\PT_711_SDK\AlturaPorts\TDMPlugins\common\Platform
c:\yourdirectory\PT_711_SDK\AlturaPorts\TDMPlugins\SignalProcessing\Public
c:\yourdirectory\PT_711_SDK\AlturaPorts\SADriver\Interfaces
c:\yourdirectory\PT_711_SDK\AlturaPorts\DigiPublic\Interfaces
c:\yourdirectory\PT_711_SDK\AlturaPorts\Fic\Interfaces\DAEClient
c:\yourdirectory\PT_711_SDK\AlturaPorts\NewFileLibs\Cmn
c:\yourdirectory\PT_711_SDK\AlturaPorts\NewFileLibs\DOA
c:\yourdirectory\PT_711_SDK\AlturaPorts\AlturaSource\PPC_H
c:\yourdirectory\PT_711_SDK\AlturaPorts\AlturaSource\AppSupport
c:\yourdirectory\PT_73_SDK\AlturaPorts\TDMPlugins\PluginLibrary\EffectClasses
c:\yourdirectory\PT_73_SDK\AlturaPorts\TDMPlugins\PluginLibrary\ProcessClasses
c:\yourdirectory\PT_73_SDK\AlturaPorts\TDMPlugins\PluginLibrary\ProcessClasses\Interfaces
c:\yourdirectory\PT_73_SDK\AlturaPorts\TDMPlugins\PluginLibrary\Utilities
c:\yourdirectory\PT_73_SDK\AlturaPorts\TDMPlugins\PluginLibrary\RTASP_Adapt
c:\yourdirectory\PT_73_SDK\AlturaPorts\TDMPlugins\PluginLibrary\CoreClasses
c:\yourdirectory\PT_73_SDK\AlturaPorts\TDMPlugins\PluginLibrary\Controls
c:\yourdirectory\PT_73_SDK\AlturaPorts\TDMPlugins\PluginLibrary\Meters
c:\yourdirectory\PT_73_SDK\AlturaPorts\TDMPlugins\PluginLibrary\ViewClasses
c:\yourdirectory\PT_73_SDK\AlturaPorts\TDMPlugins\PluginLibrary\DSPClasses
c:\yourdirectory\PT_73_SDK\AlturaPorts\TDMPlugins\PluginLibrary\Interfaces
c:\yourdirectory\PT_73_SDK\AlturaPorts\TDMPlugins\common
c:\yourdirectory\PT_73_SDK\AlturaPorts\TDMPlugins\common\Platform
c:\yourdirectory\PT_73_SDK\AlturaPorts\TDMPlugins\SignalProcessing\Public
c:\yourdirectory\PT_73_SDK\AlturaPorts\SADriver\Interfaces
c:\yourdirectory\PT_73_SDK\AlturaPorts\DigiPublic\Interfaces
c:\yourdirectory\PT_73_SDK\AlturaPorts\Fic\Interfaces\DAEClient
c:\yourdirectory\PT_73_SDK\AlturaPorts\NewFileLibs\Cmn
c:\yourdirectory\PT_73_SDK\AlturaPorts\NewFileLibs\DOA
c:\yourdirectory\PT_73_SDK\AlturaPorts\AlturaSource\PPC_H
c:\yourdirectory\PT_73_SDK\AlturaPorts\AlturaSource\AppSupport
c:\yourdirectory\PT_73_SDK\AvidCode\AVX2sdk\AVX\avx2\avx2sdk\inc

- The Visual Studio juce_RTAS project contains a folder called "libs", with "debug" and
"release" subdirectories - these should contain links to the Digidesign lib files
@@ -180,6 +181,12 @@ Compiling the juce demo RTAS on the PC:

- Fingers crossed, this should now compile..

- IMPORTANT NOTE! If you're using MSVC2005 to build your plugin, the users will need to
have the Microsoft VC8 Runtime installed on their machines, otherwise the DLL will
silently fail to load. You should probably add the runtime to your plugin's installer,
and you can get a copy of it here:
http://www.microsoft.com/downloads/details.aspx?FamilyID=32bc1bee-a3f9-4c13-9c99-220b62a191ee&DisplayLang=en


Creating a project for your own RTAS on the PC:
=================================================


+ 8
- 8
extras/audio plugins/demo/build/RTAS_Win32/juce_RTAS.vcproj View File

@@ -542,7 +542,7 @@
Name="debug"
>
<File
RelativePath="..\..\..\..\..\..\..\essentials\PT_711_SDK\WinBag\Debug\lib\DAE.lib"
RelativePath="..\..\..\..\..\..\..\essentials\PT_73_SDK\WinBag\Debug\lib\DAE.lib"
>
<FileConfiguration
Name="Release|Win32"
@@ -554,7 +554,7 @@
</FileConfiguration>
</File>
<File
RelativePath="..\..\..\..\..\..\..\essentials\PT_711_SDK\WinBag\Debug\lib\DigiExt.lib"
RelativePath="..\..\..\..\..\..\..\essentials\PT_73_SDK\WinBag\Debug\lib\DigiExt.lib"
>
<FileConfiguration
Name="Release|Win32"
@@ -566,7 +566,7 @@
</FileConfiguration>
</File>
<File
RelativePath="..\..\..\..\..\..\..\essentials\PT_711_SDK\WinBag\Debug\lib\DSI.lib"
RelativePath="..\..\..\..\..\..\..\essentials\PT_73_SDK\WinBag\Debug\lib\DSI.lib"
>
<FileConfiguration
Name="Release|Win32"
@@ -578,7 +578,7 @@
</FileConfiguration>
</File>
<File
RelativePath="..\..\..\..\..\..\..\essentials\PT_711_SDK\WinBag\Debug\lib\PlugInLib.lib"
RelativePath="..\..\..\..\..\..\..\essentials\PT_73_SDK\WinBag\Debug\lib\PlugInLib.lib"
>
<FileConfiguration
Name="Release|Win32"
@@ -594,7 +594,7 @@
Name="release"
>
<File
RelativePath="..\..\..\..\..\..\..\essentials\PT_711_SDK\WinBag\Release\lib\DAE.lib"
RelativePath="..\..\..\..\..\..\..\essentials\PT_73_SDK\WinBag\Release\lib\DAE.lib"
>
<FileConfiguration
Name="Debug|Win32"
@@ -606,7 +606,7 @@
</FileConfiguration>
</File>
<File
RelativePath="..\..\..\..\..\..\..\essentials\PT_711_SDK\WinBag\Release\lib\DigiExt.lib"
RelativePath="..\..\..\..\..\..\..\essentials\PT_73_SDK\WinBag\Release\lib\DigiExt.lib"
>
<FileConfiguration
Name="Debug|Win32"
@@ -618,7 +618,7 @@
</FileConfiguration>
</File>
<File
RelativePath="..\..\..\..\..\..\..\essentials\PT_711_SDK\WinBag\Release\lib\DSI.lib"
RelativePath="..\..\..\..\..\..\..\essentials\PT_73_SDK\WinBag\Release\lib\DSI.lib"
>
<FileConfiguration
Name="Debug|Win32"
@@ -630,7 +630,7 @@
</FileConfiguration>
</File>
<File
RelativePath="..\..\..\..\..\..\..\essentials\PT_711_SDK\WinBag\Release\lib\PlugInLib.lib"
RelativePath="..\..\..\..\..\..\..\essentials\PT_73_SDK\WinBag\Release\lib\PlugInLib.lib"
>
<FileConfiguration
Name="Debug|Win32"


+ 0
- 4
extras/audio plugins/demo/src/JucePluginCharacteristics.h View File

@@ -120,10 +120,6 @@
#define JucePlugin_PreferredChannelConfigurations { 1, 1 }, { 2, 2 }
//==============================================================================
/** The plugin's internal latency, as a number of samples.
*/
#define JucePlugin_Latency 0
/** Set this value to 1 if your plugin is a synth, or 0 if it isn't.
*/
#define JucePlugin_IsSynth 1


+ 14
- 1
extras/audio plugins/wrapper/formats/AudioUnit/juce_AudioUnitWrapper.cpp View File

@@ -300,7 +300,7 @@ public:
if (GetSampleRate() <= 0)
return 0.0;
return (JucePlugin_Latency) / GetSampleRate();
return getLatencySamples() / GetSampleRate();
}
//==============================================================================
@@ -435,6 +435,19 @@ public:
ComponentResult Initialize()
{
AUMIDIEffectBase::Initialize();
const int numIns = GetInput(0) != 0 ? GetInput(0)->GetStreamFormat().mChannelsPerFrame : 0;
const int numOuts = GetOutput(0) != 0 ? GetOutput(0)->GetStreamFormat().mChannelsPerFrame : 0;
bool isValidChannelConfig = false;
for (int i = 0; i < numChannelConfigs; ++i)
if (numIns == channelConfigs[i][0] && numOuts == channelConfigs[i][1])
isValidChannelConfig = true;
if (! isValidChannelConfig)
return kAudioUnitErr_FormatNotSupported;
prepareToPlay();
return noErr;
}


+ 9
- 1
extras/audio plugins/wrapper/formats/RTAS/juce_RTASUtilities.cpp View File

@@ -35,8 +35,16 @@
// at the same time as the Digi headers)
#include <windows.h>
#ifdef _MSC_VER
#pragma pack (push, 8)
#endif
#include "../../juce_AudioFilterBase.h"
#include "../../juce_AudioFilterEditor.h"
#ifdef _MSC_VER
#pragma pack (pop)
#endif
//==============================================================================


+ 10
- 1
extras/audio plugins/wrapper/formats/RTAS/juce_RTASWrapper.cpp View File

@@ -79,9 +79,18 @@
#include "CPluginControl_OnOff.h"
//==============================================================================
#ifdef _MSC_VER
#pragma pack (push, 8)
#endif
#include "../../juce_AudioFilterBase.h"
#include "../../juce_AudioFilterEditor.h"
#include "../../juce_IncludeCharacteristics.h"
#ifdef _MSC_VER
#pragma pack (pop)
#endif
#undef Component
//==============================================================================
@@ -526,7 +535,7 @@ protected:
ComponentResult GetDelaySamplesLong (long* aNumSamples)
{
if (aNumSamples != 0)
*aNumSamples = JucePlugin_Latency;
*aNumSamples = juceFilter != 0 ? juceFilter->getLatencySamples() : 0;
return noErr;
}


+ 0
- 2
extras/audio plugins/wrapper/formats/RTAS/juce_RTAS_dlldefs.def View File

@@ -1,5 +1,3 @@
EXPORTS
NewPlugIn @1
_PI_GetRoutineDescriptor @2

+ 12
- 1
extras/audio plugins/wrapper/formats/VST/juce_VstWrapper.cpp View File

@@ -91,7 +91,16 @@
#endif
//==============================================================================
#ifdef _MSC_VER
#pragma pack (push, 8)
#endif
#include "../../juce_AudioFilterBase.h"
#ifdef _MSC_VER
#pragma pack (pop)
#endif
#undef MemoryBlock
class JuceVSTWrapper;
@@ -349,7 +358,7 @@ public:
isSynth ((JucePlugin_IsSynth) != 0);
noTail ((JucePlugin_SilenceInProducesSilenceOut) != 0);
setInitialDelay (JucePlugin_Latency);
setInitialDelay (filter->getLatencySamples());
programsAreChunks (true);
activePlugins.add (this);
@@ -669,6 +678,8 @@ public:
filter->prepareToPlay (rate, blockSize);
midiEvents.clear();
setInitialDelay (filter->getLatencySamples());
AudioEffectX::resume();
#if JucePlugin_ProducesMidiOutput


+ 10
- 0
extras/audio plugins/wrapper/juce_AudioFilterBase.cpp View File

@@ -40,6 +40,7 @@ AudioFilterBase::AudioFilterBase()
blockSize (0),
numInputChannels (0),
numOutputChannels (0),
latencySamples (0),
suspended (false)
{
}
@@ -71,6 +72,15 @@ void AudioFilterBase::setPlayConfigDetails (const int numIns,
blockSize = blockSize_;
}
void JUCE_CALLTYPE AudioFilterBase::setLatencySamples (const int newLatency)
{
if (latencySamples != newLatency)
{
latencySamples = newLatency;
updateHostDisplay();
}
}
void AudioFilterBase::setParameterNotifyingHost (const int parameterIndex,
const float newValue)
{


+ 16
- 9
extras/audio plugins/wrapper/juce_AudioFilterBase.h View File

@@ -32,10 +32,6 @@
#ifndef __JUCE_AUDIOFILTERBASE_JUCEHEADER__
#define __JUCE_AUDIOFILTERBASE_JUCEHEADER__
#ifdef _MSC_VER
#pragma pack (push, 8)
#endif
#include "../../../juce.h"
#include "juce_AudioFilterEditor.h"
#undef MemoryBlock
@@ -274,6 +270,21 @@ public:
/** Returns true if the specified channel is part of a stereo pair with its neighbour. */
virtual bool JUCE_CALLTYPE isOutputChannelStereoPair (int index) const = 0;
/** This returns the number of samples delay that the filter imposes on the audio
passing through it.
The host will call this to find the latency - the filter itself should set this value
by calling setLatencySamples() as soon as it can during its initialisation.
*/
int JUCE_CALLTYPE getLatencySamples() const throw() { return latencySamples; }
/** The filter should call this to set the number of samples delay that it introduces.
The filter should call this as soon as it can during initialisation, and can call it
later if the value changes.
*/
void JUCE_CALLTYPE setLatencySamples (const int newLatency);
//==============================================================================
/** This returns a critical section that will automatically be locked while the host
is calling the processBlock() method.
@@ -586,7 +597,7 @@ protected:
private:
AudioFilterEditor* activeEditor;
double sampleRate;
int blockSize, numInputChannels, numOutputChannels;
int blockSize, numInputChannels, numOutputChannels, latencySamples;
bool suspended;
CriticalSection callbackLock;
@@ -601,9 +612,5 @@ private:
*/
extern AudioFilterBase* JUCE_CALLTYPE createPluginFilter();
#ifdef _MSC_VER
#pragma pack (pop)
#endif
#endif // __JUCE_AUDIOFILTERBASE_JUCEHEADER__

+ 0
- 7
extras/audio plugins/wrapper/juce_AudioFilterEditor.h View File

@@ -32,10 +32,6 @@
#ifndef __JUCE_AUDIOFILTEREDITOR_JUCEHEADER__
#define __JUCE_AUDIOFILTEREDITOR_JUCEHEADER__
#ifdef _MSC_VER
#pragma pack (push, 8)
#endif
#include "../../../juce.h"
class AudioFilterBase;
@@ -72,8 +68,5 @@ private:
AudioFilterBase* const ownerFilter;
};
#ifdef _MSC_VER
#pragma pack (pop)
#endif
#endif // __JUCE_AUDIOFILTEREDITOR_JUCEHEADER__

+ 2
- 2
extras/audio plugins/wrapper/juce_IncludeCharacteristics.h View File

@@ -79,8 +79,8 @@
#error "You need to define the JucePlugin_PreferredChannelConfigurations value in your JucePluginCharacteristics.h file!"
#endif
#ifndef JucePlugin_Latency
#error "You need to define the JucePlugin_Latency value in your JucePluginCharacteristics.h file!"
#ifdef JucePlugin_Latency
#error "JucePlugin_Latency is now deprecated - instead, call the AudioFilterBase::setLatencySamples() method if your plugin has a non-zero delay"
#endif
#ifndef JucePlugin_SilenceInProducesSilenceOut


+ 605
- 605
extras/juce demo/src/MainDemoWindow.cpp
File diff suppressed because it is too large
View File


+ 147
- 18
src/juce_core/containers/juce_ReferenceCountedArray.h View File

@@ -46,9 +46,12 @@
and takes care of incrementing and decrementing their ref counts when they
are added and removed from the array.
To make all the array's methods thread-safe, pass in "CriticalSection" as the templated
TypeOfCriticalSectionToUse parameter, instead of the default DummyCriticalSection.
@see Array, OwnedArray, StringArray
*/
template <class ObjectClass>
template <class ObjectClass, class TypeOfCriticalSectionToUse = DummyCriticalSection>
class ReferenceCountedArray : private ArrayAllocationBase <ObjectClass*>
{
public:
@@ -68,26 +71,32 @@ public:
}
/** Creates a copy of another array */
ReferenceCountedArray (const ReferenceCountedArray<ObjectClass>& other) throw()
ReferenceCountedArray (const ReferenceCountedArray<ObjectClass, TypeOfCriticalSectionToUse>& other) throw()
: ArrayAllocationBase <ObjectClass*> (other.granularity),
numUsed (other.numUsed)
{
other.lockArray();
this->setAllocatedSize (numUsed);
memcpy (this->elements, other.elements, numUsed * sizeof (ObjectClass*));
for (int i = numUsed; --i >= 0;)
if (this->elements[i] != 0)
this->elements[i]->incReferenceCount();
other.unlockArray();
}
/** Copies another array into this one.
Any existing objects in this array will first be released.
*/
const ReferenceCountedArray<ObjectClass>& operator= (const ReferenceCountedArray<ObjectClass>& other) throw()
const ReferenceCountedArray<ObjectClass, TypeOfCriticalSectionToUse>& operator= (const ReferenceCountedArray<ObjectClass, TypeOfCriticalSectionToUse>& other) throw()
{
if (this != &other)
{
other.lockArray();
lock.enter();
clear();
this->granularity = other.granularity;
@@ -99,6 +108,9 @@ public:
for (int i = numUsed; --i >= 0;)
if (this->elements[i] != 0)
this->elements[i]->incReferenceCount();
lock.exit();
other.unlockArray();
}
return *this;
@@ -120,12 +132,16 @@ public:
*/
void clear()
{
lock.enter();
while (numUsed > 0)
if (this->elements [--numUsed] != 0)
this->elements [numUsed]->decReferenceCount();
jassert (numUsed == 0);
this->setAllocatedSize (0);
lock.exit();
}
/** Returns the current number of objects in the array. */
@@ -144,8 +160,10 @@ public:
*/
inline ObjectClass* operator[] (const int index) const throw()
{
lock.enter();
return (index >= 0 && index < numUsed) ? this->elements [index]
: (ObjectClass*) 0;
lock.exit();
}
/** Returns a pointer to the object at this index in the array, without checking whether the index is in-range.
@@ -155,8 +173,10 @@ public:
*/
inline ObjectClass* getUnchecked (const int index) const throw()
{
lock.enter();
jassert (index >= 0 && index < numUsed);
return this->elements [index];
lock.exit();
}
/** Returns a pointer to the first object in the array.
@@ -166,8 +186,12 @@ public:
*/
inline ObjectClass* getFirst() const throw()
{
return (numUsed > 0) ? this->elements [0]
: (ObjectClass*) 0;
lock.enter();
ObjectClass* const result = (numUsed > 0) ? this->elements [0]
: (ObjectClass*) 0;
lock.exit();
return result;
}
/** Returns a pointer to the last object in the array.
@@ -177,8 +201,12 @@ public:
*/
inline ObjectClass* getLast() const throw()
{
return (numUsed > 0) ? this->elements [numUsed - 1]
: (ObjectClass*) 0;
lock.enter();
ObjectClass* const result = (numUsed > 0) ? this->elements [numUsed - 1]
: (ObjectClass*) 0;
lock.exit();
return result;
}
//==============================================================================
@@ -189,17 +217,24 @@ public:
*/
int indexOf (const ObjectClass* const objectToLookFor) const throw()
{
int result = -1;
lock.enter();
ObjectClass** e = this->elements;
for (int i = numUsed; --i >= 0;)
{
if (objectToLookFor == *e)
return (int) (e - this->elements);
{
result = (int) (e - this->elements);
break;
}
++e;
}
return -1;
lock.exit();
return result;
}
/** Returns true if the array contains a specified object.
@@ -209,16 +244,21 @@ public:
*/
bool contains (const ObjectClass* const objectToLookFor) const throw()
{
lock.enter();
ObjectClass** e = this->elements;
for (int i = numUsed; --i >= 0;)
{
if (objectToLookFor == *e)
{
lock.exit();
return true;
}
++e;
}
lock.exit();
return false;
}
@@ -231,11 +271,14 @@ public:
*/
void add (ObjectClass* const newObject) throw()
{
lock.enter();
this->ensureAllocatedSize (numUsed + 1);
this->elements [numUsed++] = newObject;
if (newObject != 0)
newObject->incReferenceCount();
lock.exit();
}
/** Inserts a new object into the array at the given index.
@@ -256,6 +299,7 @@ public:
{
if (indexToInsertAt >= 0)
{
lock.enter();
if (indexToInsertAt > numUsed)
indexToInsertAt = numUsed;
@@ -273,6 +317,7 @@ public:
newObject->incReferenceCount();
++numUsed;
lock.exit();
}
else
{
@@ -289,8 +334,12 @@ public:
*/
void addIfNotAlreadyThere (ObjectClass* const newObject) throw()
{
lock.enter();
if (! contains (newObject))
add (newObject);
lock.exit();
}
/** Replaces an object in the array with a different one.
@@ -310,6 +359,8 @@ public:
{
if (indexToChange >= 0)
{
lock.enter();
if (newObject != 0)
newObject->incReferenceCount();
@@ -325,6 +376,8 @@ public:
this->ensureAllocatedSize (numUsed + 1);
this->elements [numUsed++] = newObject;
}
lock.exit();
}
}
@@ -337,10 +390,13 @@ public:
all available elements will be copied.
@see add
*/
void addArray (const ReferenceCountedArray<ObjectClass>& arrayToAddFrom,
void addArray (const ReferenceCountedArray<ObjectClass, TypeOfCriticalSectionToUse>& arrayToAddFrom,
int startIndex = 0,
int numElementsToAdd = -1) throw()
{
arrayToAddFrom.lockArray();
lock.enter();
if (startIndex < 0)
{
jassertfalse
@@ -357,6 +413,9 @@ public:
while (--numElementsToAdd >= 0)
add (arrayToAddFrom.getUnchecked (startIndex++));
}
lock.exit();
arrayToAddFrom.unlockArray();
}
/** Inserts a new object into the array assuming that the array is sorted.
@@ -374,7 +433,9 @@ public:
void addSorted (ElementComparator& comparator,
ObjectClass* newObject) throw()
{
lock.enter();
insert (findInsertIndexInSortedArray (comparator, this->elements, newObject, 0, numUsed), newObject);
lock.exit();
}
//==============================================================================
@@ -393,6 +454,8 @@ public:
*/
void remove (const int indexToRemove)
{
lock.enter();
if (indexToRemove >= 0 && indexToRemove < numUsed)
{
ObjectClass** const e = this->elements + indexToRemove;
@@ -409,6 +472,8 @@ public:
if ((numUsed << 1) < this->numAllocated)
minimiseStorageOverheads();
}
lock.exit();
}
/** Removes the first occurrence of a specified object from the array.
@@ -421,7 +486,9 @@ public:
*/
void removeObject (ObjectClass* const objectToRemove)
{
lock.enter();
remove (indexOf (objectToRemove));
lock.exit();
}
/** Removes a range of objects from the array.
@@ -442,6 +509,8 @@ public:
void removeRange (const int startIndex,
const int numberToRemove)
{
lock.enter();
const int start = jlimit (0, numUsed, startIndex);
const int end = jlimit (0, numUsed, startIndex + numberToRemove);
@@ -471,6 +540,8 @@ public:
if ((numUsed << 1) < this->numAllocated)
minimiseStorageOverheads();
}
lock.exit();
}
/** Removes the last n objects from the array.
@@ -483,11 +554,15 @@ public:
*/
void removeLast (int howManyToRemove = 1)
{
lock.enter();
if (howManyToRemove > numUsed)
howManyToRemove = numUsed;
while (--howManyToRemove >= 0)
remove (numUsed - 1);
lock.exit();
}
/** Swaps a pair of objects in the array.
@@ -498,12 +573,16 @@ public:
void swap (const int index1,
const int index2) throw()
{
lock.enter();
if (index1 >= 0 && index1 < numUsed
&& index2 >= 0 && index2 < numUsed)
{
swapVariables (this->elements [index1],
this->elements [index2]);
}
lock.exit();
}
/** Moves one of the objects to a different position.
@@ -524,6 +603,8 @@ public:
{
if (currentIndex != newIndex)
{
lock.enter();
if (currentIndex >= 0 && currentIndex < numUsed)
{
if (newIndex < 0 || newIndex > numUsed - 1)
@@ -546,6 +627,8 @@ public:
this->elements [newIndex] = value;
}
lock.exit();
}
}
@@ -554,23 +637,36 @@ public:
@returns true only if the other array contains the same objects in the same order
*/
bool operator== (const ReferenceCountedArray<ObjectClass>& other) const throw()
bool operator== (const ReferenceCountedArray<ObjectClass, TypeOfCriticalSectionToUse>& other) const throw()
{
if (numUsed != other.numUsed)
return false;
other.lockArray();
lock.enter();
for (int i = numUsed; --i >= 0;)
if (this->elements [i] != other.elements [i])
return false;
bool result = numUsed == other.numUsed;
if (result)
{
for (int i = numUsed; --i >= 0;)
{
if (this->elements [i] != other.elements [i])
{
result = false;
break;
}
}
}
return true;
lock.exit();
other.unlockArray();
return result;
}
/** Compares this array to another one.
@see operator==
*/
bool operator!= (const ReferenceCountedArray<ObjectClass>& other) const throw()
bool operator!= (const ReferenceCountedArray<ObjectClass, TypeOfCriticalSectionToUse>& other) const throw()
{
return ! operator== (other);
}
@@ -608,7 +704,10 @@ public:
{
(void) comparator; // if you pass in an object with a static compareElements() method, this
// avoids getting warning messages about the parameter being unused
lock.enter();
sortArray (comparator, this->elements, 0, size() - 1, retainOrderOfEquivalentItems);
lock.exit();
}
//==============================================================================
@@ -620,6 +719,8 @@ public:
*/
void minimiseStorageOverheads() throw()
{
lock.enter();
if (numUsed == 0)
{
this->setAllocatedSize (0);
@@ -631,6 +732,33 @@ public:
if (newAllocation < this->numAllocated)
this->setAllocatedSize (newAllocation);
}
lock.exit();
}
//==============================================================================
/** Locks the array's CriticalSection.
Of course if the type of section used is a DummyCriticalSection, this won't
have any effect.
@see unlockArray
*/
void lockArray() const throw()
{
lock.enter();
}
/** Unlocks the array's CriticalSection.
Of course if the type of section used is a DummyCriticalSection, this won't
have any effect.
@see lockArray
*/
void unlockArray() const throw()
{
lock.exit();
}
@@ -639,6 +767,7 @@ public:
private:
int numUsed;
TypeOfCriticalSectionToUse lock;
};


+ 8
- 6
src/juce_core/containers/juce_ReferenceCountedObject.h View File

@@ -178,10 +178,11 @@ public:
if (newObject != 0)
newObject->incReferenceCount();
if (referencedObject != 0)
referencedObject->decReferenceCount();
ReferenceCountedObjectClass* const oldObject = referencedObject;
referencedObject = newObject;
if (oldObject != 0)
oldObject->decReferenceCount();
}
return *this;
@@ -199,10 +200,11 @@ public:
if (newObject != 0)
newObject->incReferenceCount();
if (referencedObject != 0)
referencedObject->decReferenceCount();
ReferenceCountedObjectClass* const oldObject = referencedObject;
referencedObject = newObject;
if (oldObject != 0)
oldObject->decReferenceCount();
}
return *this;


Loading…
Cancel
Save