diff options
Diffstat (limited to 'src/Common')
-rw-r--r-- | src/Common/ConfigManager.cpp | 20 | ||||
-rw-r--r-- | src/Common/ConfigManager.h | 3 | ||||
-rw-r--r-- | src/Common/Logger.cpp | 53 | ||||
-rw-r--r-- | src/Common/Logger.h | 38 | ||||
-rw-r--r-- | src/Common/LoggerBase.h | 6 |
5 files changed, 84 insertions, 36 deletions
diff --git a/src/Common/ConfigManager.cpp b/src/Common/ConfigManager.cpp index c119cf7..6727cc3 100644 --- a/src/Common/ConfigManager.cpp +++ b/src/Common/ConfigManager.cpp @@ -52,7 +52,10 @@ void ConfigManager::handleConfigEntry(const ConfigEntry &entry) { Logger::logf(Logger::WARNING, "Invalid config option '%s'.", entry[entry.getSize()-1].getKey().c_str()); } -bool ConfigManager::loadFile(const std::string &filename, bool finish) { +bool ConfigManager::loadFile(const std::string &filename) { + if(finished) + return false; + std::ifstream file(filename.c_str()); ConfigEntry entry; std::string line, input; @@ -112,13 +115,18 @@ bool ConfigManager::loadFile(const std::string &filename, bool finish) { // TODO Depth check - if(finish) { - for(std::set<Configurable*>::iterator c = configurables.begin(); c != configurables.end(); ++c) - (*c)->configFinished(); - } - return true; } +void ConfigManager::finish() { + if(finished) + return; + + for(std::set<Configurable*>::iterator c = configurables.begin(); c != configurables.end(); ++c) + (*c)->configFinished(); + + finished = true; +} + } } diff --git a/src/Common/ConfigManager.h b/src/Common/ConfigManager.h index 45a78ec..bf34f6f 100644 --- a/src/Common/ConfigManager.h +++ b/src/Common/ConfigManager.h @@ -46,7 +46,8 @@ class ConfigManager { void handleConfigEntry(const ConfigEntry &entry); public: - bool loadFile(const std::string &filename, bool finish = true); + bool loadFile(const std::string &filename); + void finish(); void registerConfigurable(Configurable *c) { configurables.insert(c); diff --git a/src/Common/Logger.cpp b/src/Common/Logger.cpp index 27c98ba..51a320f 100644 --- a/src/Common/Logger.cpp +++ b/src/Common/Logger.cpp @@ -20,6 +20,8 @@ #include "Logger.h" #include "ConfigEntry.h" #include "ConfigManager.h" +#include "Backends/ConsoleLogger.h" +#include "Backends/FileLogger.h" #include <cstdlib> @@ -27,21 +29,49 @@ namespace Mad { namespace Common { std::auto_ptr<Logger::ConfigHelper> Logger::configHelper; -std::list<Logger*> Logger::loggers; - +std::set<Logger*> Logger::loggers; +std::auto_ptr<std::queue<Logger::Message> > Logger::messageQueue(new std::queue<Message>); bool Logger::ConfigHelper::handleConfigEntry(const ConfigEntry &entry, bool handled) { if(handled) return false; - if(entry[0].getKey().matches("Logger") && entry[1].empty()) { - logf(WARNING, "Unknown logger '%s'.", entry[0][0].c_str()); - return true; + if(entry[0].getKey().matches("Logger")) { + if(entry[0][0].matches("Console")) { + if(entry[1].empty()) { + loggers.insert(new Backends::ConsoleLogger()); + return true; + } + } + else if(entry[1].empty()) { + logf(WARNING, "Unknown logger '%s'.", entry[0][0].c_str()); + return true; + } } return false; } +void Logger::ConfigHelper::configFinished() { + std::auto_ptr<std::queue<Message> > queue = messageQueue; + + if(loggers.empty()) + loggers.insert(new Backends::ConsoleLogger()); + + while(!queue->empty()) { + const Message &message = queue->front(); + log(message.category, message.level, message.timestamp, message.message); + queue->pop(); + } +} + +Logger::ConfigHelper::~ConfigHelper() { + // TODO delete all those loggers... + + //while(!loggers.empty()) + // delete (*loggers.begin()); +} + void Logger::logfv(MessageCategory category, MessageLevel level, const char *format, va_list ap) { int size = 100; char *buf = (char*)std::malloc(size); @@ -70,11 +100,16 @@ void Logger::logfv(MessageCategory category, MessageLevel level, const char *for } -void Logger::log(MessageCategory category, MessageLevel level, const std::string &message) { - time_t messageTimestamp = std::time(NULL); - for(std::list<Logger*>::iterator logger = loggers.begin(); logger != loggers.end(); ++logger) { +void Logger::log(MessageCategory category, MessageLevel level, time_t timestamp, const std::string &message) { + if(messageQueue.get()) { // Queue message if loggers aren't configured yet + Message m = {category, level, timestamp, message}; + messageQueue->push(m); + return; + } + + for(std::set<Logger*>::iterator logger = loggers.begin(); logger != loggers.end(); ++logger) { if((*logger)->getLevel() >= level && (*logger)->isCategorySet(category)) - (*logger)->logMessage(category, level, messageTimestamp, message); + (*logger)->logMessage(category, level, timestamp, message); } } diff --git a/src/Common/Logger.h b/src/Common/Logger.h index 9499792..cf7e7d5 100644 --- a/src/Common/Logger.h +++ b/src/Common/Logger.h @@ -26,8 +26,9 @@ #include <algorithm> #include <cstdarg> #include <ctime> -#include <list> #include <memory> +#include <queue> +#include <set> #include <string> namespace Mad { @@ -38,22 +39,38 @@ class Logger : public LoggerBase { class ConfigHelper : private Configurable { protected: virtual bool handleConfigEntry(const ConfigEntry &entry, bool handled); + virtual void configFinished(); + + public: + ~ConfigHelper(); + }; + + struct Message { + MessageCategory category; + MessageLevel level; + time_t timestamp; + std::string message; }; static std::auto_ptr<ConfigHelper> configHelper; - static std::list<Logger*> loggers; + static std::set<Logger*> loggers; + static std::auto_ptr<std::queue<Message> > messageQueue; static void logfv(MessageCategory category, MessageLevel level, const char *format, va_list ap); + static void log(MessageCategory category, MessageLevel level, time_t timestamp, const std::string &message); + protected: - virtual void logMessage(MessageCategory category, MessageLevel level, time_t messageTimestamp, const std::string &message) = 0; + virtual void logMessage(MessageCategory category, MessageLevel level, time_t timestamp, const std::string &message) = 0; public: static void initConfigHelper() { configHelper.reset(new ConfigHelper()); } - static void log(MessageCategory category, MessageLevel level, const std::string &message); + static void log(MessageCategory category, MessageLevel level, const std::string &message) { + log(category, level, std::time(0), message); + } static void log(MessageCategory category, const std::string &message) { log(category, DEFAULT, message); } @@ -68,19 +85,6 @@ class Logger : public LoggerBase { static void logf(MessageCategory category, const char *format, ...); static void logf(MessageLevel level, const char *format, ...); static void logf(const char *format, ...); - - static void registerLogger(Logger *logger) { - loggers.push_back(logger); - } - - static void unregisterLogger(Logger *logger) { - std::list<Logger*>::iterator it = std::find(loggers.begin(), loggers.end(), logger); - if(it != loggers.end()) - loggers.erase(it); - } - - Logger() {} - virtual ~Logger() {} }; } diff --git a/src/Common/LoggerBase.h b/src/Common/LoggerBase.h index 0513594..b06f03a 100644 --- a/src/Common/LoggerBase.h +++ b/src/Common/LoggerBase.h @@ -40,6 +40,9 @@ class LoggerBase { std::bitset<16> categories; MessageLevel level; + LoggerBase() : level(DEFAULT) {setAllCategories();} + virtual ~LoggerBase() {} + public: void setCategory(MessageCategory newCategory) { categories.set(newCategory); @@ -68,9 +71,6 @@ class LoggerBase { void setLevel(MessageLevel newLevel) { level = newLevel; } - - LoggerBase() : level(DEFAULT) {setAllCategories();} - virtual ~LoggerBase() {} }; } |