Integrated new version of the Visualization modules:

From change List number 20662.
p4#: 20667
This commit is contained in:
Jacob Støren
2013-02-28 11:37:32 +01:00
parent 1a05676551
commit 5a84a12864
39 changed files with 3071 additions and 264 deletions

View File

@@ -14,6 +14,7 @@ cvfAssert.h
cvfBase.h
cvfBase64.h
cvfCharArray.h
cvfCodeLocation.h
cvfCollection.h
cvfCollection.inl
cvfColor3.h
@@ -24,6 +25,11 @@ cvfFlags.h
cvfFlags.inl
cvfFunctorRange.h
cvfLibCore.h
cvfLogDestination.h
cvfLogDestinationConsole.h
cvfLogDestinationFile.h
cvfLogEvent.h
cvfLogManager.h
cvfLogger.h
cvfMath.h
cvfMath.inl
@@ -31,6 +37,7 @@ cvfMatrix3.h
cvfMatrix3.inl
cvfMatrix4.h
cvfMatrix4.inl
cvfMutex.h
cvfObject.h
cvfObject.inl
cvfPlane.h
@@ -60,11 +67,17 @@ set(CEE_SOURCE_FILES
cvfAssert.cpp
cvfBase64.cpp
cvfCharArray.cpp
cvfCodeLocation.cpp
cvfColor3.cpp
cvfColor4.cpp
cvfDebugTimer.cpp
cvfLogDestinationConsole.cpp
cvfLogDestinationFile.cpp
cvfLogEvent.cpp
cvfLogManager.cpp
cvfLogger.cpp
cvfMath.cpp
cvfMutex.cpp
cvfObject.cpp
cvfPlane.cpp
cvfPropertySet.cpp

View File

@@ -0,0 +1,163 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2012 Ceetron AS
//
// This library 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 3 of the License, or
// (at your option) any later version.
//
// This library 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 at <<http://www.gnu.org/licenses/gpl.html>>
// for more details.
//
//##################################################################################################
#include "cvfBase.h"
#include "cvfCodeLocation.h"
#include <algorithm>
#include <cstring>
namespace cvf {
//==================================================================================================
///
/// \class cvf::CodeLocation
/// \ingroup Core
///
/// Represents a source code location.
///
/// Typically used with logging, asserts etc. Typically initialized using built-in compiler macros
/// such as __FILE__ and __LINE__.
///
/// Note that the strings parameters for file name and function must be a static strings with a
/// lifetime that's longer than the lifetime of the CodeLocation object
///
//==================================================================================================
static const char* const EMPTY_STRING = "";
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
CodeLocation::CodeLocation()
: m_fileName(EMPTY_STRING),
m_functionName(EMPTY_STRING),
m_lineNumber(-1)
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
CodeLocation::CodeLocation(const char* fileName, const char* functionName, int lineNumber)
: m_fileName(fileName),
m_functionName(functionName),
m_lineNumber(lineNumber)
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
CodeLocation::CodeLocation(const CodeLocation& other)
: m_fileName(other.m_fileName),
m_functionName(other.m_functionName),
m_lineNumber(other.m_lineNumber)
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const CodeLocation& CodeLocation::operator=(CodeLocation rhs)
{
// Copy-and-swap (copy already done since parameter is passed by value)
rhs.swap(*this);
return *this;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const char* CodeLocation::fileName() const
{
return m_fileName ? m_fileName : EMPTY_STRING;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const char* CodeLocation::shortFileName() const
{
if (m_fileName)
{
const char* ptrToLastSlash = strrchr(m_fileName, '/');
#ifdef WIN32
const char* ptrToLastBwdSlash = strrchr(m_fileName, '\\');
if (ptrToLastBwdSlash > ptrToLastSlash)
{
ptrToLastSlash = ptrToLastBwdSlash;
}
#endif
if (ptrToLastSlash)
{
return ptrToLastSlash + 1;
}
else
{
return m_fileName;
}
}
else
{
return EMPTY_STRING;
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const char* CodeLocation::functionName() const
{
return m_functionName ? m_functionName : EMPTY_STRING;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
int CodeLocation::lineNumber() const
{
return m_lineNumber;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void CodeLocation::swap(CodeLocation& other)
{
std::swap(m_fileName, other.m_fileName);
std::swap(m_functionName, other.m_functionName);
std::swap(m_lineNumber, other.m_lineNumber);
}
} // namespace cvf

View File

@@ -0,0 +1,65 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2012 Ceetron AS
//
// This library 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 3 of the License, or
// (at your option) any later version.
//
// This library 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 at <<http://www.gnu.org/licenses/gpl.html>>
// for more details.
//
//##################################################################################################
#pragma once
namespace cvf {
//==================================================================================================
//
//
//
//==================================================================================================
class CodeLocation
{
public:
CodeLocation();
CodeLocation(const char* fileName, const char* functionName, int lineNumber);
CodeLocation(const CodeLocation& other);
const CodeLocation& operator=(CodeLocation rhs);
const char* fileName() const;
const char* shortFileName() const;
const char* functionName() const;
int lineNumber() const;
void swap(CodeLocation& other);
private:
const char* m_fileName;
const char* m_functionName;
int m_lineNumber;
};
#if defined(_MSC_VER)
#define CVF_CODELOC_FUNCNAME __FUNCSIG__
#elif defined(__GNUC__)
#define CVF_CODELOC_FUNCNAME __PRETTY_FUNCTION__
#else
#define CVF_CODELOC_FUNCNAME ""
#endif
#define CVF_CODE_LOCATION ::cvf::CodeLocation(__FILE__, CVF_CODELOC_FUNCNAME, __LINE__)
} // cvf

View File

@@ -0,0 +1,44 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2012 Ceetron AS
//
// This library 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 3 of the License, or
// (at your option) any later version.
//
// This library 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 at <<http://www.gnu.org/licenses/gpl.html>>
// for more details.
//
//##################################################################################################
#pragma once
#include "cvfObject.h"
namespace cvf {
class LogEvent;
//==================================================================================================
//
// Interface for log destinations
//
//==================================================================================================
class LogDestination : public Object
{
public:
virtual void log(const LogEvent& logEvent) = 0;
};
} // cvf

View File

@@ -0,0 +1,141 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2012 Ceetron AS
//
// This library 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 3 of the License, or
// (at your option) any later version.
//
// This library 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 at <<http://www.gnu.org/licenses/gpl.html>>
// for more details.
//
//##################################################################################################
#include "cvfBase.h"
#include "cvfLogDestinationConsole.h"
#include "cvfLogEvent.h"
#ifdef WIN32
#pragma warning (push)
#pragma warning (disable: 4668)
#include <windows.h>
#pragma warning (pop)
#else
#include <cstdio>
#include <cstdarg>
#endif
namespace cvf {
//==================================================================================================
///
/// \class cvf::LogDestinationConsole
/// \ingroup Core
///
///
///
//==================================================================================================
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void LogDestinationConsole::log(const LogEvent& logEvent)
{
String str;
bool addLocationInfo = false;
Logger::Level logEventLevel = logEvent.level();
if (logEventLevel == Logger::LL_ERROR)
{
str = "ERROR: " + logEvent.message();
addLocationInfo = true;
}
else if (logEventLevel == Logger::LL_WARNING)
{
str = "warn: " + logEvent.message();
}
else if (logEventLevel == Logger::LL_INFO)
{
str = "info: " + logEvent.message();
}
else if (logEventLevel == Logger::LL_DEBUG)
{
str = "debug: " + logEvent.message();
}
if (addLocationInfo)
{
str += "\n";
str += String(" -func: %1\n").arg(logEvent.location().functionName());
str += String(" -file: %1(%2)").arg(logEvent.location().shortFileName()).arg(logEvent.location().lineNumber());
}
CharArray charArrMsg = str.toAscii();
const char* szMsg = charArrMsg.ptr();
{
Mutex::ScopedLock lock(m_mutex);
#ifdef WIN32
writeToWindowsConsole(szMsg, true);
#else
writeToStderr(szMsg, true);
#endif
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void LogDestinationConsole::writeToWindowsConsole(const char* theString, bool addNewLine)
{
#ifdef WIN32
CVF_ASSERT(theString);
AllocConsole();
HANDLE hStdOutputHandle = GetStdHandle(STD_OUTPUT_HANDLE);
if (hStdOutputHandle && theString)
{
DWORD stringLength = static_cast<DWORD>(System::strlen(theString));
unsigned long iDum = 0;
WriteConsoleA(hStdOutputHandle, theString, stringLength, &iDum, NULL);
if (addNewLine) WriteConsole(hStdOutputHandle, "\n", 1, &iDum, NULL);
}
#else
CVF_UNUSED(theString);
CVF_UNUSED(addNewLine);
#endif
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void LogDestinationConsole::writeToStderr(const char* theString, bool addNewLine)
{
CVF_ASSERT(theString);
if (theString)
{
fprintf(stderr, "%s", theString);
if (addNewLine)
{
fprintf(stderr, "\n");
}
}
}
} // namespace cvf

View File

@@ -0,0 +1,49 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2012 Ceetron AS
//
// This library 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 3 of the License, or
// (at your option) any later version.
//
// This library 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 at <<http://www.gnu.org/licenses/gpl.html>>
// for more details.
//
//##################################################################################################
#pragma once
#include "cvfLogDestination.h"
#include "cvfMutex.h"
namespace cvf {
//==================================================================================================
//
//
//
//==================================================================================================
class LogDestinationConsole : public LogDestination
{
public:
virtual void log(const LogEvent& logEvent);
private:
static void writeToWindowsConsole(const char* theString, bool addNewLine);
static void writeToStderr(const char* theString, bool addNewLine);
private:
Mutex m_mutex;
};
} // cvf

View File

@@ -0,0 +1,169 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2012 Ceetron AS
//
// This library 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 3 of the License, or
// (at your option) any later version.
//
// This library 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 at <<http://www.gnu.org/licenses/gpl.html>>
// for more details.
//
//##################################################################################################
#include "cvfBase.h"
#include "cvfLogDestinationFile.h"
#include "cvfLogEvent.h"
#ifdef WIN32
#pragma warning (push)
#pragma warning (disable: 4668)
#include <windows.h>
#pragma warning (pop)
#else
#include <cstdio>
#include <cstdarg>
#endif
namespace cvf {
class FileWrapper
{
public:
FileWrapper(const String& fileName)
: m_fileName(fileName),
m_filePtr(NULL)
{
}
~FileWrapper()
{
if (m_filePtr)
{
fclose(m_filePtr);
}
}
bool open(const String& mode)
{
CVF_ASSERT(m_filePtr == NULL);
#ifdef WIN32
if (_wfopen_s(&m_filePtr, m_fileName.c_str(), mode.c_str()) != 0)
{
m_filePtr = NULL;
}
#else
m_filePtr = ::fopen(m_fileName.toUtf8().ptr(), mode.toUtf8().ptr());
#endif
return m_filePtr != NULL;
}
FILE* filePtr()
{
return m_filePtr;
}
private:
String m_fileName;
FILE* m_filePtr;
};
//==================================================================================================
///
/// \class cvf::LogDestinationFile
/// \ingroup Core
///
///
///
//==================================================================================================
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void LogDestinationFile::log(const LogEvent& logEvent)
{
String str;
bool addLocationInfo = false;
Logger::Level logEventLevel = logEvent.level();
if (logEventLevel == Logger::LL_ERROR)
{
str = "ERROR: " + logEvent.message();
addLocationInfo = true;
}
else if (logEventLevel == Logger::LL_WARNING)
{
str = "warn: " + logEvent.message();
}
else if (logEventLevel == Logger::LL_INFO)
{
str = "info: " + logEvent.message();
}
else if (logEventLevel == Logger::LL_DEBUG)
{
str = "debug: " + logEvent.message();
}
if (addLocationInfo)
{
str += "\n";
str += String(" -func: %1\n").arg(logEvent.location().functionName());
str += String(" -file: %1(%2)").arg(logEvent.location().shortFileName()).arg(logEvent.location().lineNumber());
}
CharArray charArrMsg = str.toAscii();
const char* szMsg = charArrMsg.ptr();
Mutex::ScopedLock lock(m_mutex);
writeToFile(szMsg, true);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void LogDestinationFile::writeToFile(const char* theString, bool addNewLine)
{
FileWrapper file(m_fileName);
if (m_firstTimeOpen)
{
if (!file.open("wt"))
{
return;
}
m_firstTimeOpen = false;
}
else
{
if (!file.open("at"))
{
return;
}
}
if (file.filePtr() && theString)
{
if (addNewLine)
{
fprintf(file.filePtr(), "%s\n", theString);
}
else
{
fprintf(file.filePtr(), "%s", theString);
}
}
}
} // namespace cvf

View File

@@ -0,0 +1,53 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2012 Ceetron AS
//
// This library 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 3 of the License, or
// (at your option) any later version.
//
// This library 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 at <<http://www.gnu.org/licenses/gpl.html>>
// for more details.
//
//##################################################################################################
#pragma once
#include "cvfLogDestination.h"
#include "cvfString.h"
#include "cvfMutex.h"
namespace cvf {
//==================================================================================================
//
//
//
//==================================================================================================
class LogDestinationFile : public LogDestination
{
public:
LogDestinationFile(const String& fileName);
virtual void log(const LogEvent& logEvent);
private:
void writeToFile(const char* theString, bool addNewLine);
private:
String m_fileName;
bool m_firstTimeOpen; // Initialized to true, Will be set to false after first write operation
Mutex m_mutex;
};
} // cvf

View File

@@ -0,0 +1,128 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2012 Ceetron AS
//
// This library 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 3 of the License, or
// (at your option) any later version.
//
// This library 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 at <<http://www.gnu.org/licenses/gpl.html>>
// for more details.
//
//##################################################################################################
#include "cvfBase.h"
#include "cvfLogEvent.h"
namespace cvf {
//==================================================================================================
///
/// \class cvf::LogEvent
/// \ingroup Core
///
///
///
//==================================================================================================
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
LogEvent::LogEvent()
: m_level(Logger::LL_ERROR)
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
LogEvent::LogEvent(const String& source, const String& message, Logger::Level level, const CodeLocation& codeLocation)
: m_source(source),
m_message(message),
m_level(level),
m_codeLocation(codeLocation)
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
LogEvent::LogEvent(const LogEvent& other)
: m_source(other.m_source),
m_message(other.m_message),
m_level(other.m_level),
m_codeLocation(other.m_codeLocation)
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const LogEvent& LogEvent::operator=(LogEvent rhs)
{
// Copy-and-swap (copy already done since parameter is passed by value)
rhs.swap(*this);
return *this;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const String& LogEvent::source() const
{
return m_source;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
Logger::Level LogEvent::level() const
{
return m_level;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const String& LogEvent::message() const
{
return m_message;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const CodeLocation& LogEvent::location() const
{
return m_codeLocation;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void LogEvent::swap(LogEvent& other)
{
m_source.swap(other.m_source);
m_message.swap(other.m_message);
std::swap(m_level, other.m_level);
m_codeLocation.swap(other.m_codeLocation);
}
} // namespace cvf

View File

@@ -0,0 +1,62 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2012 Ceetron AS
//
// This library 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 3 of the License, or
// (at your option) any later version.
//
// This library 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 at <<http://www.gnu.org/licenses/gpl.html>>
// for more details.
//
//##################################################################################################
#pragma once
#include "cvfObject.h"
#include "cvfString.h"
#include "cvfLogger.h"
namespace cvf {
//==================================================================================================
//
//
//
//==================================================================================================
class LogEvent
{
public:
LogEvent();
LogEvent(const String& source, const String& message, Logger::Level level, const CodeLocation& codeLocation);
LogEvent(const LogEvent& other);
const LogEvent& operator=(LogEvent rhs);
const String& source() const;
Logger::Level level() const;
const String& message() const;
const CodeLocation& location() const;
private:
void swap(LogEvent& other);
private:
String m_source;
String m_message;
Logger::Level m_level;
CodeLocation m_codeLocation;
};
} // cvf

View File

@@ -0,0 +1,236 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2012 Ceetron AS
//
// This library 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 3 of the License, or
// (at your option) any later version.
//
// This library 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 at <<http://www.gnu.org/licenses/gpl.html>>
// for more details.
//
//##################################################################################################
#include "cvfBase.h"
#include "cvfLogManager.h"
#include "cvfLogger.h"
#include "cvfLogDestinationConsole.h"
namespace cvf {
//==================================================================================================
///
/// \class cvf::LogManager
/// \ingroup Core
///
///
///
//==================================================================================================
cvf::ref<LogManager> LogManager::sm_logManagerInstance;
Mutex LogManager::sm_instanceMutex;
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
LogManager::LogManager()
{
// Create the root logger
ref<Logger> rootLogger = new Logger("", Logger::LL_WARNING, new LogDestinationConsole);
m_loggerMap[""] = rootLogger;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
LogManager::~LogManager()
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
LogManager* LogManager::instance()
{
Mutex::ScopedLock mutexLock(sm_instanceMutex);
if (sm_logManagerInstance.isNull())
{
sm_logManagerInstance = new LogManager;
}
return sm_logManagerInstance.p();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void LogManager::setInstance(LogManager* logManagerInstance)
{
Mutex::ScopedLock mutexLock(sm_instanceMutex);
sm_logManagerInstance = logManagerInstance;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void LogManager::shutdownInstance()
{
Mutex::ScopedLock mutexLock(sm_instanceMutex);
sm_logManagerInstance = NULL;
}
//--------------------------------------------------------------------------------------------------
/// Returns logger with the specified name
///
/// Will create the logger if it doesn't already exist. In this case, the newly created logger will
/// be initialized with the same logging level and appender as its parent.
//--------------------------------------------------------------------------------------------------
Logger* LogManager::logger(const String& loggerName)
{
Mutex::ScopedLock mutexLock(m_mutex);
ref<Logger> theLogger = find(loggerName);
if (theLogger.isNull())
{
// Must create a new logger
// Try and find parent (optionally we'll use the root logger) and use its settings to initialize level and appender
String parentLoggerName = LogManager::nameOfParentLogger(loggerName);
ref<Logger> parentLogger = find(parentLoggerName);
if (parentLogger.isNull())
{
parentLogger = rootLogger();
}
CVF_ASSERT(parentLogger.notNull());
theLogger = new Logger(loggerName, parentLogger->level(), parentLogger->destination());
m_loggerMap[loggerName] = theLogger;
}
return theLogger.p();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
Logger* LogManager::rootLogger()
{
return logger(String());
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void LogManager::setLevelRecursive(const String& baseLoggerName, int logLevel)
{
Mutex::ScopedLock mutexLock(m_mutex);
const size_t baseNameLength = baseLoggerName.size();
const bool baseNameIsRoot = (baseNameLength == 0);
for (LoggerMap_T::iterator it = m_loggerMap.begin(); it != m_loggerMap.end(); ++it)
{
Logger* logger = it->second.p();
if (baseNameIsRoot)
{
logger->setLevel(logLevel);
}
else
{
const String& loggerName = logger->name();
if (loggerName.startsWith(baseLoggerName) &&
((loggerName.size() == baseNameLength) || (loggerName[baseNameLength] == '.')) )
{
logger->setLevel(logLevel);
}
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void LogManager::setDestinationRecursive(const String& baseLoggerName, LogDestination* logDestination)
{
Mutex::ScopedLock mutexLock(m_mutex);
const size_t baseNameLength = baseLoggerName.size();
const bool baseNameIsRoot = (baseNameLength == 0);
for (LoggerMap_T::iterator it = m_loggerMap.begin(); it != m_loggerMap.end(); ++it)
{
Logger* logger = it->second.p();
if (baseNameIsRoot)
{
logger->setDestination(logDestination);
}
else
{
const String& loggerName = logger->name();
if (loggerName.startsWith(baseLoggerName) &&
((loggerName.size() == baseNameLength) || (loggerName[baseNameLength] == '.')) )
{
logger->setDestination(logDestination);
}
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
Logger* LogManager::find(const String& loggerName)
{
LoggerMap_T::iterator it = m_loggerMap.find(loggerName);
if (it != m_loggerMap.end())
{
return it->second.p();
}
else
{
return NULL;
}
}
//--------------------------------------------------------------------------------------------------
/// Determine name of the parent logger of \a childLoggerName
//--------------------------------------------------------------------------------------------------
String LogManager::nameOfParentLogger(const String& childLoggerName)
{
std::wstring childName = childLoggerName.toStdWString();
std::wstring::size_type pos = childName.rfind('.');
if (pos != std::wstring::npos)
{
std::wstring parentName = childName.substr(0, pos);
return parentName;
}
else
{
return String();
}
}
} // namespace cvf

View File

@@ -0,0 +1,74 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2012 Ceetron AS
//
// This library 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 3 of the License, or
// (at your option) any later version.
//
// This library 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 at <<http://www.gnu.org/licenses/gpl.html>>
// for more details.
//
//##################################################################################################
#pragma once
#include "cvfObject.h"
#include "cvfString.h"
#include "cvfMutex.h"
#include <map>
namespace cvf {
class Logger;
class LogDestination;
//==================================================================================================
//
//
//
//==================================================================================================
class LogManager : public Object
{
public:
LogManager();
~LogManager();
static LogManager* instance();
static void setInstance(LogManager* logManagerInstance);
static void shutdownInstance();
Logger* logger(const String& loggerName);
Logger* rootLogger();
void setLevelRecursive(const String& baseLoggerName, int logLevel);
void setDestinationRecursive(const String& baseLoggerName, LogDestination* logDestination);
private:
Logger* find(const String& loggerName);
static String nameOfParentLogger(const String& childLoggerName);
private:
typedef std::map<String, cvf::ref<Logger> > LoggerMap_T;
LoggerMap_T m_loggerMap;
Mutex m_mutex;
static cvf::ref<LogManager> sm_logManagerInstance;
static Mutex sm_instanceMutex;
CVF_DISABLE_COPY_AND_ASSIGN(LogManager);
};
} // cvf

View File

@@ -19,7 +19,8 @@
#include "cvfBase.h"
#include "cvfLogger.h"
#include "cvfTrace.h"
#include "cvfLogEvent.h"
#include "cvfLogDestination.h"
namespace cvf {
@@ -31,17 +32,20 @@ namespace cvf {
/// \ingroup Core
///
/// Logger class
///
/// Currently, output is written using Trace, and special formatting of the string makes it possible
/// to navigate to source code using F4 in Visual Studio. See http://msdn.microsoft.com/en-us/library/yxkt8b26.aspx
///
/// Note that in itself, the Logger is not thread safe. This means that logger configuration, such
/// as setting the logging level and specifying the log destination, must be done in a single
/// threaded environment.
///
//==================================================================================================
//--------------------------------------------------------------------------------------------------
/// Constructor
//--------------------------------------------------------------------------------------------------
Logger::Logger()
: m_debugLogging(false)
Logger::Logger(const String& loggerName, int logLevel, LogDestination* logDestination)
: m_name(loggerName),
m_logLevel(logLevel),
m_destination(logDestination)
{
}
@@ -51,62 +55,145 @@ Logger::Logger()
//--------------------------------------------------------------------------------------------------
Logger::~Logger()
{
}
//--------------------------------------------------------------------------------------------------
/// Use file and line to create a specially formatted string for Visual Studio.
///
/// \param message The actual error message
/// \param fileName Use system macro __FILE__ for source code file name
/// \param line Use system macro __LINE__ for source code line number
//--------------------------------------------------------------------------------------------------
const String& Logger::name() const
{
return m_name;
}
//--------------------------------------------------------------------------------------------------
/// Set the logging level of this logger
///
/// __FILE__ and __LINE__ are used to create the variables used to navigate to the line in the
/// source code file the error message was logged at.
/// Set a level of 0 to disable all logging for this logger.
//--------------------------------------------------------------------------------------------------
void Logger::error(const String& message, const char* fileName, int lineNumber)
void Logger::setLevel(int logLevel)
{
String tmp;
tmp = String(fileName) + "(" + String(lineNumber) + "): error: " + message;
Trace::show(tmp);
m_logLevel = logLevel;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void Logger::enableDebug(bool enableDebugLogging)
int Logger::level() const
{
m_debugLogging = enableDebugLogging;
return m_logLevel;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool Logger::isDebugEnabled() const
LogDestination* Logger::destination()
{
return m_debugLogging;
return m_destination.p();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void Logger::debug(const String& message, const char* /*fileName*/, int /*lineNumber*/)
void Logger::setDestination(LogDestination* logDestination)
{
if (m_debugLogging)
m_destination = logDestination;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void Logger::error(const String& message)
{
error(message, CodeLocation());
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void Logger::error(const String& message, const CodeLocation& location)
{
if (m_logLevel >= LL_ERROR && m_destination.notNull())
{
// For now, don't report file and line
String tmp;
tmp = "debug: " + message;
Trace::show(tmp);
log(message, LL_ERROR, location);
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void Logger::warning(const String& message)
{
warning(message, CodeLocation());
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void Logger::warning(const String& message, const CodeLocation& location)
{
if (m_logLevel >= LL_WARNING && m_destination.notNull())
{
log(message, LL_WARNING, location);
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void Logger::info(const String& message)
{
info(message, CodeLocation());
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void Logger::info(const String& message, const CodeLocation& location)
{
if (m_logLevel >= LL_INFO && m_destination.notNull())
{
log(message, LL_INFO, location);
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void Logger::debug(const String& message, const CodeLocation& location)
{
if (m_logLevel >= LL_DEBUG && m_destination.notNull())
{
log(message, LL_DEBUG, location);
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void Logger::log(const String& message, Logger::Level messageLevel, const CodeLocation& location)
{
if (m_logLevel >= messageLevel && m_destination.notNull())
{
m_destination->log(LogEvent(m_name, message, messageLevel, location));
}
}
} // namespace cvf

View File

@@ -21,9 +21,14 @@
#include "cvfObject.h"
#include "cvfString.h"
#include "cvfCodeLocation.h"
namespace cvf {
class LogEvent;
class LogDestination;
//==================================================================================================
//
@@ -33,20 +38,57 @@ namespace cvf {
class Logger : public Object
{
public:
Logger();
enum Level
{
LL_ERROR = 1,
LL_WARNING,
LL_INFO,
LL_DEBUG
};
public:
Logger(const String& loggerName, int logLevel, LogDestination* logDestination);
~Logger();
void error(const String& message, const char* fileName, int lineNumber);
const String& name() const;
int level() const;
void setLevel(int logLevel);
LogDestination* destination();
void setDestination(LogDestination* logDestination);
void enableDebug(bool enableDebugLogging);
bool isDebugEnabled() const;
void debug(const String& message, const char* fileName, int lineNumber);
void error(const String& message);
void error(const String& message, const CodeLocation& location);
void warning(const String& message);
void warning(const String& message, const CodeLocation& location);
void info(const String& message);
void info(const String& message, const CodeLocation& location);
void debug(const String& message, const CodeLocation& location);
bool isErrorEnabled() const { return m_logLevel >= LL_ERROR; }
bool isWarningEnabled() const { return m_logLevel >= LL_WARNING; }
bool isInfoEnabled() const { return m_logLevel >= LL_INFO; }
bool isDebugEnabled() const { return m_logLevel >= LL_DEBUG; }
private:
bool m_debugLogging; // Whether debug messages get logged or not
void log(const String& message, Logger::Level messageLevel, const CodeLocation& location);
private:
String m_name; // Logger name
int m_logLevel; // Logging level, all messages with a level less than or equal to this level will be logged
ref<LogDestination> m_destination;
CVF_DISABLE_COPY_AND_ASSIGN(Logger);
};
// Helper macros for writing log messages to a logger
#define CVF_LOG_ERROR(theLogger, theMessage) if ((theLogger)->isErrorEnabled()) { (theLogger)->error((theMessage), CVF_CODE_LOCATION); }
#define CVF_LOG_WARNING(theLogger, theMessage) if ((theLogger)->isWarningEnabled()) { (theLogger)->warning((theMessage), CVF_CODE_LOCATION); }
#define CVF_LOG_INFO(theLogger, theMessage) if ((theLogger)->isInfoEnabled()) { (theLogger)->info((theMessage), CVF_CODE_LOCATION); }
#define CVF_LOG_DEBUG(theLogger, theMessage) if ((theLogger)->isDebugEnabled()) { (theLogger)->debug((theMessage), CVF_CODE_LOCATION); }
} // cvf

View File

@@ -0,0 +1,202 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2012 Ceetron AS
//
// This library 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 3 of the License, or
// (at your option) any later version.
//
// This library 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 at <<http://www.gnu.org/licenses/gpl.html>>
// for more details.
//
//##################################################################################################
#include "cvfBase.h"
#include "cvfMutex.h"
#ifdef WIN32
#pragma warning (push)
#pragma warning (disable: 4668)
#include <windows.h>
#pragma warning (pop)
#endif
#ifdef CVF_LINUX
#include <pthread.h>
#endif
namespace cvf {
//==================================================================================================
//
// Win32 implementation using critical section
//
//==================================================================================================
#ifdef WIN32
class MutexImpl
{
public:
MutexImpl()
{
::InitializeCriticalSection(&m_critSection);
}
~MutexImpl()
{
::DeleteCriticalSection(&m_critSection);
}
void lock()
{
::EnterCriticalSection(&m_critSection);
}
void unlock()
{
::LeaveCriticalSection(&m_critSection);
}
private:
CRITICAL_SECTION m_critSection;
};
#endif
//==================================================================================================
//
// Linux implementation using POSIX/Pthreads
//
//==================================================================================================
#ifdef CVF_LINUX
class MutexImpl
{
public:
MutexImpl()
{
pthread_mutexattr_t mutexAttribs;
int errCode = 0;
CVF_UNUSED(errCode);
errCode = pthread_mutexattr_init(&mutexAttribs);
CVF_ASSERT(errCode == 0);
// Use a recursive mutex to be aligned with Win32 implementation
errCode = pthread_mutexattr_settype(&mutexAttribs, PTHREAD_MUTEX_RECURSIVE);
CVF_ASSERT(errCode == 0);
errCode = pthread_mutex_init(&m_mutex, &mutexAttribs);
CVF_ASSERT(errCode == 0);
// We're done with the attribs object
errCode = pthread_mutexattr_destroy(&mutexAttribs);
CVF_ASSERT(errCode == 0);
}
~MutexImpl()
{
int errCode = pthread_mutex_destroy(&m_mutex);
CVF_UNUSED(errCode);
CVF_TIGHT_ASSERT(errCode == 0);
}
void lock()
{
int errCode = pthread_mutex_lock(&m_mutex);
CVF_UNUSED(errCode);
CVF_TIGHT_ASSERT(errCode == 0);
}
void unlock()
{
int errCode = pthread_mutex_unlock(&m_mutex);
CVF_UNUSED(errCode);
CVF_TIGHT_ASSERT(errCode == 0);
}
private:
pthread_mutex_t m_mutex;
};
#endif
//==================================================================================================
///
/// \class cvf::Mutex
/// \ingroup Core
///
/// Implements a recursive mutex where the same thread can acquire the lock multiple times.
///
/// The mutex is implemented as an recursive mutex since on Windows platforms its implementation
/// is based critical sections. Win32 critical sections are always recursive, and therefore we also
/// make the other platform implementations recursive for consistency.
///
//==================================================================================================
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
Mutex::Mutex()
: m_pimpl(new MutexImpl)
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
Mutex::~Mutex()
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void Mutex::lock()
{
m_pimpl->lock();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void Mutex::unlock()
{
m_pimpl->unlock();
}
//==================================================================================================
///
/// \class cvf::Mutex::ScopedLock
/// \ingroup Core
///
///
///
//==================================================================================================
Mutex::ScopedLock::ScopedLock(Mutex& mutex)
: m_theMutex(mutex)
{
m_theMutex.lock();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
Mutex::ScopedLock::~ScopedLock()
{
m_theMutex.unlock();
}
} // namespace cvf

View File

@@ -0,0 +1,60 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2012 Ceetron AS
//
// This library 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 3 of the License, or
// (at your option) any later version.
//
// This library 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 at <<http://www.gnu.org/licenses/gpl.html>>
// for more details.
//
//##################################################################################################
#pragma once
#include <memory>
namespace cvf {
//==================================================================================================
//
//
//
//==================================================================================================
class Mutex
{
public:
Mutex();
~Mutex();
void lock();
void unlock();
class ScopedLock
{
public:
ScopedLock(Mutex& mutex);
~ScopedLock();
private:
Mutex& m_theMutex;
};
private:
std::auto_ptr<class MutexImpl> m_pimpl;
CVF_DISABLE_COPY_AND_ASSIGN(Mutex);
};
} // cvf

View File

@@ -1063,6 +1063,15 @@ size_t String::find(const String& str, size_t start) const
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool String::startsWith(const String& str) const
{
return (find(str) == 0);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------

View File

@@ -69,6 +69,7 @@ public:
std::vector<String> split(const String& delimiters = " ") const;
size_t find(const String& str, size_t start = 0) const;
bool startsWith(const String& str) const;
String subString(size_t start, size_t length = npos) const;
void replace(const String& before, const String& after);