/include/tite/core/log/detail/Log_.hpp
C++ Header | 291 lines | 177 code | 27 blank | 87 comment | 5 complexity | e68bb19e167d9091ee7dc9b36819ff8a MD5 | raw file
Possible License(s): GPL-3.0
- /****************************************************************************
- ** Tite Interactive Text Engine (TiTE)
- ** Copyright (C) 2010 Eisoft Group
- **
- ** This file is part of TiTE.
- **
- ** TiTE is free software: you can redistribute it and/or modify
- ** it under the terms of the GNU General Public License as published by
- ** the Free Software Foundation, either version 3 of the License, or
- ** (at your option) any later version.
- **
- ** TiTE is distributed in the hope that it will be useful,
- ** but WITHOUT ANY WARRANTY; without even the implied warranty of
- ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- ** GNU General Public License for more details.
- **
- ** You should have received a copy of the GNU General Public License
- ** along with TiTE. If not, see <http://www.gnu.org/licenses/>.
- ****************************************************************************/
-
- /*!
- * \file Log_.hpp
- *
- * \date 01/10/2011
- */
-
- #ifndef TITE_CORE_LOG__HPP
- #define TITE_CORE_LOG__HPP
-
- #include <algorithm>
- #include <ctime>
- #include <string>
- #include <vector>
-
- #include <tite/core/log/ILogListener.hpp>
-
- /*!
- * \namespace tite
- *
- * \brief The TiTE namespace.
- */
- namespace tite
- {
- /*!
- * \namespace core
- *
- * \brief The TiTE core namespace.
- */
- namespace core
- {
- /*!
- * \class Log_ Log_.hpp
- *
- * \brief A simple, efficient generic logging class.
- *
- * \note The Container template parameter expects an STL-style container.
- *
- * \author Jason Omahen
- * \version 0.02, 12/18/2010
- */
- template<
- typename T,
- typename Listener = ILogListener,
- template <typename, typename> class Container = stdext::vector,
- typename Allocator = stdext::allocator<T>
- >
- class Log_
- {
- // Log_ helper functions to provide a simple interface
- friend Log_& log_I(void);
- #if defined(DEBUG) || defined(_DEBUG)
- friend Log_& log_D(void);
- #endif
- friend Log_& log_W(void);
- friend Log_& log_C(void);
- friend Log_& log_F(void);
-
- public:
- typedef T log_elem_t;
- typedef Listener listener_t;
- typedef listener_t* listener_ptr_t;
- typedef listener_t *const listener_const_ptr_t;
-
- Log_(void);
- ~Log_(void);
-
- void log(const stdext::string & message, log_levels::LogLevel messageLevel);
-
- void addListener(listener_const_ptr_t pLogListener);
- void removeListener(listener_const_ptr_t pLogListener);
-
- template<typename U>
- Log_& operator<<(const U & u);
-
- private:
- char* _getLocalTime(void);
- void _prepare(log_levels::LogLevel l);
- void _writeToBuffer(const stdext::string & message);
-
- std::time_t m_rawTime;
- log_levels::LogLevel m_currentLogLevel;
-
- Container<T, Allocator> m_logBuffer;
- Container<listener_ptr_t, Allocator> m_logListeners;
- };
-
- /*!
- * \brief Log_ ctor.
- */
- template<
- typename T,
- typename Listener,
- template <typename, typename> class Container,
- typename Allocator
- >
- Log_<T, Listener, Container, Allocator>::Log_(void)
- : m_currentLogLevel(log_levels::None)
- {
- log("[Log Singleton] Starting up ...\n", log_levels::Info);
- }
-
- /*!
- * \brief Log_ dtor.
- */
- template<
- typename T,
- typename Listener,
- template <typename, typename> class Container,
- typename Allocator
- >
- Log_<T, Listener, Container, Allocator>::~Log_(void)
- {
- log("[Log Singleton] Shutting down ...\n", log_levels::Warning);
-
- for (Container<listener_ptr_t, Allocator>::iterator it = m_logListeners.begin(); it != m_logListeners.end(); ++it)
- safe_delete(&(*it));
- }
-
- /*!
- * \brief Logs a message at the specified log level.
- *
- * \param message Contents to log.
- * \param messageLevel Message type.
- */
- template<
- typename T,
- typename Listener,
- template <typename, typename> class Container,
- typename Allocator
- >
- void Log_<T, Listener, Container, Allocator>::log(const std::string & message, log_levels::LogLevel messageLevel)
- {
- _prepare(messageLevel);
- _writeToBuffer(message);
- }
-
- template<
- typename T,
- typename Listener,
- template <typename, typename> class Container,
- typename Allocator
- >
- void Log_<T, Listener, Container, Allocator>::addListener(typename Log_<T, Listener, Container, Allocator>::listener_const_ptr_t pLogListener)
- {
- if (pLogListener)
- m_logListeners.push_back(pLogListener);
- }
-
- template<
- typename T,
- typename Listener,
- template <typename, typename> class Container,
- typename Allocator
- >
- void Log_<T, Listener, Container, Allocator>::removeListener(typename Log_<T, Listener, Container, Allocator>::listener_const_ptr_t pLogListener)
- {
- m_logListeners.erase(stdext::remove(m_logListeners.begin(),
- m_logListeners.end(),
- pLogListener),
- m_logListeners.end());
- }
-
- /*!
- * \brief Overloaded "stream" insertion operator; writes contents directly
- * to the log buffer.
- *
- * \note Use in conjunction with the log_X helper functions for increased
- * clarity and simplicity.
- *
- * \param u std::string-convertable message to log.
- *
- * \return Modified Log_ object after message was logged.
- */
- template<
- typename T,
- typename Listener,
- template <typename, typename> class Container,
- typename Allocator
- >
- template<typename U>
- Log_<T, Listener, Container, Allocator>& Log_<T, Listener, Container, Allocator>::operator<<(const U & u)
- {
- _writeToBuffer(u);
- return *this;
- }
-
- /*!
- * \brief Formats the computer's local date/time into an ASCII string.
- *
- * \return The local date/time.
- */
- template<
- typename T,
- typename Listener,
- template <typename, typename> class Container,
- typename Allocator
- >
- char* Log_<T, Listener, Container, Allocator>::_getLocalTime(void)
- {
- std::time(&m_rawTime);
- return std::asctime(std::localtime(&m_rawTime));
- }
-
- /*!
- * \brief Prepares the logging buffer for a specific LogLevel.
- *
- * \param l Logging level.
- */
- template<
- typename T,
- typename Listener,
- template <typename, typename> class Container,
- typename Allocator
- >
- void Log_<T, Listener, Container, Allocator>::_prepare(log_levels::LogLevel l)
- {
- stdext::string header, time(_getLocalTime());
-
- // Remove \n character from the time string
- time.pop_back();
-
- switch (l)
- {
- case log_levels::Info:
- header = "[INFO.]";
- break;
- case log_levels::Debug:
- header = "[DEBUG]";
- break;
- case log_levels::Warning:
- header = "[WARN!]";
- break;
- case log_levels::Critical:
- case log_levels::Fatal:
- header = "[FATAL]";
- break;
- }
- header += "[" + time + "] ";
-
- // Write the prefix message
- m_currentLogLevel = l;
- _writeToBuffer(header);
- }
-
- /*!
- * \brief Commits the message to the internal logging buffer.
- *
- * \param message Contents to log.
- */
- template<
- typename T,
- typename Listener,
- template <typename, typename> class Container,
- typename Allocator
- >
- void Log_<T, Listener, Container, Allocator>::_writeToBuffer(const stdext::string & message)
- {
- // A buffer may be completely unnecessary now... waste memory for already processed
- // messages? Eh... let's rethink this!
- m_logBuffer.insert(m_logBuffer.end(), message.begin(), message.end());
- stdext::for_each(m_logListeners.begin(),
- m_logListeners.end(),
- stdext::bind(&Listener::logMessage,
- stdext::placeholders::_1,
- stdext::cref(message),
- m_currentLogLevel));
- }
- }// End of core namespace
- }// End of tite namespace
-
- #endif /* TITE_CORE_LOG__HPP */