Panda3D
Loading...
Searching...
No Matches
pandaSystem.cxx
Go to the documentation of this file.
1/**
2 * PANDA 3D SOFTWARE
3 * Copyright (c) Carnegie Mellon University. All rights reserved.
4 *
5 * All use of this software is subject to the terms of the revised BSD
6 * license. You should have received a copy of this license along
7 * with this source code in a file named "LICENSE."
8 *
9 * @file pandaSystem.cxx
10 * @author drose
11 * @date 2005-01-26
12 */
13
14#include "pandaSystem.h"
15#include "pandaVersion.h"
16#include "dtool_platform.h"
17
18using std::string;
19
20PandaSystem *PandaSystem::_global_ptr = nullptr;
21TypeHandle PandaSystem::_type_handle;
22
23/**
24 * Don't try to construct a PandaSystem object; there is only one of these,
25 * and it constructs itself. Use get_global_ptr() to get a pointer to the one
26 * PandaSystem.
27 */
28PandaSystem::
29PandaSystem() :
30 _systems(get_class_type())
31{
32 _system_names_dirty = false;
33
34 // These are settable via Config.prc, but only in development (!NDEBUG)
35 // mode, and only if they are not already defined.
36 _package_version_string = PANDA_PACKAGE_VERSION_STR;
37 _package_host_url = PANDA_PACKAGE_HOST_URL;
38
39#ifdef STDFLOAT_DOUBLE
40 add_system("stdfloat-double");
41#endif
42
43#ifdef HAVE_EIGEN
44 add_system("eigen");
45#ifdef LINMATH_ALIGN
46 set_system_tag("eigen", "vectorize", "1");
47#else
48 set_system_tag("eigen", "vectorize", "0");
49#endif
50#ifdef __AVX__
51 set_system_tag("eigen", "avx", "1");
52#else
53 set_system_tag("eigen", "avx", "0");
54#endif
55#endif // HAVE_EIGEN
56
57#ifdef USE_MEMORY_DLMALLOC
58 set_system_tag("system", "malloc", "dlmalloc");
59#elif defined(USE_MEMORY_PTMALLOC2)
60 set_system_tag("system", "malloc", "ptmalloc2");
61#elif defined(USE_MEMORY_MIMALLOC)
62 set_system_tag("system", "malloc", "mimalloc");
63#else
64 set_system_tag("system", "malloc", "malloc");
65#endif
66
67#ifdef _LIBCPP_VERSION
68 set_system_tag("system", "stdlib", "libc++");
69#elif defined(__GLIBCXX__)
70 set_system_tag("system", "stdlib", "libstdc++");
71#endif
72}
73
74/**
75 * Don't try to destruct the global PandaSystem object.
76 */
77PandaSystem::
78~PandaSystem() {
79}
80
81/**
82 * Returns the current version of Panda, expressed as a string, e.g. "1.0.0".
83 * The string will end in the letter "c" if this build does not represent an
84 * official version.
85 */
86string PandaSystem::
88 return PANDA_VERSION_STR;
89}
90
91/**
92 * Returns the version of the Panda3D distributable package that provides this
93 * build of Panda.
94 *
95 * When the currently-executing version of Panda was loaded from a
96 * distributable package, such as via the browser plugin, then this string
97 * will be nonempty and will contain the corresponding version string. You
98 * can build applications that use this particular version of Panda by
99 * requesting it in the pdef file, using "panda3d", this version string, and
100 * the download host provided by get_package_host_url().
101 *
102 * If this string is empty, then the currently-executing Panda was built
103 * independently, and is not part of a distributable package.
104 *
105 * This string is set explicitly at compilation time. Normally, it should be
106 * set to a nonempty string only when building a Panda3D package for
107 * distribution.
108 */
111#ifdef NDEBUG
112 return PANDA_PACKAGE_VERSION_STR;
113#else
114 return get_global_ptr()->_package_version_string;
115#endif
116}
117
118/**
119 * Returns the URL of the download server that provides the Panda3D
120 * distributable package currently running. This can be used, along with the
121 * get_package_version_string(), to uniquely identify the running version of
122 * Panda among distributable Panda versions.
123 *
124 * See get_package_version_string() for more information.
125 *
126 * This string is set explicitly at compilation time. Normally, it should be
127 * set to a nonempty string only when building a Panda3D package for
128 * distribution.
129 */
132#ifdef NDEBUG
133 return PANDA_PACKAGE_HOST_URL;
134#else
135 return get_global_ptr()->_package_host_url;
136#endif
137}
138
139/**
140 * Returns the current version of Panda's Core API, expressed as a string of
141 * dot-delimited integers. There are usually four integers in this version,
142 * but this is not guaranteed.
143 *
144 * The Core API is used during the runtime (plugin) environment only. This
145 * may be the empty string if the current version of Panda is not built to
146 * provide a particular Core API, which will be the normal case in a
147 * development SDK. However, you should not use this method to determine
148 * whether you are running in a runtime environment or not.
149 */
152#ifndef P3D_COREAPI_VERSION_STR
153 return "";
154#else
155 return P3D_COREAPI_VERSION_STR;
156#endif
157}
158
159/**
160 * Returns the major version number of the current version of Panda. This is
161 * the first number of the dotted triple returned by get_version_string(). It
162 * changes very rarely.
163 */
166 return PANDA_MAJOR_VERSION;
167}
168
169/**
170 * Returns the minor version number of the current version of Panda. This is
171 * the second number of the dotted triple returned by get_version_string().
172 * It changes with each release that introduces new features.
173 */
176 return PANDA_MINOR_VERSION;
177}
178
179/**
180 * Returns the sequence version number of the current version of Panda. This
181 * is the third number of the dotted triple returned by get_version_string().
182 * It changes with bugfix updates and very minor feature updates.
183 */
186 return PANDA_SEQUENCE_VERSION;
187}
188
189/**
190 * Returns true if current version of Panda claims to be an "official"
191 * version, that is, one that was compiled by an official distributor of Panda
192 * using a specific version of the panda source tree. If this is true, there
193 * will not be a "c" at the end of the version string returned by
194 * get_version_string().
195 *
196 * Note that we must take the distributor's word for it here.
197 */
198bool PandaSystem::
200#ifdef PANDA_OFFICIAL_VERSION
201 return true;
202#else
203 return false;
204#endif
205}
206
207/**
208 * Returns the memory alignment that Panda's allocators are using.
209 */
212 return MEMORY_HOOK_ALIGNMENT;
213}
214
215/**
216 * Returns the string defined by the distributor of this version of Panda, or
217 * "homebuilt" if this version was built directly from the sources by the end-
218 * user. This is a completely arbitrary string.
219 */
220string PandaSystem::
222 return PANDA_DISTRIBUTOR;
223}
224
225/**
226 * Returns a string representing the compiler that was used to generate this
227 * version of Panda, if it is available, or "unknown" if it is not.
228 */
229string PandaSystem::
230get_compiler() {
231#if defined(_MSC_VER)
232 // MSVC defines this macro. It's an integer; we need to format it.
233 std::ostringstream strm;
234 strm << "MSC v." << _MSC_VER;
235
236 // We also get this suite of macros that tells us what the build platform
237 // is.
238#if defined(_M_IX86)
239 #ifdef MS_WIN64
240 strm << " 64 bit (Intel)";
241 #else // MS_WIN64
242 strm << " 32 bit (Intel)";
243 #endif // MS_WIN64
244#elif defined(_M_IA64)
245 strm << " 64 bit (Itanium)";
246#elif defined(_M_AMD64)
247 strm << " 64 bit (AMD64)";
248#endif
249
250 return strm.str();
251
252#elif defined(__clang__)
253 // Clang has this macro. This case has to go before __GNUC__ because that
254 // is also defined by clang.
255 return "Clang " __clang_version__;
256
257#elif defined(__GNUC__)
258 // GCC defines this simple macro.
259 return "GCC " __VERSION__;
260
261#else
262 // For other compilers, you're on your own.
263 return "unknown";
264#endif
265}
266
267/**
268 * Returns a string representing the date and time at which this version of
269 * Panda (or at least dtool) was compiled, if available.
270 */
271string PandaSystem::
273#ifdef PANDA_BUILD_DATE_STR
274 return PANDA_BUILD_DATE_STR;
275#else
276 return __DATE__ " " __TIME__;
277#endif
278}
279
280/**
281 * Returns a string representing the git commit hash that this source tree is
282 * based on, or the empty string if it has not been specified at build time.
283 */
284string PandaSystem::
286#ifdef PANDA_GIT_COMMIT_STR
287 return PANDA_GIT_COMMIT_STR;
288#else
289 return string();
290#endif
291}
292
293/**
294 * Returns a string representing the runtime platform that we are currently
295 * running on. This will be something like "win32" or "osx_i386" or
296 * "linux_amd64".
297 */
298string PandaSystem::
299get_platform() {
300 return DTOOL_PLATFORM;
301}
302
303/**
304 * Returns true if the current version of Panda claims to have the indicated
305 * subsystem installed, false otherwise. The set of available subsystems is
306 * implementation defined.
307 */
309has_system(const string &system) const {
310 Systems::const_iterator si;
311 si = _systems.find(system);
312 return (si != _systems.end());
313}
314
315/**
316 * Returns the number of Panda subsystems that have registered themselves.
317 * This can be used with get_system() to iterate through the entire list of
318 * available Panda subsystems.
319 */
320size_t PandaSystem::
321get_num_systems() const {
322 return _systems.size();
323}
324
325/**
326 * Returns the nth Panda subsystem that has registered itself. This list will
327 * be sorted in alphabetical order.
328 */
329string PandaSystem::
330get_system(size_t n) const {
331 if (n >= _systems.size()) {
332 return string();
333 }
334
335 if (_system_names_dirty) {
336 ((PandaSystem *)this)->reset_system_names();
337 }
338
339 return _system_names[n];
340}
341
342/**
343 * Returns the value associated with the indicated tag for the given system.
344 * This provides a standard way to query each subsystem's advertised
345 * capabilities. The set of tags and values are per-system and
346 * implementation-defined.
347 *
348 * The return value is the empty string if the indicated system is undefined
349 * or if does not define the indicated tag.
350 */
352get_system_tag(const string &system, const string &tag) const {
353 Systems::const_iterator si;
354 si = _systems.find(system);
355 if (si != _systems.end()) {
356 const SystemTags &tags = (*si).second;
357 SystemTags::const_iterator ti;
358 ti = tags.find(tag);
359 if (ti != tags.end()) {
360 return (*ti).second;
361 }
362 }
363
364 return string();
365}
366
367/**
368 * Intended for use by each subsystem to register itself at startup.
369 */
371add_system(const string &system) {
372 bool inserted = _systems.insert(Systems::value_type(system, SystemTags(get_class_type()))).second;
373 if (inserted) {
374 _system_names_dirty = true;
375 }
376}
377
378/**
379 * Intended for use by each subsystem to register its set of capabilities at
380 * startup.
381 */
383set_system_tag(const string &system, const string &tag,
384 const string &value) {
385 std::pair<Systems::iterator, bool> result;
386 result = _systems.insert(Systems::value_type(system, SystemTags(get_class_type())));
387 if (result.second) {
388 _system_names_dirty = true;
389 }
390
391 SystemTags &tags = (*result.first).second;
392 tags[tag] = value;
393}
394
395/**
396 * Attempts to release memory back to the system, if possible. The pad
397 * argument is the minimum amount of unused memory to keep in the heap
398 * (against future allocations). Any memory above that may be released to the
399 * system, reducing the memory size of this process. There is no guarantee
400 * that any memory may be released.
401 *
402 * Returns true if any memory was actually released, false otherwise.
403 */
405heap_trim(size_t pad) {
406 // This actually just vectors into _memory_hook, which isn't published.
407 // This method only exists on PandaSystem for the convenience of Python
408 // programmers.
409 return memory_hook->heap_trim(pad);
410}
411
412/**
413 *
414 */
415void PandaSystem::
416output(std::ostream &out) const {
417 out << "Panda version " << get_version_string();
418}
419
420/**
421 *
422 */
423void PandaSystem::
424write(std::ostream &out) const {
425 out << *this << "\n"
426 << "compiled on " << get_build_date() << " by "
427 << get_distributor() << "\n"
428 << "with compiler " << PandaSystem::get_compiler() << "\n\n";
429
430 out << "Optional systems:\n";
431 for (Systems::const_iterator si = _systems.begin();
432 si != _systems.end();
433 ++si) {
434 out << " " << (*si).first << "\n";
435 const SystemTags &tags = (*si).second;
436 SystemTags::const_iterator ti;
437 for (ti = tags.begin(); ti != tags.end(); ++ti) {
438 out << " " << (*ti).first << " " << (*ti).second << "\n";
439 }
440 }
441}
442
443
444/**
445 * Returns the global PandaSystem object.
446 */
449 if (_global_ptr == nullptr) {
450 init_type();
451 _global_ptr = new PandaSystem;
452 }
453
454 return _global_ptr;
455}
456
457/**
458 * Refills the _system_names vector, which is used for get_system_name(), from
459 * the current set of available system names.
460 */
461void PandaSystem::
462reset_system_names() {
463 _system_names.clear();
464 _system_names.reserve(_systems.size());
465
466 Systems::const_iterator si;
467 for (si = _systems.begin(); si != _systems.end(); ++si) {
468 _system_names.push_back((*si).first);
469 }
470
471 _system_names_dirty = false;
472}
473
474/**
475 * Loads the value returned by get_package_version_string(). This is intended
476 * to be called by ConfigPageManager to preload the value from the panda-
477 * package-version config variable, for developer's convenience. This has no
478 * effect if the PANDA_PACKAGE_VERSION_STR configure variable is defined at
479 * compilation time. This also has no effect in NDEBUG mode.
480 */
481void PandaSystem::
482set_package_version_string(const string &package_version_string) {
483 _package_version_string = PANDA_PACKAGE_VERSION_STR;
484 if (_package_version_string.empty()) {
485 _package_version_string = package_version_string;
486 }
487}
488
489/**
490 * Loads the value returned by get_package_host_url(). This is intended to be
491 * called by ConfigPageManager to preload the value from the panda-package-
492 * host-url config variable, for developer's convenience. This has no effect
493 * if the PANDA_PACKAGE_HOST_URL configure variable is defined at compilation
494 * time. This also has no effect in NDEBUG mode.
495 */
496void PandaSystem::
497set_package_host_url(const string &package_host_url) {
498 _package_host_url = PANDA_PACKAGE_HOST_URL;
499 if (_package_host_url.empty()) {
500 _package_host_url = package_host_url;
501 }
502}
bool heap_trim(size_t pad)
Attempts to release memory back to the system, if possible.
This class is used as a namespace to group several global properties of Panda.
Definition pandaSystem.h:26
get_num_systems
Returns the number of Panda subsystems that have registered themselves.
Definition pandaSystem.h:69
get_sequence_version
Returns the sequence version number of the current version of Panda.
Definition pandaSystem.h:54
get_build_date
Returns a string representing the date and time at which this version of Panda (or at least dtool) wa...
Definition pandaSystem.h:61
is_official_version
Returns true if current version of Panda claims to be an "official" version, that is,...
Definition pandaSystem.h:55
get_system
Returns the nth Panda subsystem that has registered itself.
Definition pandaSystem.h:69
void set_system_tag(const std::string &system, const std::string &tag, const std::string &value)
Intended for use by each subsystem to register its set of capabilities at startup.
get_major_version
Returns the major version number of the current version of Panda.
Definition pandaSystem.h:52
get_platform
Returns a string representing the runtime platform that we are currently running on.
Definition pandaSystem.h:64
get_memory_alignment
Returns the memory alignment that Panda's allocators are using.
Definition pandaSystem.h:57
get_version_string
Returns the current version of Panda, expressed as a string, e.g.
Definition pandaSystem.h:51
get_git_commit
Returns a string representing the git commit hash that this source tree is based on,...
Definition pandaSystem.h:62
static std::string get_package_host_url()
Returns the URL of the download server that provides the Panda3D distributable package currently runn...
get_minor_version
Returns the minor version number of the current version of Panda.
Definition pandaSystem.h:53
get_distributor
Returns the string defined by the distributor of this version of Panda, or "homebuilt" if this versio...
Definition pandaSystem.h:59
get_compiler
Returns a string representing the compiler that was used to generate this version of Panda,...
Definition pandaSystem.h:60
static PandaSystem * get_global_ptr()
Returns the global PandaSystem object.
static std::string get_p3d_coreapi_version_string()
Returns the current version of Panda's Core API, expressed as a string of dot-delimited integers.
void add_system(const std::string &system)
Intended for use by each subsystem to register itself at startup.
bool has_system(const std::string &system) const
Returns true if the current version of Panda claims to have the indicated subsystem installed,...
std::string get_system_tag(const std::string &system, const std::string &tag) const
Returns the value associated with the indicated tag for the given system.
static std::string get_package_version_string()
Returns the version of the Panda3D distributable package that provides this build of Panda.
bool heap_trim(size_t pad)
Attempts to release memory back to the system, if possible.
TypeHandle is the identifier used to differentiate C++ class types.
Definition typeHandle.h:81
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.