Browse Source

Replaced the old atomic ops with a templated Atomic class. Minor tweaks to directory browser. Jucer development.

tags/2021-05-28
Julian Storer 15 years ago
parent
commit
b56494b29b
36 changed files with 728 additions and 365 deletions
  1. +0
    -4
      extras/Jucer (experimental)/Builds/VisualStudio2005/The Jucer.vcproj
  2. +0
    -4
      extras/Jucer (experimental)/Builds/VisualStudio2008/The Jucer.vcproj
  3. +1
    -3
      extras/Jucer (experimental)/Source/model/Project/jucer_ProjectExport_MSVC.h
  4. +22
    -0
      extras/Jucer (experimental)/Source/model/Project/jucer_ProjectExporter.cpp
  5. +4
    -0
      extras/Jucer (experimental)/Source/model/Project/jucer_ProjectExporter.h
  6. +3
    -8
      extras/Jucer (experimental)/Source/model/Project/jucer_ProjectSaver.h
  7. +14
    -7
      extras/Jucer (experimental)/Source/ui/Editor Base/jucer_EditorCanvas.cpp
  8. +2
    -2
      extras/Jucer (experimental)/Source/ui/Editor Base/jucer_EditorDragOperation.h
  9. +2
    -2
      extras/Jucer (experimental)/Source/utility/jucer_ColourEditorComponent.h
  10. +4
    -2
      extras/Jucer (experimental)/Source/utility/jucer_MarkerListBase.h
  11. +0
    -4
      extras/amalgamator/Builds/VisualStudio2005/Amalgamator.vcproj
  12. +0
    -4
      extras/amalgamator/Builds/VisualStudio2008/Amalgamator.vcproj
  13. +0
    -4
      extras/audio plugin host/Builds/VisualStudio2005/Plugin Host.vcproj
  14. +0
    -4
      extras/audio plugin host/Builds/VisualStudio2008/Plugin Host.vcproj
  15. +0
    -4
      extras/audio plugins/demo/Builds/VisualStudio2005/JuceDemoPlugin.vcproj
  16. +0
    -4
      extras/audio plugins/demo/Builds/VisualStudio2008/JuceDemoPlugin.vcproj
  17. +0
    -4
      extras/binarybuilder/Builds/VisualStudio2005/BinaryBuilder.vcproj
  18. +0
    -4
      extras/binarybuilder/Builds/VisualStudio2008/BinaryBuilder.vcproj
  19. +0
    -4
      extras/example projects/Builds/VisualStudio2005/HelloWorld.vcproj
  20. +0
    -4
      extras/example projects/Builds/VisualStudio2008/HelloWorld.vcproj
  21. +0
    -4
      extras/juce demo/Builds/VisualStudio2005/Juce Demo.vcproj
  22. +0
    -4
      extras/juce demo/Builds/VisualStudio2008/Juce Demo.vcproj
  23. +95
    -48
      juce_amalgamated.cpp
  24. +209
    -87
      juce_amalgamated.h
  25. +6
    -9
      src/containers/juce_ReferenceCountedObject.h
  26. +268
    -91
      src/core/juce_Atomic.h
  27. +49
    -5
      src/core/juce_SystemStats.cpp
  28. +5
    -23
      src/events/juce_Timer.cpp
  29. +8
    -2
      src/gui/components/filebrowser/juce_FileBrowserComponent.cpp
  30. +5
    -0
      src/gui/components/filebrowser/juce_FileChooser.cpp
  31. +3
    -3
      src/gui/components/mouse/juce_MouseCursor.cpp
  32. +1
    -0
      src/gui/components/mouse/juce_MouseCursor.h
  33. +2
    -1
      src/io/files/juce_DirectoryIterator.h
  34. +1
    -1
      src/native/windows/juce_win32_Network.cpp
  35. +17
    -8
      src/native/windows/juce_win32_Threads.cpp
  36. +7
    -7
      src/text/juce_String.cpp

+ 0
- 4
extras/Jucer (experimental)/Builds/VisualStudio2005/The Jucer.vcproj View File

@@ -54,8 +54,6 @@
GenerateDebugInformation="true"
ProgramDatabaseFile=".\Debug\Jucer.pdb"
SubSystem="2"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
TargetMachine="1"/>
<Tool Name="VCALinkTool"/>
<Tool Name="VCManifestTool"/>
@@ -115,8 +113,6 @@
GenerateManifest="false"
OptimizeReferences="2"
EnableCOMDATFolding="2"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
TargetMachine="1"/>
<Tool Name="VCALinkTool"/>
<Tool Name="VCManifestTool"/>


+ 0
- 4
extras/Jucer (experimental)/Builds/VisualStudio2008/The Jucer.vcproj View File

@@ -54,8 +54,6 @@
GenerateDebugInformation="true"
ProgramDatabaseFile=".\Debug\Jucer.pdb"
SubSystem="2"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
TargetMachine="1"/>
<Tool Name="VCALinkTool"/>
<Tool Name="VCManifestTool"/>
@@ -115,8 +113,6 @@
GenerateManifest="false"
OptimizeReferences="2"
EnableCOMDATFolding="2"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
TargetMachine="1"/>
<Tool Name="VCALinkTool"/>
<Tool Name="VCManifestTool"/>


+ 1
- 3
extras/Jucer (experimental)/Source/model/Project/jucer_ProjectExport_MSVC.h View File

@@ -526,9 +526,7 @@ private:
linker->setAttribute ("EnableCOMDATFolding", "2");
}
linker->setAttribute ("RandomizedBaseAddress", "1");
linker->setAttribute ("DataExecutionPrevention", "0");
linker->setAttribute ("TargetMachine", "1");
linker->setAttribute ("TargetMachine", "1"); // (64-bit build = 5)
String extraLinkerOptions (getExtraLinkerFlags().toString());


+ 22
- 0
extras/Jucer (experimental)/Source/model/Project/jucer_ProjectExporter.cpp View File

@@ -115,6 +115,28 @@ const File ProjectExporter::getTargetFolder() const
return project.resolveFilename (getTargetLocation().toString());
}
const String ProjectExporter::getIncludePathForFileInJuceFolder (const String& pathFromJuceFolder, const File& targetIncludeFile) const
{
String juceFolderPath (getJuceFolder().toString());
if (juceFolderPath.startsWithChar ('<'))
{
juceFolderPath = unixStylePath (File::addTrailingSeparator (juceFolderPath.substring (1).dropLastCharacters(1)));
if (juceFolderPath == "/")
juceFolderPath = String::empty;
return "<" + juceFolderPath + pathFromJuceFolder + ">";
}
else
{
const RelativePath juceFromProject (juceFolderPath, RelativePath::projectFolder);
const RelativePath fileFromProject (juceFromProject.getChildFile (pathFromJuceFolder));
const RelativePath fileFromHere (fileFromProject.rebased (project.getFile().getParentDirectory(),
targetIncludeFile.getParentDirectory(), RelativePath::unknown));
return fileFromHere.toUnixStyle().quoted();
}
}
const RelativePath ProjectExporter::getJucePathFromTargetFolder() const
{
RelativePath juceFolder (getJuceFolder().toString(), RelativePath::projectFolder);


+ 4
- 0
extras/Jucer (experimental)/Source/model/Project/jucer_ProjectExporter.h View File

@@ -78,6 +78,9 @@ public:
Value getExtraCompilerFlags() const { return getSetting ("extraCompilerFlags"); }
Value getExtraLinkerFlags() const { return getSetting ("extraLinkerFlags"); }
// This adds the quotes, and may return angle-brackets, eg: <foo/bar.h> or normal quotes.
const String getIncludePathForFileInJuceFolder (const String& pathFromJuceFolder, const File& targetIncludeFile) const;
Array<RelativePath> juceWrapperFiles;
protected:
@@ -87,6 +90,7 @@ protected:
String name;
const RelativePath getJucePathFromTargetFolder() const;
const String getDefaultBuildsRootFolder() const { return "Builds/"; }
const Array<RelativePath> getVSTFilesRequired() const;


+ 3
- 8
extras/Jucer (experimental)/Source/model/Project/jucer_ProjectSaver.h View File

@@ -251,12 +251,7 @@ private:
if (exporter != 0)
{
const RelativePath juceFromProject (exporter->getJuceFolder().toString(), RelativePath::projectFolder);
const RelativePath fileFromProject (juceFromProject.getChildFile (pathFromJuceFolder));
const RelativePath fileFromHere (fileFromProject.rebased (project.getFile().getParentDirectory(),
juceHeaderFile.getParentDirectory(), RelativePath::unknown));
paths.add (fileFromHere.toUnixStyle());
paths.add (exporter->getIncludePathForFileInJuceFolder (pathFromJuceFolder, juceHeaderFile));
guards.add (exporter->getOSTestMacro());
}
}
@@ -266,7 +261,7 @@ private:
if (uniquePaths.size() == 1)
{
out << "#include " << paths[0].quoted() << newLine;
out << "#include " << paths[0] << newLine;
}
else
{
@@ -286,7 +281,7 @@ private:
for (i = 0; i < paths.size(); ++i)
{
out << (i == 0 ? "#if " : "#elif ") << guards[i] << newLine
<< " #include " << paths[i].quoted() << newLine;
<< " #include " << paths[i] << newLine;
}
out << "#endif" << newLine;


+ 14
- 7
extras/Jucer (experimental)/Source/ui/Editor Base/jucer_EditorCanvas.cpp View File

@@ -386,6 +386,7 @@ public:
markerRootY.removeListener (this);
getSelection().removeChangeListener (this);
resizers.clear();
deleteAllChildren();
}
@@ -497,6 +498,7 @@ public:
void resized()
{
updateMarkers();
updateResizeFrames();
}
void changeListenerCallback (void*)
@@ -543,16 +545,19 @@ public:
for (i = 0; i < num; ++i)
requiredIds.add (selection.getSelectedItem(i));
for (i = getNumChildComponents(); --i >= 0;)
for (i = resizers.size(); --i >= 0;)
{
ResizeFrame* resizer = dynamic_cast <ResizeFrame*> (getChildComponent(i));
ResizeFrame* resizer = resizers.getUnchecked(i);
const int index = requiredIds.indexOf (resizer->getTargetObjectID());
if (resizer != 0)
if (index >= 0)
{
if (selection.isSelected (resizer->getTargetObjectID()))
requiredIds.removeString (resizer->getTargetObjectID());
else
delete resizer;
resizer->updatePosition();
requiredIds.remove (index);
}
else
{
resizers.remove (i);
}
}
@@ -563,6 +568,7 @@ public:
if (state.isValid()) // (the id may be a marker)
{
ResizeFrame* frame = new ResizeFrame (canvas, requiredIds[i], state);
resizers.add (frame);
addAndMakeVisible (frame);
frame->updatePosition();
}
@@ -576,6 +582,7 @@ private:
ScopedPointer <LassoComponent <SelectedItems::ItemType> > lasso;
bool mouseDownResult, isDraggingClickedComp;
SelectedItems::ItemType mouseDownCompUID;
OwnedArray <ResizeFrame> resizers;
void updateMarkers (bool isX)
{


+ 2
- 2
extras/Jucer (experimental)/Source/ui/Editor Base/jucer_EditorDragOperation.h View File

@@ -80,7 +80,7 @@ public:
if (isDraggingLeftRight())
{
verticalSnapTargets.add (SnapLine (0, -100.0f, 10000.0f));
verticalSnapTargets.add (SnapLine (getCanvasWidth(), -100.0f, 10000.0f));
verticalSnapTargets.add (SnapLine ((float) getCanvasWidth(), -100.0f, 10000.0f));
if (zone.isDraggingWholeObject() || (zone.isDraggingLeftEdge() && zone.isDraggingRightEdge()))
verticalSnapTargets.add (SnapLine ((float) getCanvasWidth() / 2.0f, 0, 10000.0f));
@@ -89,7 +89,7 @@ public:
if (isDraggingUpDown())
{
horizontalSnapTargets.add (SnapLine (0, -100.0f, 10000.0f));
horizontalSnapTargets.add (SnapLine (getCanvasHeight(), -100.0f, 10000.0f));
horizontalSnapTargets.add (SnapLine ((float) getCanvasHeight(), -100.0f, 10000.0f));
if (zone.isDraggingWholeObject() || (zone.isDraggingTopEdge() && zone.isDraggingBottomEdge()))
horizontalSnapTargets.add (SnapLine ((float) getCanvasHeight() / 2.0f, 0, 10000.0f));


+ 2
- 2
extras/Jucer (experimental)/Source/utility/jucer_ColourEditorComponent.h View File

@@ -206,12 +206,12 @@ private:
return StoredSettings::getInstance()->swatchColours.size();
}
const Colour getSwatchColour (const int index) const
const Colour getSwatchColour (int index) const
{
return StoredSettings::getInstance()->swatchColours [index];
}
void setSwatchColour (const int index, const Colour& newColour) const
void setSwatchColour (int index, const Colour& newColour) const
{
StoredSettings::getInstance()->swatchColours.set (index, newColour);
}


+ 4
- 2
extras/Jucer (experimental)/Source/utility/jucer_MarkerListBase.h View File

@@ -40,10 +40,12 @@ public:
ValueTree getMarker (int index) const { return group.getChild (index); }
ValueTree getMarkerNamed (const String& name) const { return group.getChildWithProperty (getMarkerNameProperty(), name); }
bool contains (const ValueTree& markerState) const { return markerState.isAChildOf (group); }
const Coordinate getCoordinate (const ValueTree& markerState) const { return Coordinate (markerState [getMarkerNameProperty()].toString(), isX); }
const String getName (const ValueTree& markerState) const { return markerState [getMarkerNameProperty()].toString(); }
Value getNameAsValue (const ValueTree& markerState) const { return markerState.getPropertyAsValue (getMarkerNameProperty(), getUndoManager()); }
void setCoordinate (ValueTree& markerState, const Coordinate& newCoord) { markerState.setProperty (getMarkerNameProperty(), newCoord.toString(), getUndoManager()); }
const Coordinate getCoordinate (const ValueTree& markerState) const { return Coordinate (markerState [getMarkerPosProperty()].toString(), isX); }
void setCoordinate (ValueTree& markerState, const Coordinate& newCoord) { markerState.setProperty (getMarkerPosProperty(), newCoord.toString(), getUndoManager()); }
void createMarker (const String& name, int position)
{


+ 0
- 4
extras/amalgamator/Builds/VisualStudio2005/Amalgamator.vcproj View File

@@ -54,8 +54,6 @@
GenerateDebugInformation="true"
ProgramDatabaseFile=".\Debug\amalgamator.pdb"
SubSystem="1"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
TargetMachine="1"/>
<Tool Name="VCALinkTool"/>
<Tool Name="VCManifestTool"/>
@@ -115,8 +113,6 @@
GenerateManifest="false"
OptimizeReferences="2"
EnableCOMDATFolding="2"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
TargetMachine="1"/>
<Tool Name="VCALinkTool"/>
<Tool Name="VCManifestTool"/>


+ 0
- 4
extras/amalgamator/Builds/VisualStudio2008/Amalgamator.vcproj View File

@@ -54,8 +54,6 @@
GenerateDebugInformation="true"
ProgramDatabaseFile=".\Debug\amalgamator.pdb"
SubSystem="1"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
TargetMachine="1"/>
<Tool Name="VCALinkTool"/>
<Tool Name="VCManifestTool"/>
@@ -115,8 +113,6 @@
GenerateManifest="false"
OptimizeReferences="2"
EnableCOMDATFolding="2"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
TargetMachine="1"/>
<Tool Name="VCALinkTool"/>
<Tool Name="VCManifestTool"/>


+ 0
- 4
extras/audio plugin host/Builds/VisualStudio2005/Plugin Host.vcproj View File

@@ -54,8 +54,6 @@
GenerateDebugInformation="true"
ProgramDatabaseFile=".\Debug\Plugin Host.pdb"
SubSystem="2"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
TargetMachine="1"/>
<Tool Name="VCALinkTool"/>
<Tool Name="VCManifestTool"/>
@@ -115,8 +113,6 @@
GenerateManifest="false"
OptimizeReferences="2"
EnableCOMDATFolding="2"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
TargetMachine="1"/>
<Tool Name="VCALinkTool"/>
<Tool Name="VCManifestTool"/>


+ 0
- 4
extras/audio plugin host/Builds/VisualStudio2008/Plugin Host.vcproj View File

@@ -54,8 +54,6 @@
GenerateDebugInformation="true"
ProgramDatabaseFile=".\Debug\Plugin Host.pdb"
SubSystem="2"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
TargetMachine="1"/>
<Tool Name="VCALinkTool"/>
<Tool Name="VCManifestTool"/>
@@ -115,8 +113,6 @@
GenerateManifest="false"
OptimizeReferences="2"
EnableCOMDATFolding="2"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
TargetMachine="1"/>
<Tool Name="VCALinkTool"/>
<Tool Name="VCManifestTool"/>


+ 0
- 4
extras/audio plugins/demo/Builds/VisualStudio2005/JuceDemoPlugin.vcproj View File

@@ -54,8 +54,6 @@
GenerateDebugInformation="true"
ProgramDatabaseFile=".\Debug\JuceDemoPlugin.pdb"
SubSystem="2"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
TargetMachine="1"/>
<Tool Name="VCALinkTool"/>
<Tool Name="VCManifestTool"/>
@@ -115,8 +113,6 @@
GenerateManifest="false"
OptimizeReferences="2"
EnableCOMDATFolding="2"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
TargetMachine="1"/>
<Tool Name="VCALinkTool"/>
<Tool Name="VCManifestTool"/>


+ 0
- 4
extras/audio plugins/demo/Builds/VisualStudio2008/JuceDemoPlugin.vcproj View File

@@ -54,8 +54,6 @@
GenerateDebugInformation="true"
ProgramDatabaseFile=".\Debug\JuceDemoPlugin.pdb"
SubSystem="2"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
TargetMachine="1"/>
<Tool Name="VCALinkTool"/>
<Tool Name="VCManifestTool"/>
@@ -115,8 +113,6 @@
GenerateManifest="false"
OptimizeReferences="2"
EnableCOMDATFolding="2"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
TargetMachine="1"/>
<Tool Name="VCALinkTool"/>
<Tool Name="VCManifestTool"/>


+ 0
- 4
extras/binarybuilder/Builds/VisualStudio2005/BinaryBuilder.vcproj View File

@@ -54,8 +54,6 @@
GenerateDebugInformation="true"
ProgramDatabaseFile=".\Debug\BinaryBuilder.pdb"
SubSystem="1"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
TargetMachine="1"/>
<Tool Name="VCALinkTool"/>
<Tool Name="VCManifestTool"/>
@@ -115,8 +113,6 @@
GenerateManifest="false"
OptimizeReferences="2"
EnableCOMDATFolding="2"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
TargetMachine="1"/>
<Tool Name="VCALinkTool"/>
<Tool Name="VCManifestTool"/>


+ 0
- 4
extras/binarybuilder/Builds/VisualStudio2008/BinaryBuilder.vcproj View File

@@ -54,8 +54,6 @@
GenerateDebugInformation="true"
ProgramDatabaseFile=".\Debug\BinaryBuilder.pdb"
SubSystem="1"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
TargetMachine="1"/>
<Tool Name="VCALinkTool"/>
<Tool Name="VCManifestTool"/>
@@ -115,8 +113,6 @@
GenerateManifest="false"
OptimizeReferences="2"
EnableCOMDATFolding="2"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
TargetMachine="1"/>
<Tool Name="VCALinkTool"/>
<Tool Name="VCManifestTool"/>


+ 0
- 4
extras/example projects/Builds/VisualStudio2005/HelloWorld.vcproj View File

@@ -54,8 +54,6 @@
GenerateDebugInformation="true"
ProgramDatabaseFile=".\Debug\HelloWorld.pdb"
SubSystem="2"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
TargetMachine="1"/>
<Tool Name="VCALinkTool"/>
<Tool Name="VCManifestTool"/>
@@ -115,8 +113,6 @@
GenerateManifest="false"
OptimizeReferences="2"
EnableCOMDATFolding="2"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
TargetMachine="1"/>
<Tool Name="VCALinkTool"/>
<Tool Name="VCManifestTool"/>


+ 0
- 4
extras/example projects/Builds/VisualStudio2008/HelloWorld.vcproj View File

@@ -54,8 +54,6 @@
GenerateDebugInformation="true"
ProgramDatabaseFile=".\Debug\HelloWorld.pdb"
SubSystem="2"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
TargetMachine="1"/>
<Tool Name="VCALinkTool"/>
<Tool Name="VCManifestTool"/>
@@ -115,8 +113,6 @@
GenerateManifest="false"
OptimizeReferences="2"
EnableCOMDATFolding="2"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
TargetMachine="1"/>
<Tool Name="VCALinkTool"/>
<Tool Name="VCManifestTool"/>


+ 0
- 4
extras/juce demo/Builds/VisualStudio2005/Juce Demo.vcproj View File

@@ -54,8 +54,6 @@
GenerateDebugInformation="true"
ProgramDatabaseFile=".\Debug\JuceDemo.pdb"
SubSystem="2"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
TargetMachine="1"/>
<Tool Name="VCALinkTool"/>
<Tool Name="VCManifestTool"/>
@@ -115,8 +113,6 @@
GenerateManifest="false"
OptimizeReferences="2"
EnableCOMDATFolding="2"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
TargetMachine="1"/>
<Tool Name="VCALinkTool"/>
<Tool Name="VCManifestTool"/>


+ 0
- 4
extras/juce demo/Builds/VisualStudio2008/Juce Demo.vcproj View File

@@ -54,8 +54,6 @@
GenerateDebugInformation="true"
ProgramDatabaseFile=".\Debug\JuceDemo.pdb"
SubSystem="2"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
TargetMachine="1"/>
<Tool Name="VCALinkTool"/>
<Tool Name="VCManifestTool"/>
@@ -115,8 +113,6 @@
GenerateManifest="false"
OptimizeReferences="2"
EnableCOMDATFolding="2"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
TargetMachine="1"/>
<Tool Name="VCALinkTool"/>
<Tool Name="VCManifestTool"/>


+ 95
- 48
juce_amalgamated.cpp View File

@@ -1444,6 +1444,54 @@ const StringArray SystemStats::getMACAddressStrings()

static bool juceInitialisedNonGUI = false;

#if JUCE_DEBUG
template <typename Type>
static void juce_testAtomicType (Type)
{
Atomic<Type> a;
a.set ((Type) 10);
a += (Type) 15;
a.memoryBarrier();
a -= (Type) 5;
++a;
++a;
--a;
a.memoryBarrier();

/* These are some simple test cases to check the atomics - let me know
if any of these assertions fail on your system!
*/
jassert (a.get() == (Type) 21);
jassert (a.compareAndSetValue ((Type) 100, (Type) 50) == (Type) 21);
jassert (a.get() == (Type) 21);
jassert (a.compareAndSetValue ((Type) 101, a.get()) == (Type) 21);
jassert (a.get() == (Type) 101);
jassert (! a.compareAndSetBool ((Type) 300, (Type) 200));
jassert (a.get() == (Type) 101);
jassert (a.compareAndSetBool ((Type) 200, a.get()));
jassert (a.get() == (Type) 200);

jassert (a.exchange ((Type) 300) == (Type) 200);
jassert (a.get() == (Type) 300);
}

static void juce_testAtomics()
{
juce_testAtomicType ((int) 0);
juce_testAtomicType ((unsigned int) 0);
juce_testAtomicType ((int32) 0);
juce_testAtomicType ((uint32) 0);
juce_testAtomicType ((long) 0);
juce_testAtomicType ((void*) 0);
juce_testAtomicType ((int*) 0);
#if ! (JUCE_WINDOWS && JUCE_32BIT) // some 64-bit intrinsics aren't available on win32
juce_testAtomicType ((int64) 0);
juce_testAtomicType ((uint64) 0);
#endif

}
#endif

void JUCE_PUBLIC_FUNCTION initialiseJuce_NonGUI()
{
if (! juceInitialisedNonGUI)
@@ -1473,11 +1521,7 @@ void JUCE_PUBLIC_FUNCTION initialiseJuce_NonGUI()
int a2[3];
jassert (numElementsInArray(a2) == 3);

int n = 1;
Atomic::increment (n);
jassert (Atomic::incrementAndReturn (n) == 3);
Atomic::decrement (n);
jassert (Atomic::decrementAndReturn (n) == 1);
juce_testAtomics();

jassert (ByteOrder::swap ((uint16) 0x1122) == 0x2211);
jassert (ByteOrder::swap ((uint32) 0x11223344) == 0x44332211);
@@ -9962,7 +10006,7 @@ public:
static juce_wchar* createUninitialised (const size_t numChars)
{
StringHolder* const s = reinterpret_cast <StringHolder*> (new char [sizeof (StringHolder) + numChars * sizeof (juce_wchar)]);
s->refCount = 0;
s->refCount.value = 0;
s->allocatedNumChars = numChars;
return &(s->text[0]);
}
@@ -9989,12 +10033,12 @@ public:

static void retain (juce_wchar* const text) throw()
{
Atomic::increment (bufferFromText (text)->refCount);
++(bufferFromText (text)->refCount);
}

static inline void release (StringHolder* const b) throw()
{
if (Atomic::decrementAndReturn (b->refCount) == -1 && b != &empty)
if (--(b->refCount) == -1 && b != &empty)
delete[] reinterpret_cast <char*> (b);
}

@@ -10007,7 +10051,7 @@ public:
{
StringHolder* const b = bufferFromText (text);

if (b->refCount <= 0)
if (b->refCount.get() <= 0)
return text;

juce_wchar* const newText = createCopy (text, b->allocatedNumChars);
@@ -10020,7 +10064,7 @@ public:
{
StringHolder* const b = bufferFromText (text);

if (b->refCount <= 0 && b->allocatedNumChars >= numChars)
if (b->refCount.get() <= 0 && b->allocatedNumChars >= numChars)
return text;

juce_wchar* const newText = createUninitialised (jmax (b->allocatedNumChars, numChars));
@@ -10041,7 +10085,7 @@ public:
dest [numChars] = 0;
}

int refCount;
Atomic<int> refCount;
size_t allocatedNumChars;
juce_wchar text[1];

@@ -10108,7 +10152,7 @@ String& String::operator= (const String& other) throw()
{
juce_wchar* const newText = other.text;
StringHolder::retain (newText);
StringHolder::release (static_cast <juce_wchar*> (Atomic::swapPointers ((void* volatile*) &text, newText)));
StringHolder::release (reinterpret_cast <Atomic<juce_wchar*>*> (&text)->exchange (newText));
return *this;
}

@@ -37723,7 +37767,7 @@ public:
InternalTimerThread()
: Thread ("Juce Timer"),
firstTimer (0),
callbackNeeded (false)
callbackNeeded (0)
{
triggerAsyncUpdate();
}
@@ -37766,13 +37810,13 @@ public:

if (timeUntilFirstTimer <= 0)
{
if (callbackNeeded.set (true))
if (callbackNeeded.compareAndSetBool (1, 0))
{
postMessage (new Message());

const uint32 messageDeliveryTimeout = now + 2000;

while (callbackNeeded.get())
while (callbackNeeded.get() != 0)
{
wait (4);

@@ -37814,7 +37858,7 @@ public:
JUCE_CATCH_EXCEPTION
}

callbackNeeded.set (false);
callbackNeeded.set (0);
}

void handleMessage (const Message&)
@@ -37882,24 +37926,7 @@ private:
static InternalTimerThread* instance;
static CriticalSection lock;
Timer* volatile firstTimer;

class AtomicBool
{
public:
AtomicBool (const bool value) throw() : value (static_cast<int32> (value)) {}
~AtomicBool() throw() {}

bool get() const throw() { return value != 0; }
bool set (const bool newValue) { return Atomic::compareAndExchange (value, newValue ? 1 : 0, value) != 0; }

private:
int32 value;

AtomicBool (const AtomicBool&);
AtomicBool& operator= (const AtomicBool&);
};

AtomicBool callbackNeeded;
Atomic <int> callbackNeeded;

void addTimer (Timer* const t) throw()
{
@@ -56530,10 +56557,13 @@ int FileBrowserComponent::getNumSelectedFiles() const throw()

const File FileBrowserComponent::getSelectedFile (int index) const throw()
{
if ((flags & canSelectDirectories) != 0 && filenameBox->getText().isEmpty())
return currentRoot;

if (! filenameBox->isReadOnly())
return currentRoot.getChildFile (filenameBox->getText());
else
return chosenFiles[index];
return chosenFiles[index];
}

bool FileBrowserComponent::currentFileIsValid() const
@@ -56704,6 +56734,9 @@ void FileBrowserComponent::fileDoubleClicked (const File& f)
if (f.isDirectory())
{
setRoot (f);

if ((flags & canSelectDirectories) != 0)
filenameBox->setText (String::empty);
}
else
{
@@ -56997,8 +57030,13 @@ bool FileChooser::showDialog (const bool selectsDirectories,
flags |= FileBrowserComponent::canSelectFiles;

if (selectsDirectories)
{
flags |= FileBrowserComponent::canSelectDirectories;

if (! isSave)
flags |= FileBrowserComponent::filenameBoxIsReadOnly;
}

if (selectMultipleFiles)
flags |= FileBrowserComponent::canSelectMultipleItems;

@@ -69405,13 +69443,13 @@ public:

SharedCursorHandle* retain() throw()
{
Atomic::increment (refCount);
++refCount;
return this;
}

void release()
{
if (Atomic::decrementAndReturn (refCount) == 0)
if (--refCount == 0)
{
if (isStandard)
{
@@ -69429,7 +69467,7 @@ public:

private:
void* const handle;
int32 refCount;
Atomic <int> refCount;
const MouseCursor::StandardCursorType standardType;
const bool isStandard;

@@ -211074,15 +211112,24 @@ const String SystemStats::getFullUserName()
#if ! JUCE_USE_INTRINSICS
// In newer compilers, the inline versions of these are used (in juce_Atomic.h), but in
// older ones we have to actually call the ops as win32 functions..
void Atomic::increment (int32& variable) { InterlockedIncrement (reinterpret_cast <volatile long*> (&variable)); }
int32 Atomic::incrementAndReturn (int32& variable) { return InterlockedIncrement (reinterpret_cast <volatile long*> (&variable)); }
void Atomic::decrement (int32& variable) { InterlockedDecrement (reinterpret_cast <volatile long*> (&variable)); }
int32 Atomic::decrementAndReturn (int32& variable) { return InterlockedDecrement (reinterpret_cast <volatile long*> (&variable)); }
int32 Atomic::compareAndExchange (int32& destination, int32 newValue, int32 oldValue)
{ return InterlockedCompareExchange (reinterpret_cast <volatile long*> (&destination), newValue, oldValue); }
#endif
long juce_InterlockedExchange (volatile long* a, long b) throw() { return InterlockedExchange (a, b); }
long juce_InterlockedIncrement (volatile long* a) throw() { return InterlockedIncrement (a); }
long juce_InterlockedDecrement (volatile long* a) throw() { return InterlockedDecrement (a); }
long juce_InterlockedExchangeAdd (volatile long* a, long b) throw() { return InterlockedExchangeAdd (a, b); }
long juce_InterlockedCompareExchange (volatile long* a, long b, long c) throw() { return InterlockedCompareExchange (a, b, c); }

__int64 juce_InterlockedCompareExchange64 (volatile __int64* value, __int64 newValue, __int64 valueToCompare) throw()
{
jassertfalse; // This operation isn't available in old MS compiler versions!

void* Atomic::swapPointers (void* volatile* value1, void* volatile value2) { return InterlockedExchangePointer (value1, value2); }
__int64 oldValue = *value;
if (oldValue == valueToCompare)
*value = newValue;

return oldValue;
}

#endif

CriticalSection::CriticalSection() throw()
{
@@ -212588,7 +212635,7 @@ static int getMACAddressesViaNetBios (int64* addresses, int maxNum, const bool l
};

ASTAT astat;
zerostruct (astat);
zeromem (&astat, sizeof (astat)); // (can't use zerostruct here in VC6)

LANA_ENUM enums;
zerostruct (enums);


+ 209
- 87
juce_amalgamated.h View File

@@ -3120,108 +3120,231 @@ private:
#ifndef __JUCE_ATOMIC_JUCEHEADER__
#define __JUCE_ATOMIC_JUCEHEADER__

class JUCE_API Atomic
template <typename Type>
class Atomic
{
public:
static void increment (int32& variable);
inline Atomic() throw()
: value (0)
{
}

static int32 incrementAndReturn (int32& variable);
inline Atomic (const Type initialValue) throw()
: value (initialValue)
{
}

static void decrement (int32& variable);
inline Atomic (const Atomic& other) throw()
: value (other.get())
{
}

static int32 decrementAndReturn (int32& variable);
inline Atomic& operator= (const Atomic& other) throw()
{
set (other.get());
}

static int32 compareAndExchange (int32& destination, int32 newValue, int32 requiredCurrentValue);
inline ~Atomic() throw()
{
// This class can only be used for types which are 32 or 64 bits in size.
static_jassert (sizeof (Type) == 4 || sizeof (Type) == 8);
}

static void* swapPointers (void* volatile* value1, void* value2);
Type get() const throw();

private:
Atomic();
Atomic (const Atomic&);
Atomic& operator= (const Atomic&);
void set (Type newValue) throw();

Type exchange (Type value) throw();

Type operator+= (Type amountToAdd) throw();

Type operator-= (Type amountToSubtract) throw();

Type operator++() throw();

Type operator--() throw();

bool compareAndSetBool (Type newValue, Type valueToCompare) throw();

Type compareAndSetValue (Type newValue, Type valueToCompare) throw();

static void memoryBarrier() throw();

#if JUCE_MSVC
__declspec (align (8))
#else
__attribute__ ((aligned (8)))
#endif

Type value;
};

#if (JUCE_IPHONE && (__IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_3_2 || ! defined (__IPHONE_3_2))) \
|| (JUCE_MAC && (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 2))) // Older OSX builds using gcc4.1 or earlier...
|| (JUCE_MAC && (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 2)))
#define JUCE_ATOMICS_MAC 1 // Older OSX builds using gcc4.1 or earlier

inline void Atomic::increment (int32& variable) { OSAtomicIncrement32 (static_cast <int32_t*> (&variable)); }
inline int32 Atomic::incrementAndReturn (int32& variable) { return OSAtomicIncrement32 (static_cast <int32_t*> (&variable)); }
inline void Atomic::decrement (int32& variable) { OSAtomicDecrement32 (static_cast <int32_t*> (&variable)); }
inline int32 Atomic::decrementAndReturn (int32& variable) { return OSAtomicDecrement32 (static_cast <int32_t*> (&variable)); }
#elif JUCE_GCC
#define JUCE_ATOMICS_GCC 1 // GCC with intrinsics

inline int32 Atomic::compareAndExchange (int32& destination, int32 newValue, int32 oldValue)
{
for (;;) // Annoying workaround for OSX only having a bool CAS operation..
{
if (OSAtomicCompareAndSwap32Barrier (oldValue, newValue, static_cast <int32_t*> (&destination)))
return oldValue;
#else
#define JUCE_ATOMICS_WINDOWS 1 // Windows with intrinsics

#if JUCE_USE_INTRINSICS
#pragma intrinsic (_InterlockedExchange, _InterlockedIncrement, _InterlockedDecrement, _InterlockedCompareExchange, \
_InterlockedCompareExchange64, _InterlockedExchangeAdd, _ReadWriteBarrier)
#define juce_InterlockedExchange(a, b) _InterlockedExchange(a, b)
#define juce_InterlockedIncrement(a) _InterlockedIncrement(a)
#define juce_InterlockedDecrement(a) _InterlockedDecrement(a)
#define juce_InterlockedExchangeAdd(a, b) _InterlockedExchangeAdd(a, b)
#define juce_InterlockedCompareExchange(a, b, c) _InterlockedCompareExchange(a, b, c)
#define juce_InterlockedCompareExchange64(a, b, c) _InterlockedCompareExchange64(a, b, c)
#define juce_MemoryBarrier MemoryBarrier
#else
// (these are defined in juce_win32_Threads.cpp)
long juce_InterlockedExchange (volatile long* a, long b) throw();
long juce_InterlockedIncrement (volatile long* a) throw();
long juce_InterlockedDecrement (volatile long* a) throw();
long juce_InterlockedExchangeAdd (volatile long* a, long b) throw();
long juce_InterlockedCompareExchange (volatile long* a, long b, long c) throw();
__int64 juce_InterlockedCompareExchange64 (volatile __int64* a, __int64 b, __int64 c) throw();
static void juce_MemoryBarrier() throw() { long x = 0; juce_InterlockedIncrement (&x); }
#endif

const uint32 result = destination;
if (result != oldValue)
return result;
}
}
#if JUCE_64BIT
#pragma intrinsic (_InterlockedExchangeAdd64, _InterlockedExchange64, _InterlockedIncrement64, _InterlockedDecrement64)
#define juce_InterlockedExchangeAdd64(a, b) _InterlockedExchangeAdd64(a, b)
#define juce_InterlockedExchange64(a, b) _InterlockedExchange64(a, b)
#define juce_InterlockedIncrement64(a) _InterlockedIncrement64(a)
#define juce_InterlockedDecrement64(a) _InterlockedDecrement64(a)
#else
// None of these atomics are available in a 32-bit Windows build!!
static __int64 juce_InterlockedExchangeAdd64 (volatile __int64* a, __int64 b) throw() { jassertfalse; __int64 old = *a; *a += b; return old; }
static __int64 juce_InterlockedExchange64 (volatile __int64* a, __int64 b) throw() { jassertfalse; __int64 old = *a; *a = b; return old; }
static __int64 juce_InterlockedIncrement64 (volatile __int64* a) throw() { jassertfalse; return ++*a; }
static __int64 juce_InterlockedDecrement64 (volatile __int64* a) throw() { jassertfalse; return --*a; }
#endif
#endif

inline void* Atomic::swapPointers (void* volatile* value1, void* value2)
{
void* currentVal = *value1;
#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5 && ! JUCE_64BIT
while (! OSAtomicCompareAndSwap32 (reinterpret_cast <int32_t> (currentVal), reinterpret_cast <int32_t> (value2),
const_cast <int32_t*> (reinterpret_cast <volatile int32_t*> (value1)))) { currentVal = *value1; }
#else
while (! OSAtomicCompareAndSwapPtr (currentVal, value2, value1)) { currentVal = *value1; }
#endif
return currentVal;
}
template <typename Type>
inline Type Atomic<Type>::get() const throw()
{
return const_cast <Atomic<Type>*> (this)->operator+= (0);
}

#elif JUCE_LINUX && __INTEL_COMPILER // Linux with Intel compiler...
template <typename Type>
inline void Atomic<Type>::set (const Type newValue) throw()
{
exchange (newValue);
}

inline void Atomic::increment (int32& variable) { _InterlockedIncrement (&variable); }
inline int32 Atomic::incrementAndReturn (int32& variable) { return _InterlockedIncrement (&variable); }
inline void Atomic::decrement (int32& variable) { _InterlockedDecrement (&variable); }
inline int32 Atomic::decrementAndReturn (int32& variable) { return _InterlockedDecrement (&variable); }
inline int32 Atomic::compareAndExchange (int32& destination, int32 newValue, int32 oldValue)
{ return _InterlockedCompareExchange (&destination, newValue, oldValue); }
template <typename Type>
Type Atomic<Type>::exchange (const Type newValue) throw()
{
#if JUCE_ATOMICS_MAC || JUCE_ATOMICS_GCC
Type currentVal = value;
while (! compareAndSetBool (newValue, currentVal)) { currentVal = value; }
return currentVal;
#elif JUCE_ATOMICS_WINDOWS
return sizeof (Type) == 4 ? (Type) juce_InterlockedExchange ((volatile long*) &value, (long) newValue)
: (Type) juce_InterlockedExchange64 ((volatile __int64*) &value, (__int64) newValue);
#endif
}

inline void* Atomic::swapPointers (void* volatile* value1, void* value2)
{
#if __ia64__
return reinterpret_cast<void*> (_InterlockedExchange64 (const_cast<void**> (value1), reinterpret_cast<__int64> (value2)));
#else
return reinterpret_cast<void*> (_InterlockedExchange (const_cast<void**> (value1), reinterpret_cast<long> (value2)));
#endif
}
template <typename Type>
inline Type Atomic<Type>::operator+= (const Type amountToAdd) throw()
{
#if JUCE_ATOMICS_MAC
return sizeof (Type) == 4 ? (Type) OSAtomicAdd32 ((int32_t) amountToAdd, (int32_t*) &value)
: (Type) OSAtomicAdd64 ((int64_t) amountToAdd, (int64_t*) &value);
#elif JUCE_ATOMICS_WINDOWS
return sizeof (Type) == 4 ? (Type) (juce_InterlockedExchangeAdd ((volatile long*) &value, (long) amountToAdd) + (long) amountToAdd)
: (Type) (juce_InterlockedExchangeAdd64 ((volatile __int64*) &value, (__int64) amountToAdd) + (__int64) amountToAdd);
#elif JUCE_ATOMICS_GCC
return (Type) __sync_add_and_fetch (&value, amountToAdd);
#endif
}

template <typename Type>
inline Type Atomic<Type>::operator-= (const Type amountToSubtract) throw()
{
return operator+= (sizeof (Type) == 4 ? (Type) (-(int32) amountToSubtract)
: (Type) (-(int64) amountToSubtract));
}

template <typename Type>
inline Type Atomic<Type>::operator++() throw()
{
#if JUCE_ATOMICS_MAC
return sizeof (Type) == 4 ? (Type) OSAtomicIncrement32 ((int32_t*) &value)
: (Type) OSAtomicIncrement64 ((int64_t*) &value);
#elif JUCE_ATOMICS_WINDOWS
return sizeof (Type) == 4 ? (Type) juce_InterlockedIncrement ((volatile long*) &value)
: (Type) juce_InterlockedIncrement64 ((volatile __int64*) &value);
#elif JUCE_ATOMICS_GCC
return (Type) __sync_add_and_fetch (&value, 1);
#endif
}

#elif JUCE_GCC // On GCC, use intrinsics...
template <typename Type>
inline Type Atomic<Type>::operator--() throw()
{
#if JUCE_ATOMICS_MAC
return sizeof (Type) == 4 ? (Type) OSAtomicDecrement32 ((int32_t*) &value)
: (Type) OSAtomicDecrement64 ((int64_t*) &value);
#elif JUCE_ATOMICS_WINDOWS
return sizeof (Type) == 4 ? (Type) juce_InterlockedDecrement ((volatile long*) &value)
: (Type) juce_InterlockedDecrement64 ((volatile __int64*) &value);
#elif JUCE_ATOMICS_GCC
return (Type) __sync_add_and_fetch (&value, -1);
#endif
}

inline void Atomic::increment (int32& variable) { __sync_add_and_fetch (&variable, 1); }
inline int32 Atomic::incrementAndReturn (int32& variable) { return __sync_add_and_fetch (&variable, 1); }
inline void Atomic::decrement (int32& variable) { __sync_add_and_fetch (&variable, -1); }
inline int32 Atomic::decrementAndReturn (int32& variable) { return __sync_add_and_fetch (&variable, -1); }
inline int32 Atomic::compareAndExchange (int32& destination, int32 newValue, int32 oldValue)
{ return __sync_val_compare_and_swap (&destination, oldValue, newValue); }
template <typename Type>
inline bool Atomic<Type>::compareAndSetBool (const Type newValue, const Type valueToCompare) throw()
{
#if JUCE_ATOMICS_MAC
return sizeof (Type) == 4 ? (Type) OSAtomicCompareAndSwap32Barrier ((int32_t) valueToCompare, (int32_t) newValue, (int32_t*) &value)
: (Type) OSAtomicCompareAndSwap64Barrier ((int64_t) valueToCompare, (int64_t) newValue, (int64_t*) &value);
#elif JUCE_ATOMICS_WINDOWS
return compareAndSetValue (newValue, valueToCompare) == valueToCompare;
#elif JUCE_ATOMICS_GCC
return __sync_bool_compare_and_swap (&value, valueToCompare, newValue);
#endif
}

inline void* Atomic::swapPointers (void* volatile* value1, void* value2)
template <typename Type>
inline Type Atomic<Type>::compareAndSetValue (const Type newValue, const Type valueToCompare) throw()
{
#if JUCE_ATOMICS_MAC
for (;;) // Annoying workaround for OSX only having a bool CAS operation..
{
void* currentVal = *value1;
while (! __sync_bool_compare_and_swap (value1, currentVal, value2)) { currentVal = *value1; }
return currentVal;
}
if (compareAndSetBool (newValue, valueToCompare))
return valueToCompare;

#elif JUCE_USE_INTRINSICS // Windows...
const Type result = value;
if (result != valueToCompare)
return result;
}

// (If JUCE_USE_INTRINSICS isn't enabled, a fallback version of these methods is declared in juce_win32_Threads.cpp)
#pragma intrinsic (_InterlockedIncrement)
#pragma intrinsic (_InterlockedDecrement)
#pragma intrinsic (_InterlockedCompareExchange)
#elif JUCE_ATOMICS_WINDOWS
return sizeof (Type) == 4 ? (Type) juce_InterlockedCompareExchange ((volatile long*) &value, (long) newValue, (long) valueToCompare)
: (Type) juce_InterlockedCompareExchange64 ((volatile __int64*) &value, (__int64) newValue, (__int64) valueToCompare);
#elif JUCE_ATOMICS_GCC
return __sync_val_compare_and_swap (&value, valueToCompare, newValue);
#endif
}

inline void Atomic::increment (int32& variable) { _InterlockedIncrement (reinterpret_cast <volatile long*> (&variable)); }
inline int32 Atomic::incrementAndReturn (int32& variable) { return _InterlockedIncrement (reinterpret_cast <volatile long*> (&variable)); }
inline void Atomic::decrement (int32& variable) { _InterlockedDecrement (reinterpret_cast <volatile long*> (&variable)); }
inline int32 Atomic::decrementAndReturn (int32& variable) { return _InterlockedDecrement (reinterpret_cast <volatile long*> (&variable)); }
inline int32 Atomic::compareAndExchange (int32& destination, int32 newValue, int32 oldValue)
{ return _InterlockedCompareExchange (reinterpret_cast <volatile long*> (&destination), newValue, oldValue); }
#endif
template <typename Type>
inline void Atomic<Type>::memoryBarrier() throw()
{
#if JUCE_ATOMICS_MAC
OSMemoryBarrier();
#elif JUCE_ATOMICS_GCC
__sync_synchronize();
#elif JUCE_ATOMICS_WINDOWS
juce_MemoryBarrier();
#endif
}

#endif // __JUCE_ATOMIC_JUCEHEADER__
/*** End of inlined file: juce_Atomic.h ***/
@@ -3232,40 +3355,37 @@ public:

inline void incReferenceCount() throw()
{
Atomic::increment (refCounts);

jassert (refCounts > 0);
++refCount;
}

inline void decReferenceCount() throw()
{
jassert (refCounts > 0);
jassert (getReferenceCount() > 0);

if (Atomic::decrementAndReturn (refCounts) == 0)
if (--refCount == 0)
delete this;
}

inline int getReferenceCount() const throw()
{
return refCounts;
return refCount.get();
}

protected:

ReferenceCountedObject()
: refCounts (0)
{
}

virtual ~ReferenceCountedObject()
{
// it's dangerous to delete an object that's still referenced by something else!
jassert (refCounts == 0);
jassert (getReferenceCount() == 0);
}

private:

int32 refCounts;
Atomic <int> refCount;
};

template <class ReferenceCountedObjectClass>
@@ -7768,10 +7888,11 @@ private:
bool* isDirectory, bool* isHidden, int64* fileSize,
Time* modTime, Time* creationTime, bool* isReadOnly);

class Pimpl;

juce_UseDebuggingNewOperator

private:
class Pimpl;
friend class DirectoryIterator;
friend class ScopedPointer<Pimpl>;
ScopedPointer<Pimpl> pimpl;
@@ -9386,6 +9507,7 @@ public:

private:
class SharedCursorHandle;
friend class SharedCursorHandle;
SharedCursorHandle* cursorHandle;

friend class MouseInputSourceInternal;


+ 6
- 9
src/containers/juce_ReferenceCountedObject.h View File

@@ -68,9 +68,7 @@ public:
*/
inline void incReferenceCount() throw()
{
Atomic::increment (refCounts);
jassert (refCounts > 0);
++refCount;
}
/** Decreases the object's reference count.
@@ -79,16 +77,16 @@ public:
*/
inline void decReferenceCount() throw()
{
jassert (refCounts > 0);
jassert (getReferenceCount() > 0);
if (Atomic::decrementAndReturn (refCounts) == 0)
if (--refCount == 0)
delete this;
}
/** Returns the object's current reference count. */
inline int getReferenceCount() const throw()
{
return refCounts;
return refCount.get();
}
@@ -96,7 +94,6 @@ protected:
//==============================================================================
/** Creates the reference-counted object (with an initial ref count of zero). */
ReferenceCountedObject()
: refCounts (0)
{
}
@@ -104,12 +101,12 @@ protected:
virtual ~ReferenceCountedObject()
{
// it's dangerous to delete an object that's still referenced by something else!
jassert (refCounts == 0);
jassert (getReferenceCount() == 0);
}
private:
//==============================================================================
int32 refCounts;
Atomic <int> refCount;
};


+ 268
- 91
src/core/juce_Atomic.h View File

@@ -28,123 +28,300 @@
//==============================================================================
/** Contains static functions for thread-safe atomic operations.
/**
Simple class to hold a primitive value and perform atomic operations on it.
The type used must be a 32 or 64 bit primitive, like an int, pointer, etc.
There are methods to perform most of the basic atomic operations.
*/
class JUCE_API Atomic
template <typename Type>
class Atomic
{
public:
/** Increments an integer in a thread-safe way. */
static void increment (int32& variable);
/** Creates a new value, initialised to zero. */
inline Atomic() throw()
: value (0)
{
}
/** Increments an integer in a thread-safe way and returns its new value. */
static int32 incrementAndReturn (int32& variable);
/** Creates a new value, with a given initial value. */
inline Atomic (const Type initialValue) throw()
: value (initialValue)
{
}
/** Decrements an integer in a thread-safe way. */
static void decrement (int32& variable);
/** Copies another value (atomically). */
inline Atomic (const Atomic& other) throw()
: value (other.get())
{
}
/** Decrements an integer in a thread-safe way and returns its new value. */
static int32 decrementAndReturn (int32& variable);
/** Copies another value onto this one (atomically). */
inline Atomic& operator= (const Atomic& other) throw()
{
set (other.get());
}
/** If the current value of destination is equal to requiredCurrentValue, this
will set it to newValue; otherwise, it will leave it unchanged.
@returns the original value of destination
*/
static int32 compareAndExchange (int32& destination, int32 newValue, int32 requiredCurrentValue);
/** Destructor. */
inline ~Atomic() throw()
{
// This class can only be used for types which are 32 or 64 bits in size.
static_jassert (sizeof (Type) == 4 || sizeof (Type) == 8);
}
/** This atomically sets *value1 to be value2, and returns the previous value of *value1. */
static void* swapPointers (void* volatile* value1, void* value2);
/** Atomically reads and returns the current value. */
Type get() const throw();
private:
Atomic();
Atomic (const Atomic&);
Atomic& operator= (const Atomic&);
};
/** Atomically sets the current value. */
void set (Type newValue) throw();
/** Atomically sets the current value, returning the value that was replaced. */
Type exchange (Type value) throw();
//==============================================================================
#if (JUCE_IPHONE && (__IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_3_2 || ! defined (__IPHONE_3_2))) \
|| (JUCE_MAC && (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 2))) // Older OSX builds using gcc4.1 or earlier...
/** Atomically adds a number to this value, returning the new value. */
Type operator+= (Type amountToAdd) throw();
inline void Atomic::increment (int32& variable) { OSAtomicIncrement32 (static_cast <int32_t*> (&variable)); }
inline int32 Atomic::incrementAndReturn (int32& variable) { return OSAtomicIncrement32 (static_cast <int32_t*> (&variable)); }
inline void Atomic::decrement (int32& variable) { OSAtomicDecrement32 (static_cast <int32_t*> (&variable)); }
inline int32 Atomic::decrementAndReturn (int32& variable) { return OSAtomicDecrement32 (static_cast <int32_t*> (&variable)); }
/** Atomically subtracts a number from this value, returning the new value. */
Type operator-= (Type amountToSubtract) throw();
inline int32 Atomic::compareAndExchange (int32& destination, int32 newValue, int32 oldValue)
{
for (;;) // Annoying workaround for OSX only having a bool CAS operation..
/** Atomically increments this value, returning the new value. */
Type operator++() throw();
/** Atomically decrements this value, returning the new value. */
Type operator--() throw();
/** Atomically compares this value with a target value, and if it is equal, sets
this to be equal to a new value.
This operation is the atomic equivalent of doing this:
@code
bool compareAndSetBool (Type newValue, Type valueToCompare) throw();
{
if (OSAtomicCompareAndSwap32Barrier (oldValue, newValue, static_cast <int32_t*> (&destination)))
return oldValue;
if (get() == valueToCompare)
{
set (newValue);
return true;
}
const uint32 result = destination;
if (result != oldValue)
return result;
return false;
}
}
@endcode
inline void* Atomic::swapPointers (void* volatile* value1, void* value2)
{
void* currentVal = *value1;
#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5 && ! JUCE_64BIT
while (! OSAtomicCompareAndSwap32 (reinterpret_cast <int32_t> (currentVal), reinterpret_cast <int32_t> (value2),
const_cast <int32_t*> (reinterpret_cast <volatile int32_t*> (value1)))) { currentVal = *value1; }
#else
while (! OSAtomicCompareAndSwapPtr (currentVal, value2, value1)) { currentVal = *value1; }
#endif
return currentVal;
}
@returns true if the comparison was true and the value was replaced; false if
the comparison failed and the value was left unchanged.
@see compareAndSetValue
*/
bool compareAndSetBool (Type newValue, Type valueToCompare) throw();
//==============================================================================
#elif JUCE_LINUX && __INTEL_COMPILER // Linux with Intel compiler...
/** Atomically compares this value with a target value, and if it is equal, sets
this to be equal to a new value.
inline void Atomic::increment (int32& variable) { _InterlockedIncrement (&variable); }
inline int32 Atomic::incrementAndReturn (int32& variable) { return _InterlockedIncrement (&variable); }
inline void Atomic::decrement (int32& variable) { _InterlockedDecrement (&variable); }
inline int32 Atomic::decrementAndReturn (int32& variable) { return _InterlockedDecrement (&variable); }
inline int32 Atomic::compareAndExchange (int32& destination, int32 newValue, int32 oldValue)
{ return _InterlockedCompareExchange (&destination, newValue, oldValue); }
This operation is the atomic equivalent of doing this:
@code
Type compareAndSetValue (Type newValue, Type valueToCompare) throw();
{
Type oldValue = get();
if (oldValue == valueToCompare)
set (newValue);
return oldValue;
}
@endcode
@returns the old value before it was changed.
@see compareAndSetBool
*/
Type compareAndSetValue (Type newValue, Type valueToCompare) throw();
/** Performs a memory write barrier. */
static void memoryBarrier() throw();
//==============================================================================
#if JUCE_MSVC
__declspec (align (8))
#else
__attribute__ ((aligned (8)))
#endif
/** The raw value that this class operates on.
This is exposed publically in case you need to manipulate it directly
for performance reasons.
*/
Type value;
};
inline void* Atomic::swapPointers (void* volatile* value1, void* value2)
{
#if __ia64__
return reinterpret_cast<void*> (_InterlockedExchange64 (const_cast<void**> (value1), reinterpret_cast<__int64> (value2)));
#else
return reinterpret_cast<void*> (_InterlockedExchange (const_cast<void**> (value1), reinterpret_cast<long> (value2)));
#endif
}
//==============================================================================
#elif JUCE_GCC // On GCC, use intrinsics...
/*
The following code allows the atomics to be performed as inline functions where possible...
*/
#if (JUCE_IPHONE && (__IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_3_2 || ! defined (__IPHONE_3_2))) \
|| (JUCE_MAC && (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 2)))
#define JUCE_ATOMICS_MAC 1 // Older OSX builds using gcc4.1 or earlier
//==============================================================================
#elif JUCE_GCC
#define JUCE_ATOMICS_GCC 1 // GCC with intrinsics
//==============================================================================
#else
#define JUCE_ATOMICS_WINDOWS 1 // Windows with intrinsics
#if JUCE_USE_INTRINSICS
#pragma intrinsic (_InterlockedExchange, _InterlockedIncrement, _InterlockedDecrement, _InterlockedCompareExchange, \
_InterlockedCompareExchange64, _InterlockedExchangeAdd, _ReadWriteBarrier)
#define juce_InterlockedExchange(a, b) _InterlockedExchange(a, b)
#define juce_InterlockedIncrement(a) _InterlockedIncrement(a)
#define juce_InterlockedDecrement(a) _InterlockedDecrement(a)
#define juce_InterlockedExchangeAdd(a, b) _InterlockedExchangeAdd(a, b)
#define juce_InterlockedCompareExchange(a, b, c) _InterlockedCompareExchange(a, b, c)
#define juce_InterlockedCompareExchange64(a, b, c) _InterlockedCompareExchange64(a, b, c)
#define juce_MemoryBarrier MemoryBarrier
#else
// (these are defined in juce_win32_Threads.cpp)
long juce_InterlockedExchange (volatile long* a, long b) throw();
long juce_InterlockedIncrement (volatile long* a) throw();
long juce_InterlockedDecrement (volatile long* a) throw();
long juce_InterlockedExchangeAdd (volatile long* a, long b) throw();
long juce_InterlockedCompareExchange (volatile long* a, long b, long c) throw();
__int64 juce_InterlockedCompareExchange64 (volatile __int64* a, __int64 b, __int64 c) throw();
static void juce_MemoryBarrier() throw() { long x = 0; juce_InterlockedIncrement (&x); }
#endif
#if JUCE_64BIT
#pragma intrinsic (_InterlockedExchangeAdd64, _InterlockedExchange64, _InterlockedIncrement64, _InterlockedDecrement64)
#define juce_InterlockedExchangeAdd64(a, b) _InterlockedExchangeAdd64(a, b)
#define juce_InterlockedExchange64(a, b) _InterlockedExchange64(a, b)
#define juce_InterlockedIncrement64(a) _InterlockedIncrement64(a)
#define juce_InterlockedDecrement64(a) _InterlockedDecrement64(a)
#else
// None of these atomics are available in a 32-bit Windows build!!
static __int64 juce_InterlockedExchangeAdd64 (volatile __int64* a, __int64 b) throw() { jassertfalse; __int64 old = *a; *a += b; return old; }
static __int64 juce_InterlockedExchange64 (volatile __int64* a, __int64 b) throw() { jassertfalse; __int64 old = *a; *a = b; return old; }
static __int64 juce_InterlockedIncrement64 (volatile __int64* a) throw() { jassertfalse; return ++*a; }
static __int64 juce_InterlockedDecrement64 (volatile __int64* a) throw() { jassertfalse; return --*a; }
#endif
#endif
//==============================================================================
template <typename Type>
inline Type Atomic<Type>::get() const throw()
{
return const_cast <Atomic<Type>*> (this)->operator+= (0);
}
inline void Atomic::increment (int32& variable) { __sync_add_and_fetch (&variable, 1); }
inline int32 Atomic::incrementAndReturn (int32& variable) { return __sync_add_and_fetch (&variable, 1); }
inline void Atomic::decrement (int32& variable) { __sync_add_and_fetch (&variable, -1); }
inline int32 Atomic::decrementAndReturn (int32& variable) { return __sync_add_and_fetch (&variable, -1); }
inline int32 Atomic::compareAndExchange (int32& destination, int32 newValue, int32 oldValue)
{ return __sync_val_compare_and_swap (&destination, oldValue, newValue); }
template <typename Type>
inline void Atomic<Type>::set (const Type newValue) throw()
{
exchange (newValue);
}
template <typename Type>
Type Atomic<Type>::exchange (const Type newValue) throw()
{
#if JUCE_ATOMICS_MAC || JUCE_ATOMICS_GCC
Type currentVal = value;
while (! compareAndSetBool (newValue, currentVal)) { currentVal = value; }
return currentVal;
#elif JUCE_ATOMICS_WINDOWS
return sizeof (Type) == 4 ? (Type) juce_InterlockedExchange ((volatile long*) &value, (long) newValue)
: (Type) juce_InterlockedExchange64 ((volatile __int64*) &value, (__int64) newValue);
#endif
}
template <typename Type>
inline Type Atomic<Type>::operator+= (const Type amountToAdd) throw()
{
#if JUCE_ATOMICS_MAC
return sizeof (Type) == 4 ? (Type) OSAtomicAdd32 ((int32_t) amountToAdd, (int32_t*) &value)
: (Type) OSAtomicAdd64 ((int64_t) amountToAdd, (int64_t*) &value);
#elif JUCE_ATOMICS_WINDOWS
return sizeof (Type) == 4 ? (Type) (juce_InterlockedExchangeAdd ((volatile long*) &value, (long) amountToAdd) + (long) amountToAdd)
: (Type) (juce_InterlockedExchangeAdd64 ((volatile __int64*) &value, (__int64) amountToAdd) + (__int64) amountToAdd);
#elif JUCE_ATOMICS_GCC
return (Type) __sync_add_and_fetch (&value, amountToAdd);
#endif
}
template <typename Type>
inline Type Atomic<Type>::operator-= (const Type amountToSubtract) throw()
{
return operator+= (sizeof (Type) == 4 ? (Type) (-(int32) amountToSubtract)
: (Type) (-(int64) amountToSubtract));
}
inline void* Atomic::swapPointers (void* volatile* value1, void* value2)
template <typename Type>
inline Type Atomic<Type>::operator++() throw()
{
#if JUCE_ATOMICS_MAC
return sizeof (Type) == 4 ? (Type) OSAtomicIncrement32 ((int32_t*) &value)
: (Type) OSAtomicIncrement64 ((int64_t*) &value);
#elif JUCE_ATOMICS_WINDOWS
return sizeof (Type) == 4 ? (Type) juce_InterlockedIncrement ((volatile long*) &value)
: (Type) juce_InterlockedIncrement64 ((volatile __int64*) &value);
#elif JUCE_ATOMICS_GCC
return (Type) __sync_add_and_fetch (&value, 1);
#endif
}
template <typename Type>
inline Type Atomic<Type>::operator--() throw()
{
#if JUCE_ATOMICS_MAC
return sizeof (Type) == 4 ? (Type) OSAtomicDecrement32 ((int32_t*) &value)
: (Type) OSAtomicDecrement64 ((int64_t*) &value);
#elif JUCE_ATOMICS_WINDOWS
return sizeof (Type) == 4 ? (Type) juce_InterlockedDecrement ((volatile long*) &value)
: (Type) juce_InterlockedDecrement64 ((volatile __int64*) &value);
#elif JUCE_ATOMICS_GCC
return (Type) __sync_add_and_fetch (&value, -1);
#endif
}
template <typename Type>
inline bool Atomic<Type>::compareAndSetBool (const Type newValue, const Type valueToCompare) throw()
{
#if JUCE_ATOMICS_MAC
return sizeof (Type) == 4 ? (Type) OSAtomicCompareAndSwap32Barrier ((int32_t) valueToCompare, (int32_t) newValue, (int32_t*) &value)
: (Type) OSAtomicCompareAndSwap64Barrier ((int64_t) valueToCompare, (int64_t) newValue, (int64_t*) &value);
#elif JUCE_ATOMICS_WINDOWS
return compareAndSetValue (newValue, valueToCompare) == valueToCompare;
#elif JUCE_ATOMICS_GCC
return __sync_bool_compare_and_swap (&value, valueToCompare, newValue);
#endif
}
template <typename Type>
inline Type Atomic<Type>::compareAndSetValue (const Type newValue, const Type valueToCompare) throw()
{
#if JUCE_ATOMICS_MAC
for (;;) // Annoying workaround for OSX only having a bool CAS operation..
{
void* currentVal = *value1;
while (! __sync_bool_compare_and_swap (value1, currentVal, value2)) { currentVal = *value1; }
return currentVal;
if (compareAndSetBool (newValue, valueToCompare))
return valueToCompare;
const Type result = value;
if (result != valueToCompare)
return result;
}
//==============================================================================
#elif JUCE_USE_INTRINSICS // Windows...
// (If JUCE_USE_INTRINSICS isn't enabled, a fallback version of these methods is declared in juce_win32_Threads.cpp)
#pragma intrinsic (_InterlockedIncrement)
#pragma intrinsic (_InterlockedDecrement)
#pragma intrinsic (_InterlockedCompareExchange)
inline void Atomic::increment (int32& variable) { _InterlockedIncrement (reinterpret_cast <volatile long*> (&variable)); }
inline int32 Atomic::incrementAndReturn (int32& variable) { return _InterlockedIncrement (reinterpret_cast <volatile long*> (&variable)); }
inline void Atomic::decrement (int32& variable) { _InterlockedDecrement (reinterpret_cast <volatile long*> (&variable)); }
inline int32 Atomic::decrementAndReturn (int32& variable) { return _InterlockedDecrement (reinterpret_cast <volatile long*> (&variable)); }
inline int32 Atomic::compareAndExchange (int32& destination, int32 newValue, int32 oldValue)
{ return _InterlockedCompareExchange (reinterpret_cast <volatile long*> (&destination), newValue, oldValue); }
#endif
#elif JUCE_ATOMICS_WINDOWS
return sizeof (Type) == 4 ? (Type) juce_InterlockedCompareExchange ((volatile long*) &value, (long) newValue, (long) valueToCompare)
: (Type) juce_InterlockedCompareExchange64 ((volatile __int64*) &value, (__int64) newValue, (__int64) valueToCompare);
#elif JUCE_ATOMICS_GCC
return __sync_val_compare_and_swap (&value, valueToCompare, newValue);
#endif
}
template <typename Type>
inline void Atomic<Type>::memoryBarrier() throw()
{
#if JUCE_ATOMICS_MAC
OSMemoryBarrier();
#elif JUCE_ATOMICS_GCC
__sync_synchronize();
#elif JUCE_ATOMICS_WINDOWS
juce_MemoryBarrier();
#endif
}
#endif // __JUCE_ATOMIC_JUCEHEADER__

+ 49
- 5
src/core/juce_SystemStats.cpp View File

@@ -70,6 +70,54 @@ const StringArray SystemStats::getMACAddressStrings()
//==============================================================================
static bool juceInitialisedNonGUI = false;
#if JUCE_DEBUG
template <typename Type>
static void juce_testAtomicType (Type)
{
Atomic<Type> a;
a.set ((Type) 10);
a += (Type) 15;
a.memoryBarrier();
a -= (Type) 5;
++a;
++a;
--a;
a.memoryBarrier();
/* These are some simple test cases to check the atomics - let me know
if any of these assertions fail on your system!
*/
jassert (a.get() == (Type) 21);
jassert (a.compareAndSetValue ((Type) 100, (Type) 50) == (Type) 21);
jassert (a.get() == (Type) 21);
jassert (a.compareAndSetValue ((Type) 101, a.get()) == (Type) 21);
jassert (a.get() == (Type) 101);
jassert (! a.compareAndSetBool ((Type) 300, (Type) 200));
jassert (a.get() == (Type) 101);
jassert (a.compareAndSetBool ((Type) 200, a.get()));
jassert (a.get() == (Type) 200);
jassert (a.exchange ((Type) 300) == (Type) 200);
jassert (a.get() == (Type) 300);
}
static void juce_testAtomics()
{
juce_testAtomicType ((int) 0);
juce_testAtomicType ((unsigned int) 0);
juce_testAtomicType ((int32) 0);
juce_testAtomicType ((uint32) 0);
juce_testAtomicType ((long) 0);
juce_testAtomicType ((void*) 0);
juce_testAtomicType ((int*) 0);
#if ! (JUCE_WINDOWS && JUCE_32BIT) // some 64-bit intrinsics aren't available on win32
juce_testAtomicType ((int64) 0);
juce_testAtomicType ((uint64) 0);
#endif
}
#endif
void JUCE_PUBLIC_FUNCTION initialiseJuce_NonGUI()
{
if (! juceInitialisedNonGUI)
@@ -99,11 +147,7 @@ void JUCE_PUBLIC_FUNCTION initialiseJuce_NonGUI()
int a2[3];
jassert (numElementsInArray(a2) == 3);
int n = 1;
Atomic::increment (n);
jassert (Atomic::incrementAndReturn (n) == 3);
Atomic::decrement (n);
jassert (Atomic::decrementAndReturn (n) == 1);
juce_testAtomics();
jassert (ByteOrder::swap ((uint16) 0x1122) == 0x2211);
jassert (ByteOrder::swap ((uint32) 0x11223344) == 0x44332211);


+ 5
- 23
src/events/juce_Timer.cpp View File

@@ -48,7 +48,7 @@ public:
InternalTimerThread()
: Thread ("Juce Timer"),
firstTimer (0),
callbackNeeded (false)
callbackNeeded (0)
{
triggerAsyncUpdate();
}
@@ -96,7 +96,7 @@ public:
but if it fails it means the message-thread changed the value from under us so at least
some processing is happenening and we can just loop around and try again
*/
if (callbackNeeded.set (true))
if (callbackNeeded.compareAndSetBool (1, 0))
{
postMessage (new Message());
@@ -106,7 +106,7 @@ public:
*/
const uint32 messageDeliveryTimeout = now + 2000;
while (callbackNeeded.get())
while (callbackNeeded.get() != 0)
{
wait (4);
@@ -154,7 +154,7 @@ public:
get a message then the value is true and the other thread can only set it to true again and
we will get another callback to set it to false.
*/
callbackNeeded.set (false);
callbackNeeded.set (0);
}
void handleMessage (const Message&)
@@ -222,25 +222,7 @@ private:
static InternalTimerThread* instance;
static CriticalSection lock;
Timer* volatile firstTimer;
//==============================================================================
class AtomicBool
{
public:
AtomicBool (const bool value) throw() : value (static_cast<int32> (value)) {}
~AtomicBool() throw() {}
bool get() const throw() { return value != 0; }
bool set (const bool newValue) { return Atomic::compareAndExchange (value, newValue ? 1 : 0, value) != 0; }
private:
int32 value;
AtomicBool (const AtomicBool&);
AtomicBool& operator= (const AtomicBool&);
};
AtomicBool callbackNeeded;
Atomic <int> callbackNeeded;
//==============================================================================
void addTimer (Timer* const t) throw()


+ 8
- 2
src/gui/components/filebrowser/juce_FileBrowserComponent.cpp View File

@@ -176,10 +176,13 @@ int FileBrowserComponent::getNumSelectedFiles() const throw()
const File FileBrowserComponent::getSelectedFile (int index) const throw()
{
if ((flags & canSelectDirectories) != 0 && filenameBox->getText().isEmpty())
return currentRoot;
if (! filenameBox->isReadOnly())
return currentRoot.getChildFile (filenameBox->getText());
else
return chosenFiles[index];
return chosenFiles[index];
}
bool FileBrowserComponent::currentFileIsValid() const
@@ -354,6 +357,9 @@ void FileBrowserComponent::fileDoubleClicked (const File& f)
if (f.isDirectory())
{
setRoot (f);
if ((flags & canSelectDirectories) != 0)
filenameBox->setText (String::empty);
}
else
{


+ 5
- 0
src/gui/components/filebrowser/juce_FileChooser.cpp View File

@@ -137,8 +137,13 @@ bool FileChooser::showDialog (const bool selectsDirectories,
flags |= FileBrowserComponent::canSelectFiles;
if (selectsDirectories)
{
flags |= FileBrowserComponent::canSelectDirectories;
if (! isSave)
flags |= FileBrowserComponent::filenameBoxIsReadOnly;
}
if (selectMultipleFiles)
flags |= FileBrowserComponent::canSelectMultipleItems;


+ 3
- 3
src/gui/components/mouse/juce_MouseCursor.cpp View File

@@ -73,13 +73,13 @@ public:
SharedCursorHandle* retain() throw()
{
Atomic::increment (refCount);
++refCount;
return this;
}
void release()
{
if (Atomic::decrementAndReturn (refCount) == 0)
if (--refCount == 0)
{
if (isStandard)
{
@@ -99,7 +99,7 @@ public:
private:
void* const handle;
int32 refCount;
Atomic <int> refCount;
const MouseCursor::StandardCursorType standardType;
const bool isStandard;


+ 1
- 0
src/gui/components/mouse/juce_MouseCursor.h View File

@@ -145,6 +145,7 @@ public:
private:
class SharedCursorHandle;
friend class SharedCursorHandle;
SharedCursorHandle* cursorHandle;
friend class MouseInputSourceInternal;


+ 2
- 1
src/io/files/juce_DirectoryIterator.h View File

@@ -128,10 +128,11 @@ private:
bool* isDirectory, bool* isHidden, int64* fileSize,
Time* modTime, Time* creationTime, bool* isReadOnly);
class Pimpl;
juce_UseDebuggingNewOperator
private:
class Pimpl;
friend class DirectoryIterator;
friend class ScopedPointer<Pimpl>;
ScopedPointer<Pimpl> pimpl;


+ 1
- 1
src/native/windows/juce_win32_Network.cpp View File

@@ -352,7 +352,7 @@ static int getMACAddressesViaNetBios (int64* addresses, int maxNum, const bool l
};
ASTAT astat;
zerostruct (astat);
zeromem (&astat, sizeof (astat)); // (can't use zerostruct here in VC6)
LANA_ENUM enums;
zerostruct (enums);


+ 17
- 8
src/native/windows/juce_win32_Threads.cpp View File

@@ -35,15 +35,24 @@
#if ! JUCE_USE_INTRINSICS
// In newer compilers, the inline versions of these are used (in juce_Atomic.h), but in
// older ones we have to actually call the ops as win32 functions..
void Atomic::increment (int32& variable) { InterlockedIncrement (reinterpret_cast <volatile long*> (&variable)); }
int32 Atomic::incrementAndReturn (int32& variable) { return InterlockedIncrement (reinterpret_cast <volatile long*> (&variable)); }
void Atomic::decrement (int32& variable) { InterlockedDecrement (reinterpret_cast <volatile long*> (&variable)); }
int32 Atomic::decrementAndReturn (int32& variable) { return InterlockedDecrement (reinterpret_cast <volatile long*> (&variable)); }
int32 Atomic::compareAndExchange (int32& destination, int32 newValue, int32 oldValue)
{ return InterlockedCompareExchange (reinterpret_cast <volatile long*> (&destination), newValue, oldValue); }
#endif
long juce_InterlockedExchange (volatile long* a, long b) throw() { return InterlockedExchange (a, b); }
long juce_InterlockedIncrement (volatile long* a) throw() { return InterlockedIncrement (a); }
long juce_InterlockedDecrement (volatile long* a) throw() { return InterlockedDecrement (a); }
long juce_InterlockedExchangeAdd (volatile long* a, long b) throw() { return InterlockedExchangeAdd (a, b); }
long juce_InterlockedCompareExchange (volatile long* a, long b, long c) throw() { return InterlockedCompareExchange (a, b, c); }
__int64 juce_InterlockedCompareExchange64 (volatile __int64* value, __int64 newValue, __int64 valueToCompare) throw()
{
jassertfalse; // This operation isn't available in old MS compiler versions!
__int64 oldValue = *value;
if (oldValue == valueToCompare)
*value = newValue;
void* Atomic::swapPointers (void* volatile* value1, void* volatile value2) { return InterlockedExchangePointer (value1, value2); }
return oldValue;
}
#endif
//==============================================================================
CriticalSection::CriticalSection() throw()


+ 7
- 7
src/text/juce_String.cpp View File

@@ -63,7 +63,7 @@ public:
static juce_wchar* createUninitialised (const size_t numChars)
{
StringHolder* const s = reinterpret_cast <StringHolder*> (new char [sizeof (StringHolder) + numChars * sizeof (juce_wchar)]);
s->refCount = 0;
s->refCount.value = 0;
s->allocatedNumChars = numChars;
return &(s->text[0]);
}
@@ -91,12 +91,12 @@ public:
//==============================================================================
static void retain (juce_wchar* const text) throw()
{
Atomic::increment (bufferFromText (text)->refCount);
++(bufferFromText (text)->refCount);
}
static inline void release (StringHolder* const b) throw()
{
if (Atomic::decrementAndReturn (b->refCount) == -1 && b != &empty)
if (--(b->refCount) == -1 && b != &empty)
delete[] reinterpret_cast <char*> (b);
}
@@ -110,7 +110,7 @@ public:
{
StringHolder* const b = bufferFromText (text);
if (b->refCount <= 0)
if (b->refCount.get() <= 0)
return text;
juce_wchar* const newText = createCopy (text, b->allocatedNumChars);
@@ -123,7 +123,7 @@ public:
{
StringHolder* const b = bufferFromText (text);
if (b->refCount <= 0 && b->allocatedNumChars >= numChars)
if (b->refCount.get() <= 0 && b->allocatedNumChars >= numChars)
return text;
juce_wchar* const newText = createUninitialised (jmax (b->allocatedNumChars, numChars));
@@ -145,7 +145,7 @@ public:
}
//==============================================================================
int refCount;
Atomic<int> refCount;
size_t allocatedNumChars;
juce_wchar text[1];
@@ -214,7 +214,7 @@ String& String::operator= (const String& other) throw()
{
juce_wchar* const newText = other.text;
StringHolder::retain (newText);
StringHolder::release (static_cast <juce_wchar*> (Atomic::swapPointers ((void* volatile*) &text, newText)));
StringHolder::release (reinterpret_cast <Atomic<juce_wchar*>*> (&text)->exchange (newText));
return *this;
}


Loading…
Cancel
Save