00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include <algorithm>
00024 #include <iomanip>
00025 #include <fstream>
00026
00027
00028 #include <SDL.h>
00029
00030
00031
00032
00033
00034 #include "modules.h"
00035 #include "logger.h"
00036 #include "util/base/exception.h"
00037
00038
00039 struct ModuleInfo {
00040 logmodule_t module;
00041 logmodule_t parent;
00042 std::string name;
00043 };
00044 MODULE_INFO_RELATIONSHIPS
00045
00046
00047 namespace FIFE {
00048 LogManager* LogManager::m_instance = NULL;
00049
00050 Logger::Logger(logmodule_t module):
00051 m_module(module) {
00052 }
00053
00054 Logger::~Logger() {
00055 }
00056
00057 void Logger::log(LogManager::LogLevel level, const std::string& msg) {
00058 LogManager::instance()->log(level, m_module, msg);
00059 }
00060
00061 void Logger::log(LogManager::LogLevel level, const LMsg& msg) {
00062 LogManager::instance()->log(level, m_module, msg.str);
00063 }
00064
00065 LogManager* LogManager::instance() {
00066 if (!m_instance) {
00067 m_instance = new LogManager();
00068 }
00069 return m_instance;
00070 }
00071
00072 LogManager::~LogManager() {
00073 delete m_instance;
00074 }
00075
00076
00077 void LogManager::log(LogLevel level, logmodule_t module, const std::string& msg) {
00078 if (level < m_level) {
00079 return;
00080 }
00081 if (!isVisible(module)) {
00082 return;
00083 }
00084 std::string lvlstr = "";
00085 switch (level) {
00086 case LEVEL_DEBUG: lvlstr = "DEBUG";
00087 break;
00088
00089 case LEVEL_LOG: lvlstr = "LOG";
00090 break;
00091
00092 case LEVEL_WARN: lvlstr = "WARN";
00093 break;
00094
00095 case LEVEL_ERROR: lvlstr = "ERROR";
00096 break;
00097
00098 case LEVEL_PANIC: lvlstr = "PANIC";
00099 break;
00100
00101 default: lvlstr = "ERROR";
00102 break;
00103 }
00104 if (m_logtoprompt) {
00105 std::cout << moduleInfos[module].name << ":" << lvlstr << ":" << msg << std::endl;
00106 }
00107 if (m_logtofile) {
00108 *m_logfile << moduleInfos[module].name << ":" << lvlstr << ":" << msg << std::endl;
00109 }
00110 if (level == LEVEL_PANIC) {
00111 abort();
00112 }
00113 }
00114
00115 void LogManager::setLevelFilter(LogLevel level) {
00116 m_level = level;
00117 }
00118
00119 LogManager::LogLevel LogManager::getLevelFilter() {
00120 return m_level;
00121 }
00122
00123 void LogManager::addVisibleModule(logmodule_t module) {
00124 validateModule(module);
00125 int32_t ind = static_cast<int32_t>(module);
00126 m_modules[ind] = true;
00127 if (moduleInfos[ind].parent != LM_CORE) {
00128 addVisibleModule(moduleInfos[ind].parent);
00129 }
00130 }
00131
00132 void LogManager::removeVisibleModule(logmodule_t module) {
00133 validateModule(module);
00134 m_modules[module] = false;
00135 }
00136
00137 void LogManager::clearVisibleModules() {
00138 for (int32_t i = 0; i < LM_MODULE_MAX; i++) {
00139 m_modules[i] = false;
00140 }
00141 }
00142
00143 void LogManager::setLogToPrompt(bool log_to_promt) {
00144 m_logtoprompt = log_to_promt;
00145 }
00146
00147 bool LogManager::isLoggingToPrompt() {
00148 return m_logtoprompt;
00149 }
00150
00151 void LogManager::setLogToFile(bool logtofile) {
00152 if(logtofile){
00153 m_logfile = new std::ofstream("fife.log");
00154 }
00155 else {
00156 if (m_logfile){
00157 delete m_logfile;
00158 }
00159 }
00160 m_logtofile = logtofile;
00161 }
00162
00163 bool LogManager::isLoggingToFile() {
00164 return m_logtofile;
00165 }
00166
00167 bool LogManager::isVisible(logmodule_t module) {
00168 if (!m_modules[module]) {
00169 return false;
00170 }
00171 if (moduleInfos[module].parent != LM_CORE) {
00172 return isVisible(moduleInfos[module].parent);
00173 }
00174 return true;
00175 }
00176
00177 LogManager::LogManager():
00178 m_level(LEVEL_DEBUG),
00179 module_check_stack(),
00180 m_logtofile(false),
00181 m_logtoprompt(false) {
00182 validateModuleDescription(LM_CORE);
00183 m_logfile = 0;
00184 clearVisibleModules();
00185 }
00186
00187 void LogManager::validateModule(logmodule_t m) {
00188 if ((m <= LM_CORE) || (m >= LM_MODULE_MAX)) {
00189 std::cout << "Invalid module received in LogManager: " << m << ", aborting\n";
00190 abort();
00191 }
00192 }
00193
00194 void LogManager::validateModuleDescription(logmodule_t module) {
00195 if (module == LM_CORE) {
00196 for (int32_t m = static_cast<int32_t>(LM_CORE)+1; m < static_cast<int32_t>(LM_MODULE_MAX); m++) {
00197 if (moduleInfos[m].module != static_cast<logmodule_t>(m)) {
00198 std::ostringstream stream;
00199 stream << m;
00200 std::string msg = "Log module definition ids do not match in index ";
00201 msg += stream.str();
00202 std::cout << msg << std::endl;
00203 throw InvalidFormat(msg);
00204 }
00205 module_check_stack.clear();
00206 validateModuleDescription(static_cast<logmodule_t>(m));
00207 }
00208 } else {
00209 module_check_stack.push_back(module);
00210 if (count(module_check_stack.begin(), module_check_stack.end(), module) > 1) {
00211 throw InvalidFormat("Log module definition hierarchy contains cycles");
00212 }
00213 }
00214 }
00215
00216 std::string LogManager::getModuleName(logmodule_t module) {
00217 return moduleInfos[module].name;
00218 }
00219 }