OpenSceneGraph/src/osg/Notify.cpp
Robert Osfield d14a602a59 From Jannik Heller, typo fixes
git-svn-id: http://svn.openscenegraph.org/osg/OpenSceneGraph/trunk@14882 16af8721-9629-0410-8352-f15c8da7e697
2015-06-01 13:11:49 +00:00

250 lines
7.0 KiB
C++

/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
*
* This library is open source and may be redistributed and/or modified under
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
* (at your option) any later version. The full license is in LICENSE file
* included with this distribution, and on the openscenegraph.org website.
*
* 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
* OpenSceneGraph Public License for more details.
*/
#include <osg/Notify>
#include <osg/ApplicationUsage>
#include <osg/ref_ptr>
#include <string>
#include <stdlib.h>
#include <stdio.h>
#include <sstream>
#include <iostream>
#include <ctype.h>
#define OSG_INIT_SINGLETON_PROXY(ProxyName, Func) static struct ProxyName{ ProxyName() { Func; } } s_##ProxyName;
namespace osg
{
class NullStreamBuffer : public std::streambuf
{
private:
std::streamsize xsputn(const std::streambuf::char_type * /*str*/, std::streamsize n)
{
return n;
}
};
struct NullStream : public std::ostream
{
public:
NullStream():
std::ostream(new NullStreamBuffer)
{ _buffer = dynamic_cast<NullStreamBuffer *>(rdbuf()); }
~NullStream()
{
rdbuf(0);
delete _buffer;
}
protected:
NullStreamBuffer* _buffer;
};
/** Stream buffer calling notify handler when buffer is synchronized (usually on std::endl).
* Stream stores last notification severity to pass it to handler call.
*/
struct NotifyStreamBuffer : public std::stringbuf
{
NotifyStreamBuffer() : _severity(osg::NOTICE)
{
}
void setNotifyHandler(osg::NotifyHandler *handler) { _handler = handler; }
osg::NotifyHandler *getNotifyHandler() const { return _handler.get(); }
/** Sets severity for next call of notify handler */
void setCurrentSeverity(osg::NotifySeverity severity)
{
if (_severity != severity)
{
sync();
_severity = severity;
}
}
osg::NotifySeverity getCurrentSeverity() const { return _severity; }
private:
int sync()
{
sputc(0); // string termination
if (_handler.valid())
_handler->notify(_severity, pbase());
pubseekpos(0, std::ios_base::out); // or str(std::string())
return 0;
}
osg::ref_ptr<osg::NotifyHandler> _handler;
osg::NotifySeverity _severity;
};
struct NotifyStream : public std::ostream
{
public:
NotifyStream():
std::ostream(new NotifyStreamBuffer)
{ _buffer = dynamic_cast<NotifyStreamBuffer *>(rdbuf()); }
void setCurrentSeverity(osg::NotifySeverity severity)
{
_buffer->setCurrentSeverity(severity);
}
osg::NotifySeverity getCurrentSeverity() const
{
return _buffer->getCurrentSeverity();
}
~NotifyStream()
{
rdbuf(0);
delete _buffer;
}
protected:
NotifyStreamBuffer* _buffer;
};
}
using namespace osg;
static osg::ApplicationUsageProxy Notify_e0(osg::ApplicationUsage::ENVIRONMENTAL_VARIABLE, "OSG_NOTIFY_LEVEL <mode>", "FATAL | WARN | NOTICE | DEBUG_INFO | DEBUG_FP | DEBUG | INFO | ALWAYS");
struct NotifySingleton
{
NotifySingleton()
{
// _notifyLevel
// =============
_notifyLevel = osg::NOTICE; // Default value
char* OSGNOTIFYLEVEL=getenv("OSG_NOTIFY_LEVEL");
if (!OSGNOTIFYLEVEL) OSGNOTIFYLEVEL=getenv("OSGNOTIFYLEVEL");
if(OSGNOTIFYLEVEL)
{
std::string stringOSGNOTIFYLEVEL(OSGNOTIFYLEVEL);
// Convert to upper case
for(std::string::iterator i=stringOSGNOTIFYLEVEL.begin();
i!=stringOSGNOTIFYLEVEL.end();
++i)
{
*i=toupper(*i);
}
if(stringOSGNOTIFYLEVEL.find("ALWAYS")!=std::string::npos) _notifyLevel=osg::ALWAYS;
else if(stringOSGNOTIFYLEVEL.find("FATAL")!=std::string::npos) _notifyLevel=osg::FATAL;
else if(stringOSGNOTIFYLEVEL.find("WARN")!=std::string::npos) _notifyLevel=osg::WARN;
else if(stringOSGNOTIFYLEVEL.find("NOTICE")!=std::string::npos) _notifyLevel=osg::NOTICE;
else if(stringOSGNOTIFYLEVEL.find("DEBUG_INFO")!=std::string::npos) _notifyLevel=osg::DEBUG_INFO;
else if(stringOSGNOTIFYLEVEL.find("DEBUG_FP")!=std::string::npos) _notifyLevel=osg::DEBUG_FP;
else if(stringOSGNOTIFYLEVEL.find("DEBUG")!=std::string::npos) _notifyLevel=osg::DEBUG_INFO;
else if(stringOSGNOTIFYLEVEL.find("INFO")!=std::string::npos) _notifyLevel=osg::INFO;
else std::cout << "Warning: invalid OSG_NOTIFY_LEVEL set ("<<stringOSGNOTIFYLEVEL<<")"<<std::endl;
}
// Setup standard notify handler
osg::NotifyStreamBuffer *buffer = dynamic_cast<osg::NotifyStreamBuffer *>(_notifyStream.rdbuf());
if (buffer && !buffer->getNotifyHandler())
buffer->setNotifyHandler(new StandardNotifyHandler);
}
osg::NotifySeverity _notifyLevel;
osg::NullStream _nullStream;
osg::NotifyStream _notifyStream;
};
static NotifySingleton& getNotifySingleton()
{
static NotifySingleton s_NotifySingleton;
return s_NotifySingleton;
}
bool osg::initNotifyLevel()
{
getNotifySingleton();
return true;
}
// Use a proxy to force the initialization of the NotifySingleton during static initialization
OSG_INIT_SINGLETON_PROXY(NotifySingletonProxy, osg::initNotifyLevel())
void osg::setNotifyLevel(osg::NotifySeverity severity)
{
getNotifySingleton()._notifyLevel = severity;
}
osg::NotifySeverity osg::getNotifyLevel()
{
return getNotifySingleton()._notifyLevel;
}
void osg::setNotifyHandler(osg::NotifyHandler *handler)
{
osg::NotifyStreamBuffer *buffer = static_cast<osg::NotifyStreamBuffer*>(getNotifySingleton()._notifyStream.rdbuf());
if (buffer) buffer->setNotifyHandler(handler);
}
osg::NotifyHandler* osg::getNotifyHandler()
{
osg::NotifyStreamBuffer *buffer = static_cast<osg::NotifyStreamBuffer *>(getNotifySingleton()._notifyStream.rdbuf());
return buffer ? buffer->getNotifyHandler() : 0;
}
#ifndef OSG_NOTIFY_DISABLED
bool osg::isNotifyEnabled( osg::NotifySeverity severity )
{
return severity<=getNotifySingleton()._notifyLevel;
}
#endif
std::ostream& osg::notify(const osg::NotifySeverity severity)
{
if (osg::isNotifyEnabled(severity))
{
getNotifySingleton()._notifyStream.setCurrentSeverity(severity);
return getNotifySingleton()._notifyStream;
}
return getNotifySingleton()._nullStream;
}
void osg::StandardNotifyHandler::notify(osg::NotifySeverity severity, const char *message)
{
if (severity <= osg::WARN)
fputs(message, stderr);
else
fputs(message, stdout);
}
#if defined(WIN32) && !defined(__CYGWIN__)
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#include <windows.h>
void osg::WinDebugNotifyHandler::notify(osg::NotifySeverity severity, const char *message)
{
OutputDebugStringA(message);
}
#endif