Merge branch 'next' of git://gitorious.org/fg/simgear into next

This commit is contained in:
Erik Hofman 2011-10-30 10:40:00 +01:00
commit 110753e92c
66 changed files with 891 additions and 468 deletions

View File

@ -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)

View File

@ -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"
>

View File

@ -7,6 +7,7 @@ set(HLA_HEADERS
HLABasicDataElement.hxx
HLABasicDataType.hxx
HLADataElement.hxx
HLADataElementVisitor.hxx
HLADataType.hxx
HLADataTypeVisitor.hxx
HLAEnumeratedDataElement.hxx

View File

@ -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)
{

View File

@ -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;

View File

@ -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
{

View File

@ -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); \
\

View File

@ -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)
{

View File

@ -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;

View 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

View File

@ -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)
{

View File

@ -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;

View File

@ -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)
{

View File

@ -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;

View File

@ -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
{

View File

@ -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);

View File

@ -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)
{

View File

@ -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;

View File

@ -11,6 +11,7 @@ libsghla_a_HEADERS = \
HLABasicDataElement.hxx \
HLABasicDataType.hxx \
HLADataElement.hxx \
HLADataElementVisitor.hxx \
HLADataType.hxx \
HLADataTypeVisitor.hxx \
HLAEnumeratedDataElement.hxx \

View File

@ -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;

View File

@ -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) {

View File

@ -73,6 +73,6 @@ bool SGIOChannel::close() {
// dummy eof routine
bool SGIOChannel::eof() {
bool SGIOChannel::eof() const {
return false;
}

View File

@ -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; }

View File

@ -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; };
};

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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>

View File

@ -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();

View File

@ -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 "";

View File

@ -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.

View File

@ -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

View File

@ -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

View File

@ -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);
}

View File

@ -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();

View File

@ -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);

View File

@ -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),

View File

@ -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

View File

@ -1,3 +1,6 @@
#ifdef HAVE_CONFIG_H
# include <simgear_config.h>
#endif
#include <simgear/compiler.h>

View File

@ -3,6 +3,10 @@
// Test harness.
////////////////////////////////////////////////////////////////////////
#ifdef HAVE_CONFIG_H
# include <simgear_config.h>
#endif
#include <simgear/compiler.h>
#include <iostream>

View File

@ -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();
}

View File

@ -102,4 +102,14 @@ namespace effect
{
const char* colorFields[] = {"red", "green", "blue", "alpha"};
}
PassAttributeBuilder::~PassAttributeBuilder()
{
}
} // of namespace simgear

View File

@ -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)

View File

@ -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);

View File

@ -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

View File

@ -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();

View File

@ -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;
}

View File

@ -86,4 +86,10 @@ StateAttributeFactory::StateAttributeFactory()
_depthWritesDisabled->setDataVariance(Object::STATIC);
}
// anchor the destructor into this file, to avoid ref_ptr warnings
StateAttributeFactory::~StateAttributeFactory()
{
}
}

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -82,7 +82,7 @@ public:
/**
* Destructor
*/
~SGSoundSample ();
virtual ~SGSoundSample ();
/**
* Detect wheter this audio sample holds the information of a sound file.

View 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

View 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
@ -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;

View File

@ -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

View File

@ -1,3 +1,7 @@
#ifdef HAVE_CONFIG_H
# include <simgear_config.h>
#endif
#include "event_mgr.hxx"
#include <simgear/math/SGMath.hxx>

View File

@ -18,6 +18,10 @@
//
// $Id$
#ifdef HAVE_CONFIG_H
# include <simgear_config.h>
#endif
#include <simgear/debug/logstream.hxx>
#include <simgear/timing/timestamp.hxx>

View File

@ -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(&current, &tz);
gettimeofday(&current, 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;

View File

@ -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
*/

View File

@ -26,6 +26,10 @@
*
************************************************************************/
#ifdef HAVE_CONFIG_H
# include <simgear_config.h>
#endif
#include <errno.h>
#include <string.h>
#include <stdio.h>