Panda3D

notifyCategory.cxx

00001 // Filename: notifyCategory.cxx
00002 // Created by:  drose (29Feb00)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) Carnegie Mellon University.  All rights reserved.
00008 //
00009 // All use of this software is subject to the terms of the revised BSD
00010 // license.  You should have received a copy of this license along
00011 // with this source code in a file named "LICENSE."
00012 //
00013 ////////////////////////////////////////////////////////////////////
00014 
00015 #include "notifyCategory.h"
00016 #include "pnotify.h"
00017 #include "configPageManager.h"
00018 #include "configVariableString.h"
00019 #include "configVariableBool.h"
00020 #include "config_prc.h"
00021 
00022 #include <time.h>  // for strftime().
00023 #include <assert.h>
00024 
00025 long NotifyCategory::_server_delta = 0;
00026 
00027 ////////////////////////////////////////////////////////////////////
00028 //     Function: NotifyCategory::Constructor
00029 //       Access: Private
00030 //  Description:
00031 ////////////////////////////////////////////////////////////////////
00032 NotifyCategory::
00033 NotifyCategory(const string &fullname, const string &basename,
00034                NotifyCategory *parent) :
00035   _fullname(fullname),
00036   _basename(basename),
00037   _parent(parent),
00038   _severity(get_config_name(), NS_unspecified, 
00039             "Default severity of this notify category", 
00040             ConfigVariable::F_dynamic),
00041   _local_modified(initial_invalid_cache())
00042 {
00043   if (_parent != (NotifyCategory *)NULL) {
00044     _parent->_children.push_back(this);
00045   }
00046 
00047   // Only the unnamed top category is allowed not to have a parent.
00048   nassertv(_parent != (NotifyCategory *)NULL || _fullname.empty());
00049 }
00050 
00051 ////////////////////////////////////////////////////////////////////
00052 //     Function: NotifyCategory::out
00053 //       Access: Published
00054 //  Description: Begins a new message to this Category at the
00055 //               indicated severity level.  If the indicated severity
00056 //               level is enabled, this writes a prefixing string to
00057 //               the Notify::out() stream and returns that.  If the
00058 //               severity level is disabled, this returns
00059 //               Notify::null().
00060 ////////////////////////////////////////////////////////////////////
00061 ostream &NotifyCategory::
00062 out(NotifySeverity severity, bool prefix) const {
00063   if (is_on(severity)) {
00064     if (prefix) {
00065       if (get_notify_timestamp()) {
00066         // Format a timestamp to include as a prefix as well.
00067         time_t now = time(NULL) + _server_delta;
00068         struct tm *ptm = localtime(&now);
00069 
00070         char buffer[128];
00071         strftime(buffer, 128, ":%m-%d-%Y %H:%M:%S ", ptm);
00072         nout << buffer;
00073       }
00074 
00075       if (severity == NS_info) {
00076         return nout << *this << ": ";
00077       } else {
00078         return nout << *this << "(" << severity << "): ";
00079       }
00080     } else {
00081       return nout;
00082     }
00083 
00084   } else if (severity <= NS_debug && get_check_debug_notify_protect()) {
00085     // Someone issued a debug Notify output statement without
00086     // protecting it within an if statement.  This can cause a
00087     // significant runtime performance hit, since it forces the
00088     // iostream library to fully format its output, and then discards
00089     // the output.
00090     nout << " **Not protected!** ";
00091     if (prefix) {
00092       nout << *this << "(" << severity << "): ";
00093     }
00094     if (assert_abort) {
00095       nassertr(false, nout);
00096     }
00097 
00098     return nout;
00099 
00100   } else {
00101     return Notify::null();
00102   }
00103 }
00104 
00105 ////////////////////////////////////////////////////////////////////
00106 //     Function: NotifyCategory::get_num_children
00107 //       Access: Published
00108 //  Description: Returns the number of child Categories of this
00109 //               particular Category.
00110 ////////////////////////////////////////////////////////////////////
00111 int NotifyCategory::
00112 get_num_children() const {
00113   return _children.size();
00114 }
00115 
00116 ////////////////////////////////////////////////////////////////////
00117 //     Function: NotifyCategory::get_child
00118 //       Access: Published
00119 //  Description: Returns the nth child Category of this particular
00120 //               Category.
00121 ////////////////////////////////////////////////////////////////////
00122 NotifyCategory *NotifyCategory::
00123 get_child(int i) const {
00124   assert(i >= 0 && i < (int)_children.size());
00125   return _children[i];
00126 }
00127 
00128 ////////////////////////////////////////////////////////////////////
00129 //     Function: NotifyCategory::set_server_delta
00130 //       Access: Published, Static
00131 //  Description: Sets a global delta (in seconds) between the local
00132 //               time and the server's time, for the purpose of
00133 //               synchronizing the time stamps in the log messages of
00134 //               the client with that of a known server.
00135 ////////////////////////////////////////////////////////////////////
00136 void NotifyCategory::
00137 set_server_delta(long delta) {
00138   _server_delta = delta;
00139 }
00140 
00141 ////////////////////////////////////////////////////////////////////
00142 //     Function: NotifyCategory::get_config_name
00143 //       Access: Private
00144 //  Description: Returns the name of the config variable that controls
00145 //               this category.  This is called at construction time.
00146 ////////////////////////////////////////////////////////////////////
00147 string NotifyCategory::
00148 get_config_name() const {
00149   string config_name;
00150 
00151   if (_fullname.empty()) {
00152     config_name = "notify-level";
00153   } else if (!_basename.empty()) {
00154     config_name = "notify-level-" + _basename;
00155   }
00156 
00157   return config_name;
00158 }
00159 
00160 ////////////////////////////////////////////////////////////////////
00161 //     Function: NotifyCategory::update_severity_cache
00162 //       Access: Public
00163 //  Description:
00164 ////////////////////////////////////////////////////////////////////
00165 void NotifyCategory::
00166 update_severity_cache() {
00167   if (_severity == NS_unspecified) {
00168     // If we don't have an explicit severity level, inherit our
00169     // parent's.
00170     if (_severity.has_value()) {
00171       nout << "Invalid severity name for " << _severity.get_name() << ": "
00172            << _severity.get_string_value() << "\n";
00173     }
00174     if (_parent != (NotifyCategory *)NULL) {
00175       _severity_cache = _parent->get_severity();
00176 
00177     } else {
00178       // Unless, of course, we're the root.
00179       _severity_cache = NS_info;
00180     }
00181   } else {
00182     _severity_cache = _severity;
00183   }
00184   mark_cache_valid(_local_modified);  
00185 }
00186 
00187 ////////////////////////////////////////////////////////////////////
00188 //     Function: NotifyCategory::get_notify_timestamp
00189 //       Access: Private, Static
00190 //  Description: Returns the value of the notify-timestamp
00191 //               ConfigVariable.  This is defined using a method
00192 //               accessor rather than a static ConfigVariableBool, to
00193 //               protect against the variable needing to be accessed
00194 //               at static init time.
00195 ////////////////////////////////////////////////////////////////////
00196 bool NotifyCategory::
00197 get_notify_timestamp() {
00198   static ConfigVariableBool *notify_timestamp = NULL;
00199   if (notify_timestamp == (ConfigVariableBool *)NULL) {
00200     notify_timestamp = new ConfigVariableBool
00201       ("notify-timestamp", false,
00202        "Set true to output the date & time with each notify message.");
00203   }
00204   return *notify_timestamp;
00205 }
00206 
00207 ////////////////////////////////////////////////////////////////////
00208 //     Function: NotifyCategory::get_check_debug_notify_protect
00209 //       Access: Private, Static
00210 //  Description: Returns the value of the check-debug-notify-protect
00211 //               ConfigVariable.  This is defined using a method
00212 //               accessor rather than a static ConfigVariableBool, to
00213 //               protect against the variable needing to be accessed
00214 //               at static init time.
00215 ////////////////////////////////////////////////////////////////////
00216 bool NotifyCategory::
00217 get_check_debug_notify_protect() {
00218   static ConfigVariableBool *check_debug_notify_protect = NULL;
00219   if (check_debug_notify_protect == (ConfigVariableBool *)NULL) {
00220     check_debug_notify_protect = new ConfigVariableBool
00221       ("check-debug-notify-protect", false,
00222        "Set true to issue a warning message if a debug or spam "
00223        "notify output is not protected within an if statement.");
00224   }
00225   return *check_debug_notify_protect;
00226 }
 All Classes Functions Variables Enumerations