ARGoS
3
A parallel, multi-engine simulator for swarm robotics
|
00001 00016 #ifndef ARGOSLOG_H 00017 #define ARGOSLOG_H 00018 00019 #include <argos3/core/config.h> 00020 #include <iomanip> 00021 #include <string> 00022 #include <iostream> 00023 #include <fstream> 00024 #include <cstdio> 00025 #include <cstring> 00026 #include <cstdlib> 00027 00028 #ifdef ARGOS_THREADSAFE_LOG 00029 #include <pthread.h> 00030 #include <sstream> 00031 #include <map> 00032 #include <vector> 00033 #endif 00034 00035 namespace argos { 00036 class CARGOSLogger; 00037 } 00038 00039 #include <argos3/core/utility/logging/argos_colored_text.h> 00040 00041 namespace argos { 00042 00043 class CARGoSLog { 00044 00045 private: 00046 00048 std::ostream& m_cStream; 00049 00051 SLogColor m_sLogColor; 00052 00054 bool m_bColoredOutput; 00055 00056 #ifdef ARGOS_THREADSAFE_LOG 00057 00058 std::map<pthread_t, size_t> m_mapStreamOrder; 00059 00061 std::vector<std::stringstream*> m_vecStreams; 00062 00064 pthread_mutex_t m_tMutex; 00065 #endif 00066 00067 public: 00068 00069 CARGoSLog(std::ostream& c_stream, 00070 const SLogColor& s_log_color, 00071 bool b_colored_output_enabled = true) : 00072 m_cStream(c_stream), 00073 m_sLogColor(s_log_color), 00074 m_bColoredOutput(b_colored_output_enabled) { 00075 #ifdef ARGOS_THREADSAFE_LOG 00076 pthread_mutex_init(&m_tMutex, NULL); 00077 AddThreadSafeBuffer(); 00078 #endif 00079 } 00080 00081 ~CARGoSLog() { 00082 #ifdef ARGOS_THREADSAFE_LOG 00083 pthread_mutex_destroy(&m_tMutex); 00084 while(!m_vecStreams.empty()) { 00085 delete m_vecStreams.back(); 00086 m_vecStreams.pop_back(); 00087 } 00088 #endif 00089 if(m_bColoredOutput) { 00090 reset(m_cStream); 00091 } 00092 } 00093 00094 inline void EnableColoredOutput() { 00095 m_bColoredOutput = true; 00096 } 00097 00098 inline void DisableColoredOutput() { 00099 m_bColoredOutput = false; 00100 } 00101 00102 inline bool IsColoredOutput() const { 00103 return m_bColoredOutput; 00104 } 00105 00106 inline std::ostream& GetStream() { 00107 return m_cStream; 00108 } 00109 00110 #ifdef ARGOS_THREADSAFE_LOG 00111 inline void Flush() { 00112 pthread_mutex_lock(&m_tMutex); 00113 for(size_t i = 0; i < m_vecStreams.size(); ++i) { 00114 m_cStream << m_vecStreams[i]->str(); 00115 m_vecStreams[i]->str(""); 00116 } 00117 pthread_mutex_unlock(&m_tMutex); 00118 } 00119 00120 inline void AddThreadSafeBuffer() { 00121 pthread_mutex_lock(&m_tMutex); 00122 m_mapStreamOrder.insert(std::make_pair<pthread_t, size_t>(pthread_self(), m_vecStreams.size())); 00123 m_vecStreams.push_back(new std::stringstream); 00124 pthread_mutex_unlock(&m_tMutex); 00125 } 00126 #else 00127 void Flush() {} 00128 #endif 00129 00130 inline CARGoSLog& operator<<(std::ostream& (*c_stream)(std::ostream&)) { 00131 #ifdef ARGOS_THREADSAFE_LOG 00132 *(m_vecStreams[m_mapStreamOrder.find(pthread_self())->second]) << c_stream; 00133 #else 00134 m_cStream << c_stream; 00135 #endif 00136 return *this; 00137 } 00138 00139 template <typename T> CARGoSLog& operator<<(const T t_msg) { 00140 if(m_bColoredOutput) { 00141 #ifdef ARGOS_THREADSAFE_LOG 00142 *(m_vecStreams[m_mapStreamOrder.find(pthread_self())->second]) << m_sLogColor << t_msg << reset; 00143 #else 00144 m_cStream << m_sLogColor << t_msg << reset; 00145 #endif 00146 } 00147 else { 00148 #ifdef ARGOS_THREADSAFE_LOG 00149 *(m_vecStreams[m_mapStreamOrder.find(pthread_self())->second]) << t_msg; 00150 #else 00151 m_cStream << m_sLogColor << t_msg << reset; 00152 #endif 00153 } 00154 return *this; 00155 } 00156 00157 }; 00158 00159 extern CARGoSLog LOG; 00160 extern CARGoSLog LOGERR; 00161 00162 } 00163 00164 #define RLOG LOG << "[" << GetId() << "] " 00165 #define RLOGERR LOGERR << "[" << GetId() << "] " 00166 00167 #endif