Panda3D
|
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 }