diff --git a/CMakeLists.txt b/CMakeLists.txt
index f6729155..fc2d2630 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -99,7 +99,7 @@ find_package(ZLIB REQUIRED)
find_package(Threads REQUIRED)
if(SIMGEAR_HEADLESS)
- message(STATUS "headlesss mode")
+ message(STATUS "headless mode")
set(NO_OPENSCENEGRAPH_INTERFACE 1)
else()
find_package(OpenGL REQUIRED)
@@ -179,6 +179,13 @@ check_cxx_source_compiles(
if(CMAKE_COMPILER_IS_GNUCXX)
set(WARNING_FLAGS -Wall)
+
+ # certain GCC versions don't provide the atomic builds, and hence
+ # require is to provide them in SGAtomic.cxx
+ set(CMAKE_REQUIRED_INCLUDES ${CMAKE_INCLUDE_PATH})
+ check_cxx_source_compiles(
+ "int main() { unsigned mValue; return __sync_add_and_fetch(&mValue, 1); }"
+ GCC_ATOMIC_BUILTINS_FOUND)
endif(CMAKE_COMPILER_IS_GNUCXX)
if(WIN32)
diff --git a/projects/VC90/SimGear.vcproj b/projects/VC90/SimGear.vcproj
index 077af7ae..f3d50894 100644
--- a/projects/VC90/SimGear.vcproj
+++ b/projects/VC90/SimGear.vcproj
@@ -671,14 +671,6 @@
RelativePath="..\..\simgear\misc\sg_path.hxx"
>
-
-
-
-
@@ -1499,6 +1491,14 @@
+
+
+
+
diff --git a/simgear/hla/CMakeLists.txt b/simgear/hla/CMakeLists.txt
index a822fc24..f9c35c5e 100644
--- a/simgear/hla/CMakeLists.txt
+++ b/simgear/hla/CMakeLists.txt
@@ -7,6 +7,7 @@ set(HLA_HEADERS
HLABasicDataElement.hxx
HLABasicDataType.hxx
HLADataElement.hxx
+ HLADataElementVisitor.hxx
HLADataType.hxx
HLADataTypeVisitor.hxx
HLAEnumeratedDataElement.hxx
diff --git a/simgear/hla/HLAArrayDataElement.cxx b/simgear/hla/HLAArrayDataElement.cxx
index e2a7fc73..01e40243 100644
--- a/simgear/hla/HLAArrayDataElement.cxx
+++ b/simgear/hla/HLAArrayDataElement.cxx
@@ -19,6 +19,8 @@
#include
+#include "HLADataElementVisitor.hxx"
+
namespace simgear {
HLAAbstractArrayDataElement::HLAAbstractArrayDataElement(const HLAArrayDataType* dataType) :
@@ -30,6 +32,18 @@ HLAAbstractArrayDataElement::~HLAAbstractArrayDataElement()
{
}
+void
+HLAAbstractArrayDataElement::accept(HLADataElementVisitor& visitor)
+{
+ visitor.apply(*this);
+}
+
+void
+HLAAbstractArrayDataElement::accept(HLAConstDataElementVisitor& visitor) const
+{
+ visitor.apply(*this);
+}
+
bool
HLAAbstractArrayDataElement::decode(HLADecodeStream& stream)
{
diff --git a/simgear/hla/HLAArrayDataElement.hxx b/simgear/hla/HLAArrayDataElement.hxx
index b7c9c1e3..c236c4e4 100644
--- a/simgear/hla/HLAArrayDataElement.hxx
+++ b/simgear/hla/HLAArrayDataElement.hxx
@@ -33,6 +33,9 @@ public:
HLAAbstractArrayDataElement(const HLAArrayDataType* dataType);
virtual ~HLAAbstractArrayDataElement();
+ virtual void accept(HLADataElementVisitor& visitor);
+ virtual void accept(HLAConstDataElementVisitor& visitor) const;
+
virtual bool decode(HLADecodeStream& stream);
virtual bool encode(HLAEncodeStream& stream) const;
diff --git a/simgear/hla/HLABasicDataElement.cxx b/simgear/hla/HLABasicDataElement.cxx
index 69401104..f68cad36 100644
--- a/simgear/hla/HLABasicDataElement.cxx
+++ b/simgear/hla/HLABasicDataElement.cxx
@@ -17,6 +17,7 @@
#include "HLABasicDataElement.hxx"
+#include "HLADataElementVisitor.hxx"
#include "HLADataTypeVisitor.hxx"
namespace simgear {
@@ -30,6 +31,18 @@ HLABasicDataElement::~HLABasicDataElement()
{
}
+void
+HLABasicDataElement::accept(HLADataElementVisitor& visitor)
+{
+ visitor.apply(*this);
+}
+
+void
+HLABasicDataElement::accept(HLAConstDataElementVisitor& visitor) const
+{
+ visitor.apply(*this);
+}
+
const HLABasicDataType*
HLABasicDataElement::getDataType() const
{
diff --git a/simgear/hla/HLABasicDataElement.hxx b/simgear/hla/HLABasicDataElement.hxx
index e38499df..70c275be 100644
--- a/simgear/hla/HLABasicDataElement.hxx
+++ b/simgear/hla/HLABasicDataElement.hxx
@@ -28,6 +28,12 @@ public:
HLABasicDataElement(const HLABasicDataType* dataType);
virtual ~HLABasicDataElement();
+ virtual void accept(HLADataElementVisitor& visitor);
+ virtual void accept(HLAConstDataElementVisitor& visitor) const;
+
+ virtual bool encode(HLAEncodeStream& stream) const = 0;
+ virtual bool decode(HLADecodeStream& stream) = 0;
+
virtual const HLABasicDataType* getDataType() const;
virtual bool setDataType(const HLADataType* dataType);
void setDataType(const HLABasicDataType* dataType);
@@ -41,6 +47,7 @@ class HLAAbstract##type##DataElement : public HLABasicDataElement { \
public: \
HLAAbstract##type##DataElement(const HLABasicDataType* dataType = 0); \
virtual ~HLAAbstract##type##DataElement(); \
+ \
virtual bool encode(HLAEncodeStream& stream) const; \
virtual bool decode(HLADecodeStream& stream); \
\
diff --git a/simgear/hla/HLADataElement.cxx b/simgear/hla/HLADataElement.cxx
index ae981128..8245bddd 100644
--- a/simgear/hla/HLADataElement.cxx
+++ b/simgear/hla/HLADataElement.cxx
@@ -19,6 +19,8 @@
#include
+#include "HLADataElementVisitor.hxx"
+
namespace simgear {
HLADataElement::PathElement::Data::~Data()
@@ -129,6 +131,18 @@ HLADataElement::~HLADataElement()
{
}
+void
+HLADataElement::accept(HLADataElementVisitor& visitor)
+{
+ visitor.apply(*this);
+}
+
+void
+HLADataElement::accept(HLAConstDataElementVisitor& visitor) const
+{
+ visitor.apply(*this);
+}
+
std::string
HLADataElement::toString(const Path& path)
{
diff --git a/simgear/hla/HLADataElement.hxx b/simgear/hla/HLADataElement.hxx
index 284422b8..e3d52933 100644
--- a/simgear/hla/HLADataElement.hxx
+++ b/simgear/hla/HLADataElement.hxx
@@ -1,4 +1,4 @@
-// Copyright (C) 2009 - 2010 Mathias Froehlich - Mathias.Froehlich@web.de
+// Copyright (C) 2009 - 2011 Mathias Froehlich - Mathias.Froehlich@web.de
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
@@ -30,10 +30,16 @@ class SGTimeStamp;
namespace simgear {
+class HLADataElementVisitor;
+class HLAConstDataElementVisitor;
+
class HLADataElement : public SGReferenced {
public:
virtual ~HLADataElement();
+ virtual void accept(HLADataElementVisitor& visitor) = 0;
+ virtual void accept(HLAConstDataElementVisitor& visitor) const = 0;
+
virtual bool encode(HLAEncodeStream& stream) const = 0;
virtual bool decode(HLADecodeStream& stream) = 0;
diff --git a/simgear/hla/HLADataElementVisitor.hxx b/simgear/hla/HLADataElementVisitor.hxx
new file mode 100644
index 00000000..938f7302
--- /dev/null
+++ b/simgear/hla/HLADataElementVisitor.hxx
@@ -0,0 +1,57 @@
+// Copyright (C) 2009 - 2011 Mathias Froehlich - Mathias.Froehlich@web.de
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+
+#ifndef HLADataElementVisitor_hxx
+#define HLADataElementVisitor_hxx
+
+namespace simgear {
+
+class HLABasicDataElement;
+class HLAAbstractEnumeratedDataElement;
+class HLAAbstractFixedRecordDataElement;
+class HLAAbstractArrayDataElement;
+class HLAAbstractVariantDataElement;
+
+class HLADataElementVisitor {
+public:
+ virtual ~HLADataElementVisitor() {}
+
+ virtual void apply(HLADataElement&);
+
+ virtual void apply(HLABasicDataElement&);
+ virtual void apply(HLAAbstractEnumeratedDataElement&);
+ virtual void apply(HLAAbstractArrayDataElement&);
+ virtual void apply(HLAAbstractFixedRecordDataElement&);
+ virtual void apply(HLAAbstractVariantDataElement&);
+};
+
+class HLAConstDataElementVisitor {
+public:
+ virtual ~HLAConstDataElementVisitor() {}
+
+ virtual void apply(const HLADataElement&);
+
+ virtual void apply(const HLABasicDataElement&);
+ virtual void apply(const HLAAbstractEnumeratedDataElement&);
+ virtual void apply(const HLAAbstractArrayDataElement&);
+ virtual void apply(const HLAAbstractFixedRecordDataElement&);
+ virtual void apply(const HLAAbstractVariantDataElement&);
+};
+
+}
+
+#endif
diff --git a/simgear/hla/HLAEnumeratedDataElement.cxx b/simgear/hla/HLAEnumeratedDataElement.cxx
index a09e0dec..d5af6d41 100644
--- a/simgear/hla/HLAEnumeratedDataElement.cxx
+++ b/simgear/hla/HLAEnumeratedDataElement.cxx
@@ -19,6 +19,8 @@
#include
+#include "HLADataElementVisitor.hxx"
+
namespace simgear {
HLAAbstractEnumeratedDataElement::HLAAbstractEnumeratedDataElement(const HLAEnumeratedDataType* dataType) :
@@ -30,6 +32,18 @@ HLAAbstractEnumeratedDataElement::~HLAAbstractEnumeratedDataElement()
{
}
+void
+HLAAbstractEnumeratedDataElement::accept(HLADataElementVisitor& visitor)
+{
+ visitor.apply(*this);
+}
+
+void
+HLAAbstractEnumeratedDataElement::accept(HLAConstDataElementVisitor& visitor) const
+{
+ visitor.apply(*this);
+}
+
bool
HLAAbstractEnumeratedDataElement::decode(HLADecodeStream& stream)
{
diff --git a/simgear/hla/HLAEnumeratedDataElement.hxx b/simgear/hla/HLAEnumeratedDataElement.hxx
index f7dfbd38..10d8f105 100644
--- a/simgear/hla/HLAEnumeratedDataElement.hxx
+++ b/simgear/hla/HLAEnumeratedDataElement.hxx
@@ -28,6 +28,9 @@ public:
HLAAbstractEnumeratedDataElement(const HLAEnumeratedDataType* dataType);
virtual ~HLAAbstractEnumeratedDataElement();
+ virtual void accept(HLADataElementVisitor& visitor);
+ virtual void accept(HLAConstDataElementVisitor& visitor) const;
+
virtual bool decode(HLADecodeStream& stream);
virtual bool encode(HLAEncodeStream& stream) const;
diff --git a/simgear/hla/HLAFixedRecordDataElement.cxx b/simgear/hla/HLAFixedRecordDataElement.cxx
index d0980b95..c4c0c8b2 100644
--- a/simgear/hla/HLAFixedRecordDataElement.cxx
+++ b/simgear/hla/HLAFixedRecordDataElement.cxx
@@ -20,6 +20,8 @@
#include
#include
#include
+
+#include "HLADataElementVisitor.hxx"
#include "HLADataTypeVisitor.hxx"
namespace simgear {
@@ -33,6 +35,18 @@ HLAAbstractFixedRecordDataElement::~HLAAbstractFixedRecordDataElement()
{
}
+void
+HLAAbstractFixedRecordDataElement::accept(HLADataElementVisitor& visitor)
+{
+ visitor.apply(*this);
+}
+
+void
+HLAAbstractFixedRecordDataElement::accept(HLAConstDataElementVisitor& visitor) const
+{
+ visitor.apply(*this);
+}
+
bool
HLAAbstractFixedRecordDataElement::decode(HLADecodeStream& stream)
{
diff --git a/simgear/hla/HLAFixedRecordDataElement.hxx b/simgear/hla/HLAFixedRecordDataElement.hxx
index d99719d0..ca8ed997 100644
--- a/simgear/hla/HLAFixedRecordDataElement.hxx
+++ b/simgear/hla/HLAFixedRecordDataElement.hxx
@@ -30,6 +30,9 @@ public:
HLAAbstractFixedRecordDataElement(const HLAFixedRecordDataType* dataType);
virtual ~HLAAbstractFixedRecordDataElement();
+ virtual void accept(HLADataElementVisitor& visitor);
+ virtual void accept(HLAConstDataElementVisitor& visitor) const;
+
virtual bool decode(HLADecodeStream& stream);
virtual bool encode(HLAEncodeStream& stream) const;
diff --git a/simgear/hla/HLAPropertyDataElement.cxx b/simgear/hla/HLAPropertyDataElement.cxx
index e8a931ee..af19ff4d 100644
--- a/simgear/hla/HLAPropertyDataElement.cxx
+++ b/simgear/hla/HLAPropertyDataElement.cxx
@@ -18,6 +18,8 @@
#include "HLAPropertyDataElement.hxx"
#include "HLAArrayDataElement.hxx"
+#include "HLABasicDataElement.hxx"
+#include "HLADataElementVisitor.hxx"
#include "HLADataTypeVisitor.hxx"
#include "HLAFixedRecordDataElement.hxx"
#include "HLAVariantDataElement.hxx"
@@ -152,7 +154,7 @@ protected:
const SGPropertyNode& _propertyNode;
};
-class HLAPropertyDataElement::ScalarDataElement : public HLADataElement {
+class HLAPropertyDataElement::ScalarDataElement : public HLABasicDataElement {
public:
ScalarDataElement(const HLABasicDataType* dataType, SGPropertyNode* propertyNode);
virtual ~ScalarDataElement();
@@ -160,16 +162,12 @@ public:
virtual bool encode(HLAEncodeStream& stream) const;
virtual bool decode(HLADecodeStream& stream);
- virtual const HLADataType* getDataType() const;
- virtual bool setDataType(const HLADataType* dataType);
-
private:
- SGSharedPtr _dataType;
SGSharedPtr _propertyNode;
};
HLAPropertyDataElement::ScalarDataElement::ScalarDataElement(const HLABasicDataType* dataType, SGPropertyNode* propertyNode) :
- _dataType(dataType),
+ HLABasicDataElement(dataType),
_propertyNode(propertyNode)
{
}
@@ -194,162 +192,64 @@ HLAPropertyDataElement::ScalarDataElement::decode(HLADecodeStream& stream)
return true;
}
-const HLADataType*
-HLAPropertyDataElement::ScalarDataElement::getDataType() const
-{
- return _dataType.get();
-}
-
-bool
-HLAPropertyDataElement::ScalarDataElement::setDataType(const HLADataType* dataType)
-{
- if (!dataType)
- return false;
- const HLABasicDataType* basicDataType = dataType->toBasicDataType();
- if (!basicDataType)
- return false;
- _dataType = basicDataType;
- return true;
-}
-
-
-class HLAPropertyDataElement::StringDecodeVisitor : public HLADataTypeDecodeVisitor {
-public:
- StringDecodeVisitor(HLADecodeStream& stream, SGPropertyNode& propertyNode) :
- HLADataTypeDecodeVisitor(stream),
- _propertyNode(propertyNode)
- { }
-
- virtual void apply(const HLAFixedArrayDataType& dataType)
- {
- unsigned numElements = dataType.getNumElements();
- std::string value;
- value.reserve(numElements);
- for (unsigned i = 0; i < numElements; ++i) {
- HLATemplateDecodeVisitor visitor(_stream);
- dataType.getElementDataType()->accept(visitor);
- value.push_back(visitor.getValue());
- }
- _propertyNode.setStringValue(value);
- }
- virtual void apply(const HLAVariableArrayDataType& dataType)
- {
- HLATemplateDecodeVisitor numElementsVisitor(_stream);
- dataType.getSizeDataType()->accept(numElementsVisitor);
- std::string::size_type numElements = numElementsVisitor.getValue();
- std::string value;
- value.reserve(numElements);
- for (std::string::size_type i = 0; i < numElements; ++i) {
- HLATemplateDecodeVisitor visitor(_stream);
- dataType.getElementDataType()->accept(visitor);
- value.push_back(visitor.getValue());
- }
- _propertyNode.setStringValue(value);
- }
-
-protected:
- SGPropertyNode& _propertyNode;
-};
-
-class HLAPropertyDataElement::StringEncodeVisitor : public HLADataTypeEncodeVisitor {
-public:
- StringEncodeVisitor(HLAEncodeStream& stream, const SGPropertyNode& propertyNode) :
- HLADataTypeEncodeVisitor(stream),
- _propertyNode(propertyNode)
- { }
-
- virtual void apply(const HLAFixedArrayDataType& dataType)
- {
- unsigned numElements = dataType.getNumElements();
- std::string value = _propertyNode.getStringValue();
- for (unsigned i = 0; i < numElements; ++i) {
- if (i < value.size()) {
- HLATemplateEncodeVisitor visitor(_stream, value[i]);
- dataType.getElementDataType()->accept(visitor);
- } else {
- HLADataTypeEncodeVisitor visitor(_stream);
- dataType.getElementDataType()->accept(visitor);
- }
- }
- }
-
- virtual void apply(const HLAVariableArrayDataType& dataType)
- {
- std::string value = _propertyNode.getStringValue();
- HLATemplateEncodeVisitor numElementsVisitor(_stream, value.size());
- dataType.getSizeDataType()->accept(numElementsVisitor);
- for (unsigned i = 0; i < value.size(); ++i) {
- HLATemplateEncodeVisitor visitor(_stream, value[i]);
- dataType.getElementDataType()->accept(visitor);
- }
- }
-
-protected:
- const SGPropertyNode& _propertyNode;
-};
-
-class HLAPropertyDataElement::StringDataElement : public HLADataElement {
+class HLAPropertyDataElement::StringDataElement : public HLAStringDataElement {
public:
StringDataElement(const HLAArrayDataType* dataType, SGPropertyNode* propertyNode);
virtual ~StringDataElement();
- virtual bool encode(HLAEncodeStream& stream) const;
- virtual bool decode(HLADecodeStream& stream);
+ virtual bool decodeElement(HLADecodeStream& stream, unsigned i);
- virtual const HLADataType* getDataType() const;
- virtual bool setDataType(const HLADataType* dataType);
+ class Listener : public SGPropertyChangeListener {
+ public:
+ Listener(StringDataElement* stringDataElement);
+ virtual ~Listener();
+ virtual void valueChanged (SGPropertyNode * node);
+ private:
+ StringDataElement* _stringDataElement;
+ };
private:
- SGSharedPtr _dataType;
SGSharedPtr _propertyNode;
+ Listener* _listener;
};
-HLAPropertyDataElement::StringDataElement::StringDataElement(const HLAArrayDataType* dataType, SGPropertyNode* propertyNode) :
- _dataType(dataType),
- _propertyNode(propertyNode)
+HLAPropertyDataElement::StringDataElement::Listener::Listener(StringDataElement* stringDataElement) :
+ _stringDataElement(stringDataElement)
{
}
+HLAPropertyDataElement::StringDataElement::Listener::~Listener()
+{
+}
+
+void
+HLAPropertyDataElement::StringDataElement::Listener::valueChanged (SGPropertyNode * node)
+{
+ _stringDataElement->setValue(node->getStringValue());
+}
+
+HLAPropertyDataElement::StringDataElement::StringDataElement(const HLAArrayDataType* dataType, SGPropertyNode* propertyNode) :
+ HLAStringDataElement(dataType),
+ _propertyNode(propertyNode),
+ _listener(new Listener(this))
+{
+ _propertyNode->addChangeListener(_listener, true);
+}
+
HLAPropertyDataElement::StringDataElement::~StringDataElement()
{
+ _propertyNode->removeChangeListener(_listener);
+ delete _listener;
+ _listener = 0;
}
bool
-HLAPropertyDataElement::StringDataElement::encode(HLAEncodeStream& stream) const
+HLAPropertyDataElement::StringDataElement::decodeElement(HLADecodeStream& stream, unsigned i)
{
- StringEncodeVisitor visitor(stream, *_propertyNode);
- _dataType->accept(visitor);
- return true;
-}
-
-bool
-HLAPropertyDataElement::StringDataElement::decode(HLADecodeStream& stream)
-{
- StringDecodeVisitor visitor(stream, *_propertyNode);
- _dataType->accept(visitor);
- return true;
-}
-
-const HLADataType*
-HLAPropertyDataElement::StringDataElement::getDataType() const
-{
- return _dataType.get();
-}
-
-bool
-HLAPropertyDataElement::StringDataElement::setDataType(const HLADataType* dataType)
-{
- if (!dataType)
+ if (!HLAStringDataElement::decodeElement(stream, i))
return false;
- const HLAArrayDataType* arrayDataType = dataType->toArrayDataType();
- if (!arrayDataType)
- return false;
- const HLADataType* elementDataType = arrayDataType->getElementDataType();
- if (!elementDataType)
- return false;
- if (!elementDataType->toBasicDataType())
- return false;
- _dataType = arrayDataType;
+ if (i + 1 == getValue().size())
+ _propertyNode->setStringValue(getValue());
return true;
}
@@ -534,6 +434,38 @@ HLAPropertyDataElement::~HLAPropertyDataElement()
{
}
+void
+HLAPropertyDataElement::accept(HLADataElementVisitor& visitor)
+{
+ if (_dataElement.valid()) {
+ visitor.apply(*_dataElement);
+ } else {
+ // We cant do anything if the data type is not valid
+ if (_dataType.valid()) {
+ HLADataElementFactoryVisitor factoryVisitor;
+ _dataType->accept(factoryVisitor);
+ _dataElement = factoryVisitor.getDataElement();
+ if (_dataElement.valid()) {
+ visitor.apply(*_dataElement);
+ } else {
+ HLADataElement::accept(visitor);
+ }
+ } else {
+ HLADataElement::accept(visitor);
+ }
+ }
+}
+
+void
+HLAPropertyDataElement::accept(HLAConstDataElementVisitor& visitor) const
+{
+ if (_dataElement.valid()) {
+ visitor.apply(*_dataElement);
+ } else {
+ HLADataElement::accept(visitor);
+ }
+}
+
bool
HLAPropertyDataElement::encode(HLAEncodeStream& stream) const
{
diff --git a/simgear/hla/HLAPropertyDataElement.hxx b/simgear/hla/HLAPropertyDataElement.hxx
index 4354a1d9..da21b2ab 100644
--- a/simgear/hla/HLAPropertyDataElement.hxx
+++ b/simgear/hla/HLAPropertyDataElement.hxx
@@ -31,6 +31,9 @@ public:
HLAPropertyDataElement(const HLADataType* dataType);
virtual ~HLAPropertyDataElement();
+ virtual void accept(HLADataElementVisitor& visitor);
+ virtual void accept(HLAConstDataElementVisitor& visitor) const;
+
virtual bool encode(HLAEncodeStream& stream) const;
virtual bool decode(HLADecodeStream& stream);
diff --git a/simgear/hla/HLAVariantDataElement.cxx b/simgear/hla/HLAVariantDataElement.cxx
index 98c22f78..2eca369a 100644
--- a/simgear/hla/HLAVariantDataElement.cxx
+++ b/simgear/hla/HLAVariantDataElement.cxx
@@ -19,6 +19,8 @@
#include
+#include "HLADataElementVisitor.hxx"
+
namespace simgear {
HLAAbstractVariantDataElement::HLAAbstractVariantDataElement(const HLAVariantDataType* dataType) :
@@ -30,6 +32,18 @@ HLAAbstractVariantDataElement::~HLAAbstractVariantDataElement()
{
}
+void
+HLAAbstractVariantDataElement::accept(HLADataElementVisitor& visitor)
+{
+ visitor.apply(*this);
+}
+
+void
+HLAAbstractVariantDataElement::accept(HLAConstDataElementVisitor& visitor) const
+{
+ visitor.apply(*this);
+}
+
bool
HLAAbstractVariantDataElement::decode(HLADecodeStream& stream)
{
diff --git a/simgear/hla/HLAVariantDataElement.hxx b/simgear/hla/HLAVariantDataElement.hxx
index b3ced7ca..0b14ef45 100644
--- a/simgear/hla/HLAVariantDataElement.hxx
+++ b/simgear/hla/HLAVariantDataElement.hxx
@@ -30,6 +30,9 @@ public:
HLAAbstractVariantDataElement(const HLAVariantDataType* dataType);
virtual ~HLAAbstractVariantDataElement();
+ virtual void accept(HLADataElementVisitor& visitor);
+ virtual void accept(HLAConstDataElementVisitor& visitor) const;
+
virtual bool decode(HLADecodeStream& stream);
virtual bool encode(HLAEncodeStream& stream) const;
diff --git a/simgear/hla/Makefile.am b/simgear/hla/Makefile.am
index e214e6a0..3bb38603 100644
--- a/simgear/hla/Makefile.am
+++ b/simgear/hla/Makefile.am
@@ -11,6 +11,7 @@ libsghla_a_HEADERS = \
HLABasicDataElement.hxx \
HLABasicDataType.hxx \
HLADataElement.hxx \
+ HLADataElementVisitor.hxx \
HLADataType.hxx \
HLADataTypeVisitor.hxx \
HLAEnumeratedDataElement.hxx \
diff --git a/simgear/io/HTTPRequest.cxx b/simgear/io/HTTPRequest.cxx
index 4b7a11bf..38651a3e 100644
--- a/simgear/io/HTTPRequest.cxx
+++ b/simgear/io/HTTPRequest.cxx
@@ -66,7 +66,7 @@ void Request::responseStart(const string& r)
void Request::responseHeader(const string& key, const string& value)
{
if (key == "connection") {
- _willClose = (value.find("close") >= 0);
+ _willClose = (value.find("close") != string::npos);
}
_responseHeaders[key] = value;
diff --git a/simgear/io/httpget.cxx b/simgear/io/httpget.cxx
index e10a29b4..b4934b8d 100644
--- a/simgear/io/httpget.cxx
+++ b/simgear/io/httpget.cxx
@@ -12,7 +12,7 @@
#include
#include
#include
-#include
+#include
using namespace simgear;
using std::cout;
@@ -156,7 +156,7 @@ int main(int argc, char* argv[])
while (!req->complete()) {
cl.update();
- sleepForMSec(100);
+ SGTimeStamp::sleepForMSec(100);
}
if (req->responseCode() != 200) {
diff --git a/simgear/io/iochannel.cxx b/simgear/io/iochannel.cxx
index 9b88c6d5..468f666b 100644
--- a/simgear/io/iochannel.cxx
+++ b/simgear/io/iochannel.cxx
@@ -73,6 +73,6 @@ bool SGIOChannel::close() {
// dummy eof routine
-bool SGIOChannel::eof() {
+bool SGIOChannel::eof() const {
return false;
}
diff --git a/simgear/io/iochannel.hxx b/simgear/io/iochannel.hxx
index ea1b0077..f5266b03 100644
--- a/simgear/io/iochannel.hxx
+++ b/simgear/io/iochannel.hxx
@@ -149,7 +149,7 @@ public:
* false.
* @return result of eof check
*/
- virtual bool eof();
+ virtual bool eof() const;
inline void set_type( SGChannelType t ) { type = t; }
inline SGChannelType get_type() const { return type; }
diff --git a/simgear/io/sg_file.hxx b/simgear/io/sg_file.hxx
index 7e5854c1..7d842863 100644
--- a/simgear/io/sg_file.hxx
+++ b/simgear/io/sg_file.hxx
@@ -88,7 +88,7 @@ public:
inline std::string get_file_name() const { return file_name; }
/** @return true of eof conditions exists */
- inline bool eof() const { return eof_flag; };
+ virtual bool eof() const { return eof_flag; };
};
diff --git a/simgear/io/test_HTTP.cxx b/simgear/io/test_HTTP.cxx
index 048cbb41..988f8bba 100644
--- a/simgear/io/test_HTTP.cxx
+++ b/simgear/io/test_HTTP.cxx
@@ -12,7 +12,6 @@
#include
#include
#include
-#include
using std::cout;
using std::cerr;
@@ -321,7 +320,7 @@ void waitForComplete(HTTP::Client* cl, TestRequest* tr)
if (tr->complete) {
return;
}
- sleepForMSec(1);
+ SGTimeStamp::sleepForMSec(1);
}
cerr << "timed out" << endl;
@@ -335,7 +334,7 @@ void waitForFailed(HTTP::Client* cl, TestRequest* tr)
if (tr->failed) {
return;
}
- sleepForMSec(1);
+ SGTimeStamp::sleepForMSec(1);
}
cerr << "timed out waiting for failure" << endl;
diff --git a/simgear/math/SGGeod.cxx b/simgear/math/SGGeod.cxx
index 15468707..20fa1938 100644
--- a/simgear/math/SGGeod.cxx
+++ b/simgear/math/SGGeod.cxx
@@ -15,6 +15,10 @@
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
+#ifdef HAVE_CONFIG_H
+# include
+#endif
+
#include "SGMath.hxx"
#ifndef NO_OPENSCENEGRAPH_INTERFACE
diff --git a/simgear/math/project.cxx b/simgear/math/project.cxx
index f1c2b143..c6a4ef73 100644
--- a/simgear/math/project.cxx
+++ b/simgear/math/project.cxx
@@ -15,8 +15,14 @@
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
+#ifdef HAVE_CONFIG_H
+# include
+#endif
+
#include "project.hxx"
+#ifndef NO_OPENSCENEGRAPH_INTERFACE
+
#include
#include
@@ -41,3 +47,6 @@ GLint project(GLdouble objX, GLdouble objY, GLdouble objZ,
}
}
+
+#endif // of NO_OPENSCENEGRAPH_INTERFACE
+
diff --git a/simgear/math/project.hxx b/simgear/math/project.hxx
index 40353a2d..07a97d79 100644
--- a/simgear/math/project.hxx
+++ b/simgear/math/project.hxx
@@ -16,6 +16,9 @@
//
#ifndef SIMGEAR_PROJECT_HXX
#define SIMGEAR_PROJECT_HXX 1
+
+#ifndef NO_OPENSCENEGRAPH_INTERFACE
+
#include
namespace simgear
@@ -26,4 +29,8 @@ extern GLint project(GLdouble objX, GLdouble objY, GLdouble objZ,
const GLint *view,
GLdouble* winX, GLdouble* winY, GLdouble* winZ);
}
+
+#endif // of NO_OPENSCENEGRAPH_INTERFACE
+
#endif
+
diff --git a/simgear/misc/CMakeLists.txt b/simgear/misc/CMakeLists.txt
index 7a06f3bd..43904321 100644
--- a/simgear/misc/CMakeLists.txt
+++ b/simgear/misc/CMakeLists.txt
@@ -7,7 +7,6 @@ set(HEADERS
interpolator.hxx
sg_dir.hxx
sg_path.hxx
- sg_sleep.hxx
sgstream.hxx
stdint.hxx
stopwatch.hxx
@@ -24,7 +23,6 @@ set(SOURCES
interpolator.cxx
sg_dir.cxx
sg_path.cxx
- sg_sleep.cxx
sgstream.cxx
strutils.cxx
tabbed_values.cxx
diff --git a/simgear/misc/Makefile.am b/simgear/misc/Makefile.am
index ae696e79..e671418a 100644
--- a/simgear/misc/Makefile.am
+++ b/simgear/misc/Makefile.am
@@ -14,8 +14,7 @@ include_HEADERS = \
stdint.hxx \
PathOptions.hxx \
sg_dir.hxx \
- ResourceManager.hxx \
- sg_sleep.hxx
+ ResourceManager.hxx
libsgmisc_a_SOURCES = \
sg_path.cxx \
@@ -27,8 +26,7 @@ libsgmisc_a_SOURCES = \
interpolator.cxx \
PathOptions.cxx \
sg_dir.cxx \
- ResourceManager.cxx \
- sg_sleep.cxx
+ ResourceManager.cxx
#noinst_PROGRAMS = tabbed_value_test swap_test
diff --git a/simgear/misc/PathOptions.cxx b/simgear/misc/PathOptions.cxx
index 32c719d6..b81600d8 100644
--- a/simgear/misc/PathOptions.cxx
+++ b/simgear/misc/PathOptions.cxx
@@ -17,6 +17,12 @@
//
// $Id$
+#ifdef HAVE_CONFIG_H
+# include
+#endif
+
+#ifndef NO_OPENSCENEGRAPH_INTERFACE
+
#include
#include "PathOptions.hxx"
@@ -31,3 +37,5 @@ osgDB::ReaderWriter::Options* simgear::makeOptionsFromPath(const SGPath& path)
options->setDatabasePath(path.str());
return options;
}
+
+#endif // of NO_OPENSCENEGRAPH_INTERFACE
diff --git a/simgear/misc/PathOptions.hxx b/simgear/misc/PathOptions.hxx
index 9b14d6e8..8d4186a7 100644
--- a/simgear/misc/PathOptions.hxx
+++ b/simgear/misc/PathOptions.hxx
@@ -20,6 +20,7 @@
#ifndef PATHOPTIONSHXX
#define PATHOPTIONSHXX 1
+#ifndef NO_OPENSCENEGRAPH_INTERFACE
#include
#include
@@ -28,3 +29,5 @@ namespace simgear
osgDB::ReaderWriter::Options* makeOptionsFromPath(const SGPath&);
}
#endif
+
+#endif
diff --git a/simgear/misc/interpolator.cxx b/simgear/misc/interpolator.cxx
index 2e902cae..04a898cc 100644
--- a/simgear/misc/interpolator.cxx
+++ b/simgear/misc/interpolator.cxx
@@ -16,6 +16,10 @@
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#ifdef HAVE_CONFIG_H
+# include
+#endif
+
#include "interpolator.hxx"
#include
diff --git a/simgear/misc/path_test.cxx b/simgear/misc/path_test.cxx
index 2d789e64..459f064c 100644
--- a/simgear/misc/path_test.cxx
+++ b/simgear/misc/path_test.cxx
@@ -27,7 +27,7 @@ using std::endl;
void test_dir()
{
simgear::Dir temp = simgear::Dir::tempDir("foo");
- cout << "created:" << temp.path().str() << endl;
+ cout << "created:" << temp.path() << endl;
VERIFY(temp.exists());
VERIFY(temp.path().isDir());
@@ -82,7 +82,7 @@ int main(int argc, char* argv[])
SGPath pj("/Foo/zot.dot/thing.tar.gz");
COMPARE(pj.dir(), std::string("/Foo/zot.dot"));
COMPARE(pj.file(), std::string("thing.tar.gz"));
- COMPARE(pj.base(), std::string("/Foo/zot.dot/thing"));
+ COMPARE(pj.base(), std::string("/Foo/zot.dot/thing.tar"));
COMPARE(pj.file_base(), std::string("thing"));
COMPARE(pj.extension(), std::string("gz"));
COMPARE(pj.complete_lower_extension(), std::string("tar.gz"));
@@ -124,7 +124,7 @@ int main(int argc, char* argv[])
SGPath extB("BAH/FOO.HTML.GZ");
COMPARE(extB.extension(), "GZ");
- COMPARE(extB.base(), "BAH/FOO");
+ COMPARE(extB.base(), "BAH/FOO.HTML");
COMPARE(extB.lower_extension(), "gz");
COMPARE(extB.complete_lower_extension(), "html.gz");
#ifdef _WIN32
@@ -135,6 +135,14 @@ int main(int argc, char* argv[])
#else
COMPARE(d1.str_native(), std::string("/usr/local"));
#endif
+
+// paths with only the file components
+ SGPath pf("something.txt.gz");
+ COMPARE(pf.base(), "something.txt");
+ COMPARE(pf.file(), "something.txt.gz");
+ COMPARE(pf.dir(), "");
+ COMPARE(pf.lower_extension(), "gz");
+ COMPARE(pf.complete_lower_extension(), "txt.gz");
test_dir();
diff --git a/simgear/misc/sg_path.cxx b/simgear/misc/sg_path.cxx
index bff1a61c..46e80228 100644
--- a/simgear/misc/sg_path.cxx
+++ b/simgear/misc/sg_path.cxx
@@ -175,12 +175,13 @@ void SGPath::concat( const string& p ) {
// Get the file part of the path (everything after the last path sep)
-string SGPath::file() const {
- int index = path.rfind(sgDirPathSep);
- if (index >= 0) {
- return path.substr(index + 1);
+string SGPath::file() const
+{
+ string::size_type index = path.rfind(sgDirPathSep);
+ if (index != string::npos) {
+ return path.substr(index + 1);
} else {
- return "";
+ return path;
}
}
@@ -189,40 +190,40 @@ string SGPath::file() const {
string SGPath::dir() const {
int index = path.rfind(sgDirPathSep);
if (index >= 0) {
- return path.substr(0, index);
+ return path.substr(0, index);
} else {
- return "";
+ return "";
}
}
// get the base part of the path (everything but the extension.)
-string SGPath::base() const {
- unsigned int index = path.rfind(sgDirPathSep);
- if (index == string::npos) {
- index = 0; // no separator in the name
- } else {
- ++index; // skip past the separator
- }
-
-// find the first dot after the final separator
- unsigned int firstDot = path.find(".", index);
- if (firstDot == string::npos) {
- return path; // no extension, return whole path
+string SGPath::base() const
+{
+ string::size_type index = path.rfind(".");
+ string::size_type lastSep = path.rfind(sgDirPathSep);
+
+// tolerate dots inside directory names
+ if ((lastSep != string::npos) && (index < lastSep)) {
+ return path;
}
- return path.substr(0, firstDot);
+ if (index != string::npos) {
+ return path.substr(0, index);
+ } else {
+ return path;
+ }
}
string SGPath::file_base() const
{
- unsigned int index = path.rfind(sgDirPathSep);
+ string::size_type index = path.rfind(sgDirPathSep);
if (index == string::npos) {
index = 0; // no separator in the name
} else {
++index; // skip past the separator
}
- unsigned int firstDot = path.find(".", index);
+ string::size_type firstDot = path.find(".", index);
if (firstDot == string::npos) {
return path.substr(index); // no extensions
}
@@ -248,15 +249,15 @@ string SGPath::lower_extension() const {
string SGPath::complete_lower_extension() const
{
- unsigned int index = path.rfind(sgDirPathSep);
+ string::size_type index = path.rfind(sgDirPathSep);
if (index == string::npos) {
index = 0; // no separator in the name
} else {
++index; // skip past the separator
}
- int firstDot = path.find(".", index);
- if ((firstDot >= 0) && (path.find(sgDirPathSep, firstDot) == string::npos)) {
+ string::size_type firstDot = path.find(".", index);
+ if ((firstDot != string::npos) && (path.find(sgDirPathSep, firstDot) == string::npos)) {
return boost::to_lower_copy(path.substr(firstDot + 1));
} else {
return "";
diff --git a/simgear/misc/sg_path.hxx b/simgear/misc/sg_path.hxx
index e71c5f54..969eec0b 100644
--- a/simgear/misc/sg_path.hxx
+++ b/simgear/misc/sg_path.hxx
@@ -124,7 +124,7 @@ public:
std::string dir() const;
/**
- * Get the base part of the path (everything but the extension.)
+ * Get the base part of the path (everything but the final extension.)
* @return the base string
*/
std::string base() const;
@@ -236,6 +236,13 @@ private:
mutable time_t _modTime;
};
+/// Output to an ostream
+template
+inline
+std::basic_ostream&
+operator<<(std::basic_ostream& s, const SGPath& p)
+{ return s << "Path \"" << p.str() << "\""; }
+
/**
* Split a directory string into a list of it's parent directories.
diff --git a/simgear/misc/sg_sleep.cxx b/simgear/misc/sg_sleep.cxx
deleted file mode 100644
index a52880c5..00000000
--- a/simgear/misc/sg_sleep.cxx
+++ /dev/null
@@ -1,60 +0,0 @@
-
-// Written by James Turner, started July 2010.
-//
-// Copyright (C) 2010 Curtis L. Olson - http://www.flightgear.org/~curt
-//
-// This library is free software; you can redistribute it and/or
-// modify it under the terms of the GNU Library General Public
-// License as published by the Free Software Foundation; either
-// version 2 of the License, or (at your option) any later version.
-//
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// Library General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-//
-// $Id$
-
-#include
-
-#ifdef SG_WINDOWS
-# include
-#else
-# include
-#endif
-
-namespace simgear
-{
-
-#ifdef SG_WINDOWS
-
-void sleepForSeconds(int seconds)
-{
- Sleep(1000 * seconds);
-}
-
-void sleepForMSec(int msec)
-{
- Sleep(msec);
-}
-
-#else
-
-void sleepForSeconds(int seconds)
-{
- ::sleep(seconds);
-}
-
-void sleepForMSec(int msec)
-{
- ::usleep(msec * 1000);
-}
-
-#endif
-
-} // of namespace simhear
-
diff --git a/simgear/misc/sg_sleep.hxx b/simgear/misc/sg_sleep.hxx
deleted file mode 100644
index 389fdff3..00000000
--- a/simgear/misc/sg_sleep.hxx
+++ /dev/null
@@ -1,41 +0,0 @@
-
-// Written by James Turner, started July 2010.
-//
-// Copyright (C) 2010 Curtis L. Olson - http://www.flightgear.org/~curt
-//
-// This library is free software; you can redistribute it and/or
-// modify it under the terms of the GNU Library General Public
-// License as published by the Free Software Foundation; either
-// version 2 of the License, or (at your option) any later version.
-//
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// Library General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-//
-// $Id$
-
-
-#ifndef _SG_SLEEP_HXX
-#define _SG_SLEEP_HXX
-
-
-#include
-
-
-namespace simgear
-{
-
-void sleepForSeconds(int seconds);
-
-void sleepForMSec(int msec);
-
-} // of namespace simgear
-
-#endif // _SG_SLEEP_HXX
-
-
diff --git a/simgear/misc/zfstream.cxx b/simgear/misc/zfstream.cxx
index 9ad2dd77..0b75eb55 100644
--- a/simgear/misc/zfstream.cxx
+++ b/simgear/misc/zfstream.cxx
@@ -167,7 +167,7 @@ gzfilebuf::close()
std::streampos
-gzfilebuf::seekoff( std::streamoff, ios_seekdir, int )
+gzfilebuf::seekoff( std::streamoff, ios_seekdir, ios_openmode )
{
return std::streampos(EOF);
}
diff --git a/simgear/misc/zfstream.hxx b/simgear/misc/zfstream.hxx
index a8635483..a9f065ea 100644
--- a/simgear/misc/zfstream.hxx
+++ b/simgear/misc/zfstream.hxx
@@ -90,7 +90,7 @@ public:
bool is_open() const { return (file != NULL); }
/** @return stream position */
- virtual std::streampos seekoff( std::streamoff off, ios_seekdir way, int which );
+ virtual std::streampos seekoff( std::streamoff off, ios_seekdir way, ios_openmode which );
/** sync the stream */
virtual int sync();
diff --git a/simgear/nasal/codegen.c b/simgear/nasal/codegen.c
index d1c05ef6..059c1144 100644
--- a/simgear/nasal/codegen.c
+++ b/simgear/nasal/codegen.c
@@ -536,6 +536,9 @@ static void genAssign(struct Parser* p, struct Token* t)
{
struct Token *lv = LEFT(t), *rv = RIGHT(t);
int len, dummy, var=0;
+ if (!lv)
+ naParseError(p, "bad assignment, missing variable", t->line);
+ else
if(parListLen(lv) || (lv->type == TOK_VAR && parListLen(RIGHT(lv)))) {
if(lv->type == TOK_VAR) { lv = RIGHT(lv); var = 1; }
len = parListLen(lv);
diff --git a/simgear/props/propertyObject.cxx b/simgear/props/propertyObject.cxx
index df3f81f9..ff87898e 100644
--- a/simgear/props/propertyObject.cxx
+++ b/simgear/props/propertyObject.cxx
@@ -34,6 +34,13 @@ void PropertyObjectBase::setDefaultRoot(SGPropertyNode* aRoot)
{
static_defaultRoot = aRoot;
}
+
+PropertyObjectBase::PropertyObjectBase() :
+ _path(NULL),
+ _prop(NULL)
+{
+
+}
PropertyObjectBase::PropertyObjectBase(const PropertyObjectBase& aOther) :
_path(aOther._path),
diff --git a/simgear/props/propertyObject.hxx b/simgear/props/propertyObject.hxx
index 5cc1588b..a6d357f8 100644
--- a/simgear/props/propertyObject.hxx
+++ b/simgear/props/propertyObject.hxx
@@ -28,6 +28,8 @@ class PropertyObjectBase
public:
static void setDefaultRoot(SGPropertyNode* aRoot);
+ PropertyObjectBase();
+
PropertyObjectBase(const PropertyObjectBase& aOther);
PropertyObjectBase(const char* aChild);
@@ -57,6 +59,8 @@ template
class PropertyObject : PropertyObjectBase
{
public:
+ PropertyObject();
+
/**
* Create from path relative to the default root, and option default value
*/
@@ -220,11 +224,9 @@ private:
} // of namespace simgear
-/*
typedef simgear::PropertyObject SGPropObjDouble;
typedef simgear::PropertyObject SGPropObjBool;
typedef simgear::PropertyObject SGPropObjString;
typedef simgear::PropertyObject SGPropObjInt;
-*/
#endif
diff --git a/simgear/props/propertyObject_test.cxx b/simgear/props/propertyObject_test.cxx
index 5bb4ae58..b07bb483 100644
--- a/simgear/props/propertyObject_test.cxx
+++ b/simgear/props/propertyObject_test.cxx
@@ -1,3 +1,6 @@
+#ifdef HAVE_CONFIG_H
+# include
+#endif
#include
diff --git a/simgear/props/props_test.cxx b/simgear/props/props_test.cxx
index cd54ec50..f8299263 100644
--- a/simgear/props/props_test.cxx
+++ b/simgear/props/props_test.cxx
@@ -3,6 +3,10 @@
// Test harness.
////////////////////////////////////////////////////////////////////////
+#ifdef HAVE_CONFIG_H
+# include
+#endif
+
#include
#include
diff --git a/simgear/props/tiedpropertylist.hxx b/simgear/props/tiedpropertylist.hxx
index f33478ac..7fb354c4 100644
--- a/simgear/props/tiedpropertylist.hxx
+++ b/simgear/props/tiedpropertylist.hxx
@@ -51,7 +51,7 @@ public:
template SGPropertyNode_ptr Tie( SGPropertyNode_ptr node, const SGRawValue &rawValue, bool useDefault = true ) {
bool success = node->tie( rawValue, useDefault );
if( success ) {
- SG_LOG( SG_ALL, SG_INFO, "Tied " << node->getPath() );
+ SG_LOG( SG_ALL, SG_DEBUG, "Tied " << node->getPath() );
push_back( node );
} else {
#if PROPS_STANDALONE
@@ -125,7 +125,7 @@ public:
void Untie() {
while( size() > 0 ) {
- SG_LOG( SG_ALL, SG_INFO, "untie of " << back()->getPath() );
+ SG_LOG( SG_ALL, SG_DEBUG, "untie of " << back()->getPath() );
back()->untie();
pop_back();
}
diff --git a/simgear/scene/material/EffectBuilder.cxx b/simgear/scene/material/EffectBuilder.cxx
index 338fc9aa..79ebb248 100644
--- a/simgear/scene/material/EffectBuilder.cxx
+++ b/simgear/scene/material/EffectBuilder.cxx
@@ -102,4 +102,14 @@ namespace effect
{
const char* colorFields[] = {"red", "green", "blue", "alpha"};
}
+
+PassAttributeBuilder::~PassAttributeBuilder()
+{
}
+
+} // of namespace simgear
+
+
+
+
+
diff --git a/simgear/scene/material/EffectBuilder.hxx b/simgear/scene/material/EffectBuilder.hxx
index a30efa5e..3165ae18 100644
--- a/simgear/scene/material/EffectBuilder.hxx
+++ b/simgear/scene/material/EffectBuilder.hxx
@@ -350,8 +350,11 @@ protected:
struct PassAttrMapSingleton : public simgear::Singleton
{
PassAttrMap passAttrMap;
+
};
public:
+ virtual ~PassAttributeBuilder(); // anchor into the compilation unit.
+
virtual void buildAttribute(Effect* effect, Pass* pass,
const SGPropertyNode* prop,
const SGReaderWriterXMLOptions* options)
diff --git a/simgear/scene/tgdb/SGOceanTile.cxx b/simgear/scene/tgdb/SGOceanTile.cxx
index 2907bbac..def796cd 100644
--- a/simgear/scene/tgdb/SGOceanTile.cxx
+++ b/simgear/scene/tgdb/SGOceanTile.cxx
@@ -60,12 +60,11 @@ using namespace simgear;
// it may be superfluous for such a small mesh.
namespace
{
-const int lonPoints = 5;
-const int latPoints = 5;
-
class OceanMesh {
public:
- OceanMesh():
+ OceanMesh(int latP, int lonP):
+ latPoints(latP),
+ lonPoints(lonP),
geoPoints(latPoints * lonPoints + 2 * (lonPoints + latPoints)),
geod_nodes(latPoints * lonPoints),
vl(new osg::Vec3Array(geoPoints)),
@@ -75,11 +74,24 @@ public:
nlArray(*nl, lonPoints + 2, lonPoints, 1),
tlArray(*tl, lonPoints + 2, lonPoints, 1)
{
+ int numPoints = latPoints * lonPoints;
+ geod = new SGGeod[numPoints];
+ normals = new SGVec3f[numPoints];
+ rel = new SGVec3d[numPoints];
}
+
+ ~OceanMesh()
+ {
+ delete[] geod;
+ delete[] normals;
+ delete[] rel;
+ }
+
+ const int latPoints, lonPoints;
const int geoPoints;
- SGGeod geod[latPoints][lonPoints];
- SGVec3f normals[latPoints][lonPoints];
- SGVec3d rel[latPoints][lonPoints];
+ SGGeod* geod;
+ SGVec3f* normals;
+ SGVec3d* rel;
std::vector geod_nodes;
@@ -114,10 +126,11 @@ void OceanMesh::calcMesh(const SGVec3d& cartCenter, const SGQuatd& orient,
for (int j = 0; j < latPoints; j++) {
double lat = startLat + j * latInc;
for (int i = 0; i < lonPoints; i++) {
- geod[j][i] = SGGeod::fromDeg(startLon + i * longInc, lat);
- SGVec3d cart = SGVec3d::fromGeod(geod[j][i]);
- rel[j][i] = orient.transform(cart - cartCenter);
- normals[j][i] = toVec3f(orient.transform(normalize(cart)));
+ int index = (j * lonPoints) + i;
+ geod[index] = SGGeod::fromDeg(startLon + i * longInc, lat);
+ SGVec3d cart = SGVec3d::fromGeod(geod[index]);
+ rel[index] = orient.transform(cart - cartCenter);
+ normals[index] = toVec3f(orient.transform(normalize(cart)));
}
}
@@ -130,8 +143,9 @@ void OceanMesh::calcMesh(const SGVec3d& cartCenter, const SGQuatd& orient,
VectorArrayAdapter rectArray(rectangle, lonPoints);
for (int j = 0; j < latPoints; j++) {
for (int i = 0; i < lonPoints; i++) {
- geodNodesArray(j, i) = geod[j][i];
- rectArray(j, i) = j * 5 + i;
+ int index = (j * lonPoints) + i;
+ geodNodesArray(j, i) = geod[index];
+ rectArray(j, i) = index;
}
}
@@ -144,8 +158,9 @@ void OceanMesh::calcMesh(const SGVec3d& cartCenter, const SGQuatd& orient,
for (int j = 0; j < latPoints; j++) {
for (int i = 0; i < lonPoints; ++i) {
- vlArray(j, i) = toOsg(rel[j][i]);
- nlArray(j, i) = toOsg(normals[j][i]);
+ int index = (j * lonPoints) + i;
+ vlArray(j, i) = toOsg(rel[index]);
+ nlArray(j, i) = toOsg(normals[index]);
tlArray(j, i) = toOsg(texsArray(j, i));
}
}
@@ -259,7 +274,7 @@ void fillDrawElementsWithApron(short height, short width,
}
}
-osg::Node* SGOceanTile(const SGBucket& b, SGMaterialLib *matlib)
+osg::Node* SGOceanTile(const SGBucket& b, SGMaterialLib *matlib, int latPoints, int lonPoints)
{
Effect *effect = 0;
@@ -277,7 +292,7 @@ osg::Node* SGOceanTile(const SGBucket& b, SGMaterialLib *matlib)
} else {
SG_LOG( SG_TERRAIN, SG_ALERT, "Ack! unknown use material name = Ocean");
}
- OceanMesh grid;
+ OceanMesh grid(latPoints, lonPoints);
// Calculate center point
SGVec3d cartCenter = SGVec3d::fromGeod(b.get_center());
SGGeod geodPos = SGGeod::fromCart(cartCenter);
diff --git a/simgear/scene/tgdb/SGOceanTile.hxx b/simgear/scene/tgdb/SGOceanTile.hxx
index 3e48aebc..75b1f262 100644
--- a/simgear/scene/tgdb/SGOceanTile.hxx
+++ b/simgear/scene/tgdb/SGOceanTile.hxx
@@ -28,6 +28,6 @@ class SGBucket;
class SGMaterialLib;
// Generate an ocean tile
-osg::Node* SGOceanTile(const SGBucket& b, SGMaterialLib *matlib);
+osg::Node* SGOceanTile(const SGBucket& b, SGMaterialLib *matlib, int latPoints = 5, int lonPoints = 5);
#endif // _SG_OBJ_HXX
diff --git a/simgear/scene/tgdb/obj.cxx b/simgear/scene/tgdb/obj.cxx
index 36011d72..6e16dc70 100644
--- a/simgear/scene/tgdb/obj.cxx
+++ b/simgear/scene/tgdb/obj.cxx
@@ -583,7 +583,7 @@ SGLoadBTG(const std::string& path, SGMaterialLib *matlib, bool calc_lights, bool
{
SGBinObject tile;
if (!tile.read_bin(path))
- return false;
+ return NULL;
SGVec3d center = tile.get_gbs_center();
SGGeod geodPos = SGGeod::fromCart(center);
@@ -604,7 +604,7 @@ SGLoadBTG(const std::string& path, SGMaterialLib *matlib, bool calc_lights, bool
SGTileGeometryBin tileGeometryBin;
if (!tileGeometryBin.insertBinObj(tile, matlib))
- return false;
+ return NULL;
SGVec3f up(0, 0, 1);
GroundLightManager* lightManager = GroundLightManager::instance();
diff --git a/simgear/scene/tsync/terrasync.cxx b/simgear/scene/tsync/terrasync.cxx
index 0f99d4e5..800f278a 100644
--- a/simgear/scene/tsync/terrasync.cxx
+++ b/simgear/scene/tsync/terrasync.cxx
@@ -45,6 +45,7 @@
#include // atoi() atof() abs() system()
#include // signal()
+#include
#include
#include
@@ -486,7 +487,18 @@ bool SGTerraSync::SvnThread::syncTreeExternal(const char* dir)
command = buf.str();
#endif
SG_LOG(SG_TERRAIN,SG_DEBUG, "sync command '" << command << "'");
+
+#ifdef SG_WINDOWS
+ // tbd: does Windows support "popen"?
int rc = system( command.c_str() );
+#else
+ FILE* pipe = popen( command.c_str(), "r");
+ int rc=-1;
+ // wait for external process to finish
+ if (pipe)
+ rc = pclose(pipe);
+#endif
+
if (rc)
{
SG_LOG(SG_TERRAIN,SG_ALERT,
@@ -701,12 +713,21 @@ void SGTerraSync::reinit()
_svnThread->setExtSvnUtility(_terraRoot->getStringValue("ext-svn-utility","svn"));
if (_svnThread->start())
+ {
syncAirportsModels();
+ if (last_lat != NOWHERE && last_lon != NOWHERE)
+ {
+ // reschedule most recent position
+ int lat = last_lat;
+ int lon = last_lon;
+ last_lat = NOWHERE;
+ last_lon = NOWHERE;
+ schedulePosition(lat, lon);
+ }
+ }
}
_stalled_node->setBoolValue(_svnThread->_stalled);
- last_lat = NOWHERE;
- last_lon = NOWHERE;
}
void SGTerraSync::bind()
@@ -802,10 +823,11 @@ void SGTerraSync::setTileCache(TileCache* tile_cache)
void SGTerraSync::syncAirportsModels()
{
- static const char bounds[] = "KZAJ";
- for( unsigned i = 0; i < sizeof(bounds)/sizeof(bounds[0])/2; i+= 2 )
+ static const char* bounds = "MZAJKL"; // airport sync order: K-L, A-J, M-Z
+ // note "request" method uses LIFO order, i.e. processes most recent request first
+ for( unsigned i = 0; i < strlen(bounds)/2; i++ )
{
- for ( char synced_other = bounds[i]; synced_other <= bounds[i+1]; synced_other++ )
+ for ( char synced_other = bounds[2*i]; synced_other <= bounds[2*i+1]; synced_other++ )
{
ostringstream dir;
dir << "Airports/" << synced_other;
@@ -896,46 +918,49 @@ void SGTerraSync::syncAreas( int lat, int lon, int lat_dir, int lon_dir )
bool SGTerraSync::schedulePosition(int lat, int lon)
{
+ bool Ok = false;
+
// Ignore messages where the location does not change
if ( lat != last_lat || lon != last_lon )
{
- SG_LOG(SG_TERRAIN,SG_DEBUG, "Requesting scenery update for position " <<
- lat << "," << lon);
- int lat_dir, lon_dir, dist;
- if ( last_lat == NOWHERE || last_lon == NOWHERE )
+ if (_svnThread->_running)
{
- lat_dir = lon_dir = 0;
- } else
- {
- dist = lat - last_lat;
- if ( dist != 0 )
+ SG_LOG(SG_TERRAIN,SG_DEBUG, "Requesting scenery update for position " <<
+ lat << "," << lon);
+ int lat_dir=0;
+ int lon_dir=0;
+ if ( last_lat != NOWHERE && last_lon != NOWHERE )
{
- lat_dir = dist / abs(dist);
- }
- else
- {
- lat_dir = 0;
- }
- dist = lon - last_lon;
- if ( dist != 0 )
- {
- lon_dir = dist / abs(dist);
- } else
- {
- lon_dir = 0;
+ int dist = lat - last_lat;
+ if ( dist != 0 )
+ {
+ lat_dir = dist / abs(dist);
+ }
+ else
+ {
+ lat_dir = 0;
+ }
+ dist = lon - last_lon;
+ if ( dist != 0 )
+ {
+ lon_dir = dist / abs(dist);
+ } else
+ {
+ lon_dir = 0;
+ }
}
+
+ SG_LOG(SG_TERRAIN,SG_DEBUG, "Scenery update for " <<
+ "lat = " << lat << ", lon = " << lon <<
+ ", lat_dir = " << lat_dir << ", " <<
+ "lon_dir = " << lon_dir);
+
+ syncAreas( lat, lon, lat_dir, lon_dir );
+ Ok = true;
}
-
- SG_LOG(SG_TERRAIN,SG_DEBUG, "Scenery update for " <<
- "lat = " << lat << ", lon = " << lon <<
- ", lat_dir = " << lat_dir << ", " <<
- "lon_dir = " << lon_dir);
-
- syncAreas( lat, lon, lat_dir, lon_dir );
-
last_lat = lat;
last_lon = lon;
- return true;
}
- return false;
+
+ return Ok;
}
diff --git a/simgear/scene/util/StateAttributeFactory.cxx b/simgear/scene/util/StateAttributeFactory.cxx
index 25a0a576..3e289ad5 100644
--- a/simgear/scene/util/StateAttributeFactory.cxx
+++ b/simgear/scene/util/StateAttributeFactory.cxx
@@ -86,4 +86,10 @@ StateAttributeFactory::StateAttributeFactory()
_depthWritesDisabled->setDataVariance(Object::STATIC);
}
+// anchor the destructor into this file, to avoid ref_ptr warnings
+StateAttributeFactory::~StateAttributeFactory()
+{
+
+}
+
}
diff --git a/simgear/scene/util/StateAttributeFactory.hxx b/simgear/scene/util/StateAttributeFactory.hxx
index 0076fa51..47603e7b 100644
--- a/simgear/scene/util/StateAttributeFactory.hxx
+++ b/simgear/scene/util/StateAttributeFactory.hxx
@@ -45,6 +45,8 @@ namespace simgear
class StateAttributeFactory :
public ReferencedSingleton {
public:
+ ~StateAttributeFactory();
+
// Alpha test > .01
osg::AlphaFunc* getStandardAlphaFunc() { return _standardAlphaFunc.get(); }
// alpha source, 1 - alpha destination
diff --git a/simgear/simgear_config_cmake.h.in b/simgear/simgear_config_cmake.h.in
index 3d132306..a1192283 100644
--- a/simgear/simgear_config_cmake.h.in
+++ b/simgear/simgear_config_cmake.h.in
@@ -16,5 +16,7 @@
#cmakedefine HAVE_SVN_CLIENT_H
#cmakedefine HAVE_LIBSVN_CLIENT_1
+#cmakedefine GCC_ATOMIC_BUILTINS_FOUND
+
// set if building headless (no OSG or OpenGL libs)
#cmakedefine NO_OPENSCENEGRAPH_INTERFACE
diff --git a/simgear/sound/CMakeLists.txt b/simgear/sound/CMakeLists.txt
index c07a7065..6670190a 100644
--- a/simgear/sound/CMakeLists.txt
+++ b/simgear/sound/CMakeLists.txt
@@ -16,4 +16,22 @@ set(SOURCES
xmlsound.cxx
)
-simgear_component(sound sound "${SOURCES}" "${HEADERS}")
\ No newline at end of file
+simgear_component(sound sound "${SOURCES}" "${HEADERS}")
+
+set(SOUND_TEST_LIBS
+ sgsound sgio sgmath sgstructure sgthreads sgtiming sgmisc sgdebug
+ ${CMAKE_THREAD_LIBS_INIT}
+ ${RT_LIBRARY}
+ ${ALUT_LIBRARY} ${OPENAL_LIBRARY})
+
+function(create_test TEST_NAME)
+ add_executable(${TEST_NAME} ${TEST_NAME}.cxx)
+ target_link_libraries(${TEST_NAME} ${SOUND_TEST_LIBS})
+ set_target_properties(${TEST_NAME} PROPERTIES
+ COMPILE_DEFINITIONS "SRC_DIR=\"${CMAKE_CURRENT_SOURCE_DIR}\"" )
+endfunction()
+
+create_test(openal_test1)
+create_test(openal_test2)
+create_test(openal_test3)
+create_test(openal_test4)
diff --git a/simgear/sound/openal_test1.cxx b/simgear/sound/openal_test1.cxx
index 3d055b00..0a6dc885 100644
--- a/simgear/sound/openal_test1.cxx
+++ b/simgear/sound/openal_test1.cxx
@@ -103,10 +103,6 @@ int main( int argc, char *argv[] ) {
ALfloat source_vel[3];
// configuration values
-// ALenum format;
-// ALsizei size;
-// ALvoid* data;
-// ALsizei freq;
ALboolean loop = false;
source_pos[0] = 0.0; source_pos[1] = 0.0; source_pos[2] = 0.0;
@@ -131,6 +127,11 @@ int main( int argc, char *argv[] ) {
}
#else
+ ALenum format;
+ ALsizei size;
+ ALvoid* data;
+ ALsizei freq;
+
# if defined (__APPLE__)
alutLoadWAVFile( (ALbyte *)AUDIOFILE, &format, &data, &size, &freq );
# else
diff --git a/simgear/sound/sample_openal.hxx b/simgear/sound/sample_openal.hxx
index b5267bb1..9e816c21 100644
--- a/simgear/sound/sample_openal.hxx
+++ b/simgear/sound/sample_openal.hxx
@@ -82,7 +82,7 @@ public:
/**
* Destructor
*/
- ~SGSoundSample ();
+ virtual ~SGSoundSample ();
/**
* Detect wheter this audio sample holds the information of a sound file.
diff --git a/simgear/structure/SGAtomic.cxx b/simgear/structure/SGAtomic.cxx
index 728994df..71f24ed9 100644
--- a/simgear/structure/SGAtomic.cxx
+++ b/simgear/structure/SGAtomic.cxx
@@ -1,6 +1,6 @@
/* -*-c++-*-
*
- * Copyright (C) 2005-2009 Mathias Froehlich
+ * Copyright (C) 2005-2009,2011 Mathias Froehlich
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@@ -18,58 +18,105 @@
*
*/
+#ifdef HAVE_CONFIG_H
+# include
+#endif
+
#include "SGAtomic.hxx"
-#if defined(SGATOMIC_USE_GCC4_BUILTINS) && defined (__i386__)
+#if defined(SGATOMIC_USE_LIBRARY_FUNCTIONS)
-// Usually the appropriate functions are inlined by gcc.
-// But if gcc is called with something equivalent to -march=i386,
-// it will not assume that there is a lock instruction and instead
-// calls this pair of functions. We will provide them here in this case.
-// Note that this assembler code will not work on a i386 chip anymore.
-// But I firmly believe that we can assume to run at least on a i486 ...
+#if defined(_WIN32)
+# include
+#elif defined(GCC_ATOMIC_BUILTINS_FOUND)
+#elif defined(__GNUC__) && defined(__i386__)
+#elif defined(SGATOMIC_USE_MUTEX)
+# include
+#else
+# error
+#endif
-extern "C" {
-
-unsigned __sync_sub_and_fetch_4(volatile void *ptr, unsigned value)
+unsigned
+SGAtomic::operator++()
{
- register volatile unsigned* mem = reinterpret_cast(ptr);
- register unsigned result;
- __asm__ __volatile__("lock; xadd{l} {%0,%1|%1,%0}"
- : "=r" (result), "=m" (*mem)
- : "0" (-value), "m" (*mem)
- : "memory");
- return result - value;
+#if defined(_WIN32)
+ return InterlockedIncrement(reinterpret_cast(&mValue));
+#elif defined(GCC_ATOMIC_BUILTINS_FOUND)
+ return __sync_add_and_fetch(&mValue, 1);
+#elif defined(__GNUC__) && defined(__i386__)
+ register volatile unsigned* mem = reinterpret_cast(&mValue);
+ register unsigned result;
+ __asm__ __volatile__("lock; xadd{l} {%0,%1|%1,%0}"
+ : "=r" (result), "=m" (*mem)
+ : "0" (1), "m" (*mem)
+ : "memory");
+ return result + 1;
+#else
+ SGGuard lock(mMutex);
+ return ++mValue;
+#endif
}
-unsigned __sync_add_and_fetch_4(volatile void *ptr, unsigned value)
+unsigned
+SGAtomic::operator--()
{
- register volatile unsigned* mem = reinterpret_cast(ptr);
- register unsigned result;
- __asm__ __volatile__("lock; xadd{l} {%0,%1|%1,%0}"
- : "=r" (result), "=m" (*mem)
- : "0" (value), "m" (*mem)
- : "memory");
- return result + value;
+#if defined(_WIN32)
+ return InterlockedDecrement(reinterpret_cast(&mValue));
+#elif defined(GCC_ATOMIC_BUILTINS_FOUND)
+ return __sync_sub_and_fetch(&mValue, 1);
+#elif defined(__GNUC__) && defined(__i386__)
+ register volatile unsigned* mem = reinterpret_cast(&mValue);
+ register unsigned result;
+ __asm__ __volatile__("lock; xadd{l} {%0,%1|%1,%0}"
+ : "=r" (result), "=m" (*mem)
+ : "0" (-1), "m" (*mem)
+ : "memory");
+ return result - 1;
+#else
+ SGGuard lock(mMutex);
+ return --mValue;
+#endif
}
-unsigned __sync_bool_compare_and_swap_4(volatile void *ptr,
- unsigned oldValue, unsigned newValue)
+SGAtomic::operator unsigned() const
{
- register volatile unsigned* mem = reinterpret_cast(ptr);
- unsigned before;
- __asm__ __volatile__("lock; cmpxchg{l} {%1,%2|%1,%2}"
- : "=a"(before)
- : "q"(newValue), "m"(*mem), "0"(oldValue)
- : "memory");
- return before == oldValue;
+#if defined(_WIN32)
+ return static_cast(mValue);
+#elif defined(GCC_ATOMIC_BUILTINS_FOUND)
+ __sync_synchronize();
+ return mValue;
+#elif defined(__GNUC__) && defined(__i386__)
+ __asm__ __volatile__("": : : "memory");
+ return mValue;
+#else
+ SGGuard lock(mMutex);
+ return mValue;
+#endif
}
-void __sync_synchronize()
+bool
+SGAtomic::compareAndExchange(unsigned oldValue, unsigned newValue)
{
- __asm__ __volatile__("": : : "memory");
+#if defined(_WIN32)
+ long volatile* lvPtr = reinterpret_cast(&mValue);
+ return oldValue == InterlockedCompareExchange(lvPtr, newValue, oldValue);
+#elif defined(GCC_ATOMIC_BUILTINS_FOUND)
+ return __sync_bool_compare_and_swap(&mValue, oldValue, newValue);
+#elif defined(__GNUC__) && defined(__i386__)
+ register volatile unsigned* mem = reinterpret_cast(&mValue);
+ unsigned before;
+ __asm__ __volatile__("lock; cmpxchg{l} {%1,%2|%1,%2}"
+ : "=a"(before)
+ : "q"(newValue), "m"(*mem), "0"(oldValue)
+ : "memory");
+ return before == oldValue;
+#else
+ SGGuard lock(mMutex);
+ if (mValue != oldValue)
+ return false;
+ mValue = newValue;
+ return true;
+#endif
}
-} // extern "C"
-
#endif
diff --git a/simgear/structure/SGAtomic.hxx b/simgear/structure/SGAtomic.hxx
index 081a4906..493c8d25 100644
--- a/simgear/structure/SGAtomic.hxx
+++ b/simgear/structure/SGAtomic.hxx
@@ -1,6 +1,6 @@
/* -*-c++-*-
*
- * Copyright (C) 2005-2009 Mathias Froehlich
+ * Copyright (C) 2005-2009,2011 Mathias Froehlich
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@@ -21,93 +21,96 @@
#ifndef SGAtomic_HXX
#define SGAtomic_HXX
-#if defined(__GNUC__) && ((4 < __GNUC__)||(4 == __GNUC__ && 1 <= __GNUC_MINOR__)) \
- && (defined(__i386__) || defined(__x86_64__))
+#if defined(__GNUC__) && ((4 < __GNUC__)||(4 == __GNUC__ && 1 <= __GNUC_MINOR__)) && \
+ defined(__x86_64__)
// No need to include something. Is a Compiler API ...
# define SGATOMIC_USE_GCC4_BUILTINS
+#elif defined(__GNUC__) && defined(__i386__)
+# define SGATOMIC_USE_LIBRARY_FUNCTIONS
#elif defined(__sgi) && defined(_COMPILER_VERSION) && (_COMPILER_VERSION>=730)
// No need to include something. Is a Compiler API ...
# define SGATOMIC_USE_MIPSPRO_BUILTINS
#elif defined(_WIN32)
-# include
-# define SGATOMIC_USE_WIN32_INTERLOCKED
+# define SGATOMIC_USE_LIBRARY_FUNCTIONS
#else
// The sledge hammer ...
+# define SGATOMIC_USE_LIBRARY_FUNCTIONS
+# define SGATOMIC_USE_MUTEX
# include
-# include
#endif
class SGAtomic {
public:
SGAtomic(unsigned value = 0) : mValue(value)
{ }
+
+#if defined(SGATOMIC_USE_LIBRARY_FUNCTIONS)
+ unsigned operator++();
+#else
unsigned operator++()
{
-#if defined(SGATOMIC_USE_GCC4_BUILTINS)
+# if defined(SGATOMIC_USE_GCC4_BUILTINS)
return __sync_add_and_fetch(&mValue, 1);
-#elif defined(SGATOMIC_USE_MIPOSPRO_BUILTINS)
+# elif defined(SGATOMIC_USE_MIPOSPRO_BUILTINS)
return __add_and_fetch(&mValue, 1);
-#elif defined(SGATOMIC_USE_WIN32_INTERLOCKED)
- return InterlockedIncrement(reinterpret_cast(&mValue));
-#else
- SGGuard lock(mMutex);
- return ++mValue;
-#endif
+# else
+# error
+# endif
}
+#endif
+
+#if defined(SGATOMIC_USE_LIBRARY_FUNCTIONS)
+ unsigned operator--();
+#else
unsigned operator--()
{
-#if defined(SGATOMIC_USE_GCC4_BUILTINS)
+# if defined(SGATOMIC_USE_GCC4_BUILTINS)
return __sync_sub_and_fetch(&mValue, 1);
-#elif defined(SGATOMIC_USE_MIPOSPRO_BUILTINS)
+# elif defined(SGATOMIC_USE_MIPOSPRO_BUILTINS)
return __sub_and_fetch(&mValue, 1);
-#elif defined(SGATOMIC_USE_WIN32_INTERLOCKED)
- return InterlockedDecrement(reinterpret_cast(&mValue));
-#else
- SGGuard lock(mMutex);
- return --mValue;
-#endif
+# else
+# error
+# endif
}
+#endif
+
+#if defined(SGATOMIC_USE_LIBRARY_FUNCTIONS)
+ operator unsigned() const;
+#else
operator unsigned() const
{
-#if defined(SGATOMIC_USE_GCC4_BUILTINS)
+# if defined(SGATOMIC_USE_GCC4_BUILTINS)
__sync_synchronize();
return mValue;
-#elif defined(SGATOMIC_USE_MIPOSPRO_BUILTINS)
+# elif defined(SGATOMIC_USE_MIPOSPRO_BUILTINS)
__synchronize();
return mValue;
-#elif defined(SGATOMIC_USE_WIN32_INTERLOCKED)
- return static_cast(mValue);
-#else
- SGGuard lock(mMutex);
- return mValue;
-#endif
+# else
+# error
+# endif
}
+#endif
+#if defined(SGATOMIC_USE_LIBRARY_FUNCTIONS)
+ bool compareAndExchange(unsigned oldValue, unsigned newValue);
+#else
bool compareAndExchange(unsigned oldValue, unsigned newValue)
{
-#if defined(SGATOMIC_USE_GCC4_BUILTINS)
+# if defined(SGATOMIC_USE_GCC4_BUILTINS)
return __sync_bool_compare_and_swap(&mValue, oldValue, newValue);
-#elif defined(SGATOMIC_USE_MIPOSPRO_BUILTINS)
+# elif defined(SGATOMIC_USE_MIPOSPRO_BUILTINS)
return __compare_and_swap(&mValue, oldValue, newValue);
-#elif defined(SGATOMIC_USE_WIN32_INTERLOCKED)
- long volatile* lvPtr = reinterpret_cast(&mValue);
- return oldValue == InterlockedCompareExchange(lvPtr, newValue, oldValue);
-#else
- SGGuard lock(mMutex);
- if (mValue != oldValue)
- return false;
- mValue = newValue;
- return true;
-#endif
+# else
+# error
+# endif
}
+#endif
private:
SGAtomic(const SGAtomic&);
SGAtomic& operator=(const SGAtomic&);
-#if !defined(SGATOMIC_USE_GCC4_BUILTINS) \
- && !defined(SGATOMIC_USE_MIPOSPRO_BUILTINS) \
- && !defined(SGATOMIC_USE_WIN32_INTERLOCKED)
+#if defined(SGATOMIC_USE_MUTEX)
mutable SGMutex mMutex;
#endif
unsigned mValue;
diff --git a/simgear/structure/Singleton.hxx b/simgear/structure/Singleton.hxx
index 0c3a5946..cc98c497 100644
--- a/simgear/structure/Singleton.hxx
+++ b/simgear/structure/Singleton.hxx
@@ -3,8 +3,10 @@
#include
+#ifndef NO_OPENSCENEGRAPH_INTERFACE
#include
#include
+#endif
namespace simgear
{
@@ -27,6 +29,7 @@ public:
}
};
+#ifndef NO_OPENSCENEGRAPH_INTERFACE
template
class SingletonRefPtr
{
@@ -54,5 +57,7 @@ public:
return SingletonRefPtr::instance();
}
};
+#endif // of NO_OPENSCENEGRAPH_INTERFACE
+
}
#endif
diff --git a/simgear/structure/event_mgr.cxx b/simgear/structure/event_mgr.cxx
index 11b34b7a..f448a649 100644
--- a/simgear/structure/event_mgr.cxx
+++ b/simgear/structure/event_mgr.cxx
@@ -1,3 +1,7 @@
+#ifdef HAVE_CONFIG_H
+# include
+#endif
+
#include "event_mgr.hxx"
#include
diff --git a/simgear/structure/subsystem_mgr.cxx b/simgear/structure/subsystem_mgr.cxx
index 39598abe..a59d6ef0 100644
--- a/simgear/structure/subsystem_mgr.cxx
+++ b/simgear/structure/subsystem_mgr.cxx
@@ -18,6 +18,10 @@
//
// $Id$
+#ifdef HAVE_CONFIG_H
+# include
+#endif
+
#include
#include
diff --git a/simgear/timing/timestamp.cxx b/simgear/timing/timestamp.cxx
index 83eff2fc..2189d643 100644
--- a/simgear/timing/timestamp.cxx
+++ b/simgear/timing/timestamp.cxx
@@ -31,6 +31,7 @@
#include
#include
+#include
#ifdef HAVE_SYS_TIMEB_H
# include // for ftime() and struct timeb
@@ -44,7 +45,6 @@
#if defined(_POSIX_TIMERS) && (0 < _POSIX_TIMERS)
# include
-# include
#endif
#ifdef WIN32
@@ -58,6 +58,29 @@
#include "timestamp.hxx"
+#if defined(_POSIX_TIMERS) && (0 < _POSIX_TIMERS)
+static clockid_t getClockId()
+{
+#if defined(_POSIX_MONOTONIC_CLOCK)
+ static clockid_t clockid = CLOCK_MONOTONIC;
+ static bool firstTime = true;
+ if (!firstTime)
+ return clockid;
+
+ firstTime = false;
+ // For the first time test if the monotonic clock is available.
+ // If so use this, if not use the realtime clock.
+ struct timespec ts;
+ if (-1 == clock_gettime(clockid, &ts) && errno == EINVAL)
+ clockid = CLOCK_REALTIME;
+ return clockid;
+#else
+ return CLOCK_REALTIME;
+#endif
+}
+
+#endif
+
void SGTimeStamp::stamp() {
#ifdef _WIN32
unsigned int t;
@@ -66,27 +89,12 @@ void SGTimeStamp::stamp() {
_nsec = ( t - ( _sec * 1000 ) ) * 1000 * 1000;
#elif defined(_POSIX_TIMERS) && (0 < _POSIX_TIMERS)
struct timespec ts;
-#if defined(_POSIX_MONOTONIC_CLOCK)
- static clockid_t clockid = CLOCK_MONOTONIC;
- static bool firstTime = true;
- if (firstTime) {
- firstTime = false;
- // For the first time test if the monotonic clock is available.
- // If so use this if not use the realtime clock.
- if (-1 == clock_gettime(clockid, &ts) && errno == EINVAL)
- clockid = CLOCK_REALTIME;
- }
- clock_gettime(clockid, &ts);
-#else
- clock_gettime(CLOCK_REALTIME, &ts);
-#endif
+ clock_gettime(getClockId(), &ts);
_sec = ts.tv_sec;
_nsec = ts.tv_nsec;
#elif defined( HAVE_GETTIMEOFDAY )
struct timeval current;
- struct timezone tz;
- // sg_timestamp currtime;
- gettimeofday(¤t, &tz);
+ gettimeofday(¤t, NULL);
_sec = current.tv_sec;
_nsec = current.tv_usec * 1000;
#elif defined( HAVE_GETLOCALTIME )
@@ -104,6 +112,181 @@ void SGTimeStamp::stamp() {
#endif
}
+// sleep based timing loop.
+//
+// Calling sleep, even usleep() on linux is less accurate than
+// we like, but it does free up the cpu for other tasks during
+// the sleep so it is desirable. Because of the way sleep()
+// is implemented in consumer operating systems like windows
+// and linux, you almost always sleep a little longer than the
+// requested amount.
+//
+// To combat the problem of sleeping too long, we calculate the
+// desired wait time and shorten it by 2000us (2ms) to avoid
+// [hopefully] over-sleep'ing. The 2ms value was arrived at
+// via experimentation. We follow this up at the end with a
+// simple busy-wait loop to get the final pause timing exactly
+// right.
+//
+// Assuming we don't oversleep by more than 2000us, this
+// should be a reasonable compromise between sleep based
+// waiting, and busy waiting.
+//
+// Usually posix timer resolutions are low enough that we
+// could just leave this to the operating system today.
+// The day where the busy loop was introduced in flightgear,
+// the usual kernels still had just about 10ms (=HZ for
+// the timer tick) accuracy which is too bad to catch 60Hz...
+bool SGTimeStamp::sleepUntil(const SGTimeStamp& abstime)
+{
+#if defined(_POSIX_TIMERS) && (0 < _POSIX_TIMERS)
+ SGTimeStamp abstimeForSleep = abstime;
+
+ // Always undersleep by resolution of the clock
+ struct timespec ts;
+ if (-1 != clock_getres(getClockId(), &ts)) {
+ abstimeForSleep -= SGTimeStamp::fromSecNSec(ts.tv_sec, ts.tv_nsec);
+ } else {
+ abstimeForSleep -= SGTimeStamp::fromSecMSec(0, 2);
+ }
+
+ ts.tv_sec = abstimeForSleep._sec;
+ ts.tv_nsec = abstimeForSleep._nsec;
+ for (;;) {
+ int ret = clock_nanosleep(getClockId(), TIMER_ABSTIME, &ts, NULL);
+ if (-1 == ret && errno != EINTR)
+ return false;
+ if (ret == 0)
+ break;
+ }
+
+ // The busy loop for the rest
+ SGTimeStamp currentTime;
+ do {
+ currentTime.stamp();
+ } while (currentTime < abstime);
+
+ return true;
+
+#elif defined _WIN32
+
+ SGTimeStamp currentTime;
+ currentTime.stamp();
+ if (abstime <= currentTime)
+ return true;
+
+ SGTimeStamp abstimeForSleep = abstime - SGTimeStamp::fromSecMSec(0, 2);
+ for (;abstimeForSleep < currentTime;) {
+ SGTimeStamp timeDiff = abstimeForSleep - currentTime;
+ if (timeDiff < SGTimeStamp::fromSecMSec(0, 1))
+ break;
+ // Don't know, but may be win32 has something better today??
+ Sleep(static_cast(timeDiff.toMSecs()));
+
+ currentTime.stamp();
+ }
+
+ // Follow by a busy loop
+ while (currentTime < abstime) {
+ currentTime.stamp();
+ }
+
+ return true;
+
+#else
+
+ SGTimeStamp currentTime;
+ currentTime.stamp();
+ if (abstime <= currentTime)
+ return true;
+
+ SGTimeStamp abstimeForSleep = abstime - SGTimeStamp::fromSecMSec(0, 2);
+ for (;abstimeForSleep < currentTime;) {
+ SGTimeStamp timeDiff = abstimeForSleep - currentTime;
+ if (timeDiff < SGTimeStamp::fromSecUSec(0, 1))
+ break;
+ // Its documented that some systems bail out on usleep for longer than 1s
+ // since we recheck the current time anyway just wait for
+ // less than a second multiple times
+ bool truncated = false;
+ if (SGTimeStamp::fromSec(1) < timeDiff) {
+ timeDiff = SGTimeStamp::fromSec(1);
+ truncated = true;
+ }
+ int ret = usleep(static_cast(timeDiff.toUSecs()));
+ if (-1 == ret && errno != EINTR)
+ return false;
+ if (ret == 0 && !truncated)
+ break;
+
+ currentTime.stamp();
+ }
+
+ // Follow by a busy loop
+ while (currentTime < abstime) {
+ currentTime.stamp();
+ }
+
+ return true;
+
+#endif
+}
+
+bool SGTimeStamp::sleepFor(const SGTimeStamp& reltime)
+{
+#if defined(_POSIX_TIMERS) && (0 < _POSIX_TIMERS)
+ struct timespec ts;
+ ts.tv_sec = reltime._sec;
+ ts.tv_nsec = reltime._nsec;
+ for (;;) {
+ struct timespec rem;
+ int ret = clock_nanosleep(getClockId(), 0, &ts, &rem);
+ if (-1 == ret && errno != EINTR)
+ return false;
+ if (ret == 0)
+ break;
+ // Use the remainder for the next cycle.
+ ts = rem;
+ }
+ return true;
+#elif defined _WIN32
+ if (reltime < SGTimeStamp::fromSecMSec(0, 1))
+ return true;
+ // Don't know, but may be win32 has something better today??
+ Sleep(static_cast(reltime.toMSecs()));
+ return true;
+#else
+ SGTimeStamp abstime;
+ abstime.stamp();
+ abstime += reltime;
+
+ SGTimeStamp currentTime;
+ currentTime.stamp();
+ for (;abstime < currentTime;) {
+ SGTimeStamp timeDiff = abstime - currentTime;
+ if (timeDiff < SGTimeStamp::fromSecUSec(0, 1))
+ break;
+ // Its documented that some systems bail out on usleep for longer than 1s
+ // since we recheck the current time anyway just wait for
+ // less than a second multiple times
+ bool truncated = false;
+ if (SGTimeStamp::fromSec(1) < timeDiff) {
+ timeDiff = SGTimeStamp::fromSec(1);
+ truncated = true;
+ }
+ int ret = usleep(static_cast(timeDiff.toUSecs()));
+ if (-1 == ret && errno != EINTR)
+ return false;
+ if (ret == 0 && !truncated)
+ break;
+
+ currentTime.stamp();
+ }
+
+ return true;
+#endif
+}
+
int SGTimeStamp::elapsedMSec() const
{
SGTimeStamp now;
diff --git a/simgear/timing/timestamp.hxx b/simgear/timing/timestamp.hxx
index f195dc37..ac9ca142 100644
--- a/simgear/timing/timestamp.hxx
+++ b/simgear/timing/timestamp.hxx
@@ -184,6 +184,8 @@ public:
{ SGTimeStamp ts; ts.setTime(sec); return ts; }
static SGTimeStamp fromSec(const double& sec)
{ SGTimeStamp ts; ts.setTime(sec); return ts; }
+ static SGTimeStamp fromMSec(nsec_type msec)
+ { return SGTimeStamp(0, 1000*1000*msec); }
static SGTimeStamp fromUSec(nsec_type usec)
{ return SGTimeStamp(0, 1000*usec); }
static SGTimeStamp fromNSec(nsec_type nsec)
@@ -195,6 +197,22 @@ public:
static SGTimeStamp now()
{ SGTimeStamp ts; ts.stamp(); return ts; }
+ /**
+ * Sleep until the time of abstime is passed.
+ */
+ static bool sleepUntil(const SGTimeStamp& abstime);
+
+ /**
+ * Sleep for reltime.
+ */
+ static bool sleepFor(const SGTimeStamp& reltime);
+
+ /**
+ * Alias for the most common use case with milliseconds.
+ */
+ static bool sleepForMSec(unsigned msec)
+ { return sleepFor(fromMSec(msec)); }
+
/**
* elapsed time since the stamp was taken, in msec
*/
diff --git a/simgear/timing/timezone.cxx b/simgear/timing/timezone.cxx
index 7f09e6c6..11884918 100644
--- a/simgear/timing/timezone.cxx
+++ b/simgear/timing/timezone.cxx
@@ -26,6 +26,10 @@
*
************************************************************************/
+#ifdef HAVE_CONFIG_H
+# include
+#endif
+
#include
#include
#include