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