From 7d03876a3e11aedff0201a8330bfdb2b5523fc5e Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Wed, 29 Jan 2014 19:22:03 +0000 Subject: Added LOGREPLACELINE for line replacement --- src/Log.cpp | 31 ++++++++++++++++++++++++++++-- src/Log.h | 4 ++-- src/MCLogger.cpp | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++------ src/MCLogger.h | 7 ++++++- src/World.cpp | 10 +++++----- 5 files changed, 94 insertions(+), 16 deletions(-) (limited to 'src') diff --git a/src/Log.cpp b/src/Log.cpp index 2d6be0f59..a23a79ccc 100644 --- a/src/Log.cpp +++ b/src/Log.cpp @@ -99,7 +99,7 @@ void cLog::ClearLog() -void cLog::Log(const char * a_Format, va_list argList) +void cLog::Log(const char * a_Format, va_list argList, bool a_ReplaceCurrentLine) { AString Message; AppendVPrintf(Message, a_Format, argList); @@ -134,7 +134,34 @@ void cLog::Log(const char * a_Format, va_list argList) __android_log_print(ANDROID_LOG_ERROR, "MCServer", "%s", Line.c_str() ); //CallJavaFunction_Void_String(g_JavaThread, "AddToLog", Line ); #else - printf("%s", Line.c_str()); + if (a_ReplaceCurrentLine) + { +#ifdef _WIN32 + if (m_LastStringSize == 0) + { + m_LastStringSize = Line.length(); + } + else if (Line.length() < m_LastStringSize) // If last printed line was longer than current, clear this line + { + for (size_t X = 0; X != m_LastStringSize; ++X) + { + fputs(" ", stdout); + } + } +#else // _WIN32 + fputs("\033[K", stdout); // Clear current line +#endif + + printf("\r%s", Line.c_str()); + +#ifdef __linux + fputs("\033[1B", stdout); // Move down one line +#endif // __linux + } + else + { + printf("%s", Line.c_str()); + } #endif #if defined (_WIN32) && defined(_DEBUG) diff --git a/src/Log.h b/src/Log.h index cba248dae..c8c26913b 100644 --- a/src/Log.h +++ b/src/Log.h @@ -10,11 +10,11 @@ class cLog private: FILE * m_File; static cLog * s_Log; - + size_t m_LastStringSize = 0; public: cLog(const AString & a_FileName); ~cLog(); - void Log(const char * a_Format, va_list argList); + void Log(const char * a_Format, va_list argList, bool a_ReplaceCurrentLine = false); void Log(const char * a_Format, ...); // tolua_begin void SimpleLog(const char * a_String); diff --git a/src/MCLogger.cpp b/src/MCLogger.cpp index 4f3e5dc0f..632ea2efe 100644 --- a/src/MCLogger.cpp +++ b/src/MCLogger.cpp @@ -119,13 +119,51 @@ void cMCLogger::LogSimple(const char* a_Text, int a_LogType /* = 0 */ ) -void cMCLogger::Log(const char * a_Format, va_list a_ArgList) +void cMCLogger::Log(const char * a_Format, va_list a_ArgList, bool a_ShouldReplaceLine) { cCSLock Lock(m_CriticalSection); - SetColor(csRegular); - m_Log->Log(a_Format, a_ArgList); - ResetColor(); - puts(""); + + if (!m_BeginLineUpdate && a_ShouldReplaceLine) + { + a_ShouldReplaceLine = false; // Print a normal line first if this is the initial replace line + m_BeginLineUpdate = true; + } + else if (m_BeginLineUpdate && !a_ShouldReplaceLine) + { + m_BeginLineUpdate = false; + } + + if (a_ShouldReplaceLine) + { +#ifdef _WIN32 + HANDLE Output = GetStdHandle(STD_OUTPUT_HANDLE); + + CONSOLE_SCREEN_BUFFER_INFO csbi; + GetConsoleScreenBufferInfo(Output, &csbi); + + COORD Position = { 0, csbi.dwCursorPosition.Y - 1 }; // Move cursor up one line + SetConsoleCursorPosition(Output, Position); + + SetColor(csRegular); + m_Log->Log(a_Format, a_ArgList, a_ShouldReplaceLine); + ResetColor(); + + Position = { 0, csbi.dwCursorPosition.Y }; // Set cursor to original position + SetConsoleCursorPosition(Output, Position); +#else // _WIN32 + fputs("\033[1A", stdout); // Move cursor up one line + SetColor(csRegular); + m_Log->Log(a_Format, a_ArgList, a_ShouldReplaceLine); + ResetColor(); +#endif + } + else + { + SetColor(csRegular); + m_Log->Log(a_Format, a_ArgList, a_ShouldReplaceLine); + ResetColor(); + puts(""); + } } @@ -188,7 +226,7 @@ void cMCLogger::SetColor(eColorScheme a_Scheme) default: ASSERT(!"Unhandled color scheme"); } SetConsoleTextAttribute(g_Console, Attrib); - #elif defined(__linux) && !defined(ANDROID_NDK) + #elif (defined(__linux) || defined(__apple)) && !defined(ANDROID_NDK) switch (a_Scheme) { case csRegular: printf("\x1b[0m"); break; // Whatever the console default is @@ -224,6 +262,14 @@ void cMCLogger::ResetColor(void) ////////////////////////////////////////////////////////////////////////// // Global functions +void LOGREPLACELINE(const char* a_Format, ...) +{ + va_list argList; + va_start(argList, a_Format); + cMCLogger::GetInstance()->Log(a_Format, argList, true); + va_end(argList); +} + void LOG(const char* a_Format, ...) { va_list argList; diff --git a/src/MCLogger.h b/src/MCLogger.h index c949a4cdf..7bcc195dd 100644 --- a/src/MCLogger.h +++ b/src/MCLogger.h @@ -21,7 +21,7 @@ public: // tolua_export ~cMCLogger(); // tolua_export - void Log(const char* a_Format, va_list a_ArgList); + void Log(const char* a_Format, va_list a_ArgList, bool a_ShouldReplaceLine = false); void Info(const char* a_Format, va_list a_ArgList); void Warn(const char* a_Format, va_list a_ArgList); void Error(const char* a_Format, va_list a_ArgList); @@ -51,12 +51,17 @@ private: /// Common initialization for all constructors, creates a logfile with the specified name and assigns s_MCLogger to this void InitLog(const AString & a_FileName); + + /** Flag to show whether a 'replace line' log command has been issued + Used to decide when to put a newline */ + bool m_BeginLineUpdate = false; }; // tolua_export +extern void LOGREPLACELINE(const char* a_Format, ...); extern void LOG(const char* a_Format, ...); extern void LOGINFO(const char* a_Format, ...); extern void LOGWARN(const char* a_Format, ...); diff --git a/src/World.cpp b/src/World.cpp index 88bbf5f8a..bac529d4a 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -100,13 +100,13 @@ protected: { for (;;) { - LOG("%d chunks to load, %d chunks to generate", + LOGREPLACELINE("%d chunks to load, %d chunks to generate", m_World->GetStorage().GetLoadQueueLength(), m_World->GetGenerator().GetQueueLength() ); - // Wait for 2 sec, but be "reasonably wakeable" when the thread is to finish - for (int i = 0; i < 20; i++) + // Wait for 0.5 sec, but be "reasonably wakeable" when the thread is to finish + for (int i = 0; i < 5; i++) { cSleep::MilliSleep(100); if (m_ShouldTerminate) @@ -152,10 +152,10 @@ protected: { for (;;) { - LOG("%d chunks remaining to light", m_Lighting->GetQueueLength() + LOGREPLACELINE("%d chunks remaining to light", m_Lighting->GetQueueLength() ); - // Wait for 2 sec, but be "reasonably wakeable" when the thread is to finish + // Wait for 0.5 sec, but be "reasonably wakeable" when the thread is to finish for (int i = 0; i < 20; i++) { cSleep::MilliSleep(100); -- cgit v1.2.3