Browse Source

Fix for multithreaded Mac OpenGL components; better responding to shutdown messages on Windows; a couple of small VST tweaks; fixed a typo in the AudioDeviceManager and made it close and reopen the audio device while the midi output is being changed; changed AlertWindow to give more control over the desktop window style; fixed a small bug in Graphics; changed SparseSet to avoid an overflow error; stopped BufferedInputStream locking up when its source stream fails; added a case-sensitivity option to StringPairArray and LocalisedStrings.

tags/2021-05-28
jules 16 years ago
parent
commit
bf501e1fda
16 changed files with 333 additions and 68 deletions
  1. +94
    -22
      build/macosx/platform_specific_code/juce_mac_OpenGLComponent.mm
  2. +10
    -1
      build/win32/platform_specific_code/juce_win32_Windowing.cpp
  3. +21
    -1
      extras/audio plugins/wrapper/VST/juce_VST_Wrapper.cpp
  4. +130
    -24
      juce_amalgamated.cpp
  5. +24
    -9
      juce_amalgamated.h
  6. +7
    -1
      src/juce_appframework/audio/devices/juce_AudioDeviceManager.cpp
  7. +5
    -0
      src/juce_appframework/gui/components/windows/juce_AlertWindow.cpp
  8. +2
    -0
      src/juce_appframework/gui/components/windows/juce_AlertWindow.h
  9. +1
    -1
      src/juce_appframework/gui/graphics/contexts/juce_Graphics.cpp
  10. +1
    -0
      src/juce_core/containers/juce_ArrayAllocationBase.h
  11. +12
    -9
      src/juce_core/containers/juce_SparseSet.h
  12. +4
    -0
      src/juce_core/io/streams/juce_BufferedInputStream.cpp
  13. +5
    -0
      src/juce_core/text/juce_LocalisedStrings.cpp
  14. +7
    -0
      src/juce_core/text/juce_LocalisedStrings.h
  15. +5
    -0
      src/juce_core/text/juce_StringPairArray.cpp
  16. +5
    -0
      src/juce_core/text/juce_StringPairArray.h

+ 94
- 22
build/macosx/platform_specific_code/juce_mac_OpenGLComponent.mm View File

@@ -33,6 +33,88 @@
// compiled on its own).
#if JUCE_INCLUDED_FILE && JUCE_OPENGL
END_JUCE_NAMESPACE
//==============================================================================
@interface ThreadSafeNSOpenGLView : NSOpenGLView
{
CriticalSection* contextLock;
bool needsUpdate;
}
- (id) initWithFrame: (NSRect) frameRect pixelFormat: (NSOpenGLPixelFormat*) format;
- (bool) makeActive;
- (void) makeInactive;
- (void) reshape;
@end
@implementation ThreadSafeNSOpenGLView
- (id) initWithFrame: (NSRect) frameRect
pixelFormat: (NSOpenGLPixelFormat*) format
{
contextLock = new CriticalSection();
self = [super initWithFrame: frameRect pixelFormat: format];
if (self != nil)
[[NSNotificationCenter defaultCenter] addObserver: self
selector: @selector (_surfaceNeedsUpdate:)
name: NSViewGlobalFrameDidChangeNotification
object: self];
return self;
}
- (void) dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver: self];
delete contextLock;
[super dealloc];
}
- (bool) makeActive
{
const ScopedLock sl (*contextLock);
if ([self openGLContext] == 0)
return false;
[[self openGLContext] makeCurrentContext];
if (needsUpdate)
{
[super update];
needsUpdate = false;
}
return true;
}
- (void) makeInactive
{
const ScopedLock sl (*contextLock);
[NSOpenGLContext clearCurrentContext];
}
- (void) _surfaceNeedsUpdate: (NSNotification*) notification
{
const ScopedLock sl (*contextLock);
needsUpdate = true;
}
- (void) update
{
const ScopedLock sl (*contextLock);
needsUpdate = true;
}
- (void) reshape
{
const ScopedLock sl (*contextLock);
needsUpdate = true;
}
@end
BEGIN_JUCE_NAMESPACE
//==============================================================================
class WindowedGLContext : public OpenGLContext
@@ -50,6 +132,7 @@ public:
int n = 0;
attribs[n++] = NSOpenGLPFADoubleBuffer;
attribs[n++] = NSOpenGLPFAAccelerated;
attribs[n++] = NSOpenGLPFAMPSafe; // NSOpenGLPFAAccelerated, NSOpenGLPFAMultiScreen, NSOpenGLPFASingleRenderer
attribs[n++] = NSOpenGLPFAColorSize;
attribs[n++] = (NSOpenGLPixelFormatAttribute) jmax (pixelFormat.redBits,
pixelFormat.greenBits,
@@ -67,7 +150,6 @@ public:
pixelFormat.accumulationBufferAlphaBits);
// xxx not sure how to do fullSceneAntiAliasingNumSamples..
attribs[n++] = NSOpenGLPFASampleBuffers;
attribs[n++] = (NSOpenGLPixelFormatAttribute) 1;
attribs[n++] = NSOpenGLPFAClosestPolicy;
@@ -77,21 +159,13 @@ public:
NSOpenGLPixelFormat* format
= [[NSOpenGLPixelFormat alloc] initWithAttributes: attribs];
NSOpenGLView* view
= [[NSOpenGLView alloc] initWithFrame: NSMakeRect (0, 0, 100.0f, 100.0f)
pixelFormat: format];
if (sharedContext != 0)
{
renderContext = [[NSOpenGLContext alloc] initWithFormat: format
shareContext: sharedContext];
[view setOpenGLContext: renderContext];
[renderContext setView: view];
}
else
{
renderContext = [view openGLContext];
}
view = [[ThreadSafeNSOpenGLView alloc] initWithFrame: NSMakeRect (0, 0, 100.0f, 100.0f)
pixelFormat: format];
renderContext = [[[NSOpenGLContext alloc] initWithFormat: format
shareContext: sharedContext] autorelease];
[view setOpenGLContext: renderContext];
[renderContext setView: view];
[format release];
@@ -108,15 +182,13 @@ public:
bool makeActive() const throw()
{
jassert (renderContext != 0);
[renderContext makeCurrentContext];
return renderContext != 0;
[view makeActive];
return isActive();
}
bool makeInactive() const throw()
{
if (! isActive())
[NSOpenGLContext clearCurrentContext];
[view makeInactive];
return true;
}
@@ -134,7 +206,6 @@ public:
void swapBuffers()
{
glFlush();
[renderContext flushBuffer];
}
@@ -173,6 +244,7 @@ public:
juce_UseDebuggingNewOperator
NSOpenGLContext* renderContext;
ThreadSafeNSOpenGLView* view;
private:
OpenGLPixelFormat pixelFormat;


+ 10
- 1
build/win32/platform_specific_code/juce_win32_Windowing.cpp View File

@@ -2033,9 +2033,18 @@ private:
return 0;
case WM_QUIT:
JUCEApplication::quit();
if (JUCEApplication::getInstance() != 0)
JUCEApplication::getInstance()->systemRequestedQuit();
return 0;
case WM_QUERYENDSESSION:
if (JUCEApplication::getInstance() != 0)
{
JUCEApplication::getInstance()->systemRequestedQuit();
return MessageManager::getInstance()->hasStopMessageBeenSent();
}
return TRUE;
//==============================================================================
case WM_TRAYNOTIFY:
if (component->isCurrentlyBlockedByAnotherModalComponent())


+ 21
- 1
extras/audio plugins/wrapper/VST/juce_VST_Wrapper.cpp View File

@@ -69,12 +69,26 @@
#include "public.sdk/source/vst2.x/aeffeditor.h"
#include "public.sdk/source/vst2.x/audioeffectx.cpp"
#include "public.sdk/source/vst2.x/audioeffect.cpp"
#if JUCE_LINUX
#define __cdecl
#endif
#if ! VST_2_4_EXTENSIONS
#error // You're probably trying to include the wrong VSTSDK version - make sure your include path matches the JUCE_USE_VSTSDK_2_4 flag
#endif
#else
// VSTSDK V2.3 includes..
#include "source/common/audioeffectx.h"
#include "source/common/AEffEditor.hpp"
#include "source/common/audioeffectx.cpp"
#include "source/common/AudioEffect.cpp"
#if (! VST_2_3_EXTENSIONS) || VST_2_4_EXTENSIONS
#error // You're probably trying to include the wrong VSTSDK version - make sure your include path matches the JUCE_USE_VSTSDK_2_4 flag
#endif
typedef long VstInt32;
typedef long VstIntPtr;
enum Vst2StringConstants
@@ -966,7 +980,13 @@ public:
bool setSpeakerArrangement (VstSpeakerArrangement* pluginInput,
VstSpeakerArrangement* pluginOutput)
{
// if this method isn't implemented, nuendo4 + cubase4 crash when you've got multiple channels..
if (numInChans != pluginInput->numChannels
|| numOutChans != pluginOutput->numChannels)
{
setNumInputs (pluginInput->numChannels);
setNumOutputs (pluginOutput->numChannels);
ioChanged();
}
numInChans = pluginInput->numChannels;
numOutChans = pluginOutput->numChannels;


+ 130
- 24
juce_amalgamated.cpp View File

@@ -8029,8 +8029,12 @@ int BufferedInputStream::read (void* destBuffer, int maxBytesToRead)
destBuffer = (void*) (((char*) destBuffer) + bytesAvailable);
}

const int64 oldLastReadPos = lastReadPos;
ensureBuffered();

if (oldLastReadPos == lastReadPos)
break; // if ensureBuffered() failed to read any more data, bail out

if (isExhausted())
break;
}
@@ -9749,6 +9753,11 @@ void LocalisedStrings::loadFromText (const String& fileContents) throw()
}
}

void LocalisedStrings::setIgnoresCase (const bool shouldIgnoreCase) throw()
{
translations.setIgnoresCase (shouldIgnoreCase);
}

static CriticalSection currentMappingsLock;
static LocalisedStrings* currentMappings = 0;

@@ -12592,6 +12601,11 @@ void StringPairArray::remove (const int index) throw()
values.remove (index);
}

void StringPairArray::setIgnoresCase (const bool shouldIgnoreCase) throw()
{
ignoreCase = shouldIgnoreCase;
}

void StringPairArray::minimiseStorageOverheads() throw()
{
keys.minimiseStorageOverheads();
@@ -22363,7 +22377,7 @@ const String AudioDeviceManager::setAudioDeviceSetup (const AudioDeviceSetup& ne
const String newOutputDeviceName (numOutputChansNeeded == 0 ? String::empty : newSetup.outputDeviceName);

if (currentSetup.inputDeviceName != newInputDeviceName
|| currentSetup.inputDeviceName != newOutputDeviceName
|| currentSetup.outputDeviceName != newOutputDeviceName
|| currentAudioDevice == 0)
{
deleteCurrentDevice();
@@ -22813,12 +22827,18 @@ void AudioDeviceManager::setDefaultMidiOutput (const String& deviceName)
{
if (defaultMidiOutputName != deviceName)
{
if (currentCallback != 0 && currentAudioDevice != 0)
currentCallback->audioDeviceStopped();

deleteAndZero (defaultMidiOutput);
defaultMidiOutputName = deviceName;

if (deviceName.isNotEmpty())
defaultMidiOutput = MidiOutput::openDevice (MidiOutput::getDevices().indexOf (deviceName));

if (currentCallback != 0 && currentAudioDevice != 0)
currentCallback->audioDeviceAboutToStart (currentAudioDevice);

updateXml();
sendChangeMessage (this);
}
@@ -71675,6 +71695,11 @@ void AlertWindow::lookAndFeelChanged()
setDropShadowEnabled ((flags & ComponentPeer::windowHasDropShadow) != 0);
}

int AlertWindow::getDesktopWindowStyleFlags() const
{
return getLookAndFeel().getAlertBoxWindowFlags();
}

struct AlertWindowInfo
{
String title, message, button1, button2, button3;
@@ -76036,7 +76061,7 @@ void Graphics::strokePath (const Path& path,
const PathStrokeType& strokeType,
const AffineTransform& transform) const throw()
{
if (! state->colour.isTransparent())
if ((! state->colour.isTransparent()) || state->brush != 0)
{
Path stroke;
strokeType.createStrokedPath (stroke, path, transform);
@@ -244183,9 +244208,18 @@ private:
return 0;

case WM_QUIT:
JUCEApplication::quit();
if (JUCEApplication::getInstance() != 0)
JUCEApplication::getInstance()->systemRequestedQuit();
return 0;

case WM_QUERYENDSESSION:
if (JUCEApplication::getInstance() != 0)
{
JUCEApplication::getInstance()->systemRequestedQuit();
return MessageManager::getInstance()->hasStopMessageBeenSent();
}
return TRUE;

case WM_TRAYNOTIFY:
if (component->isCurrentlyBlockedByAnotherModalComponent())
{
@@ -267842,6 +267876,88 @@ void AppleRemoteDevice::handleCallbackInternal()
// compiled on its own).
#if JUCE_INCLUDED_FILE && JUCE_OPENGL

END_JUCE_NAMESPACE

@interface ThreadSafeNSOpenGLView : NSOpenGLView
{
CriticalSection* contextLock;
bool needsUpdate;
}

- (id) initWithFrame: (NSRect) frameRect pixelFormat: (NSOpenGLPixelFormat*) format;
- (bool) makeActive;
- (void) makeInactive;
- (void) reshape;
@end

@implementation ThreadSafeNSOpenGLView

- (id) initWithFrame: (NSRect) frameRect
pixelFormat: (NSOpenGLPixelFormat*) format
{
contextLock = new CriticalSection();
self = [super initWithFrame: frameRect pixelFormat: format];

if (self != nil)
[[NSNotificationCenter defaultCenter] addObserver: self
selector: @selector (_surfaceNeedsUpdate:)
name: NSViewGlobalFrameDidChangeNotification
object: self];
return self;
}

- (void) dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver: self];
delete contextLock;
[super dealloc];
}

- (bool) makeActive
{
const ScopedLock sl (*contextLock);

if ([self openGLContext] == 0)
return false;

[[self openGLContext] makeCurrentContext];

if (needsUpdate)
{
[super update];
needsUpdate = false;
}

return true;
}

- (void) makeInactive
{
const ScopedLock sl (*contextLock);
[NSOpenGLContext clearCurrentContext];
}

- (void) _surfaceNeedsUpdate: (NSNotification*) notification
{
const ScopedLock sl (*contextLock);
needsUpdate = true;
}

- (void) update
{
const ScopedLock sl (*contextLock);
needsUpdate = true;
}

- (void) reshape
{
const ScopedLock sl (*contextLock);
needsUpdate = true;
}

@end
BEGIN_JUCE_NAMESPACE

class WindowedGLContext : public OpenGLContext
{
public:
@@ -267857,6 +267973,7 @@ public:
int n = 0;
attribs[n++] = NSOpenGLPFADoubleBuffer;
attribs[n++] = NSOpenGLPFAAccelerated;
attribs[n++] = NSOpenGLPFAMPSafe; // NSOpenGLPFAAccelerated, NSOpenGLPFAMultiScreen, NSOpenGLPFASingleRenderer
attribs[n++] = NSOpenGLPFAColorSize;
attribs[n++] = (NSOpenGLPixelFormatAttribute) jmax (pixelFormat.redBits,
pixelFormat.greenBits,
@@ -267874,7 +267991,6 @@ public:
pixelFormat.accumulationBufferAlphaBits);

// xxx not sure how to do fullSceneAntiAliasingNumSamples..

attribs[n++] = NSOpenGLPFASampleBuffers;
attribs[n++] = (NSOpenGLPixelFormatAttribute) 1;
attribs[n++] = NSOpenGLPFAClosestPolicy;
@@ -267884,21 +268000,13 @@ public:
NSOpenGLPixelFormat* format
= [[NSOpenGLPixelFormat alloc] initWithAttributes: attribs];

NSOpenGLView* view
= [[NSOpenGLView alloc] initWithFrame: NSMakeRect (0, 0, 100.0f, 100.0f)
pixelFormat: format];
view = [[ThreadSafeNSOpenGLView alloc] initWithFrame: NSMakeRect (0, 0, 100.0f, 100.0f)
pixelFormat: format];

if (sharedContext != 0)
{
renderContext = [[NSOpenGLContext alloc] initWithFormat: format
shareContext: sharedContext];
[view setOpenGLContext: renderContext];
[renderContext setView: view];
}
else
{
renderContext = [view openGLContext];
}
renderContext = [[[NSOpenGLContext alloc] initWithFormat: format
shareContext: sharedContext] autorelease];
[view setOpenGLContext: renderContext];
[renderContext setView: view];

[format release];

@@ -267915,15 +268023,13 @@ public:
bool makeActive() const throw()
{
jassert (renderContext != 0);
[renderContext makeCurrentContext];
return renderContext != 0;
[view makeActive];
return isActive();
}

bool makeInactive() const throw()
{
if (! isActive())
[NSOpenGLContext clearCurrentContext];

[view makeInactive];
return true;
}

@@ -267941,7 +268047,6 @@ public:

void swapBuffers()
{
glFlush();
[renderContext flushBuffer];
}

@@ -267979,6 +268084,7 @@ public:
juce_UseDebuggingNewOperator

NSOpenGLContext* renderContext;
ThreadSafeNSOpenGLView* view;

private:
OpenGLPixelFormat pixelFormat;


+ 24
- 9
juce_amalgamated.h View File

@@ -2783,6 +2783,7 @@ protected:
numAllocated (0),
granularity (granularity_)
{
jassert (granularity > 0);
}

/** Destructor. */
@@ -8102,6 +8103,10 @@ public:
*/
void remove (const int index) throw();

/** Indicates whether to use a case-insensitive search when looking up a key string.
*/
void setIgnoresCase (const bool shouldIgnoreCase) throw();

/** Reduces the amount of storage being used by the array.

Arrays typically allocate slightly more storage than they need, and after
@@ -11214,23 +11219,26 @@ public:
{
jassert (numValuesToRemove >= 0);

if (numValuesToRemove != 0
if (numValuesToRemove >= 0
&& firstValue < values.getLast())
{
const bool onAtStart = contains (firstValue - 1);
Type lastValue = firstValue + numValuesToRemove;

if (lastValue < firstValue) // possible if the signed arithmetic wraps around
lastValue = values.getLast();

const Type lastValue = firstValue + jmin (numValuesToRemove, values.getLast() - firstValue);
const bool onAtEnd = contains (lastValue);

for (int i = values.size(); --i >= 0;)
{
if (values.getUnchecked(i) >= firstValue
&& values.getUnchecked(i) <= lastValue)
if (values.getUnchecked(i) <= lastValue)
{
values.remove (i);
while (values.getUnchecked(i) >= firstValue)
{
values.remove (i);

if (--i < 0)
break;
}

break;
}
}

@@ -13693,6 +13701,11 @@ public:
*/
const StringArray getCountryCodes() const throw() { return countryCodes; }

/** Indicates whether to use a case-insensitive search when looking up a string.
This defaults to true.
*/
void setIgnoresCase (const bool shouldIgnoreCase) throw();

juce_UseDebuggingNewOperator

private:
@@ -50713,6 +50726,8 @@ protected:
void lookAndFeelChanged();
/** @internal */
void userTriedToCloseWindow();
/** @internal */
int getDesktopWindowStyleFlags() const;

private:
String text;


+ 7
- 1
src/juce_appframework/audio/devices/juce_AudioDeviceManager.cpp View File

@@ -379,7 +379,7 @@ const String AudioDeviceManager::setAudioDeviceSetup (const AudioDeviceSetup& ne
const String newOutputDeviceName (numOutputChansNeeded == 0 ? String::empty : newSetup.outputDeviceName);
if (currentSetup.inputDeviceName != newInputDeviceName
|| currentSetup.inputDeviceName != newOutputDeviceName
|| currentSetup.outputDeviceName != newOutputDeviceName
|| currentAudioDevice == 0)
{
deleteCurrentDevice();
@@ -832,12 +832,18 @@ void AudioDeviceManager::setDefaultMidiOutput (const String& deviceName)
{
if (defaultMidiOutputName != deviceName)
{
if (currentCallback != 0 && currentAudioDevice != 0)
currentCallback->audioDeviceStopped();
deleteAndZero (defaultMidiOutput);
defaultMidiOutputName = deviceName;
if (deviceName.isNotEmpty())
defaultMidiOutput = MidiOutput::openDevice (MidiOutput::getDevices().indexOf (deviceName));
if (currentCallback != 0 && currentAudioDevice != 0)
currentCallback->audioDeviceAboutToStart (currentAudioDevice);
updateXml();
sendChangeMessage (this);
}


+ 5
- 0
src/juce_appframework/gui/components/windows/juce_AlertWindow.cpp View File

@@ -591,6 +591,11 @@ void AlertWindow::lookAndFeelChanged()
setDropShadowEnabled ((flags & ComponentPeer::windowHasDropShadow) != 0);
}
int AlertWindow::getDesktopWindowStyleFlags() const
{
return getLookAndFeel().getAlertBoxWindowFlags();
}
//==============================================================================
struct AlertWindowInfo
{


+ 2
- 0
src/juce_appframework/gui/components/windows/juce_AlertWindow.h View File

@@ -339,6 +339,8 @@ protected:
void lookAndFeelChanged();
/** @internal */
void userTriedToCloseWindow();
/** @internal */
int getDesktopWindowStyleFlags() const;
private:
String text;


+ 1
- 1
src/juce_appframework/gui/graphics/contexts/juce_Graphics.cpp View File

@@ -429,7 +429,7 @@ void Graphics::strokePath (const Path& path,
const PathStrokeType& strokeType,
const AffineTransform& transform) const throw()
{
if (! state->colour.isTransparent())
if ((! state->colour.isTransparent()) || state->brush != 0)
{
Path stroke;
strokeType.createStrokedPath (stroke, path, transform);


+ 1
- 0
src/juce_core/containers/juce_ArrayAllocationBase.h View File

@@ -65,6 +65,7 @@ protected:
numAllocated (0),
granularity (granularity_)
{
jassert (granularity > 0);
}
/** Destructor. */


+ 12
- 9
src/juce_core/containers/juce_SparseSet.h View File

@@ -225,23 +225,26 @@ public:
{
jassert (numValuesToRemove >= 0);
if (numValuesToRemove != 0
if (numValuesToRemove >= 0
&& firstValue < values.getLast())
{
const bool onAtStart = contains (firstValue - 1);
Type lastValue = firstValue + numValuesToRemove;
if (lastValue < firstValue) // possible if the signed arithmetic wraps around
lastValue = values.getLast();
const Type lastValue = firstValue + jmin (numValuesToRemove, values.getLast() - firstValue);
const bool onAtEnd = contains (lastValue);
for (int i = values.size(); --i >= 0;)
{
if (values.getUnchecked(i) >= firstValue
&& values.getUnchecked(i) <= lastValue)
if (values.getUnchecked(i) <= lastValue)
{
values.remove (i);
while (values.getUnchecked(i) >= firstValue)
{
values.remove (i);
if (--i < 0)
break;
}
break;
}
}


+ 4
- 0
src/juce_core/io/streams/juce_BufferedInputStream.cpp View File

@@ -153,8 +153,12 @@ int BufferedInputStream::read (void* destBuffer, int maxBytesToRead)
destBuffer = (void*) (((char*) destBuffer) + bytesAvailable);
}
const int64 oldLastReadPos = lastReadPos;
ensureBuffered();
if (oldLastReadPos == lastReadPos)
break; // if ensureBuffered() failed to read any more data, bail out
if (isExhausted())
break;
}


+ 5
- 0
src/juce_core/text/juce_LocalisedStrings.cpp View File

@@ -124,6 +124,11 @@ void LocalisedStrings::loadFromText (const String& fileContents) throw()
}
}
void LocalisedStrings::setIgnoresCase (const bool shouldIgnoreCase) throw()
{
translations.setIgnoresCase (shouldIgnoreCase);
}
//==============================================================================
static CriticalSection currentMappingsLock;
static LocalisedStrings* currentMappings = 0;


+ 7
- 0
src/juce_core/text/juce_LocalisedStrings.h View File

@@ -181,6 +181,13 @@ public:
*/
const StringArray getCountryCodes() const throw() { return countryCodes; }
//==============================================================================
/** Indicates whether to use a case-insensitive search when looking up a string.
This defaults to true.
*/
void setIgnoresCase (const bool shouldIgnoreCase) throw();
//==============================================================================
juce_UseDebuggingNewOperator


+ 5
- 0
src/juce_core/text/juce_StringPairArray.cpp View File

@@ -130,6 +130,11 @@ void StringPairArray::remove (const int index) throw()
values.remove (index);
}
void StringPairArray::setIgnoresCase (const bool shouldIgnoreCase) throw()
{
ignoreCase = shouldIgnoreCase;
}
void StringPairArray::minimiseStorageOverheads() throw()
{
keys.minimiseStorageOverheads();


+ 5
- 0
src/juce_core/text/juce_StringPairArray.h View File

@@ -138,6 +138,11 @@ public:
*/
void remove (const int index) throw();
//==============================================================================
/** Indicates whether to use a case-insensitive search when looking up a key string.
*/
void setIgnoresCase (const bool shouldIgnoreCase) throw();
//==============================================================================
/** Reduces the amount of storage being used by the array.


Loading…
Cancel
Save