1 #pragma once
2 
3 #include "lib/enum/logtype.hpp"
4 #include "lib/format.hpp"
5 #include "lib/logmessage.hpp"
6 #include "lib/developermode.hpp"
7 
8 #include <iostream>
9 #include <regex>
10 
11 namespace lib
12 {
13 	/**
14 	 * Application logging
15 	 */
16 	class log
17 	{
18 	public:
19 		/**
20 		 * Log information with formatting
21 		 */
22 		template<typename Format, typename Arg, typename... Args>
info(const Format & fmt,const Arg & arg,Args &&...args)23 		static void info(const Format &fmt, const Arg &arg, Args &&... args)
24 		{
25 			return info(fmt::format(fmt, arg, args...));
26 		}
27 
28 		/**
29 		 * Log information
30 		 */
31 		template<typename Format>
info(const Format & fmt)32 		static void info(const Format &fmt)
33 		{
34 			message(log_type::information, fmt);
35 		}
36 
37 		/**
38 		 * Log warning with formatting
39 		 */
40 		template<typename Format, typename Arg, typename... Args>
warn(const Format & fmt,const Arg & arg,Args &&...args)41 		static void warn(const Format &fmt, const Arg &arg, Args &&... args)
42 		{
43 			return warn(fmt::format(fmt, arg, args...));
44 		}
45 
46 		/**
47 		 * Log warning
48 		 */
49 		template<typename Format>
warn(const Format & fmt)50 		static void warn(const Format &fmt)
51 		{
52 			message(log_type::warning, fmt);
53 		}
54 
55 		/***
56 		 * Log error with formatting
57 		 */
58 		template<typename Format, typename Arg, typename... Args>
error(const Format & fmt,const Arg & arg,Args &&...args)59 		static void error(const Format &fmt, const Arg &arg, Args &&... args)
60 		{
61 			return error(fmt::format(fmt, arg, args...));
62 		}
63 
64 		/**
65 		 * Log error
66 		 */
67 		template<typename Format>
error(const Format & fmt)68 		static void error(const Format &fmt)
69 		{
70 			message(log_type::error, fmt);
71 		}
72 
73 		/**
74 		 * Log verbose message with formatting
75 		 * @note developer_mode needs to be enabled
76 		 */
77 		template<typename Format, typename Arg, typename... Args>
dev(const Format & fmt,const Arg & arg,Args &&...args)78 		static void dev(const Format &fmt, const Arg &arg, Args &&... args)
79 		{
80 			return dev(fmt::format(fmt, arg, args...));
81 		}
82 
83 		/**
84 		 * Log verbose message
85 		 * @note developer_mode needs to be enabled
86 		 */
87 		template<typename Format>
dev(const Format & fmt)88 		static void dev(const Format &fmt)
89 		{
90 			if (!developer_mode::enabled)
91 				return;
92 
93 			message(log_type::verbose, fmt);
94 		}
95 
96 		/**
97 		 * Get all messages that has been logged since application start
98 		 * @return Log messages
99 		 */
100 		static const std::vector<log_message> &get_messages();
101 
102 		/**
103 		 * Clears all messages in the log
104 		 */
105 		static void clear();
106 
107 		/**
108 		 * Enable or disable logging to standard output/error,
109 		 * enabled by default
110 		 */
111 		static void set_log_to_stdout(bool value);
112 
113 	private:
114 		/**
115 		 * Private constructor, this is a static class
116 		 */
117 		log() = default;
118 
119 		/**
120 		 * History of all messages
121 		 */
122 		static std::vector<log_message> messages;
123 
124 		/**
125 		 * Also print to stdout/stderr
126 		 */
127 		static bool log_to_stdout;
128 
129 		/**
130 		 * Log a message with the specified type
131 		 * @param logType Type of log
132 		 * @param message Message to log
133 		 */
134 		static void message(log_type log_type, const std::string &message);
135 	};
136 }
137