MessageHandler.hh
Go to the documentation of this file.00001
00002
00003
00004
00011 #ifndef MESSAGE_HANDLER_h
00012 #define MESSAGE_HANDLER_h 1
00013
00014 #include <iostream>
00015 #include <sstream>
00016 #include <set>
00017 #include <queue>
00018 #include <time.h>
00019
00020
00021 namespace boost{
00022 class thread;
00023 class mutex;
00024 class condition_variable;
00025 };
00026
00029
00033 enum MESSAGE_LEVEL {DEBUG3=0, DEBUG2, DEBUG, INFO, WARNING, ERROR,
00034 CRITICAL, EXCEPTION, N_MESSAGE_LEVELS};
00035
00037 std::ostream& operator<<(std::ostream& out, const MESSAGE_LEVEL& level);
00039 std::istream& operator>>(std::istream& in, MESSAGE_LEVEL& level);
00041 MESSAGE_LEVEL& operator++(MESSAGE_LEVEL& level);
00043 MESSAGE_LEVEL& operator--(MESSAGE_LEVEL& level);
00044
00045
00046
00047 class Message;
00048
00053 class MessageHandler{
00054 public:
00056 static MessageHandler* GetInstance(){ return &_instance; }
00058 void End();
00060 void Post(std::ostringstream* mgs, MESSAGE_LEVEL level);
00061
00063 template<class MsgAction>
00064 void* AddMessenger(MESSAGE_LEVEL thresh,MsgAction act)
00065 {
00066 VMessenger* m = new Messenger<MsgAction>(thresh,act);
00067 _messengers.insert(m);
00068 return m;
00069 }
00071 void RemoveMessenger(void* m);
00073 void SetThreshold(MESSAGE_LEVEL thresh, void* messenger=0);
00075 void UpdateThreshold(){ SetThreshold(_default_threshold); }
00077 MESSAGE_LEVEL GetDefaultMessageThreshold(){return _default_threshold;}
00078
00082 class PrintToStream{
00083 std::ostream& _stream;
00084 bool _use_color;
00085 public:
00086 PrintToStream(std::ostream& out=std::cout, bool use_color=true) :
00087 _stream(out), _use_color(use_color) {}
00088 void operator()(const std::string& s, MESSAGE_LEVEL level, time_t t);
00089 };
00090
00091 private:
00092
00093 MessageHandler();
00094 ~MessageHandler();
00095
00096 MessageHandler(const MessageHandler& ) {}
00097 MessageHandler& operator=(const MessageHandler& ) {return *this;}
00098
00099 void Deliver(std::ostringstream* msg, MESSAGE_LEVEL level, time_t t=time(0));
00100
00101
00102
00103 class VMessenger{
00104 public:
00105 VMessenger(MESSAGE_LEVEL thresh) : _thresh(thresh) {}
00106 virtual ~VMessenger() {}
00107 virtual void Deliver(std::ostringstream*, MESSAGE_LEVEL, time_t) = 0;
00108 void SetThreshold(MESSAGE_LEVEL thresh){ _thresh = thresh; }
00109 protected:
00110 MESSAGE_LEVEL _thresh;
00111 };
00112
00113 template<class MsgAction> class Messenger : public VMessenger{
00114 public:
00115 Messenger(MESSAGE_LEVEL thresh, MsgAction action) : VMessenger(thresh),
00116 _action(action) {}
00117 ~Messenger() {}
00118 void Deliver(std::ostringstream* msg, MESSAGE_LEVEL level, time_t t)
00119 { if (level >= _thresh ) _action(msg->str(),level,t); }
00120 private:
00121 MsgAction _action;
00122 };
00123
00124 std::set<VMessenger*> _messengers;
00125 static MessageHandler _instance;
00126 MESSAGE_LEVEL _default_threshold;
00127
00128
00129 private:
00130 struct MsgData{
00131 std::ostringstream* msg;
00132 MESSAGE_LEVEL level;
00133 time_t t;
00134 MsgData(std::ostringstream* m, MESSAGE_LEVEL l) : msg(m), level(l)
00135 {time(&t);}
00136 };
00137 std::queue<MsgData> _inbox;
00138 bool _kill_thread;
00139 boost::mutex* _inbox_mutex;
00140 boost::condition_variable* _message_waiting;
00141 boost::thread* _delivery_thread;
00142 public:
00143 void operator()();
00144
00145 };
00146
00148
00149 #endif