Yet Another Game Engine
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
logger.h
Go to the documentation of this file.
1 
10 #pragma once
11 
12 #include "../util/active.h"
13 
14 #include <memory>
15 #include <sstream>
16 #include <string>
17 #include <vector>
18 
19 namespace yage
20 {
21 
22 class Logger;
23 
29 enum class LogLevel {
32  DEBUG,
33 
35  INFO,
36 
38  WARNING,
39 
40 #ifdef _WIN32
41 #ifdef ERROR
42 #define YAGE_ERROR_TMP ERROR
43 #undef ERROR
44 #endif
45 #endif
46 
48  ERROR,
49 
50 #ifdef _WIN32
51 #ifdef YAGE_ERROR_TMP
52 #define ERROR YAGE_ERROR_TMP
53 #undef YAGE_ERROR_TMP
54 #endif
55 #endif
56 
59  FATAL,
60 };
61 
63 {
64 public:
65  ~LogMessage();
66 
67  LogMessage(LogMessage const &msg) = delete;
68 
69  LogMessage &operator=(LogMessage const &msg) = delete;
70  LogMessage &operator=(LogMessage &&msg) = delete;
71 
72  template <typename T>
73  LogMessage &operator<<(T const &value);
74 
75  LogMessage &operator<<(std::ostream &(*fn)(std::ostream &os));
76 
77  struct Meta {
79  std::string fileName;
80  int line;
81  };
82 
83 private:
84  friend class Logger;
85 
86  std::ostringstream buffer_;
87  Logger *owner_;
88  LogMessage::Meta meta_;
89 
90  LogMessage(Logger *owner, LogLevel level, std::string const &file_name,
91  int line_num);
92  LogMessage(LogMessage &&msg);
93 };
94 
95 class LogSink
96 {
97 public:
98  template <typename T>
99  LogSink(T impl);
100 
101  LogSink(LogSink const &sink);
102  LogSink(LogSink &&sink);
103 
104  LogSink &operator=(LogSink const &sink);
105  LogSink &operator=(LogSink &&sink);
106  bool operator==(LogSink const &sink);
107 
108  void write(LogMessage::Meta const &meta, std::string const &msg) const;
109 
110 private:
111  struct Concept {
112  virtual ~Concept() = default;
113 
114  virtual Concept *clone() const = 0;
115  virtual void write(LogMessage::Meta const &meta,
116  std::string const &msg) const = 0;
117  };
118 
119  template <typename T>
120  struct Model : Concept {
121  Model(T impl_i);
122  virtual Concept *clone() const override;
123  virtual void write(const LogMessage::Meta &meta,
124  std::string const &msg) const override;
125 
126  T impl;
127  };
128 
129  std::unique_ptr<Concept> wrapper_;
130 };
131 
132 class Logger
133 {
134 public:
135  Logger();
136  explicit Logger(std::string const &file_path);
137  explicit Logger(LogLevel min_level);
138  Logger(LogLevel min_level, std::string const &file_path);
139 
141  std::string const &fileName = "", int lineNum = -1);
142 
143  void flush(LogMessage const *msg);
144  void add(LogSink const &sink);
145  void remove(LogSink const &sink);
146  void clear();
147 
148  static Logger &instance();
149 
150  // setter for the level
151  void setLevel(LogLevel min_level);
152 
153 private:
154  std::vector<LogSink> sinks_;
155  std::unique_ptr<Active> active_;
156  LogLevel min_level_;
157 };
158 
160 
161 LogSink makeFileSink(std::string const &filename);
162 LogSink makeFileSink(std::string &&filename);
163 
164 /* -----------------------------------------------------------------------------
165  * Template Implementation
166  * -----------------------------------------------------------------------------
167  */
168 
169 template <typename T>
170 LogSink::LogSink(T impl) : wrapper_(new Model<T>(std::move(impl)))
171 {
172 }
173 
174 template <typename T>
175 LogSink::Model<T>::Model(T impl_i) : impl(impl_i)
176 {
177 }
178 
179 template <typename T>
180 LogSink::Concept *LogSink::Model<T>::clone() const
181 {
182  return new Model<T>(impl);
183 }
184 
185 template <typename T>
186 void LogSink::Model<T>::write(LogMessage::Meta const &meta,
187  std::string const &msg) const
188 {
189  impl(meta, msg);
190 }
191 
192 template <typename T>
194 {
195  buffer_ << value;
196  return *this;
197 }
198 
199 } // namespace yage
200 
201 #define yLogger (yage::Logger::instance())
202 
203 #define yLogDebug \
204  (yage::Logger::instance()(yage::LogLevel::DEBUG, __FILE__, __LINE__))
205 
206 #define yLogInfo \
207  (yage::Logger::instance()(yage::LogLevel::INFO, __FILE__, __LINE__))
208 
209 #define yLogWarning \
210  (yage::Logger::instance()(yage::LogLevel::WARNING, __FILE__, __LINE__))
211 
212 #define yLogError \
213  (yage::Logger::instance()(yage::LogLevel::ERROR, __FILE__, __LINE__))
214 
215 #define yLogFatal \
216  (yage::Logger::instance()(yage::LogLevel::FATAL, __FILE__, __LINE__))
LogMessage & operator=(LogMessage const &msg)=delete
LogMessage(LogMessage const &msg)=delete
bool operator==(LogSink const &sink)
Warning message.
Fatal message that should be output when the game crashes.
Definition: logger.h:62
LogLevel
Different log levels that can be assigned to each message sent to the Logger.
Definition: logger.h:29
LogSink & operator=(LogSink const &sink)
void add(LogSink const &sink)
Definition: logger.cpp:208
void flush(LogMessage const *msg)
Definition: logger.cpp:192
void setLevel(LogLevel min_level)
Definition: logger.cpp:234
void clear()
Definition: logger.cpp:222
LogSink makeConsoleSink()
LogSink(T impl)
Definition: logger.h:170
void write(LogMessage::Meta const &meta, std::string const &msg) const
LogSink makeFileSink(std::string const &filename)
static Logger & instance()
Definition: logger.cpp:227
LogMessage & operator<<(T const &value)
Definition: logger.h:193
std::string fileName
Definition: logger.h:79
Lowest log level. This is used by the game engine to output debugging information but is turned off i...
int line
Definition: logger.h:80
Error message.
LogLevel level
Definition: logger.h:78
Definition: logger.h:132
Information message.
Definition: logger.h:77
LogMessage operator()(LogLevel level=LogLevel::INFO, std::string const &fileName="", int lineNum=-1)
Definition: logger.cpp:186
Definition: logger.h:95