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


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

@@ -54,8 +54,6 @@
GenerateDebugInformation="true" GenerateDebugInformation="true"
ProgramDatabaseFile=".\Debug\Jucer.pdb" ProgramDatabaseFile=".\Debug\Jucer.pdb"
SubSystem="2" SubSystem="2"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
TargetMachine="1"/> TargetMachine="1"/>
<Tool Name="VCALinkTool"/> <Tool Name="VCALinkTool"/>
<Tool Name="VCManifestTool"/> <Tool Name="VCManifestTool"/>
@@ -115,8 +113,6 @@
GenerateManifest="false" GenerateManifest="false"
OptimizeReferences="2" OptimizeReferences="2"
EnableCOMDATFolding="2" EnableCOMDATFolding="2"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
TargetMachine="1"/> TargetMachine="1"/>
<Tool Name="VCALinkTool"/> <Tool Name="VCALinkTool"/>
<Tool Name="VCManifestTool"/> <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 ("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()); 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()); 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 const RelativePath ProjectExporter::getJucePathFromTargetFolder() const
{ {
RelativePath juceFolder (getJuceFolder().toString(), RelativePath::projectFolder); 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 getExtraCompilerFlags() const { return getSetting ("extraCompilerFlags"); }
Value getExtraLinkerFlags() const { return getSetting ("extraLinkerFlags"); } 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; Array<RelativePath> juceWrapperFiles;
protected: protected:
@@ -87,6 +90,7 @@ protected:
String name; String name;
const RelativePath getJucePathFromTargetFolder() const; const RelativePath getJucePathFromTargetFolder() const;
const String getDefaultBuildsRootFolder() const { return "Builds/"; } const String getDefaultBuildsRootFolder() const { return "Builds/"; }
const Array<RelativePath> getVSTFilesRequired() const; 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) 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()); guards.add (exporter->getOSTestMacro());
} }
} }
@@ -266,7 +261,7 @@ private:
if (uniquePaths.size() == 1) if (uniquePaths.size() == 1)
{ {
out << "#include " << paths[0].quoted() << newLine;
out << "#include " << paths[0] << newLine;
} }
else else
{ {
@@ -286,7 +281,7 @@ private:
for (i = 0; i < paths.size(); ++i) for (i = 0; i < paths.size(); ++i)
{ {
out << (i == 0 ? "#if " : "#elif ") << guards[i] << newLine out << (i == 0 ? "#if " : "#elif ") << guards[i] << newLine
<< " #include " << paths[i].quoted() << newLine;
<< " #include " << paths[i] << newLine;
} }
out << "#endif" << 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); markerRootY.removeListener (this);
getSelection().removeChangeListener (this); getSelection().removeChangeListener (this);
resizers.clear();
deleteAllChildren(); deleteAllChildren();
} }
@@ -497,6 +498,7 @@ public:
void resized() void resized()
{ {
updateMarkers(); updateMarkers();
updateResizeFrames();
} }
void changeListenerCallback (void*) void changeListenerCallback (void*)
@@ -543,16 +545,19 @@ public:
for (i = 0; i < num; ++i) for (i = 0; i < num; ++i)
requiredIds.add (selection.getSelectedItem(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) if (state.isValid()) // (the id may be a marker)
{ {
ResizeFrame* frame = new ResizeFrame (canvas, requiredIds[i], state); ResizeFrame* frame = new ResizeFrame (canvas, requiredIds[i], state);
resizers.add (frame);
addAndMakeVisible (frame); addAndMakeVisible (frame);
frame->updatePosition(); frame->updatePosition();
} }
@@ -576,6 +582,7 @@ private:
ScopedPointer <LassoComponent <SelectedItems::ItemType> > lasso; ScopedPointer <LassoComponent <SelectedItems::ItemType> > lasso;
bool mouseDownResult, isDraggingClickedComp; bool mouseDownResult, isDraggingClickedComp;
SelectedItems::ItemType mouseDownCompUID; SelectedItems::ItemType mouseDownCompUID;
OwnedArray <ResizeFrame> resizers;
void updateMarkers (bool isX) 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()) if (isDraggingLeftRight())
{ {
verticalSnapTargets.add (SnapLine (0, -100.0f, 10000.0f)); 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())) if (zone.isDraggingWholeObject() || (zone.isDraggingLeftEdge() && zone.isDraggingRightEdge()))
verticalSnapTargets.add (SnapLine ((float) getCanvasWidth() / 2.0f, 0, 10000.0f)); verticalSnapTargets.add (SnapLine ((float) getCanvasWidth() / 2.0f, 0, 10000.0f));
@@ -89,7 +89,7 @@ public:
if (isDraggingUpDown()) if (isDraggingUpDown())
{ {
horizontalSnapTargets.add (SnapLine (0, -100.0f, 10000.0f)); 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())) if (zone.isDraggingWholeObject() || (zone.isDraggingTopEdge() && zone.isDraggingBottomEdge()))
horizontalSnapTargets.add (SnapLine ((float) getCanvasHeight() / 2.0f, 0, 10000.0f)); 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(); return StoredSettings::getInstance()->swatchColours.size();
} }
const Colour getSwatchColour (const int index) const
const Colour getSwatchColour (int index) const
{ {
return StoredSettings::getInstance()->swatchColours [index]; 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); 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 getMarker (int index) const { return group.getChild (index); }
ValueTree getMarkerNamed (const String& name) const { return group.getChildWithProperty (getMarkerNameProperty(), name); } ValueTree getMarkerNamed (const String& name) const { return group.getChildWithProperty (getMarkerNameProperty(), name); }
bool contains (const ValueTree& markerState) const { return markerState.isAChildOf (group); } 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(); } const String getName (const ValueTree& markerState) const { return markerState [getMarkerNameProperty()].toString(); }
Value getNameAsValue (const ValueTree& markerState) const { return markerState.getPropertyAsValue (getMarkerNameProperty(), getUndoManager()); } 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) void createMarker (const String& name, int position)
{ {


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

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


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

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


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

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


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

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


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

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


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

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


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

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


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

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


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

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


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

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


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

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


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

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


+ 95
- 48
juce_amalgamated.cpp View File

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


static bool juceInitialisedNonGUI = false; 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() void JUCE_PUBLIC_FUNCTION initialiseJuce_NonGUI()
{ {
if (! juceInitialisedNonGUI) if (! juceInitialisedNonGUI)
@@ -1473,11 +1521,7 @@ void JUCE_PUBLIC_FUNCTION initialiseJuce_NonGUI()
int a2[3]; int a2[3];
jassert (numElementsInArray(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 ((uint16) 0x1122) == 0x2211);
jassert (ByteOrder::swap ((uint32) 0x11223344) == 0x44332211); jassert (ByteOrder::swap ((uint32) 0x11223344) == 0x44332211);
@@ -9962,7 +10006,7 @@ public:
static juce_wchar* createUninitialised (const size_t numChars) static juce_wchar* createUninitialised (const size_t numChars)
{ {
StringHolder* const s = reinterpret_cast <StringHolder*> (new char [sizeof (StringHolder) + numChars * sizeof (juce_wchar)]); StringHolder* const s = reinterpret_cast <StringHolder*> (new char [sizeof (StringHolder) + numChars * sizeof (juce_wchar)]);
s->refCount = 0;
s->refCount.value = 0;
s->allocatedNumChars = numChars; s->allocatedNumChars = numChars;
return &(s->text[0]); return &(s->text[0]);
} }
@@ -9989,12 +10033,12 @@ public:


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


static inline void release (StringHolder* const b) throw() 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); delete[] reinterpret_cast <char*> (b);
} }


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


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


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


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


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


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


@@ -10108,7 +10152,7 @@ String& String::operator= (const String& other) throw()
{ {
juce_wchar* const newText = other.text; juce_wchar* const newText = other.text;
StringHolder::retain (newText); 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; return *this;
} }


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


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


const uint32 messageDeliveryTimeout = now + 2000; const uint32 messageDeliveryTimeout = now + 2000;


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


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


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


void handleMessage (const Message&) void handleMessage (const Message&)
@@ -37882,24 +37926,7 @@ private:
static InternalTimerThread* instance; static InternalTimerThread* instance;
static CriticalSection lock; static CriticalSection lock;
Timer* volatile firstTimer; 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() void addTimer (Timer* const t) throw()
{ {
@@ -56530,10 +56557,13 @@ int FileBrowserComponent::getNumSelectedFiles() const throw()


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

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


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

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


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


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

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


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


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


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


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


@@ -211074,15 +211112,24 @@ const String SystemStats::getFullUserName()
#if ! JUCE_USE_INTRINSICS #if ! JUCE_USE_INTRINSICS
// In newer compilers, the inline versions of these are used (in juce_Atomic.h), but in // 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.. // 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() CriticalSection::CriticalSection() throw()
{ {
@@ -212588,7 +212635,7 @@ static int getMACAddressesViaNetBios (int64* addresses, int maxNum, const bool l
}; };


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


LANA_ENUM enums; LANA_ENUM enums;
zerostruct (enums); zerostruct (enums);


+ 209
- 87
juce_amalgamated.h View File

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


class JUCE_API Atomic
template <typename Type>
class Atomic
{ {
public: 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))) \ #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__ #endif // __JUCE_ATOMIC_JUCEHEADER__
/*** End of inlined file: juce_Atomic.h ***/ /*** End of inlined file: juce_Atomic.h ***/
@@ -3232,40 +3355,37 @@ public:


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

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


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


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


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


protected: protected:


ReferenceCountedObject() ReferenceCountedObject()
: refCounts (0)
{ {
} }


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


private: private:


int32 refCounts;
Atomic <int> refCount;
}; };


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


class Pimpl;

juce_UseDebuggingNewOperator juce_UseDebuggingNewOperator


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


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


friend class MouseInputSourceInternal; friend class MouseInputSourceInternal;


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

@@ -68,9 +68,7 @@ public:
*/ */
inline void incReferenceCount() throw() inline void incReferenceCount() throw()
{ {
Atomic::increment (refCounts);
jassert (refCounts > 0);
++refCount;
} }
/** Decreases the object's reference count. /** Decreases the object's reference count.
@@ -79,16 +77,16 @@ public:
*/ */
inline void decReferenceCount() throw() inline void decReferenceCount() throw()
{ {
jassert (refCounts > 0);
jassert (getReferenceCount() > 0);
if (Atomic::decrementAndReturn (refCounts) == 0)
if (--refCount == 0)
delete this; delete this;
} }
/** Returns the object's current reference count. */ /** Returns the object's current reference count. */
inline int getReferenceCount() const throw() 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). */ /** Creates the reference-counted object (with an initial ref count of zero). */
ReferenceCountedObject() ReferenceCountedObject()
: refCounts (0)
{ {
} }
@@ -104,12 +101,12 @@ protected:
virtual ~ReferenceCountedObject() virtual ~ReferenceCountedObject()
{ {
// it's dangerous to delete an object that's still referenced by something else! // it's dangerous to delete an object that's still referenced by something else!
jassert (refCounts == 0);
jassert (getReferenceCount() == 0);
} }
private: 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: 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__ #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; 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() void JUCE_PUBLIC_FUNCTION initialiseJuce_NonGUI()
{ {
if (! juceInitialisedNonGUI) if (! juceInitialisedNonGUI)
@@ -99,11 +147,7 @@ void JUCE_PUBLIC_FUNCTION initialiseJuce_NonGUI()
int a2[3]; int a2[3];
jassert (numElementsInArray(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 ((uint16) 0x1122) == 0x2211);
jassert (ByteOrder::swap ((uint32) 0x11223344) == 0x44332211); jassert (ByteOrder::swap ((uint32) 0x11223344) == 0x44332211);


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

@@ -48,7 +48,7 @@ public:
InternalTimerThread() InternalTimerThread()
: Thread ("Juce Timer"), : Thread ("Juce Timer"),
firstTimer (0), firstTimer (0),
callbackNeeded (false)
callbackNeeded (0)
{ {
triggerAsyncUpdate(); triggerAsyncUpdate();
} }
@@ -96,7 +96,7 @@ public:
but if it fails it means the message-thread changed the value from under us so at least 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 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()); postMessage (new Message());
@@ -106,7 +106,7 @@ public:
*/ */
const uint32 messageDeliveryTimeout = now + 2000; const uint32 messageDeliveryTimeout = now + 2000;
while (callbackNeeded.get())
while (callbackNeeded.get() != 0)
{ {
wait (4); 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 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. we will get another callback to set it to false.
*/ */
callbackNeeded.set (false);
callbackNeeded.set (0);
} }
void handleMessage (const Message&) void handleMessage (const Message&)
@@ -222,25 +222,7 @@ private:
static InternalTimerThread* instance; static InternalTimerThread* instance;
static CriticalSection lock; static CriticalSection lock;
Timer* volatile firstTimer; 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() 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() const File FileBrowserComponent::getSelectedFile (int index) const throw()
{ {
if ((flags & canSelectDirectories) != 0 && filenameBox->getText().isEmpty())
return currentRoot;
if (! filenameBox->isReadOnly()) if (! filenameBox->isReadOnly())
return currentRoot.getChildFile (filenameBox->getText()); return currentRoot.getChildFile (filenameBox->getText());
else
return chosenFiles[index];
return chosenFiles[index];
} }
bool FileBrowserComponent::currentFileIsValid() const bool FileBrowserComponent::currentFileIsValid() const
@@ -354,6 +357,9 @@ void FileBrowserComponent::fileDoubleClicked (const File& f)
if (f.isDirectory()) if (f.isDirectory())
{ {
setRoot (f); setRoot (f);
if ((flags & canSelectDirectories) != 0)
filenameBox->setText (String::empty);
} }
else 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; flags |= FileBrowserComponent::canSelectFiles;
if (selectsDirectories) if (selectsDirectories)
{
flags |= FileBrowserComponent::canSelectDirectories; flags |= FileBrowserComponent::canSelectDirectories;
if (! isSave)
flags |= FileBrowserComponent::filenameBoxIsReadOnly;
}
if (selectMultipleFiles) if (selectMultipleFiles)
flags |= FileBrowserComponent::canSelectMultipleItems; flags |= FileBrowserComponent::canSelectMultipleItems;


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

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


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

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


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

@@ -128,10 +128,11 @@ private:
bool* isDirectory, bool* isHidden, int64* fileSize, bool* isDirectory, bool* isHidden, int64* fileSize,
Time* modTime, Time* creationTime, bool* isReadOnly); Time* modTime, Time* creationTime, bool* isReadOnly);
class Pimpl;
juce_UseDebuggingNewOperator juce_UseDebuggingNewOperator
private: private:
class Pimpl;
friend class DirectoryIterator; friend class DirectoryIterator;
friend class ScopedPointer<Pimpl>; friend class ScopedPointer<Pimpl>;
ScopedPointer<Pimpl> 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; ASTAT astat;
zerostruct (astat);
zeromem (&astat, sizeof (astat)); // (can't use zerostruct here in VC6)
LANA_ENUM enums; LANA_ENUM enums;
zerostruct (enums); zerostruct (enums);


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

@@ -35,15 +35,24 @@
#if ! JUCE_USE_INTRINSICS #if ! JUCE_USE_INTRINSICS
// In newer compilers, the inline versions of these are used (in juce_Atomic.h), but in // 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.. // 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() 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) static juce_wchar* createUninitialised (const size_t numChars)
{ {
StringHolder* const s = reinterpret_cast <StringHolder*> (new char [sizeof (StringHolder) + numChars * sizeof (juce_wchar)]); StringHolder* const s = reinterpret_cast <StringHolder*> (new char [sizeof (StringHolder) + numChars * sizeof (juce_wchar)]);
s->refCount = 0;
s->refCount.value = 0;
s->allocatedNumChars = numChars; s->allocatedNumChars = numChars;
return &(s->text[0]); return &(s->text[0]);
} }
@@ -91,12 +91,12 @@ public:
//============================================================================== //==============================================================================
static void retain (juce_wchar* const text) throw() static void retain (juce_wchar* const text) throw()
{ {
Atomic::increment (bufferFromText (text)->refCount);
++(bufferFromText (text)->refCount);
} }
static inline void release (StringHolder* const b) throw() 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); delete[] reinterpret_cast <char*> (b);
} }
@@ -110,7 +110,7 @@ public:
{ {
StringHolder* const b = bufferFromText (text); StringHolder* const b = bufferFromText (text);
if (b->refCount <= 0)
if (b->refCount.get() <= 0)
return text; return text;
juce_wchar* const newText = createCopy (text, b->allocatedNumChars); juce_wchar* const newText = createCopy (text, b->allocatedNumChars);
@@ -123,7 +123,7 @@ public:
{ {
StringHolder* const b = bufferFromText (text); StringHolder* const b = bufferFromText (text);
if (b->refCount <= 0 && b->allocatedNumChars >= numChars)
if (b->refCount.get() <= 0 && b->allocatedNumChars >= numChars)
return text; return text;
juce_wchar* const newText = createUninitialised (jmax (b->allocatedNumChars, numChars)); juce_wchar* const newText = createUninitialised (jmax (b->allocatedNumChars, numChars));
@@ -145,7 +145,7 @@ public:
} }
//============================================================================== //==============================================================================
int refCount;
Atomic<int> refCount;
size_t allocatedNumChars; size_t allocatedNumChars;
juce_wchar text[1]; juce_wchar text[1];
@@ -214,7 +214,7 @@ String& String::operator= (const String& other) throw()
{ {
juce_wchar* const newText = other.text; juce_wchar* const newText = other.text;
StringHolder::retain (newText); 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; return *this;
} }


Loading…
Cancel
Save