mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-04 02:42:49 -04:00
219 lines
6.0 KiB
C++
219 lines
6.0 KiB
C++
/**
|
|
* PANDA 3D SOFTWARE
|
|
* Copyright (c) Carnegie Mellon University. All rights reserved.
|
|
*
|
|
* All use of this software is subject to the terms of the revised BSD
|
|
* license. You should have received a copy of this license along
|
|
* with this source code in a file named "LICENSE."
|
|
*
|
|
* @file notifyCategory.cxx
|
|
* @author drose
|
|
* @date 2000-02-29
|
|
*/
|
|
|
|
#include "notifyCategory.h"
|
|
#include "pnotify.h"
|
|
#include "configPageManager.h"
|
|
#include "configVariableString.h"
|
|
#include "configVariableBool.h"
|
|
#include "config_prc.h"
|
|
|
|
#ifdef ANDROID
|
|
#include "androidLogStream.h"
|
|
#endif
|
|
|
|
#include <time.h> // for strftime().
|
|
#include <assert.h>
|
|
|
|
long NotifyCategory::_server_delta = 0;
|
|
|
|
/**
|
|
*
|
|
*/
|
|
NotifyCategory::
|
|
NotifyCategory(const string &fullname, const string &basename,
|
|
NotifyCategory *parent) :
|
|
_fullname(fullname),
|
|
_basename(basename),
|
|
_parent(parent),
|
|
_severity(get_config_name(), NS_unspecified,
|
|
"Default severity of this notify category",
|
|
ConfigVariable::F_dynamic),
|
|
_local_modified(initial_invalid_cache())
|
|
{
|
|
if (_parent != (NotifyCategory *)NULL) {
|
|
_parent->_children.push_back(this);
|
|
}
|
|
|
|
// Only the unnamed top category is allowed not to have a parent.
|
|
nassertv(_parent != (NotifyCategory *)NULL || _fullname.empty());
|
|
}
|
|
|
|
/**
|
|
* Begins a new message to this Category at the indicated severity level. If
|
|
* the indicated severity level is enabled, this writes a prefixing string to
|
|
* the Notify::out() stream and returns that. If the severity level is
|
|
* disabled, this returns Notify::null().
|
|
*/
|
|
ostream &NotifyCategory::
|
|
out(NotifySeverity severity, bool prefix) const {
|
|
if (is_on(severity)) {
|
|
|
|
#ifdef ANDROID
|
|
// Android redirects stdio and stderr to devnull, but does provide its own
|
|
// logging system. We use a special type of stream that redirects it to
|
|
// Android's log system.
|
|
if (prefix) {
|
|
return AndroidLogStream::out(severity) << *this << ": ";
|
|
} else {
|
|
return AndroidLogStream::out(severity);
|
|
}
|
|
#else
|
|
|
|
if (prefix) {
|
|
if (get_notify_timestamp()) {
|
|
// Format a timestamp to include as a prefix as well.
|
|
time_t now = time(NULL) + _server_delta;
|
|
struct tm atm;
|
|
#ifdef _WIN32
|
|
localtime_s(&atm, &now);
|
|
#else
|
|
localtime_r(&now, &atm);
|
|
#endif
|
|
|
|
char buffer[128];
|
|
strftime(buffer, 128, ":%m-%d-%Y %H:%M:%S ", &atm);
|
|
nout << buffer;
|
|
}
|
|
|
|
if (severity == NS_info) {
|
|
return nout << *this << ": ";
|
|
} else {
|
|
return nout << *this << "(" << severity << "): ";
|
|
}
|
|
} else {
|
|
return nout;
|
|
}
|
|
#endif
|
|
|
|
} else if (severity <= NS_debug && get_check_debug_notify_protect()) {
|
|
// Someone issued a debug Notify output statement without protecting it
|
|
// within an if statement. This can cause a significant runtime
|
|
// performance hit, since it forces the iostream library to fully format
|
|
// its output, and then discards the output.
|
|
nout << " **Not protected!** ";
|
|
if (prefix) {
|
|
nout << *this << "(" << severity << "): ";
|
|
}
|
|
if (assert_abort) {
|
|
nassertr(false, nout);
|
|
}
|
|
|
|
return nout;
|
|
|
|
} else {
|
|
return Notify::null();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Returns the number of child Categories of this particular Category.
|
|
*/
|
|
size_t NotifyCategory::
|
|
get_num_children() const {
|
|
return _children.size();
|
|
}
|
|
|
|
/**
|
|
* Returns the nth child Category of this particular Category.
|
|
*/
|
|
NotifyCategory *NotifyCategory::
|
|
get_child(size_t i) const {
|
|
assert(i < _children.size());
|
|
return _children[i];
|
|
}
|
|
|
|
/**
|
|
* Sets a global delta (in seconds) between the local time and the server's
|
|
* time, for the purpose of synchronizing the time stamps in the log messages
|
|
* of the client with that of a known server.
|
|
*/
|
|
void NotifyCategory::
|
|
set_server_delta(long delta) {
|
|
_server_delta = delta;
|
|
}
|
|
|
|
/**
|
|
* Returns the name of the config variable that controls this category. This
|
|
* is called at construction time.
|
|
*/
|
|
string NotifyCategory::
|
|
get_config_name() const {
|
|
string config_name;
|
|
|
|
if (_fullname.empty()) {
|
|
config_name = "notify-level";
|
|
} else if (!_basename.empty()) {
|
|
config_name = "notify-level-" + _basename;
|
|
}
|
|
|
|
return config_name;
|
|
}
|
|
|
|
/**
|
|
*
|
|
*/
|
|
void NotifyCategory::
|
|
update_severity_cache() {
|
|
if (_severity == NS_unspecified) {
|
|
// If we don't have an explicit severity level, inherit our parent's.
|
|
if (_severity.has_value()) {
|
|
nout << "Invalid severity name for " << _severity.get_name() << ": "
|
|
<< _severity.get_string_value() << "\n";
|
|
}
|
|
if (_parent != (NotifyCategory *)NULL) {
|
|
_severity_cache = _parent->get_severity();
|
|
|
|
} else {
|
|
// Unless, of course, we're the root.
|
|
_severity_cache = NS_info;
|
|
}
|
|
} else {
|
|
_severity_cache = _severity;
|
|
}
|
|
mark_cache_valid(_local_modified);
|
|
}
|
|
|
|
/**
|
|
* Returns the value of the notify-timestamp ConfigVariable. This is defined
|
|
* using a method accessor rather than a static ConfigVariableBool, to protect
|
|
* against the variable needing to be accessed at static init time.
|
|
*/
|
|
bool NotifyCategory::
|
|
get_notify_timestamp() {
|
|
static ConfigVariableBool *notify_timestamp = NULL;
|
|
if (notify_timestamp == (ConfigVariableBool *)NULL) {
|
|
notify_timestamp = new ConfigVariableBool
|
|
("notify-timestamp", false,
|
|
"Set true to output the date & time with each notify message.");
|
|
}
|
|
return *notify_timestamp;
|
|
}
|
|
|
|
/**
|
|
* Returns the value of the check-debug-notify-protect ConfigVariable. This
|
|
* is defined using a method accessor rather than a static ConfigVariableBool,
|
|
* to protect against the variable needing to be accessed at static init time.
|
|
*/
|
|
bool NotifyCategory::
|
|
get_check_debug_notify_protect() {
|
|
static ConfigVariableBool *check_debug_notify_protect = NULL;
|
|
if (check_debug_notify_protect == (ConfigVariableBool *)NULL) {
|
|
check_debug_notify_protect = new ConfigVariableBool
|
|
("check-debug-notify-protect", false,
|
|
"Set true to issue a warning message if a debug or spam "
|
|
"notify output is not protected within an if statement.");
|
|
}
|
|
return *check_debug_notify_protect;
|
|
}
|