diff --git a/extras/Jucer (experimental)/Builds/VisualStudio2005/The Jucer.vcproj b/extras/Jucer (experimental)/Builds/VisualStudio2005/The Jucer.vcproj
index 64696c98a1..e41cd85336 100644
--- a/extras/Jucer (experimental)/Builds/VisualStudio2005/The Jucer.vcproj
+++ b/extras/Jucer (experimental)/Builds/VisualStudio2005/The Jucer.vcproj
@@ -54,8 +54,6 @@
GenerateDebugInformation="true"
ProgramDatabaseFile=".\Debug\Jucer.pdb"
SubSystem="2"
- RandomizedBaseAddress="1"
- DataExecutionPrevention="0"
TargetMachine="1"/>
@@ -115,8 +113,6 @@
GenerateManifest="false"
OptimizeReferences="2"
EnableCOMDATFolding="2"
- RandomizedBaseAddress="1"
- DataExecutionPrevention="0"
TargetMachine="1"/>
diff --git a/extras/Jucer (experimental)/Builds/VisualStudio2008/The Jucer.vcproj b/extras/Jucer (experimental)/Builds/VisualStudio2008/The Jucer.vcproj
index d4e7960493..483a2fbd48 100644
--- a/extras/Jucer (experimental)/Builds/VisualStudio2008/The Jucer.vcproj
+++ b/extras/Jucer (experimental)/Builds/VisualStudio2008/The Jucer.vcproj
@@ -54,8 +54,6 @@
GenerateDebugInformation="true"
ProgramDatabaseFile=".\Debug\Jucer.pdb"
SubSystem="2"
- RandomizedBaseAddress="1"
- DataExecutionPrevention="0"
TargetMachine="1"/>
@@ -115,8 +113,6 @@
GenerateManifest="false"
OptimizeReferences="2"
EnableCOMDATFolding="2"
- RandomizedBaseAddress="1"
- DataExecutionPrevention="0"
TargetMachine="1"/>
diff --git a/extras/Jucer (experimental)/Source/model/Project/jucer_ProjectExport_MSVC.h b/extras/Jucer (experimental)/Source/model/Project/jucer_ProjectExport_MSVC.h
index 2ebcfa8b1d..a14f86a888 100644
--- a/extras/Jucer (experimental)/Source/model/Project/jucer_ProjectExport_MSVC.h
+++ b/extras/Jucer (experimental)/Source/model/Project/jucer_ProjectExport_MSVC.h
@@ -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());
diff --git a/extras/Jucer (experimental)/Source/model/Project/jucer_ProjectExporter.cpp b/extras/Jucer (experimental)/Source/model/Project/jucer_ProjectExporter.cpp
index f4939d236f..b18cf3556e 100644
--- a/extras/Jucer (experimental)/Source/model/Project/jucer_ProjectExporter.cpp
+++ b/extras/Jucer (experimental)/Source/model/Project/jucer_ProjectExporter.cpp
@@ -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);
diff --git a/extras/Jucer (experimental)/Source/model/Project/jucer_ProjectExporter.h b/extras/Jucer (experimental)/Source/model/Project/jucer_ProjectExporter.h
index 87def6586f..b36174067a 100644
--- a/extras/Jucer (experimental)/Source/model/Project/jucer_ProjectExporter.h
+++ b/extras/Jucer (experimental)/Source/model/Project/jucer_ProjectExporter.h
@@ -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: or normal quotes.
+ const String getIncludePathForFileInJuceFolder (const String& pathFromJuceFolder, const File& targetIncludeFile) const;
+
Array juceWrapperFiles;
protected:
@@ -87,6 +90,7 @@ protected:
String name;
const RelativePath getJucePathFromTargetFolder() const;
+
const String getDefaultBuildsRootFolder() const { return "Builds/"; }
const Array getVSTFilesRequired() const;
diff --git a/extras/Jucer (experimental)/Source/model/Project/jucer_ProjectSaver.h b/extras/Jucer (experimental)/Source/model/Project/jucer_ProjectSaver.h
index 1d70cc7aa9..96332315e2 100644
--- a/extras/Jucer (experimental)/Source/model/Project/jucer_ProjectSaver.h
+++ b/extras/Jucer (experimental)/Source/model/Project/jucer_ProjectSaver.h
@@ -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;
diff --git a/extras/Jucer (experimental)/Source/ui/Editor Base/jucer_EditorCanvas.cpp b/extras/Jucer (experimental)/Source/ui/Editor Base/jucer_EditorCanvas.cpp
index c61f5680e6..a4d04dec0d 100644
--- a/extras/Jucer (experimental)/Source/ui/Editor Base/jucer_EditorCanvas.cpp
+++ b/extras/Jucer (experimental)/Source/ui/Editor Base/jucer_EditorCanvas.cpp
@@ -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 (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 > lasso;
bool mouseDownResult, isDraggingClickedComp;
SelectedItems::ItemType mouseDownCompUID;
+ OwnedArray resizers;
void updateMarkers (bool isX)
{
diff --git a/extras/Jucer (experimental)/Source/ui/Editor Base/jucer_EditorDragOperation.h b/extras/Jucer (experimental)/Source/ui/Editor Base/jucer_EditorDragOperation.h
index 165563307e..1444abda85 100644
--- a/extras/Jucer (experimental)/Source/ui/Editor Base/jucer_EditorDragOperation.h
+++ b/extras/Jucer (experimental)/Source/ui/Editor Base/jucer_EditorDragOperation.h
@@ -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));
diff --git a/extras/Jucer (experimental)/Source/utility/jucer_ColourEditorComponent.h b/extras/Jucer (experimental)/Source/utility/jucer_ColourEditorComponent.h
index 93450dcd95..3d58cdae03 100644
--- a/extras/Jucer (experimental)/Source/utility/jucer_ColourEditorComponent.h
+++ b/extras/Jucer (experimental)/Source/utility/jucer_ColourEditorComponent.h
@@ -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);
}
diff --git a/extras/Jucer (experimental)/Source/utility/jucer_MarkerListBase.h b/extras/Jucer (experimental)/Source/utility/jucer_MarkerListBase.h
index ba322dca45..2bcb184069 100644
--- a/extras/Jucer (experimental)/Source/utility/jucer_MarkerListBase.h
+++ b/extras/Jucer (experimental)/Source/utility/jucer_MarkerListBase.h
@@ -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)
{
diff --git a/extras/amalgamator/Builds/VisualStudio2005/Amalgamator.vcproj b/extras/amalgamator/Builds/VisualStudio2005/Amalgamator.vcproj
index 02303395ea..f8ead20775 100644
--- a/extras/amalgamator/Builds/VisualStudio2005/Amalgamator.vcproj
+++ b/extras/amalgamator/Builds/VisualStudio2005/Amalgamator.vcproj
@@ -54,8 +54,6 @@
GenerateDebugInformation="true"
ProgramDatabaseFile=".\Debug\amalgamator.pdb"
SubSystem="1"
- RandomizedBaseAddress="1"
- DataExecutionPrevention="0"
TargetMachine="1"/>
@@ -115,8 +113,6 @@
GenerateManifest="false"
OptimizeReferences="2"
EnableCOMDATFolding="2"
- RandomizedBaseAddress="1"
- DataExecutionPrevention="0"
TargetMachine="1"/>
diff --git a/extras/amalgamator/Builds/VisualStudio2008/Amalgamator.vcproj b/extras/amalgamator/Builds/VisualStudio2008/Amalgamator.vcproj
index 1b67708a15..1972640dc1 100644
--- a/extras/amalgamator/Builds/VisualStudio2008/Amalgamator.vcproj
+++ b/extras/amalgamator/Builds/VisualStudio2008/Amalgamator.vcproj
@@ -54,8 +54,6 @@
GenerateDebugInformation="true"
ProgramDatabaseFile=".\Debug\amalgamator.pdb"
SubSystem="1"
- RandomizedBaseAddress="1"
- DataExecutionPrevention="0"
TargetMachine="1"/>
@@ -115,8 +113,6 @@
GenerateManifest="false"
OptimizeReferences="2"
EnableCOMDATFolding="2"
- RandomizedBaseAddress="1"
- DataExecutionPrevention="0"
TargetMachine="1"/>
diff --git a/extras/audio plugin host/Builds/VisualStudio2005/Plugin Host.vcproj b/extras/audio plugin host/Builds/VisualStudio2005/Plugin Host.vcproj
index 537dd2553c..b4daf47447 100644
--- a/extras/audio plugin host/Builds/VisualStudio2005/Plugin Host.vcproj
+++ b/extras/audio plugin host/Builds/VisualStudio2005/Plugin Host.vcproj
@@ -54,8 +54,6 @@
GenerateDebugInformation="true"
ProgramDatabaseFile=".\Debug\Plugin Host.pdb"
SubSystem="2"
- RandomizedBaseAddress="1"
- DataExecutionPrevention="0"
TargetMachine="1"/>
@@ -115,8 +113,6 @@
GenerateManifest="false"
OptimizeReferences="2"
EnableCOMDATFolding="2"
- RandomizedBaseAddress="1"
- DataExecutionPrevention="0"
TargetMachine="1"/>
diff --git a/extras/audio plugin host/Builds/VisualStudio2008/Plugin Host.vcproj b/extras/audio plugin host/Builds/VisualStudio2008/Plugin Host.vcproj
index 06d4132847..8a12df5457 100644
--- a/extras/audio plugin host/Builds/VisualStudio2008/Plugin Host.vcproj
+++ b/extras/audio plugin host/Builds/VisualStudio2008/Plugin Host.vcproj
@@ -54,8 +54,6 @@
GenerateDebugInformation="true"
ProgramDatabaseFile=".\Debug\Plugin Host.pdb"
SubSystem="2"
- RandomizedBaseAddress="1"
- DataExecutionPrevention="0"
TargetMachine="1"/>
@@ -115,8 +113,6 @@
GenerateManifest="false"
OptimizeReferences="2"
EnableCOMDATFolding="2"
- RandomizedBaseAddress="1"
- DataExecutionPrevention="0"
TargetMachine="1"/>
diff --git a/extras/audio plugins/demo/Builds/VisualStudio2005/JuceDemoPlugin.vcproj b/extras/audio plugins/demo/Builds/VisualStudio2005/JuceDemoPlugin.vcproj
index a3b74cfca9..b7fa377df7 100644
--- a/extras/audio plugins/demo/Builds/VisualStudio2005/JuceDemoPlugin.vcproj
+++ b/extras/audio plugins/demo/Builds/VisualStudio2005/JuceDemoPlugin.vcproj
@@ -54,8 +54,6 @@
GenerateDebugInformation="true"
ProgramDatabaseFile=".\Debug\JuceDemoPlugin.pdb"
SubSystem="2"
- RandomizedBaseAddress="1"
- DataExecutionPrevention="0"
TargetMachine="1"/>
@@ -115,8 +113,6 @@
GenerateManifest="false"
OptimizeReferences="2"
EnableCOMDATFolding="2"
- RandomizedBaseAddress="1"
- DataExecutionPrevention="0"
TargetMachine="1"/>
diff --git a/extras/audio plugins/demo/Builds/VisualStudio2008/JuceDemoPlugin.vcproj b/extras/audio plugins/demo/Builds/VisualStudio2008/JuceDemoPlugin.vcproj
index 24634d48bc..9f0f0f872a 100644
--- a/extras/audio plugins/demo/Builds/VisualStudio2008/JuceDemoPlugin.vcproj
+++ b/extras/audio plugins/demo/Builds/VisualStudio2008/JuceDemoPlugin.vcproj
@@ -54,8 +54,6 @@
GenerateDebugInformation="true"
ProgramDatabaseFile=".\Debug\JuceDemoPlugin.pdb"
SubSystem="2"
- RandomizedBaseAddress="1"
- DataExecutionPrevention="0"
TargetMachine="1"/>
@@ -115,8 +113,6 @@
GenerateManifest="false"
OptimizeReferences="2"
EnableCOMDATFolding="2"
- RandomizedBaseAddress="1"
- DataExecutionPrevention="0"
TargetMachine="1"/>
diff --git a/extras/binarybuilder/Builds/VisualStudio2005/BinaryBuilder.vcproj b/extras/binarybuilder/Builds/VisualStudio2005/BinaryBuilder.vcproj
index 84b05a8e88..7f86ecfec3 100644
--- a/extras/binarybuilder/Builds/VisualStudio2005/BinaryBuilder.vcproj
+++ b/extras/binarybuilder/Builds/VisualStudio2005/BinaryBuilder.vcproj
@@ -54,8 +54,6 @@
GenerateDebugInformation="true"
ProgramDatabaseFile=".\Debug\BinaryBuilder.pdb"
SubSystem="1"
- RandomizedBaseAddress="1"
- DataExecutionPrevention="0"
TargetMachine="1"/>
@@ -115,8 +113,6 @@
GenerateManifest="false"
OptimizeReferences="2"
EnableCOMDATFolding="2"
- RandomizedBaseAddress="1"
- DataExecutionPrevention="0"
TargetMachine="1"/>
diff --git a/extras/binarybuilder/Builds/VisualStudio2008/BinaryBuilder.vcproj b/extras/binarybuilder/Builds/VisualStudio2008/BinaryBuilder.vcproj
index 857b85baf4..fa7242cee8 100644
--- a/extras/binarybuilder/Builds/VisualStudio2008/BinaryBuilder.vcproj
+++ b/extras/binarybuilder/Builds/VisualStudio2008/BinaryBuilder.vcproj
@@ -54,8 +54,6 @@
GenerateDebugInformation="true"
ProgramDatabaseFile=".\Debug\BinaryBuilder.pdb"
SubSystem="1"
- RandomizedBaseAddress="1"
- DataExecutionPrevention="0"
TargetMachine="1"/>
@@ -115,8 +113,6 @@
GenerateManifest="false"
OptimizeReferences="2"
EnableCOMDATFolding="2"
- RandomizedBaseAddress="1"
- DataExecutionPrevention="0"
TargetMachine="1"/>
diff --git a/extras/example projects/Builds/VisualStudio2005/HelloWorld.vcproj b/extras/example projects/Builds/VisualStudio2005/HelloWorld.vcproj
index fe16774b9d..6b03dd6c54 100644
--- a/extras/example projects/Builds/VisualStudio2005/HelloWorld.vcproj
+++ b/extras/example projects/Builds/VisualStudio2005/HelloWorld.vcproj
@@ -54,8 +54,6 @@
GenerateDebugInformation="true"
ProgramDatabaseFile=".\Debug\HelloWorld.pdb"
SubSystem="2"
- RandomizedBaseAddress="1"
- DataExecutionPrevention="0"
TargetMachine="1"/>
@@ -115,8 +113,6 @@
GenerateManifest="false"
OptimizeReferences="2"
EnableCOMDATFolding="2"
- RandomizedBaseAddress="1"
- DataExecutionPrevention="0"
TargetMachine="1"/>
diff --git a/extras/example projects/Builds/VisualStudio2008/HelloWorld.vcproj b/extras/example projects/Builds/VisualStudio2008/HelloWorld.vcproj
index 96dd24a5c8..7474258d9a 100644
--- a/extras/example projects/Builds/VisualStudio2008/HelloWorld.vcproj
+++ b/extras/example projects/Builds/VisualStudio2008/HelloWorld.vcproj
@@ -54,8 +54,6 @@
GenerateDebugInformation="true"
ProgramDatabaseFile=".\Debug\HelloWorld.pdb"
SubSystem="2"
- RandomizedBaseAddress="1"
- DataExecutionPrevention="0"
TargetMachine="1"/>
@@ -115,8 +113,6 @@
GenerateManifest="false"
OptimizeReferences="2"
EnableCOMDATFolding="2"
- RandomizedBaseAddress="1"
- DataExecutionPrevention="0"
TargetMachine="1"/>
diff --git a/extras/juce demo/Builds/VisualStudio2005/Juce Demo.vcproj b/extras/juce demo/Builds/VisualStudio2005/Juce Demo.vcproj
index 83e203a5df..14e2fab842 100644
--- a/extras/juce demo/Builds/VisualStudio2005/Juce Demo.vcproj
+++ b/extras/juce demo/Builds/VisualStudio2005/Juce Demo.vcproj
@@ -54,8 +54,6 @@
GenerateDebugInformation="true"
ProgramDatabaseFile=".\Debug\JuceDemo.pdb"
SubSystem="2"
- RandomizedBaseAddress="1"
- DataExecutionPrevention="0"
TargetMachine="1"/>
@@ -115,8 +113,6 @@
GenerateManifest="false"
OptimizeReferences="2"
EnableCOMDATFolding="2"
- RandomizedBaseAddress="1"
- DataExecutionPrevention="0"
TargetMachine="1"/>
diff --git a/extras/juce demo/Builds/VisualStudio2008/Juce Demo.vcproj b/extras/juce demo/Builds/VisualStudio2008/Juce Demo.vcproj
index f7f06ff1d2..21144e1332 100644
--- a/extras/juce demo/Builds/VisualStudio2008/Juce Demo.vcproj
+++ b/extras/juce demo/Builds/VisualStudio2008/Juce Demo.vcproj
@@ -54,8 +54,6 @@
GenerateDebugInformation="true"
ProgramDatabaseFile=".\Debug\JuceDemo.pdb"
SubSystem="2"
- RandomizedBaseAddress="1"
- DataExecutionPrevention="0"
TargetMachine="1"/>
@@ -115,8 +113,6 @@
GenerateManifest="false"
OptimizeReferences="2"
EnableCOMDATFolding="2"
- RandomizedBaseAddress="1"
- DataExecutionPrevention="0"
TargetMachine="1"/>
diff --git a/juce_amalgamated.cpp b/juce_amalgamated.cpp
index 77312ba8f8..120df76270 100644
--- a/juce_amalgamated.cpp
+++ b/juce_amalgamated.cpp
@@ -1444,6 +1444,54 @@ const StringArray SystemStats::getMACAddressStrings()
static bool juceInitialisedNonGUI = false;
+#if JUCE_DEBUG
+template
+static void juce_testAtomicType (Type)
+{
+ Atomic 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 (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 (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 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 (Atomic::swapPointers ((void* volatile*) &text, newText)));
+ StringHolder::release (reinterpret_cast *> (&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 (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 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 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 (&variable)); }
-int32 Atomic::incrementAndReturn (int32& variable) { return InterlockedIncrement (reinterpret_cast (&variable)); }
-void Atomic::decrement (int32& variable) { InterlockedDecrement (reinterpret_cast (&variable)); }
-int32 Atomic::decrementAndReturn (int32& variable) { return InterlockedDecrement (reinterpret_cast (&variable)); }
-int32 Atomic::compareAndExchange (int32& destination, int32 newValue, int32 oldValue)
- { return InterlockedCompareExchange (reinterpret_cast (&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);
diff --git a/juce_amalgamated.h b/juce_amalgamated.h
index b76274e3ec..23609b6c6a 100644
--- a/juce_amalgamated.h
+++ b/juce_amalgamated.h
@@ -3120,108 +3120,231 @@ private:
#ifndef __JUCE_ATOMIC_JUCEHEADER__
#define __JUCE_ATOMIC_JUCEHEADER__
-class JUCE_API Atomic
+template
+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 (&variable)); }
- inline int32 Atomic::incrementAndReturn (int32& variable) { return OSAtomicIncrement32 (static_cast (&variable)); }
- inline void Atomic::decrement (int32& variable) { OSAtomicDecrement32 (static_cast (&variable)); }
- inline int32 Atomic::decrementAndReturn (int32& variable) { return OSAtomicDecrement32 (static_cast (&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 (&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 (currentVal), reinterpret_cast (value2),
- const_cast (reinterpret_cast (value1)))) { currentVal = *value1; }
- #else
- while (! OSAtomicCompareAndSwapPtr (currentVal, value2, value1)) { currentVal = *value1; }
- #endif
- return currentVal;
- }
+template
+inline Type Atomic::get() const throw()
+{
+ return const_cast *> (this)->operator+= (0);
+}
-#elif JUCE_LINUX && __INTEL_COMPILER // Linux with Intel compiler...
+template
+inline void Atomic::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
+Type Atomic::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 (_InterlockedExchange64 (const_cast (value1), reinterpret_cast<__int64> (value2)));
- #else
- return reinterpret_cast (_InterlockedExchange (const_cast (value1), reinterpret_cast (value2)));
- #endif
- }
+template
+inline Type Atomic::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
+inline Type Atomic::operator-= (const Type amountToSubtract) throw()
+{
+ return operator+= (sizeof (Type) == 4 ? (Type) (-(int32) amountToSubtract)
+ : (Type) (-(int64) amountToSubtract));
+}
+
+template
+inline Type Atomic::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
+inline Type Atomic::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
+inline bool Atomic::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
+inline Type Atomic::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 (&variable)); }
- inline int32 Atomic::incrementAndReturn (int32& variable) { return _InterlockedIncrement (reinterpret_cast (&variable)); }
- inline void Atomic::decrement (int32& variable) { _InterlockedDecrement (reinterpret_cast (&variable)); }
- inline int32 Atomic::decrementAndReturn (int32& variable) { return _InterlockedDecrement (reinterpret_cast (&variable)); }
- inline int32 Atomic::compareAndExchange (int32& destination, int32 newValue, int32 oldValue)
- { return _InterlockedCompareExchange (reinterpret_cast (&destination), newValue, oldValue); }
-#endif
+template
+inline void Atomic::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 refCount;
};
template
@@ -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;
ScopedPointer pimpl;
@@ -9386,6 +9507,7 @@ public:
private:
class SharedCursorHandle;
+ friend class SharedCursorHandle;
SharedCursorHandle* cursorHandle;
friend class MouseInputSourceInternal;
diff --git a/src/containers/juce_ReferenceCountedObject.h b/src/containers/juce_ReferenceCountedObject.h
index 94408a9e64..bf423b8dc2 100644
--- a/src/containers/juce_ReferenceCountedObject.h
+++ b/src/containers/juce_ReferenceCountedObject.h
@@ -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 refCount;
};
diff --git a/src/core/juce_Atomic.h b/src/core/juce_Atomic.h
index 3c8340cf4d..9ef71b0466 100644
--- a/src/core/juce_Atomic.h
+++ b/src/core/juce_Atomic.h
@@ -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
+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 (&variable)); }
- inline int32 Atomic::incrementAndReturn (int32& variable) { return OSAtomicIncrement32 (static_cast (&variable)); }
- inline void Atomic::decrement (int32& variable) { OSAtomicDecrement32 (static_cast (&variable)); }
- inline int32 Atomic::decrementAndReturn (int32& variable) { return OSAtomicDecrement32 (static_cast (&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 (&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 (currentVal), reinterpret_cast (value2),
- const_cast (reinterpret_cast (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 (_InterlockedExchange64 (const_cast (value1), reinterpret_cast<__int64> (value2)));
- #else
- return reinterpret_cast (_InterlockedExchange (const_cast (value1), reinterpret_cast (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
+inline Type Atomic::get() const throw()
+{
+ return const_cast *> (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
+inline void Atomic::set (const Type newValue) throw()
+{
+ exchange (newValue);
+}
+
+template
+Type Atomic::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
+inline Type Atomic::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
+inline Type Atomic::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
+inline Type Atomic::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
+inline Type Atomic::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
+inline bool Atomic::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
+inline Type Atomic::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 (&variable)); }
- inline int32 Atomic::incrementAndReturn (int32& variable) { return _InterlockedIncrement (reinterpret_cast (&variable)); }
- inline void Atomic::decrement (int32& variable) { _InterlockedDecrement (reinterpret_cast (&variable)); }
- inline int32 Atomic::decrementAndReturn (int32& variable) { return _InterlockedDecrement (reinterpret_cast (&variable)); }
- inline int32 Atomic::compareAndExchange (int32& destination, int32 newValue, int32 oldValue)
- { return _InterlockedCompareExchange (reinterpret_cast (&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
+inline void Atomic::memoryBarrier() throw()
+{
+ #if JUCE_ATOMICS_MAC
+ OSMemoryBarrier();
+ #elif JUCE_ATOMICS_GCC
+ __sync_synchronize();
+ #elif JUCE_ATOMICS_WINDOWS
+ juce_MemoryBarrier();
+ #endif
+}
+
#endif // __JUCE_ATOMIC_JUCEHEADER__
diff --git a/src/core/juce_SystemStats.cpp b/src/core/juce_SystemStats.cpp
index f03088532c..bae4a85779 100644
--- a/src/core/juce_SystemStats.cpp
+++ b/src/core/juce_SystemStats.cpp
@@ -70,6 +70,54 @@ const StringArray SystemStats::getMACAddressStrings()
//==============================================================================
static bool juceInitialisedNonGUI = false;
+#if JUCE_DEBUG
+template
+static void juce_testAtomicType (Type)
+{
+ Atomic 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);
diff --git a/src/events/juce_Timer.cpp b/src/events/juce_Timer.cpp
index 7da04b1544..ee4e63785b 100644
--- a/src/events/juce_Timer.cpp
+++ b/src/events/juce_Timer.cpp
@@ -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 (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 callbackNeeded;
//==============================================================================
void addTimer (Timer* const t) throw()
diff --git a/src/gui/components/filebrowser/juce_FileBrowserComponent.cpp b/src/gui/components/filebrowser/juce_FileBrowserComponent.cpp
index abf1d46975..623a97401a 100644
--- a/src/gui/components/filebrowser/juce_FileBrowserComponent.cpp
+++ b/src/gui/components/filebrowser/juce_FileBrowserComponent.cpp
@@ -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
{
diff --git a/src/gui/components/filebrowser/juce_FileChooser.cpp b/src/gui/components/filebrowser/juce_FileChooser.cpp
index 411fd3cee2..3ebb54cc07 100644
--- a/src/gui/components/filebrowser/juce_FileChooser.cpp
+++ b/src/gui/components/filebrowser/juce_FileChooser.cpp
@@ -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;
diff --git a/src/gui/components/mouse/juce_MouseCursor.cpp b/src/gui/components/mouse/juce_MouseCursor.cpp
index 3354eaf085..15234134ae 100644
--- a/src/gui/components/mouse/juce_MouseCursor.cpp
+++ b/src/gui/components/mouse/juce_MouseCursor.cpp
@@ -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 refCount;
const MouseCursor::StandardCursorType standardType;
const bool isStandard;
diff --git a/src/gui/components/mouse/juce_MouseCursor.h b/src/gui/components/mouse/juce_MouseCursor.h
index c36ea62c97..89dd45eb8a 100644
--- a/src/gui/components/mouse/juce_MouseCursor.h
+++ b/src/gui/components/mouse/juce_MouseCursor.h
@@ -145,6 +145,7 @@ public:
private:
class SharedCursorHandle;
+ friend class SharedCursorHandle;
SharedCursorHandle* cursorHandle;
friend class MouseInputSourceInternal;
diff --git a/src/io/files/juce_DirectoryIterator.h b/src/io/files/juce_DirectoryIterator.h
index fcea05271e..75f57a7db5 100644
--- a/src/io/files/juce_DirectoryIterator.h
+++ b/src/io/files/juce_DirectoryIterator.h
@@ -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;
ScopedPointer pimpl;
diff --git a/src/native/windows/juce_win32_Network.cpp b/src/native/windows/juce_win32_Network.cpp
index a0ecd89b3f..60733276ab 100644
--- a/src/native/windows/juce_win32_Network.cpp
+++ b/src/native/windows/juce_win32_Network.cpp
@@ -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);
diff --git a/src/native/windows/juce_win32_Threads.cpp b/src/native/windows/juce_win32_Threads.cpp
index d69373724e..ed1fa17a71 100644
--- a/src/native/windows/juce_win32_Threads.cpp
+++ b/src/native/windows/juce_win32_Threads.cpp
@@ -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 (&variable)); }
-int32 Atomic::incrementAndReturn (int32& variable) { return InterlockedIncrement (reinterpret_cast (&variable)); }
-void Atomic::decrement (int32& variable) { InterlockedDecrement (reinterpret_cast (&variable)); }
-int32 Atomic::decrementAndReturn (int32& variable) { return InterlockedDecrement (reinterpret_cast (&variable)); }
-int32 Atomic::compareAndExchange (int32& destination, int32 newValue, int32 oldValue)
- { return InterlockedCompareExchange (reinterpret_cast (&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()
diff --git a/src/text/juce_String.cpp b/src/text/juce_String.cpp
index 3e20c49e76..ce7c767f40 100644
--- a/src/text/juce_String.cpp
+++ b/src/text/juce_String.cpp
@@ -63,7 +63,7 @@ public:
static juce_wchar* createUninitialised (const size_t numChars)
{
StringHolder* const s = reinterpret_cast (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 (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 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 (Atomic::swapPointers ((void* volatile*) &text, newText)));
+ StringHolder::release (reinterpret_cast *> (&text)->exchange (newText));
return *this;
}