mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-09 23:34:20 +00:00
This commit is contained in:
parent
87fcded399
commit
eb5b9a7ac9
17 changed files with 880 additions and 697 deletions
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
=================================================
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
||||
//==============================================================================
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,3 @@
|
|||
EXPORTS
|
||||
NewPlugIn @1
|
||||
_PI_GetRoutineDescriptor @2
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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__
|
||||
|
|
|
|||
|
|
@ -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__
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -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;
|
||||
|
||||
return true;
|
||||
if (result)
|
||||
{
|
||||
for (int i = numUsed; --i >= 0;)
|
||||
{
|
||||
if (this->elements [i] != other.elements [i])
|
||||
{
|
||||
result = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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…
Add table
Add a link
Reference in a new issue