Panda3D
 All Classes Functions Variables Enumerations
dtoolbase_cc.h
00001 // Filename: dtoolbase_cc.h
00002 // Created by:  drose (13Sep00)
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 #ifndef DTOOLBASE_CC_H
00016 #define DTOOLBASE_CC_H
00017 
00018 // This file should never be included directly; it's intended to be
00019 // included only from dtoolbase.h.  Include that file instead.
00020 
00021 #ifdef __cplusplus
00022 
00023 #ifdef USE_TAU
00024 // Tau provides this destructive version of stdbool.h that we must mask.
00025 #define __PDT_STDBOOL_H_
00026 #endif
00027 
00028 #ifdef CPPPARSER
00029 #include <iostream>
00030 #include <string>
00031 
00032 using namespace std;
00033 
00034 #define INLINE inline
00035 #define TYPENAME typename
00036 
00037 #define EXPORT_TEMPLATE_CLASS(expcl, exptp, classname)
00038 
00039 // We define the macro PUBLISHED to mark C++ methods that are to be
00040 // published via interrogate to scripting languages.  However, if
00041 // we're not running the interrogate pass (CPPPARSER isn't defined),
00042 // this maps to public.
00043 #define PUBLISHED __published
00044 
00045 typedef int streamsize;
00046 typedef int ios_openmode;
00047 typedef int ios_fmtflags;
00048 typedef int ios_iostate;
00049 typedef int ios_seekdir;
00050 
00051 #else  // CPPPARSER
00052 
00053 #ifdef PHAVE_IOSTREAM
00054 #include <iostream>
00055 #include <fstream>
00056 #include <iomanip>
00057 #else
00058 #include <iostream.h>
00059 #include <fstream.h>
00060 #include <iomanip.h>
00061 #endif
00062 
00063 #ifdef PHAVE_SSTREAM
00064 #include <sstream>
00065 #else
00066 #include "fakestringstream.h"
00067 #endif
00068 
00069 #ifdef PHAVE_NEW
00070 #include <new>
00071 #endif
00072 
00073 #include <string>
00074 
00075 #ifdef HAVE_NAMESPACE
00076 using namespace std;
00077 #endif
00078 
00079 #ifdef HAVE_TYPENAME
00080 #define TYPENAME typename
00081 #else
00082 #define TYPENAME
00083 #endif
00084 
00085 #ifndef HAVE_WCHAR_T
00086 // Some C++ libraries (os x 3.1) don't define this.
00087 typedef unsigned short wchar_t;
00088 #endif
00089 
00090 #ifndef HAVE_WSTRING
00091 // Some C++ libraries (gcc 2.95) don't define this.
00092 typedef basic_string<wchar_t> wstring;
00093 #endif
00094 
00095 #ifndef HAVE_STREAMSIZE
00096 // Some C++ libraries (Irix) don't define this.
00097 typedef int streamsize;
00098 #endif
00099 
00100 #ifndef HAVE_IOS_TYPEDEFS
00101 typedef int ios_openmode;
00102 typedef int ios_fmtflags;
00103 typedef int ios_iostate;
00104 // Old iostream libraries used ios::seek_dir instead of ios::seekdir.
00105 typedef ios::seek_dir ios_seekdir;
00106 #else
00107 typedef ios::openmode ios_openmode;
00108 typedef ios::fmtflags ios_fmtflags;
00109 typedef ios::iostate ios_iostate;
00110 typedef ios::seekdir ios_seekdir;
00111 #endif
00112 
00113 #if defined(WIN32_VC) && defined(FORCE_INLINING)
00114 // If FORCE_INLINING is defined, we use the keyword __forceinline,
00115 // which tells MS VC++ to override its internal benefit heuristic
00116 // and inline the fn if it is technically possible to do so.
00117 #define INLINE __forceinline
00118 #else
00119 #define INLINE inline
00120 #endif
00121 
00122 #if defined(WIN32_VC) && !defined(LINK_ALL_STATIC) && defined(EXPORT_TEMPLATES)
00123 // This macro must be used to export an instantiated template class
00124 // from a DLL.  If the template class name itself contains commas, it
00125 // may be necessary to first define a macro for the class name, to
00126 // allow proper macro parameter passing.
00127 #define EXPORT_TEMPLATE_CLASS(expcl, exptp, classname) \
00128   exptp template class expcl classname;
00129 #else
00130 #define EXPORT_TEMPLATE_CLASS(expcl, exptp, classname)
00131 #endif
00132 
00133 // We define the macro PUBLISHED to mark C++ methods that are to be
00134 // published via interrogate to scripting languages.  However, if
00135 // we're not running the interrogate pass (CPPPARSER isn't defined),
00136 // this maps to public.
00137 #define PUBLISHED public
00138 
00139 #endif  // CPPPARSER
00140 
00141 // The ReferenceCount class is defined later, within Panda, but we
00142 // need to pass around forward references to it here at the very low
00143 // level.
00144 class ReferenceCount;
00145 
00146 // We need a pointer to a global MemoryHook object, to manage all
00147 // malloc and free requests from Panda.  See the comments in
00148 // MemoryHook itself.
00149 class MemoryHook;
00150 EXPCL_DTOOL extern MemoryHook *memory_hook;
00151 EXPCL_DTOOL void init_memory_hook();
00152 
00153 // Now redefine some handy macros to hook into the above MemoryHook
00154 // object.
00155 #ifndef USE_MEMORY_NOWRAPPERS
00156 #define PANDA_MALLOC_SINGLE(size) (memory_hook->heap_alloc_single(size))
00157 #define PANDA_FREE_SINGLE(ptr) memory_hook->heap_free_single(ptr)
00158 #define PANDA_MALLOC_ARRAY(size) (memory_hook->heap_alloc_array(size))
00159 #define PANDA_REALLOC_ARRAY(ptr, size) (memory_hook->heap_realloc_array(ptr, size))
00160 #define PANDA_FREE_ARRAY(ptr) memory_hook->heap_free_array(ptr)
00161 #else
00162 #define PANDA_MALLOC_SINGLE(size) ::malloc(size)
00163 #define PANDA_FREE_SINGLE(ptr) ::free(ptr)
00164 #define PANDA_MALLOC_ARRAY(size) ::malloc(size)
00165 #define PANDA_REALLOC_ARRAY(ptr, size) ::realloc(ptr, size)
00166 #define PANDA_FREE_ARRAY(ptr) ::free(ptr)
00167 #endif  // USE_MEMORY_NOWRAPPERS
00168 
00169 #if defined(HAVE_THREADS) && defined(SIMPLE_THREADS)
00170 // We need another forward-reference function to allow low-level code
00171 // to cooperatively yield the timeslice, in SIMPLE_THREADS mode.
00172 extern EXPCL_DTOOL void (*global_thread_yield)();
00173 extern EXPCL_DTOOL void (*global_thread_consider_yield)();
00174 
00175 INLINE void thread_yield() {
00176   (*global_thread_yield)();
00177 }
00178 INLINE void thread_consider_yield() {
00179   (*global_thread_consider_yield)();
00180 }
00181 
00182 #else
00183 
00184 INLINE void thread_yield() {
00185 }
00186 INLINE void thread_consider_yield() {
00187 }
00188 
00189 #endif  // HAVE_THREADS && SIMPLE_THREADS
00190 
00191 #if defined(USE_TAU) && defined(WIN32)
00192 // Hack around tau's lack of DLL export declarations for Profiler class.
00193 extern EXPCL_DTOOL bool __tau_shutdown;
00194 class EXPCL_DTOOL TauProfile {
00195 public:
00196   TauProfile(void *&tautimer, char *name, char *type, int group, char *group_name) {
00197     Tau_profile_c_timer(&tautimer, name, type, group, group_name);
00198     _tautimer = tautimer;
00199     TAU_PROFILE_START(_tautimer); 
00200   }
00201   ~TauProfile() {
00202     if (!__tau_shutdown) {
00203       TAU_PROFILE_STOP(_tautimer);
00204     }
00205   }
00206 
00207 private:
00208   void *_tautimer;
00209 };
00210 
00211 #undef TAU_PROFILE
00212 #define TAU_PROFILE(name, type, group) \
00213   static void *__tautimer; \
00214   TauProfile __taupr(__tautimer, name, type, group, #group)
00215 
00216 #undef TAU_PROFILE_EXIT
00217 #define TAU_PROFILE_EXIT(msg) \
00218   __tau_shutdown = true; \
00219   Tau_exit(msg);
00220 
00221 #endif  // USE_TAU
00222 
00223 #ifdef CPPPARSER
00224 #define EXT_METHOD(cl, m) cl::m()
00225 #define EXT_METHOD_ARGS(cl, m, ...) cl::m(__VA_ARGS__)
00226 #define EXT_CONST_METHOD(cl, m) cl::m() const
00227 #define EXT_CONST_METHOD_ARGS(cl, m, ...) cl::m(__VA_ARGS__) const
00228 #define EXT_NESTED_METHOD(cl1, cl2, m) cl1::cl2::m()
00229 #define EXT_NESTED_METHOD_ARGS(cl1, cl2, m, ...) cl1::cl2::m(__VA_ARGS__)
00230 #define EXT_NESTED_CONST_METHOD(cl1, cl2, m) cl1::cl2::m() const
00231 #define EXT_NESTED_CONST_METHOD_ARGS(cl1, cl2, m, ...) cl1::cl2::m(__VA_ARGS__) const
00232 #define CALL_EXT_METHOD(cl, m, obj, ...) (obj)-> m(__VA_ARGS__)
00233 #else
00234 /* If you change these, don't forget to also change it in interrogate itself. */
00235 #define __EXT_METHOD(cl, m) _ext_ ## cl ## _ ## m
00236 #define _EXT_METHOD(cl, m) __EXT_METHOD(cl, m)
00237 #define __EXT_NEST(cl1, cl2) cl1 ## __ ## cl2
00238 #define _EXT_NEST(cl1, cl2) __EXT_NEST(cl1, cl2)
00239 #define EXT_METHOD(cl, m) _EXT_METHOD(cl, m) (cl * _ext_this)
00240 #define EXT_METHOD_ARGS(cl, m, ...) _EXT_METHOD(cl, m) (cl * _ext_this, __VA_ARGS__)
00241 #define EXT_CONST_METHOD(cl, m) _EXT_METHOD(cl, m) (const cl * _ext_this)
00242 #define EXT_CONST_METHOD_ARGS(cl, m, ...) _EXT_METHOD(cl, m) (const cl * _ext_this, __VA_ARGS__)
00243 #define EXT_NESTED_METHOD(cl1, cl2, m) _EXT_METHOD(_EXT_NEST(cl1, cl2), m) (cl1::cl2 * _ext_this)
00244 #define EXT_NESTED_METHOD_ARGS(cl1, cl2, m, ...) _EXT_METHOD(_EXT_NEST(cl1, cl2), m) (cl1::cl2 * _ext_this, __VA_ARGS__)
00245 #define EXT_NESTED_CONST_METHOD(cl1, cl2, m) _EXT_METHOD(_EXT_NEST(cl1, cl2), m) (const cl1::cl2 * _ext_this)
00246 #define EXT_NESTED_CONST_METHOD_ARGS(cl1, cl2, m, ...) _EXT_METHOD(_EXT_NEST(cl1, cl2), m) (const cl1::cl2 * _ext_this, __VA_ARGS__)
00247 #define CALL_EXT_METHOD(cl, m, ...) _EXT_METHOD(cl, m) (__VA_ARGS__)
00248 #endif
00249 
00250 #endif  //  __cplusplus
00251 #endif
 All Classes Functions Variables Enumerations