Compare commits
18 Commits
version/20
...
version/20
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8dec1cb38c | ||
|
|
f25e95958a | ||
|
|
08108d9cf1 | ||
|
|
02cfd941c9 | ||
|
|
75b5a927c8 | ||
|
|
e4b58b65f3 | ||
|
|
b1334bf9a0 | ||
|
|
2a9767b568 | ||
|
|
29f6d06f1a | ||
|
|
fcd8ebb8a3 | ||
|
|
7a773f30e6 | ||
|
|
eb03782908 | ||
|
|
c79580d853 | ||
|
|
1b3c048363 | ||
|
|
01f689a0e4 | ||
|
|
b155f2e40f | ||
|
|
10ab8b830a | ||
|
|
8a4871db83 |
@@ -10,6 +10,15 @@ if(COMMAND cmake_policy)
|
||||
if(POLICY CMP0067)
|
||||
cmake_policy(SET CMP0067 NEW)
|
||||
endif()
|
||||
|
||||
# OpenGL VND policy : use the old definition for now, until we can audit this
|
||||
if(POLICY CMP0072)
|
||||
cmake_policy(SET CMP0072 OLD)
|
||||
endif()
|
||||
|
||||
if(POLICY CMP0093)
|
||||
cmake_policy(SET CMP0093 NEW)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
||||
@@ -216,7 +225,7 @@ if(${CMAKE_SYSTEM_NAME} MATCHES "Linux" OR ${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD
|
||||
endif()
|
||||
|
||||
find_package(Boost REQUIRED)
|
||||
set (BOOST_CXX_FLAGS "-DBOOST_BIMAP_DISABLE_SERIALIZATION")
|
||||
set (BOOST_CXX_FLAGS "-DBOOST_BIMAP_DISABLE_SERIALIZATION -DBOOST_NO_STDLIB_CONFIG")
|
||||
include(BoostTestTargets)
|
||||
|
||||
if(SIMGEAR_HEADLESS)
|
||||
|
||||
@@ -46,11 +46,17 @@ set(BOOST_TEST_TARGET_PREFIX "test")
|
||||
if(NOT Boost_FOUND)
|
||||
find_package(Boost 1.34.0 QUIET)
|
||||
endif()
|
||||
if("${Boost_VERSION}0" LESS "1034000")
|
||||
|
||||
if (NOT Boost_VERSION_MACRO)
|
||||
# Compatibility with pre CMP0093 (CMake 3.15)
|
||||
set(Boost_VERSION_MACRO ${Boost_VERSION})
|
||||
endif()
|
||||
|
||||
if("${Boost_VERSION_MACRO}0" LESS "1034000")
|
||||
set(_shared_msg
|
||||
"NOTE: boost::test-based targets and tests cannot "
|
||||
"be added: boost >= 1.34.0 required but not found. "
|
||||
"(found: '${Boost_VERSION}'; want >=103400) ")
|
||||
"(found: '${Boost_VERSION_MACRO}'; want >=103400) ")
|
||||
if(ENABLE_TESTS)
|
||||
message(FATAL_ERROR
|
||||
${_shared_msg}
|
||||
@@ -66,7 +72,7 @@ endif()
|
||||
include(GetForceIncludeDefinitions)
|
||||
include(CopyResourcesToBuildTree)
|
||||
|
||||
if(Boost_FOUND AND NOT "${Boost_VERSION}0" LESS "1034000")
|
||||
if(Boost_FOUND AND NOT "${Boost_VERSION_MACRO}0" LESS "1034000")
|
||||
set(_boosttesttargets_libs)
|
||||
set(_boostConfig "BoostTestTargetsIncluded.h")
|
||||
if(NOT Boost_UNIT_TEST_FRAMEWORK_LIBRARY)
|
||||
@@ -129,7 +135,7 @@ function(add_boost_test _name)
|
||||
"Syntax error in use of add_boost_test: at least one source file required!")
|
||||
endif()
|
||||
|
||||
if(Boost_FOUND AND NOT "${Boost_VERSION}0" LESS "1034000")
|
||||
if(Boost_FOUND AND NOT "${Boost_VERSION_MACRO}0" LESS "1034000")
|
||||
|
||||
include_directories(${Boost_INCLUDE_DIRS})
|
||||
|
||||
@@ -221,7 +227,7 @@ function(add_boost_test _name)
|
||||
set(_test_command ${_target_name})
|
||||
endif()
|
||||
|
||||
if(TESTS AND ( "${Boost_VERSION}" VERSION_GREATER "103799" ))
|
||||
if(TESTS AND ( "${Boost_VERSION_MACRO}" VERSION_GREATER "103799" ))
|
||||
foreach(_test ${TESTS})
|
||||
add_test(
|
||||
${_name}-${_test}
|
||||
|
||||
@@ -107,6 +107,8 @@ public:
|
||||
unsigned int bytesTransferred;
|
||||
unsigned int lastTransferRate;
|
||||
uint64_t totalBytesDownloaded;
|
||||
|
||||
SGPath tlsCertificatePath;
|
||||
};
|
||||
|
||||
Client::Client() :
|
||||
@@ -122,6 +124,8 @@ Client::Client() :
|
||||
d->maxPipelineDepth = 5;
|
||||
setUserAgent("SimGear-" SG_STRINGIZE(SIMGEAR_VERSION));
|
||||
|
||||
d->tlsCertificatePath = SGPath::fromEnv("SIMGEAR_TLS_CERT_PATH");
|
||||
|
||||
static bool didInitCurlGlobal = false;
|
||||
if (!didInitCurlGlobal) {
|
||||
curl_global_init(CURL_GLOBAL_ALL);
|
||||
@@ -275,6 +279,11 @@ void Client::makeRequest(const Request_ptr& r)
|
||||
|
||||
curl_easy_setopt(curlRequest, CURLOPT_FOLLOWLOCATION, 1);
|
||||
|
||||
if (!d->tlsCertificatePath.isNull()) {
|
||||
const auto utf8 = d->tlsCertificatePath.utf8Str();
|
||||
curl_easy_setopt(curlRequest, CURLOPT_CAINFO, utf8.c_str());
|
||||
}
|
||||
|
||||
if (!d->proxy.empty()) {
|
||||
curl_easy_setopt(curlRequest, CURLOPT_PROXY, d->proxy.c_str());
|
||||
curl_easy_setopt(curlRequest, CURLOPT_PROXYPORT, d->proxyPort);
|
||||
@@ -472,12 +481,26 @@ size_t Client::requestReadCallback(char *ptr, size_t size, size_t nmemb, void *u
|
||||
return actualBytes;
|
||||
}
|
||||
|
||||
bool isRedirectStatus(int code)
|
||||
{
|
||||
return ((code >= 300) && (code < 400));
|
||||
}
|
||||
|
||||
size_t Client::requestHeaderCallback(char *rawBuffer, size_t size, size_t nitems, void *userdata)
|
||||
{
|
||||
size_t byteSize = size * nitems;
|
||||
Request* req = static_cast<Request*>(userdata);
|
||||
std::string h = strutils::simplify(std::string(rawBuffer, byteSize));
|
||||
|
||||
if (req->readyState() >= HTTP::Request::HEADERS_RECEIVED) {
|
||||
// this can happen with chunked transfers (secondary chunks)
|
||||
// or redirects
|
||||
if (isRedirectStatus(req->responseCode())) {
|
||||
req->responseStart(h);
|
||||
return byteSize;
|
||||
}
|
||||
}
|
||||
|
||||
if (req->readyState() == HTTP::Request::OPENED) {
|
||||
req->responseStart(h);
|
||||
return byteSize;
|
||||
|
||||
@@ -328,6 +328,16 @@ unsigned int Request::responseLength() const
|
||||
return _responseLength;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void Request::setSuccess(int code)
|
||||
{
|
||||
_responseStatus = code;
|
||||
_responseReason.clear();
|
||||
if( !isComplete() ) {
|
||||
setReadyState(DONE);
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void Request::setFailure(int code, const std::string& reason)
|
||||
{
|
||||
|
||||
@@ -224,7 +224,7 @@ protected:
|
||||
virtual void onAlways();
|
||||
|
||||
void setFailure(int code, const std::string& reason);
|
||||
|
||||
void setSuccess(int code);
|
||||
private:
|
||||
friend class Client;
|
||||
friend class Connection;
|
||||
|
||||
@@ -273,7 +273,23 @@ public:
|
||||
d << "\r\n"; // final CRLF to terminate the headers
|
||||
d << contentStr;
|
||||
push(d.str().c_str());
|
||||
|
||||
} else if (path == "/test_redirect") {
|
||||
string contentStr("<html>See <a href=\"wibble\">Here</a></html>");
|
||||
stringstream d;
|
||||
d << "HTTP/1.1 " << 302 << " " << "Found" << "\r\n";
|
||||
d << "Location:" << " http://localhost:2000/was_redirected" << "\r\n";
|
||||
d << "Content-Length:" << contentStr.size() << "\r\n";
|
||||
d << "\r\n"; // final CRLF to terminate the headers
|
||||
d << contentStr;
|
||||
push(d.str().c_str());
|
||||
} else if (path == "/was_redirected") {
|
||||
string contentStr(BODY1);
|
||||
stringstream d;
|
||||
d << "HTTP/1.1 " << 200 << " " << reasonForCode(200) << "\r\n";
|
||||
d << "Content-Length:" << contentStr.size() << "\r\n";
|
||||
d << "\r\n"; // final CRLF to terminate the headers
|
||||
d << contentStr;
|
||||
push(d.str().c_str());
|
||||
} else {
|
||||
TestServerChannel::processRequestHeaders();
|
||||
}
|
||||
@@ -773,6 +789,24 @@ cout << "testing proxy close" << endl;
|
||||
SG_CHECK_EQUAL(tr2->bodyData, string(BODY1));
|
||||
SG_CHECK_EQUAL(tr2->responseBytesReceived(), strlen(BODY1));
|
||||
}
|
||||
|
||||
{
|
||||
cout << "redirect test" << endl;
|
||||
// redirect test
|
||||
testServer.disconnectAll();
|
||||
cl.clearAllConnections();
|
||||
|
||||
TestRequest* tr = new TestRequest("http://localhost:2000/test_redirect");
|
||||
HTTP::Request_ptr own(tr);
|
||||
cl.makeRequest(tr);
|
||||
|
||||
waitForComplete(&cl, tr);
|
||||
SG_CHECK_EQUAL(tr->responseCode(), 200);
|
||||
SG_CHECK_EQUAL(tr->responseReason(), string("OK"));
|
||||
SG_CHECK_EQUAL(tr->responseLength(), strlen(BODY1));
|
||||
SG_CHECK_EQUAL(tr->responseBytesReceived(), strlen(BODY1));
|
||||
SG_CHECK_EQUAL(tr->bodyData, string(BODY1));
|
||||
}
|
||||
|
||||
cout << "all tests passed ok" << endl;
|
||||
return EXIT_SUCCESS;
|
||||
|
||||
@@ -30,7 +30,6 @@ public:
|
||||
|
||||
virtual ~TestServerChannel()
|
||||
{
|
||||
std::cerr << "dtor test server channel" << std::endl;
|
||||
}
|
||||
|
||||
virtual void collectIncomingData(const char* s, int n)
|
||||
@@ -139,8 +138,8 @@ public:
|
||||
|
||||
void sendErrorResponse(int code, bool close, std::string content)
|
||||
{
|
||||
std::cerr << "sending error " << code << " for " << path << std::endl;
|
||||
std::cerr << "\tcontent:" << content << std::endl;
|
||||
// std::cerr << "sending error " << code << " for " << path << std::endl;
|
||||
// std::cerr << "\tcontent:" << content << std::endl;
|
||||
|
||||
std::stringstream headerData;
|
||||
headerData << "HTTP/1.1 " << code << " " << reasonForCode(code) << "\r\n";
|
||||
@@ -168,7 +167,6 @@ public:
|
||||
|
||||
virtual void handleClose (void)
|
||||
{
|
||||
std::cerr << "channel close" << std::endl;
|
||||
NetBufferChannel::handleClose();
|
||||
}
|
||||
|
||||
|
||||
@@ -635,7 +635,7 @@ void ArchiveExtractor::extractBytes(const uint8_t* bytes, size_t count)
|
||||
d.reset(new ZipExtractorPrivate(this));
|
||||
}
|
||||
else {
|
||||
SG_LOG(SG_IO, SG_ALERT, "Invcalid archive type");
|
||||
SG_LOG(SG_IO, SG_WARN, "Invalid archive type");
|
||||
_invalidDataType = true;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include "NasalString.hxx"
|
||||
|
||||
#include <cassert>
|
||||
#include <stdexcept> // for std::runtime_error
|
||||
|
||||
namespace nasal
|
||||
{
|
||||
|
||||
@@ -24,6 +24,11 @@
|
||||
|
||||
#include <simgear/structure/map.hxx>
|
||||
#include <boost/iterator/iterator_facade.hpp>
|
||||
#if BOOST_VERSION >= 105600
|
||||
#include <boost/core/enable_if.hpp>
|
||||
#else
|
||||
#include <boost/utility/enable_if.hpp>
|
||||
#endif
|
||||
|
||||
namespace nasal
|
||||
{
|
||||
|
||||
@@ -302,15 +302,18 @@ static char* dosprintf(char* f, ...)
|
||||
char* buf;
|
||||
va_list va;
|
||||
int olen, len = 16;
|
||||
va_start(va, f);
|
||||
while(1) {
|
||||
buf = naAlloc(len);
|
||||
va_start(va, f);
|
||||
olen = vsnprintf(buf, len, f, va);
|
||||
va_list vaCopy;
|
||||
va_copy(vaCopy, va);
|
||||
olen = vsnprintf(buf, len, f, vaCopy);
|
||||
if(olen >= 0 && olen < len) {
|
||||
va_end(va);
|
||||
va_end(vaCopy);
|
||||
return buf;
|
||||
}
|
||||
va_end(va);
|
||||
va_end(vaCopy);
|
||||
naFree(buf);
|
||||
len *= 2;
|
||||
}
|
||||
|
||||
@@ -18,8 +18,8 @@
|
||||
#include <simgear_config.h>
|
||||
#include <simgear/package/Install.hxx>
|
||||
|
||||
#include <boost/foreach.hpp>
|
||||
#include <fstream>
|
||||
#include <cstdlib>
|
||||
|
||||
#include <simgear/package/unzip.h>
|
||||
#include <simgear/package/md5.h>
|
||||
@@ -43,25 +43,21 @@ namespace pkg {
|
||||
class Install::PackageArchiveDownloader : public HTTP::Request
|
||||
{
|
||||
public:
|
||||
PackageArchiveDownloader(InstallRef aOwner) :
|
||||
PackageArchiveDownloader(InstallRef aOwner, const string_list& urls) :
|
||||
HTTP::Request("" /* dummy URL */),
|
||||
m_owner(aOwner)
|
||||
{
|
||||
m_urls = m_owner->package()->downloadUrls();
|
||||
if (m_urls.empty()) {
|
||||
throw sg_exception("no package download URLs");
|
||||
m_urls = urls;
|
||||
if (urls.empty()) {
|
||||
m_urls = m_owner->package()->downloadUrls();
|
||||
}
|
||||
|
||||
// if (m_owner->package()->properties()->hasChild("archive-type")) {
|
||||
// setArchiveTypeFromExtension(m_owner->package()->properties()->getStringValue("archive-type"));
|
||||
//}
|
||||
selectMirrorUrl();
|
||||
|
||||
// TODO randomise order of m_urls
|
||||
|
||||
m_extractPath = aOwner->path().dir();
|
||||
m_extractPath.append("_extract_" + aOwner->package()->md5());
|
||||
|
||||
// clean up any existing files
|
||||
// clean up any existing files (eg from previous failed download)
|
||||
Dir d(m_extractPath);
|
||||
if (d.exists()) {
|
||||
d.remove(true /* recursive */);
|
||||
@@ -93,36 +89,54 @@ public:
|
||||
return (m_downloaded * 100) / responseLength();
|
||||
}
|
||||
protected:
|
||||
virtual std::string url() const
|
||||
void selectMirrorUrl()
|
||||
{
|
||||
return m_urls.front();
|
||||
const int randomizedIndex = rand() % m_urls.size();
|
||||
m_activeURL = m_urls.at(randomizedIndex);
|
||||
m_urls.erase(m_urls.begin() + randomizedIndex);
|
||||
}
|
||||
|
||||
virtual std::string url() const override
|
||||
{
|
||||
return m_activeURL;
|
||||
}
|
||||
|
||||
virtual void responseHeadersComplete()
|
||||
void responseHeadersComplete() override
|
||||
{
|
||||
Request::responseHeadersComplete();
|
||||
|
||||
Dir d(m_extractPath);
|
||||
d.create(0755);
|
||||
if (!d.create(0755)) {
|
||||
SG_LOG(SG_GENERAL, SG_WARN, "Failed to create extraction directory" << d.path());
|
||||
}
|
||||
|
||||
m_extractor.reset(new ArchiveExtractor(m_extractPath));
|
||||
memset(&m_md5, 0, sizeof(SG_MD5_CTX));
|
||||
SG_MD5Init(&m_md5);
|
||||
}
|
||||
|
||||
virtual void gotBodyData(const char* s, int n)
|
||||
void gotBodyData(const char* s, int n) override
|
||||
{
|
||||
// if there's a pre-existing error, discard byte sinstead of pushing
|
||||
// more through the extactor
|
||||
if (m_extractor->hasError()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const uint8_t* ubytes = (uint8_t*) s;
|
||||
SG_MD5Update(&m_md5, ubytes, n);
|
||||
m_downloaded += n;
|
||||
m_owner->installProgress(m_downloaded, responseLength());
|
||||
m_extractor->extractBytes(ubytes, n);
|
||||
if (m_extractor->hasError()) {
|
||||
SG_LOG(SG_GENERAL, SG_WARN, "archive extraction failed (from " + m_activeURL + ")");
|
||||
}
|
||||
}
|
||||
|
||||
virtual void onDone()
|
||||
void onDone() override
|
||||
{
|
||||
if (responseCode() != 200) {
|
||||
SG_LOG(SG_GENERAL, SG_ALERT, "download failure:" << responseCode() <<
|
||||
SG_LOG(SG_GENERAL, SG_WARN, "download failure:" << responseCode() <<
|
||||
"\n\t" << url());
|
||||
Delegate::StatusCode code = Delegate::FAIL_DOWNLOAD;
|
||||
if (responseCode() == 404) {
|
||||
@@ -139,7 +153,7 @@ protected:
|
||||
strutils::encodeHex(digest, MD5_DIGEST_LENGTH);
|
||||
|
||||
if (hex_md5 != m_owner->package()->md5()) {
|
||||
SG_LOG(SG_GENERAL, SG_ALERT, "md5 verification failed:\n"
|
||||
SG_LOG(SG_GENERAL, SG_WARN, "md5 verification failed:\n"
|
||||
<< "\t" << hex_md5 << "\n\t"
|
||||
<< m_owner->package()->md5() << "\n\t"
|
||||
<< "downloading from:" << url());
|
||||
@@ -194,7 +208,7 @@ protected:
|
||||
m_owner->installResult(Delegate::STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
virtual void onFail()
|
||||
void onFail() override
|
||||
{
|
||||
if (responseCode() == -1) {
|
||||
doFailure(Delegate::USER_CANCELLED);
|
||||
@@ -210,14 +224,28 @@ private:
|
||||
if (dir.exists()) {
|
||||
dir.remove(true /* recursive */);
|
||||
}
|
||||
|
||||
const auto canRetry = (aReason == Delegate::FAIL_NOT_FOUND) ||
|
||||
(aReason == Delegate::FAIL_DOWNLOAD) || (aReason == Delegate::FAIL_CHECKSUM);
|
||||
|
||||
if (canRetry && !m_urls.empty()) {
|
||||
SG_LOG(SG_GENERAL, SG_WARN, "archive download failed from:" << m_activeURL
|
||||
<< "\n\twill retry with next mirror");
|
||||
// becuase selectMirrorUrl erased the active URL from m_urls,
|
||||
// this new request will select one of the other mirrors
|
||||
auto retryDownload = new PackageArchiveDownloader(m_owner, m_urls);
|
||||
m_owner->m_download.reset(retryDownload);
|
||||
m_owner->package()->catalog()->root()->makeHTTPRequest(retryDownload);
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO - try other mirrors
|
||||
m_owner->m_download.reset(); // ensure we get cleaned up
|
||||
m_owner->installResult(aReason);
|
||||
}
|
||||
|
||||
|
||||
InstallRef m_owner;
|
||||
string m_activeURL;
|
||||
string_list m_urls;
|
||||
SG_MD5_CTX m_md5;
|
||||
SGPath m_extractPath;
|
||||
@@ -281,7 +309,7 @@ void Install::startUpdate()
|
||||
return; // already active
|
||||
}
|
||||
|
||||
m_download = new PackageArchiveDownloader(this);
|
||||
m_download = new PackageArchiveDownloader(this, {});
|
||||
m_package->catalog()->root()->makeHTTPRequest(m_download);
|
||||
m_package->catalog()->root()->startInstall(this);
|
||||
}
|
||||
@@ -341,6 +369,7 @@ void Install::cancelDownload()
|
||||
}
|
||||
|
||||
m_package->catalog()->root()->cancelDownload(this);
|
||||
m_download.clear();
|
||||
}
|
||||
|
||||
SGPath Install::primarySetPath() const
|
||||
|
||||
@@ -122,14 +122,17 @@ void printPackageInfo(pkg::Package* pkg)
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
|
||||
sglog().setLogLevels( SG_ALL, SG_INFO );
|
||||
|
||||
HTTP::Client* http = new HTTP::Client();
|
||||
pkg::Root* root = new pkg::Root(Dir::current().path(), "");
|
||||
|
||||
|
||||
SGPath rootPath = SGPath::fromEnv("SG_PKG_ROOT", Dir::current().path());
|
||||
pkg::Root* root = new pkg::Root(rootPath, "2019.1.1");
|
||||
|
||||
MyDelegate dlg;
|
||||
root->addDelegate(&dlg);
|
||||
|
||||
cout << "Package root is:" << Dir::current().path() << endl;
|
||||
cout << "Package root is:" << rootPath << endl;
|
||||
cout << "have " << root->catalogs().size() << " catalog(s)" << endl;
|
||||
|
||||
root->setHTTPClient(http);
|
||||
|
||||
@@ -55,13 +55,18 @@ namespace boost {
|
||||
struct disable_if : public disable_if_c<Cond::value, T> {};
|
||||
}
|
||||
#else
|
||||
# include <boost/utility.hpp>
|
||||
# include <boost/type_traits/is_enum.hpp>
|
||||
#if BOOST_VERSION >= 105600
|
||||
#include <boost/core/enable_if.hpp>
|
||||
#else
|
||||
#include <boost/utility/enable_if.hpp>
|
||||
#endif
|
||||
|
||||
# include <simgear/debug/logstream.hxx>
|
||||
# include <simgear/math/SGMathFwd.hxx>
|
||||
# include <simgear/math/sg_types.hxx>
|
||||
#endif
|
||||
|
||||
#include <simgear/structure/SGReferenced.hxx>
|
||||
#include <simgear/structure/SGSharedPtr.hxx>
|
||||
|
||||
|
||||
@@ -136,11 +136,19 @@ osg::Vec2d eventToWindowCoords(const osgGA::GUIEventAdapter& ea)
|
||||
|
||||
virtual void update(double dt, int keyModState)
|
||||
{
|
||||
if (!_condition || _condition->test()) {
|
||||
SG_UNUSED(keyModState);
|
||||
if (!_repeatable)
|
||||
return;
|
||||
SG_UNUSED(keyModState);
|
||||
if (_condition && !_condition->test()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!_repeatable)
|
||||
return;
|
||||
|
||||
const bool zeroInterval = (_repeatInterval <= 0.0);
|
||||
if (zeroInterval) {
|
||||
// fire once per frame
|
||||
fireBindingList(_bindingsDown);
|
||||
} else {
|
||||
_repeatTime += dt;
|
||||
while (_repeatInterval < _repeatTime) {
|
||||
_repeatTime -= _repeatInterval;
|
||||
@@ -682,12 +690,18 @@ public:
|
||||
if (_hasDragged) {
|
||||
return;
|
||||
}
|
||||
|
||||
_repeatTime += dt;
|
||||
while (_repeatInterval < _repeatTime) {
|
||||
_repeatTime -= _repeatInterval;
|
||||
|
||||
const bool zeroInterval = (_repeatInterval <= 0.0);
|
||||
if (zeroInterval) {
|
||||
// fire once per frame
|
||||
fire(keyModState & osgGA::GUIEventAdapter::MODKEY_SHIFT, _direction);
|
||||
} // of repeat iteration
|
||||
} else {
|
||||
_repeatTime += dt;
|
||||
while (_repeatInterval < _repeatTime) {
|
||||
_repeatTime -= _repeatInterval;
|
||||
fire(keyModState & osgGA::GUIEventAdapter::MODKEY_SHIFT, _direction);
|
||||
} // of repeat iteration
|
||||
}
|
||||
}
|
||||
|
||||
virtual bool hover( const osg::Vec2d& windowPos,
|
||||
|
||||
@@ -353,10 +353,6 @@ void SGSampleGroup::update_sample_config( SGSoundSample *sample )
|
||||
velocity = sample->get_velocity();
|
||||
}
|
||||
|
||||
if (_smgr->bad_doppler_effect()) {
|
||||
velocity *= 100.0f;
|
||||
}
|
||||
|
||||
#if 0
|
||||
if (length(position) > 20000)
|
||||
printf("%s source and listener distance greater than 20km!\n",
|
||||
|
||||
@@ -50,6 +50,7 @@ using std::vector;
|
||||
|
||||
|
||||
#define MAX_SOURCES 128
|
||||
#define SPEED_OF_SOUND 340.4f
|
||||
|
||||
#ifndef ALC_ALL_DEVICES_SPECIFIER
|
||||
# define ALC_ALL_DEVICES_SPECIFIER 0x1013
|
||||
@@ -218,8 +219,8 @@ void SGSoundMgr::init()
|
||||
alListenerfv( AL_POSITION, SGVec3f::zeros().data() );
|
||||
alListenerfv( AL_VELOCITY, SGVec3f::zeros().data() );
|
||||
|
||||
alDopplerFactor(1.0);
|
||||
alDopplerVelocity(340.3); // speed of sound in meters per second.
|
||||
alDopplerFactor(1.0f);
|
||||
alDopplerVelocity(SPEED_OF_SOUND);
|
||||
|
||||
// gain = AL_REFERENCE_DISTANCE / (AL_REFERENCE_DISTANCE +
|
||||
// AL_ROLLOFF_FACTOR * (distance - AL_REFERENCE_DISTANCE));
|
||||
@@ -248,8 +249,10 @@ void SGSoundMgr::init()
|
||||
_renderer = (const char *)alGetString(AL_RENDERER);
|
||||
|
||||
if (_vendor == "Creative Labs Inc.") {
|
||||
alDopplerFactor(100.0f);
|
||||
_bad_doppler = true;
|
||||
} else if (_vendor == "OpenAL Community" && _renderer == "OpenAL Soft") {
|
||||
alDopplerFactor(100.0f);
|
||||
_bad_doppler = true;
|
||||
}
|
||||
|
||||
@@ -340,7 +343,7 @@ void SGSoundMgr::suspend()
|
||||
for ( auto current = d->_sample_groups.begin();
|
||||
current != d->_sample_groups.end(); ++current ) {
|
||||
SGSampleGroup *sgrp = current->second;
|
||||
sgrp->stop();
|
||||
sgrp->suspend();
|
||||
}
|
||||
_active = false;
|
||||
}
|
||||
@@ -392,14 +395,20 @@ if (isNaN(toVec3f(_velocity).data())) printf("NaN in listener velocity\n");
|
||||
SGVec3d velocity = SGVec3d::zeros();
|
||||
if ( _velocity[0] || _velocity[1] || _velocity[2] ) {
|
||||
velocity = hlOr.backTransform(_velocity*SG_FEET_TO_METER);
|
||||
}
|
||||
|
||||
if ( _bad_doppler ) {
|
||||
velocity *= 100.0f;
|
||||
if ( _bad_doppler ) {
|
||||
double fact = 100.0;
|
||||
double mag = length( velocity );
|
||||
|
||||
if (mag > SPEED_OF_SOUND) {
|
||||
fact *= SPEED_OF_SOUND / mag;
|
||||
}
|
||||
alDopplerFactor(fact);
|
||||
}
|
||||
}
|
||||
|
||||
alListenerfv( AL_VELOCITY, toVec3f(velocity).data() );
|
||||
// alDopplerVelocity(340.3); // TODO: altitude dependent
|
||||
// alDopplerVelocity(SPEED_OF_SOUND);
|
||||
testForError("update");
|
||||
_changed = false;
|
||||
}
|
||||
|
||||
@@ -83,6 +83,9 @@ SGXmlSound::~SGXmlSound()
|
||||
if (_sample)
|
||||
_sample->stop();
|
||||
|
||||
if (_sgrp && (_name != ""))
|
||||
_sgrp->remove(_name);
|
||||
|
||||
_volume.clear();
|
||||
_pitch.clear();
|
||||
}
|
||||
|
||||
@@ -22,7 +22,11 @@
|
||||
#include "SGSharedPtr.hxx"
|
||||
|
||||
#include <boost/type_traits/is_base_of.hpp>
|
||||
#if BOOST_VERSION >= 105600
|
||||
#include <boost/core/enable_if.hpp>
|
||||
#else
|
||||
#include <boost/utility/enable_if.hpp>
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# pragma warning(push)
|
||||
|
||||
Reference in New Issue
Block a user