00001 //////////////////////////////////////////////////////////////////////////////// 00002 // Scorched3D (c) 2000-2009 00003 // 00004 // This file is part of Scorched3D. 00005 // 00006 // Scorched3D is free software; you can redistribute it and/or modify 00007 // it under the terms of the GNU General Public License as published by 00008 // the Free Software Foundation; either version 2 of the License, or 00009 // (at your option) any later version. 00010 // 00011 // Scorched3D is distributed in the hope that it will be useful, 00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 // GNU General Public License for more details. 00015 // 00016 // You should have received a copy of the GNU General Public License 00017 // along with Scorched3D; if not, write to the Free Software 00018 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00019 //////////////////////////////////////////////////////////////////////////////// 00020 00021 #include <common/Defines.h> 00022 #include <common/Logger.h> 00023 #include <common/LoggerI.h> 00024 #include <SDL/SDL.h> 00025 #include <SDL/SDL_thread.h> 00026 #include <time.h> 00027 #include <stdio.h> 00028 #include <stdarg.h> 00029 #include <algorithm> 00030 00031 // ************************************************ 00032 // NOTE: This logger is and needs to be thread safe 00033 // ************************************************ 00034 00035 static SDL_mutex *logMutex_ = 0; 00036 static Uint32 threadId = (Uint32) -1; 00037 Logger * Logger::instance_ = 0; 00038 00039 Logger * Logger::instance() 00040 { 00041 if (!instance_) 00042 { 00043 instance_ = new Logger; 00044 } 00045 return instance_; 00046 } 00047 00048 Logger::Logger() 00049 { 00050 if (!logMutex_) logMutex_ = SDL_CreateMutex(); 00051 } 00052 00053 Logger::~Logger() 00054 { 00055 } 00056 00057 void Logger::addLogger(LoggerI *logger) 00058 { 00059 Logger::instance(); 00060 SDL_LockMutex(logMutex_); 00061 Logger::instance()->loggers_.push_back(logger); 00062 SDL_UnlockMutex(logMutex_); 00063 } 00064 00065 void Logger::remLogger(LoggerI *logger) 00066 { 00067 Logger::instance(); 00068 std::list<LoggerI *>::iterator itor; 00069 SDL_LockMutex(logMutex_); 00070 itor = Logger::instance()->loggers_.begin(); 00071 while(itor != Logger::instance()->loggers_.end()) { 00072 if (*itor == logger) { 00073 Logger::instance()->loggers_.erase(itor); 00074 break; 00075 } 00076 itor++; 00077 } 00078 SDL_UnlockMutex(logMutex_); 00079 } 00080 00081 void Logger::log(const std::string &text) 00082 { 00083 log(text.c_str()); 00084 } 00085 00086 void Logger::log(const char *text) 00087 { 00088 if (!text) return; 00089 00090 Logger::instance(); 00091 00092 SDL_LockMutex(logMutex_); 00093 00094 LoggerInfo info; 00095 info.setMessage(text); 00096 addLog(info); 00097 00098 SDL_UnlockMutex(logMutex_); 00099 00100 if (SDL_ThreadID() == threadId) 00101 { 00102 processLogEntries(); 00103 } 00104 } 00105 00106 void Logger::log(const LoggerInfo &info) 00107 { 00108 Logger::instance(); 00109 00110 SDL_LockMutex(logMutex_); 00111 addLog((LoggerInfo &) info); 00112 SDL_UnlockMutex(logMutex_); 00113 } 00114 00115 void Logger::addLog(LoggerInfo &info) 00116 { 00117 // Add the time to the beginning of the log message 00118 info.setTime(); 00119 00120 // Add single or multiple lines 00121 char *found = (char *) strchr(info.getMessage(), '\n'); 00122 char *start = (char *) info.getMessage(); 00123 if (found) 00124 { 00125 while (found) 00126 { 00127 *found = '\0'; 00128 LoggerInfo *newInfo = new LoggerInfo(info); 00129 newInfo->setMessage(start); 00130 instance_->entries_.push_back(newInfo); 00131 start = found; 00132 start++; 00133 00134 found = strchr(start, '\n'); 00135 00136 /*if (SDL_ThreadID() == threadId) 00137 { 00138 processLogEntries(); 00139 }*/ 00140 } 00141 if (start[0] != '\0') 00142 { 00143 LoggerInfo *newInfo = new LoggerInfo(info); 00144 newInfo->setMessage(start); 00145 instance_->entries_.push_back(newInfo); 00146 } 00147 } 00148 else 00149 { 00150 instance_->entries_.push_back( 00151 new LoggerInfo(info)); 00152 } 00153 } 00154 00155 void Logger::processLogEntries() 00156 { 00157 if (threadId == (Uint32) -1) 00158 { 00159 threadId = SDL_ThreadID(); 00160 } 00161 00162 Logger::instance(); 00163 00164 SDL_LockMutex(logMutex_); 00165 std::list<LoggerInfo *> &entries = Logger::instance()->entries_; 00166 while (!entries.empty()) 00167 { 00168 LoggerInfo *firstEntry = entries.front(); 00169 00170 std::list<LoggerI *> &loggers = Logger::instance()->loggers_; 00171 std::list<LoggerI *>::iterator logItor; 00172 for (logItor = loggers.begin(); 00173 logItor != loggers.end(); 00174 logItor++) 00175 { 00176 LoggerI *log = (*logItor); 00177 log->logMessage(*firstEntry); 00178 } 00179 00180 entries.pop_front(); 00181 delete firstEntry; 00182 } 00183 SDL_UnlockMutex(logMutex_); 00184 } 00185
1.5.3