2009-04-18 19:00:33 +02:00
|
|
|
/* Copyright (C) 2009 Wildfire Games.
|
|
|
|
* This file is part of 0 A.D.
|
|
|
|
*
|
|
|
|
* 0 A.D. is free software: you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation, either version 2 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* 0 A.D. is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
2007-10-13 17:17:50 +02:00
|
|
|
/**
|
|
|
|
*-----------------------------------------------------------------------------
|
|
|
|
* FILE : NetLog.cpp
|
|
|
|
* PROJECT : 0 A.D.
|
|
|
|
* DESCRIPTION : Network subsystem logging classes implementation
|
|
|
|
*-----------------------------------------------------------------------------
|
|
|
|
*/
|
2005-02-21 18:13:31 +01:00
|
|
|
|
2007-10-13 17:17:50 +02:00
|
|
|
// INCLUDES
|
|
|
|
#include "precompiled.h"
|
2005-02-21 18:13:31 +01:00
|
|
|
#include "NetLog.h"
|
2007-10-13 17:17:50 +02:00
|
|
|
#include "ps/CConsole.h"
|
2009-11-06 19:35:32 +01:00
|
|
|
#include "lib/wchar.h"
|
2007-10-13 17:17:50 +02:00
|
|
|
|
2005-02-21 18:13:31 +01:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdarg.h>
|
2005-06-01 22:12:45 +02:00
|
|
|
#include <time.h>
|
2005-02-21 18:13:31 +01:00
|
|
|
|
2007-10-13 17:17:50 +02:00
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Name: CNetLogEvent()
|
|
|
|
// Desc: Constructor
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
CNetLogEvent::CNetLogEvent(
|
|
|
|
LogLevel level,
|
|
|
|
const CStr& message,
|
|
|
|
const CStr& loggerName )
|
|
|
|
{
|
|
|
|
m_Level = level;
|
|
|
|
m_Message = message;
|
|
|
|
m_LoggerName = loggerName;
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Name: ~CNetLogEvent()
|
|
|
|
// Desc: Destructor
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
CNetLogEvent::~CNetLogEvent( void )
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Name: CNetLogSink()
|
|
|
|
// Desc: Constructor
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
CNetLogSink::CNetLogSink( void )
|
|
|
|
{
|
|
|
|
m_Active = false;
|
|
|
|
}
|
2005-02-21 18:13:31 +01:00
|
|
|
|
2007-10-13 17:17:50 +02:00
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Name: ~CNetLogSink()
|
|
|
|
// Desc: Destructor
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
CNetLogSink::~CNetLogSink( void )
|
|
|
|
{
|
|
|
|
}
|
2005-02-21 18:13:31 +01:00
|
|
|
|
2007-10-13 17:17:50 +02:00
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Name: SetName()
|
|
|
|
// Desc: Set the name for the sink
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
void CNetLogSink::SetName( const CStr& name )
|
|
|
|
{
|
|
|
|
m_Name = name;
|
|
|
|
}
|
2005-02-21 18:13:31 +01:00
|
|
|
|
2007-10-13 17:17:50 +02:00
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Name: SetLevel()
|
|
|
|
// Desc: Set the level for the sink
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
void CNetLogSink::SetLevel( LogLevel level )
|
2005-02-21 18:13:31 +01:00
|
|
|
{
|
2007-10-13 17:17:50 +02:00
|
|
|
m_Level = level;
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Name: SetHeader()
|
|
|
|
// Desc: Set new header text
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
void CNetLogSink::SetHeader( const CStr& header )
|
|
|
|
{
|
|
|
|
m_Header = header;
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Name: SetFooter()
|
|
|
|
// Desc: Set new footer text
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
void CNetLogSink::SetFooter( const CStr& footer )
|
|
|
|
{
|
|
|
|
m_Footer = footer;
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Name: Activate()
|
|
|
|
// Desc: Activates the sink
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
void CNetLogSink::Activate( void )
|
|
|
|
{
|
|
|
|
CScopeLock lock( m_Mutex );
|
|
|
|
|
|
|
|
if ( !m_Active )
|
2005-02-21 18:13:31 +01:00
|
|
|
{
|
2007-10-13 17:17:50 +02:00
|
|
|
OnActivate();
|
|
|
|
|
|
|
|
m_Active = true;
|
2005-02-21 18:13:31 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-10-13 17:17:50 +02:00
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Name: Close()
|
|
|
|
// Desc: Closes the sink
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
void CNetLogSink::Close( void )
|
2005-02-21 18:13:31 +01:00
|
|
|
{
|
2007-10-13 17:17:50 +02:00
|
|
|
CScopeLock lock( m_Mutex );
|
|
|
|
|
|
|
|
OnClose();
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Name: DoSink()
|
|
|
|
// Desc: Perform event logging
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
void CNetLogSink::DoSink( const CNetLogEvent& event )
|
|
|
|
{
|
|
|
|
CScopeLock lock( m_Mutex );
|
|
|
|
|
|
|
|
// Not activated? Nothing to log
|
|
|
|
if ( !m_Active ) return;
|
2005-02-21 18:13:31 +01:00
|
|
|
|
2007-10-13 17:17:50 +02:00
|
|
|
if ( TestEvent( event ) )
|
|
|
|
{
|
|
|
|
Sink( event );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Name: DoBulkSink()
|
|
|
|
// Desc: Perform logging for a list of events
|
|
|
|
//-----------------------------------------------------------------------------
|
had to remove uint and ulong from lib/types.h due to conflict with other library.
this snowballed into a massive search+destroy of the hodgepodge of
mostly equivalent types we had in use (int, uint, unsigned, unsigned
int, i32, u32, ulong, uintN).
it is more efficient to use 64-bit types in 64-bit mode, so the
preferred default is size_t (for anything remotely resembling a size or
index). tile coordinates are ssize_t to allow more efficient conversion
to/from floating point. flags are int because we almost never need more
than 15 distinct bits, bit test/set is not slower and int is fastest to
type. finally, some data that is pretty much directly passed to OpenGL
is now typed accordingly.
after several hours, the code now requires fewer casts and less
guesswork.
other changes:
- unit and player IDs now have an "invalid id" constant in the
respective class to avoid casting and -1
- fix some endian/64-bit bugs in the map (un)packing. added a
convenience function to write/read a size_t.
- ia32: change CPUID interface to allow passing in ecx (required for
cache topology detection, which I need at work). remove some unneeded
functions from asm, replace with intrinsics where possible.
This was SVN commit r5942.
2008-05-11 20:48:32 +02:00
|
|
|
void CNetLogSink::DoBulkSink( const CNetLogEvent* pEvents, size_t eventCount )
|
2007-10-13 17:17:50 +02:00
|
|
|
{
|
2008-05-13 21:43:02 +02:00
|
|
|
size_t* pIndices = NULL;
|
had to remove uint and ulong from lib/types.h due to conflict with other library.
this snowballed into a massive search+destroy of the hodgepodge of
mostly equivalent types we had in use (int, uint, unsigned, unsigned
int, i32, u32, ulong, uintN).
it is more efficient to use 64-bit types in 64-bit mode, so the
preferred default is size_t (for anything remotely resembling a size or
index). tile coordinates are ssize_t to allow more efficient conversion
to/from floating point. flags are int because we almost never need more
than 15 distinct bits, bit test/set is not slower and int is fastest to
type. finally, some data that is pretty much directly passed to OpenGL
is now typed accordingly.
after several hours, the code now requires fewer casts and less
guesswork.
other changes:
- unit and player IDs now have an "invalid id" constant in the
respective class to avoid casting and -1
- fix some endian/64-bit bugs in the map (un)packing. added a
convenience function to write/read a size_t.
- ia32: change CPUID interface to allow passing in ecx (required for
cache topology detection, which I need at work). remove some unneeded
functions from asm, replace with intrinsics where possible.
This was SVN commit r5942.
2008-05-11 20:48:32 +02:00
|
|
|
size_t indexCount = 0;
|
|
|
|
size_t i;
|
2007-10-13 17:17:50 +02:00
|
|
|
|
|
|
|
CScopeLock lock( m_Mutex );
|
|
|
|
|
|
|
|
// Validate parameters
|
|
|
|
if ( !pEvents ) return;
|
|
|
|
|
|
|
|
// Not activated? Nothing to log
|
|
|
|
if ( m_Closed ) return;
|
|
|
|
|
|
|
|
// Allocate new array which will store the events that will be logged
|
2008-06-26 09:25:50 +02:00
|
|
|
pIndices = new size_t[ eventCount ];
|
2007-10-13 17:17:50 +02:00
|
|
|
if ( !pIndices )
|
|
|
|
{
|
|
|
|
throw std::bad_alloc();
|
2005-02-21 18:13:31 +01:00
|
|
|
return;
|
2007-10-13 17:17:50 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// Filter each event and store the index for
|
|
|
|
// those passing the filter test
|
|
|
|
for ( i = 0; i < eventCount; i++ )
|
|
|
|
{
|
|
|
|
if ( TestEvent( pEvents[ i ] ) )
|
|
|
|
{
|
|
|
|
pIndices[ indexCount++ ] = i;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Log each event
|
|
|
|
for ( i = 0; i < indexCount; i++ )
|
|
|
|
{
|
|
|
|
Sink( pEvents[ pIndices[ i ] ] );
|
|
|
|
}
|
|
|
|
|
|
|
|
delete [] pIndices;
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Name: CNetLogSink()
|
|
|
|
// Desc: Test if the event can be logged
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
bool CNetLogSink::TestEvent( const CNetLogEvent& event )
|
|
|
|
{
|
|
|
|
return ( event.GetLevel() >= m_Level );
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Name: WriteHeader()
|
|
|
|
// Desc: Writes a header
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
void CNetLogSink::WriteHeader( void )
|
|
|
|
{
|
|
|
|
if ( !m_Header.empty() )
|
|
|
|
{
|
|
|
|
Write( m_Header );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Name: WriteFooter()
|
|
|
|
// Desc: Writes a footer
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
void CNetLogSink::WriteFooter( void )
|
|
|
|
{
|
|
|
|
if ( !m_Footer.empty() )
|
|
|
|
{
|
|
|
|
Write( m_Footer );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Name: OnActivate()
|
|
|
|
// Desc: Called on activation
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
void CNetLogSink::OnActivate( void )
|
|
|
|
{
|
|
|
|
// Does nothing by default
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Name: OnClose()
|
|
|
|
// Desc: Called on sink closure
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
void CNetLogSink::OnClose( void )
|
|
|
|
{
|
|
|
|
// Does nothing by default
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Name: CNetLogFileSink()
|
|
|
|
// Desc: Constructor
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
CNetLogFileSink::CNetLogFileSink( void )
|
|
|
|
{
|
|
|
|
// Get string time
|
2007-12-20 21:21:45 +01:00
|
|
|
CStr time;
|
2007-10-13 17:17:50 +02:00
|
|
|
CNetLogger::GetStringTime( time );
|
2005-02-21 18:13:31 +01:00
|
|
|
|
2007-10-13 17:17:50 +02:00
|
|
|
// Make relative path
|
2009-11-03 22:46:35 +01:00
|
|
|
fs::wpath path(psLogDir()/L"net_log");
|
|
|
|
path /= CStrW(time)+L".txt";
|
2009-11-04 16:29:28 +01:00
|
|
|
m_FileName = path.string();
|
2007-12-20 21:21:45 +01:00
|
|
|
m_Append = true;
|
2007-10-13 17:17:50 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Name: CNetLogFileSink()
|
|
|
|
// Desc: Constructor
|
|
|
|
//-----------------------------------------------------------------------------
|
2009-11-03 22:46:35 +01:00
|
|
|
CNetLogFileSink::CNetLogFileSink( const fs::wpath& filename )
|
2007-10-13 17:17:50 +02:00
|
|
|
{
|
|
|
|
m_FileName = filename;
|
|
|
|
m_Append = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Name: CNetLogFileSink()
|
|
|
|
// Desc: Constructor
|
|
|
|
//-----------------------------------------------------------------------------
|
2009-11-03 22:46:35 +01:00
|
|
|
CNetLogFileSink::CNetLogFileSink( const fs::wpath& filename, bool append )
|
2007-10-13 17:17:50 +02:00
|
|
|
{
|
|
|
|
m_FileName = filename;
|
|
|
|
m_Append = append;
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Name: ~CNetLogFileSink()
|
|
|
|
// Desc: Destructor
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
CNetLogFileSink::~CNetLogFileSink( void )
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Name: Activate()
|
|
|
|
// Desc: Open the file which will be used for logging
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
void CNetLogFileSink::OnActivate( void )
|
|
|
|
{
|
|
|
|
OpenFile( m_FileName, m_Append );
|
|
|
|
|
|
|
|
WriteHeader();
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Name: OnClose()
|
|
|
|
// Desc: Closes the file used for logging
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
void CNetLogFileSink::OnClose( void )
|
|
|
|
{
|
|
|
|
WriteFooter();
|
|
|
|
|
|
|
|
CloseFile();
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Name: Sink()
|
|
|
|
// Desc: Log the event to file
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
void CNetLogFileSink::Sink( const CNetLogEvent& event )
|
|
|
|
{
|
|
|
|
Write( event.GetMessage() );
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Name: Write()
|
|
|
|
// Desc: Writes a message to log file
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
void CNetLogFileSink::Write( const CStr& message )
|
|
|
|
{
|
|
|
|
// File not opened?
|
|
|
|
if ( !m_File.is_open() )
|
|
|
|
{
|
|
|
|
OpenFile( m_FileName, m_Append );
|
|
|
|
|
|
|
|
// If still not opened, ignore message
|
|
|
|
if ( !m_File.is_open() ) return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Write message
|
|
|
|
if ( !message.empty() )
|
|
|
|
{
|
|
|
|
m_File << message;
|
|
|
|
}
|
2005-02-21 18:13:31 +01:00
|
|
|
}
|
|
|
|
|
2007-10-13 17:17:50 +02:00
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Name: Write()
|
|
|
|
// Desc: Writes a character to the file
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
void CNetLogFileSink::Write( char c )
|
2006-04-24 01:14:18 +02:00
|
|
|
{
|
2007-10-13 17:17:50 +02:00
|
|
|
// File not opened?
|
|
|
|
if ( !m_File.is_open() )
|
2005-02-21 18:13:31 +01:00
|
|
|
{
|
2007-10-13 17:17:50 +02:00
|
|
|
OpenFile( m_FileName, m_Append );
|
|
|
|
|
|
|
|
// If still not opened, ignore character
|
|
|
|
if ( !m_File.is_open() ) return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Write character
|
|
|
|
m_File << c;
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Name: OpenFile()
|
|
|
|
// Desc: Open the file where the logging will output
|
|
|
|
//-----------------------------------------------------------------------------
|
2009-11-03 22:46:35 +01:00
|
|
|
void CNetLogFileSink::OpenFile( const fs::wpath& fileName, bool append )
|
2007-10-13 17:17:50 +02:00
|
|
|
{
|
|
|
|
// Close any open file
|
|
|
|
if ( m_File.is_open() ) m_File.close();
|
|
|
|
|
|
|
|
// Open the file and log start
|
2009-11-06 19:35:32 +01:00
|
|
|
m_File.open( string_from_wstring(fileName.string()).c_str(), append ? std::ios::app : std::ios::out );
|
2007-10-13 17:17:50 +02:00
|
|
|
if ( !m_File.is_open() )
|
|
|
|
{
|
|
|
|
// throw std::ios_base::failure
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
m_FileName = fileName;
|
|
|
|
m_Append = append;
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Name: CloseFile()
|
|
|
|
// Desc: Closes the opened file
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
void CNetLogFileSink::CloseFile( void )
|
|
|
|
{
|
|
|
|
if ( m_File.is_open() )
|
|
|
|
{
|
|
|
|
m_File.flush();
|
|
|
|
m_File.close();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Name: CNetLogConsoleSink()
|
|
|
|
// Desc: Constructor
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
CNetLogConsoleSink::CNetLogConsoleSink( void )
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Name: ~CNetLogConsoleSink()
|
|
|
|
// Desc: Destructor
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
CNetLogConsoleSink::~CNetLogConsoleSink( void )
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Name: Activate()
|
|
|
|
// Desc: Activates the game console
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
void CNetLogConsoleSink::OnActivate( void )
|
|
|
|
{
|
|
|
|
WriteHeader();
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Name: OnClose()
|
|
|
|
// Desc: Toggles off game console
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
void CNetLogConsoleSink::OnClose( void )
|
|
|
|
{
|
|
|
|
WriteFooter();
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Name: Sink()
|
|
|
|
// Desc: Log the event to file
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
void CNetLogConsoleSink::Sink( const CNetLogEvent& event )
|
|
|
|
{
|
|
|
|
Write( event.GetMessage() );
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Name: Write()
|
|
|
|
// Desc: Writes a message to game console
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
void CNetLogConsoleSink::Write( const CStr& message )
|
|
|
|
{
|
|
|
|
// Do we have a valid console?
|
|
|
|
if ( !g_Console ) return;
|
|
|
|
|
|
|
|
// Write message
|
|
|
|
if ( !message.empty() )
|
|
|
|
{
|
|
|
|
g_Console->InsertMessage( message.FromUTF8().c_str() );
|
2005-02-21 18:13:31 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-10-13 17:17:50 +02:00
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Name: Write()
|
|
|
|
// Desc: Writes a character to the file
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
void CNetLogConsoleSink::Write( char c )
|
2005-02-21 18:13:31 +01:00
|
|
|
{
|
2007-10-13 17:17:50 +02:00
|
|
|
// Do we have a valid console?
|
|
|
|
if ( !g_Console ) return;
|
|
|
|
|
|
|
|
// Write character
|
|
|
|
Write( CStr( c ) );
|
2005-02-21 18:13:31 +01:00
|
|
|
}
|
|
|
|
|
2007-10-13 17:17:50 +02:00
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Name: CNetLogger()
|
|
|
|
// Desc: Constructor
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
CNetLogger::CNetLogger( const CStr& name )
|
2005-02-21 18:13:31 +01:00
|
|
|
{
|
2007-10-13 17:17:50 +02:00
|
|
|
m_Name = name;
|
2008-01-10 02:17:09 +01:00
|
|
|
m_Level = LOG_LEVEL_ALL;
|
2007-10-13 17:17:50 +02:00
|
|
|
}
|
2005-02-21 18:13:31 +01:00
|
|
|
|
2007-10-13 17:17:50 +02:00
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Name: ~CNetLogger()
|
|
|
|
// Desc: Destructor
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
CNetLogger::~CNetLogger( void )
|
|
|
|
{
|
|
|
|
}
|
2005-02-21 18:13:31 +01:00
|
|
|
|
2007-10-13 17:17:50 +02:00
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Name: SetLevel()
|
|
|
|
// Desc: Set logger level
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
void CNetLogger::SetLevel( LogLevel level )
|
|
|
|
{
|
|
|
|
m_Level = level;
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Name: IsDebugEnabled()
|
|
|
|
// Desc: Check if enabled for DEBUG level
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
bool CNetLogger::IsDebugEnabled( void ) const
|
|
|
|
{
|
|
|
|
return ( LOG_LEVEL_DEBUG >= m_Level );
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Name: IsErrorEnabled()
|
|
|
|
// Desc: Check if enabled for ERROR level
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
bool CNetLogger::IsErrorEnabled( void ) const
|
|
|
|
{
|
|
|
|
return ( LOG_LEVEL_ERROR >= m_Level );
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Name: IsFatalEnabled()
|
|
|
|
// Desc: Check if enabled for FATAL level
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
bool CNetLogger::IsFatalEnabled( void ) const
|
|
|
|
{
|
|
|
|
return ( LOG_LEVEL_FATAL >= m_Level );
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Name: IsInfoEnabled()
|
|
|
|
// Desc: Check if enabled for INFO level
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
bool CNetLogger::IsInfoEnabled( void ) const
|
|
|
|
{
|
|
|
|
return ( LOG_LEVEL_INFO >= m_Level );
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Name: IsWarnEnabled()
|
|
|
|
// Desc: Check if enabled for WARN level
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
bool CNetLogger::IsWarnEnabled( void ) const
|
|
|
|
{
|
|
|
|
return ( LOG_LEVEL_WARN >= m_Level );
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Name: Debug()
|
|
|
|
// Desc: Log a message with DEBUG level
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
void CNetLogger::Debug( const CStr& message )
|
|
|
|
{
|
|
|
|
if ( IsDebugEnabled() )
|
|
|
|
{
|
|
|
|
// Get timestamp as a string
|
|
|
|
CStr timer;
|
|
|
|
GetStringTimeStamp( timer );
|
|
|
|
|
|
|
|
CStr eventMessage = "DEBUG";
|
|
|
|
eventMessage += " - ";
|
|
|
|
eventMessage += timer;
|
|
|
|
eventMessage += " ";
|
|
|
|
eventMessage += message;
|
|
|
|
eventMessage += "\n";
|
|
|
|
|
|
|
|
CNetLogEvent newEvent( LOG_LEVEL_DEBUG, eventMessage, m_Name );
|
|
|
|
|
|
|
|
CallSinks( newEvent );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Name: Debug()
|
|
|
|
// Desc: Log a formatted message with DEBUG level
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
void CNetLogger::DebugFormat( const char* pFormat, ... )
|
|
|
|
{
|
|
|
|
if ( IsDebugEnabled() )
|
|
|
|
{
|
|
|
|
char buffer[ 512 ] = { 0 };
|
|
|
|
CStr timer;
|
|
|
|
va_list args;
|
|
|
|
|
|
|
|
// Get timestamp as a string
|
|
|
|
GetStringTimeStamp( timer );
|
|
|
|
|
|
|
|
// Get arguments as a string
|
|
|
|
va_start ( args, pFormat );
|
|
|
|
vsnprintf ( buffer, 512, pFormat, args );
|
|
|
|
va_end ( args );
|
|
|
|
|
|
|
|
// Format message (e.g. ERROR - Hello World)
|
|
|
|
CStr eventMessage = "DEBUG";
|
|
|
|
eventMessage += " - ";
|
|
|
|
eventMessage += timer;
|
|
|
|
eventMessage += " ";
|
|
|
|
eventMessage += buffer;
|
|
|
|
eventMessage += "\n";
|
|
|
|
|
|
|
|
CNetLogEvent newEvent( LOG_LEVEL_DEBUG, eventMessage, m_Name );
|
|
|
|
|
|
|
|
CallSinks( newEvent );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Name: Error()
|
|
|
|
// Desc: Log a message with ERROR level
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
void CNetLogger::Error( const CStr& message )
|
|
|
|
{
|
|
|
|
if ( IsErrorEnabled() )
|
|
|
|
{
|
|
|
|
// Get timestamp as a string
|
|
|
|
CStr timer;
|
|
|
|
GetStringTimeStamp( timer );
|
|
|
|
|
|
|
|
CStr eventMessage = "ERROR";
|
|
|
|
eventMessage += " - ";
|
|
|
|
eventMessage += timer;
|
|
|
|
eventMessage += " ";
|
|
|
|
eventMessage += message;
|
|
|
|
eventMessage += "\n";
|
|
|
|
|
|
|
|
CNetLogEvent newEvent( LOG_LEVEL_ERROR, eventMessage, m_Name );
|
|
|
|
|
|
|
|
CallSinks( newEvent );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Name: Error()
|
|
|
|
// Desc: Log a formatted message with ERROR level
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
void CNetLogger::ErrorFormat( const char* pFormat, ... )
|
|
|
|
{
|
|
|
|
if ( IsErrorEnabled() )
|
|
|
|
{
|
|
|
|
char buffer[ 512 ] = { 0 };
|
|
|
|
CStr timer;
|
|
|
|
va_list args;
|
|
|
|
|
|
|
|
// Get timestamp as a string
|
|
|
|
GetStringTimeStamp( timer );
|
|
|
|
|
|
|
|
// Get arguments as a string
|
|
|
|
va_start ( args, pFormat );
|
|
|
|
vsnprintf ( buffer, 512, pFormat, args );
|
|
|
|
va_end ( args );
|
|
|
|
|
|
|
|
// Format message (e.g. ERROR - Hello World)
|
|
|
|
CStr eventMessage = "ERROR";
|
|
|
|
eventMessage += " - ";
|
|
|
|
eventMessage += timer;
|
|
|
|
eventMessage += " ";
|
|
|
|
eventMessage += buffer;
|
|
|
|
eventMessage += "\n";
|
|
|
|
|
|
|
|
CNetLogEvent newEvent( LOG_LEVEL_ERROR, eventMessage, m_Name );
|
|
|
|
|
|
|
|
CallSinks( newEvent );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Name: Fatal()
|
|
|
|
// Desc: Log a message with FATAL level
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
void CNetLogger::Fatal( const CStr& message )
|
|
|
|
{
|
|
|
|
if ( IsFatalEnabled() )
|
|
|
|
{
|
|
|
|
// Get timestamp as a string
|
|
|
|
CStr timer;
|
|
|
|
GetStringTimeStamp( timer );
|
|
|
|
|
|
|
|
CStr eventMessage = "FATAL";
|
|
|
|
eventMessage += " - ";
|
|
|
|
eventMessage += timer;
|
|
|
|
eventMessage += " ";
|
|
|
|
eventMessage += message;
|
|
|
|
eventMessage += "\n";
|
|
|
|
|
|
|
|
CNetLogEvent newEvent( LOG_LEVEL_FATAL, eventMessage, m_Name );
|
|
|
|
|
|
|
|
CallSinks( newEvent );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Name: Fatal()
|
|
|
|
// Desc: Log a formatted message with FATAL error
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
void CNetLogger::FatalFormat( const char* pFormat, ... )
|
|
|
|
{
|
|
|
|
if ( IsFatalEnabled() )
|
|
|
|
{
|
|
|
|
char buffer[ 512 ] = { 0 };
|
|
|
|
CStr timer;
|
|
|
|
va_list args;
|
|
|
|
|
|
|
|
// Get timestamp as a string
|
|
|
|
GetStringTimeStamp( timer );
|
|
|
|
|
|
|
|
// Get arguments as a string
|
|
|
|
va_start ( args, pFormat );
|
|
|
|
vsnprintf ( buffer, 512, pFormat, args );
|
|
|
|
va_end ( args );
|
|
|
|
|
|
|
|
// Format message (e.g. ERROR - Hello World)
|
|
|
|
CStr eventMessage = "FATAL";
|
|
|
|
eventMessage += " - ";
|
|
|
|
eventMessage += timer;
|
|
|
|
eventMessage += " ";
|
|
|
|
eventMessage += buffer;
|
|
|
|
eventMessage += "\n";
|
|
|
|
|
|
|
|
CNetLogEvent newEvent( LOG_LEVEL_FATAL, eventMessage, m_Name );
|
|
|
|
|
|
|
|
CallSinks( newEvent );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Name: Info()
|
|
|
|
// Desc: Log a message with INFO level
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
void CNetLogger::Info( const CStr& message )
|
|
|
|
{
|
|
|
|
if ( IsInfoEnabled() )
|
|
|
|
{
|
|
|
|
// Get timestamp as a string
|
|
|
|
CStr timer;
|
|
|
|
GetStringTimeStamp( timer );
|
|
|
|
|
|
|
|
CStr eventMessage = "INFO";
|
|
|
|
eventMessage += " - ";
|
|
|
|
eventMessage += timer;
|
|
|
|
eventMessage += " ";
|
|
|
|
eventMessage += message;
|
|
|
|
eventMessage += "\n";
|
|
|
|
|
|
|
|
CNetLogEvent newEvent( LOG_LEVEL_INFO, eventMessage, m_Name );
|
|
|
|
|
|
|
|
CallSinks( newEvent );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Name: Info()
|
|
|
|
// Desc: Log a formatted message with INFO level
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
void CNetLogger::InfoFormat( const char* pFormat, ... )
|
|
|
|
{
|
|
|
|
if ( IsInfoEnabled() )
|
|
|
|
{
|
|
|
|
char buffer[ 512 ] = { 0 };
|
|
|
|
CStr timer;
|
|
|
|
va_list args;
|
|
|
|
|
|
|
|
// Get timestamp as a string
|
|
|
|
GetStringTimeStamp( timer );
|
|
|
|
|
|
|
|
// Get arguments as a string
|
|
|
|
va_start ( args, pFormat );
|
|
|
|
vsnprintf ( buffer, 512, pFormat, args );
|
|
|
|
va_end ( args );
|
|
|
|
|
|
|
|
// Format message (e.g. ERROR - Hello World)
|
|
|
|
CStr eventMessage = "INFO";
|
|
|
|
eventMessage += " - ";
|
|
|
|
eventMessage += timer;
|
|
|
|
eventMessage += " ";
|
|
|
|
eventMessage += buffer;
|
|
|
|
eventMessage += "\n";
|
|
|
|
|
|
|
|
CNetLogEvent newEvent( LOG_LEVEL_INFO, eventMessage, m_Name );
|
|
|
|
|
|
|
|
CallSinks( newEvent );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Name: Warn()
|
|
|
|
// Desc: Log a message with WARN level
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
void CNetLogger::Warn( const CStr& message )
|
|
|
|
{
|
|
|
|
if ( IsWarnEnabled() )
|
|
|
|
{
|
|
|
|
// Get timestamp as a string
|
|
|
|
CStr timer;
|
|
|
|
GetStringTimeStamp( timer );
|
|
|
|
|
|
|
|
CStr eventMessage = "WARN";
|
|
|
|
eventMessage += " - ";
|
|
|
|
eventMessage += timer;
|
|
|
|
eventMessage += " ";
|
|
|
|
eventMessage += message;
|
|
|
|
eventMessage += "\n";
|
|
|
|
|
|
|
|
CNetLogEvent newEvent( LOG_LEVEL_WARN, eventMessage, m_Name );
|
|
|
|
|
|
|
|
CallSinks( newEvent );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Name: Warn()
|
|
|
|
// Desc: Log a formatted message with WARN level
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
void CNetLogger::WarnFormat( const char* pFormat, ... )
|
|
|
|
{
|
|
|
|
if ( IsWarnEnabled() )
|
|
|
|
{
|
|
|
|
char buffer[ 512 ] = { 0 };
|
|
|
|
CStr timer;
|
|
|
|
va_list args;
|
|
|
|
|
|
|
|
// Get timestamp as a string
|
|
|
|
GetStringTimeStamp( timer );
|
|
|
|
|
|
|
|
// Get arguments as a string
|
|
|
|
va_start ( args, pFormat );
|
|
|
|
vsnprintf ( buffer, 512, pFormat, args );
|
|
|
|
va_end ( args );
|
|
|
|
|
|
|
|
// Format message (e.g. ERROR - Hello World)
|
|
|
|
CStr eventMessage = "WARN";
|
|
|
|
eventMessage += " - ";
|
|
|
|
eventMessage += timer;
|
|
|
|
eventMessage += " ";
|
|
|
|
eventMessage += buffer;
|
|
|
|
eventMessage += "\n";
|
|
|
|
|
|
|
|
CNetLogEvent newEvent( LOG_LEVEL_WARN, eventMessage, m_Name );
|
|
|
|
|
|
|
|
CallSinks( newEvent );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Name: AddSink()
|
|
|
|
// Desc: Attaches a new sink
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
void CNetLogger::AddSink( CNetLogSink* pSink )
|
|
|
|
{
|
had to remove uint and ulong from lib/types.h due to conflict with other library.
this snowballed into a massive search+destroy of the hodgepodge of
mostly equivalent types we had in use (int, uint, unsigned, unsigned
int, i32, u32, ulong, uintN).
it is more efficient to use 64-bit types in 64-bit mode, so the
preferred default is size_t (for anything remotely resembling a size or
index). tile coordinates are ssize_t to allow more efficient conversion
to/from floating point. flags are int because we almost never need more
than 15 distinct bits, bit test/set is not slower and int is fastest to
type. finally, some data that is pretty much directly passed to OpenGL
is now typed accordingly.
after several hours, the code now requires fewer casts and less
guesswork.
other changes:
- unit and player IDs now have an "invalid id" constant in the
respective class to avoid casting and -1
- fix some endian/64-bit bugs in the map (un)packing. added a
convenience function to write/read a size_t.
- ia32: change CPUID interface to allow passing in ecx (required for
cache topology detection, which I need at work). remove some unneeded
functions from asm, replace with intrinsics where possible.
This was SVN commit r5942.
2008-05-11 20:48:32 +02:00
|
|
|
size_t i;
|
2007-10-13 17:17:50 +02:00
|
|
|
CScopeLock lock( m_Mutex );
|
|
|
|
|
|
|
|
assert( pSink );
|
|
|
|
|
|
|
|
// Validate parameter
|
|
|
|
if ( !pSink ) return;
|
|
|
|
|
|
|
|
// Check if already exists
|
|
|
|
for ( i = 0; i < GetSinkCount(); i++ )
|
|
|
|
{
|
|
|
|
CNetLogSink* pCurrSink = GetSink( i );
|
|
|
|
if ( pCurrSink == pSink ) break;
|
|
|
|
}
|
2005-02-21 18:13:31 +01:00
|
|
|
|
2007-10-13 17:17:50 +02:00
|
|
|
// Already exists?
|
|
|
|
if ( i >= GetSinkCount() )
|
|
|
|
{
|
|
|
|
// Activate new sink
|
|
|
|
pSink->Activate();
|
|
|
|
|
|
|
|
// Add new sink to list
|
|
|
|
m_Sinks.push_back( pSink );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Name: RemoveSink()
|
|
|
|
// Desc: Removes the sink from the list of attached sinks
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
CNetLogSink* CNetLogger::RemoveSink( CNetLogSink* pSink )
|
|
|
|
{
|
|
|
|
CScopeLock lock( m_Mutex );
|
|
|
|
|
|
|
|
// Validate parameter
|
|
|
|
if ( !pSink ) return NULL;
|
|
|
|
|
|
|
|
// Lookup the sink object
|
|
|
|
SinkList::iterator it = m_Sinks.begin();
|
|
|
|
for ( ; it != m_Sinks.end(); it++ )
|
|
|
|
{
|
|
|
|
CNetLogSink* pCurrSink = *it;
|
|
|
|
if ( pCurrSink == pSink )
|
|
|
|
{
|
|
|
|
m_Sinks.erase( it );
|
|
|
|
|
|
|
|
return pCurrSink;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
2005-02-21 18:13:31 +01:00
|
|
|
}
|
|
|
|
|
2007-10-13 17:17:50 +02:00
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Name: RemoveSink()
|
|
|
|
// Desc: Removes the named sink
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
CNetLogSink* CNetLogger::RemoveSink( const CStr& name )
|
2005-02-21 18:13:31 +01:00
|
|
|
{
|
2007-10-13 17:17:50 +02:00
|
|
|
CScopeLock lock( m_Mutex );
|
|
|
|
|
|
|
|
// Lookup sink by name
|
|
|
|
SinkList::iterator it = m_Sinks.begin();
|
|
|
|
for ( ; it != m_Sinks.end(); it++ )
|
|
|
|
{
|
|
|
|
CNetLogSink* pCurrSink = *it;
|
|
|
|
if ( !pCurrSink ) continue;
|
|
|
|
|
|
|
|
if ( pCurrSink->GetName() == name )
|
|
|
|
{
|
|
|
|
m_Sinks.erase( it );
|
|
|
|
|
|
|
|
return pCurrSink;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Sink not found
|
|
|
|
return NULL;
|
2005-02-21 18:13:31 +01:00
|
|
|
}
|
2007-10-13 17:17:50 +02:00
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Name: RemoveAllSinks()
|
|
|
|
// Desc: Remove all attached sinks
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
void CNetLogger::RemoveAllSinks( void )
|
|
|
|
{
|
|
|
|
CScopeLock lock( m_Mutex );
|
|
|
|
|
2009-11-03 22:46:35 +01:00
|
|
|
for ( size_t i = 0; i < GetSinkCount(); i++ )
|
|
|
|
delete m_Sinks[i];
|
2007-10-13 17:17:50 +02:00
|
|
|
m_Sinks.clear();
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Name: GetSinkCount()
|
|
|
|
// Desc: Retrive the number of attached sinks
|
|
|
|
//-----------------------------------------------------------------------------
|
had to remove uint and ulong from lib/types.h due to conflict with other library.
this snowballed into a massive search+destroy of the hodgepodge of
mostly equivalent types we had in use (int, uint, unsigned, unsigned
int, i32, u32, ulong, uintN).
it is more efficient to use 64-bit types in 64-bit mode, so the
preferred default is size_t (for anything remotely resembling a size or
index). tile coordinates are ssize_t to allow more efficient conversion
to/from floating point. flags are int because we almost never need more
than 15 distinct bits, bit test/set is not slower and int is fastest to
type. finally, some data that is pretty much directly passed to OpenGL
is now typed accordingly.
after several hours, the code now requires fewer casts and less
guesswork.
other changes:
- unit and player IDs now have an "invalid id" constant in the
respective class to avoid casting and -1
- fix some endian/64-bit bugs in the map (un)packing. added a
convenience function to write/read a size_t.
- ia32: change CPUID interface to allow passing in ecx (required for
cache topology detection, which I need at work). remove some unneeded
functions from asm, replace with intrinsics where possible.
This was SVN commit r5942.
2008-05-11 20:48:32 +02:00
|
|
|
size_t CNetLogger::GetSinkCount( void )
|
2007-10-13 17:17:50 +02:00
|
|
|
{
|
had to remove uint and ulong from lib/types.h due to conflict with other library.
this snowballed into a massive search+destroy of the hodgepodge of
mostly equivalent types we had in use (int, uint, unsigned, unsigned
int, i32, u32, ulong, uintN).
it is more efficient to use 64-bit types in 64-bit mode, so the
preferred default is size_t (for anything remotely resembling a size or
index). tile coordinates are ssize_t to allow more efficient conversion
to/from floating point. flags are int because we almost never need more
than 15 distinct bits, bit test/set is not slower and int is fastest to
type. finally, some data that is pretty much directly passed to OpenGL
is now typed accordingly.
after several hours, the code now requires fewer casts and less
guesswork.
other changes:
- unit and player IDs now have an "invalid id" constant in the
respective class to avoid casting and -1
- fix some endian/64-bit bugs in the map (un)packing. added a
convenience function to write/read a size_t.
- ia32: change CPUID interface to allow passing in ecx (required for
cache topology detection, which I need at work). remove some unneeded
functions from asm, replace with intrinsics where possible.
This was SVN commit r5942.
2008-05-11 20:48:32 +02:00
|
|
|
return m_Sinks.size();
|
2007-10-13 17:17:50 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Name: GetSink()
|
|
|
|
// Desc: Retrieves the sink by index
|
|
|
|
//-----------------------------------------------------------------------------
|
had to remove uint and ulong from lib/types.h due to conflict with other library.
this snowballed into a massive search+destroy of the hodgepodge of
mostly equivalent types we had in use (int, uint, unsigned, unsigned
int, i32, u32, ulong, uintN).
it is more efficient to use 64-bit types in 64-bit mode, so the
preferred default is size_t (for anything remotely resembling a size or
index). tile coordinates are ssize_t to allow more efficient conversion
to/from floating point. flags are int because we almost never need more
than 15 distinct bits, bit test/set is not slower and int is fastest to
type. finally, some data that is pretty much directly passed to OpenGL
is now typed accordingly.
after several hours, the code now requires fewer casts and less
guesswork.
other changes:
- unit and player IDs now have an "invalid id" constant in the
respective class to avoid casting and -1
- fix some endian/64-bit bugs in the map (un)packing. added a
convenience function to write/read a size_t.
- ia32: change CPUID interface to allow passing in ecx (required for
cache topology detection, which I need at work). remove some unneeded
functions from asm, replace with intrinsics where possible.
This was SVN commit r5942.
2008-05-11 20:48:32 +02:00
|
|
|
CNetLogSink* CNetLogger::GetSink( size_t index )
|
2007-10-13 17:17:50 +02:00
|
|
|
{
|
|
|
|
// Validate parameter
|
had to remove uint and ulong from lib/types.h due to conflict with other library.
this snowballed into a massive search+destroy of the hodgepodge of
mostly equivalent types we had in use (int, uint, unsigned, unsigned
int, i32, u32, ulong, uintN).
it is more efficient to use 64-bit types in 64-bit mode, so the
preferred default is size_t (for anything remotely resembling a size or
index). tile coordinates are ssize_t to allow more efficient conversion
to/from floating point. flags are int because we almost never need more
than 15 distinct bits, bit test/set is not slower and int is fastest to
type. finally, some data that is pretty much directly passed to OpenGL
is now typed accordingly.
after several hours, the code now requires fewer casts and less
guesswork.
other changes:
- unit and player IDs now have an "invalid id" constant in the
respective class to avoid casting and -1
- fix some endian/64-bit bugs in the map (un)packing. added a
convenience function to write/read a size_t.
- ia32: change CPUID interface to allow passing in ecx (required for
cache topology detection, which I need at work). remove some unneeded
functions from asm, replace with intrinsics where possible.
This was SVN commit r5942.
2008-05-11 20:48:32 +02:00
|
|
|
if ( index > m_Sinks.size() ) return NULL;
|
2007-10-13 17:17:50 +02:00
|
|
|
|
|
|
|
return m_Sinks[ index ];
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Name: GetSink()
|
|
|
|
// Desc: Retrieve the sink by name
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
CNetLogSink* CNetLogger::GetSink( const CStr& name )
|
|
|
|
{
|
had to remove uint and ulong from lib/types.h due to conflict with other library.
this snowballed into a massive search+destroy of the hodgepodge of
mostly equivalent types we had in use (int, uint, unsigned, unsigned
int, i32, u32, ulong, uintN).
it is more efficient to use 64-bit types in 64-bit mode, so the
preferred default is size_t (for anything remotely resembling a size or
index). tile coordinates are ssize_t to allow more efficient conversion
to/from floating point. flags are int because we almost never need more
than 15 distinct bits, bit test/set is not slower and int is fastest to
type. finally, some data that is pretty much directly passed to OpenGL
is now typed accordingly.
after several hours, the code now requires fewer casts and less
guesswork.
other changes:
- unit and player IDs now have an "invalid id" constant in the
respective class to avoid casting and -1
- fix some endian/64-bit bugs in the map (un)packing. added a
convenience function to write/read a size_t.
- ia32: change CPUID interface to allow passing in ecx (required for
cache topology detection, which I need at work). remove some unneeded
functions from asm, replace with intrinsics where possible.
This was SVN commit r5942.
2008-05-11 20:48:32 +02:00
|
|
|
for ( size_t i = 0; i < GetSinkCount(); i++ )
|
2007-10-13 17:17:50 +02:00
|
|
|
{
|
|
|
|
CNetLogSink* pCurrSink = GetSink( i );
|
|
|
|
if ( !pCurrSink ) continue;
|
|
|
|
|
|
|
|
if ( pCurrSink->GetName() == name )
|
|
|
|
return pCurrSink;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Sink not found
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Name: CallSinks()
|
|
|
|
// Desc:
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
void CNetLogger::CallSinks( const CNetLogEvent& event )
|
|
|
|
{
|
had to remove uint and ulong from lib/types.h due to conflict with other library.
this snowballed into a massive search+destroy of the hodgepodge of
mostly equivalent types we had in use (int, uint, unsigned, unsigned
int, i32, u32, ulong, uintN).
it is more efficient to use 64-bit types in 64-bit mode, so the
preferred default is size_t (for anything remotely resembling a size or
index). tile coordinates are ssize_t to allow more efficient conversion
to/from floating point. flags are int because we almost never need more
than 15 distinct bits, bit test/set is not slower and int is fastest to
type. finally, some data that is pretty much directly passed to OpenGL
is now typed accordingly.
after several hours, the code now requires fewer casts and less
guesswork.
other changes:
- unit and player IDs now have an "invalid id" constant in the
respective class to avoid casting and -1
- fix some endian/64-bit bugs in the map (un)packing. added a
convenience function to write/read a size_t.
- ia32: change CPUID interface to allow passing in ecx (required for
cache topology detection, which I need at work). remove some unneeded
functions from asm, replace with intrinsics where possible.
This was SVN commit r5942.
2008-05-11 20:48:32 +02:00
|
|
|
for ( size_t i = 0; i < GetSinkCount(); i++ )
|
2007-10-13 17:17:50 +02:00
|
|
|
{
|
|
|
|
CNetLogSink* pCurrSink = GetSink( i );
|
|
|
|
if ( !pCurrSink ) continue;
|
|
|
|
|
|
|
|
pCurrSink->DoSink( event );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Name: GetStringLocalTime()
|
|
|
|
// Desc: Returns the local date time into the passed in string
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
void CNetLogger::GetStringDateTime( CStr &str )
|
|
|
|
{
|
|
|
|
char buffer[ 128 ] = { 0 };
|
|
|
|
time_t tm;
|
2007-10-13 18:36:17 +02:00
|
|
|
struct tm *now;
|
2007-10-13 17:17:50 +02:00
|
|
|
|
2007-10-13 18:36:17 +02:00
|
|
|
#if OS_WIN
|
2007-10-13 17:17:50 +02:00
|
|
|
// Set timezone
|
|
|
|
_tzset();
|
|
|
|
|
|
|
|
// Get time and convert to tm structure
|
|
|
|
time( &tm );
|
2007-10-13 18:36:17 +02:00
|
|
|
struct tm nowBuf;
|
|
|
|
localtime_s( &nowBuf, &tm );
|
|
|
|
now = &nowBuf;
|
|
|
|
#else
|
|
|
|
time ( &tm );
|
|
|
|
now = localtime( &tm );
|
|
|
|
#endif
|
|
|
|
|
2007-10-13 17:17:50 +02:00
|
|
|
// Build custom time string
|
2007-10-13 18:36:17 +02:00
|
|
|
strftime( buffer, 128, "%Y-%m-%d %H:%M:%S", now );
|
2007-10-13 17:17:50 +02:00
|
|
|
|
|
|
|
str = buffer;
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Name: GetStringTime()
|
|
|
|
// Desc: Returns the local time into the passed string
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
void CNetLogger::GetStringTime( CStr& str )
|
|
|
|
{
|
|
|
|
char buffer[ 128 ] = { 0 };
|
|
|
|
time_t tm;
|
2007-10-13 18:36:17 +02:00
|
|
|
struct tm *now;
|
2007-10-13 17:17:50 +02:00
|
|
|
|
2007-10-13 18:36:17 +02:00
|
|
|
#if OS_WIN
|
2007-10-13 17:17:50 +02:00
|
|
|
// Set timezone
|
|
|
|
_tzset();
|
|
|
|
|
|
|
|
// Get time and convert to tm structure
|
|
|
|
time( &tm );
|
2007-10-13 18:36:17 +02:00
|
|
|
struct tm nowBuf;
|
|
|
|
localtime_s( &nowBuf, &tm );
|
|
|
|
now = &nowBuf;
|
|
|
|
#else
|
|
|
|
time ( &tm );
|
|
|
|
now = localtime( &tm );
|
|
|
|
#endif
|
2007-10-13 17:17:50 +02:00
|
|
|
|
|
|
|
// Build custom time string
|
2007-10-13 18:36:17 +02:00
|
|
|
strftime( buffer, 128, "%H%M%S", now );
|
2007-10-13 17:17:50 +02:00
|
|
|
|
|
|
|
str = buffer;
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Name: GetStringTimeStamp()
|
|
|
|
// Desc: Returns the formatted current time into the passed string
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
void CNetLogger::GetStringTimeStamp( CStr& str )
|
|
|
|
{
|
|
|
|
char buffer[ 128 ] = { 0 };
|
had to remove uint and ulong from lib/types.h due to conflict with other library.
this snowballed into a massive search+destroy of the hodgepodge of
mostly equivalent types we had in use (int, uint, unsigned, unsigned
int, i32, u32, ulong, uintN).
it is more efficient to use 64-bit types in 64-bit mode, so the
preferred default is size_t (for anything remotely resembling a size or
index). tile coordinates are ssize_t to allow more efficient conversion
to/from floating point. flags are int because we almost never need more
than 15 distinct bits, bit test/set is not slower and int is fastest to
type. finally, some data that is pretty much directly passed to OpenGL
is now typed accordingly.
after several hours, the code now requires fewer casts and less
guesswork.
other changes:
- unit and player IDs now have an "invalid id" constant in the
respective class to avoid casting and -1
- fix some endian/64-bit bugs in the map (un)packing. added a
convenience function to write/read a size_t.
- ia32: change CPUID interface to allow passing in ecx (required for
cache topology detection, which I need at work). remove some unneeded
functions from asm, replace with intrinsics where possible.
This was SVN commit r5942.
2008-05-11 20:48:32 +02:00
|
|
|
double timestamp = timer_Time();
|
2009-11-06 11:59:10 +01:00
|
|
|
sprintf_s( buffer, ARRAY_SIZE(buffer), "[%3u.%03u]", ( unsigned )timestamp, ( ( unsigned )( timestamp * 1000 ) % 1000 ) );
|
2007-10-13 17:17:50 +02:00
|
|
|
str = buffer;
|
|
|
|
}
|
|
|
|
|
|
|
|
// List of loggers under log manager
|
|
|
|
LoggerList CNetLogManager::m_Loggers;
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Name: Shutdown()
|
|
|
|
// Desc: Shuts down the log manager
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
void CNetLogManager::Shutdown( void )
|
|
|
|
{
|
|
|
|
// Remove all loggers
|
|
|
|
LoggerList::iterator it = m_Loggers.begin();
|
|
|
|
for ( ; it != m_Loggers.end(); it++ )
|
|
|
|
{
|
|
|
|
CNetLogger *pCurrLogger = *it;
|
|
|
|
if ( !pCurrLogger ) continue;
|
|
|
|
|
|
|
|
pCurrLogger->RemoveAllSinks();
|
|
|
|
|
|
|
|
delete pCurrLogger;
|
|
|
|
}
|
|
|
|
|
|
|
|
m_Loggers.clear();
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Name: GetLogger()
|
|
|
|
// Desc: Retrieve or create a named logger
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
CNetLogger* CNetLogManager::GetLogger( const CStr& name )
|
|
|
|
{
|
|
|
|
LoggerList::const_iterator it = m_Loggers.begin();
|
|
|
|
for ( ; it != m_Loggers.end(); it++ )
|
|
|
|
{
|
|
|
|
CNetLogger* pCurrLogger = *it;
|
|
|
|
if ( !pCurrLogger ) continue;
|
|
|
|
|
|
|
|
if ( pCurrLogger->GetName() == name )
|
|
|
|
return pCurrLogger;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Logger not found, create it
|
|
|
|
CNetLogger* pNewLogger = new CNetLogger( name );
|
|
|
|
if ( !pNewLogger ) return NULL;
|
|
|
|
|
|
|
|
// Add new logger to list
|
|
|
|
m_Loggers.push_back( pNewLogger );
|
|
|
|
|
|
|
|
return pNewLogger;
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Name: GetAllLoggers()
|
|
|
|
// Desc: Return the list of loggers
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
const LoggerList& CNetLogManager::GetAllLoggers( void )
|
|
|
|
{
|
|
|
|
return m_Loggers;
|
|
|
|
}
|
|
|
|
|
|
|
|
|