singletonmodule.h

Go to the documentation of this file.
00001 /*
00002  Copyright (C) 2001-2006, William Joseph.
00003  All Rights Reserved.
00004 
00005  This file is part of GtkRadiant.
00006 
00007  GtkRadiant is free software; you can redistribute it and/or modify
00008  it under the terms of the GNU General Public License as published by
00009  the Free Software Foundation; either version 2 of the License, or
00010  (at your option) any later version.
00011 
00012  GtkRadiant is distributed in the hope that it will be useful,
00013  but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  GNU General Public License for more details.
00016 
00017  You should have received a copy of the GNU General Public License
00018  along with GtkRadiant; if not, write to the Free Software
00019  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00020  */
00021 
00022 #if !defined(INCLUDED_MODULESYSTEM_SINGLETONMODULE_H)
00023 #define INCLUDED_MODULESYSTEM_SINGLETONMODULE_H
00024 
00025 #include "modulesystem.h"
00026 #include <cstddef>
00027 #include "debugging/debugging.h"
00028 #include "modulesystem/moduleregistry.h"
00029 #include "generic/reference.h"
00030 
00031 template<typename API, typename Dependencies>
00032 class DefaultAPIConstructor
00033 {
00034     public:
00035         const char* getName ()
00036         {
00037             return typename API::Name();
00038         }
00039 
00040         API* constructAPI (Dependencies& dependencies)
00041         {
00042             return new API;
00043         }
00044         void destroyAPI (API* api)
00045         {
00046             delete api;
00047         }
00048 };
00049 
00050 template<typename API, typename Dependencies>
00051 class DependenciesAPIConstructor
00052 {
00053     public:
00054         const char* getName ()
00055         {
00056             return typename API::Name();
00057         }
00058 
00059         API* constructAPI (Dependencies& dependencies)
00060         {
00061             return new API(dependencies);
00062         }
00063         void destroyAPI (API* api)
00064         {
00065             delete api;
00066         }
00067 };
00068 
00069 class NullDependencies
00070 {
00071 };
00072 
00073 template<typename API, typename Dependencies = NullDependencies, typename APIConstructor = DefaultAPIConstructor<API,
00074         Dependencies> >
00075 class SingletonModule: public APIConstructor, public Module, public ModuleRegisterable
00076 {
00077         Dependencies* m_dependencies;
00078         API* m_api;
00079         std::size_t m_refcount;
00080         bool m_dependencyCheck;
00081         bool m_cycleCheck;
00082     public:
00083         typedef typename API::Type Type;
00084 
00085         SingletonModule () :
00086             m_dependencies(0), m_api(0), m_refcount(0), m_dependencyCheck(false), m_cycleCheck(false)
00087         {
00088         }
00089         explicit SingletonModule (const APIConstructor& constructor) :
00090             APIConstructor(constructor), m_dependencies(0), m_api(0), m_refcount(0), m_dependencyCheck(false),
00091                     m_cycleCheck(false)
00092         {
00093         }
00094         virtual ~SingletonModule ()
00095         {
00096             ASSERT_MESSAGE(m_refcount == 0, "module still referenced at shutdown");
00097         }
00098 
00099         void selfRegister ()
00100         {
00101             globalModuleServer().registerModule(typename Type::Name(), typename Type::Version(),
00102                     APIConstructor::getName(), *this);
00103         }
00104 
00105         Dependencies& getDependencies ()
00106         {
00107             return *m_dependencies;
00108         }
00109         void* getTable ()
00110         {
00111             if (m_api != 0) {
00112                 return m_api->getTable();
00113             }
00114             return 0;
00115         }
00116         void capture ()
00117         {
00118             if (++m_refcount == 1) {
00119                 globalOutputStream() << "Module Initialising: '" << typename Type::Name() << "' '"
00120                         << APIConstructor::getName() << "'\n";
00121                 m_dependencies = new Dependencies();
00122                 m_dependencyCheck = !globalModuleServer().getError();
00123                 if (m_dependencyCheck) {
00124                     m_api = APIConstructor::constructAPI(*m_dependencies);
00125                     globalOutputStream() << "Module Ready: '" << typename Type::Name() << "' '"
00126                             << APIConstructor::getName() << "'\n";
00127                 } else {
00128                     globalOutputStream() << "Module Dependencies Failed: '" << typename Type::Name() << "' '"
00129                             << APIConstructor::getName() << "'\n";
00130                 }
00131                 m_cycleCheck = true;
00132             }
00133 
00134             ASSERT_MESSAGE(m_cycleCheck, "cyclic dependency detected");
00135         }
00136         void release ()
00137         {
00138             if (--m_refcount == 0) {
00139                 if (m_dependencyCheck) {
00140                     APIConstructor::destroyAPI(m_api);
00141                 }
00142                 delete m_dependencies;
00143             }
00144         }
00145 };
00146 
00147 #endif

Generated by  doxygen 1.6.2