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