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