//----------------------------------------------------------------------------- // Copyright (c) 2013 GarageGames, LLC // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to // deal in the Software without restriction, including without limitation the // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or // sell copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS // IN THE SOFTWARE. //----------------------------------------------------------------------------- #include "console/consoleLogger.h" #include "console/consoleTypes.h" #include "consoleLogger_ScriptBinding.h" Vector ConsoleLogger::mActiveLoggers; bool ConsoleLogger::smInitialized = false; IMPLEMENT_CONOBJECT( ConsoleLogger ); //----------------------------------------------------------------------------- ConsoleLogger::ConsoleLogger() { mFilename = NULL; mLogging = false; mAppend = false; mLevel = ConsoleLogEntry::Normal; } //----------------------------------------------------------------------------- ConsoleLogger::ConsoleLogger( const char *fileName, bool append ) { mLogging = false; mLevel = ConsoleLogEntry::Normal; mFilename = StringTable->insert( fileName ); mAppend = append; init(); } //----------------------------------------------------------------------------- static EnumTable::Enums logLevelEnums[] = { { ConsoleLogEntry::Normal, "normal" }, { ConsoleLogEntry::Warning, "warning" }, { ConsoleLogEntry::Error, "error" }, }; static EnumTable gLogLevelTable( 3, &logLevelEnums[0] ); void ConsoleLogger::initPersistFields() { Parent::initPersistFields(); addGroup( "Logging" ); addField( "level", TypeEnum, Offset( mLevel, ConsoleLogger ), 1, &gLogLevelTable ); endGroup( "Logging" ); } //----------------------------------------------------------------------------- bool ConsoleLogger::processArguments( S32 argc, const char **argv ) { if( argc == 0 ) return false; bool append = false; if( argc == 2 ) append = dAtob( argv[1] ); mAppend = append; mFilename = StringTable->insert( argv[0] ); if( init() ) { attach(); return true; } return false; } //----------------------------------------------------------------------------- ConsoleLogger::~ConsoleLogger() { detach(); } //----------------------------------------------------------------------------- bool ConsoleLogger::init() { if( smInitialized ) return true; Con::addConsumer( ConsoleLogger::logCallback ); smInitialized = true; return true; } //----------------------------------------------------------------------------- bool ConsoleLogger::attach() { if( mFilename == NULL ) { Con::errorf( "ConsoleLogger failed to attach: no filename supplied." ); return false; } // Check to see if this is initialized before using it if( !smInitialized ) { if( !init() ) { Con::errorf( "ConsoleLogger failed to initalize." ); return false; } } if( mLogging ) return false; // Open the filestream mStream.open( mFilename, ( mAppend ? FileStream::WriteAppend : FileStream::Write ) ); // Add this to list of active loggers mActiveLoggers.push_back( this ); mLogging = true; return true; } //----------------------------------------------------------------------------- bool ConsoleLogger::detach() { // Make sure this is valid before messing with it if( !smInitialized ) { if( !init() ) { return false; } } if( !mLogging ) return false; // Close filestream mStream.close(); // Remove this object from the list of active loggers for( int i = 0; i < mActiveLoggers.size(); i++ ) { if( mActiveLoggers[i] == this ) { mActiveLoggers.erase( i ); mLogging = false; return true; } } return false; // If this happens, it's bad... } //----------------------------------------------------------------------------- void ConsoleLogger::logCallback( ConsoleLogEntry::Level level, const char *consoleLine ) { ConsoleLogger *curr; // Loop through active consumers and send them the message for( int i = 0; i < mActiveLoggers.size(); i++ ) { curr = mActiveLoggers[i]; // If the log level is within the log threshhold, log it if( curr->mLevel <= level ) curr->log( consoleLine ); } } //----------------------------------------------------------------------------- void ConsoleLogger::log( const char *consoleLine ) { // Check to see if this is intalized before using it if( !smInitialized ) { if( !init() ) { Con::errorf( "I don't know how this happened, but log called on this without it being initialized" ); return; } } mStream.writeLine( (U8 *)consoleLine ); } //-----------------------------------------------------------------------------