d14a602a59
git-svn-id: http://svn.openscenegraph.org/osg/OpenSceneGraph/trunk@14882 16af8721-9629-0410-8352-f15c8da7e697
250 lines
7.0 KiB
C++
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
|