sdl_keeper.cpp
00001 00002 /*************************************************************************** 00003 * sdl_keeper.cpp - utility to keep track of SDL initialization state 00004 * 00005 * Created: Mon Nov 05 14:34:36 2007 00006 * Copyright 2007 Tim Niemueller [www.niemueller.de] 00007 * 00008 ****************************************************************************/ 00009 00010 /* This program is free software; you can redistribute it and/or modify 00011 * it under the terms of the GNU General Public License as published by 00012 * the Free Software Foundation; either version 2 of the License, or 00013 * (at your option) any later version. A runtime exception applies to 00014 * this software (see LICENSE.GPL_WRE file mentioned below for details). 00015 * 00016 * This program is distributed in the hope that it will be useful, 00017 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00019 * GNU Library General Public License for more details. 00020 * 00021 * Read the full text in the LICENSE.GPL_WRE file in the doc directory. 00022 */ 00023 00024 #include <fvwidgets/sdl_keeper.h> 00025 00026 #include <core/threading/mutex.h> 00027 #include <core/threading/mutex_locker.h> 00028 #include <core/exception.h> 00029 00030 #include <SDL.h> 00031 00032 using namespace fawkes; 00033 00034 unsigned int SDLKeeper::_refcount = 0; 00035 Mutex SDLKeeper::_mutex; 00036 00037 00038 /** @class SDLKeeper <fvwidgets/sdl_keeper.h> 00039 * SDL Reference keeper. 00040 * 00041 * Use this keeper to initialize and quit the SDL library. As there may be many 00042 * modules using the SDL a central place for reference counting is needed. 00043 * 00044 * @author Tim Niemueller 00045 */ 00046 00047 /** Private inaccessible constructor. */ 00048 SDLKeeper::SDLKeeper() 00049 { 00050 } 00051 00052 00053 /** Init SDL. 00054 * Keeps track of SDL_Init calls and only calls SDL_InitSubSystem on consecutive 00055 * calls. 00056 * @param flags Same flags as for SDL_Init 00057 */ 00058 void 00059 SDLKeeper::init(unsigned int flags) 00060 { 00061 MutexLocker lock(&_mutex); 00062 00063 unsigned int alive_subsys = SDL_WasInit(SDL_INIT_EVERYTHING); 00064 if ( (alive_subsys & flags) != flags ) { 00065 // Subsystem has not been initialized, yet 00066 if ( _refcount == 0 ) { 00067 if ( SDL_Init(flags) != 0 ) { 00068 throw Exception("SDL: initialization failed"); 00069 } 00070 } else { 00071 unsigned int still_to_init = ~alive_subsys & flags; 00072 if ( SDL_Init(still_to_init) != 0 ) { 00073 throw Exception("SDL: initialization failed"); 00074 } 00075 } 00076 } 00077 00078 ++_refcount; 00079 } 00080 00081 00082 /** Conditionally quit SDL. 00083 * Use this after you are done with the SDL. No subsystem will be closed after all 00084 * users of SDL quit the usage. Then the whole SDL will be released at once. 00085 */ 00086 void 00087 SDLKeeper::quit() throw() 00088 { 00089 MutexLocker lock(&_mutex); 00090 00091 if ( (_refcount > 0) && (--_refcount == 0) ) { 00092 SDL_Quit(); 00093 } 00094 } 00095 00096 00097 /** Force quit of SDL. 00098 * This will quit the SDL no matter of the reference count. Use with extreme care. 00099 */ 00100 void 00101 SDLKeeper::force_quit() 00102 { 00103 MutexLocker lock(&_mutex); 00104 00105 SDL_Quit(); 00106 _refcount = 0; 00107 }

