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