00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #ifndef TORRENT_ALERT_HPP_INCLUDED
00034 #define TORRENT_ALERT_HPP_INCLUDED
00035
00036 #include <memory>
00037 #include <queue>
00038 #include <string>
00039 #include <cassert>
00040 #include <typeinfo>
00041
00042 #ifdef _MSC_VER
00043 #pragma warning(push, 1)
00044 #endif
00045
00046 #include <boost/thread/mutex.hpp>
00047
00048 #include <boost/preprocessor/repetition/enum_params_with_a_default.hpp>
00049 #include <boost/preprocessor/repetition/enum.hpp>
00050 #include <boost/preprocessor/repetition/enum_params.hpp>
00051 #include <boost/preprocessor/repetition/enum_shifted_params.hpp>
00052 #include <boost/date_time/posix_time/posix_time.hpp>
00053
00054 #ifdef _MSC_VER
00055 #pragma warning(pop)
00056 #endif
00057
00058 #include "libtorrent/config.hpp"
00059
00060 #define TORRENT_MAX_ALERT_TYPES 10
00061
00062 namespace libtorrent {
00063
00064 class TORRENT_EXPORT alert
00065 {
00066 public:
00067 enum severity_t { debug, info, warning, critical, fatal, none };
00068
00069 alert(severity_t severity, const std::string& msg);
00070 virtual ~alert();
00071
00072
00073 boost::posix_time::ptime timestamp() const;
00074
00075 const std::string& msg() const;
00076
00077 severity_t severity() const;
00078
00079 virtual std::auto_ptr<alert> clone() const = 0;
00080
00081 private:
00082 std::string m_msg;
00083 severity_t m_severity;
00084 boost::posix_time::ptime m_timestamp;
00085 };
00086
00087 class TORRENT_EXPORT alert_manager
00088 {
00089 public:
00090 alert_manager();
00091 ~alert_manager();
00092
00093 void post_alert(const alert& alert_);
00094 bool pending() const;
00095 std::auto_ptr<alert> get();
00096
00097 void set_severity(alert::severity_t severity);
00098 bool should_post(alert::severity_t severity) const;
00099
00100 private:
00101 std::queue<alert*> m_alerts;
00102 alert::severity_t m_severity;
00103 mutable boost::mutex m_mutex;
00104 };
00105
00106 struct TORRENT_EXPORT unhandled_alert : std::exception
00107 {
00108 unhandled_alert() {}
00109 };
00110
00111 namespace detail {
00112
00113 struct void_;
00114
00115 template<
00116 class Handler
00117 , BOOST_PP_ENUM_PARAMS(TORRENT_MAX_ALERT_TYPES, class T)
00118 >
00119 void handle_alert_dispatch(
00120 const std::auto_ptr<alert>& alert_
00121 , const Handler& handler
00122 , const std::type_info& typeid_
00123 , BOOST_PP_ENUM_BINARY_PARAMS(TORRENT_MAX_ALERT_TYPES, T, *p))
00124 {
00125 if (typeid_ == typeid(T0))
00126 handler(*static_cast<T0*>(alert_.get()));
00127 else
00128 handle_alert_dispatch(
00129 alert_
00130 , handler
00131 , typeid_
00132 , BOOST_PP_ENUM_SHIFTED_PARAMS(TORRENT_MAX_ALERT_TYPES, p), (void_*)0
00133 );
00134 }
00135
00136 template<class Handler>
00137 void handle_alert_dispatch(
00138 const std::auto_ptr<alert>& alert_
00139 , const Handler& handler
00140 , const std::type_info& typeid_
00141 , BOOST_PP_ENUM_PARAMS(TORRENT_MAX_ALERT_TYPES, void_* BOOST_PP_INTERCEPT))
00142 {
00143 throw unhandled_alert();
00144 }
00145
00146 }
00147
00148 template<
00149 BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(TORRENT_MAX_ALERT_TYPES, class T, detail::void_)
00150 >
00151 struct TORRENT_EXPORT handle_alert
00152 {
00153 template<class Handler>
00154 handle_alert(
00155 const std::auto_ptr<alert>& alert_
00156 , const Handler& handler)
00157 {
00158 #define ALERT_POINTER_TYPE(z, n, text) (BOOST_PP_CAT(T, n)*)0
00159
00160 detail::handle_alert_dispatch(
00161 alert_
00162 , handler
00163 , typeid(*alert_)
00164 , BOOST_PP_ENUM(TORRENT_MAX_ALERT_TYPES, ALERT_POINTER_TYPE, _)
00165 );
00166
00167 #undef ALERT_POINTER_TYPE
00168 }
00169 };
00170
00171 }
00172
00173 #endif // TORRENT_ALERT_HPP_INCLUDED
00174