Merge branch 'next' of git://gitorious.org/fg/simgear into next
This commit is contained in:
commit
110753e92c
@ -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)
|
||||
|
@ -671,14 +671,6 @@
|
||||
RelativePath="..\..\simgear\misc\sg_path.hxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\misc\sg_sleep.cxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\misc\sg_sleep.hxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\misc\sgstream.cxx"
|
||||
>
|
||||
@ -1499,6 +1491,14 @@
|
||||
<Filter
|
||||
Name="Lib_sgstructure"
|
||||
>
|
||||
<File
|
||||
RelativePath="..\..\simgear\structure\SGAtomic.hxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\structure\SGAtomic.cxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\structure\callback.hxx"
|
||||
>
|
||||
|
@ -7,6 +7,7 @@ set(HLA_HEADERS
|
||||
HLABasicDataElement.hxx
|
||||
HLABasicDataType.hxx
|
||||
HLADataElement.hxx
|
||||
HLADataElementVisitor.hxx
|
||||
HLADataType.hxx
|
||||
HLADataTypeVisitor.hxx
|
||||
HLAEnumeratedDataElement.hxx
|
||||
|
@ -19,6 +19,8 @@
|
||||
|
||||
#include <simgear/debug/logstream.hxx>
|
||||
|
||||
#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)
|
||||
{
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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); \
|
||||
\
|
||||
|
@ -19,6 +19,8 @@
|
||||
|
||||
#include <simgear/debug/logstream.hxx>
|
||||
|
||||
#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)
|
||||
{
|
||||
|
@ -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;
|
||||
|
||||
|
57
simgear/hla/HLADataElementVisitor.hxx
Normal file
57
simgear/hla/HLADataElementVisitor.hxx
Normal file
@ -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
|
@ -19,6 +19,8 @@
|
||||
|
||||
#include <simgear/debug/logstream.hxx>
|
||||
|
||||
#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)
|
||||
{
|
||||
|
@ -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;
|
||||
|
||||
|
@ -20,6 +20,8 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <simgear/debug/logstream.hxx>
|
||||
|
||||
#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)
|
||||
{
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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<const HLABasicDataType> _dataType;
|
||||
SGSharedPtr<SGPropertyNode> _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<char> visitor(_stream);
|
||||
dataType.getElementDataType()->accept(visitor);
|
||||
value.push_back(visitor.getValue());
|
||||
}
|
||||
_propertyNode.setStringValue(value);
|
||||
}
|
||||
virtual void apply(const HLAVariableArrayDataType& dataType)
|
||||
{
|
||||
HLATemplateDecodeVisitor<std::string::size_type> 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<char> 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<char> 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<std::string::size_type> numElementsVisitor(_stream, value.size());
|
||||
dataType.getSizeDataType()->accept(numElementsVisitor);
|
||||
for (unsigned i = 0; i < value.size(); ++i) {
|
||||
HLATemplateEncodeVisitor<char> 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<const HLAArrayDataType> _dataType;
|
||||
SGSharedPtr<SGPropertyNode> _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
|
||||
{
|
||||
|
@ -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);
|
||||
|
||||
|
@ -19,6 +19,8 @@
|
||||
|
||||
#include <simgear/debug/logstream.hxx>
|
||||
|
||||
#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)
|
||||
{
|
||||
|
@ -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;
|
||||
|
||||
|
@ -11,6 +11,7 @@ libsghla_a_HEADERS = \
|
||||
HLABasicDataElement.hxx \
|
||||
HLABasicDataType.hxx \
|
||||
HLADataElement.hxx \
|
||||
HLADataElementVisitor.hxx \
|
||||
HLADataType.hxx \
|
||||
HLADataTypeVisitor.hxx \
|
||||
HLAEnumeratedDataElement.hxx \
|
||||
|
@ -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;
|
||||
|
@ -12,7 +12,7 @@
|
||||
#include <simgear/io/HTTPRequest.hxx>
|
||||
#include <simgear/io/sg_netChannel.hxx>
|
||||
#include <simgear/misc/strutils.hxx>
|
||||
#include <simgear/misc/sg_sleep.hxx>
|
||||
#include <simgear/timing/timestamp.hxx>
|
||||
|
||||
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) {
|
||||
|
@ -73,6 +73,6 @@ bool SGIOChannel::close() {
|
||||
|
||||
|
||||
// dummy eof routine
|
||||
bool SGIOChannel::eof() {
|
||||
bool SGIOChannel::eof() const {
|
||||
return false;
|
||||
}
|
||||
|
@ -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; }
|
||||
|
@ -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; };
|
||||
};
|
||||
|
||||
|
||||
|
@ -12,7 +12,6 @@
|
||||
#include <simgear/io/sg_netChat.hxx>
|
||||
#include <simgear/misc/strutils.hxx>
|
||||
#include <simgear/timing/timestamp.hxx>
|
||||
#include <simgear/misc/sg_sleep.hxx>
|
||||
|
||||
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;
|
||||
|
@ -15,6 +15,10 @@
|
||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
//
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <simgear_config.h>
|
||||
#endif
|
||||
|
||||
#include "SGMath.hxx"
|
||||
|
||||
#ifndef NO_OPENSCENEGRAPH_INTERFACE
|
||||
|
@ -15,8 +15,14 @@
|
||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
//
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <simgear_config.h>
|
||||
#endif
|
||||
|
||||
#include "project.hxx"
|
||||
|
||||
#ifndef NO_OPENSCENEGRAPH_INTERFACE
|
||||
|
||||
#include <osg/Math>
|
||||
#include <osg/Matrixd>
|
||||
|
||||
@ -41,3 +47,6 @@ GLint project(GLdouble objX, GLdouble objY, GLdouble objZ,
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif // of NO_OPENSCENEGRAPH_INTERFACE
|
||||
|
||||
|
@ -16,6 +16,9 @@
|
||||
//
|
||||
#ifndef SIMGEAR_PROJECT_HXX
|
||||
#define SIMGEAR_PROJECT_HXX 1
|
||||
|
||||
#ifndef NO_OPENSCENEGRAPH_INTERFACE
|
||||
|
||||
#include <osg/GL>
|
||||
|
||||
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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -17,6 +17,12 @@
|
||||
//
|
||||
// $Id$
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <simgear_config.h>
|
||||
#endif
|
||||
|
||||
#ifndef NO_OPENSCENEGRAPH_INTERFACE
|
||||
|
||||
#include <osgDB/Registry>
|
||||
|
||||
#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
|
||||
|
@ -20,6 +20,7 @@
|
||||
#ifndef PATHOPTIONSHXX
|
||||
#define PATHOPTIONSHXX 1
|
||||
|
||||
#ifndef NO_OPENSCENEGRAPH_INTERFACE
|
||||
#include <osgDB/ReaderWriter>
|
||||
#include <simgear/misc/sg_path.hxx>
|
||||
|
||||
@ -28,3 +29,5 @@ namespace simgear
|
||||
osgDB::ReaderWriter::Options* makeOptionsFromPath(const SGPath&);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -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 <simgear_config.h>
|
||||
#endif
|
||||
|
||||
#include "interpolator.hxx"
|
||||
|
||||
#include <simgear/math/SGMath.hxx>
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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 "";
|
||||
|
@ -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<typename char_type, typename traits_type>
|
||||
inline
|
||||
std::basic_ostream<char_type, traits_type>&
|
||||
operator<<(std::basic_ostream<char_type, traits_type>& s, const SGPath& p)
|
||||
{ return s << "Path \"" << p.str() << "\""; }
|
||||
|
||||
|
||||
/**
|
||||
* Split a directory string into a list of it's parent directories.
|
||||
|
@ -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 <simgear/misc/sg_sleep.hxx>
|
||||
|
||||
#ifdef SG_WINDOWS
|
||||
# include <windows.h>
|
||||
#else
|
||||
# include <unistd.h>
|
||||
#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
|
||||
|
@ -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 <simgear/compiler.h>
|
||||
|
||||
|
||||
namespace simgear
|
||||
{
|
||||
|
||||
void sleepForSeconds(int seconds);
|
||||
|
||||
void sleepForMSec(int msec);
|
||||
|
||||
} // of namespace simgear
|
||||
|
||||
#endif // _SG_SLEEP_HXX
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
|
@ -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),
|
||||
|
@ -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 <typename T>
|
||||
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<double> SGPropObjDouble;
|
||||
typedef simgear::PropertyObject<bool> SGPropObjBool;
|
||||
typedef simgear::PropertyObject<std::string> SGPropObjString;
|
||||
typedef simgear::PropertyObject<long> SGPropObjInt;
|
||||
*/
|
||||
|
||||
#endif
|
||||
|
@ -1,3 +1,6 @@
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <simgear_config.h>
|
||||
#endif
|
||||
|
||||
#include <simgear/compiler.h>
|
||||
|
||||
|
@ -3,6 +3,10 @@
|
||||
// Test harness.
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <simgear_config.h>
|
||||
#endif
|
||||
|
||||
#include <simgear/compiler.h>
|
||||
|
||||
#include <iostream>
|
||||
|
@ -51,7 +51,7 @@ public:
|
||||
template<typename T> SGPropertyNode_ptr Tie( SGPropertyNode_ptr node, const SGRawValue<T> &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();
|
||||
}
|
||||
|
@ -102,4 +102,14 @@ namespace effect
|
||||
{
|
||||
const char* colorFields[] = {"red", "green", "blue", "alpha"};
|
||||
}
|
||||
|
||||
PassAttributeBuilder::~PassAttributeBuilder()
|
||||
{
|
||||
}
|
||||
|
||||
} // of namespace simgear
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -350,8 +350,11 @@ protected:
|
||||
struct PassAttrMapSingleton : public simgear::Singleton<PassAttrMapSingleton>
|
||||
{
|
||||
PassAttrMap passAttrMap;
|
||||
|
||||
};
|
||||
public:
|
||||
virtual ~PassAttributeBuilder(); // anchor into the compilation unit.
|
||||
|
||||
virtual void buildAttribute(Effect* effect, Pass* pass,
|
||||
const SGPropertyNode* prop,
|
||||
const SGReaderWriterXMLOptions* options)
|
||||
|
@ -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<SGGeod> 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<int_list> 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);
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
|
@ -45,6 +45,7 @@
|
||||
|
||||
#include <stdlib.h> // atoi() atof() abs() system()
|
||||
#include <signal.h> // signal()
|
||||
#include <string.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
@ -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;
|
||||
}
|
||||
|
@ -86,4 +86,10 @@ StateAttributeFactory::StateAttributeFactory()
|
||||
_depthWritesDisabled->setDataVariance(Object::STATIC);
|
||||
}
|
||||
|
||||
// anchor the destructor into this file, to avoid ref_ptr warnings
|
||||
StateAttributeFactory::~StateAttributeFactory()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -45,6 +45,8 @@ namespace simgear
|
||||
class StateAttributeFactory :
|
||||
public ReferencedSingleton<StateAttributeFactory> {
|
||||
public:
|
||||
~StateAttributeFactory();
|
||||
|
||||
// Alpha test > .01
|
||||
osg::AlphaFunc* getStandardAlphaFunc() { return _standardAlphaFunc.get(); }
|
||||
// alpha source, 1 - alpha destination
|
||||
|
@ -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
|
||||
|
@ -16,4 +16,22 @@ set(SOURCES
|
||||
xmlsound.cxx
|
||||
)
|
||||
|
||||
simgear_component(sound sound "${SOURCES}" "${HEADERS}")
|
||||
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)
|
||||
|
@ -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
|
||||
|
@ -82,7 +82,7 @@ public:
|
||||
/**
|
||||
* Destructor
|
||||
*/
|
||||
~SGSoundSample ();
|
||||
virtual ~SGSoundSample ();
|
||||
|
||||
/**
|
||||
* Detect wheter this audio sample holds the information of a sound file.
|
||||
|
@ -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 <simgear_config.h>
|
||||
#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 <windows.h>
|
||||
#elif defined(GCC_ATOMIC_BUILTINS_FOUND)
|
||||
#elif defined(__GNUC__) && defined(__i386__)
|
||||
#elif defined(SGATOMIC_USE_MUTEX)
|
||||
# include <simgear/threads/SGGuard.hxx>
|
||||
#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<volatile unsigned*>(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<long volatile*>(&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<volatile unsigned*>(&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<SGMutex> 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<volatile unsigned*>(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<long volatile*>(&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<volatile unsigned*>(&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<SGMutex> 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<volatile unsigned*>(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<unsigned const volatile &>(mValue);
|
||||
#elif defined(GCC_ATOMIC_BUILTINS_FOUND)
|
||||
__sync_synchronize();
|
||||
return mValue;
|
||||
#elif defined(__GNUC__) && defined(__i386__)
|
||||
__asm__ __volatile__("": : : "memory");
|
||||
return mValue;
|
||||
#else
|
||||
SGGuard<SGMutex> 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<long volatile*>(&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<volatile unsigned*>(&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<SGMutex> lock(mMutex);
|
||||
if (mValue != oldValue)
|
||||
return false;
|
||||
mValue = newValue;
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
} // extern "C"
|
||||
|
||||
#endif
|
||||
|
@ -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 <windows.h>
|
||||
# define SGATOMIC_USE_WIN32_INTERLOCKED
|
||||
# define SGATOMIC_USE_LIBRARY_FUNCTIONS
|
||||
#else
|
||||
// The sledge hammer ...
|
||||
# define SGATOMIC_USE_LIBRARY_FUNCTIONS
|
||||
# define SGATOMIC_USE_MUTEX
|
||||
# include <simgear/threads/SGThread.hxx>
|
||||
# include <simgear/threads/SGGuard.hxx>
|
||||
#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<long volatile*>(&mValue));
|
||||
#else
|
||||
SGGuard<SGMutex> 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<long volatile*>(&mValue));
|
||||
#else
|
||||
SGGuard<SGMutex> 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<unsigned const volatile &>(mValue);
|
||||
#else
|
||||
SGGuard<SGMutex> 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<long volatile*>(&mValue);
|
||||
return oldValue == InterlockedCompareExchange(lvPtr, newValue, oldValue);
|
||||
#else
|
||||
SGGuard<SGMutex> 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;
|
||||
|
@ -3,8 +3,10 @@
|
||||
|
||||
#include <boost/pool/detail/singleton.hpp>
|
||||
|
||||
#ifndef NO_OPENSCENEGRAPH_INTERFACE
|
||||
#include <osg/Referenced>
|
||||
#include <osg/ref_ptr>
|
||||
#endif
|
||||
|
||||
namespace simgear
|
||||
{
|
||||
@ -27,6 +29,7 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
#ifndef NO_OPENSCENEGRAPH_INTERFACE
|
||||
template <typename RefClass>
|
||||
class SingletonRefPtr
|
||||
{
|
||||
@ -54,5 +57,7 @@ public:
|
||||
return SingletonRefPtr<RefClass>::instance();
|
||||
}
|
||||
};
|
||||
#endif // of NO_OPENSCENEGRAPH_INTERFACE
|
||||
|
||||
}
|
||||
#endif
|
||||
|
@ -1,3 +1,7 @@
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <simgear_config.h>
|
||||
#endif
|
||||
|
||||
#include "event_mgr.hxx"
|
||||
|
||||
#include <simgear/math/SGMath.hxx>
|
||||
|
@ -18,6 +18,10 @@
|
||||
//
|
||||
// $Id$
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <simgear_config.h>
|
||||
#endif
|
||||
|
||||
#include <simgear/debug/logstream.hxx>
|
||||
#include <simgear/timing/timestamp.hxx>
|
||||
|
||||
|
@ -31,6 +31,7 @@
|
||||
#include <simgear/compiler.h>
|
||||
|
||||
#include <ctime>
|
||||
#include <cerrno>
|
||||
|
||||
#ifdef HAVE_SYS_TIMEB_H
|
||||
# include <sys/timeb.h> // for ftime() and struct timeb
|
||||
@ -44,7 +45,6 @@
|
||||
|
||||
#if defined(_POSIX_TIMERS) && (0 < _POSIX_TIMERS)
|
||||
# include <time.h>
|
||||
# include <errno.h>
|
||||
#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<DWORD>(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<int>(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<DWORD>(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<int>(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;
|
||||
|
@ -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
|
||||
*/
|
||||
|
@ -26,6 +26,10 @@
|
||||
*
|
||||
************************************************************************/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <simgear_config.h>
|
||||
#endif
|
||||
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
Loading…
Reference in New Issue
Block a user