]> git.mxchange.org Git - simgear.git/commitdiff
Use Boost singleton template for our singletons
authortimoore <timoore>
Wed, 10 Dec 2008 22:39:02 +0000 (22:39 +0000)
committertimoore <timoore>
Wed, 10 Dec 2008 22:39:02 +0000 (22:39 +0000)
acinclude.m4
configure.ac
simgear/scene/model/ModelRegistry.cxx
simgear/scene/model/ModelRegistry.hxx
simgear/scene/sky/newcloud.cxx
simgear/scene/tgdb/GroundLightManager.cxx
simgear/scene/tgdb/GroundLightManager.hxx
simgear/scene/util/StateAttributeFactory.cxx
simgear/scene/util/StateAttributeFactory.hxx
simgear/structure/Makefile.am
simgear/structure/Singleton.hxx [new file with mode: 0644]

index cf74b133f61581231e96bebbe89520a339440d96..af9004cb45e72d901eb8d0b3c164bdccfba2c408 100644 (file)
@@ -460,3 +460,227 @@ pushdef([AC_PROG_INSTALL],
     INSTALL_PROGRAM='${INSTALL} $(INSTALL_STRIP_FLAG)'
     INSTALL_SCRIPT='${INSTALL}'
 ])dnl
+
+# ===========================================================================
+#             http://autoconf-archive.cryp.to/ax_boost_base.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+#   AX_BOOST_BASE([MINIMUM-VERSION])
+#
+# DESCRIPTION
+#
+#   Test for the Boost C++ libraries of a particular version (or newer)
+#
+#   If no path to the installed boost library is given the macro searchs
+#   under /usr, /usr/local, /opt and /opt/local and evaluates the
+#   $BOOST_ROOT environment variable. Further documentation is available at
+#   <http://randspringer.de/boost/index.html>.
+#
+#   This macro calls:
+#
+#     AC_SUBST(BOOST_CPPFLAGS) / AC_SUBST(BOOST_LDFLAGS)
+#
+#   And sets:
+#
+#     HAVE_BOOST
+#
+# LAST MODIFICATION
+#
+#   2008-04-12
+#
+# COPYLEFT
+#
+#   Copyright (c) 2008 Thomas Porschberg <thomas@randspringer.de>
+#
+#   Copying and distribution of this file, with or without modification, are
+#   permitted in any medium without royalty provided the copyright notice
+#   and this notice are preserved.
+
+AC_DEFUN([AX_BOOST_BASE],
+[
+AC_ARG_WITH([boost],
+       AS_HELP_STRING([--with-boost@<:@=DIR@:>@], [use boost (default is yes) - it is possible to specify the root directory for boost (optional)]),
+       [
+    if test "$withval" = "no"; then
+               want_boost="no"
+    elif test "$withval" = "yes"; then
+        want_boost="yes"
+        ac_boost_path=""
+    else
+           want_boost="yes"
+        ac_boost_path="$withval"
+       fi
+    ],
+    [want_boost="yes"])
+
+
+AC_ARG_WITH([boost-libdir],
+        AS_HELP_STRING([--with-boost-libdir=LIB_DIR],
+        [Force given directory for boost libraries. Note that this will overwrite library path detection, so use this parameter only if default library detection fails and you know exactly where your boost libraries are located.]),
+        [
+        if test -d $withval
+        then
+                ac_boost_lib_path="$withval"
+        else
+                AC_MSG_ERROR(--with-boost-libdir expected directory name)
+        fi
+        ],
+        [ac_boost_lib_path=""]
+)
+
+if test "x$want_boost" = "xyes"; then
+       boost_lib_version_req=ifelse([$1], ,1.20.0,$1)
+       boost_lib_version_req_shorten=`expr $boost_lib_version_req : '\([[0-9]]*\.[[0-9]]*\)'`
+       boost_lib_version_req_major=`expr $boost_lib_version_req : '\([[0-9]]*\)'`
+       boost_lib_version_req_minor=`expr $boost_lib_version_req : '[[0-9]]*\.\([[0-9]]*\)'`
+       boost_lib_version_req_sub_minor=`expr $boost_lib_version_req : '[[0-9]]*\.[[0-9]]*\.\([[0-9]]*\)'`
+       if test "x$boost_lib_version_req_sub_minor" = "x" ; then
+               boost_lib_version_req_sub_minor="0"
+       fi
+       WANT_BOOST_VERSION=`expr $boost_lib_version_req_major \* 100000 \+  $boost_lib_version_req_minor \* 100 \+ $boost_lib_version_req_sub_minor`
+       AC_MSG_CHECKING(for boostlib >= $boost_lib_version_req)
+       succeeded=no
+
+       dnl first we check the system location for boost libraries
+       dnl this location ist chosen if boost libraries are installed with the --layout=system option
+       dnl or if you install boost with RPM
+       if test "$ac_boost_path" != ""; then
+               BOOST_LDFLAGS="-L$ac_boost_path/lib"
+               BOOST_CPPFLAGS="-I$ac_boost_path/include"
+       else
+               for ac_boost_path_tmp in /usr /usr/local /opt /opt/local ; do
+                       if test -d "$ac_boost_path_tmp/include/boost" && test -r "$ac_boost_path_tmp/include/boost"; then
+                               BOOST_LDFLAGS="-L$ac_boost_path_tmp/lib"
+                               BOOST_CPPFLAGS="-I$ac_boost_path_tmp/include"
+                               break;
+                       fi
+               done
+       fi
+
+    dnl overwrite ld flags if we have required special directory with
+    dnl --with-boost-libdir parameter
+    if test "$ac_boost_lib_path" != ""; then
+       BOOST_LDFLAGS="-L$ac_boost_lib_path"
+    fi
+
+       CPPFLAGS_SAVED="$CPPFLAGS"
+       CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS"
+       export CPPFLAGS
+
+       LDFLAGS_SAVED="$LDFLAGS"
+       LDFLAGS="$LDFLAGS $BOOST_LDFLAGS"
+       export LDFLAGS
+
+       AC_LANG_PUSH(C++)
+       AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+       @%:@include <boost/version.hpp>
+       ]], [[
+       #if BOOST_VERSION >= $WANT_BOOST_VERSION
+       // Everything is okay
+       #else
+       #  error Boost version is too old
+       #endif
+       ]])],[
+        AC_MSG_RESULT(yes)
+       succeeded=yes
+       found_system=yes
+               ],[
+               ])
+       AC_LANG_POP([C++])
+
+
+
+       dnl if we found no boost with system layout we search for boost libraries
+       dnl built and installed without the --layout=system option or for a staged(not installed) version
+       if test "x$succeeded" != "xyes"; then
+               _version=0
+               if test "$ac_boost_path" != ""; then
+                       if test -d "$ac_boost_path" && test -r "$ac_boost_path"; then
+                               for i in `ls -d $ac_boost_path/include/boost-* 2>/dev/null`; do
+                                       _version_tmp=`echo $i | sed "s#$ac_boost_path##" | sed 's/\/include\/boost-//' | sed 's/_/./'`
+                                       V_CHECK=`expr $_version_tmp \> $_version`
+                                       if test "$V_CHECK" = "1" ; then
+                                               _version=$_version_tmp
+                                       fi
+                                       VERSION_UNDERSCORE=`echo $_version | sed 's/\./_/'`
+                                       BOOST_CPPFLAGS="-I$ac_boost_path/include/boost-$VERSION_UNDERSCORE"
+                               done
+                       fi
+               else
+                       for ac_boost_path in /usr /usr/local /opt /opt/local ; do
+                               if test -d "$ac_boost_path" && test -r "$ac_boost_path"; then
+                                       for i in `ls -d $ac_boost_path/include/boost-* 2>/dev/null`; do
+                                               _version_tmp=`echo $i | sed "s#$ac_boost_path##" | sed 's/\/include\/boost-//' | sed 's/_/./'`
+                                               V_CHECK=`expr $_version_tmp \> $_version`
+                                               if test "$V_CHECK" = "1" ; then
+                                                       _version=$_version_tmp
+                                                       best_path=$ac_boost_path
+                                               fi
+                                       done
+                               fi
+                       done
+
+                       VERSION_UNDERSCORE=`echo $_version | sed 's/\./_/'`
+                       BOOST_CPPFLAGS="-I$best_path/include/boost-$VERSION_UNDERSCORE"
+            if test "$ac_boost_lib_path" = ""
+            then
+               BOOST_LDFLAGS="-L$best_path/lib"
+            fi
+
+                       if test "x$BOOST_ROOT" != "x"; then
+                               if test -d "$BOOST_ROOT" && test -r "$BOOST_ROOT" && test -d "$BOOST_ROOT/stage/lib" && test -r "$BOOST_ROOT/stage/lib"; then
+                                       version_dir=`expr //$BOOST_ROOT : '.*/\(.*\)'`
+                                       stage_version=`echo $version_dir | sed 's/boost_//' | sed 's/_/./g'`
+                                       stage_version_shorten=`expr $stage_version : '\([[0-9]]*\.[[0-9]]*\)'`
+                                       V_CHECK=`expr $stage_version_shorten \>\= $_version`
+                    if test "$V_CHECK" = "1" -a "$ac_boost_lib_path" = "" ; then
+                                               AC_MSG_NOTICE(We will use a staged boost library from $BOOST_ROOT)
+                                               BOOST_CPPFLAGS="-I$BOOST_ROOT"
+                                               BOOST_LDFLAGS="-L$BOOST_ROOT/stage/lib"
+                                       fi
+                               fi
+                       fi
+               fi
+
+               CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS"
+               export CPPFLAGS
+               LDFLAGS="$LDFLAGS $BOOST_LDFLAGS"
+               export LDFLAGS
+
+               AC_LANG_PUSH(C++)
+               AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+               @%:@include <boost/version.hpp>
+               ]], [[
+               #if BOOST_VERSION >= $WANT_BOOST_VERSION
+               // Everything is okay
+               #else
+               #  error Boost version is too old
+               #endif
+               ]])],[
+               AC_MSG_RESULT(yes)
+               succeeded=yes
+               found_system=yes
+                       ],[
+               ])
+               AC_LANG_POP([C++])
+       fi
+
+       if test "$succeeded" != "yes" ; then
+               if test "$_version" = "0" ; then
+                       AC_MSG_ERROR([[We could not detect the boost libraries (version $boost_lib_version_req_shorten or higher). If you have a staged boost library (still not installed) please specify \$BOOST_ROOT in your environment and do not give a PATH to --with-boost option.  If you are sure you have boost installed, then check your version number looking in <boost/version.hpp>. See http://randspringer.de/boost for more documentation.]])
+               else
+                       AC_MSG_NOTICE([Your boost libraries seems to old (version $_version).])
+               fi
+       else
+               AC_SUBST(BOOST_CPPFLAGS)
+               AC_SUBST(BOOST_LDFLAGS)
+               AC_DEFINE(HAVE_BOOST,,[define if the Boost library is available])
+       fi
+
+        CPPFLAGS="$CPPFLAGS_SAVED"
+               LDFLAGS="$LDFLAGS_SAVED"
+fi
+
+])
index 847828c31b7c2ea2ded52cbe9fb26f60e86d4915..cbe9a21ac0f24cbb054a359cdb3aabd2540fa760 100644 (file)
@@ -37,6 +37,11 @@ AC_PROG_CXX
 AC_PROG_RANLIB
 AC_PROG_INSTALL
 AC_PROG_LN_S
+AX_BOOST_BASE([1.34.0])
+
+if test "x$BOOST_CPPFLAGS" != "x-I/usr/include" ; then
+   CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS"
+fi
 
 dnl set the $host variable based on local machine/os
 AC_CANONICAL_HOST
@@ -398,6 +403,16 @@ if test "x$ac_cv_header_osg_Version" != "xyes"; then
     exit
 fi
 
+AC_CHECK_HEADER(boost/version.hpp)
+if test "x$ac_cv_header_boost_version_hpp" != "xyes"; then
+    echo
+    echo "You *must* have the Boost library installed on your system"
+    echo "to build this version of SimGear!"
+    echo
+    echo "configure aborted."
+    exit
+fi
+
 AC_LANG_POP
 
 dnl Check for system installed zlib
index 6b44a0555b2901bf7ae9505c2fb1f0f993f966c8..d20ce3ed61b302314559877dbff385cc1af83c56 100644 (file)
@@ -473,16 +473,6 @@ ModelRegistry::addNodeCallbackForExtension(const string& extension,
     nodeCallbackMap.insert(CallbackMap::value_type(extension, callback));
 }
 
-ref_ptr<ModelRegistry> ModelRegistry::instance;
-
-ModelRegistry* ModelRegistry::getInstance()
-
-{
-    if (!instance.valid())
-        instance = new ModelRegistry;
-    return instance.get();
-}
-
 ReaderWriter::ReadResult
 ModelRegistry::readNode(const string& fileName,
                         const ReaderWriter::Options* opt)
@@ -516,7 +506,7 @@ public:
     registry->setOptions(options);
     registry->getOrCreateSharedStateManager()->
       setShareMode(SharedStateManager::SHARE_STATESETS);
-    registry->setReadFileCallback(ModelRegistry::getInstance());
+    registry->setReadFileCallback(ModelRegistry::instance());
   }
 };
 
index 229f75578280ad82212b05f6e374a290625b9b26..7b7ffe4eb2b43b180c623e388035df76e5654211 100644 (file)
@@ -29,6 +29,7 @@
 #include <osgDB/Registry>
 
 #include <simgear/compiler.h>
+#include <simgear/structure/Singleton.hxx>
 
 #include <string>
 #include <map>
@@ -200,7 +201,8 @@ typedef ModelRegistryCallback<DefaultProcessPolicy, DefaultCachePolicy,
                               OSGSubstitutePolicy> DefaultCallback;
 
 // The manager for the callbacks
-class ModelRegistry : public osgDB::Registry::ReadFileCallback {
+class ModelRegistry : public osgDB::Registry::ReadFileCallback,
+                      public ReferencedSingleton<ModelRegistry> {
 public:
     ModelRegistry();
     virtual osgDB::ReaderWriter::ReadResult
@@ -215,10 +217,8 @@ public:
     void addNodeCallbackForExtension(const std::string& extension,
                                      osgDB::Registry::ReadFileCallback*
                                      callback);
-    static ModelRegistry* getInstance();
     virtual ~ModelRegistry() {}
 protected:
-    static osg::ref_ptr<ModelRegistry> instance;
     typedef std::map<std::string, osg::ref_ptr<osgDB::Registry::ReadFileCallback> >
     CallbackMap;
     CallbackMap imageCallbackMap;
@@ -243,7 +243,7 @@ class ModelRegistryCallbackProxy
 public:
     ModelRegistryCallbackProxy(std::string extension)
     {
-        ModelRegistry::getInstance()
+        ModelRegistry::instance()
             ->addNodeCallbackForExtension(extension, new T(extension));
     }
 };
index 62e75501917c15209d53477c222ec057ebfd57f7..3624a53cf7cd708310ac6c203ffa9c58b5bda7ae 100644 (file)
@@ -48,7 +48,9 @@
 #include <simgear/scene/util/SGUpdateVisitor.hxx>
 
 #include <algorithm>
+#include <osg/BlendFunc>
 #include <osg/GLU>
+#include <osg/ShadeModel>
 
 #include "cloudfield.hxx"
 #include "newcloud.hxx"
index 09309087bc9f01aae0365586e1f04b4b48f2f3f6..d500103bf6ff3c0116edaf64cbc0863182ab457e 100644 (file)
@@ -30,12 +30,6 @@ GroundLightManager::GroundLightManager()
     groundLightSS = makeLightSS();
 }
 
-GroundLightManager* GroundLightManager::instance()
-{
-    static ref_ptr<GroundLightManager> manager = new GroundLightManager;
-    return manager.get();
-}
-
 void GroundLightManager::update(const SGUpdateVisitor* updateVisitor)
 {
     osg::Fog* fog;
index f9bfdf792343102c659ab4ca9021490b9873cb1d..92130db0a4637e1c2571bceeebe9be74e4795d1f 100644 (file)
 #include <osg/Vec4>
 #include <osg/Referenced>
 #include <osg/StateSet>
+
+
+#include <simgear/structure/Singleton.hxx>
 #include <simgear/scene/util/SGUpdateVisitor.hxx>
 
 namespace simgear
 {
-class GroundLightManager : public osg::Referenced {
+class GroundLightManager : public ReferencedSingleton<GroundLightManager> {
 public:
     GroundLightManager();
     osg::StateSet* getRunwayLightStateSet() { return runwayLightSS.get(); }
@@ -36,7 +39,6 @@ public:
     // so use it.
     void update (const SGUpdateVisitor* updateVisitor);
     unsigned getLightNodeMask(const SGUpdateVisitor* updateVisitor);
-    static GroundLightManager* instance();
 protected:
     osg::ref_ptr<osg::StateSet> runwayLightSS;
     osg::ref_ptr<osg::StateSet> taxiLightSS;
index 902379606c859787f51dc636c9c375120e166dcb..43e09b9738ec569f6b41ecbd6fe5771753e88aca 100644 (file)
  * MA 02110-1301, USA.
  *
  */
+#include "StateAttributeFactory.hxx"
 
-#include <OpenThreads/ScopedLock>
+#include <osg/AlphaFunc>
+#include <osg/Array>
+#include <osg/BlendFunc>
+#include <osg/CullFace>
+#include <osg/ShadeModel>
+#include <osg/Texture2D>
+#include <osg/TexEnv>
 
 #include <osg/Image>
-#include "StateAttributeFactory.hxx"
 
 using namespace osg;
 
@@ -66,15 +72,4 @@ StateAttributeFactory::StateAttributeFactory()
     _cullFaceBack->setDataVariance(Object::STATIC);
 }
 
-osg::ref_ptr<StateAttributeFactory> StateAttributeFactory::_theInstance;
-OpenThreads::Mutex StateAttributeFactory::_instanceMutex;
-
-StateAttributeFactory* StateAttributeFactory::instance()
-{
-    OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_instanceMutex);
-    if (!_theInstance.valid()) {
-        _theInstance = new StateAttributeFactory;
-    }
-    return _theInstance.get();
-}
 }
index 0a7809dd74dacd8e073bec9605648e0b2714c597..9d55ebc0685467dbc55563381242b378eeea3a8c 100644 (file)
 
 #include <OpenThreads/Mutex>
 #include <osg/ref_ptr>
-#include <osg/AlphaFunc>
 #include <osg/Array>
-#include <osg/BlendFunc>
-#include <osg/CullFace>
-#include <osg/ShadeModel>
-#include <osg/Texture2D>
-#include <osg/TexEnv>
+
+namespace osg
+{
+class AlphaFunc;
+class BlendFunc;
+class CullFace;
+class ShadeModel;
+class Texture2D;
+class TexEnv;
+}
+
+#include <simgear/structure/Singleton.hxx>
 
 // Return read-only instances of common OSG state attributes.
 namespace simgear
 {
-class StateAttributeFactory : public osg::Referenced {
+class StateAttributeFactory :
+        public ReferencedSingleton<StateAttributeFactory> {
 public:
     // Alpha test > .01
     osg::AlphaFunc* getStandardAlphaFunc() { return _standardAlphaFunc.get(); }
@@ -52,10 +59,8 @@ public:
     // cull front and back facing polygons
     osg::CullFace* getCullFaceFront() { return _cullFaceFront.get(); }
     osg::CullFace* getCullFaceBack() { return _cullFaceBack.get(); }
-    
-    static StateAttributeFactory* instance();
+    StateAttributeFactory();    
 protected:
-    StateAttributeFactory();
     osg::ref_ptr<osg::AlphaFunc> _standardAlphaFunc;
     osg::ref_ptr<osg::ShadeModel> _smooth;
     osg::ref_ptr<osg::ShadeModel> _flat;
@@ -65,8 +70,6 @@ protected:
     osg::ref_ptr<osg::Vec4Array> _white;
     osg::ref_ptr<osg::CullFace> _cullFaceFront;
     osg::ref_ptr<osg::CullFace> _cullFaceBack;
-    static osg::ref_ptr<StateAttributeFactory> _theInstance;
-    static OpenThreads::Mutex _instanceMutex;
 };
 }
 #endif
index 17e2ff9ba73564503515697958aec0122bdae231..d0009177bbfc212b737a0fbcba7ee0aa550c1fa1 100644 (file)
@@ -16,7 +16,8 @@ include_HEADERS = \
        SGReferenced.hxx \
        SGSharedPtr.hxx \
        SGSmplhist.hxx \
-       SGSmplstat.hxx
+       SGSmplstat.hxx \
+       Singleton.hxx
 
 libsgstructure_a_SOURCES = \
        commands.cxx \
diff --git a/simgear/structure/Singleton.hxx b/simgear/structure/Singleton.hxx
new file mode 100644 (file)
index 0000000..0c3a594
--- /dev/null
@@ -0,0 +1,58 @@
+#ifndef SIMGEAR_SINGLETON_HXX
+#define SIMGEAR_SINGLETON_HXX 1
+
+#include <boost/pool/detail/singleton.hpp>
+
+#include <osg/Referenced>
+#include <osg/ref_ptr>
+
+namespace simgear
+{
+/**
+ * Class that supplies the address of a singleton instance. This class
+ * can be inherited by its Class argument in order to support the
+ * instance() method in that class.
+ */
+template <typename Class>
+class Singleton
+{
+protected:
+    Singleton() {}
+public:
+    static Class* instance()
+    {
+        Class& singleton
+            = boost::details::pool::singleton_default<Class>::instance();
+        return &singleton;
+    }
+};
+
+template <typename RefClass>
+class SingletonRefPtr
+{
+public:
+    SingletonRefPtr()
+    {
+        ptr = new RefClass;
+    }
+    static RefClass* instance()
+    {
+        SingletonRefPtr& singleton
+            = boost::details::pool::singleton_default<SingletonRefPtr>::instance();
+        return singleton.ptr.get();
+    }
+private:
+    osg::ref_ptr<RefClass> ptr;
+};
+
+template <typename RefClass>
+class ReferencedSingleton : public virtual osg::Referenced
+{
+public:
+    static RefClass* instance()
+    {
+        return SingletonRefPtr<RefClass>::instance();
+    }
+};
+}
+#endif