Skip to content

Commit

Permalink
Refactor CLogWriter for portability and optimization.
Browse files Browse the repository at this point in the history
This update improves the `CLogWriter` class by enhancing portability and
performance:

- Replaced WinAPI's `CreateFile` with `std::fstream` for file operations,
  ensuring compatibility across platforms.
- Updated timestamp generation to use `std::chrono`, improving code clarity
  and modernizing time handling.
- Introduced a `std::mutex` for thread-safe logging to address potential
  concurrency issues.
- Simplified and standardized log messages using `std::format`, improving
  readability and maintainability.

These changes modernize the logging implementation, making it more
portable and easier to maintain while adhering to modern C++ standards.
  • Loading branch information
stevewgr committed Nov 19, 2024
1 parent 081569c commit 37f5024
Show file tree
Hide file tree
Showing 30 changed files with 176 additions and 267 deletions.
2 changes: 2 additions & 0 deletions src/common/StdBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,5 @@

#include <random>
#include <filesystem>
#include <chrono>
#include <mutex>
140 changes: 38 additions & 102 deletions src/engine/N3Base/LogWriter.cpp
Original file line number Diff line number Diff line change
@@ -1,138 +1,74 @@
// LogWriter.cpp: implementation of the CLogWriter class.
//
//////////////////////////////////////////////////////////////////////

#include <stdio.h>
#include "StdAfx.h"
#include "LogWriter.h"

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
//HANDLE CLogWriter::s_hFile = NULL;
fs::path CLogWriter::s_fsLogFile;

CLogWriter::CLogWriter() {}

CLogWriter::~CLogWriter() {}
static std::mutex s_mtxLog;

void CLogWriter::Open(const fs::path & fsFile) {
// if (s_hFile || fsFile.empty()) {
// return;
// }
if (fsFile.empty()) {
return;
}

s_fsLogFile = fsFile;
std::lock_guard<std::mutex> lock(s_mtxLog);

HANDLE hFile = CreateFileW(s_fsLogFile.c_str(), GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (INVALID_HANDLE_VALUE == hFile) {
hFile = CreateFileW(s_fsLogFile.c_str(), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (INVALID_HANDLE_VALUE == hFile) {
return;
}
}
s_fsLogFile = fsFile;

DWORD dwSizeHigh = 0;
DWORD dwSizeLow = ::GetFileSize(hFile, &dwSizeHigh);
if (dwSizeLow > 256000) // 파일 사이즈가 너무 크면 지운다..
{
CloseHandle(hFile);
// Remove the file if its size exceeds 512 KB
if (fs::exists(s_fsLogFile) && fs::file_size(s_fsLogFile) > 512000) {
fs::remove(s_fsLogFile);
hFile = CreateFileW(s_fsLogFile.c_str(), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (INVALID_HANDLE_VALUE == hFile) {
return;
}
}

::SetFilePointer(hFile, 0, NULL, FILE_END); // 추가 하기 위해서 파일의 끝으로 옮기고..

char szBuff[1024];
SYSTEMTIME time;
GetLocalTime(&time);
DWORD dwRWC = 0;

sprintf(szBuff, "---------------------------------------------------------------------------\r\n");
int iLength = lstrlen(szBuff);
WriteFile(hFile, szBuff, iLength, &dwRWC, NULL);
std::ofstream ofsFile(s_fsLogFile, std::ios::app | std::ios::binary);
if (!ofsFile) {
return;
}

sprintf(szBuff, "// Begin writing log... [%.2d/%.2d %.2d:%.2d]\r\n", time.wMonth, time.wDay, time.wHour,
time.wMinute);
iLength = lstrlen(szBuff);
WriteFile(hFile, szBuff, iLength, &dwRWC, NULL);
auto tpNow = std::chrono::system_clock::now();
auto tmLocal = std::chrono::current_zone()->to_local(tpNow);

CloseHandle(hFile);
ofsFile << "---------------------------------------------------------------------------\n";
ofsFile << std::format("// Begin writing log... [{:%m/%d %H:%M}]\n", tmLocal);
}

void CLogWriter::Close() {
HANDLE hFile = CreateFileW(s_fsLogFile.c_str(), GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (INVALID_HANDLE_VALUE == hFile) {
hFile = CreateFileW(s_fsLogFile.c_str(), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (INVALID_HANDLE_VALUE == hFile) {
hFile = NULL;
}
if (s_fsLogFile.empty()) {
return;
}

if (hFile) {
::SetFilePointer(hFile, 0, NULL, FILE_END); // 추가 하기 위해서 파일의 끝으로 옮기고..
std::lock_guard<std::mutex> lock(s_mtxLog);

char szBuff[1024];
SYSTEMTIME time;
GetLocalTime(&time);
DWORD dwRWC = 0;
std::ofstream ofsFile(s_fsLogFile, std::ios::app | std::ios::binary);
if (!ofsFile) {
return;
}

sprintf(szBuff, "// End writing log... [%.2d/%.2d %.2d:%.2d]\r\n", time.wMonth, time.wDay, time.wHour,
time.wMinute);
int iLength = lstrlen(szBuff);
WriteFile(hFile, szBuff, iLength, &dwRWC, NULL);
auto tpNow = std::chrono::system_clock::now();
auto tmLocal = std::chrono::current_zone()->to_local(tpNow);

sprintf(szBuff, "---------------------------------------------------------------------------\r\n");
iLength = lstrlen(szBuff);
WriteFile(hFile, szBuff, iLength, &dwRWC, NULL);
ofsFile << std::format("// End writing log... [{:%m/%d %H:%M}]\n", tmLocal);
ofsFile << "---------------------------------------------------------------------------\n";

CloseHandle(hFile);
hFile = NULL;
}
s_fsLogFile.clear();
}

void CLogWriter::Write(const char * lpszFormat, ...) {
if (s_fsLogFile.empty() || NULL == lpszFormat) {
void CLogWriter::WriteImpl(std::string_view szFmt, const std::format_args fmtArgs) {
if (s_fsLogFile.empty() || szFmt.empty()) {
return;
}

static char szFinal[1024];
static SYSTEMTIME time;
GetLocalTime(&time);
szFinal[0] = NULL;

DWORD dwRWC = 0;
sprintf(szFinal, " [%.2d:%.2d:%.2d] ", time.wHour, time.wMinute, time.wSecond);

static char szBuff[1024];
szBuff[0] = NULL;
va_list argList;
va_start(argList, lpszFormat);
vsprintf(szBuff, lpszFormat, argList);
va_end(argList);
N3_DEBUG("CLogWriter::Write: {}", szBuff);

lstrcat(szFinal, szBuff);
lstrcat(szFinal, "\r\n");
int iLength = lstrlen(szFinal);

HANDLE hFile = CreateFileW(s_fsLogFile.c_str(), GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (INVALID_HANDLE_VALUE == hFile) {
hFile = CreateFileW(s_fsLogFile.c_str(), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (INVALID_HANDLE_VALUE == hFile) {
hFile = NULL;
}
}
std::lock_guard<std::mutex> lock(s_mtxLog);

std::string szMsg = std::vformat(szFmt, fmtArgs);
N3_DEBUG("CLogWriter::Write: {:s}", szMsg);

auto tpNow = std::chrono::system_clock::now();
auto tmLocal = std::chrono::current_zone()->to_local(tpNow);

if (hFile) {
::SetFilePointer(hFile, 0, NULL, FILE_END); // 추가 하기 위해서 파일의 끝으로 옮기고..
std::string szLog = std::format(" [{:%H:%M:%S}] ", tmLocal) + szMsg + "\n";

WriteFile(hFile, szFinal, iLength, &dwRWC, NULL);
CloseHandle(hFile);
std::ofstream ofsFile(s_fsLogFile, std::ios::app | std::ios::binary);
if (ofsFile) {
ofsFile.write(szLog.c_str(), szLog.size());
}
}
22 changes: 9 additions & 13 deletions src/engine/N3Base/LogWriter.h
Original file line number Diff line number Diff line change
@@ -1,21 +1,17 @@
// LogWriter.h: interface for the CLogWriter class.
//
//////////////////////////////////////////////////////////////////////

#pragma once

#include <string>

class CLogWriter {
protected:
// static HANDLE s_hFile;
static fs::path s_fsLogFile;

public:
static void Open(const fs::path & fsFile);
static void Close();
static void Write(const char * lpszFormat, ...);

CLogWriter();
virtual ~CLogWriter();
template <class... T> static void Write(std::string_view szFmt, T &&... fmtArgs) {
WriteImpl(szFmt, std::make_format_args(fmtArgs...));
}

private:
static void WriteImpl(std::string_view szFmt, const std::format_args fmtArgs);

private:
static fs::path s_fsLogFile;
};
6 changes: 3 additions & 3 deletions src/engine/N3Base/N3BaseFileAccess.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,12 +68,12 @@ bool CN3BaseFileAccess::LoadFromFile() {
HANDLE hFile =
::CreateFileW(FilePathAbs().c_str(), GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (INVALID_HANDLE_VALUE == hFile) {
std::string szErr = FilePathAbs().string() + " - Can't open file (read)";
std::string szErr = std::format("{:s} - Can't open file (read)", FilePathAbs());
#ifdef _N3TOOL
MessageBox(::GetActiveWindow(), szErr.c_str(), "File Handle error", MB_OK);
#endif
#ifdef _N3GAME
CLogWriter::Write(szErr.c_str());
CLogWriter::Write(szErr);
#endif
return false;
}
Expand All @@ -98,7 +98,7 @@ bool CN3BaseFileAccess::SaveToFile() {
HANDLE hFile =
::CreateFileW(FilePathAbs().c_str(), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE) {
std::string szErr = FilePathAbs().string() + " - Can't open file(write)";
std::string szErr = std::format("{:s} - Can't open file(write)", FilePathAbs());
MessageBox(::GetActiveWindow(), szErr.c_str(), "File Handle error", MB_OK);
return false;
}
Expand Down
6 changes: 3 additions & 3 deletions src/engine/N3Base/N3Eng.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ bool CN3Eng::Init(BOOL bWindowed, HWND hWnd, DWORD dwWidth, DWORD dwHeight, DWOR
errMsg << "]";
MessageBox(hWnd, errMsg.str().c_str(), "Initialization", MB_OK);
#ifdef _N3GAME
CLogWriter::Write(errMsg.str().c_str());
CLogWriter::Write(errMsg.str());
#endif
LocalFree(pszDebug);
// for (int iii = 0; iii < 3; iii++) { // 여러번 삑~
Expand Down Expand Up @@ -403,7 +403,7 @@ void CN3Eng::Present(HWND hWnd, RECT * pRC) {
#ifdef _N3GAME
// char szErr[256];
// D3DXGetErrorString(rval, szErr, 256);
// CLogWriter::Write("CNEng::Present - device present failed (%s)", szErr);
// CLogWriter::Write("CNEng::Present - device present failed ({:s})", szErr);
// Beep(2000, 50);
#endif
} else {
Expand All @@ -414,7 +414,7 @@ void CN3Eng::Present(HWND hWnd, RECT * pRC) {
#ifdef _N3GAME
// char szErr[256];
// D3DXGetErrorString(rval, szErr, 256);
// CLogWriter::Write("CNEng::Present - device present failed (%s)", szErr);
// CLogWriter::Write("CNEng::Present - device present failed ({:s})", szErr);
// Beep(2000, 50);
#endif
}
Expand Down
2 changes: 1 addition & 1 deletion src/engine/N3Base/N3FXShape.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,7 @@ bool CN3FXSPart::Load(HANDLE hFile) {

ReadFile(hFile, &iLen, 4, &dwRWC, NULL); // Mesh FileName
if (iLen <= 0) {
N3_ERROR("CN3FXShape's n3shape file without n3pmesh ({:s})", FilePath().string());
N3_ERROR("CN3FXShape's n3shape file without n3pmesh ({:s})", FilePath());
return false;
}

Expand Down
4 changes: 2 additions & 2 deletions src/engine/N3Base/N3IMesh.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ bool CN3IMesh::Create(int nFC, int nVC, int nUVC) {

#ifdef _N3GAME
if (nFC > 32768) {
CLogWriter::Write("CN3IMesh::Create - Too many faces. (more than 32768) (%s)", FilePath().string().c_str());
CLogWriter::Write("CN3IMesh::Create - Too many faces. (more than 32768) ({:s})", FilePath());
}
#endif

Expand All @@ -96,7 +96,7 @@ bool CN3IMesh::Create(int nFC, int nVC, int nUVC) {
//
// if (NULL == m_lpVB) {
//#ifdef _N3GAME
// CLogWriter::Write("CN3IMesh::Create - Can't Create VertexBuffer (%s)", FilePath().string().c_str());
// CLogWriter::Write("CN3IMesh::Create - Can't Create VertexBuffer ({:s})", FilePath());
//#endif
// this->Release();
// return false;
Expand Down
6 changes: 2 additions & 4 deletions src/engine/N3Base/N3Mesh.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -146,8 +146,7 @@ void CN3Mesh::Create(int nVC, int nIC) {
{
#ifdef _N3GAME
if (nVC > 32768) {
CLogWriter::Write("CN3IMesh::Create - Too many vertices. (more than 32768) (%s)",
FilePath().string().c_str());
CLogWriter::Write("CN3IMesh::Create - Too many vertices. (more than 32768) ({:s})", FilePath());
}
#endif
if (m_pVertices) {
Expand All @@ -162,8 +161,7 @@ void CN3Mesh::Create(int nVC, int nIC) {
{
#ifdef _N3GAME
if (nIC > 32768) {
CLogWriter::Write("CN3IMesh::Create - Too many indices. (more than 32768) (%s)",
FilePath().string().c_str());
CLogWriter::Write("CN3IMesh::Create - Too many indices. (more than 32768) ({:s})", FilePath());
}
#endif
if (m_psnIndices) {
Expand Down
6 changes: 3 additions & 3 deletions src/engine/N3Base/N3SndEng.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ bool CN3SndEng::LoadSource(LPSOUNDSOURCE pSrc) {
HRESULT hr = WaveFile.Open(pSrc->fsFile, NULL, 1); //#define WAVEFILE_READ 1
if (FAILED(hr)) {
#ifdef _N3GAME
CLogWriter::Write("CN3SndEng::LoadSource - WaveFile Open Failed.. (%)", pSrc->fsFile.string().c_str());
CLogWriter::Write("CN3SndEng::LoadSource - WaveFile Open Failed.. ({:s})", pSrc->fsFile);
#endif
return false;
}
Expand All @@ -157,14 +157,14 @@ bool CN3SndEng::LoadSource(LPSOUNDSOURCE pSrc) {
hr = m_pDS->CreateSoundBuffer(&dsbd, &(pSrc->pDSBuff), NULL);
if (FAILED(hr)) {
#ifdef _N3GAME
CLogWriter::Write("CN3SndEng::LoadSource - CreateSoundBuffer Failed.. (%)", pSrc->fsFile.string().c_str());
CLogWriter::Write("CN3SndEng::LoadSource - CreateSoundBuffer Failed.. ({:s})", pSrc->fsFile);
#endif
return false;
}

if (!FillBufferWithSound(pSrc, &WaveFile)) {
#ifdef _N3GAME
CLogWriter::Write("CN3SndEng::LoadSource - FillBufferWithSound Failed.. (%)", pSrc->fsFile.string().c_str());
CLogWriter::Write("CN3SndEng::LoadSource - FillBufferWithSound Failed.. ({:s})", pSrc->fsFile);
#endif
return false;
}
Expand Down
6 changes: 3 additions & 3 deletions src/engine/N3Base/N3SndObj.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ bool CN3SndObj::Create(const fs::path & fsFile, e_SndType eType) {
if (FAILED(hr)) {
#ifdef _N3GAME
if (!fsFile.empty()) {
CLogWriter::Write("CN3SndEng::LoadSource - WaveFile Open Failed.. (%s)", fsFile.string().c_str());
CLogWriter::Write("CN3SndEng::LoadSource - WaveFile Open Failed.. ({:s})", fsFile);
}
#endif
return false;
Expand All @@ -212,14 +212,14 @@ bool CN3SndObj::Create(const fs::path & fsFile, e_SndType eType) {
hr = s_lpDS->CreateSoundBuffer(&dsbd, &m_lpDSBuff, NULL);
if (FAILED(hr)) {
#ifdef _N3GAME
CLogWriter::Write("CN3SndObj::Create - CreateSoundBuffer Failed.. (%)", fsFile.string().c_str());
CLogWriter::Write("CN3SndObj::Create - CreateSoundBuffer Failed.. {:s})", fsFile);
#endif
return false;
}

if (!FillBufferWithSound(&WaveFile)) {
#ifdef _N3GAME
CLogWriter::Write("CN3SndObj::Create - FillBufferWithSound Failed.. (%)", fsFile.string().c_str());
CLogWriter::Write("CN3SndObj::Create - FillBufferWithSound Failed.. {:s})", fsFile);
#endif
return false;
}
Expand Down
4 changes: 2 additions & 2 deletions src/engine/N3Base/N3TableBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,7 @@ template <class Type> BOOL CN3TableBase<Type>::LoadFromFile(const fs::path & fsF

if (INVALID_HANDLE_VALUE == hFile) {
#ifdef _N3GAME
CLogWriter::Write("N3TableBase - Can't open file(read) File Handle error (%s)", fsFile.string().c_str());
CLogWriter::Write("N3TableBase - Can't open file(read) File Handle error ({:s})", fsFile);
#endif
return FALSE;
}
Expand Down Expand Up @@ -342,7 +342,7 @@ template <class Type> BOOL CN3TableBase<Type>::LoadFromFile(const fs::path & fsF

if (FALSE == bResult) {
#ifdef _N3GAME
CLogWriter::Write("N3TableBase - incorrect table (%s)", fsFile.string().c_str());
CLogWriter::Write("N3TableBase - incorrect table ({:s})", fsFile);
#endif
}

Expand Down
Loading

0 comments on commit 37f5024

Please sign in to comment.