Panda3D

pandaSystem.cxx

00001 // Filename: pandaSystem.cxx
00002 // Created by:  drose (26Jan05)
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 "pandaSystem.h"
00016 #include "pandaVersion.h"
00017 #include "dtool_platform.h"
00018 
00019 PandaSystem *PandaSystem::_global_ptr = NULL;
00020 TypeHandle PandaSystem::_type_handle;
00021 
00022 ////////////////////////////////////////////////////////////////////
00023 //     Function: PandaSystem::Constructor
00024 //       Access: Protected
00025 //  Description: Don't try to construct a PandaSystem object; there is
00026 //               only one of these, and it constructs itself.  Use
00027 //               get_global_ptr() to get a pointer to the one
00028 //               PandaSystem.
00029 ////////////////////////////////////////////////////////////////////
00030 PandaSystem::
00031 PandaSystem() :
00032   _systems(get_class_type())
00033 {
00034   _system_names_dirty = false;
00035 
00036   // These are settable via Config.prc, but only in development
00037   // (!NDEBUG) mode, and only if they are not already defined.
00038   _package_version_string = PANDA_PACKAGE_VERSION_STR;
00039   _package_host_url = PANDA_PACKAGE_HOST_URL;
00040 }
00041 
00042 ////////////////////////////////////////////////////////////////////
00043 //     Function: PandaSystem::Destructor
00044 //       Access: Protected
00045 //  Description: Don't try to destruct the global PandaSystem object.
00046 ////////////////////////////////////////////////////////////////////
00047 PandaSystem::
00048 ~PandaSystem() {
00049 }
00050 
00051 ////////////////////////////////////////////////////////////////////
00052 //     Function: PandaSystem::get_version_string
00053 //       Access: Published, Static
00054 //  Description: Returns the current version of Panda, expressed as a
00055 //               string, e.g. "1.0.0".  The string will end in the
00056 //               letter "c" if this build does not represent an
00057 //               official version.
00058 ////////////////////////////////////////////////////////////////////
00059 string PandaSystem::
00060 get_version_string() {
00061   return PANDA_VERSION_STR;
00062 }
00063 
00064 ////////////////////////////////////////////////////////////////////
00065 //     Function: PandaSystem::get_package_version_string
00066 //       Access: Published, Static
00067 //  Description: Returns the version of the Panda3D distributable
00068 //               package that provides this build of Panda.
00069 //
00070 //               When the currently-executing version of Panda was
00071 //               loaded from a distributable package, such as via the
00072 //               browser plugin, then this string will be nonempty and
00073 //               will contain the corresponding version string.  You
00074 //               can build applications that use this particular
00075 //               version of Panda by requesting it in the pdef file,
00076 //               using "panda3d", this version string, and the
00077 //               download host provided by get_package_host_url().
00078 //
00079 //               If this string is empty, then the currently-executing
00080 //               Panda was built independently, and is not part of a
00081 //               distributable package.
00082 //
00083 //               This string is set explicitly at compilation time.
00084 //               Normally, it should be set to a nonempty string only
00085 //               when building a Panda3D package for distribution.
00086 ////////////////////////////////////////////////////////////////////
00087 string PandaSystem::
00088 get_package_version_string() {
00089 #ifdef NDEBUG
00090   return PANDA_PACKAGE_VERSION_STR;
00091 #else
00092   return get_global_ptr()->_package_version_string;
00093 #endif
00094 }
00095 
00096 ////////////////////////////////////////////////////////////////////
00097 //     Function: PandaSystem::get_package_host_url
00098 //       Access: Published, Static
00099 //  Description: Returns the URL of the download server that provides
00100 //               the Panda3D distributable package currently running.
00101 //               This can be used, along with the
00102 //               get_package_version_string(), to uniquely identify
00103 //               the running version of Panda among distributable
00104 //               Panda versions.
00105 //
00106 //               See get_package_version_string() for more information.
00107 //
00108 //               This string is set explicitly at compilation time.
00109 //               Normally, it should be set to a nonempty string only
00110 //               when building a Panda3D package for distribution.
00111 ////////////////////////////////////////////////////////////////////
00112 string PandaSystem::
00113 get_package_host_url() {
00114 #ifdef NDEBUG
00115   return PANDA_PACKAGE_HOST_URL;
00116 #else
00117   return get_global_ptr()->_package_host_url;
00118 #endif
00119 }
00120 
00121 ////////////////////////////////////////////////////////////////////
00122 //     Function: PandaSystem::get_p3d_coreapi_version_string
00123 //       Access: Published, Static
00124 //  Description: Returns the current version of Panda's Core API,
00125 //               expressed as a string of dot-delimited integers.
00126 //               There are usually four integers in this version, but
00127 //               this is not guaranteed.
00128 //
00129 //               The Core API is used during the runtime (plugin)
00130 //               environment only.  This may be the empty string if
00131 //               the current version of Panda is not built to provide
00132 //               a particular Core API, which will be the normal case
00133 //               in a development SDK.  However, you should not use
00134 //               this method to determine whether you are running in a
00135 //               runtime environment or not.
00136 ////////////////////////////////////////////////////////////////////
00137 string PandaSystem::
00138 get_p3d_coreapi_version_string() {
00139 #ifndef P3D_COREAPI_VERSION_STR
00140   return "";
00141 #else
00142   return P3D_COREAPI_VERSION_STR;
00143 #endif
00144 }
00145 
00146 ////////////////////////////////////////////////////////////////////
00147 //     Function: PandaSystem::get_major_version
00148 //       Access: Published, Static
00149 //  Description: Returns the major version number of the current
00150 //               version of Panda.  This is the first number of the
00151 //               dotted triple returned by get_version_string().  It
00152 //               changes very rarely.
00153 ////////////////////////////////////////////////////////////////////
00154 int PandaSystem::
00155 get_major_version() {
00156   return PANDA_MAJOR_VERSION;
00157 }
00158 
00159 ////////////////////////////////////////////////////////////////////
00160 //     Function: PandaSystem::get_minor_version
00161 //       Access: Published, Static
00162 //  Description: Returns the minor version number of the current
00163 //               version of Panda.  This is the second number of the
00164 //               dotted triple returned by get_version_string().  It
00165 //               changes with each release that introduces new
00166 //               features.
00167 ////////////////////////////////////////////////////////////////////
00168 int PandaSystem::
00169 get_minor_version() {
00170   return PANDA_MINOR_VERSION;
00171 }
00172 
00173 ////////////////////////////////////////////////////////////////////
00174 //     Function: PandaSystem::get_sequence_version
00175 //       Access: Published, Static
00176 //  Description: Returns the sequence version number of the current
00177 //               version of Panda.  This is the third number of the
00178 //               dotted triple returned by get_version_string().  It
00179 //               changes with bugfix updates and very minor feature
00180 //               updates.
00181 ////////////////////////////////////////////////////////////////////
00182 int PandaSystem::
00183 get_sequence_version() {
00184   return PANDA_SEQUENCE_VERSION;
00185 }
00186 
00187 ////////////////////////////////////////////////////////////////////
00188 //     Function: PandaSystem::is_official_version
00189 //       Access: Published, Static
00190 //  Description: Returns true if current version of Panda claims to be
00191 //               an "official" version, that is, one that was compiled
00192 //               by an official distributor of Panda using a specific
00193 //               version of the panda source tree.  If this is true,
00194 //               there will not be a "c" at the end of the version
00195 //               string returned by get_version_string().
00196 //
00197 //               Note that we must take the distributor's word for it
00198 //               here.
00199 ////////////////////////////////////////////////////////////////////
00200 bool PandaSystem::
00201 is_official_version() {
00202 #ifdef PANDA_OFFICIAL_VERSION
00203   return true;
00204 #else
00205   return false;
00206 #endif
00207 }
00208   
00209 ////////////////////////////////////////////////////////////////////
00210 //     Function: PandaSystem::get_distributor
00211 //       Access: Published, Static
00212 //  Description: Returns the string defined by the distributor of this
00213 //               version of Panda, or "homebuilt" if this version was
00214 //               built directly from the sources by the end-user.
00215 //               This is a completely arbitrary string.
00216 ////////////////////////////////////////////////////////////////////
00217 string PandaSystem::
00218 get_distributor() {
00219   return PANDA_DISTRIBUTOR;
00220 }
00221   
00222 ////////////////////////////////////////////////////////////////////
00223 //     Function: PandaSystem::get_compiler
00224 //       Access: Published, Static
00225 //  Description: Returns a string representing the compiler that was
00226 //               used to generate this version of Panda, if it is
00227 //               available, or "unknown" if it is not.
00228 ////////////////////////////////////////////////////////////////////
00229 string PandaSystem::
00230 get_compiler() {
00231 #if defined(_MSC_VER)
00232   // MSVC defines this macro.  It's an integer; we need to format it.
00233   ostringstream strm;
00234   strm << "MSC v." << _MSC_VER;
00235 
00236   // We also get this suite of macros that tells us what the build
00237   // platform is.
00238 #if defined(_M_IX86)
00239   #ifdef MS_WIN64
00240   strm << " 64 bit (Intel)";
00241   #else  // MS_WIN64
00242   strm << " 32 bit (Intel)";
00243   #endif  // MS_WIN64
00244 #elif defined(_M_IA64)
00245   strm << " 64 bit (Itanium)";
00246 #elif defined(_M_AMD64)
00247   strm << " 64 bit (AMD64)";
00248 #endif
00249 
00250   return strm.str();
00251 
00252 #elif defined(__GNUC__)
00253   // GCC defines this simple macro.
00254   return "GCC " __VERSION__;
00255 
00256 #else
00257   // For other compilers, you're on your own.
00258   return "unknown";
00259 #endif
00260 }
00261   
00262 ////////////////////////////////////////////////////////////////////
00263 //     Function: PandaSystem::get_build_date
00264 //       Access: Published, Static
00265 //  Description: Returns a string representing the date and time at
00266 //               which this version of Panda (or at least dtool) was
00267 //               compiled, if available.
00268 ////////////////////////////////////////////////////////////////////
00269 string PandaSystem::
00270 get_build_date() {
00271   return __DATE__ " " __TIME__;
00272 }
00273   
00274 ////////////////////////////////////////////////////////////////////
00275 //     Function: PandaSystem::get_platform
00276 //       Access: Published, Static
00277 //  Description: Returns a string representing the runtime platform
00278 //               that we are currently running on.  This will be
00279 //               something like "win32" or "osx.i386" or
00280 //               "linux.amd64".
00281 ////////////////////////////////////////////////////////////////////
00282 string PandaSystem::
00283 get_platform() {
00284   return DTOOL_PLATFORM;
00285 }
00286 
00287 ////////////////////////////////////////////////////////////////////
00288 //     Function: PandaSystem::has_system
00289 //       Access: Published
00290 //  Description: Returns true if the current version of Panda claims
00291 //               to have the indicated subsystem installed, false
00292 //               otherwise.  The set of available subsystems is
00293 //               implementation defined.
00294 ////////////////////////////////////////////////////////////////////
00295 bool PandaSystem::
00296 has_system(const string &system) const {
00297   Systems::const_iterator si;
00298   si = _systems.find(system);
00299   return (si != _systems.end());
00300 }
00301 
00302 ////////////////////////////////////////////////////////////////////
00303 //     Function: PandaSystem::get_num_systems
00304 //       Access: Published
00305 //  Description: Returns the number of Panda subsystems that have
00306 //               registered themselves.  This can be used with
00307 //               get_system() to iterate through the entire list of
00308 //               available Panda subsystems.
00309 ////////////////////////////////////////////////////////////////////
00310 int PandaSystem::
00311 get_num_systems() const {
00312   return _systems.size();
00313 }
00314 
00315 ////////////////////////////////////////////////////////////////////
00316 //     Function: PandaSystem::get_system
00317 //       Access: Published
00318 //  Description: Returns the nth Panda subsystem that has registered
00319 //               itself.  This list will be sorted in alphabetical
00320 //               order.
00321 ////////////////////////////////////////////////////////////////////
00322 string PandaSystem::
00323 get_system(int n) const {
00324   if (n < 0 || n >= (int)_systems.size()) {
00325     return string();
00326   }
00327 
00328   if (_system_names_dirty) {
00329     ((PandaSystem *)this)->reset_system_names();
00330   }
00331 
00332   return _system_names[n];
00333 }
00334 
00335 ////////////////////////////////////////////////////////////////////
00336 //     Function: PandaSystem::get_system_tag
00337 //       Access: Published
00338 //  Description: Returns the value associated with the indicated tag
00339 //               for the given system.  This provides a standard way
00340 //               to query each subsystem's advertised capabilities.
00341 //               The set of tags and values are per-system and
00342 //               implementation-defined.
00343 //
00344 //               The return value is the empty string if the indicated
00345 //               system is undefined or if does not define the
00346 //               indicated tag.
00347 ////////////////////////////////////////////////////////////////////
00348 string PandaSystem::
00349 get_system_tag(const string &system, const string &tag) const {
00350   Systems::const_iterator si;
00351   si = _systems.find(system);
00352   if (si != _systems.end()) {
00353     const SystemTags &tags = (*si).second;
00354     SystemTags::const_iterator ti;
00355     ti = tags.find(tag);
00356     if (ti != tags.end()) {
00357       return (*ti).second;
00358     }
00359   }
00360 
00361   return string();
00362 }
00363 
00364 ////////////////////////////////////////////////////////////////////
00365 //     Function: PandaSystem::add_system
00366 //       Access: Published
00367 //  Description: Intended for use by each subsystem to register itself
00368 //               at startup.
00369 ////////////////////////////////////////////////////////////////////
00370 void PandaSystem::
00371 add_system(const string &system) {
00372   bool inserted = _systems.insert(Systems::value_type(system, SystemTags(get_class_type()))).second;
00373   if (inserted) {
00374     _system_names_dirty = true;
00375   }
00376 }
00377 
00378 ////////////////////////////////////////////////////////////////////
00379 //     Function: PandaSystem::set_system_tag
00380 //       Access: Published
00381 //  Description: Intended for use by each subsystem to register its
00382 //               set of capabilities at startup.
00383 ////////////////////////////////////////////////////////////////////
00384 void PandaSystem::
00385 set_system_tag(const string &system, const string &tag,
00386                const string &value) {
00387   pair<Systems::iterator, bool> result;
00388   result = _systems.insert(Systems::value_type(system, SystemTags(get_class_type())));
00389   if (result.second) {
00390     _system_names_dirty = true;
00391   }
00392 
00393   SystemTags &tags = (*result.first).second;
00394   tags[tag] = value;
00395 }
00396 
00397 ////////////////////////////////////////////////////////////////////
00398 //     Function: PandaSystem::heap_trim
00399 //       Access: Published
00400 //  Description: Attempts to release memory back to the system, if
00401 //               possible.  The pad argument is the minimum amount of
00402 //               unused memory to keep in the heap (against future
00403 //               allocations).  Any memory above that may be released
00404 //               to the system, reducing the memory size of this
00405 //               process.  There is no guarantee that any memory may
00406 //               be released.
00407 //
00408 //               Returns true if any memory was actually released,
00409 //               false otherwise.
00410 ////////////////////////////////////////////////////////////////////
00411 bool PandaSystem::
00412 heap_trim(size_t pad) {
00413   // This actually just vectors into _memory_hook, which isn't
00414   // published.  This method only exists on PandaSystem for the
00415   // convenience of Python programmers.
00416   return memory_hook->heap_trim(pad);
00417 }
00418 
00419 ////////////////////////////////////////////////////////////////////
00420 //     Function: PandaSystem::output
00421 //       Access: Published
00422 //  Description: 
00423 ////////////////////////////////////////////////////////////////////
00424 void PandaSystem::
00425 output(ostream &out) const {
00426   out << "Panda version " << get_version_string();
00427 }
00428 
00429 ////////////////////////////////////////////////////////////////////
00430 //     Function: PandaSystem::write
00431 //       Access: Published
00432 //  Description: 
00433 ////////////////////////////////////////////////////////////////////
00434 void PandaSystem::
00435 write(ostream &out) const {
00436   out << *this << "\n"
00437       << "compiled on " << get_build_date() << " by "
00438       << get_distributor() << "\n"
00439       << "with compiler " << PandaSystem::get_compiler() << "\n\n";
00440 
00441   out << "Optional systems:\n";
00442   for (Systems::const_iterator si = _systems.begin();
00443        si != _systems.end();
00444        ++si) {
00445     out << "  " << (*si).first << "\n";
00446     const SystemTags &tags = (*si).second;
00447     SystemTags::const_iterator ti;
00448     for (ti = tags.begin(); ti != tags.end(); ++ti) {
00449       out << "    " << (*ti).first << " " << (*ti).second << "\n";
00450     }
00451   }
00452 }
00453 
00454   
00455 ////////////////////////////////////////////////////////////////////
00456 //     Function: PandaSystem::get_global_ptr
00457 //       Access: Published, Static
00458 //  Description: Returns the global PandaSystem object.
00459 ////////////////////////////////////////////////////////////////////
00460 PandaSystem *PandaSystem::
00461 get_global_ptr() {
00462   if (_global_ptr == (PandaSystem *)NULL) {
00463     _global_ptr = new PandaSystem;
00464   }
00465 
00466   return _global_ptr;
00467 }
00468 
00469 ////////////////////////////////////////////////////////////////////
00470 //     Function: PandaSystem::reset_system_names
00471 //       Access: Private
00472 //  Description: Refills the _system_names vector, which is used for
00473 //               get_system_name(), from the current set of available
00474 //               system names.
00475 ////////////////////////////////////////////////////////////////////
00476 void PandaSystem::
00477 reset_system_names() {
00478   _system_names.clear();
00479   _system_names.reserve(_systems.size());
00480   
00481   Systems::const_iterator si;
00482   for (si = _systems.begin(); si != _systems.end(); ++si) {
00483     _system_names.push_back((*si).first);
00484   }
00485   
00486   _system_names_dirty = false;
00487 }
00488 
00489 ////////////////////////////////////////////////////////////////////
00490 //     Function: PandaSystem::set_package_version_string
00491 //       Access: Private
00492 //  Description: Loads the value returned by
00493 //               get_package_version_string().  This is intended to be
00494 //               called by ConfigPageManager to preload the value from
00495 //               the panda-package-version config variable, for
00496 //               developer's convenience.  This has no effect if the
00497 //               PANDA_PACKAGE_VERSION_STR configure variable is
00498 //               defined at compilation time.  This also has no effect
00499 //               in NDEBUG mode.
00500 ////////////////////////////////////////////////////////////////////
00501 void PandaSystem::
00502 set_package_version_string(const string &package_version_string) {
00503   _package_version_string = PANDA_PACKAGE_VERSION_STR;
00504   if (_package_version_string.empty()) {
00505     _package_version_string = package_version_string;
00506   }
00507 }
00508 
00509 ////////////////////////////////////////////////////////////////////
00510 //     Function: PandaSystem::set_package_host_url
00511 //       Access: Private
00512 //  Description: Loads the value returned by
00513 //               get_package_host_url().  This is intended to be
00514 //               called by ConfigPageManager to preload the value from
00515 //               the panda-package-host-url config variable, for
00516 //               developer's convenience.  This has no effect if the
00517 //               PANDA_PACKAGE_HOST_URL configure variable is defined
00518 //               at compilation time.  This also has no effect in
00519 //               NDEBUG mode.
00520 ////////////////////////////////////////////////////////////////////
00521 void PandaSystem::
00522 set_package_host_url(const string &package_host_url) {
00523   _package_host_url = PANDA_PACKAGE_HOST_URL;
00524   if (_package_host_url.empty()) {
00525     _package_host_url = package_host_url;
00526   }
00527 }
 All Classes Functions Variables Enumerations