Gorgon Game Engine
Logging.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include <iostream>
4 #include <fstream>
5 #include <string>
6 #include <mutex>
7 
8 #include "../Time.h"
9 #include "../Utils/Console.h"
10 
11 namespace Gorgon { namespace Utils {
12 
19  class Logger {
20  friend class helper;
21  std::mutex mtx;
22 
23  class helper {
24  friend class Logger;
25 
26  Logger *parent;
27  int shift = 0;
28  bool extraenter = false;
29 
30  helper() : parent(nullptr) { }
31 
32  helper(Logger *parent, int shift, bool extraenter) : parent(parent), shift(shift), extraenter(extraenter) {
33  if(!parent) return;
34  parent->mtx.lock();
35  }
36 
37  helper(helper &&h) {
38  parent=h.parent;
39  shift=h.shift;
40  extraenter=h.extraenter;
41 
42  h.parent=nullptr;
43  }
44 
45  helper &operator =(helper &&h) {
46  if(parent)
47  parent->mtx.unlock();
48 
49  parent=h.parent;
50  shift=h.shift;
51  extraenter=h.extraenter;
52 
53  h.parent=nullptr;
54 
55  return *this;
56  }
57 
58  public:
59  ~helper() {
60  if(!parent) return;
61 
62  parent->mtx.unlock();
63 
64  if(extraenter)
65  (*parent->stream) << "\n";
66 
67  (*parent->stream)<<std::endl;
68 
69  if(parent->IsColorFunctional())
70  parent->reset(*parent->stream);
71  }
72 
73  using endl_t = decltype(&std::endl<char, std::char_traits<char>>);
74 
75  helper &operator <<(const endl_t &) {
76  if(!parent) return *this;
77 
78  (*parent->stream) << std::endl << std::string(shift, ' ');
79 
80  extraenter=true;
81 
82 #ifndef NDEBUG
83  if(!(*parent->stream)) {
84  throw std::runtime_error("Logging failed");
85  }
86 #endif
87 
88  return *this;
89  }
90 
91  template <class T_>
92  helper &operator <<(const T_ &v) {
93  if(!parent) return *this;
94 
95  (*parent->stream) << v;
96 
97 #ifndef NDEBUG
98  if(!(*parent->stream)) {
99  throw std::runtime_error("Logging failed");
100  }
101 #endif
102 
103  return *this;
104  }
105  };
106 
107  public:
108  enum State {
112  Success
113  };
114 
116  Logger(const std::string &section = "", bool marktime = true, bool markdate = false) :
118  { }
119 
121  Logger(const char *section, bool marktime = true, bool markdate = false) :
122  Logger(std::string(section), marktime, markdate)
123  { }
124 
125  Logger(bool marktime, bool markdate = false) : Logger("", marktime, markdate) { }
126 
127  Logger(std::ostream &stream, const std::string &section = "", bool marktime = true, bool markdate = false) :
129  {
130 
131  }
132 
134  CleanUp();
135  }
136 
138  CleanUp();
139  stream=&std::cout;
140  owner=false;
141  console = StdConsole();
142  }
143 
146  void InitializeStream(std::ostream &stream) {
147 #ifndef NO_LOGGING
148  CleanUp();
149  this->stream=&stream;
150  owner=false;
151 #endif
152  }
153 
156  void InitializeFile(const std::string &filename) {
157 #ifndef NO_LOGGING
158  CleanUp();
159  stream=new std::ofstream(filename);
160  owner=true;
161 #endif
162  }
163 
166  void CleanUp() {
167  if(owner) {
168  delete stream;
169  }
170 
171  stream = nullptr;
172  console = Console();
173  }
174 
176  void SetWidth(int width) {
177  this->width = width;
178  }
179 
186  template <class T_>
187  helper operator <<(const T_ &v) {
188  return Log(v, Message);
189  }
190 
199  template <class T_>
200  helper Log(const T_ &v, State state = Error) {
201 #ifndef NO_LOGGING
202  if(!this->stream) return {nullptr, 0, false};
203  auto &stream = *this->stream;
204 
205  int headw = marktime * 8 + markdate * 10 + (markdate && marktime) * 1 + ((markdate || marktime) && !section.empty()) * 1 + (int)section.size();
206 
207  if(headw) headw += 2;
208 
209  helper h;
210 
211  if(width && headw*1.25 >= width) {
212  stream<<std::endl;
213 
214  h = {this, 4, true};
215  }
216  else if(headw) {
217  h = {this, headw, false};
218  }
219  else {
220  h = {this, 0, true};
221  }
222 
223  if(marktime || markdate) {
224  auto dt = Time::Date::Now();
225 
226  if(markdate) {
227  if(IsColorFunctional())
229 
230  stream<<dt.ISODate();
231 
232  if(marktime) stream<<" ";
233  }
234 
235  if(marktime) {
236  stream<<dt.Time();
237  }
238 
239  if(!section.empty()) stream<<" ";
240  }
241 
242  if(IsColorFunctional()) {
243  reset(stream);
244  console.SetBold(true);
245  colorize(state);
246  }
247 
248  if(!section.empty()) stream<<section;
249 
250  if(headw) stream<<" ";
251 
252  if(IsColorFunctional())
253  reset(stream);
254 
255  if(state != Message) {
256  if(IsColorFunctional()) {
257  colorize(state);
258  }
259  else {
260  stream << (state == Error ? "Error! : " : "Success: ");
261  }
262  }
263 
264  return std::move(h << v);
265 #else
266  return {nullptr, 0, false};
267 #endif
268  }
269 
271  void SetSection(const std::string &value) {
272  section = value;
273  }
274 
276  std::string GetSection() const {
277  return section;
278  }
279 
281  void SetMarkTime(bool value) {
282  marktime = value;
283  }
284 
286  bool GetMarkTime() const {
287  return marktime;
288  }
289 
291  void SetMarkDate(bool value) {
292  markdate = value;
293  }
294 
296  bool GetMarkDate() const {
297  return markdate;
298  }
299 
303  void EnableColor() {
304  color = true;
305  }
306 
307 
309  void DisableColor() {
310  color = false;
311  }
312 
316  void SetColorEnabled(bool value) {
317  color = value;
318  }
319 
322  bool IsColorEnabled() const {
323  return color;
324  }
325 
327  bool IsColorFunctional() const {
328  return color && hasconsole && console.IsColorSupported();
329  }
330 
331 
332  protected:
333 
334  void reset(std::ostream &stream) {
335  if(console)
336  console.Reset();
337  }
338 
340 
341  std::ostream *stream = nullptr;
342  bool owner = false;
343 
344  bool marktime = true;
345  bool markdate = true;
346 
347  bool hasconsole = false;
348  bool color = true;
349  int width = 0;
350 
351  std::string section;
352 
353  private:
354  void colorize(State state) {
355  switch(state) {
356  case Message: /*do nothing*/ break;
357  case Error: console.SetColor(Console::Color::Red ); break;
360  default: console.SetColor(Console::Color::White); break;
361  }
362  }
363  };
364 
365 #ifdef NDEBUG
366 # define DEBUGONLY(action)
367 #else
368 # define DEBUGONLY(action) action
369 #endif
370 
371 } }
Gorgon::Utils::Logger::SetMarkTime
void SetMarkTime(bool value)
Sets whether to mark the time on log output.
Definition: Logging.h:281
Gorgon::Utils::Console::ColorSupportLevel
ColorSupportLevel
Level of support for color.
Definition: Console.h:35
Gorgon::Utils::Logger::EnableColor
void EnableColor()
Enables color support, however, if the underlying stream does not allow coloring this will not have a...
Definition: Logging.h:303
Gorgon::Utils::Logger::operator<<
helper operator<<(const T_ &v)
Streams out the given value to the underlying stream.
Definition: Logging.h:187
Gorgon::Utils::Logger::markdate
bool markdate
Definition: Logging.h:345
Gorgon::Utils::Logger::helper
friend class helper
Definition: Logging.h:20
Gorgon::Utils::Logger::stream
std::ostream * stream
Definition: Logging.h:341
Gorgon::Utils::Console::Color
Color
The colors that can be used for console coloring. This is a safe list.
Definition: Console.h:47
Gorgon::Utils::Console::Reset
void Reset()
Resets terminal attributes.
Gorgon::Graphics::Color::White
constexpr RGBA White
Definition: Color.h:731
Gorgon::Utils::Logger::SetColorEnabled
void SetColorEnabled(bool value)
Sets color enabled state.
Definition: Logging.h:316
Gorgon::OS::GetEnvVar
std::string GetEnvVar(const std::string &var)
Returns the value of an environment variable.
Definition: Linux.cpp:17
Gorgon::Utils::Logger::~Logger
~Logger()
Definition: Logging.h:133
Gorgon::Utils::Logger::color
bool color
Definition: Logging.h:348
Gorgon::Utils::Console::SetColor
void SetColor(Color color)
Sets the color to the given value, avoid, black and white as console can have its background color re...
Gorgon::Utils::Logger::owner
bool owner
Definition: Logging.h:342
Console.h
Gorgon::Utils::Console::Red
@ Red
Definition: Console.h:51
Gorgon::Utils::Logger::Logger
Logger(const std::string &section="", bool marktime=true, bool markdate=false)
Default constructor. Allows you to specify a section.
Definition: Logging.h:116
Gorgon::Utils::Console::None
@ None
Color is not supported.
Definition: Console.h:37
Gorgon::Utils::Logger::Logger
Logger(bool marktime, bool markdate=false)
Definition: Logging.h:125
Gorgon::Graphics::Color::Cyan
constexpr RGBA Cyan
Definition: Color.h:640
Gorgon::Utils::Console::Safelist
@ Safelist
Only colors in the safelist can be used.
Definition: Console.h:40
Gorgon::Utils::Logger::CleanUp
void CleanUp()
Cleans the stream.
Definition: Logging.h:166
Gorgon::Geometry::Size
basic_Size< int > Size
Definition: Size.h:385
Gorgon::Utils::Console::SetBold
void SetBold(bool bold=true)
Sets terminal font to bold or normal.
Gorgon::Utils::Logger::IsColorFunctional
bool IsColorFunctional() const
Returns whether the color output is currently working.
Definition: Logging.h:327
Gorgon::Utils::Logger::Notice
@ Notice
Definition: Logging.h:111
Gorgon::Utils::Console::White
@ White
Definition: Console.h:50
Gorgon::Utils::Logger::marktime
bool marktime
Definition: Logging.h:344
Gorgon::Utils::Logger::InitializeStream
void InitializeStream(std::ostream &stream)
Initializes the logger to direct its input to the given stream.
Definition: Logging.h:146
Gorgon
Root namespace for Gorgon Game Engine.
Definition: Any.h:19
Gorgon::Utils::Logger::width
int width
Definition: Logging.h:349
Gorgon::Utils::Logger::GetMarkTime
bool GetMarkTime() const
Returns whether time is being marked.
Definition: Logging.h:286
Gorgon::Utils::Console
Console manipulation functions. Not thread safe. Current only std::cout is supported.
Definition: Console.h:14
Gorgon::Utils::Logger::InitializeConsole
void InitializeConsole()
Definition: Logging.h:137
Gorgon::Utils::Logger::SetWidth
void SetWidth(int width)
Sets the width to break lines from. Set to 0 to disable.
Definition: Logging.h:176
Gorgon::Graphics::Color::Yellow
constexpr RGBA Yellow
Definition: Color.h:629
Gorgon::Utils::Logger
Eases logging procedure by appending necessary information to the given data and streams to a standar...
Definition: Logging.h:19
Gorgon::Geometry::Point
basic_Point< int > Point
Definition: Point.h:598
Gorgon::Utils::Logger::Success
@ Success
Definition: Logging.h:112
Gorgon::Utils::Logger::InitializeFile
void InitializeFile(const std::string &filename)
Opens and initializer the logger using the given filename.
Definition: Logging.h:156
Gorgon::Utils::Logger::GetMarkDate
bool GetMarkDate() const
Returns whether date is being marked.
Definition: Logging.h:296
Gorgon::Utils::Console::Blue
@ Blue
Definition: Console.h:53
Gorgon::Utils::Logger::SetSection
void SetSection(const std::string &value)
Sets the section of this logger.
Definition: Logging.h:271
Gorgon::Utils::Logger::IsColorEnabled
bool IsColorEnabled() const
Whether color is enabled, a value of true is not a warranty that color output is working,...
Definition: Logging.h:322
Gorgon::Time::Date::Now
static Date Now()
Returns current time.
Definition: Time.h:171
Gorgon::Utils::Logger::State
State
Definition: Logging.h:108
Gorgon::Utils::Logger::Logger
Logger(std::ostream &stream, const std::string &section="", bool marktime=true, bool markdate=false)
Definition: Logging.h:127
Gorgon::Utils::Logger::Error
@ Error
Definition: Logging.h:110
Gorgon::Utils::Console::IsColorSupported
bool IsColorSupported() const
Returns if the color is supported by this console.
Definition: Console.h:63
Gorgon::Utils::Logger::DisableColor
void DisableColor()
Disable color output.
Definition: Logging.h:309
Gorgon::Utils::Logger::Log
helper Log(const T_ &v, State state=Error)
Streams out the given value to the underlying stream.
Definition: Logging.h:200
Gorgon::Utils::Console::Cyan
@ Cyan
Definition: Console.h:52
Gorgon::Utils::Console::Yellow
@ Yellow
Definition: Console.h:54
Gorgon::Utils::Console::RGB
@ RGB
Graphics::RGBA can be used for color.
Definition: Console.h:43
Gorgon::Utils::Logger::Message
@ Message
Definition: Logging.h:109
Gorgon::Utils::Logger::reset
void reset(std::ostream &stream)
Definition: Logging.h:334
Gorgon::Utils::Logger::SetMarkDate
void SetMarkDate(bool value)
Sets whether to mark the date on log output.
Definition: Logging.h:291
Gorgon::Utils::Console::Black
@ Black
Definition: Console.h:49
Gorgon::Graphics::Color::Green
constexpr RGBA Green
Definition: Color.h:619
Gorgon::Utils::Logger::GetSection
std::string GetSection() const
Returns the current section of this logger.
Definition: Logging.h:276
Gorgon::Utils::Logger::hasconsole
bool hasconsole
Definition: Logging.h:347
Gorgon::Utils::Console::Green
@ Green
Definition: Console.h:56
Gorgon::Graphics::Color::Red
constexpr RGBA Red
Definition: Color.h:623
Gorgon::Utils::Logger::section
std::string section
Definition: Logging.h:351
Gorgon::Utils::Logger::Logger
Logger(const char *section, bool marktime=true, bool markdate=false)
Default constructor. Allows you to specify a section.
Definition: Logging.h:121
Gorgon::Utils::Console::Magenta
@ Magenta
Definition: Console.h:55
Gorgon::Utils::Logger::console
Console console
Definition: Logging.h:339