update Logger
This commit is contained in:
		
							parent
							
								
									ec512490dd
								
							
						
					
					
						commit
						eea3f92567
					
				|  | @ -19,6 +19,7 @@ | |||
| // THE SOFTWARE.
 | ||||
| 
 | ||||
| #include "logs.h" | ||||
| #include <iostream> | ||||
| 
 | ||||
| namespace easy2d | ||||
| { | ||||
|  | @ -68,8 +69,21 @@ namespace easy2d | |||
| 	} | ||||
| 
 | ||||
| 	Logger::Logger() | ||||
| 		: enabled_(true) | ||||
| 		, has_console_(false) | ||||
| 		, default_stdout_color_(0) | ||||
| 		, default_stderr_color_(0) | ||||
| 		, output_stream_(std::wcout.rdbuf()) | ||||
| 		, error_stream_(std::wcerr.rdbuf()) | ||||
| 	{ | ||||
| 		ResetOutputStream(); | ||||
| 	} | ||||
| 
 | ||||
| 	void Logger::ResetOutputStream() | ||||
| 	{ | ||||
| 		has_console_ = ::GetConsoleWindow() != nullptr; | ||||
| 		if (has_console_) | ||||
| 		{ | ||||
| 		enabled_ = ::GetConsoleWindow() != nullptr; | ||||
| 			default_stdout_color_ = default_stderr_color_ = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_INTENSITY; | ||||
| 
 | ||||
| 			CONSOLE_SCREEN_BUFFER_INFO stdout_info; | ||||
|  | @ -83,6 +97,20 @@ namespace easy2d | |||
| 			{ | ||||
| 				default_stderr_color_ = stderr_info.wAttributes; | ||||
| 			} | ||||
| 
 | ||||
| 			RedirectOutputStreamBuffer(std::wcout.rdbuf()); | ||||
| 			RedirectErrorStreamBuffer(std::wcerr.rdbuf()); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	std::wstreambuf* Logger::RedirectOutputStreamBuffer(std::wstreambuf* buf) | ||||
| 	{ | ||||
| 		return output_stream_.rdbuf(buf); | ||||
| 	} | ||||
| 
 | ||||
| 	std::wstreambuf* Logger::RedirectErrorStreamBuffer(std::wstreambuf* buf) | ||||
| 	{ | ||||
| 		return error_stream_.rdbuf(buf); | ||||
| 	} | ||||
| 
 | ||||
| } | ||||
|  |  | |||
|  | @ -23,7 +23,6 @@ | |||
| #include "../common/Singleton.hpp" | ||||
| #include <ctime> | ||||
| #include <iomanip> | ||||
| #include <iostream> | ||||
| #include <sstream> | ||||
| 
 | ||||
| #ifndef E2D_LOG | ||||
|  | @ -44,10 +43,81 @@ | |||
| 
 | ||||
| namespace easy2d | ||||
| { | ||||
| 	class E2D_API Logger | ||||
| 		: public Singleton<Logger> | ||||
| 	{ | ||||
| 		E2D_DECLARE_SINGLETON(Logger); | ||||
| 
 | ||||
| 	public: | ||||
| 		void Enable(); | ||||
| 
 | ||||
| 		void Disable(); | ||||
| 
 | ||||
| 		template <typename ..._Args> | ||||
| 		void Print(const wchar_t* format, _Args&&... args); | ||||
| 
 | ||||
| 		template <typename ..._Args> | ||||
| 		void Println(const wchar_t* format, _Args&&... args); | ||||
| 
 | ||||
| 		template <typename ..._Args> | ||||
| 		void Message(const wchar_t * format, _Args&&... args); | ||||
| 
 | ||||
| 		template <typename ..._Args> | ||||
| 		void Messageln(const wchar_t * format, _Args&&... args); | ||||
| 
 | ||||
| 		template <typename ..._Args> | ||||
| 		void Warning(const wchar_t* format, _Args&&... args); | ||||
| 
 | ||||
| 		template <typename ..._Args> | ||||
| 		void Warningln(const wchar_t* format, _Args&&... args); | ||||
| 
 | ||||
| 		template <typename ..._Args> | ||||
| 		void Error(const wchar_t* format, _Args&&... args); | ||||
| 
 | ||||
| 		template <typename ..._Args> | ||||
| 		void Errorln(const wchar_t* format, _Args&&... args); | ||||
| 
 | ||||
| 		std::wstreambuf* RedirectOutputStreamBuffer(std::wstreambuf* buf); | ||||
| 
 | ||||
| 		std::wstreambuf* RedirectErrorStreamBuffer(std::wstreambuf* buf); | ||||
| 
 | ||||
| 		void ResetOutputStream(); | ||||
| 
 | ||||
| 	private: | ||||
| 		Logger(); | ||||
| 
 | ||||
| 		template <typename ..._Args> | ||||
| 		void OutputLine(std::wostream& os, std::wostream&(*color)(std::wostream&), const wchar_t* prompt, const wchar_t* format, _Args&&... args) const; | ||||
| 
 | ||||
| 		template <typename ..._Args> | ||||
| 		void Output(std::wostream& os, std::wostream&(*color)(std::wostream&), const wchar_t* prompt, const wchar_t* format, _Args&&... args) const; | ||||
| 
 | ||||
| 		template <typename ..._Args> | ||||
| 		std::wstring MakeOutputString(const wchar_t* prompt, const wchar_t* format, _Args&&... args) const; | ||||
| 
 | ||||
| 		void ResetConsoleColor() const; | ||||
| 
 | ||||
| 		static std::wostream& DefaultOutputColor(std::wostream& out); | ||||
| 
 | ||||
| 		static std::wostream& OutPrefix(std::wostream& out); | ||||
| 
 | ||||
| 	private: | ||||
| 		bool enabled_; | ||||
| 		bool has_console_; | ||||
| 		WORD default_stdout_color_; | ||||
| 		WORD default_stderr_color_; | ||||
| 
 | ||||
| 		std::wostream output_stream_; | ||||
| 		std::wostream error_stream_; | ||||
| 	}; | ||||
| 
 | ||||
| 
 | ||||
| 	//
 | ||||
| 	// details of Logger
 | ||||
| 	//
 | ||||
| 
 | ||||
| 	namespace __console_colors | ||||
| 	{ | ||||
| 		using ConsoleColor = std::wostream&(*)(std::wostream&); | ||||
| 
 | ||||
| #define DECLARE_COLOR(COLOR)\ | ||||
| 		extern std::wostream&(stdout_##COLOR)(std::wostream&);\ | ||||
| 		extern std::wostream&(stderr_##COLOR)(std::wostream&); | ||||
|  | @ -73,109 +143,99 @@ namespace easy2d | |||
| #undef DECLARE_BG_COLOR | ||||
| 	} | ||||
| 
 | ||||
| 	class E2D_API Logger | ||||
| 		: public Singleton<Logger> | ||||
| 	{ | ||||
| 		E2D_DECLARE_SINGLETON(Logger); | ||||
| 
 | ||||
| 	public: | ||||
| 		inline void Enable() | ||||
| 	inline void Logger::Enable() | ||||
| 	{ | ||||
| 		enabled_ = true; | ||||
| 	} | ||||
| 
 | ||||
| 		inline void Disable() | ||||
| 	inline void Logger::Disable() | ||||
| 	{ | ||||
| 		enabled_ = false; | ||||
| 	} | ||||
| 
 | ||||
| 	template <typename ..._Args> | ||||
| 		inline void Print(const wchar_t* format, _Args&&... args) const | ||||
| 	inline void Logger::Print(const wchar_t* format, _Args&&... args) | ||||
| 	{ | ||||
| 			using namespace __console_colors; | ||||
| 			Output(std::wcout, stdout_white, nullptr, format, std::forward<_Args>(args)...); | ||||
| 		Output(output_stream_, Logger::DefaultOutputColor, nullptr, format, std::forward<_Args>(args)...); | ||||
| 	} | ||||
| 
 | ||||
| 	template <typename ..._Args> | ||||
| 		inline void Println(const wchar_t* format, _Args&&... args) const | ||||
| 	inline void Logger::Println(const wchar_t* format, _Args&&... args) | ||||
| 	{ | ||||
| 			using namespace __console_colors; | ||||
| 			OutputLine(std::wcout, stdout_white, nullptr, format, std::forward<_Args>(args)...); | ||||
| 		OutputLine(output_stream_, Logger::DefaultOutputColor, nullptr, format, std::forward<_Args>(args)...); | ||||
| 	} | ||||
| 
 | ||||
| 	template <typename ..._Args> | ||||
| 		inline void Message(const wchar_t * format, _Args&&... args) const | ||||
| 	inline void Logger::Message(const wchar_t * format, _Args&&... args) | ||||
| 	{ | ||||
| 		using namespace __console_colors; | ||||
| 			Output(std::wcout, stdout_blue, nullptr, format, std::forward<_Args>(args)...); | ||||
| 		Output(output_stream_, stdout_blue, nullptr, format, std::forward<_Args>(args)...); | ||||
| 	} | ||||
| 
 | ||||
| 	template <typename ..._Args> | ||||
| 		inline void Messageln(const wchar_t * format, _Args&&... args) const | ||||
| 	inline void Logger::Messageln(const wchar_t * format, _Args&&... args) | ||||
| 	{ | ||||
| 		using namespace __console_colors; | ||||
| 			OutputLine(std::wcout, stdout_blue, nullptr, format, std::forward<_Args>(args)...); | ||||
| 		OutputLine(output_stream_, stdout_blue, nullptr, format, std::forward<_Args>(args)...); | ||||
| 	} | ||||
| 
 | ||||
| 	template <typename ..._Args> | ||||
| 		inline void Warning(const wchar_t* format, _Args&&... args) const | ||||
| 	inline void Logger::Warning(const wchar_t* format, _Args&&... args) | ||||
| 	{ | ||||
| 		using namespace __console_colors; | ||||
| 			Output(std::wcerr, stdout_yellow_bg, L"Warning: ", format, std::forward<_Args>(args)...); | ||||
| 		Output(output_stream_, stdout_yellow_bg, L"Warning: ", format, std::forward<_Args>(args)...); | ||||
| 	} | ||||
| 
 | ||||
| 	template <typename ..._Args> | ||||
| 		inline void Warningln(const wchar_t* format, _Args&&... args) const | ||||
| 	inline void Logger::Warningln(const wchar_t* format, _Args&&... args) | ||||
| 	{ | ||||
| 		using namespace __console_colors; | ||||
| 			OutputLine(std::wcerr, stdout_yellow_bg, L"Warning: ", format, std::forward<_Args>(args)...); | ||||
| 		OutputLine(output_stream_, stdout_yellow_bg, L"Warning: ", format, std::forward<_Args>(args)...); | ||||
| 	} | ||||
| 
 | ||||
| 	template <typename ..._Args> | ||||
| 		inline void Error(const wchar_t* format, _Args&&... args) const | ||||
| 	inline void Logger::Error(const wchar_t* format, _Args&&... args) | ||||
| 	{ | ||||
| 		using namespace __console_colors; | ||||
| 			Output(std::wcerr, stderr_red_bg, L"Error: ", format, std::forward<_Args>(args)...); | ||||
| 		Output(error_stream_, stderr_red_bg, L"Error: ", format, std::forward<_Args>(args)...); | ||||
| 	} | ||||
| 
 | ||||
| 	template <typename ..._Args> | ||||
| 		inline void Errorln(const wchar_t* format, _Args&&... args) const | ||||
| 	inline void Logger::Errorln(const wchar_t* format, _Args&&... args) | ||||
| 	{ | ||||
| 		using namespace __console_colors; | ||||
| 			OutputLine(std::wcerr, stderr_red_bg, L"Error: ", format, std::forward<_Args>(args)...); | ||||
| 		OutputLine(error_stream_, stderr_red_bg, L"Error: ", format, std::forward<_Args>(args)...); | ||||
| 	} | ||||
| 
 | ||||
| 	private: | ||||
| 		Logger(); | ||||
| 
 | ||||
| 	template <typename ..._Args> | ||||
| 		inline void OutputLine(std::wostream& os, __console_colors::ConsoleColor color, const wchar_t* prompt, const wchar_t* format, _Args&&... args) const | ||||
| 	inline void Logger::OutputLine(std::wostream& os, std::wostream&(*color)(std::wostream&), const wchar_t* prompt, const wchar_t* format, _Args&&... args) const | ||||
| 	{ | ||||
| 		if (enabled_ && has_console_) | ||||
| 		{ | ||||
| 			if (!enabled_) | ||||
| 				return; | ||||
| 
 | ||||
| 			Output(os, color, prompt, format, std::forward<_Args>(args)...); | ||||
| 
 | ||||
| 			os << std::endl; | ||||
| 			::OutputDebugStringW(L"\r\n"); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	template <typename ..._Args> | ||||
| 		inline void Output(std::wostream& os, __console_colors::ConsoleColor color, const wchar_t* prompt, const wchar_t* format, _Args&&... args) const | ||||
| 	inline void Logger::Output(std::wostream& os, std::wostream&(*color)(std::wostream&), const wchar_t* prompt, const wchar_t* format, _Args&&... args) const | ||||
| 	{ | ||||
| 		if (enabled_ && has_console_) | ||||
| 		{ | ||||
| 			if (!enabled_) | ||||
| 				return; | ||||
| 
 | ||||
| 			std::wstring output = MakeOutputString(prompt, format, std::forward<_Args>(args)...); | ||||
| 
 | ||||
| 			os << color << output; | ||||
| 			::OutputDebugStringW(output.c_str()); | ||||
| 
 | ||||
| 			ResetColor(); | ||||
| 			ResetConsoleColor(); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	template <typename ..._Args> | ||||
| 		inline std::wstring MakeOutputString(const wchar_t* prompt, const wchar_t* format, _Args&&... args) const | ||||
| 	inline std::wstring Logger::MakeOutputString(const wchar_t* prompt, const wchar_t* format, _Args&&... args) const | ||||
| 	{ | ||||
| 		static wchar_t temp_buffer[1024 * 3 + 1]; | ||||
| 
 | ||||
|  | @ -193,13 +253,19 @@ namespace easy2d | |||
| 		return ss.str(); | ||||
| 	} | ||||
| 
 | ||||
| 		inline void ResetColor() const | ||||
| 	inline void Logger::ResetConsoleColor() const | ||||
| 	{ | ||||
| 		::SetConsoleTextAttribute(::GetStdHandle(STD_OUTPUT_HANDLE), default_stdout_color_); | ||||
| 		::SetConsoleTextAttribute(::GetStdHandle(STD_ERROR_HANDLE), default_stderr_color_); | ||||
| 	} | ||||
| 
 | ||||
| 		static inline std::wostream& OutPrefix(std::wostream& out) | ||||
| 	inline std::wostream& Logger::DefaultOutputColor(std::wostream& out) | ||||
| 	{ | ||||
| 		::SetConsoleTextAttribute(::GetStdHandle(STD_OUTPUT_HANDLE), Logger::Instance().default_stdout_color_); | ||||
| 		return out; | ||||
| 	} | ||||
| 
 | ||||
| 	inline std::wostream& Logger::OutPrefix(std::wostream& out) | ||||
| 	{ | ||||
| 		std::time_t unix = std::time(nullptr); | ||||
| 		std::tm tmbuf; | ||||
|  | @ -207,12 +273,6 @@ namespace easy2d | |||
| 		out << std::put_time(&tmbuf, L"[easy2d] %H:%M:%S "); | ||||
| 		return out; | ||||
| 	} | ||||
| 
 | ||||
| 	private: | ||||
| 		bool enabled_; | ||||
| 		WORD default_stdout_color_; | ||||
| 		WORD default_stderr_color_; | ||||
| 	}; | ||||
| } | ||||
| 
 | ||||
| namespace easy2d | ||||
|  |  | |||
|  | @ -31,9 +31,98 @@ | |||
| #include <windowsx.h> | ||||
| #include <imm.h> | ||||
| #include <iostream> | ||||
| #include <fstream> | ||||
| 
 | ||||
| #pragma comment(lib, "imm32.lib") | ||||
| 
 | ||||
| namespace | ||||
| { | ||||
| 	std::streambuf *cin_buffer, *cout_buffer, *cerr_buffer; | ||||
| 	std::fstream console_input, console_output, console_error; | ||||
| 
 | ||||
| 	std::wstreambuf *wcin_buffer, *wcout_buffer, *wcerr_buffer; | ||||
| 	std::wfstream wconsole_input, wconsole_output, wconsole_error; | ||||
| 
 | ||||
| 	void RedirectStdIO() | ||||
| 	{ | ||||
| 		cin_buffer = std::cin.rdbuf(); | ||||
| 		cout_buffer = std::cout.rdbuf(); | ||||
| 		cerr_buffer = std::cerr.rdbuf(); | ||||
| 		wcin_buffer = std::wcin.rdbuf(); | ||||
| 		wcout_buffer = std::wcout.rdbuf(); | ||||
| 		wcerr_buffer = std::wcerr.rdbuf(); | ||||
| 
 | ||||
| 		console_input.open("CONIN$", std::ios::in); | ||||
| 		console_output.open("CONOUT$", std::ios::out); | ||||
| 		console_error.open("CONOUT$", std::ios::out); | ||||
| 		wconsole_input.open("CONIN$", std::ios::in); | ||||
| 		wconsole_output.open("CONOUT$", std::ios::out); | ||||
| 		wconsole_error.open("CONOUT$", std::ios::out); | ||||
| 
 | ||||
| 		std::cin.rdbuf(console_input.rdbuf()); | ||||
| 		std::cout.rdbuf(console_output.rdbuf()); | ||||
| 		std::cerr.rdbuf(console_error.rdbuf()); | ||||
| 		std::wcin.rdbuf(wconsole_input.rdbuf()); | ||||
| 		std::wcout.rdbuf(wconsole_output.rdbuf()); | ||||
| 		std::wcerr.rdbuf(wconsole_error.rdbuf()); | ||||
| 	} | ||||
| 
 | ||||
| 	void ResetStdIO() | ||||
| 	{ | ||||
| 		console_input.close(); | ||||
| 		console_output.close(); | ||||
| 		console_error.close(); | ||||
| 		wconsole_input.close(); | ||||
| 		wconsole_output.close(); | ||||
| 		wconsole_error.close(); | ||||
| 
 | ||||
| 		std::cin.rdbuf(cin_buffer); | ||||
| 		std::cout.rdbuf(cout_buffer); | ||||
| 		std::cerr.rdbuf(cerr_buffer); | ||||
| 		std::wcin.rdbuf(wcin_buffer); | ||||
| 		std::wcout.rdbuf(wcout_buffer); | ||||
| 		std::wcerr.rdbuf(wcerr_buffer); | ||||
| 
 | ||||
| 		cin_buffer = nullptr; | ||||
| 		cout_buffer = nullptr; | ||||
| 		cerr_buffer = nullptr; | ||||
| 		wcin_buffer = nullptr; | ||||
| 		wcout_buffer = nullptr; | ||||
| 		wcerr_buffer = nullptr; | ||||
| 	} | ||||
| 
 | ||||
| 	HWND allocated_console = nullptr; | ||||
| 
 | ||||
| 	HWND AllocateConsole() | ||||
| 	{ | ||||
| 		if (::AllocConsole()) | ||||
| 		{ | ||||
| 			allocated_console = ::GetConsoleWindow(); | ||||
| 
 | ||||
| 			if (allocated_console) | ||||
| 			{ | ||||
| 				RedirectStdIO(); | ||||
| 			} | ||||
| 		} | ||||
| 		return allocated_console; | ||||
| 	} | ||||
| 
 | ||||
| 	void FreeAllocatedConsole() | ||||
| 	{ | ||||
| 		if (allocated_console) | ||||
| 		{ | ||||
| 			ResetStdIO(); | ||||
| 			::FreeConsole(); | ||||
| 			allocated_console = nullptr; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	HWND GetAllocatedConsole() | ||||
| 	{ | ||||
| 		return allocated_console; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| namespace easy2d | ||||
| { | ||||
| 	Application::Application() | ||||
|  | @ -51,6 +140,8 @@ namespace easy2d | |||
| 	{ | ||||
| 		Destroy(); | ||||
| 
 | ||||
| 		FreeAllocatedConsole(); | ||||
| 
 | ||||
| 		::CoUninitialize(); | ||||
| 	} | ||||
| 
 | ||||
|  | @ -321,8 +412,6 @@ namespace easy2d | |||
| 
 | ||||
| 	void Application::ShowConsole(bool show) | ||||
| 	{ | ||||
| 		static HWND allocated_console = nullptr; | ||||
| 
 | ||||
| 		HWND current_console = ::GetConsoleWindow(); | ||||
| 		if (show) | ||||
| 		{ | ||||
|  | @ -332,44 +421,26 @@ namespace easy2d | |||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				if (!::AllocConsole()) | ||||
| 				HWND console = ::AllocateConsole(); | ||||
| 				if (!console) | ||||
| 				{ | ||||
| 					E2D_WARNING_LOG(L"AllocConsole failed"); | ||||
| 				} | ||||
| 				else | ||||
| 				{ | ||||
| 					allocated_console = ::GetConsoleWindow(); | ||||
| 
 | ||||
| 					if (allocated_console) | ||||
| 					{ | ||||
| 						FILE * dummy; | ||||
| 						freopen_s(&dummy, "CONOUT$", "w+t", stdout); | ||||
| 						freopen_s(&dummy, "CONIN$", "r+t", stdin); | ||||
| 						freopen_s(&dummy, "CONOUT$", "w+t", stderr); | ||||
| 						(void)dummy; | ||||
| 
 | ||||
| 						std::cout.clear(); | ||||
| 						std::wcout.clear(); | ||||
| 						std::cin.clear(); | ||||
| 						std::wcin.clear(); | ||||
| 						std::cerr.clear(); | ||||
| 						std::wcerr.clear(); | ||||
| 
 | ||||
| 					// disable the close button of console
 | ||||
| 						HMENU hmenu = ::GetSystemMenu(allocated_console, FALSE); | ||||
| 					HMENU hmenu = ::GetSystemMenu(console, FALSE); | ||||
| 					::RemoveMenu(hmenu, SC_CLOSE, MF_BYCOMMAND); | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			if (current_console) | ||||
| 			{ | ||||
| 				if (current_console == allocated_console) | ||||
| 				if (current_console == GetAllocatedConsole()) | ||||
| 				{ | ||||
| 					::FreeConsole(); | ||||
| 					allocated_console = nullptr; | ||||
| 					FreeAllocatedConsole(); | ||||
| 				} | ||||
| 				else | ||||
| 				{ | ||||
|  | @ -377,6 +448,8 @@ namespace easy2d | |||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		Logger::Instance().ResetOutputStream(); | ||||
| 	} | ||||
| 
 | ||||
| 	LRESULT CALLBACK Application::WndProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) | ||||
|  | @ -526,8 +599,6 @@ namespace easy2d | |||
| 		{ | ||||
| 			bool active = (LOWORD(wparam) != WA_INACTIVE); | ||||
| 
 | ||||
| 			E2D_LOG(active ? L"Window activated" : L"Window deactivated"); | ||||
| 
 | ||||
| 			app->GetWindow()->SetActive(active); | ||||
| 
 | ||||
| 			if (app->curr_scene_) | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue