PixelBullet  0.0.1
A C++ game engine
Loading...
Searching...
No Matches
Log.hpp
1#pragma once
2
3#include <fmt/ostream.h>
4
5#include <array>
6#include <fstream>
7#include <memory>
8#include <mutex>
9#include <string>
10#include <vector>
11
12namespace PixelBullet::Log
13{
14 enum class Level
15 {
16 Trace = 0,
17 Info,
18 Warn,
19 Error,
20 Critical,
21 Count
22 };
23
24 inline constexpr std::array<const char*, static_cast<size_t>(Level::Count)> LEVEL_STRINGS = { "TRACE:", "INFO:",
25 "WARN:", "ERROR:",
26 "CRITICAL:" };
27
28 inline constexpr const char* ToString(Level level)
29 {
30 return LEVEL_STRINGS[static_cast<size_t>(level)];
31 }
32
33 class Sink
34 {
35 public:
36 virtual ~Sink() = default;
37
38 virtual void Log(const std::string& channelName, const std::string& message, Level level) = 0;
39
40 void SetMinLevel(Level level)
41 {
42 m_MinLevel = level;
43 }
44 Level GetMinLevel() const
45 {
46 return m_MinLevel;
47 }
48
49 protected:
50 Level m_MinLevel = Level::Trace;
51 std::mutex m_Mutex;
52 };
53
54 class ConsoleSink : public Sink
55 {
56 public:
57 explicit ConsoleSink(Level minLevel = Level::Trace)
58 {
59 m_MinLevel = minLevel;
60 }
61
62 void Log(const std::string& channelName, const std::string& message, Level level) override;
63 };
64
65 class FileSink : public Sink
66 {
67 public:
68 explicit FileSink(const std::string& filename, Level minLevel = Level::Trace);
69 ~FileSink();
70
71 void Log(const std::string& channelName, const std::string& message, Level level) override;
72
73 private:
74 std::ofstream m_FileStream;
75 };
76
77 class Channel final
78 {
79 public:
80 static void Init();
81
82 static std::shared_ptr<Channel>& Core();
83 static std::shared_ptr<Channel>& Client();
84
85 template <typename... Args>
86 void Log(Level level, fmt::format_string<Args...> fmtStr, Args&&... args)
87 {
88 std::string message = fmt::format(fmtStr, std::forward<Args>(args)...);
89
90 for (auto& sink : m_Sinks)
91 {
92 sink->Log(m_Name, message, level);
93 }
94 }
95
96 Channel(const Channel&) = delete;
97 Channel& operator=(const Channel&) = delete;
98
99 private:
100 explicit Channel(std::string name);
101
102 void AddSink(const std::shared_ptr<Sink>& sink);
103
104 std::string m_Name;
105 std::vector<std::shared_ptr<Sink>> m_Sinks;
106
107 static std::shared_ptr<Channel> s_CoreChannel;
108 static std::shared_ptr<Channel> s_ClientChannel;
109 };
110
111 template <typename... Args>
112 void Trace(fmt::format_string<Args...> fmtStr, Args&&... args)
113 {
114 Channel::Core()->Log(Level::Trace, fmtStr, std::forward<Args>(args)...);
115 }
116
117 template <typename... Args>
118 void Info(fmt::format_string<Args...> fmtStr, Args&&... args)
119 {
120 Channel::Core()->Log(Level::Info, fmtStr, std::forward<Args>(args)...);
121 }
122
123 template <typename... Args>
124 void Warn(fmt::format_string<Args...> fmtStr, Args&&... args)
125 {
126 Channel::Core()->Log(Level::Warn, fmtStr, std::forward<Args>(args)...);
127 }
128
129 template <typename... Args>
130 void Error(fmt::format_string<Args...> fmtStr, Args&&... args)
131 {
132 Channel::Core()->Log(Level::Error, fmtStr, std::forward<Args>(args)...);
133 }
134
135 template <typename... Args>
136 void Critical(fmt::format_string<Args...> fmtStr, Args&&... args)
137 {
138 Channel::Core()->Log(Level::Critical, fmtStr, std::forward<Args>(args)...);
139 }
140
141} // namespace PixelBullet::Log
142
143namespace Log
144{
145 template <typename... Args>
146 void Trace(fmt::format_string<Args...> fmtStr, Args&&... args)
147 {
148 PixelBullet::Log::Channel::Client()->Log(PixelBullet::Log::Level::Trace, fmtStr, std::forward<Args>(args)...);
149 }
150
151 template <typename... Args>
152 void Info(fmt::format_string<Args...> fmtStr, Args&&... args)
153 {
154 PixelBullet::Log::Channel::Client()->Log(PixelBullet::Log::Level::Info, fmtStr, std::forward<Args>(args)...);
155 }
156
157 template <typename... Args>
158 void Warn(fmt::format_string<Args...> fmtStr, Args&&... args)
159 {
160 PixelBullet::Log::Channel::Client()->Log(PixelBullet::Log::Level::Warn, fmtStr, std::forward<Args>(args)...);
161 }
162
163 template <typename... Args>
164 void Error(fmt::format_string<Args...> fmtStr, Args&&... args)
165 {
166 PixelBullet::Log::Channel::Client()->Log(PixelBullet::Log::Level::Error, fmtStr, std::forward<Args>(args)...);
167 }
168
169 template <typename... Args>
170 void Critical(fmt::format_string<Args...> fmtStr, Args&&... args)
171 {
172 PixelBullet::Log::Channel::Client()->Log(PixelBullet::Log::Level::Critical, fmtStr,
173 std::forward<Args>(args)...);
174 }
175} // namespace Log
Definition Log.hpp:78
Definition Log.hpp:55
Definition Log.hpp:66
Definition Log.hpp:34