From 7086f2dc89d9fba66ed735e3f329853163d794e7 Mon Sep 17 00:00:00 2001 From: Erik Hofman Date: Mon, 28 Jun 2010 08:12:23 +0200 Subject: [PATCH 1/7] brehmt: When a sample's state constantly is "changed" (because sth. keeps updating the sample in each update loop), then SGSampleGroup::update never ever checked if the sample had already stopped playing by itself. The attached patch reorders the last two conditions. It now first checks if a sample has already stopped playing, before checking if there's sth to update. --- simgear/sound/sample_group.cxx | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/simgear/sound/sample_group.cxx b/simgear/sound/sample_group.cxx index e2a2b2c7..bc7605ac 100644 --- a/simgear/sound/sample_group.cxx +++ b/simgear/sound/sample_group.cxx @@ -103,6 +103,7 @@ void SGSampleGroup::update( double dt ) { } if ( result == AL_STOPPED ) { + sample->stop(); ALuint buffer = sample->get_buffer(); alDeleteBuffers( 1, &buffer ); testForALError("buffer remove"); @@ -157,17 +158,6 @@ void SGSampleGroup::update( double dt ) { // sadly, no free source available at this time } - } else if ( sample->is_valid_source() && sample->has_changed() ) { - if ( !sample->is_playing() ) { - // a request to stop playing the sound has been filed. - - sample->stop(); - sample->no_valid_source(); - _smgr->release_source( sample->get_source() ); - } else if ( _smgr->has_changed() ) { - update_sample_config( sample ); - } - } else if ( sample->is_valid_source() ) { // check if the sound has stopped by itself @@ -183,6 +173,18 @@ void SGSampleGroup::update( double dt ) { _smgr->release_buffer( sample ); remove( sample->get_sample_name() ); } + else + if ( sample->has_changed() ) { + if ( !sample->is_playing() ) { + // a request to stop playing the sound has been filed. + sample->stop(); + sample->no_valid_source(); + _smgr->release_source( sample->get_source() ); + } else if ( _smgr->has_changed() ) { + update_sample_config( sample ); + } + } + } testForALError("update"); } @@ -258,6 +260,7 @@ SGSampleGroup::stop () if ( sample->is_playing() ) { alSourceStop( source ); alSourcei( source, AL_BUFFER, 0 ); + sample->stop(); } _smgr->release_source( source ); sample->no_valid_source(); From b286e9d337721b41434f84d8ee348326d06865d7 Mon Sep 17 00:00:00 2001 From: James Turner Date: Thu, 8 Jul 2010 23:21:25 +0100 Subject: [PATCH 2/7] Add two more subsystem groups, to aid in fixing bug 141. --- simgear/structure/subsystem_mgr.hxx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/simgear/structure/subsystem_mgr.hxx b/simgear/structure/subsystem_mgr.hxx index 87654d9c..02332056 100644 --- a/simgear/structure/subsystem_mgr.hxx +++ b/simgear/structure/subsystem_mgr.hxx @@ -384,6 +384,8 @@ public: INIT = 0, GENERAL, FDM, ///< flight model, autopilot, instruments that run coupled + POST_FDM, ///< certain subsystems depend on FDM data + DISPLAY, ///< view, camera, rendering updates MAX_GROUPS }; From aa2ed5fb0cb16766f440231f23581bb90e9963d8 Mon Sep 17 00:00:00 2001 From: James Turner Date: Tue, 13 Jul 2010 13:07:35 +0100 Subject: [PATCH 3/7] Allow tasks to be removed from the EventManager by name. --- simgear/structure/event_mgr.cxx | 33 +++++++++++++++++++++++++++++++-- simgear/structure/event_mgr.hxx | 22 +++++++++++++--------- 2 files changed, 44 insertions(+), 11 deletions(-) diff --git a/simgear/structure/event_mgr.cxx b/simgear/structure/event_mgr.cxx index d4b573d0..6753a38f 100644 --- a/simgear/structure/event_mgr.cxx +++ b/simgear/structure/event_mgr.cxx @@ -1,8 +1,9 @@ #include "event_mgr.hxx" #include +#include -void SGEventMgr::add(SGCallback* cb, +void SGEventMgr::add(const std::string& name, SGCallback* cb, double interval, double delay, bool repeat, bool simtime) { @@ -16,7 +17,8 @@ void SGEventMgr::add(SGCallback* cb, t->mgr = this; t->repeat = repeat; t->simtime = simtime; - + t->name = name; + SGTimerQueue* q = simtime ? &_simQueue : &_rtQueue; q->insert(t, delay); @@ -43,6 +45,21 @@ void SGEventMgr::update(double delta_time_sec) _rtQueue.update(rt); } +void SGEventMgr::removeTask(const std::string& name) +{ + SGTimer* t = _simQueue.findByName(name); + if (t) { + _simQueue.remove(t); + } else if ((t = _rtQueue.findByName(name))) { + _rtQueue.remove(t); + } else { + SG_LOG(SG_GENERAL, SG_WARN, "removeTask: no task found with name:" << name); + return; + } + + delete t; +} + //////////////////////////////////////////////////////////////////////// // SGTimerQueue // This is the priority queue implementation: @@ -165,3 +182,15 @@ void SGTimerQueue::growArray() delete[] _table; _table = newTable; } + +SGTimer* SGTimerQueue::findByName(const std::string& name) const +{ + for (int i=0; i < _numEntries; ++i) { + if (_table[i].timer->name == name) { + return _table[i].timer; + } + } + + return NULL; +} + diff --git a/simgear/structure/event_mgr.hxx b/simgear/structure/event_mgr.hxx index 007321b8..5b31c809 100644 --- a/simgear/structure/event_mgr.hxx +++ b/simgear/structure/event_mgr.hxx @@ -9,6 +9,7 @@ class SGEventMgr; struct SGTimer { + std::string name; double interval; SGCallback* callback; SGEventMgr* mgr; @@ -33,6 +34,7 @@ public: SGTimer* nextTimer() { return _numEntries ? _table[0].timer : 0; } double nextTime() { return -_table[0].pri; } + SGTimer* findByName(const std::string& name) const; private: // The "priority" is stored as a negative time. This allows the // implemenetation to treat the "top" of the heap as the largest @@ -77,43 +79,45 @@ public: * ex: addTask("foo", &Function ... ) */ template - inline void addTask(const char* name, const FUNC& f, + inline void addTask(const std::string& name, const FUNC& f, double interval, double delay=0, bool sim=false) - { add(make_callback(f), interval, delay, true, sim); } + { add(name, make_callback(f), interval, delay, true, sim); } /** * Add a single function callback event as a one-shot event. * ex: addEvent("foo", &Function ... ) */ template - inline void addEvent(const char* name, const FUNC& f, + inline void addEvent(const std::string& name, const FUNC& f, double delay, bool sim=false) - { add(make_callback(f), 0, delay, false, sim); } + { add(name, make_callback(f), 0, delay, false, sim); } /** * Add a object/method pair as a repeating task. * ex: addTask("foo", &object, &ClassName::Method, ...) */ template - inline void addTask(const char* name, + inline void addTask(const std::string& name, const OBJ& o, METHOD m, double interval, double delay=0, bool sim=false) - { add(make_callback(o,m), interval, delay, true, sim); } + { add(name, make_callback(o,m), interval, delay, true, sim); } /** * Add a object/method pair as a repeating task. * ex: addEvent("foo", &object, &ClassName::Method, ...) */ template - inline void addEvent(const char* name, + inline void addEvent(const std::string& name, const OBJ& o, METHOD m, double delay, bool sim=false) - { add(make_callback(o,m), 0, delay, false, sim); } + { add(name, make_callback(o,m), 0, delay, false, sim); } + + void removeTask(const std::string& name); private: friend struct SGTimer; - void add(SGCallback* cb, + void add(const std::string& name, SGCallback* cb, double interval, double delay, bool repeat, bool simtime); From cb4716f40360d10faa7e50baa09a5e4e75a96694 Mon Sep 17 00:00:00 2001 From: James Turner Date: Thu, 15 Jul 2010 09:40:46 +0100 Subject: [PATCH 4/7] Initial work on simgear::Dir, replacement for PLIB ulDir functions. --- projects/VC90/SimGear.vcproj | 8 ++ simgear/misc/Makefile.am | 6 +- simgear/misc/sg_dir.cxx | 153 +++++++++++++++++++++++++++++++++++ simgear/misc/sg_dir.hxx | 62 ++++++++++++++ 4 files changed, 227 insertions(+), 2 deletions(-) create mode 100644 simgear/misc/sg_dir.cxx create mode 100644 simgear/misc/sg_dir.hxx diff --git a/projects/VC90/SimGear.vcproj b/projects/VC90/SimGear.vcproj index 30b7b85d..24484e8c 100644 --- a/projects/VC90/SimGear.vcproj +++ b/projects/VC90/SimGear.vcproj @@ -627,6 +627,14 @@ RelativePath="..\..\simgear\misc\sg_path.hxx" > + + + + diff --git a/simgear/misc/Makefile.am b/simgear/misc/Makefile.am index dd4e6e41..0e0fc949 100644 --- a/simgear/misc/Makefile.am +++ b/simgear/misc/Makefile.am @@ -12,7 +12,8 @@ include_HEADERS = \ zfstream.hxx \ interpolator.hxx \ stdint.hxx \ - PathOptions.hxx + PathOptions.hxx \ + sg_dir.hxx libsgmisc_a_SOURCES = \ sg_path.cxx \ @@ -22,7 +23,8 @@ libsgmisc_a_SOURCES = \ texcoord.cxx \ zfstream.cxx \ interpolator.cxx \ - PathOptions.cxx + PathOptions.cxx \ + sg_dir.cxx #noinst_PROGRAMS = tabbed_value_test swap_test diff --git a/simgear/misc/sg_dir.cxx b/simgear/misc/sg_dir.cxx new file mode 100644 index 00000000..e8775093 --- /dev/null +++ b/simgear/misc/sg_dir.cxx @@ -0,0 +1,153 @@ +// Written by James Turner, started July 2010. +// +// Copyright (C) 2010 Curtis L. Olson - http://www.flightgear.org/~curt +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +// $Id$ + + +#include + +#ifdef _WIN32 +# define WIN32_LEAN_AND_MEAN +# include +#else +# include +# include +#endif + +#include + +#include + +namespace simgear +{ + +Dir::Dir(const SGPath& path) : + _path(path) +{ +} + +Dir::Dir(const Dir& rel, const SGPath& relPath) : + _path(rel.file(relPath.str())) +{ +} + +PathList Dir::children(int types, const std::string& nameFilter) const +{ + PathList result; + if (types == 0) { + types = TYPE_FILE | TYPE_DIR | NO_DOT_OR_DOTDOT; + } + +#ifdef _WIN32 + std::string search(_path.str()); + if (nameFilter.empty()) { + search += "\\*"; // everything + } else { + search += "\\*" + nameFilter; + } + + WIN32_FIND_DATA fData; + HANDLE find = FindFirstFile(search.c_str(), &fData); + if (find == INVALID_HANDLE_VALUE) { + SG_LOG(SG_GENERAL, SG_WARN, "Dir::children: FindFirstFile failed:" << _path.str()); + return result; + } + + bool done = false; + for (bool done = false; !done; done = (FindNextFile(find, &fData) == 0)) { + if (fData.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) { + if (!(types & INCLUDE_HIDDEN)) { + continue; + } + } + + if (fData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { + if (!(types & TYPE_DIR)) { + continue; + } + } else if ((fData.dwFileAttributes & FILE_ATTRIBUTE_DEVICE) || + (fData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)) + { + continue; // always ignore device files + } else if (!(types & TYPE_FILE)) { + continue; + } + + result.push_back(file(fData.cFileName)); + } + + FindClose(find); +#else + DIR* dp = opendir(_path.c_str()); + if (!dp) { + SG_LOG(SG_GENERAL, SG_WARN, "Dir::children: opendir failed:" << _path.str()); + return result; + } + + while (true) { + struct dirent* entry = readdir(dp); + if (!entry) { + break; // done iteration + } + + // skip hidden files (names beginning with '.') unless requested + if (!(types & INCLUDE_HIDDEN) && (entry->d_name[0] == '.')) { + continue; + } + + if (entry->d_type == DT_DIR) { + if (!(types & TYPE_DIR)) { + continue; + } + + if (types & NO_DOT_OR_DOTDOT) { + if (!strcmp(entry->d_name, ".") || !strcmp(entry->d_name, "..")) { + continue; + } + } + } else if (entry->d_type == DT_REG) { + if (!(types & TYPE_FILE)) { + continue; + } + } else { + continue; // ignore char/block devices, fifos, etc + } + + if (!nameFilter.empty()) { + if (strstr(entry->d_name, nameFilter.c_str()) == NULL) { + continue; + } + } + + // passed all criteria, add to our result vector + result.push_back(file(entry->d_name)); + } + + closedir(dp); +#endif + return result; +} + +SGPath Dir::file(const std::string& name) const +{ + SGPath childPath = _path; + childPath.append(name); + return childPath; +} + +} // of namespace simgear diff --git a/simgear/misc/sg_dir.hxx b/simgear/misc/sg_dir.hxx new file mode 100644 index 00000000..5ff51c9c --- /dev/null +++ b/simgear/misc/sg_dir.hxx @@ -0,0 +1,62 @@ + +// 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_DIR_HXX +#define _SG_DIR_HXX + +#include + +#include +#include + +#include +#include + +namespace simgear +{ + typedef std::vector PathList; + + class Dir + { + public: + Dir(const SGPath& path); + Dir(const Dir& rel, const SGPath& relPath); + + enum FileTypes + { + TYPE_FILE = 1, + TYPE_DIR = 2, + NO_DOT_OR_DOTDOT = 1 << 12, + INCLUDE_HIDDEN = 1 << 13 + }; + + PathList children(int types = 0, const std::string& nameGlob = "") const; + + SGPath file(const std::string& name) const; + private: + mutable SGPath _path; + }; +} // of namespace simgear + +#endif // _SG_DIR_HXX + + From 3117ec5a7d34cbad4a446256ac53db5bd315f224 Mon Sep 17 00:00:00 2001 From: James Turner Date: Fri, 16 Jul 2010 08:40:07 +0100 Subject: [PATCH 5/7] Fix simgear::Dir compilation on some Unix setups, thanks Anders. --- simgear/misc/sg_dir.cxx | 1 + 1 file changed, 1 insertion(+) diff --git a/simgear/misc/sg_dir.cxx b/simgear/misc/sg_dir.cxx index e8775093..74b493ed 100644 --- a/simgear/misc/sg_dir.cxx +++ b/simgear/misc/sg_dir.cxx @@ -31,6 +31,7 @@ #include +#include #include namespace simgear From ed7361622bee8d67fea6e50ac21dff86d2dc092c Mon Sep 17 00:00:00 2001 From: Torsten Dreyer Date: Fri, 16 Jul 2010 18:19:56 +0200 Subject: [PATCH 6/7] Warning fix: unused variable in TextureBuilder.cxx --- simgear/scene/material/TextureBuilder.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/simgear/scene/material/TextureBuilder.cxx b/simgear/scene/material/TextureBuilder.cxx index d60e767d..9cf9cd4e 100644 --- a/simgear/scene/material/TextureBuilder.cxx +++ b/simgear/scene/material/TextureBuilder.cxx @@ -131,7 +131,7 @@ void TextureUnitBuilder::buildAttribute(Effect* effect, Pass* pass, texture = TextureBuilder::buildFromType(effect, type, prop, options); } - catch (BuilderException& e) { + catch (BuilderException& ) { SG_LOG(SG_INPUT, SG_ALERT, "No image file, " << "maybe the reader did not set the filename attribute, " << "using white on " << pass->getName()); From d2bcb86e1e6f2856c5509edb5c148b17fb3acd37 Mon Sep 17 00:00:00 2001 From: Torsten Dreyer Date: Fri, 16 Jul 2010 18:34:39 +0200 Subject: [PATCH 7/7] Warning fix: compare signed/unsigned --- simgear/scene/model/model.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/simgear/scene/model/model.cxx b/simgear/scene/model/model.cxx index 9d4d4172..648b670a 100644 --- a/simgear/scene/model/model.cxx +++ b/simgear/scene/model/model.cxx @@ -274,7 +274,7 @@ void MakeEffectVisitor::apply(osg::Geode& geode) ref_ptr userData = SGSceneUserData::getSceneUserData(&geode); if (userData.valid()) eg->setUserData(new SGSceneUserData(*userData)); - for (int i = 0; i < geode.getNumDrawables(); ++i) { + for (unsigned i = 0; i < geode.getNumDrawables(); ++i) { osg::Drawable *drawable = geode.getDrawable(i); eg->addDrawable(drawable);