tmxlite 1.0.0
lightweight parse for Tiled maps
Log.hpp
1/*********************************************************************
2Matt Marchant 2016 - 2021
3http://trederia.blogspot.com
4
5tmxlite - Zlib license.
6
7This software is provided 'as-is', without any express or
8implied warranty. In no event will the authors be held
9liable for any damages arising from the use of this software.
10
11Permission is granted to anyone to use this software for any purpose,
12including commercial applications, and to alter it and redistribute
13it freely, subject to the following restrictions:
14
151. The origin of this software must not be misrepresented;
16you must not claim that you wrote the original software.
17If you use this software in a product, an acknowledgment
18in the product documentation would be appreciated but
19is not required.
20
212. Altered source versions must be plainly marked as such,
22and must not be misrepresented as being the original software.
23
243. This notice may not be removed or altered from any
25source distribution.
26*********************************************************************/
27
28//flexible logging class, based on code at https://github.com/fallahn/xygine
29
30#ifndef TMXLITE_LOGGER_HPP_
31#define TMXLITE_LOGGER_HPP_
32
33#include <string>
34#include <iostream>
35#include <iomanip>
36#include <fstream>
37#include <sstream>
38#include <list>
39#include <ctime>
40
41#ifdef _MSC_VER
42#define NOMINMAX
43#include <windows.h>
44#endif //_MSC_VER
45
46
47#ifdef __ANDROID__
48 #include <android/log.h>
49 #include <cstring>
50
51 #define LOG_TAG "TMXlite-Debug"
52 //#define ALOG(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)
53
54 #define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)
55 #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__)
56#endif // __ANDROID__
57
58namespace tmx
59{
65 class Logger final
66 {
67 public:
68 enum class Output
69 {
70 Console,
71 File,
72 All
73 };
74
75 enum class Type
76 {
77 Info,
78 Warning,
79 Error
80 };
87 static void log(const std::string& message, Type type = Type::Info, Output output = Output::Console)
88 {
89 std::string outstring;
90 switch (type)
91 {
92 case Type::Info:
93 default:
94 outstring = "INFO: " + message;
95 break;
96 case Type::Error:
97 outstring = "ERROR: " + message;
98 break;
99 case Type::Warning:
100 outstring = "WARNING: " + message;
101 break;
102 }
103
104 if (output == Output::Console || output == Output::All)
105 {
106 if (type == Type::Error)
107 {
108#ifdef __ANDROID__
109
110 int outstringLength = outstring.length();
111 char outstring_chararray[outstringLength+1];
112 std::strcpy(outstring_chararray, outstring.c_str());
113 LOGE("%s",outstring_chararray);
114#endif
115 std::cerr << outstring << std::endl;
116 }
117 else
118 {
119#ifdef __ANDROID__
120 int outstringLength = outstring.length();
121 char outstring_chararray[outstringLength+1];
122 std::strcpy(outstring_chararray, outstring.c_str());
123 LOGI("%s", outstring_chararray);
124#endif
125 std::cout << outstring << std::endl;
126 }
127 const std::size_t maxBuffer = 30;
128 buffer().push_back(outstring);
129 if (buffer().size() > maxBuffer)buffer().pop_front(); //no majick here pl0x
130 updateOutString(maxBuffer);
131
132#ifdef _MSC_VER
133 outstring += "\n";
134 OutputDebugStringA(outstring.c_str());
135#endif //_MSC_VER
136 }
137 if (output == Output::File || output == Output::All)
138 {
139 //output to a log file
140 std::ofstream file("output.log", std::ios::app);
141 if (file.good())
142 {
143#ifndef __ANDROID__
144 std::time_t time = std::time(nullptr);
145 auto tm = *std::localtime(&time);
146 //put_time isn't implemented by the ndk versions of the stl
147 file.imbue(std::locale());
148 file << std::put_time(&tm, "%d/%m/%y-%H:%M:%S: ");
149#endif //__ANDROID__
150 file << outstring << std::endl;
151 file.close();
152 }
153 else
154 {
155 log(message, type, Output::Console);
156 log("Above message was intended for log file. Opening file probably failed.", Type::Warning, Output::Console);
157 }
158 }
159 }
160
161 static const std::string& bufferString(){ return stringOutput(); }
162
163 private:
164 static std::list<std::string>& buffer(){ static std::list<std::string> buffer; return buffer; }
165 static std::string& stringOutput() { static std::string output; return output; }
166 static void updateOutString(std::size_t maxBuffer)
167 {
168 static size_t count = 0;
169 stringOutput().append(buffer().back());
170 stringOutput().append("\n");
171 count++;
172
173 if (count > maxBuffer)
174 {
175 stringOutput() = stringOutput().substr(stringOutput().find_first_of('\n') + 1, stringOutput().size());
176 count--;
177 }
178 }
179 };
180}
181#ifndef _DEBUG_
182#define LOG(message, type)
183#else
184#define LOG(message, type) {\
185std::stringstream ss; \
186ss << message << " (" << __FILE__ << ", " << __LINE__ << ")"; \
187tmx::Logger::log(ss.str(), type);}
188#endif //_DEBUG_
189
190#endif //TMXLITE_LOGGER_HPP_
Class allowing messages to be logged to a combination of one or more destinations such as the console...
Definition Log.hpp:66
static void log(const std::string &message, Type type=Type::Info, Output output=Output::Console)
Logs a message to a given destination.
Definition Log.hpp:87