From b45f6fbbed3534e0c0c79f4fd783e5169809e414 Mon Sep 17 00:00:00 2001 From: Sam Edwards Date: Mon, 29 Oct 2018 17:50:22 -0600 Subject: [PATCH 01/26] dxgsg9: Remove DirectX 9.1 "detection" code This method of checking for pnhpast.dll was actually for DirectX 8.1 (see a16fe56c7) and its presence in the DX9 code is largely due to the copy-and-paste nature of how the DX9 GSG was created from the DX8 code. --- panda/src/dxgsg9/dxgsg9base.h | 1 - panda/src/dxgsg9/wdxGraphicsPipe9.cxx | 24 ++---------------------- panda/src/dxgsg9/wdxGraphicsPipe9.h | 1 - panda/src/dxgsg9/wdxGraphicsWindow9.cxx | 3 +-- 4 files changed, 3 insertions(+), 26 deletions(-) diff --git a/panda/src/dxgsg9/dxgsg9base.h b/panda/src/dxgsg9/dxgsg9base.h index b0e2b9dfef..430876dff5 100644 --- a/panda/src/dxgsg9/dxgsg9base.h +++ b/panda/src/dxgsg9/dxgsg9base.h @@ -211,7 +211,6 @@ struct DXScreenData { bool _is_tnl_device; bool _can_use_hw_vertex_shaders; bool _can_use_pixel_shaders; - bool _is_dx9_1; UINT _supported_screen_depths_mask; UINT _supported_tex_formats_mask; bool _supports_rgba16f_texture_format; diff --git a/panda/src/dxgsg9/wdxGraphicsPipe9.cxx b/panda/src/dxgsg9/wdxGraphicsPipe9.cxx index 6c85c6652f..ce8d33165f 100644 --- a/panda/src/dxgsg9/wdxGraphicsPipe9.cxx +++ b/panda/src/dxgsg9/wdxGraphicsPipe9.cxx @@ -193,30 +193,10 @@ init() { } // Create a Direct3D object. + __d3d9 = (*_Direct3DCreate9)(D3D_SDK_VERSION); - // these were taken from the 8.0 and 8.1 d3d8.h SDK headers - __is_dx9_1 = false; - -#define D3D_SDK_VERSION_9_0 D3D_SDK_VERSION -#define D3D_SDK_VERSION_9_1 D3D_SDK_VERSION - - // are we using 9.0 or 9.1? - WIN32_FIND_DATA TempFindData; - HANDLE hFind; - char tmppath[_MAX_PATH + 128]; - GetSystemDirectory(tmppath, MAX_PATH); - strcat(tmppath, "\\dpnhpast.dll"); - hFind = FindFirstFile (tmppath, &TempFindData); - if (hFind != INVALID_HANDLE_VALUE) { - FindClose(hFind); -// ??? This was from DX8 __is_dx9_1 = true; - __d3d9 = (*_Direct3DCreate9)(D3D_SDK_VERSION_9_1); - } else { - __is_dx9_1 = false; - __d3d9 = (*_Direct3DCreate9)(D3D_SDK_VERSION_9_0); - } if (__d3d9 == nullptr) { - wdxdisplay9_cat.error() << "Direct3DCreate9(9." << (__is_dx9_1 ? "1" : "0") << ") failed!, error = " << GetLastError() << endl; + wdxdisplay9_cat.error() << "Direct3DCreate9 failed!, error = " << GetLastError() << endl; // release_gsg(); goto error; } diff --git a/panda/src/dxgsg9/wdxGraphicsPipe9.h b/panda/src/dxgsg9/wdxGraphicsPipe9.h index 2d9eea18b0..ff25433e79 100644 --- a/panda/src/dxgsg9/wdxGraphicsPipe9.h +++ b/panda/src/dxgsg9/wdxGraphicsPipe9.h @@ -93,7 +93,6 @@ private: typedef pvector CardIDs; CardIDs _card_ids; - bool __is_dx9_1; public: static TypeHandle get_class_type() { diff --git a/panda/src/dxgsg9/wdxGraphicsWindow9.cxx b/panda/src/dxgsg9/wdxGraphicsWindow9.cxx index 3207c81189..07a265a97c 100644 --- a/panda/src/dxgsg9/wdxGraphicsWindow9.cxx +++ b/panda/src/dxgsg9/wdxGraphicsWindow9.cxx @@ -878,7 +878,7 @@ choose_device() { LARGE_INTEGER *DrvVer = &adapter_info.DriverVersion; wdxdisplay9_cat.info() - << "D3D9." << (dxpipe->__is_dx9_1 ?"1":"0") << " Adapter[" << i << "]: " << adapter_info.Description + << "D3D9 Adapter[" << i << "]: " << adapter_info.Description << ", Driver: " << adapter_info.Driver << ", DriverVersion: (" << HIWORD(DrvVer->HighPart) << "." << LOWORD(DrvVer->HighPart) << "." << HIWORD(DrvVer->LowPart) << "." << LOWORD(DrvVer->LowPart) @@ -979,7 +979,6 @@ consider_device(wdxGraphicsPipe9 *dxpipe, DXDeviceInfo *device_info) { nassertr(_dxgsg != nullptr, false); _wcontext._d3d9 = _d3d9; - _wcontext._is_dx9_1 = dxpipe->__is_dx9_1; _wcontext._card_id = device_info->cardID; // could this change by end? bool bWantStencil = (_fb_properties.get_stencil_bits() > 0); From 8d3576607ead02f5479b89994711cadd62c55364 Mon Sep 17 00:00:00 2001 From: rdb Date: Tue, 30 Oct 2018 14:10:10 +0100 Subject: [PATCH 02/26] makepanda: remove INSTALLING-PLUGINS.TXT from installer.nsi [skip ci] --- makepanda/installer.nsi | 2 -- 1 file changed, 2 deletions(-) diff --git a/makepanda/installer.nsi b/makepanda/installer.nsi index 976bfd84f5..1dab5196da 100644 --- a/makepanda/installer.nsi +++ b/makepanda/installer.nsi @@ -589,7 +589,6 @@ Section "3ds Max plug-ins" SecMaxPlugins File /nonfatal /r "${BUILT}\plugins\*.dle" File /nonfatal /r "${BUILT}\plugins\*.dlo" File /nonfatal /r "${BUILT}\plugins\*.ms" - File "${SOURCE}\doc\INSTALLING-PLUGINS.TXT" SectionEnd !endif @@ -604,7 +603,6 @@ Section "Maya plug-ins" SecMayaPlugins SetOutPath $INSTDIR\plugins File /nonfatal /r "${BUILT}\plugins\*.mll" File /nonfatal /r "${BUILT}\plugins\*.mel" - File "${SOURCE}\doc\INSTALLING-PLUGINS.TXT" SectionEnd !endif From 63484c83cbd667949ef8af03a53e84479b76b100 Mon Sep 17 00:00:00 2001 From: rdb Date: Wed, 31 Oct 2018 21:25:03 +0100 Subject: [PATCH 03/26] pipeline: CycleData should always inherit from MemoryBase We need to guarantee that CData classes are aligned properly, even if DO_PIPELINING is not enabled. --- panda/src/pipeline/cycleData.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/panda/src/pipeline/cycleData.h b/panda/src/pipeline/cycleData.h index ef21ad7a33..c2bcef4073 100644 --- a/panda/src/pipeline/cycleData.h +++ b/panda/src/pipeline/cycleData.h @@ -44,7 +44,7 @@ class EXPCL_PANDA_PIPELINE CycleData : public NodeReferenceCount // If we are *not* compiling in pipelining support, the CycleData object is // stored directly within its containing classes, and hence should not be a // ReferenceCount object. -class EXPCL_PANDA_PIPELINE CycleData +class EXPCL_PANDA_PIPELINE CycleData : public MemoryBase #endif // DO_PIPELINING { From 14411f592eac2af241cce8ca1fa7874bb3406cfe Mon Sep 17 00:00:00 2001 From: rdb Date: Thu, 1 Nov 2018 16:24:06 +0100 Subject: [PATCH 04/26] Remove obsolete .init files in configfiles directories These look like they were part of some now-defunct Disney tool. --- direct/src/configfiles/direct.init | 9 --------- panda/src/configfiles/panda.init | 10 ---------- pandatool/src/configfiles/pandatool.init | 1 - 3 files changed, 20 deletions(-) delete mode 100644 direct/src/configfiles/direct.init delete mode 100644 panda/src/configfiles/panda.init delete mode 100644 pandatool/src/configfiles/pandatool.init diff --git a/direct/src/configfiles/direct.init b/direct/src/configfiles/direct.init deleted file mode 100644 index 16eb87325c..0000000000 --- a/direct/src/configfiles/direct.init +++ /dev/null @@ -1,9 +0,0 @@ -ATTACH dmodels -ATTACH panda -MODREL ETC_PATH etc -DOCSH set parent=`dirname $DIRECT` -DOCSH if ( ${?PANDA_ROOT} ) then -DOCSH setenv PYTHONPATH "${PYTHONPATH};"`cygpath -w "$parent"` -DOCSH else -DOCSH setenv PYTHONPATH "${PYTHONPATH}:$parent" -DOCSH endif diff --git a/panda/src/configfiles/panda.init b/panda/src/configfiles/panda.init deleted file mode 100644 index 6256527d14..0000000000 --- a/panda/src/configfiles/panda.init +++ /dev/null @@ -1,10 +0,0 @@ -SETABS PANDA_VER 0.8 -MODREL ETC_PATH built/etc -DOCSH if ( ! $?CFG_PATH ) then -DOCSH setenv CFG_PATH ~ -DOCSH setenv CFG_PATH ". ${CFG_PATH} /usr/local/etc" -DOCSH endif -DOSH if [ -z "$CFG_PATH" ]; then -DOSH CFG_PATH=". $HOME /usr/local/etc" -DOSH export CFG_PATH -DOSH fi diff --git a/pandatool/src/configfiles/pandatool.init b/pandatool/src/configfiles/pandatool.init deleted file mode 100644 index 615e010d42..0000000000 --- a/pandatool/src/configfiles/pandatool.init +++ /dev/null @@ -1 +0,0 @@ -ATTACH panda From 604366aaa74259d32d54d2530bac3810ad35d687 Mon Sep 17 00:00:00 2001 From: loblao Date: Tue, 30 Oct 2018 12:13:58 -0300 Subject: [PATCH 05/26] CollisionEntrySorter: Check if entry has surface point Fixes #435 --- panda/src/collide/collisionHandlerQueue.cxx | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/panda/src/collide/collisionHandlerQueue.cxx b/panda/src/collide/collisionHandlerQueue.cxx index 75761362bd..0f6acaba52 100644 --- a/panda/src/collide/collisionHandlerQueue.cxx +++ b/panda/src/collide/collisionHandlerQueue.cxx @@ -22,10 +22,15 @@ class CollisionEntrySorter { public: CollisionEntrySorter(CollisionEntry *entry) { _entry = entry; - LVector3 vec = - entry->get_surface_point(entry->get_from_node_path()) - - entry->get_from()->get_collision_origin(); - _dist2 = vec.length_squared(); + if (entry->has_surface_point()) { + LVector3 vec = + entry->get_surface_point(entry->get_from_node_path()) - + entry->get_from()->get_collision_origin(); + _dist2 = vec.length_squared(); + } + else { + _dist2 = make_inf((PN_stdfloat)0); + } } bool operator < (const CollisionEntrySorter &other) const { return _dist2 < other._dist2; From 763049ac81345da33362e354a0af27f3d85c5d12 Mon Sep 17 00:00:00 2001 From: rdb Date: Thu, 1 Nov 2018 17:05:33 +0100 Subject: [PATCH 06/26] event: fix incorrect include in asyncFuture_ext.h --- panda/src/event/asyncFuture_ext.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/panda/src/event/asyncFuture_ext.h b/panda/src/event/asyncFuture_ext.h index 21786ee17b..94f0b3d60b 100644 --- a/panda/src/event/asyncFuture_ext.h +++ b/panda/src/event/asyncFuture_ext.h @@ -16,7 +16,7 @@ #include "extension.h" #include "py_panda.h" -#include "modelLoadRequest.h" +#include "asyncFuture.h" #ifdef HAVE_PYTHON From bc22f5781b77eb85f0dda10c638ac1f8667c9732 Mon Sep 17 00:00:00 2001 From: rdb Date: Thu, 1 Nov 2018 20:33:08 +0100 Subject: [PATCH 07/26] shader: supports preprocessed GLSL shaders in Shader.make() Fixes #436 --- panda/src/gobj/shader.cxx | 317 +++++++++++++++++++++++++++++--------- panda/src/gobj/shader.h | 13 +- 2 files changed, 254 insertions(+), 76 deletions(-) diff --git a/panda/src/gobj/shader.cxx b/panda/src/gobj/shader.cxx index 220bd56ed2..4c79745e85 100644 --- a/panda/src/gobj/shader.cxx +++ b/panda/src/gobj/shader.cxx @@ -2468,6 +2468,96 @@ read(const ShaderFile &sfile, BamCacheRecord *record) { return true; } +/** + * Loads the shader from the given string(s). Returns a boolean indicating + * success or failure. + */ +bool Shader:: +load(const ShaderFile &sbody, BamCacheRecord *record) { + _filename = ShaderFile("created-shader"); + _fullpath = Filename(); + _text._separate = sbody._separate; + + if (sbody._separate) { + if (_language == SL_none) { + shader_cat.error() + << "No shader language was specified!\n"; + return false; + } + + if (!sbody._vertex.empty() && + !do_load_source(_text._vertex, sbody._vertex, record)) { + return false; + } + if (!sbody._fragment.empty() && + !do_load_source(_text._fragment, sbody._fragment, record)) { + return false; + } + if (!sbody._geometry.empty() && + !do_load_source(_text._geometry, sbody._geometry, record)) { + return false; + } + if (!sbody._tess_control.empty() && + !do_load_source(_text._tess_control, sbody._tess_control, record)) { + return false; + } + if (!sbody._tess_evaluation.empty() && + !do_load_source(_text._tess_evaluation, sbody._tess_evaluation, record)) { + return false; + } + if (!sbody._compute.empty() && + !do_load_source(_text._compute, sbody._compute, record)) { + return false; + } + + } else { + if (!do_load_source(_text._shared, sbody._shared, record)) { + return false; + } + + // Determine which language the shader is written in. + if (_language == SL_none) { + string header; + parse_init(); + parse_line(header, true, true); + if (header == "//Cg") { + _language = SL_Cg; + } else { + shader_cat.error() + << "Unable to determine shader language of " << sbody._shared << "\n"; + return false; + } + } else if (_language == SL_GLSL) { + shader_cat.error() + << "GLSL shaders must have separate shader bodies!\n"; + return false; + } + + // Determine which language the shader is written in. + if (_language == SL_Cg) { +#ifdef HAVE_CG + cg_get_profile_from_header(_default_caps); + + if (!cg_analyze_shader(_default_caps)) { + shader_cat.error() + << "Shader encountered an error.\n"; + return false; + } +#else + shader_cat.error() + << "Tried to load Cg shader, but no Cg support is enabled.\n"; +#endif + } else { + shader_cat.error() + << "Shader is not in a supported shader-language.\n"; + return false; + } + } + + _loaded = true; + return true; +} + /** * Reads the shader file from the given path into the given string. * @@ -2476,37 +2566,85 @@ read(const ShaderFile &sfile, BamCacheRecord *record) { */ bool Shader:: do_read_source(string &into, const Filename &fn, BamCacheRecord *record) { + VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr(); + PT(VirtualFile) vf = vfs->find_file(fn, get_model_path()); + if (vf == nullptr) { + shader_cat.error() + << "Could not find shader file: " << fn << "\n"; + return false; + } + if (_language == SL_GLSL && glsl_preprocess) { - // Preprocess the GLSL file as we read it. - std::set open_files; - ostringstream sstr; - if (!r_preprocess_source(sstr, fn, Filename(), open_files, record)) { + istream *source = vf->open_read_file(true); + if (source == nullptr) { + shader_cat.error() + << "Could not open shader file: " << fn << "\n"; return false; } + + // Preprocess the GLSL file as we read it. + shader_cat.info() + << "Preprocessing shader file: " << fn << "\n"; + + std::set open_files; + ostringstream sstr; + if (!r_preprocess_source(sstr, *source, fn, vf->get_filename(), open_files, record)) { + vf->close_read_file(source); + return false; + } + vf->close_read_file(source); into = sstr.str(); } else { shader_cat.info() << "Reading shader file: " << fn << "\n"; - VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr(); - PT(VirtualFile) vf = vfs->find_file(fn, get_model_path()); - if (vf == nullptr) { - shader_cat.error() - << "Could not find shader file: " << fn << "\n"; - return false; - } - if (!vf->read_file(into, true)) { shader_cat.error() << "Could not read shader file: " << fn << "\n"; return false; } + } - if (record != nullptr) { - record->add_dependent_file(vf); + if (record != nullptr) { + record->add_dependent_file(vf); + } + + _last_modified = std::max(_last_modified, vf->get_timestamp()); + _source_files.push_back(vf->get_filename()); + + // Strip trailing whitespace. + while (!into.empty() && isspace(into[into.size() - 1])) { + into.resize(into.size() - 1); + } + + // Except add back a newline at the end, which is needed by Intel drivers. + into += "\n"; + + return true; +} + +/** + * Loads the shader file from the given string into the given string, + * performing any pre-processing on it that may be necessary. + * + * Returns false if there was an error with this shader bad enough to consider + * it 'invalid'. + */ +bool Shader:: +do_load_source(string &into, const std::string &source, BamCacheRecord *record) { + if (_language == SL_GLSL && glsl_preprocess) { + // Preprocess the GLSL file as we read it. + std::set open_files; + std::ostringstream sstr; + std::istringstream in(source); + if (!r_preprocess_source(sstr, in, Filename("created-shader"), Filename(), + open_files, record)) { + return false; } - _last_modified = std::max(_last_modified, vf->get_timestamp()); - _source_files.push_back(vf->get_filename()); + into = sstr.str(); + + } else { + into = source; } // Strip trailing whitespace. @@ -2528,10 +2666,10 @@ do_read_source(string &into, const Filename &fn, BamCacheRecord *record) { * recursive includes. */ bool Shader:: -r_preprocess_source(ostream &out, const Filename &fn, - const Filename &source_dir, - std::set &once_files, - BamCacheRecord *record, int depth) { +r_preprocess_include(ostream &out, const Filename &fn, + const Filename &source_dir, + std::set &once_files, + BamCacheRecord *record, int depth) { if (depth > glsl_include_recursion_limit) { shader_cat.error() @@ -2549,7 +2687,7 @@ r_preprocess_source(ostream &out, const Filename &fn, PT(VirtualFile) vf = vfs->find_file(fn, path); if (vf == nullptr) { shader_cat.error() - << "Could not find shader file: " << fn << "\n"; + << "Could not find shader include: " << fn << "\n"; return false; } @@ -2562,7 +2700,7 @@ r_preprocess_source(ostream &out, const Filename &fn, istream *source = vf->open_read_file(true); if (source == nullptr) { shader_cat.error() - << "Could not open shader file: " << fn << "\n"; + << "Could not open shader include: " << fn << "\n"; return false; } @@ -2578,30 +2716,43 @@ r_preprocess_source(ostream &out, const Filename &fn, // than that, unfortunately. Don't do this for the top-level file, though. // We don't want anything to get in before a potential #version directive. int fileno = 0; - if (depth > 0) { - fileno = 2048 + _included_files.size(); - // Write it into the vector so that we can substitute it later when we are - // parsing the GLSL error log. Don't store the full filename because it - // would just be too long to display. - _included_files.push_back(fn); + fileno = 2048 + _included_files.size(); - out << "#line 1 " << fileno << " // " << fn << "\n"; - if (shader_cat.is_debug()) { - shader_cat.debug() - << "Preprocessing shader include " << fileno << ": " << fn << "\n"; - } - } else { - shader_cat.info() - << "Preprocessing shader file: " << fn << "\n"; + // Write it into the vector so that we can substitute it later when we are + // parsing the GLSL error log. Don't store the full filename because it + // would just be too long to display. + _included_files.push_back(fn); + + out << "#line 1 " << fileno << " // " << fn << "\n"; + if (shader_cat.is_debug()) { + shader_cat.debug() + << "Preprocessing shader include " << fileno << ": " << fn << "\n"; } + bool result = r_preprocess_source(out, *source, fn, full_fn, once_files, record, fileno, depth); + vf->close_read_file(source); + return result; +} + +/** + * Loads a given GLSL stream line by line, processing any #pragma include and + * once statements, as well as removing any comments. + * + * The set keeps track of which files we have already included, for checking + * recursive includes. + */ +bool Shader:: +r_preprocess_source(ostream &out, istream &in, const Filename &fn, + const Filename &full_fn, std::set &once_files, + BamCacheRecord *record, int fileno, int depth) { + // Iterate over the lines for things we may need to preprocess. string line; int ext_google_include = 0; // 1 = warn, 2 = enable int ext_google_line = 0; bool had_include = false; int lineno = 0; - while (std::getline(*source, line)) { + while (std::getline(in, line)) { ++lineno; if (line.empty()) { @@ -2615,7 +2766,7 @@ r_preprocess_source(ostream &out, const Filename &fn, line.resize(line.size() - 1); string line2; - if (std::getline(*source, line2)) { + if (std::getline(in, line2)) { line += line2; out.put('\n'); ++lineno; @@ -2644,7 +2795,7 @@ r_preprocess_source(ostream &out, const Filename &fn, size_t block_end = line2.find("*/"); while (block_end == string::npos) { // Didn't find it - look in the next line. - if (std::getline(*source, line2)) { + if (std::getline(in, line2)) { out.put('\n'); ++lineno; block_end = line2.find("*/"); @@ -2703,7 +2854,7 @@ r_preprocess_source(ostream &out, const Filename &fn, } // OK, great. Process the include. - if (!r_preprocess_source(out, incfn, source_dir, once_files, record, depth + 1)) { + if (!r_preprocess_include(out, incfn, source_dir, once_files, record, depth + 1)) { // An error occurred. Pass on the failure. shader_cat.error(false) << "included at line " << lineno << " of file " << fn << ":\n " << line << "\n"; @@ -2724,8 +2875,19 @@ r_preprocess_source(ostream &out, const Filename &fn, return false; } - once_files.insert(full_fn); + if (fileno == 0) { + shader_cat.warning() + << "#pragma once in main file at line " + << lineno << " of file " << fn +#ifndef NDEBUG + << ":\n " << line +#endif + << "\n"; + } + if (!full_fn.empty()) { + once_files.insert(full_fn); + } } else { // Forward it, the driver will ignore it if it doesn't know it. out << line << "\n"; @@ -2821,7 +2983,7 @@ r_preprocess_source(ostream &out, const Filename &fn, // OK, great. Process the include. Filename source_dir = full_fn.get_dirname(); - if (!r_preprocess_source(out, incfn, source_dir, once_files, record, depth + 1)) { + if (!r_preprocess_include(out, incfn, source_dir, once_files, record, depth + 1)) { // An error occurred. Pass on the failure. shader_cat.error(false) << "included at line " << lineno << " of file " << fn << ":\n " << line << "\n"; @@ -2865,7 +3027,6 @@ r_preprocess_source(ostream &out, const Filename &fn, } } - vf->close_read_file(source); return true; } @@ -3227,28 +3388,26 @@ make(string body, ShaderLanguage lang) { if (cache_generated_shaders) { ShaderTable::const_iterator i = _make_table.find(sbody); if (i != _make_table.end() && (lang == SL_none || lang == i->second->_language)) { - return i->second; + // But check that someone hasn't modified its includes in the meantime. + if (!i->second->check_modified()) { + return i->second; + } } } PT(Shader) shader = new Shader(lang); - shader->_filename = ShaderFile("created-shader"); - shader->_text = move(sbody); - -#ifdef HAVE_CG - if (lang == SL_Cg) { - shader->cg_get_profile_from_header(_default_caps); - - if (!shader->cg_analyze_shader(_default_caps)) { - shader_cat.error() - << "Shader encountered an error.\n"; - return nullptr; - } + if (!shader->load(sbody)) { + return nullptr; } -#endif if (cache_generated_shaders) { - _make_table[shader->_text] = shader; + ShaderTable::const_iterator i = _make_table.find(shader->_text); + if (i != _make_table.end() && (lang == SL_none || lang == i->second->_language)) { + shader = i->second; + } else { + _make_table[shader->_text] = shader; + } + _make_table[std::move(sbody)] = shader; } if (dump_generated_shaders) { @@ -3290,26 +3449,27 @@ make(ShaderLanguage lang, string vertex, string fragment, string geometry, if (cache_generated_shaders) { ShaderTable::const_iterator i = _make_table.find(sbody); if (i != _make_table.end() && (lang == SL_none || lang == i->second->_language)) { - return i->second; + // But check that someone hasn't modified its includes in the meantime. + if (!i->second->check_modified()) { + return i->second; + } } } PT(Shader) shader = new Shader(lang); shader->_filename = ShaderFile("created-shader"); - shader->_text = move(sbody); - -#ifdef HAVE_CG - if (lang == SL_Cg) { - if (!shader->cg_analyze_shader(_default_caps)) { - shader_cat.error() - << "Shader encountered an error.\n"; - return nullptr; - } + if (!shader->load(sbody)) { + return nullptr; } -#endif if (cache_generated_shaders) { - _make_table[shader->_text] = shader; + ShaderTable::const_iterator i = _make_table.find(shader->_text); + if (i != _make_table.end() && (lang == SL_none || lang == i->second->_language)) { + shader = i->second; + } else { + _make_table[shader->_text] = shader; + } + _make_table[std::move(sbody)] = shader; } return shader; @@ -3333,16 +3493,27 @@ make_compute(ShaderLanguage lang, string body) { if (cache_generated_shaders) { ShaderTable::const_iterator i = _make_table.find(sbody); if (i != _make_table.end() && (lang == SL_none || lang == i->second->_language)) { - return i->second; + // But check that someone hasn't modified its includes in the meantime. + if (!i->second->check_modified()) { + return i->second; + } } } PT(Shader) shader = new Shader(lang); shader->_filename = ShaderFile("created-shader"); - shader->_text = move(sbody); + if (!shader->load(sbody)) { + return nullptr; + } if (cache_generated_shaders) { - _make_table[shader->_text] = shader; + ShaderTable::const_iterator i = _make_table.find(shader->_text); + if (i != _make_table.end() && (lang == SL_none || lang == i->second->_language)) { + shader = i->second; + } else { + _make_table[shader->_text] = shader; + } + _make_table[std::move(sbody)] = shader; } return shader; diff --git a/panda/src/gobj/shader.h b/panda/src/gobj/shader.h index 67906210f6..35971b243b 100644 --- a/panda/src/gobj/shader.h +++ b/panda/src/gobj/shader.h @@ -616,11 +616,18 @@ private: Shader(ShaderLanguage lang); bool read(const ShaderFile &sfile, BamCacheRecord *record = nullptr); + bool load(const ShaderFile &sbody, BamCacheRecord *record = nullptr); bool do_read_source(std::string &into, const Filename &fn, BamCacheRecord *record); - bool r_preprocess_source(std::ostream &out, const Filename &fn, - const Filename &source_dir, + bool do_load_source(std::string &into, const std::string &source, BamCacheRecord *record); + bool r_preprocess_include(std::ostream &out, const Filename &fn, + const Filename &source_dir, + std::set &open_files, + BamCacheRecord *record, int depth); + bool r_preprocess_source(std::ostream &out, std::istream &in, + const Filename &fn, const Filename &full_fn, std::set &open_files, - BamCacheRecord *record, int depth = 0); + BamCacheRecord *record, + int fileno = 0, int depth = 0); bool check_modified() const; From be464b61b3c10053be3ae65f1dfd0dedacb3429a Mon Sep 17 00:00:00 2001 From: rdb Date: Thu, 1 Nov 2018 22:02:45 +0100 Subject: [PATCH 08/26] shader: do not require whitespace around : in #extension directive --- panda/src/gobj/shader.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/panda/src/gobj/shader.cxx b/panda/src/gobj/shader.cxx index 4c79745e85..9a4153a5e3 100644 --- a/panda/src/gobj/shader.cxx +++ b/panda/src/gobj/shader.cxx @@ -2905,7 +2905,7 @@ r_preprocess_source(ostream &out, istream &in, const Filename &fn, // Check for special preprocessing extensions. char extension[256]; char behavior[9]; - if (sscanf(line.c_str(), " # extension%*[ \t]%255s%*[ \t]:%*[ \t]%8s", extension, behavior) == 2) { + if (sscanf(line.c_str(), " # extension%*[ \t]%255[^: \t] : %8s", extension, behavior) == 2) { // Parse the behavior string. int mode; if (strcmp(behavior, "require") == 0 || strcmp(behavior, "enable") == 0) { From f4a8e923f7c08cd9d398a6081c295c721c41720b Mon Sep 17 00:00:00 2001 From: rdb Date: Thu, 1 Nov 2018 22:03:10 +0100 Subject: [PATCH 09/26] dxgsg9: fix startup freeze when VRAM is 4GiB or higher --- panda/src/dxgsg9/wdxGraphicsPipe9.cxx | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/panda/src/dxgsg9/wdxGraphicsPipe9.cxx b/panda/src/dxgsg9/wdxGraphicsPipe9.cxx index ce8d33165f..8cb8b9782f 100644 --- a/panda/src/dxgsg9/wdxGraphicsPipe9.cxx +++ b/panda/src/dxgsg9/wdxGraphicsPipe9.cxx @@ -341,11 +341,13 @@ find_all_card_memavails() { if (!ISPOW2(dwVidMemTotal)) { // assume they wont return a proper max value, so round up to next pow // of 2 - UINT count = 0; - while ((dwVidMemTotal >> count) != 0x0) { - count++; + int count = get_next_higher_bit((uint32_t)(dwVidMemTotal - 1u)); + if (count >= 32u) { + // Maximum value that fits in a UINT. + dwVidMemTotal = 0xffffffffu; + } else { + dwVidMemTotal = (1u << count); } - dwVidMemTotal = (1 << count); } } From c4f5ed308f1bd621916fea223719f7ea961aaf0b Mon Sep 17 00:00:00 2001 From: rdb Date: Thu, 1 Nov 2018 23:25:17 +0100 Subject: [PATCH 10/26] shader: reduce unnecessary newlines and #line in preprocessed GLSL This is done by only writing out a #line when the first non-whitespace line is encountered; any blank lines before that are trimmed. This cuts down the size of the preprocessed shaders for a large project with many shader includes, such as the RenderPipeline. --- panda/src/gobj/shader.cxx | 66 +++++++++++++++++++++++++-------------- 1 file changed, 43 insertions(+), 23 deletions(-) diff --git a/panda/src/gobj/shader.cxx b/panda/src/gobj/shader.cxx index 9a4153a5e3..4b635b00e7 100644 --- a/panda/src/gobj/shader.cxx +++ b/panda/src/gobj/shader.cxx @@ -2723,7 +2723,6 @@ r_preprocess_include(ostream &out, const Filename &fn, // would just be too long to display. _included_files.push_back(fn); - out << "#line 1 " << fileno << " // " << fn << "\n"; if (shader_cat.is_debug()) { shader_cat.debug() << "Preprocessing shader include " << fileno << ": " << fn << "\n"; @@ -2752,11 +2751,17 @@ r_preprocess_source(ostream &out, istream &in, const Filename &fn, int ext_google_line = 0; bool had_include = false; int lineno = 0; + bool write_line_directive = (fileno != 0); + while (std::getline(in, line)) { ++lineno; if (line.empty()) { - out.put('\n'); + // We still write a newline to make sure the line numbering remains + // consistent, unless we are about to write a #line directive anyway. + if (!write_line_directive) { + out.put('\n'); + } continue; } @@ -2768,7 +2773,9 @@ r_preprocess_source(ostream &out, istream &in, const Filename &fn, if (std::getline(in, line2)) { line += line2; - out.put('\n'); + if (!write_line_directive) { + out.put('\n'); + } ++lineno; } else { break; @@ -2796,7 +2803,9 @@ r_preprocess_source(ostream &out, istream &in, const Filename &fn, while (block_end == string::npos) { // Didn't find it - look in the next line. if (std::getline(in, line2)) { - out.put('\n'); + if (!write_line_directive) { + out.put('\n'); + } ++lineno; block_end = line2.find("*/"); } else { @@ -2814,10 +2823,21 @@ r_preprocess_source(ostream &out, istream &in, const Filename &fn, line.resize(line.size() - 1); } + if (line.empty()) { + if (!write_line_directive) { + out.put('\n'); + } + continue; + } + // Check if this line contains a #directive. char directive[64]; if (line.size() < 8 || sscanf(line.c_str(), " # %63s", directive) != 1) { // Nope. Just pass the line through unmodified. + if (write_line_directive) { + out << "#line " << lineno << " " << fileno << " // " << fn << "\n"; + write_line_directive = false; + } out << line << "\n"; continue; } @@ -2862,8 +2882,9 @@ r_preprocess_source(ostream &out, istream &in, const Filename &fn, } // Restore the line counter. - out << "#line " << (lineno + 1) << " " << fileno << " // " << fn << "\n"; + write_line_directive = true; had_include = true; + continue; } else if (strcmp(pragma, "once") == 0) { // Do a stricter syntax check, just to be extra safe. @@ -2888,17 +2909,15 @@ r_preprocess_source(ostream &out, istream &in, const Filename &fn, if (!full_fn.empty()) { once_files.insert(full_fn); } - } else { - // Forward it, the driver will ignore it if it doesn't know it. - out << line << "\n"; + continue; } + // Otherwise, just pass it through to the driver. } else if (strcmp(directive, "endif") == 0) { // Check for an #endif after an include. We have to restore the line // number in case the include happened under an #if block. - out << line << "\n"; if (had_include) { - out << "#line " << (lineno + 1) << " " << fileno << "\n"; + write_line_directive = true; } } else if (strcmp(directive, "extension") == 0) { @@ -2931,7 +2950,8 @@ r_preprocess_source(ostream &out, istream &in, const Filename &fn, } ext_google_include = mode; ext_google_line = mode; - out << line << "\n"; + // Still pass it through to the driver, so it can enable other + // extensions. } else if (strcmp(extension, "GL_GOOGLE_include_directive") == 0) { // Enable the Google extension support for #include statements. @@ -2939,14 +2959,12 @@ r_preprocess_source(ostream &out, istream &in, const Filename &fn, // This matches the behavior of Khronos' glslang reference compiler. ext_google_include = mode; ext_google_line = mode; + continue; } else if (strcmp(extension, "GL_GOOGLE_cpp_style_line_directive") == 0) { // Enables strings in #line statements. ext_google_line = mode; - - } else { - // It's an extension the driver should worry about. - out << line << "\n"; + continue; } } else { shader_cat.error() @@ -2954,6 +2972,7 @@ r_preprocess_source(ostream &out, istream &in, const Filename &fn, << lineno << " of file " << fn << ":\n " << line << "\n"; return false; } + } else if (ext_google_include > 0 && strcmp(directive, "include") == 0) { // Warn about extension use if requested. if (ext_google_include == 1) { @@ -2991,8 +3010,9 @@ r_preprocess_source(ostream &out, istream &in, const Filename &fn, } // Restore the line counter. - out << "#line " << (lineno + 1) << " " << fileno << " // " << fn << "\n"; + write_line_directive = true; had_include = true; + continue; } else if (ext_google_line > 0 && strcmp(directive, "line") == 0) { // It's a #line directive. See if it uses a string instead of number. @@ -3016,15 +3036,15 @@ r_preprocess_source(ostream &out, istream &in, const Filename &fn, _included_files.push_back(Filename(filestr)); out << "#line " << lineno << " " << fileno << " // " << filestr << "\n"; - - } else { - // We couldn't parse the #line directive. Pass it through unmodified. - out << line << "\n"; + continue; } - } else { - // Different directive (eg. #version). Leave it untouched. - out << line << "\n"; } + + if (write_line_directive) { + out << "#line " << lineno << " " << fileno << " // " << fn << "\n"; + write_line_directive = false; + } + out << line << "\n"; } return true; From a246acc64046fd6d4f0582b749f192710bd48c39 Mon Sep 17 00:00:00 2001 From: Sam Edwards Date: Thu, 1 Nov 2018 16:03:58 -0600 Subject: [PATCH 11/26] windisplay: Undefine Configure before including d3d9.h This is for consistency with fbbc5bb9e63 which introduced the same `#undef Configure` in dxgsg9. This prevents dtool's own Configure() macro from conflicting with the declaration of D3D9's Configure function in d3d9.h. --- panda/src/windisplay/winDetectDx9.cxx | 1 + 1 file changed, 1 insertion(+) diff --git a/panda/src/windisplay/winDetectDx9.cxx b/panda/src/windisplay/winDetectDx9.cxx index 2e293950f6..4be10f0492 100644 --- a/panda/src/windisplay/winDetectDx9.cxx +++ b/panda/src/windisplay/winDetectDx9.cxx @@ -18,6 +18,7 @@ #ifndef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN 1 #endif +#undef Configure #include #include "graphicsStateGuardian.h" #include "graphicsPipe.h" From 5ac3cf3fc65c6bf447e570a8ad11766af080a49c Mon Sep 17 00:00:00 2001 From: rdb Date: Fri, 2 Nov 2018 22:33:16 +0100 Subject: [PATCH 12/26] Eliminate C++ DConfig; replace it with a Python compatibility shim --- .../src/distributed/DistributedSmoothNode.py | 3 +- direct/src/showbase/DConfig.py | 25 ++++++ direct/src/showbase/ShowBase.py | 7 +- direct/src/showbase/ShowBaseGlobal.py | 3 +- direct/src/showbase/showBase.cxx | 8 -- direct/src/showbase/showBase.h | 1 - dtool/src/dconfig/config_dconfig.cxx | 21 ----- dtool/src/dconfig/config_dconfig.h | 29 ------- dtool/src/dconfig/dconfig.I | 42 --------- dtool/src/dconfig/dconfig.cxx | 14 --- dtool/src/dconfig/dconfig.h | 27 +----- dtool/src/dconfig/p3dconfig_composite1.cxx | 3 - dtool/src/dconfig/test_config.cxx | 35 -------- dtool/src/dconfig/test_expand.cxx | 87 ------------------- dtool/src/dconfig/test_pfstream.cxx | 32 ------- dtool/src/dconfig/test_searchpath.cxx | 48 ---------- makepanda/makepanda.py | 25 +++--- panda/src/express/config_express.cxx | 8 -- panda/src/express/config_express.h | 5 -- panda/src/express/virtualFileSystem.cxx | 2 + panda/src/pgraph/config_pgraph.h | 1 + panda/src/putil/config_putil.h | 2 + pandatool/src/progbase/programBase.cxx | 1 - 23 files changed, 51 insertions(+), 378 deletions(-) create mode 100644 direct/src/showbase/DConfig.py delete mode 100644 dtool/src/dconfig/config_dconfig.cxx delete mode 100644 dtool/src/dconfig/config_dconfig.h delete mode 100644 dtool/src/dconfig/dconfig.I delete mode 100644 dtool/src/dconfig/dconfig.cxx delete mode 100644 dtool/src/dconfig/p3dconfig_composite1.cxx delete mode 100644 dtool/src/dconfig/test_config.cxx delete mode 100644 dtool/src/dconfig/test_expand.cxx delete mode 100644 dtool/src/dconfig/test_pfstream.cxx delete mode 100644 dtool/src/dconfig/test_searchpath.cxx diff --git a/direct/src/distributed/DistributedSmoothNode.py b/direct/src/distributed/DistributedSmoothNode.py index 9bc75c1da1..282ec5b88d 100644 --- a/direct/src/distributed/DistributedSmoothNode.py +++ b/direct/src/distributed/DistributedSmoothNode.py @@ -6,8 +6,7 @@ from .ClockDelta import * from . import DistributedNode from . import DistributedSmoothNodeBase from direct.task.Task import cont - -config = get_config_showbase() +from direct.showbase import DConfig as config # This number defines our tolerance for out-of-sync telemetry packets. # If a packet appears to have originated from more than MaxFuture diff --git a/direct/src/showbase/DConfig.py b/direct/src/showbase/DConfig.py new file mode 100644 index 0000000000..54c90d1566 --- /dev/null +++ b/direct/src/showbase/DConfig.py @@ -0,0 +1,25 @@ +"This module contains a deprecated shim emulating the old DConfig API." + +__all__ = [] + +from panda3d.core import (ConfigFlags, ConfigVariableBool, ConfigVariableInt, + ConfigVariableDouble, ConfigVariableString) + + +def GetBool(sym, default=False): + return ConfigVariableBool(sym, default, "DConfig", ConfigFlags.F_dconfig).value + + +def GetInt(sym, default=0): + return ConfigVariableInt(sym, default, "DConfig", ConfigFlags.F_dconfig).value + + +def GetDouble(sym, default=0.0): + return ConfigVariableDouble(sym, default, "DConfig", ConfigFlags.F_dconfig).value + + +def GetString(sym, default=""): + return ConfigVariableString(sym, default, "DConfig", ConfigFlags.F_dconfig).value + + +GetFloat = GetDouble diff --git a/direct/src/showbase/ShowBase.py b/direct/src/showbase/ShowBase.py index 13b9839255..fcd790e0bf 100644 --- a/direct/src/showbase/ShowBase.py +++ b/direct/src/showbase/ShowBase.py @@ -10,8 +10,9 @@ __all__ = ['ShowBase', 'WindowControls'] #import VerboseImport from panda3d.core import * -from panda3d.direct import get_config_showbase, throw_new_frame, init_app_for_gui +from panda3d.direct import throw_new_frame, init_app_for_gui from panda3d.direct import storeAccessibilityShortcutKeys, allowAccessibilityShortcutKeys +from . import DConfig # Register the extension methods for NodePath. from direct.extensions_native import NodePath_extensions @@ -22,7 +23,7 @@ if sys.version_info >= (3, 0): import builtins else: import __builtin__ as builtins -builtins.config = get_config_showbase() +builtins.config = DConfig from direct.directnotify.DirectNotifyGlobal import directNotify, giveNotify from .MessengerGlobal import messenger @@ -57,7 +58,7 @@ def exitfunc(): # *seem* to cause anyone any problems. class ShowBase(DirectObject.DirectObject): - config = get_config_showbase() + config = DConfig notify = directNotify.newCategory("ShowBase") def __init__(self, fStartDirect = True, windowType = None): diff --git a/direct/src/showbase/ShowBaseGlobal.py b/direct/src/showbase/ShowBaseGlobal.py index 459d5f708f..487524dd6a 100644 --- a/direct/src/showbase/ShowBaseGlobal.py +++ b/direct/src/showbase/ShowBaseGlobal.py @@ -12,9 +12,8 @@ from direct.directnotify.DirectNotifyGlobal import directNotify, giveNotify from panda3d.core import VirtualFileSystem, Notify, ClockObject, PandaSystem from panda3d.core import ConfigPageManager, ConfigVariableManager from panda3d.core import NodePath, PGTop -from panda3d.direct import get_config_showbase +from . import DConfig as config -config = get_config_showbase() __dev__ = config.GetBool('want-dev', __debug__) vfs = VirtualFileSystem.getGlobalPtr() diff --git a/direct/src/showbase/showBase.cxx b/direct/src/showbase/showBase.cxx index 7d8973996f..588dbb6540 100644 --- a/direct/src/showbase/showBase.cxx +++ b/direct/src/showbase/showBase.cxx @@ -61,14 +61,6 @@ throw_new_frame() { throw_event("NewFrame"); } -// Returns the configure object for accessing config variables from a -// scripting language. -DConfig & -get_config_showbase() { - static DConfig config_showbase; - return config_showbase; -} - // Initialize the application for making a Gui-based app, such as wx. At the // moment, this is a no-op except on Mac. void diff --git a/direct/src/showbase/showBase.h b/direct/src/showbase/showBase.h index a38a791d3b..b6b90eedd0 100644 --- a/direct/src/showbase/showBase.h +++ b/direct/src/showbase/showBase.h @@ -38,7 +38,6 @@ EXPCL_DIRECT_SHOWBASE ConfigVariableSearchPath &get_particle_path(); EXPCL_DIRECT_SHOWBASE void throw_new_frame(); -EXPCL_DIRECT_SHOWBASE DConfig &get_config_showbase(); EXPCL_DIRECT_SHOWBASE void init_app_for_gui(); // klunky interface since we cant pass array from python->C++ diff --git a/dtool/src/dconfig/config_dconfig.cxx b/dtool/src/dconfig/config_dconfig.cxx deleted file mode 100644 index f828fc8f7d..0000000000 --- a/dtool/src/dconfig/config_dconfig.cxx +++ /dev/null @@ -1,21 +0,0 @@ -/** - * PANDA 3D SOFTWARE - * Copyright (c) Carnegie Mellon University. All rights reserved. - * - * All use of this software is subject to the terms of the revised BSD - * license. You should have received a copy of this license along - * with this source code in a file named "LICENSE." - * - * @file config_dconfig.cxx - * @author drose - * @date 2000-05-15 - */ - -#include "config_dconfig.h" - -#if !defined(CPPPARSER) && !defined(LINK_ALL_STATIC) && !defined(BUILDING_DTOOL_DCONFIG) - #error Buildsystem error: BUILDING_DTOOL_DCONFIG not defined -#endif - -NotifyCategoryDef(dconfig, ""); -NotifyCategoryDef(microconfig, "dconfig"); diff --git a/dtool/src/dconfig/config_dconfig.h b/dtool/src/dconfig/config_dconfig.h deleted file mode 100644 index e01fdcf441..0000000000 --- a/dtool/src/dconfig/config_dconfig.h +++ /dev/null @@ -1,29 +0,0 @@ -/** - * PANDA 3D SOFTWARE - * Copyright (c) Carnegie Mellon University. All rights reserved. - * - * All use of this software is subject to the terms of the revised BSD - * license. You should have received a copy of this license along - * with this source code in a file named "LICENSE." - * - * @file config_dconfig.h - * @author drose - * @date 2000-05-15 - */ - -#ifndef CONFIG_DCONFIG_H -#define CONFIG_DCONFIG_H - -#ifdef WIN32_VC -/* C4231: extern before template instantiation */ -/* MPG - For some reason, this one only works if it's here */ -#pragma warning (disable : 4231) -#endif - -#include "dtoolbase.h" -#include "notifyCategoryProxy.h" - -NotifyCategoryDecl(dconfig, EXPCL_DTOOL_DCONFIG, EXPTP_DTOOL_DCONFIG); -NotifyCategoryDecl(microconfig, EXPCL_DTOOL_DCONFIG, EXPTP_DTOOL_DCONFIG); - -#endif diff --git a/dtool/src/dconfig/dconfig.I b/dtool/src/dconfig/dconfig.I deleted file mode 100644 index e40db3c2b0..0000000000 --- a/dtool/src/dconfig/dconfig.I +++ /dev/null @@ -1,42 +0,0 @@ -/** - * PANDA 3D SOFTWARE - * Copyright (c) Carnegie Mellon University. All rights reserved. - * - * All use of this software is subject to the terms of the revised BSD - * license. You should have received a copy of this license along - * with this source code in a file named "LICENSE." - * - * @file dconfig.I - * @author cary - * @date 2000-03-20 - */ - -bool DConfig:: -GetBool(const std::string &sym, bool def) { - ConfigVariableBool var(sym, def, "DConfig", ConfigFlags::F_dconfig); - return var.get_value(); -} - -int DConfig:: -GetInt(const std::string &sym, int def) { - ConfigVariableInt var(sym, def, "DConfig", ConfigFlags::F_dconfig); - return var.get_value(); -} - -float DConfig:: -GetFloat(const std::string &sym, float def) { - ConfigVariableDouble var(sym, (double)def, "DConfig", ConfigFlags::F_dconfig); - return (float)var.get_value(); -} - -double DConfig:: -GetDouble(const std::string &sym, double def) { - ConfigVariableDouble var(sym, def, "DConfig", ConfigFlags::F_dconfig); - return var.get_value(); -} - -std::string DConfig:: -GetString(const std::string &sym, const std::string &def) { - ConfigVariableString var(sym, def, "DConfig", ConfigFlags::F_dconfig); - return var.get_value(); -} diff --git a/dtool/src/dconfig/dconfig.cxx b/dtool/src/dconfig/dconfig.cxx deleted file mode 100644 index b57f5b70f4..0000000000 --- a/dtool/src/dconfig/dconfig.cxx +++ /dev/null @@ -1,14 +0,0 @@ -/** - * PANDA 3D SOFTWARE - * Copyright (c) Carnegie Mellon University. All rights reserved. - * - * All use of this software is subject to the terms of the revised BSD - * license. You should have received a copy of this license along - * with this source code in a file named "LICENSE." - * - * @file dconfig.cxx - * @author drose - * @date 1999-02-08 - */ - -#include "dconfig.h" diff --git a/dtool/src/dconfig/dconfig.h b/dtool/src/dconfig/dconfig.h index fca35685ed..fe195bf400 100644 --- a/dtool/src/dconfig/dconfig.h +++ b/dtool/src/dconfig/dconfig.h @@ -15,32 +15,7 @@ #define DCONFIG_H #include "dtoolbase.h" - -#include "config_dconfig.h" -#include "configVariableString.h" -#include "configVariableBool.h" -#include "configVariableInt.h" -#include "configVariableDouble.h" -#include "configVariableList.h" -#include "configFlags.h" - -/** - * This class emulates the old dconfig-style interface to our Panda config - * system. It exists only to provide backward-compatible support, and it is - * used primarily by Python code. For modern code, use the new - * ConfigVariable* interface instead of this deprecated interface. - */ -class EXPCL_DTOOL_DCONFIG DConfig { -PUBLISHED: - static INLINE bool GetBool(const std::string &sym, bool def = false); - static INLINE int GetInt(const std::string &sym, int def = 0); - static INLINE float GetFloat(const std::string &sym, float def = 0.); - static INLINE double GetDouble(const std::string &sym, double def = 0.); - static INLINE std::string GetString(const std::string &sym, const std::string &def = ""); -}; - -#include "dconfig.I" - +#include "notifyCategoryProxy.h" // These macros are used in each directory to call an initialization function // at static-init time. These macros may eventually be phased out in favor of diff --git a/dtool/src/dconfig/p3dconfig_composite1.cxx b/dtool/src/dconfig/p3dconfig_composite1.cxx deleted file mode 100644 index f35232700b..0000000000 --- a/dtool/src/dconfig/p3dconfig_composite1.cxx +++ /dev/null @@ -1,3 +0,0 @@ - -#include "config_dconfig.cxx" -#include "dconfig.cxx" diff --git a/dtool/src/dconfig/test_config.cxx b/dtool/src/dconfig/test_config.cxx deleted file mode 100644 index 2374bd775e..0000000000 --- a/dtool/src/dconfig/test_config.cxx +++ /dev/null @@ -1,35 +0,0 @@ -/** - * PANDA 3D SOFTWARE - * Copyright (c) Carnegie Mellon University. All rights reserved. - * - * All use of this software is subject to the terms of the revised BSD - * license. You should have received a copy of this license along - * with this source code in a file named "LICENSE." - * - * @file test_config.cxx - * @author cary - * @date 1998-09-10 - */ - -#include "dconfig.h" - -using std::cout; -using std::endl; - -#define SNARF -Configure(test); - -std::string foo = test.GetString("user"); -std::string path = test.GetString("LD_LIBRARY_PATH"); - -ConfigureFn(test) -{ - cout << "AIEE! Doing work before main()! The sky is falling!" << endl; -} - -main() -{ - cout << "Testing Configuration functionality:" << endl; - cout << "foo = " << foo << endl; - cout << "path = " << path << endl; -} diff --git a/dtool/src/dconfig/test_expand.cxx b/dtool/src/dconfig/test_expand.cxx deleted file mode 100644 index 334bf2593d..0000000000 --- a/dtool/src/dconfig/test_expand.cxx +++ /dev/null @@ -1,87 +0,0 @@ -/** - * PANDA 3D SOFTWARE - * Copyright (c) Carnegie Mellon University. All rights reserved. - * - * All use of this software is subject to the terms of the revised BSD - * license. You should have received a copy of this license along - * with this source code in a file named "LICENSE." - * - * @file test_expand.cxx - * @author cary - * @date 1998-08-31 - */ - -#include "expand.h" -#include - -using std::cout; -using std::endl; - -void TestExpandFunction() -{ - std::string line; - - line = "foo"; - cout << "input: '" << line << "'" << endl; - cout << "output: '" << Expand::Expand(line) << "'" << endl; - line = "'foo'"; - cout << "input: '" << line << "'" << endl; - cout << "output: '" << Expand::Expand(line) << "'" << endl; - line = "'$USER'"; - cout << "input: '" << line << "'" << endl; - cout << "output: '" << Expand::Expand(line) << "'" << endl; - line = "$USER"; - cout << "input: '" << line << "'" << endl; - cout << "output: '" << Expand::Expand(line) << "'" << endl; - line = "\"$USER\""; - cout << "input: '" << line << "'" << endl; - cout << "output: '" << Expand::Expand(line) << "'" << endl; - line = "`ls -l`"; - cout << "input: '" << line << "'" << endl; - cout << "output: '" << Expand::Expand(line) << "'" << endl; - line = "~"; - cout << "input: '" << line << "'" << endl; - cout << "output: '" << Expand::Expand(line) << "'" << endl; - line = "~cary"; - cout << "input: '" << line << "'" << endl; - cout << "output: '" << Expand::Expand(line) << "'" << endl; -} - -void TestExpandClass() -{ - std::string line; - - line = "foo"; - Expand::Expander ex(line); - cout << "input: '" << line << "'" << endl; - cout << "output: '" << ex() << "'" << endl; - line = "'foo'"; - cout << "input: '" << line << "'" << endl; - cout << "output: '" << ex(line) << "'" << endl; - line = "'$USER'"; - cout << "input: '" << line << "'" << endl; - cout << "output: '" << ex(line) << "'" << endl; - line = "$USER"; - cout << "input: '" << line << "'" << endl; - cout << "output: '" << ex(line) << "'" << endl; - line = "\"$USER\""; - cout << "input: '" << line << "'" << endl; - cout << "output: '" << ex(line) << "'" << endl; - line = "`ls -l`"; - cout << "input: '" << line << "'" << endl; - cout << "output: '" << ex(line) << "'" << endl; - line = "~"; - cout << "input: '" << line << "'" << endl; - cout << "output: '" << ex(line) << "'" << endl; - line = "~cary"; - cout << "input: '" << line << "'" << endl; - cout << "output: '" << ex(line) << "'" << endl; -} - -main() -{ - cout << endl << "Testing shell expansion (function version):" << endl; - TestExpandFunction(); - cout << endl << "Testing shell expansion (class version):" << endl; - TestExpandClass(); -} diff --git a/dtool/src/dconfig/test_pfstream.cxx b/dtool/src/dconfig/test_pfstream.cxx deleted file mode 100644 index 9b211c2381..0000000000 --- a/dtool/src/dconfig/test_pfstream.cxx +++ /dev/null @@ -1,32 +0,0 @@ -/** - * PANDA 3D SOFTWARE - * Copyright (c) Carnegie Mellon University. All rights reserved. - * - * All use of this software is subject to the terms of the revised BSD - * license. You should have received a copy of this license along - * with this source code in a file named "LICENSE." - * - * @file test_pfstream.cxx - * @author cary - * @date 1998-08-31 - */ - -#include "pfstream.h" -#include - -void ReadIt(std::istream& ifs) { - std::string line; - - while (!ifs.eof()) { - std::getline(ifs, line); - if (line.length() != 0) - std::cout << line << std::endl; - } -} - -main() -{ - IPipeStream ipfs("ls -l"); - - ReadIt(ipfs); -} diff --git a/dtool/src/dconfig/test_searchpath.cxx b/dtool/src/dconfig/test_searchpath.cxx deleted file mode 100644 index 4abf1f71bd..0000000000 --- a/dtool/src/dconfig/test_searchpath.cxx +++ /dev/null @@ -1,48 +0,0 @@ -/** - * PANDA 3D SOFTWARE - * Copyright (c) Carnegie Mellon University. All rights reserved. - * - * All use of this software is subject to the terms of the revised BSD - * license. You should have received a copy of this license along - * with this source code in a file named "LICENSE." - * - * @file test_searchpath.cxx - * @author cary - * @date 1998-09-01 - */ - -#include "dSearchPath.h" -// #include "expand.h" -#include - -using std::cout; -using std::endl; - -void TestSearch() -{ - std::string line, path; - -// path = ".:~ etc"; - path = ". /etc"; -// path = Expand::Expand(path); - line = "searchpath.h"; - cout << "looking for file '" << line << "' in path '" << path << "': '"; - line = DSearchPath::search_path(line, path); - cout << line << "'" << endl; - - line = ".cshrc"; - cout << "looking for file '" << line << "' in path '" << path << "': '"; - line = DSearchPath::search_path(line, path); - cout << line << "'" << endl; - - line = "passwd"; - cout << "looking for file '" << line << "' in path '" << path << "': '"; - line = DSearchPath::search_path(line, path); - cout << line << "'" << endl; -} - -main() -{ - cout << "Testing search path:" << endl; - TestSearch(); -} diff --git a/makepanda/makepanda.py b/makepanda/makepanda.py index 7f82da5b80..96effc4c43 100755 --- a/makepanda/makepanda.py +++ b/makepanda/makepanda.py @@ -2862,6 +2862,20 @@ except ImportError as err: if "No module named %s" not in str(err): raise""" % (module, module) +panda_modules_code += """ + +from direct.showbase import DConfig + +def get_config_showbase(): + return DConfig + +def get_config_express(): + return DConfig + +getConfigShowbase = get_config_showbase +getConfigExpress = get_config_express +""" + exthelpers_code = """ "This module is deprecated. Import from direct.extensions_native.extension_native_helpers instead." from direct.extensions_native.extension_native_helpers import * @@ -3412,13 +3426,6 @@ OPTS=['DIR:dtool/src/prc', 'BUILDING:DTOOLCONFIG', 'OPENSSL'] TargetAdd('p3prc_composite1.obj', opts=OPTS, input='p3prc_composite1.cxx') TargetAdd('p3prc_composite2.obj', opts=OPTS, input='p3prc_composite2.cxx') -# -# DIRECTORY: dtool/src/dconfig/ -# - -OPTS=['DIR:dtool/src/dconfig', 'BUILDING:DTOOLCONFIG'] -TargetAdd('p3dconfig_composite1.obj', opts=OPTS, input='p3dconfig_composite1.cxx') - # # DIRECTORY: dtool/metalibs/dtoolconfig/ # @@ -3426,7 +3433,6 @@ TargetAdd('p3dconfig_composite1.obj', opts=OPTS, input='p3dconfig_composite1.cxx OPTS=['DIR:dtool/metalibs/dtoolconfig', 'BUILDING:DTOOLCONFIG'] TargetAdd('p3dtoolconfig_dtoolconfig.obj', opts=OPTS, input='dtoolconfig.cxx') TargetAdd('libp3dtoolconfig.dll', input='p3dtoolconfig_dtoolconfig.obj') -TargetAdd('libp3dtoolconfig.dll', input='p3dconfig_composite1.obj') TargetAdd('libp3dtoolconfig.dll', input='p3prc_composite1.obj') TargetAdd('libp3dtoolconfig.dll', input='p3prc_composite2.obj') TargetAdd('libp3dtoolconfig.dll', input='libp3dtool.dll') @@ -5640,7 +5646,6 @@ if (RTDIST): TargetAdd('plugin_standalone_dtoolutil_filename_assist.obj', opts=OPTS, input='filename_assist.mm') TargetAdd('plugin_standalone_prc_composite1.obj', opts=OPTS, input='p3prc_composite1.cxx') TargetAdd('plugin_standalone_prc_composite2.obj', opts=OPTS, input='p3prc_composite2.cxx') - TargetAdd('plugin_standalone_dconfig_composite1.obj', opts=OPTS, input='p3dconfig_composite1.cxx') TargetAdd('plugin_standalone_express_composite1.obj', opts=OPTS, input='p3express_composite1.cxx') TargetAdd('plugin_standalone_express_composite2.obj', opts=OPTS, input='p3express_composite2.cxx') TargetAdd('plugin_standalone_downloader_composite1.obj', opts=OPTS, input='p3downloader_composite1.cxx') @@ -5659,7 +5664,6 @@ if (RTDIST): TargetAdd('p3dembed.exe', input='plugin_standalone_dtoolutil_filename_assist.obj') TargetAdd('p3dembed.exe', input='plugin_standalone_prc_composite1.obj') TargetAdd('p3dembed.exe', input='plugin_standalone_prc_composite2.obj') - TargetAdd('p3dembed.exe', input='plugin_standalone_dconfig_composite1.obj') TargetAdd('p3dembed.exe', input='plugin_standalone_express_composite1.obj') TargetAdd('p3dembed.exe', input='plugin_standalone_express_composite2.obj') TargetAdd('p3dembed.exe', input='plugin_standalone_downloader_composite1.obj') @@ -5688,7 +5692,6 @@ if (RTDIST): TargetAdd('p3dembedw.exe', input='plugin_standalone_dtoolutil_composite2.obj') TargetAdd('p3dembedw.exe', input='plugin_standalone_prc_composite1.obj') TargetAdd('p3dembedw.exe', input='plugin_standalone_prc_composite2.obj') - TargetAdd('p3dembedw.exe', input='plugin_standalone_dconfig_composite1.obj') TargetAdd('p3dembedw.exe', input='plugin_standalone_express_composite1.obj') TargetAdd('p3dembedw.exe', input='plugin_standalone_express_composite2.obj') TargetAdd('p3dembedw.exe', input='plugin_standalone_downloader_composite1.obj') diff --git a/panda/src/express/config_express.cxx b/panda/src/express/config_express.cxx index c9e664db34..c147a1ce8f 100644 --- a/panda/src/express/config_express.cxx +++ b/panda/src/express/config_express.cxx @@ -190,11 +190,3 @@ get_verify_dcast() { return *verify_dcast; } - -// Returns the configure object for accessing config variables from a -// scripting language. -DConfig & -get_config_express() { - static DConfig config_express; - return config_express; -} diff --git a/panda/src/express/config_express.h b/panda/src/express/config_express.h index 13719ad8a3..7ec19749f0 100644 --- a/panda/src/express/config_express.h +++ b/panda/src/express/config_express.h @@ -54,11 +54,6 @@ extern ConfigVariableBool multifile_always_binary; extern EXPCL_PANDA_EXPRESS ConfigVariableBool collect_tcp; extern EXPCL_PANDA_EXPRESS ConfigVariableDouble collect_tcp_interval; -// Expose the Config variable for Python access. -BEGIN_PUBLISH -EXPCL_PANDA_EXPRESS DConfig &get_config_express(); -END_PUBLISH - extern EXPCL_PANDA_EXPRESS void init_libexpress(); #endif /* __CONFIG_UTIL_H__ */ diff --git a/panda/src/express/virtualFileSystem.cxx b/panda/src/express/virtualFileSystem.cxx index eb915b566c..84b6f67224 100644 --- a/panda/src/express/virtualFileSystem.cxx +++ b/panda/src/express/virtualFileSystem.cxx @@ -22,6 +22,8 @@ #include "dSearchPath.h" #include "dcast.h" #include "config_express.h" +#include "configVariableList.h" +#include "configVariableString.h" #include "executionEnvironment.h" #include "pset.h" diff --git a/panda/src/pgraph/config_pgraph.h b/panda/src/pgraph/config_pgraph.h index 988c9b1d2b..22050bd75e 100644 --- a/panda/src/pgraph/config_pgraph.h +++ b/panda/src/pgraph/config_pgraph.h @@ -21,6 +21,7 @@ #include "configVariableInt.h" #include "configVariableDouble.h" #include "configVariableList.h" +#include "configVariableString.h" class DSearchPath; diff --git a/panda/src/putil/config_putil.h b/panda/src/putil/config_putil.h index ec9f683378..dc8681b43c 100644 --- a/panda/src/putil/config_putil.h +++ b/panda/src/putil/config_putil.h @@ -16,9 +16,11 @@ #include "pandabase.h" #include "notifyCategoryProxy.h" +#include "configVariableBool.h" #include "configVariableSearchPath.h" #include "configVariableEnum.h" #include "configVariableDouble.h" +#include "configVariableInt.h" #include "bamEnums.h" #include "dconfig.h" diff --git a/pandatool/src/progbase/programBase.cxx b/pandatool/src/progbase/programBase.cxx index 9cdb70263d..a509e93edf 100644 --- a/pandatool/src/progbase/programBase.cxx +++ b/pandatool/src/progbase/programBase.cxx @@ -19,7 +19,6 @@ #include "dSearchPath.h" #include "coordinateSystem.h" #include "dconfig.h" -#include "config_dconfig.h" #include "string_utils.h" #include "vector_string.h" #include "configVariableInt.h" From b5bf6cd73c0d43f2caf32046143786d874e7227c Mon Sep 17 00:00:00 2001 From: Sam Edwards Date: Sat, 3 Nov 2018 22:40:13 -0600 Subject: [PATCH 13/26] vision: Fix missing includes/declarations --- panda/src/vision/webcamVideoCursorOpenCV.cxx | 7 ++++++- panda/src/vision/webcamVideoCursorOpenCV.h | 1 + panda/src/vision/webcamVideoCursorV4L.cxx | 5 +++++ 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/panda/src/vision/webcamVideoCursorOpenCV.cxx b/panda/src/vision/webcamVideoCursorOpenCV.cxx index 444557fde8..629cd927ae 100644 --- a/panda/src/vision/webcamVideoCursorOpenCV.cxx +++ b/panda/src/vision/webcamVideoCursorOpenCV.cxx @@ -11,12 +11,17 @@ * @date 2010-10-20 */ -#include "webcamVideoOpenCV.h" +#include "webcamVideoCursorOpenCV.h" #ifdef HAVE_OPENCV +#include "webcamVideoOpenCV.h" +#include "movieVideoCursor.h" + #include "pStatTimer.h" +#include + TypeHandle WebcamVideoCursorOpenCV::_type_handle; /** diff --git a/panda/src/vision/webcamVideoCursorOpenCV.h b/panda/src/vision/webcamVideoCursorOpenCV.h index 6f7e0758f6..3ef1145bc2 100644 --- a/panda/src/vision/webcamVideoCursorOpenCV.h +++ b/panda/src/vision/webcamVideoCursorOpenCV.h @@ -22,6 +22,7 @@ #include "movieVideoCursor.h" class WebcamVideoOpenCV; +struct CvCapture; /** * The Video4Linux implementation of webcams. diff --git a/panda/src/vision/webcamVideoCursorV4L.cxx b/panda/src/vision/webcamVideoCursorV4L.cxx index 95565f9428..8bb77658f6 100644 --- a/panda/src/vision/webcamVideoCursorV4L.cxx +++ b/panda/src/vision/webcamVideoCursorV4L.cxx @@ -11,8 +11,13 @@ * @date 2010-06-11 */ +#include "webcamVideoCursorV4L.h" + +#include "config_vision.h" #include "webcamVideoV4L.h" +#include "movieVideoCursor.h" + #if defined(HAVE_VIDEO4LINUX) && !defined(CPPPARSER) #include From 0b91b3eeb3b0b74e85aa3c7aaf396994e960bf49 Mon Sep 17 00:00:00 2001 From: Sam Edwards Date: Sat, 3 Nov 2018 22:45:34 -0600 Subject: [PATCH 14/26] vrpn: Add VRPN headers to parser-inc, remove CPPPARSER workarounds --- dtool/src/parser-inc/vrpn_Analog.h | 4 ++++ dtool/src/parser-inc/vrpn_Button.h | 4 ++++ dtool/src/parser-inc/vrpn_Configure.h | 3 +++ dtool/src/parser-inc/vrpn_Connection.h | 3 +++ dtool/src/parser-inc/vrpn_Dial.h | 4 ++++ dtool/src/parser-inc/vrpn_Tracker.h | 6 ++++++ panda/src/vrpn/vrpn_interface.h | 10 ---------- 7 files changed, 24 insertions(+), 10 deletions(-) create mode 100644 dtool/src/parser-inc/vrpn_Analog.h create mode 100644 dtool/src/parser-inc/vrpn_Button.h create mode 100644 dtool/src/parser-inc/vrpn_Configure.h create mode 100644 dtool/src/parser-inc/vrpn_Connection.h create mode 100644 dtool/src/parser-inc/vrpn_Dial.h create mode 100644 dtool/src/parser-inc/vrpn_Tracker.h diff --git a/dtool/src/parser-inc/vrpn_Analog.h b/dtool/src/parser-inc/vrpn_Analog.h new file mode 100644 index 0000000000..f8951d032a --- /dev/null +++ b/dtool/src/parser-inc/vrpn_Analog.h @@ -0,0 +1,4 @@ +#pragma once + +class vrpn_Analog_Remote; +typedef void vrpn_ANALOGCB; diff --git a/dtool/src/parser-inc/vrpn_Button.h b/dtool/src/parser-inc/vrpn_Button.h new file mode 100644 index 0000000000..433c282a44 --- /dev/null +++ b/dtool/src/parser-inc/vrpn_Button.h @@ -0,0 +1,4 @@ +#pragma once + +class vrpn_Button_Remote; +typedef void vrpn_BUTTONCB; diff --git a/dtool/src/parser-inc/vrpn_Configure.h b/dtool/src/parser-inc/vrpn_Configure.h new file mode 100644 index 0000000000..9e4a950e73 --- /dev/null +++ b/dtool/src/parser-inc/vrpn_Configure.h @@ -0,0 +1,3 @@ +#pragma once + +#define VRPN_CALLBACK diff --git a/dtool/src/parser-inc/vrpn_Connection.h b/dtool/src/parser-inc/vrpn_Connection.h new file mode 100644 index 0000000000..c35b54de38 --- /dev/null +++ b/dtool/src/parser-inc/vrpn_Connection.h @@ -0,0 +1,3 @@ +#pragma once + +class vrpn_Connection; diff --git a/dtool/src/parser-inc/vrpn_Dial.h b/dtool/src/parser-inc/vrpn_Dial.h new file mode 100644 index 0000000000..34ae1269a7 --- /dev/null +++ b/dtool/src/parser-inc/vrpn_Dial.h @@ -0,0 +1,4 @@ +#pragma once + +class vrpn_Dial_Remote; +typedef void vrpn_DIALCB; diff --git a/dtool/src/parser-inc/vrpn_Tracker.h b/dtool/src/parser-inc/vrpn_Tracker.h new file mode 100644 index 0000000000..2fe1eecd9a --- /dev/null +++ b/dtool/src/parser-inc/vrpn_Tracker.h @@ -0,0 +1,6 @@ +#pragma once + +class vrpn_Tracker_Remote; +typedef void vrpn_TRACKERCB; +typedef void vrpn_TRACKERACCCB; +typedef void vrpn_TRACKERVELCB; diff --git a/panda/src/vrpn/vrpn_interface.h b/panda/src/vrpn/vrpn_interface.h index a788d7ae73..c85c05e31b 100644 --- a/panda/src/vrpn/vrpn_interface.h +++ b/panda/src/vrpn/vrpn_interface.h @@ -16,16 +16,6 @@ #include "pandabase.h" -#ifdef CPPPARSER - // For correct interrogate parsing of UNC's vrpn library. - #if defined(WIN32_VC) || defined(WIN64_VC) - #define SOCKET int - #else - #define linux - typedef struct timeval timeval; - #endif -#endif - // VPRN misses an include to this in vrpn_Shared.h. #include From 842667fd1a80fd6dfc74b8804756784b1012a21b Mon Sep 17 00:00:00 2001 From: rdb Date: Sun, 4 Nov 2018 15:22:54 +0100 Subject: [PATCH 15/26] physx: fix missing include [skip ci] --- panda/src/physx/config_physx.h | 1 + 1 file changed, 1 insertion(+) diff --git a/panda/src/physx/config_physx.h b/panda/src/physx/config_physx.h index f17af252b6..3c3925ec92 100644 --- a/panda/src/physx/config_physx.h +++ b/panda/src/physx/config_physx.h @@ -19,6 +19,7 @@ #include "configVariableBool.h" #include "configVariableEnum.h" #include "configVariableInt.h" +#include "configVariableString.h" #include "dconfig.h" #include "physxEnums.h" From b13c4fb8d19294d76ecfa0f104f906998ec78597 Mon Sep 17 00:00:00 2001 From: rdb Date: Mon, 5 Nov 2018 21:14:21 +0100 Subject: [PATCH 16/26] pystub: add a few more calls --- dtool/src/pystub/pystub.cxx | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/dtool/src/pystub/pystub.cxx b/dtool/src/pystub/pystub.cxx index b2e9d4d62f..299da8fa0f 100644 --- a/dtool/src/pystub/pystub.cxx +++ b/dtool/src/pystub/pystub.cxx @@ -27,6 +27,8 @@ extern "C" { EXPCL_PYSTUB int PyCFunction_New(...); EXPCL_PYSTUB int PyCFunction_NewEx(...); EXPCL_PYSTUB int PyCallable_Check(...); + EXPCL_PYSTUB int PyCapsule_GetPointer(...); + EXPCL_PYSTUB int PyCapsule_New(...); EXPCL_PYSTUB int PyDict_DelItem(...); EXPCL_PYSTUB int PyDict_DelItemString(...); EXPCL_PYSTUB int PyDict_GetItem(...); @@ -133,6 +135,7 @@ extern "C" { EXPCL_PYSTUB int PyString_InternInPlace(...); EXPCL_PYSTUB int PyString_Size(...); EXPCL_PYSTUB int PySys_GetObject(...); + EXPCL_PYSTUB int PySys_SetObject(...); EXPCL_PYSTUB int PyThreadState_Clear(...); EXPCL_PYSTUB int PyThreadState_Delete(...); EXPCL_PYSTUB int PyThreadState_Get(...); @@ -216,6 +219,7 @@ extern "C" { EXPCL_PYSTUB extern void *PyExc_ImportError; EXPCL_PYSTUB extern void *PyExc_IndexError; EXPCL_PYSTUB extern void *PyExc_KeyError; + EXPCL_PYSTUB extern void *PyExc_NameError; EXPCL_PYSTUB extern void *PyExc_OSError; EXPCL_PYSTUB extern void *PyExc_OverflowError; EXPCL_PYSTUB extern void *PyExc_RuntimeError; @@ -257,6 +261,8 @@ int PyBytes_Size(...) { return 0; } int PyCFunction_New(...) { return 0; }; int PyCFunction_NewEx(...) { return 0; }; int PyCallable_Check(...) { return 0; } +int PyCapsule_GetPointer(...) { return 0; } +int PyCapsule_New(...) { return 0; } int PyDict_DelItem(...) { return 0; } int PyDict_DelItemString(...) { return 0; } int PyDict_GetItem(...) { return 0; } @@ -363,6 +369,7 @@ int PyString_FromStringAndSize(...) { return 0; } int PyString_InternFromString(...) { return 0; } int PyString_InternInPlace(...) { return 0; } int PySys_GetObject(...) { return 0; } +int PySys_SetObject(...) { return 0; } int PyThreadState_Clear(...) { return 0; } int PyThreadState_Delete(...) { return 0; } int PyThreadState_Get(...) { return 0; } @@ -452,6 +459,7 @@ void *PyExc_FutureWarning = nullptr; void *PyExc_ImportError = nullptr; void *PyExc_IndexError = nullptr; void *PyExc_KeyError = nullptr; +void *PyExc_NameError = nullptr; void *PyExc_OSError = nullptr; void *PyExc_OverflowError = nullptr; void *PyExc_RuntimeError = nullptr; From da05ef1f5c2250cc9dc8e24ed8b7c32eec1bbc19 Mon Sep 17 00:00:00 2001 From: Brian Lach Date: Mon, 5 Nov 2018 21:16:33 +0100 Subject: [PATCH 17/26] glgsg: send fog parameters to GLSL shaders Closes #438 --- panda/src/glstuff/glShaderContext_src.cxx | 72 +++++++++++++++++++++++ 1 file changed, 72 insertions(+) diff --git a/panda/src/glstuff/glShaderContext_src.cxx b/panda/src/glstuff/glShaderContext_src.cxx index 64a5e77553..b3a608d068 100644 --- a/panda/src/glstuff/glShaderContext_src.cxx +++ b/panda/src/glstuff/glShaderContext_src.cxx @@ -1145,6 +1145,78 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) { } return; } + if (size > 4 && noprefix.substr(0, 4) == "Fog.") { + Shader::ShaderMatSpec bind; + bind._id = arg_id; + bind._func = Shader::SMF_first; + bind._arg[0] = nullptr; + bind._dep[0] = Shader::SSD_general | Shader::SSD_fog; + bind._part[1] = Shader::SMO_identity; + bind._arg[1] = nullptr; + bind._dep[1] = Shader::SSD_NONE; + + if (noprefix == "Fog.color") { + bind._part[0] = Shader::SMO_attr_fogcolor; + + if (param_type == GL_FLOAT_VEC3) { + bind._piece = Shader::SMP_row3x3; + } else if (param_type == GL_FLOAT_VEC4) { + bind._piece = Shader::SMP_row3; + } else { + GLCAT.error() + << "p3d_Fog.color should be vec3 or vec4\n"; + return; + } + + } else if (noprefix == "Fog.density") { + bind._part[0] = Shader::SMO_attr_fog; + + if (param_type == GL_FLOAT) { + bind._piece = Shader::SMP_row3x1; + } else { + GLCAT.error() + << "p3d_Fog.density should be float\n"; + return; + } + + } else if (noprefix == "Fog.start") { + bind._part[0] = Shader::SMO_attr_fog; + + if (param_type == GL_FLOAT) { + bind._piece = Shader::SMP_cell13; + } else { + GLCAT.error() + << "p3d_Fog.start should be float\n"; + return; + } + + } else if (noprefix == "Fog.end") { + bind._part[0] = Shader::SMO_attr_fog; + + if (param_type == GL_FLOAT) { + bind._piece = Shader::SMP_cell14; + } else { + GLCAT.error() + << "p3d_Fog.end should be float\n"; + return; + } + + } else if (noprefix == "Fog.scale") { + bind._part[0] = Shader::SMO_attr_fog; + + if (param_type == GL_FLOAT) { + bind._piece = Shader::SMP_cell15; + } else { + GLCAT.error() + << "p3d_Fog.scale should be float\n"; + return; + } + } + + _shader->_mat_spec.push_back(bind); + _shader->_mat_deps |= bind._dep[0]; + return; + } if (noprefix == "LightModel.ambient") { Shader::ShaderMatSpec bind; bind._id = arg_id; From e6f870ece6f973fd57ecf57c62ec96a4a898cc6c Mon Sep 17 00:00:00 2001 From: rdb Date: Mon, 5 Nov 2018 21:48:50 +0100 Subject: [PATCH 18/26] Remove Python type tables from interrogatedb --- dtool/src/dtoolbase/typeHandle.cxx | 13 ++ dtool/src/dtoolbase/typeHandle.h | 2 + dtool/src/dtoolbase/typeRegistry.cxx | 16 ++ dtool/src/dtoolbase/typeRegistry.h | 1 + dtool/src/dtoolbase/typeRegistryNode.I | 13 ++ dtool/src/dtoolbase/typeRegistryNode.cxx | 23 +++ dtool/src/dtoolbase/typeRegistryNode.h | 5 + .../interfaceMakerPythonNative.cxx | 114 +++++++++----- dtool/src/interrogate/interrogate_module.cxx | 13 +- dtool/src/interrogatedb/py_panda.I | 10 +- dtool/src/interrogatedb/py_panda.cxx | 149 ++++++------------ dtool/src/interrogatedb/py_panda.h | 20 ++- 12 files changed, 216 insertions(+), 163 deletions(-) diff --git a/dtool/src/dtoolbase/typeHandle.cxx b/dtool/src/dtoolbase/typeHandle.cxx index 15fac6b60f..30d499bf01 100644 --- a/dtool/src/dtoolbase/typeHandle.cxx +++ b/dtool/src/dtoolbase/typeHandle.cxx @@ -153,6 +153,19 @@ deallocate_array(void *ptr) { PANDA_FREE_ARRAY(ptr); } +/** + * Returns the internal void pointer that is stored for interrogate's benefit. + */ +PyObject *TypeHandle:: +get_python_type() const { + TypeRegistryNode *rnode = TypeRegistry::ptr()->look_up(*this, nullptr); + if (rnode != nullptr) { + return rnode->get_python_type(); + } else { + return nullptr; + } +} + /** * Return the Index of the BEst fit Classs from a set */ diff --git a/dtool/src/dtoolbase/typeHandle.h b/dtool/src/dtoolbase/typeHandle.h index 97dc445443..ed5ab3f586 100644 --- a/dtool/src/dtoolbase/typeHandle.h +++ b/dtool/src/dtoolbase/typeHandle.h @@ -138,6 +138,8 @@ PUBLISHED: MAKE_SEQ_PROPERTY(child_classes, get_num_child_classes, get_child_class); public: + PyObject *get_python_type() const; + void *allocate_array(size_t size) RETURNS_ALIGNED(MEMORY_HOOK_ALIGNMENT); void *reallocate_array(void *ptr, size_t size) RETURNS_ALIGNED(MEMORY_HOOK_ALIGNMENT); void deallocate_array(void *ptr); diff --git a/dtool/src/dtoolbase/typeRegistry.cxx b/dtool/src/dtoolbase/typeRegistry.cxx index 23cdb5ebfb..d18ca61244 100644 --- a/dtool/src/dtoolbase/typeRegistry.cxx +++ b/dtool/src/dtoolbase/typeRegistry.cxx @@ -207,6 +207,22 @@ record_alternate_name(TypeHandle type, const string &name) { _lock->unlock(); } +/** + * Records the given Python type pointer in the type registry for the benefit + * of interrogate. + */ +void TypeRegistry:: +record_python_type(TypeHandle type, PyObject *python_type) { + _lock->lock(); + + TypeRegistryNode *rnode = look_up(type, nullptr); + if (rnode != nullptr) { + rnode->_python_type = python_type; + } + + _lock->unlock(); +} + /** * Looks for a previously-registered type of the given name. Returns its * TypeHandle if it exists, or TypeHandle::none() if there is no such type. diff --git a/dtool/src/dtoolbase/typeRegistry.h b/dtool/src/dtoolbase/typeRegistry.h index dc7df60541..4a6bd5d1e0 100644 --- a/dtool/src/dtoolbase/typeRegistry.h +++ b/dtool/src/dtoolbase/typeRegistry.h @@ -45,6 +45,7 @@ PUBLISHED: void record_derivation(TypeHandle child, TypeHandle parent); void record_alternate_name(TypeHandle type, const std::string &name); + void record_python_type(TypeHandle type, PyObject *python_type); TypeHandle find_type(const std::string &name) const; TypeHandle find_type_by_id(int id) const; diff --git a/dtool/src/dtoolbase/typeRegistryNode.I b/dtool/src/dtoolbase/typeRegistryNode.I index 4328a47d79..1556e63847 100644 --- a/dtool/src/dtoolbase/typeRegistryNode.I +++ b/dtool/src/dtoolbase/typeRegistryNode.I @@ -11,6 +11,19 @@ * @date 2001-08-06 */ +/** + * Returns the Python type object associated with this node. + */ +INLINE PyObject *TypeRegistryNode:: +get_python_type() const { + if (_python_type != nullptr || _parent_classes.empty()) { + return _python_type; + } else { + // Recurse through parent classes. + return r_get_python_type(); + } +} + /** * */ diff --git a/dtool/src/dtoolbase/typeRegistryNode.cxx b/dtool/src/dtoolbase/typeRegistryNode.cxx index f809ddcc0b..19b4629236 100644 --- a/dtool/src/dtoolbase/typeRegistryNode.cxx +++ b/dtool/src/dtoolbase/typeRegistryNode.cxx @@ -308,6 +308,29 @@ r_build_subtrees(TypeRegistryNode *top, int bit_count, } } +/** + * Recurses through the parent nodes to find the best Python type object to + * represent objects of this type. + */ +PyObject *TypeRegistryNode:: +r_get_python_type() const { + Classes::const_iterator ni; + for (ni = _parent_classes.begin(); ni != _parent_classes.end(); ++ni) { + const TypeRegistryNode *parent = *ni; + if (parent->_python_type != nullptr) { + return parent->_python_type; + + } else if (!parent->_parent_classes.empty()) { + PyObject *py_type = parent->r_get_python_type(); + if (py_type != nullptr) { + return py_type; + } + } + } + + return nullptr; +} + /** * A recursive function to double-check the result of is_derived_from(). This * is the slow, examine-the-whole-graph approach, as opposed to the clever and diff --git a/dtool/src/dtoolbase/typeRegistryNode.h b/dtool/src/dtoolbase/typeRegistryNode.h index dd888cbf59..7dd7f387cc 100644 --- a/dtool/src/dtoolbase/typeRegistryNode.h +++ b/dtool/src/dtoolbase/typeRegistryNode.h @@ -37,6 +37,8 @@ public: static TypeHandle get_parent_towards(const TypeRegistryNode *child, const TypeRegistryNode *base); + INLINE PyObject *get_python_type() const; + void clear_subtree(); void define_subtree(); @@ -46,6 +48,7 @@ public: typedef std::vector Classes; Classes _parent_classes; Classes _child_classes; + PyObject *_python_type = nullptr; AtomicAdjust::Integer _memory_usage[TypeHandle::MC_limit]; @@ -77,6 +80,8 @@ private: void r_build_subtrees(TypeRegistryNode *top, int bit_count, SubtreeMaskType bits); + PyObject *r_get_python_type() const; + static bool check_derived_from(const TypeRegistryNode *child, const TypeRegistryNode *base); diff --git a/dtool/src/interrogate/interfaceMakerPythonNative.cxx b/dtool/src/interrogate/interfaceMakerPythonNative.cxx index 8d2b0f2288..60d2dd6466 100644 --- a/dtool/src/interrogate/interfaceMakerPythonNative.cxx +++ b/dtool/src/interrogate/interfaceMakerPythonNative.cxx @@ -821,10 +821,54 @@ write_prototypes(ostream &out_code, ostream *out_h) { } } + out_code << "/**\n"; + out_code << " * Declarations for exported classes\n"; + out_code << " */\n"; + + out_code << "static const Dtool_TypeDef exports[] = {\n"; + + for (oi = _objects.begin(); oi != _objects.end(); ++oi) { + Object *object = (*oi).second; + + if (object->_itype.is_class() || object->_itype.is_struct()) { + CPPType *type = object->_itype._cpptype; + + if (isExportThisRun(type) && is_cpp_type_legal(type)) { + string class_name = type->get_local_name(&parser); + string safe_name = make_safe_name(class_name); + + out_code << " {\"" << class_name << "\", &Dtool_" << safe_name << "},\n"; + } + } + } + + out_code << " {nullptr, nullptr},\n"; + out_code << "};\n\n"; + out_code << "/**\n"; out_code << " * Extern declarations for imported classes\n"; out_code << " */\n"; + // Write out a table of the externally imported types that will be filled in + // upon module initialization. + if (!_external_imports.empty()) { + out_code << "#ifndef LINK_ALL_STATIC\n"; + out_code << "static Dtool_TypeDef imports[] = {\n"; + + int idx = 0; + for (CPPType *type : _external_imports) { + string class_name = type->get_local_name(&parser); + string safe_name = make_safe_name(class_name); + + out_code << " {\"" << class_name << "\", nullptr},\n"; + out_code << "#define Dtool_Ptr_" << safe_name << " (imports[" << idx << "].type)\n"; + ++idx; + } + out_code << " {nullptr, nullptr},\n"; + out_code << "};\n"; + out_code << "#endif\n\n"; + } + for (CPPType *type : _external_imports) { string class_name = type->get_local_name(&parser); string safe_name = make_safe_name(class_name); @@ -834,7 +878,9 @@ write_prototypes(ostream &out_code, ostream *out_h) { out_code << "#ifndef LINK_ALL_STATIC\n"; // out_code << "IMPORT_THIS struct Dtool_PyTypedObject Dtool_" << // safe_name << ";\n"; - out_code << "static struct Dtool_PyTypedObject *Dtool_Ptr_" << safe_name << ";\n"; + //if (has_get_class_type_function(type)) { + // out_code << "static struct Dtool_PyTypedObject *Dtool_Ptr_" << safe_name << ";\n"; + //} // out_code << "#define Dtool_Ptr_" << safe_name << " &Dtool_" << // safe_name << "\n"; out_code << "IMPORT_THIS void // Dtool_PyModuleClassInit_" << safe_name << "(PyObject *module);\n"; @@ -1258,36 +1304,36 @@ write_module_support(ostream &out, ostream *out_h, InterrogateModuleDef *def) { Objects::iterator oi; - out << "void Dtool_" << def->library_name << "_RegisterTypes() {\n"; + out << "void Dtool_" << def->library_name << "_RegisterTypes() {\n" + " TypeRegistry *registry = TypeRegistry::ptr();\n" + " nassertv(registry != nullptr);\n"; + for (oi = _objects.begin(); oi != _objects.end(); ++oi) { Object *object = (*oi).second; - if (object->_itype.is_class() || - object->_itype.is_struct()) { - if (is_cpp_type_legal(object->_itype._cpptype) && - isExportThisRun(object->_itype._cpptype)) { - string class_name = make_safe_name(object->_itype.get_scoped_name()); - bool is_typed = has_get_class_type_function(object->_itype._cpptype); + if (object->_itype.is_class() || object->_itype.is_struct()) { + CPPType *type = object->_itype._cpptype; + if (is_cpp_type_legal(type) && isExportThisRun(type)) { + string class_name = object->_itype.get_scoped_name(); + string safe_name = make_safe_name(class_name); + bool is_typed = has_get_class_type_function(type); if (is_typed) { - if (has_init_type_function(object->_itype._cpptype)) { + out << " {\n"; + if (has_init_type_function(type)) { // Call the init_type function. This isn't necessary for all // types as many of them are automatically initialized at static // init type, but for some extension classes it's useful. - out << " " << object->_itype._cpptype->get_local_name(&parser) + out << " " << type->get_local_name(&parser) << "::init_type();\n"; } - out << " Dtool_" << class_name << "._type = " - << object->_itype._cpptype->get_local_name(&parser) - << "::get_class_type();\n" - << " RegisterRuntimeTypedClass(Dtool_" << class_name << ");\n"; - + out << " TypeHandle handle = " << type->get_local_name(&parser) + << "::get_class_type();\n"; + out << " Dtool_" << safe_name << "._type = handle;\n"; + out << " registry->record_python_type(handle, " + "(PyObject *)&Dtool_" << safe_name << ");\n"; + out << " }\n"; } else { - out << "#ifndef LINK_ALL_STATIC\n" - << " RegisterNamedClass(\"" << object->_itype.get_scoped_name() - << "\", Dtool_" << class_name << ");\n" - << "#endif\n"; - - if (IsPandaTypedObject(object->_itype._cpptype->as_struct_type())) { + if (IsPandaTypedObject(type->as_struct_type())) { nout << object->_itype.get_scoped_name() << " derives from TypedObject, " << "but does not define a get_class_type() function.\n"; } @@ -1297,23 +1343,6 @@ write_module_support(ostream &out, ostream *out_h, InterrogateModuleDef *def) { } out << "}\n\n"; - out << "void Dtool_" << def->library_name << "_ResolveExternals() {\n"; - out << "#ifndef LINK_ALL_STATIC\n"; - out << " // Resolve externally imported types.\n"; - - for (CPPType *type : _external_imports) { - string class_name = type->get_local_name(&parser); - string safe_name = make_safe_name(class_name); - - if (has_get_class_type_function(type)) { - out << " Dtool_Ptr_" << safe_name << " = LookupRuntimeTypedClass(" << class_name << "::get_class_type());\n"; - } else { - out << " Dtool_Ptr_" << safe_name << " = LookupNamedClass(\"" << class_name << "\");\n"; - } - } - out << "#endif\n"; - out << "}\n\n"; - out << "void Dtool_" << def->library_name << "_BuildInstants(PyObject *module) {\n"; out << " (void) module;\n"; @@ -1466,9 +1495,14 @@ write_module_support(ostream &out, ostream *out_h, InterrogateModuleDef *def) { out << " {nullptr, nullptr, 0, nullptr}\n" << "};\n\n"; - out << "struct LibraryDef " << def->library_name << "_moddef = {python_simple_funcs};\n"; + out << "extern const struct LibraryDef " << def->library_name << "_moddef = {python_simple_funcs, exports, "; + if (_external_imports.empty()) { + out << "nullptr};\n"; + } else { + out << "imports};\n"; + } if (out_h != nullptr) { - *out_h << "extern struct LibraryDef " << def->library_name << "_moddef;\n"; + *out_h << "extern const struct LibraryDef " << def->library_name << "_moddef;\n"; } } diff --git a/dtool/src/interrogate/interrogate_module.cxx b/dtool/src/interrogate/interrogate_module.cxx index 5c5cc9d9ab..986033fd3c 100644 --- a/dtool/src/interrogate/interrogate_module.cxx +++ b/dtool/src/interrogate/interrogate_module.cxx @@ -286,9 +286,8 @@ int write_python_table_native(std::ostream &out) { vector_string::const_iterator ii; for (ii = libraries.begin(); ii != libraries.end(); ++ii) { printf("Referencing Library %s\n", (*ii).c_str()); - out << "extern LibraryDef " << *ii << "_moddef;\n"; + out << "extern const struct LibraryDef " << *ii << "_moddef;\n"; out << "extern void Dtool_" << *ii << "_RegisterTypes();\n"; - out << "extern void Dtool_" << *ii << "_ResolveExternals();\n"; out << "extern void Dtool_" << *ii << "_BuildInstants(PyObject *module);\n"; } @@ -339,12 +338,9 @@ int write_python_table_native(std::ostream &out) { for (ii = libraries.begin(); ii != libraries.end(); ii++) { out << " Dtool_" << *ii << "_RegisterTypes();\n"; } - for (ii = libraries.begin(); ii != libraries.end(); ii++) { - out << " Dtool_" << *ii << "_ResolveExternals();\n"; - } out << "\n"; - out << " LibraryDef *defs[] = {"; + out << " const LibraryDef *defs[] = {"; for(ii = libraries.begin(); ii != libraries.end(); ii++) { out << "&" << *ii << "_moddef, "; } @@ -386,12 +382,9 @@ int write_python_table_native(std::ostream &out) { for (ii = libraries.begin(); ii != libraries.end(); ii++) { out << " Dtool_" << *ii << "_RegisterTypes();\n"; } - for (ii = libraries.begin(); ii != libraries.end(); ii++) { - out << " Dtool_" << *ii << "_ResolveExternals();\n"; - } out << "\n"; - out << " LibraryDef *defs[] = {"; + out << " const LibraryDef *defs[] = {"; for(ii = libraries.begin(); ii != libraries.end(); ii++) { out << "&" << *ii << "_moddef, "; } diff --git a/dtool/src/interrogatedb/py_panda.I b/dtool/src/interrogatedb/py_panda.I index 69f8961463..f5f504ca97 100644 --- a/dtool/src/interrogatedb/py_panda.I +++ b/dtool/src/interrogatedb/py_panda.I @@ -26,7 +26,7 @@ template INLINE bool DtoolInstance_GetPointer(PyObject *self, T *&into) { if (DtoolInstance_Check(self)) { - Dtool_PyTypedObject *target_class = Dtool_RuntimeTypeDtoolType(get_type_handle(T).get_index()); + Dtool_PyTypedObject *target_class = (Dtool_PyTypedObject *)get_type_handle(T).get_python_type(); if (target_class != nullptr) { if (_IS_FINAL(T)) { if (DtoolInstance_TYPE(self) == target_class) { @@ -116,28 +116,28 @@ INLINE long Dtool_EnumValue_AsLong(PyObject *value) { */ template INLINE PyObject * DTool_CreatePyInstance(const T *obj, bool memory_rules) { - Dtool_PyTypedObject *known_class = Dtool_RuntimeTypeDtoolType(get_type_handle(T).get_index()); + Dtool_PyTypedObject *known_class = (Dtool_PyTypedObject *)get_type_handle(T).get_python_type(); nassertr(known_class != nullptr, nullptr); return DTool_CreatePyInstance((void*) obj, *known_class, memory_rules, true); } template INLINE PyObject * DTool_CreatePyInstance(T *obj, bool memory_rules) { - Dtool_PyTypedObject *known_class = Dtool_RuntimeTypeDtoolType(get_type_handle(T).get_index()); + Dtool_PyTypedObject *known_class = (Dtool_PyTypedObject *)get_type_handle(T).get_python_type(); nassertr(known_class != nullptr, nullptr); return DTool_CreatePyInstance((void*) obj, *known_class, memory_rules, false); } template INLINE PyObject * DTool_CreatePyInstanceTyped(const T *obj, bool memory_rules) { - Dtool_PyTypedObject *known_class = Dtool_RuntimeTypeDtoolType(get_type_handle(T).get_index()); + Dtool_PyTypedObject *known_class = (Dtool_PyTypedObject *)get_type_handle(T).get_python_type(); nassertr(known_class != nullptr, nullptr); return DTool_CreatePyInstanceTyped((void*) obj, *known_class, memory_rules, true, obj->get_type().get_index()); } template INLINE PyObject * DTool_CreatePyInstanceTyped(T *obj, bool memory_rules) { - Dtool_PyTypedObject *known_class = Dtool_RuntimeTypeDtoolType(get_type_handle(T).get_index()); + Dtool_PyTypedObject *known_class = (Dtool_PyTypedObject *)get_type_handle(T).get_python_type(); nassertr(known_class != nullptr, nullptr); return DTool_CreatePyInstanceTyped((void*) obj, *known_class, memory_rules, false, obj->get_type().get_index()); } diff --git a/dtool/src/interrogatedb/py_panda.cxx b/dtool/src/interrogatedb/py_panda.cxx index c29796def6..68264daf0b 100644 --- a/dtool/src/interrogatedb/py_panda.cxx +++ b/dtool/src/interrogatedb/py_panda.cxx @@ -29,10 +29,6 @@ PyMemberDef standard_type_members[] = { {nullptr} /* Sentinel */ }; -static RuntimeTypeMap runtime_type_map; -static RuntimeTypeSet runtime_type_set; -static NamedTypeMap named_type_map; - /** */ @@ -431,7 +427,7 @@ PyObject *DTool_CreatePyInstanceTyped(void *local_this_in, Dtool_PyTypedObject & // IF the class is possibly a run time typed object if (type_index > 0) { // get best fit class... - Dtool_PyTypedObject *target_class = Dtool_RuntimeTypeDtoolType(type_index); + Dtool_PyTypedObject *target_class = (Dtool_PyTypedObject *)TypeHandle::from_index(type_index).get_python_type(); if (target_class != nullptr) { // cast to the type... void *new_local_this = target_class->_Dtool_DowncastInterface(local_this_in, &known_class_type); @@ -507,109 +503,30 @@ void Dtool_Accum_MethDefs(PyMethodDef in[], MethodDefmap &themap) { } } -// ** HACK ** alert.. Need to keep a runtime type dictionary ... that is -// forward declared of typed object. We rely on the fact that typed objects -// are uniquly defined by an integer. -void -RegisterNamedClass(const string &name, Dtool_PyTypedObject &otype) { - std::pair result = - named_type_map.insert(NamedTypeMap::value_type(name, &otype)); - - if (!result.second) { - // There was already a class with this name in the dictionary. - interrogatedb_cat.warning() - << "Double definition for class " << name << "\n"; - } -} - -void -RegisterRuntimeTypedClass(Dtool_PyTypedObject &otype) { - int type_index = otype._type.get_index(); - - if (type_index == 0) { - interrogatedb_cat.warning() - << "Class " << otype._PyType.tp_name - << " has a zero TypeHandle value; check that init_type() is called.\n"; - - } else if (type_index < 0 || type_index >= TypeRegistry::ptr()->get_num_typehandles()) { - interrogatedb_cat.warning() - << "Class " << otype._PyType.tp_name - << " has an illegal TypeHandle value; check that init_type() is called.\n"; - +/** + * Returns a borrowed reference to the global type dictionary. + */ +Dtool_TypeMap *Dtool_GetGlobalTypeMap() { + PyObject *capsule = PySys_GetObject("_interrogate_types"); + if (capsule != nullptr) { + return (Dtool_TypeMap *)PyCapsule_GetPointer(capsule, nullptr); } else { - std::pair result = - runtime_type_map.insert(RuntimeTypeMap::value_type(type_index, &otype)); - if (!result.second) { - // There was already an entry in the dictionary for type_index. - Dtool_PyTypedObject *other_type = (*result.first).second; - interrogatedb_cat.warning() - << "Classes " << otype._PyType.tp_name - << " and " << other_type->_PyType.tp_name - << " share the same TypeHandle value (" << type_index - << "); check class definitions.\n"; - - } else { - runtime_type_set.insert(type_index); - } - } -} - -Dtool_PyTypedObject * -LookupNamedClass(const string &name) { - NamedTypeMap::const_iterator it; - it = named_type_map.find(name); - - if (it == named_type_map.end()) { - // Find a type named like this in the type registry. - TypeHandle handle = TypeRegistry::ptr()->find_type(name); - if (handle.get_index() > 0) { - RuntimeTypeMap::const_iterator it2; - it2 = runtime_type_map.find(handle.get_index()); - if (it2 != runtime_type_map.end()) { - return it2->second; - } - } - - interrogatedb_cat.error() - << "Attempt to use type " << name << " which has not yet been defined!\n"; - return nullptr; - } else { - return it->second; - } -} - -Dtool_PyTypedObject * -LookupRuntimeTypedClass(TypeHandle handle) { - RuntimeTypeMap::const_iterator it; - it = runtime_type_map.find(handle.get_index()); - - if (it == runtime_type_map.end()) { - interrogatedb_cat.error() - << "Attempt to use type " << handle << " which has not yet been defined!\n"; - return nullptr; - } else { - return it->second; + Dtool_TypeMap *type_map = new Dtool_TypeMap; + capsule = PyCapsule_New((void *)type_map, nullptr, nullptr); + PySys_SetObject("_interrogate_types", capsule); + Py_DECREF(capsule); + return type_map; } } Dtool_PyTypedObject *Dtool_RuntimeTypeDtoolType(int type) { - RuntimeTypeMap::iterator di = runtime_type_map.find(type); - if (di != runtime_type_map.end()) { - return di->second; - } else { - int type2 = get_best_parent_from_Set(type, runtime_type_set); - di = runtime_type_map.find(type2); - if (di != runtime_type_map.end()) { - return di->second; - } - } - return nullptr; + return (Dtool_PyTypedObject *)TypeHandle::from_index(type).get_python_type(); } #if PY_MAJOR_VERSION >= 3 -PyObject *Dtool_PyModuleInitHelper(LibraryDef *defs[], PyModuleDef *module_def) { +PyObject *Dtool_PyModuleInitHelper(const LibraryDef *defs[], PyModuleDef *module_def) { #else -PyObject *Dtool_PyModuleInitHelper(LibraryDef *defs[], const char *modulename) { +PyObject *Dtool_PyModuleInitHelper(const LibraryDef *defs[], const char *modulename) { #endif // Check the version so we can print a helpful error if it doesn't match. string version = Py_GetVersion(); @@ -672,10 +589,40 @@ PyObject *Dtool_PyModuleInitHelper(LibraryDef *defs[], const char *modulename) { Dtool_PyModuleClassInit_DTOOL_SUPER_BASE(nullptr); } + Dtool_TypeMap *type_map = Dtool_GetGlobalTypeMap(); + // the module level function inits.... MethodDefmap functions; - for (int xx = 0; defs[xx] != nullptr; xx++) { - Dtool_Accum_MethDefs(defs[xx]->_methods, functions); + for (size_t i = 0; defs[i] != nullptr; i++) { + const LibraryDef &def = *defs[i]; + Dtool_Accum_MethDefs(def._methods, functions); + + // Define exported types. + const Dtool_TypeDef *types = def._types; + if (types != nullptr) { + while (types->name != nullptr) { + (*type_map)[std::string(types->name)] = types->type; + ++types; + } + } + } + + // Resolve external types, in a second pass. + for (size_t i = 0; defs[i] != nullptr; i++) { + const LibraryDef &def = *defs[i]; + + Dtool_TypeDef *types = def._external_types; + if (types != nullptr) { + while (types->name != nullptr) { + auto it = type_map->find(std::string(types->name)); + if (it != type_map->end()) { + types->type = it->second; + } else { + return PyErr_Format(PyExc_NameError, "name '%s' is not defined", types->name); + } + ++types; + } + } } PyMethodDef *newdef = new PyMethodDef[functions.size() + 1]; diff --git a/dtool/src/interrogatedb/py_panda.h b/dtool/src/interrogatedb/py_panda.h index 7916147e4d..f850f0c859 100644 --- a/dtool/src/interrogatedb/py_panda.h +++ b/dtool/src/interrogatedb/py_panda.h @@ -190,11 +190,9 @@ static void Dtool_FreeInstance_##CLASS_NAME(PyObject *self) {\ // forward declared of typed object. We rely on the fact that typed objects // are uniquly defined by an integer. -EXPCL_INTERROGATEDB void RegisterNamedClass(const std::string &name, Dtool_PyTypedObject &otype); -EXPCL_INTERROGATEDB void RegisterRuntimeTypedClass(Dtool_PyTypedObject &otype); +typedef std::map Dtool_TypeMap; -EXPCL_INTERROGATEDB Dtool_PyTypedObject *LookupNamedClass(const std::string &name); -EXPCL_INTERROGATEDB Dtool_PyTypedObject *LookupRuntimeTypedClass(TypeHandle handle); +EXPCL_INTERROGATEDB Dtool_TypeMap *Dtool_GetGlobalTypeMap(); EXPCL_INTERROGATEDB Dtool_PyTypedObject *Dtool_RuntimeTypeDtoolType(int type); @@ -326,14 +324,22 @@ EXPCL_INTERROGATEDB void Dtool_Accum_MethDefs(PyMethodDef in[], MethodDefmap &th // We need a way to runtime merge compile units into a python "Module" .. this // is done with the fallowing structors and code.. along with the support of // interigate_module + +struct Dtool_TypeDef { + const char *const name; + Dtool_PyTypedObject *type; +}; + struct LibraryDef { - PyMethodDef *_methods; + PyMethodDef *const _methods; + const Dtool_TypeDef *const _types; + Dtool_TypeDef *const _external_types; }; #if PY_MAJOR_VERSION >= 3 -EXPCL_INTERROGATEDB PyObject *Dtool_PyModuleInitHelper(LibraryDef *defs[], PyModuleDef *module_def); +EXPCL_INTERROGATEDB PyObject *Dtool_PyModuleInitHelper(const LibraryDef *defs[], PyModuleDef *module_def); #else -EXPCL_INTERROGATEDB PyObject *Dtool_PyModuleInitHelper(LibraryDef *defs[], const char *modulename); +EXPCL_INTERROGATEDB PyObject *Dtool_PyModuleInitHelper(const LibraryDef *defs[], const char *modulename); #endif // HACK.... Be carefull Dtool_BorrowThisReference This function can be used to From 49b72fb1985a40515eab9a1783d2a9d1bb7d8a47 Mon Sep 17 00:00:00 2001 From: rdb Date: Tue, 6 Nov 2018 14:22:08 +0100 Subject: [PATCH 19/26] Move Python support code from libp3interrogatedb to generated module This prevents libp3interrogatedb from having a dependency on the Python library. See #387 --- dtool/src/dtoolbase/typeHandle_ext.cxx | 3 +- .../interfaceMakerPythonNative.cxx | 2 +- dtool/src/interrogate/interrogate_module.cxx | 7 +- dtool/src/interrogatedb/dtool_super_base.cxx | 194 +-- .../p3interrogatedb_composite1.cxx | 1 - .../p3interrogatedb_composite2.cxx | 3 - dtool/src/interrogatedb/py_compat.cxx | 7 - dtool/src/interrogatedb/py_compat.h | 9 +- dtool/src/interrogatedb/py_panda.I | 19 +- dtool/src/interrogatedb/py_panda.cxx | 93 +- dtool/src/interrogatedb/py_panda.h | 81 +- dtool/src/interrogatedb/py_wrappers.cxx | 1439 +++++++++-------- dtool/src/interrogatedb/py_wrappers.h | 29 +- makepanda/makepanda.py | 11 +- makepanda/makepandacore.py | 42 + panda/src/event/asyncFuture_ext.cxx | 9 +- 16 files changed, 977 insertions(+), 972 deletions(-) diff --git a/dtool/src/dtoolbase/typeHandle_ext.cxx b/dtool/src/dtoolbase/typeHandle_ext.cxx index 2064e42844..c52b04aabd 100644 --- a/dtool/src/dtoolbase/typeHandle_ext.cxx +++ b/dtool/src/dtoolbase/typeHandle_ext.cxx @@ -22,7 +22,8 @@ */ TypeHandle Extension:: make(PyTypeObject *tp) { - if (!PyType_IsSubtype(tp, &Dtool_DTOOL_SUPER_BASE._PyType)) { + Dtool_PyTypedObject *super_base = Dtool_GetSuperBase(); + if (!PyType_IsSubtype(tp, (PyTypeObject *)super_base)) { PyErr_SetString(PyExc_TypeError, "a Panda type is required"); return TypeHandle::none(); } diff --git a/dtool/src/interrogate/interfaceMakerPythonNative.cxx b/dtool/src/interrogate/interfaceMakerPythonNative.cxx index 60d2dd6466..c0316ee5c4 100644 --- a/dtool/src/interrogate/interfaceMakerPythonNative.cxx +++ b/dtool/src/interrogate/interfaceMakerPythonNative.cxx @@ -3097,7 +3097,7 @@ write_module_class(ostream &out, Object *obj) { out << " Dtool_" << ClassName << "._PyType.tp_bases = PyTuple_Pack(" << bases.size() << baseargs << ");\n"; } else { - out << " Dtool_" << ClassName << "._PyType.tp_base = (PyTypeObject *)&Dtool_DTOOL_SUPER_BASE;\n"; + out << " Dtool_" << ClassName << "._PyType.tp_base = (PyTypeObject *)Dtool_GetSuperBase();\n"; } int num_nested = obj->_itype.number_of_nested_types(); diff --git a/dtool/src/interrogate/interrogate_module.cxx b/dtool/src/interrogate/interrogate_module.cxx index 986033fd3c..586889ed77 100644 --- a/dtool/src/interrogate/interrogate_module.cxx +++ b/dtool/src/interrogate/interrogate_module.cxx @@ -30,6 +30,9 @@ using std::cerr; using std::string; +// This contains a big source string determined at compile time. +extern const char interrogate_preamble_python_native[]; + Filename output_code_filename; string module_name; string library_name; @@ -635,8 +638,10 @@ int main(int argc, char *argv[]) { if (build_python_native_wrappers) { write_python_table_native(output_code); - } + // Output the support code. + output_code << interrogate_preamble_python_native << "\n"; + } } } diff --git a/dtool/src/interrogatedb/dtool_super_base.cxx b/dtool/src/interrogatedb/dtool_super_base.cxx index 9170af9d4f..01dcdef077 100644 --- a/dtool/src/interrogatedb/dtool_super_base.cxx +++ b/dtool/src/interrogatedb/dtool_super_base.cxx @@ -15,120 +15,132 @@ #ifdef HAVE_PYTHON -class EmptyClass { -}; -Define_Module_Class_Private(dtoolconfig, DTOOL_SUPER_BASE, EmptyClass, DTOOL_SUPER_BASE111); - static PyObject *GetSuperBase(PyObject *self) { - Py_INCREF((PyTypeObject *)&Dtool_DTOOL_SUPER_BASE); // order is important .. this is used for static functions - return (PyObject *) &Dtool_DTOOL_SUPER_BASE; + Dtool_PyTypedObject *super_base = Dtool_GetSuperBase(); + Py_XINCREF((PyTypeObject *)super_base); // order is important .. this is used for static functions + return (PyObject *)super_base; }; -PyMethodDef Dtool_Methods_DTOOL_SUPER_BASE[] = { - { "DtoolGetSuperBase", (PyCFunction) &GetSuperBase, METH_NOARGS, "Will Return SUPERbase Class"}, - { nullptr, nullptr, 0, nullptr } -}; - -EXPCL_INTERROGATEDB void Dtool_PyModuleClassInit_DTOOL_SUPER_BASE(PyObject *module) { - static bool initdone = false; - if (!initdone) { - - initdone = true; - Dtool_DTOOL_SUPER_BASE._PyType.tp_dict = PyDict_New(); - PyDict_SetItemString(Dtool_DTOOL_SUPER_BASE._PyType.tp_dict, "DtoolClassDict", Dtool_DTOOL_SUPER_BASE._PyType.tp_dict); - - if (PyType_Ready((PyTypeObject *)&Dtool_DTOOL_SUPER_BASE) < 0) { - PyErr_SetString(PyExc_TypeError, "PyType_Ready(Dtool_DTOOL_SUPER_BASE)"); - return; - } - Py_INCREF((PyTypeObject *)&Dtool_DTOOL_SUPER_BASE); - - PyDict_SetItemString(Dtool_DTOOL_SUPER_BASE._PyType.tp_dict, "DtoolGetSuperBase", PyCFunction_New(&Dtool_Methods_DTOOL_SUPER_BASE[0], (PyObject *)&Dtool_DTOOL_SUPER_BASE)); - } - +static void Dtool_PyModuleClassInit_DTOOL_SUPER_BASE(PyObject *module) { if (module != nullptr) { - Py_INCREF((PyTypeObject *)&Dtool_DTOOL_SUPER_BASE); - PyModule_AddObject(module, "DTOOL_SUPER_BASE", (PyObject *)&Dtool_DTOOL_SUPER_BASE); + Dtool_PyTypedObject *super_base = Dtool_GetSuperBase(); + Py_INCREF((PyTypeObject *)&super_base); + PyModule_AddObject(module, "DTOOL_SUPER_BASE", (PyObject *)&super_base); } } -inline void *Dtool_DowncastInterface_DTOOL_SUPER_BASE(void *from_this, Dtool_PyTypedObject *from_type) { +static void *Dtool_DowncastInterface_DTOOL_SUPER_BASE(void *from_this, Dtool_PyTypedObject *from_type) { return nullptr; } -inline void *Dtool_UpcastInterface_DTOOL_SUPER_BASE(PyObject *self, Dtool_PyTypedObject *requested_type) { +static void *Dtool_UpcastInterface_DTOOL_SUPER_BASE(PyObject *self, Dtool_PyTypedObject *requested_type) { return nullptr; } -int Dtool_Init_DTOOL_SUPER_BASE(PyObject *self, PyObject *args, PyObject *kwds) { +static int Dtool_Init_DTOOL_SUPER_BASE(PyObject *self, PyObject *args, PyObject *kwds) { assert(self != nullptr); PyErr_Format(PyExc_TypeError, "cannot init constant class %s", Py_TYPE(self)->tp_name); return -1; } -EXPORT_THIS Dtool_PyTypedObject Dtool_DTOOL_SUPER_BASE = { - { - PyVarObject_HEAD_INIT(nullptr, 0) - "dtoolconfig.DTOOL_SUPER_BASE", - sizeof(Dtool_PyInstDef), - 0, // tp_itemsize - &Dtool_FreeInstance_DTOOL_SUPER_BASE, - nullptr, // tp_print - nullptr, // tp_getattr - nullptr, // tp_setattr +static void Dtool_FreeInstance_DTOOL_SUPER_BASE(PyObject *self) { + Py_TYPE(self)->tp_free(self); +} + +/** + * Returns a pointer to the DTOOL_SUPER_BASE class that is the base class of + * all Panda types. This pointer is shared by all modules. + */ +Dtool_PyTypedObject *Dtool_GetSuperBase() { + Dtool_TypeMap *type_map = Dtool_GetGlobalTypeMap(); + auto it = type_map->find("DTOOL_SUPER_BASE"); + if (it != type_map->end()) { + return it->second; + } + + static PyMethodDef methods[] = { + { "DtoolGetSuperBase", (PyCFunction)&GetSuperBase, METH_NOARGS, "Will Return SUPERbase Class"}, + { nullptr, nullptr, 0, nullptr } + }; + + static Dtool_PyTypedObject super_base_type = { + { + PyVarObject_HEAD_INIT(nullptr, 0) + "dtoolconfig.DTOOL_SUPER_BASE", + sizeof(Dtool_PyInstDef), + 0, // tp_itemsize + &Dtool_FreeInstance_DTOOL_SUPER_BASE, + nullptr, // tp_print + nullptr, // tp_getattr + nullptr, // tp_setattr #if PY_MAJOR_VERSION >= 3 - nullptr, // tp_compare + nullptr, // tp_compare #else - &DtoolInstance_ComparePointers, + &DtoolInstance_ComparePointers, #endif - nullptr, // tp_repr - nullptr, // tp_as_number - nullptr, // tp_as_sequence - nullptr, // tp_as_mapping - &DtoolInstance_HashPointer, - nullptr, // tp_call - nullptr, // tp_str - PyObject_GenericGetAttr, - PyObject_GenericSetAttr, - nullptr, // tp_as_buffer - (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_CHECKTYPES), - nullptr, // tp_doc - nullptr, // tp_traverse - nullptr, // tp_clear + nullptr, // tp_repr + nullptr, // tp_as_number + nullptr, // tp_as_sequence + nullptr, // tp_as_mapping + &DtoolInstance_HashPointer, + nullptr, // tp_call + nullptr, // tp_str + PyObject_GenericGetAttr, + PyObject_GenericSetAttr, + nullptr, // tp_as_buffer + (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_CHECKTYPES), + nullptr, // tp_doc + nullptr, // tp_traverse + nullptr, // tp_clear #if PY_MAJOR_VERSION >= 3 - &DtoolInstance_RichComparePointers, + &DtoolInstance_RichComparePointers, #else - nullptr, // tp_richcompare + nullptr, // tp_richcompare #endif - 0, // tp_weaklistoffset - nullptr, // tp_iter - nullptr, // tp_iternext - Dtool_Methods_DTOOL_SUPER_BASE, - standard_type_members, - nullptr, // tp_getset - nullptr, // tp_base - nullptr, // tp_dict - nullptr, // tp_descr_get - nullptr, // tp_descr_set - 0, // tp_dictoffset - Dtool_Init_DTOOL_SUPER_BASE, - PyType_GenericAlloc, - Dtool_new_DTOOL_SUPER_BASE, - PyObject_Del, - nullptr, // tp_is_gc - nullptr, // tp_bases - nullptr, // tp_mro - nullptr, // tp_cache - nullptr, // tp_subclasses - nullptr, // tp_weaklist - nullptr, // tp_del - }, - TypeHandle::none(), - Dtool_PyModuleClassInit_DTOOL_SUPER_BASE, - Dtool_UpcastInterface_DTOOL_SUPER_BASE, - Dtool_DowncastInterface_DTOOL_SUPER_BASE, - nullptr, - nullptr, -}; + 0, // tp_weaklistoffset + nullptr, // tp_iter + nullptr, // tp_iternext + methods, + standard_type_members, + nullptr, // tp_getset + nullptr, // tp_base + nullptr, // tp_dict + nullptr, // tp_descr_get + nullptr, // tp_descr_set + 0, // tp_dictoffset + Dtool_Init_DTOOL_SUPER_BASE, + PyType_GenericAlloc, + nullptr, // tp_new + PyObject_Del, + nullptr, // tp_is_gc + nullptr, // tp_bases + nullptr, // tp_mro + nullptr, // tp_cache + nullptr, // tp_subclasses + nullptr, // tp_weaklist + nullptr, // tp_del + }, + TypeHandle::none(), + Dtool_PyModuleClassInit_DTOOL_SUPER_BASE, + Dtool_UpcastInterface_DTOOL_SUPER_BASE, + Dtool_DowncastInterface_DTOOL_SUPER_BASE, + nullptr, + nullptr, + }; + + super_base_type._PyType.tp_dict = PyDict_New(); + PyDict_SetItemString(super_base_type._PyType.tp_dict, "DtoolClassDict", super_base_type._PyType.tp_dict); + + if (PyType_Ready((PyTypeObject *)&super_base_type) < 0) { + PyErr_SetString(PyExc_TypeError, "PyType_Ready(Dtool_DTOOL_SUPER_BASE)"); + return nullptr; + } + Py_INCREF((PyTypeObject *)&super_base_type); + + PyDict_SetItemString(super_base_type._PyType.tp_dict, "DtoolGetSuperBase", PyCFunction_New(&methods[0], (PyObject *)&super_base_type)); + + (*type_map)["DTOOL_SUPER_BASE"] = &super_base_type; + return &super_base_type; +} #endif // HAVE_PYTHON diff --git a/dtool/src/interrogatedb/p3interrogatedb_composite1.cxx b/dtool/src/interrogatedb/p3interrogatedb_composite1.cxx index d663e9e0e5..4e54cee5a9 100644 --- a/dtool/src/interrogatedb/p3interrogatedb_composite1.cxx +++ b/dtool/src/interrogatedb/p3interrogatedb_composite1.cxx @@ -1,5 +1,4 @@ #include "config_interrogatedb.cxx" -#include "dtool_super_base.cxx" #include "indexRemapper.cxx" #include "interrogateComponent.cxx" #include "interrogateDatabase.cxx" diff --git a/dtool/src/interrogatedb/p3interrogatedb_composite2.cxx b/dtool/src/interrogatedb/p3interrogatedb_composite2.cxx index fda72f2ce8..41453e5f3e 100644 --- a/dtool/src/interrogatedb/p3interrogatedb_composite2.cxx +++ b/dtool/src/interrogatedb/p3interrogatedb_composite2.cxx @@ -4,6 +4,3 @@ #include "interrogate_datafile.cxx" #include "interrogate_interface.cxx" #include "interrogate_request.cxx" -#include "py_panda.cxx" -#include "py_compat.cxx" -#include "py_wrappers.cxx" diff --git a/dtool/src/interrogatedb/py_compat.cxx b/dtool/src/interrogatedb/py_compat.cxx index 0c1383f983..722bc8300b 100644 --- a/dtool/src/interrogatedb/py_compat.cxx +++ b/dtool/src/interrogatedb/py_compat.cxx @@ -1,11 +1,4 @@ /** - * PANDA 3D SOFTWARE - * Copyright (c) Carnegie Mellon University. All rights reserved. - * - * All use of this software is subject to the terms of the revised BSD - * license. You should have received a copy of this license along - * with this source code in a file named "LICENSE." - * * @file py_compat.cxx * @author rdb * @date 2017-12-03 diff --git a/dtool/src/interrogatedb/py_compat.h b/dtool/src/interrogatedb/py_compat.h index f87c73cf3d..fbe49a5287 100644 --- a/dtool/src/interrogatedb/py_compat.h +++ b/dtool/src/interrogatedb/py_compat.h @@ -1,11 +1,4 @@ /** - * PANDA 3D SOFTWARE - * Copyright (c) Carnegie Mellon University. All rights reserved. - * - * All use of this software is subject to the terms of the revised BSD - * license. You should have received a copy of this license along - * with this source code in a file named "LICENSE." - * * @file py_compat.h * @author rdb * @date 2017-12-02 @@ -106,7 +99,7 @@ typedef int Py_ssize_t; // PyInt_FromSize_t automatically picks the right type. # define PyLongOrInt_AS_LONG PyInt_AsLong -EXPCL_INTERROGATEDB size_t PyLongOrInt_AsSize_t(PyObject *); +size_t PyLongOrInt_AsSize_t(PyObject *); #endif // Which character to use in PyArg_ParseTuple et al for a byte string. diff --git a/dtool/src/interrogatedb/py_panda.I b/dtool/src/interrogatedb/py_panda.I index f5f504ca97..12f20f1f1e 100644 --- a/dtool/src/interrogatedb/py_panda.I +++ b/dtool/src/interrogatedb/py_panda.I @@ -1,11 +1,4 @@ /** - * PANDA 3D SOFTWARE - * Copyright (c) Carnegie Mellon University. All rights reserved. - * - * All use of this software is subject to the terms of the revised BSD - * license. You should have received a copy of this license along - * with this source code in a file named "LICENSE." - * * @file py_panda.I * @author rdb * @date 2016-06-06 @@ -142,6 +135,18 @@ DTool_CreatePyInstanceTyped(T *obj, bool memory_rules) { return DTool_CreatePyInstanceTyped((void*) obj, *known_class, memory_rules, false, obj->get_type().get_index()); } +/** + * Finishes initializing the Dtool_PyInstDef. + */ +INLINE int +DTool_PyInit_Finalize(PyObject *self, void *local_this, Dtool_PyTypedObject *type, bool memory_rules, bool is_const) { + ((Dtool_PyInstDef *)self)->_My_Type = type; + ((Dtool_PyInstDef *)self)->_ptr_to_object = local_this; + ((Dtool_PyInstDef *)self)->_memory_rules = memory_rules; + ((Dtool_PyInstDef *)self)->_is_const = is_const; + return 0; +} + /** * Checks that the tuple is empty. */ diff --git a/dtool/src/interrogatedb/py_panda.cxx b/dtool/src/interrogatedb/py_panda.cxx index 68264daf0b..bb7b5717f4 100644 --- a/dtool/src/interrogatedb/py_panda.cxx +++ b/dtool/src/interrogatedb/py_panda.cxx @@ -1,11 +1,4 @@ /** - * PANDA 3D SOFTWARE - * Copyright (c) Carnegie Mellon University. All rights reserved. - * - * All use of this software is subject to the terms of the revised BSD - * license. You should have received a copy of this license along - * with this source code in a file named "LICENSE." - * * @file py_panda.cxx * @author drose * @date 2005-07-04 @@ -480,49 +473,22 @@ PyObject *DTool_CreatePyInstance(void *local_this, Dtool_PyTypedObject &in_class return (PyObject *)self; } -// Th Finalizer for simple instances.. -int DTool_PyInit_Finalize(PyObject *self, void *local_this, Dtool_PyTypedObject *type, bool memory_rules, bool is_const) { - // lets put some code in here that checks to see the memory is properly - // configured.. prior to my call .. - - ((Dtool_PyInstDef *)self)->_My_Type = type; - ((Dtool_PyInstDef *)self)->_ptr_to_object = local_this; - ((Dtool_PyInstDef *)self)->_memory_rules = memory_rules; - ((Dtool_PyInstDef *)self)->_is_const = is_const; - return 0; -} - -// A helper function to glue method definition together .. that can not be -// done at code generation time because of multiple generation passes in -// interrogate.. -void Dtool_Accum_MethDefs(PyMethodDef in[], MethodDefmap &themap) { - for (; in->ml_name != nullptr; in++) { - if (themap.find(in->ml_name) == themap.end()) { - themap[in->ml_name] = in; - } - } -} - /** * Returns a borrowed reference to the global type dictionary. */ Dtool_TypeMap *Dtool_GetGlobalTypeMap() { - PyObject *capsule = PySys_GetObject("_interrogate_types"); + PyObject *capsule = PySys_GetObject((char *)"_interrogate_types"); if (capsule != nullptr) { return (Dtool_TypeMap *)PyCapsule_GetPointer(capsule, nullptr); } else { Dtool_TypeMap *type_map = new Dtool_TypeMap; capsule = PyCapsule_New((void *)type_map, nullptr, nullptr); - PySys_SetObject("_interrogate_types", capsule); + PySys_SetObject((char *)"_interrogate_types", capsule); Py_DECREF(capsule); return type_map; } } -Dtool_PyTypedObject *Dtool_RuntimeTypeDtoolType(int type) { - return (Dtool_PyTypedObject *)TypeHandle::from_index(type).get_python_type(); -} - #if PY_MAJOR_VERSION >= 3 PyObject *Dtool_PyModuleInitHelper(const LibraryDef *defs[], PyModuleDef *module_def) { #else @@ -544,58 +510,19 @@ PyObject *Dtool_PyModuleInitHelper(const LibraryDef *defs[], const char *modulen return nullptr; } - // Initialize the types we define in py_panda. - static bool dtool_inited = false; - if (!dtool_inited) { - dtool_inited = true; - - if (PyType_Ready(&Dtool_SequenceWrapper_Type) < 0) { - return Dtool_Raise_TypeError("PyType_Ready(Dtool_SequenceWrapper)"); - } - - if (PyType_Ready(&Dtool_MutableSequenceWrapper_Type) < 0) { - return Dtool_Raise_TypeError("PyType_Ready(Dtool_MutableSequenceWrapper)"); - } - - if (PyType_Ready(&Dtool_MappingWrapper_Type) < 0) { - return Dtool_Raise_TypeError("PyType_Ready(Dtool_MappingWrapper)"); - } - - if (PyType_Ready(&Dtool_MutableMappingWrapper_Type) < 0) { - return Dtool_Raise_TypeError("PyType_Ready(Dtool_MutableMappingWrapper)"); - } - - if (PyType_Ready(&Dtool_MappingWrapper_Keys_Type) < 0) { - return Dtool_Raise_TypeError("PyType_Ready(Dtool_MappingWrapper_Keys)"); - } - - if (PyType_Ready(&Dtool_MappingWrapper_Values_Type) < 0) { - return Dtool_Raise_TypeError("PyType_Ready(Dtool_MappingWrapper_Values)"); - } - - if (PyType_Ready(&Dtool_MappingWrapper_Items_Type) < 0) { - return Dtool_Raise_TypeError("PyType_Ready(Dtool_MappingWrapper_Items)"); - } - - if (PyType_Ready(&Dtool_GeneratorWrapper_Type) < 0) { - return Dtool_Raise_TypeError("PyType_Ready(Dtool_GeneratorWrapper)"); - } - - if (PyType_Ready(&Dtool_StaticProperty_Type) < 0) { - return Dtool_Raise_TypeError("PyType_Ready(Dtool_StaticProperty_Type)"); - } - - // Initialize the base class of everything. - Dtool_PyModuleClassInit_DTOOL_SUPER_BASE(nullptr); - } - Dtool_TypeMap *type_map = Dtool_GetGlobalTypeMap(); // the module level function inits.... MethodDefmap functions; for (size_t i = 0; defs[i] != nullptr; i++) { const LibraryDef &def = *defs[i]; - Dtool_Accum_MethDefs(def._methods, functions); + + // Accumulate method definitions. + for (PyMethodDef *meth = def._methods; meth->ml_name != nullptr; meth++) { + if (functions.find(meth->ml_name) == functions.end()) { + functions[meth->ml_name] = meth; + } + } // Define exported types. const Dtool_TypeDef *types = def._types; @@ -746,7 +673,7 @@ PyObject *Dtool_BorrowThisReference(PyObject *self, PyObject *args) { // We do expose a dictionay for dtool classes .. this should be removed at // some point.. -EXPCL_INTERROGATEDB PyObject *Dtool_AddToDictionary(PyObject *self1, PyObject *args) { +PyObject *Dtool_AddToDictionary(PyObject *self1, PyObject *args) { PyObject *self; PyObject *subject; PyObject *key; diff --git a/dtool/src/interrogatedb/py_panda.h b/dtool/src/interrogatedb/py_panda.h index f850f0c859..34693e8b90 100644 --- a/dtool/src/interrogatedb/py_panda.h +++ b/dtool/src/interrogatedb/py_panda.h @@ -1,11 +1,4 @@ /** - * PANDA 3D SOFTWARE - * Copyright (c) Carnegie Mellon University. All rights reserved. - * - * All use of this software is subject to the terms of the revised BSD - * license. You should have received a copy of this license along - * with this source code in a file named "LICENSE." - * * @file py_panda.h */ @@ -43,9 +36,6 @@ using namespace std; #endif struct Dtool_PyTypedObject; -typedef std::map RuntimeTypeMap; -typedef std::set RuntimeTypeSet; -typedef std::map NamedTypeMap; // used to stamp dtool instance.. #define PY_PANDA_SIGNATURE 0xbeaf @@ -78,7 +68,7 @@ struct Dtool_PyInstDef { }; // A Offset Dictionary Defining How to read the Above Object.. -extern EXPCL_INTERROGATEDB PyMemberDef standard_type_members[]; +extern PyMemberDef standard_type_members[]; // The Class Definition Structor For a Dtool python type. struct Dtool_PyTypedObject { @@ -192,21 +182,19 @@ static void Dtool_FreeInstance_##CLASS_NAME(PyObject *self) {\ typedef std::map Dtool_TypeMap; -EXPCL_INTERROGATEDB Dtool_TypeMap *Dtool_GetGlobalTypeMap(); - -EXPCL_INTERROGATEDB Dtool_PyTypedObject *Dtool_RuntimeTypeDtoolType(int type); +Dtool_TypeMap *Dtool_GetGlobalTypeMap(); /** */ -EXPCL_INTERROGATEDB void DTOOL_Call_ExtractThisPointerForType(PyObject *self, Dtool_PyTypedObject *classdef, void **answer); +void DTOOL_Call_ExtractThisPointerForType(PyObject *self, Dtool_PyTypedObject *classdef, void **answer); -EXPCL_INTERROGATEDB void *DTOOL_Call_GetPointerThisClass(PyObject *self, Dtool_PyTypedObject *classdef, int param, const std::string &function_name, bool const_ok, bool report_errors); +void *DTOOL_Call_GetPointerThisClass(PyObject *self, Dtool_PyTypedObject *classdef, int param, const std::string &function_name, bool const_ok, bool report_errors); -EXPCL_INTERROGATEDB bool Dtool_Call_ExtractThisPointer(PyObject *self, Dtool_PyTypedObject &classdef, void **answer); +bool Dtool_Call_ExtractThisPointer(PyObject *self, Dtool_PyTypedObject &classdef, void **answer); -EXPCL_INTERROGATEDB bool Dtool_Call_ExtractThisPointer_NonConst(PyObject *self, Dtool_PyTypedObject &classdef, - void **answer, const char *method_name); +bool Dtool_Call_ExtractThisPointer_NonConst(PyObject *self, Dtool_PyTypedObject &classdef, + void **answer, const char *method_name); template INLINE bool DtoolInstance_GetPointer(PyObject *self, T *&into); template INLINE bool DtoolInstance_GetPointer(PyObject *self, T *&into, Dtool_PyTypedObject &classdef); @@ -216,7 +204,7 @@ INLINE int DtoolInstance_ComparePointers(PyObject *v1, PyObject *v2); INLINE PyObject *DtoolInstance_RichComparePointers(PyObject *v1, PyObject *v2, int op); // Functions related to error reporting. -EXPCL_INTERROGATEDB bool _Dtool_CheckErrorOccurred(); +bool _Dtool_CheckErrorOccurred(); #ifdef NDEBUG #define Dtool_CheckErrorOccurred() (UNLIKELY(_PyErr_OCCURRED() != nullptr)) @@ -224,12 +212,12 @@ EXPCL_INTERROGATEDB bool _Dtool_CheckErrorOccurred(); #define Dtool_CheckErrorOccurred() (UNLIKELY(_Dtool_CheckErrorOccurred())) #endif -EXPCL_INTERROGATEDB PyObject *Dtool_Raise_AssertionError(); -EXPCL_INTERROGATEDB PyObject *Dtool_Raise_TypeError(const char *message); -EXPCL_INTERROGATEDB PyObject *Dtool_Raise_ArgTypeError(PyObject *obj, int param, const char *function_name, const char *type_name); -EXPCL_INTERROGATEDB PyObject *Dtool_Raise_AttributeError(PyObject *obj, const char *attribute); +PyObject *Dtool_Raise_AssertionError(); +PyObject *Dtool_Raise_TypeError(const char *message); +PyObject *Dtool_Raise_ArgTypeError(PyObject *obj, int param, const char *function_name, const char *type_name); +PyObject *Dtool_Raise_AttributeError(PyObject *obj, const char *attribute); -EXPCL_INTERROGATEDB PyObject *_Dtool_Raise_BadArgumentsError(); +PyObject *_Dtool_Raise_BadArgumentsError(); #ifdef NDEBUG // Define it to a function that just prints a generic message. #define Dtool_Raise_BadArgumentsError(x) _Dtool_Raise_BadArgumentsError() @@ -241,9 +229,9 @@ EXPCL_INTERROGATEDB PyObject *_Dtool_Raise_BadArgumentsError(); // These functions are similar to Dtool_WrapValue, except that they also // contain code for checking assertions and exceptions when compiling with // NDEBUG mode on. -EXPCL_INTERROGATEDB PyObject *_Dtool_Return_None(); -EXPCL_INTERROGATEDB PyObject *Dtool_Return_Bool(bool value); -EXPCL_INTERROGATEDB PyObject *_Dtool_Return(PyObject *value); +PyObject *_Dtool_Return_None(); +PyObject *Dtool_Return_Bool(bool value); +PyObject *_Dtool_Return(PyObject *value); #ifdef NDEBUG #define Dtool_Return_None() (LIKELY(_PyErr_OCCURRED() == nullptr) ? (Py_INCREF(Py_None), Py_None) : nullptr) @@ -256,19 +244,19 @@ EXPCL_INTERROGATEDB PyObject *_Dtool_Return(PyObject *value); /** * Wrapper around Python 3.4's enum library, which does not have a C API. */ -EXPCL_INTERROGATEDB PyTypeObject *Dtool_EnumType_Create(const char *name, PyObject *names, +PyTypeObject *Dtool_EnumType_Create(const char *name, PyObject *names, const char *module = nullptr); -EXPCL_INTERROGATEDB INLINE long Dtool_EnumValue_AsLong(PyObject *value); +INLINE long Dtool_EnumValue_AsLong(PyObject *value); /** */ -EXPCL_INTERROGATEDB PyObject *DTool_CreatePyInstanceTyped(void *local_this_in, Dtool_PyTypedObject &known_class_type, bool memory_rules, bool is_const, int RunTimeType); +PyObject *DTool_CreatePyInstanceTyped(void *local_this_in, Dtool_PyTypedObject &known_class_type, bool memory_rules, bool is_const, int RunTimeType); // DTool_CreatePyInstance .. wrapper function to finalize the existance of a // general dtool py instance.. -EXPCL_INTERROGATEDB PyObject *DTool_CreatePyInstance(void *local_this, Dtool_PyTypedObject &in_classdef, bool memory_rules, bool is_const); +PyObject *DTool_CreatePyInstance(void *local_this, Dtool_PyTypedObject &in_classdef, bool memory_rules, bool is_const); // These template methods allow use when the Dtool_PyTypedObject is not known. // They require a get_class_type() to be defined for the class. @@ -312,15 +300,13 @@ Define_Dtool_FreeInstanceRef(CLASS_NAME,CNAME)\ Define_Dtool_Class(MODULE_NAME,CLASS_NAME,PUBLIC_NAME) // The finalizer for simple instances. -EXPCL_INTERROGATEDB int DTool_PyInit_Finalize(PyObject *self, void *This, Dtool_PyTypedObject *type, bool memory_rules, bool is_const); +INLINE int DTool_PyInit_Finalize(PyObject *self, void *This, Dtool_PyTypedObject *type, bool memory_rules, bool is_const); // A heler function to glu methed definition together .. that can not be done // at code generation time becouse of multiple generation passes in // interigate.. typedef std::map MethodDefmap; -EXPCL_INTERROGATEDB void Dtool_Accum_MethDefs(PyMethodDef in[], MethodDefmap &themap); - // We need a way to runtime merge compile units into a python "Module" .. this // is done with the fallowing structors and code.. along with the support of // interigate_module @@ -337,26 +323,26 @@ struct LibraryDef { }; #if PY_MAJOR_VERSION >= 3 -EXPCL_INTERROGATEDB PyObject *Dtool_PyModuleInitHelper(const LibraryDef *defs[], PyModuleDef *module_def); +PyObject *Dtool_PyModuleInitHelper(const LibraryDef *defs[], PyModuleDef *module_def); #else -EXPCL_INTERROGATEDB PyObject *Dtool_PyModuleInitHelper(const LibraryDef *defs[], const char *modulename); +PyObject *Dtool_PyModuleInitHelper(const LibraryDef *defs[], const char *modulename); #endif // HACK.... Be carefull Dtool_BorrowThisReference This function can be used to // grab the "THIS" pointer from an object and use it Required to support fom // historical inharatence in the for of "is this instance of".. -EXPCL_INTERROGATEDB PyObject *Dtool_BorrowThisReference(PyObject *self, PyObject *args); +PyObject *Dtool_BorrowThisReference(PyObject *self, PyObject *args); #define DTOOL_PyObject_HashPointer DtoolInstance_HashPointer #define DTOOL_PyObject_ComparePointers DtoolInstance_ComparePointers -EXPCL_INTERROGATEDB PyObject * +PyObject * copy_from_make_copy(PyObject *self, PyObject *noargs); -EXPCL_INTERROGATEDB PyObject * +PyObject * copy_from_copy_constructor(PyObject *self, PyObject *noargs); -EXPCL_INTERROGATEDB PyObject * +PyObject * map_deepcopy_to_copy(PyObject *self, PyObject *args); /** @@ -365,13 +351,13 @@ map_deepcopy_to_copy(PyObject *self, PyObject *args); */ ALWAYS_INLINE bool Dtool_CheckNoArgs(PyObject *args); ALWAYS_INLINE bool Dtool_CheckNoArgs(PyObject *args, PyObject *kwds); -EXPCL_INTERROGATEDB bool Dtool_ExtractArg(PyObject **result, PyObject *args, +bool Dtool_ExtractArg(PyObject **result, PyObject *args, PyObject *kwds, const char *keyword); -EXPCL_INTERROGATEDB bool Dtool_ExtractArg(PyObject **result, PyObject *args, +bool Dtool_ExtractArg(PyObject **result, PyObject *args, PyObject *kwds); -EXPCL_INTERROGATEDB bool Dtool_ExtractOptionalArg(PyObject **result, PyObject *args, +bool Dtool_ExtractOptionalArg(PyObject **result, PyObject *args, PyObject *kwds, const char *keyword); -EXPCL_INTERROGATEDB bool Dtool_ExtractOptionalArg(PyObject **result, PyObject *args, +bool Dtool_ExtractOptionalArg(PyObject **result, PyObject *args, PyObject *kwds); /** @@ -407,10 +393,7 @@ ALWAYS_INLINE PyObject *Dtool_WrapValue(Py_buffer *value); template ALWAYS_INLINE PyObject *Dtool_WrapValue(const std::pair &value); -EXPCL_INTERROGATEDB extern struct Dtool_PyTypedObject Dtool_DTOOL_SUPER_BASE; -EXPCL_INTERROGATEDB extern void Dtool_PyModuleClassInit_DTOOL_SUPER_BASE(PyObject *module); - -#define Dtool_Ptr_DTOOL_SUPER_BASE (&Dtool_DTOOL_SUPER_BASE) +Dtool_PyTypedObject *Dtool_GetSuperBase(); #include "py_panda.I" diff --git a/dtool/src/interrogatedb/py_wrappers.cxx b/dtool/src/interrogatedb/py_wrappers.cxx index 71a5a38ffd..0b8a751cad 100644 --- a/dtool/src/interrogatedb/py_wrappers.cxx +++ b/dtool/src/interrogatedb/py_wrappers.cxx @@ -1,11 +1,4 @@ /** - * PANDA 3D SOFTWARE - * Copyright (c) Carnegie Mellon University. All rights reserved. - * - * All use of this software is subject to the terms of the revised BSD - * license. You should have received a copy of this license along - * with this source code in a file named "LICENSE." - * * @file py_wrappers.cxx * @author rdb * @date 2017-11-26 @@ -494,6 +487,24 @@ static PyObject *Dtool_MappingWrapper_get(PyObject *self, PyObject *args) { } } +/** + * This is returned by mapping.keys(). + */ +static PyObject *Dtool_MappingWrapper_Keys_repr(PyObject *self) { + Dtool_WrapperBase *wrap = (Dtool_WrapperBase *)self; + nassertr(wrap, nullptr); + + PyObject *repr = PyObject_Repr(wrap->_self); + PyObject *result; +#if PY_MAJOR_VERSION >= 3 + result = PyUnicode_FromFormat("<%s.keys() of %s>", wrap->_name, PyUnicode_AsUTF8(repr)); +#else + result = PyString_FromFormat("<%s.keys() of %s>", wrap->_name, PyString_AS_STRING(repr)); +#endif + Py_DECREF(repr); + return result; +} + /** * Implementation of property.keys(...) that returns a view of all the keys. */ @@ -510,14 +521,81 @@ static PyObject *Dtool_MappingWrapper_keys(PyObject *self, PyObject *) { return PyErr_NoMemory(); } - // If the collections.abc module is loaded, register this as a subclass. + static PySequenceMethods seq_methods = { + Dtool_SequenceWrapper_length, + nullptr, // sq_concat + nullptr, // sq_repeat + Dtool_SequenceWrapper_getitem, + nullptr, // sq_slice + nullptr, // sq_ass_item + nullptr, // sq_ass_slice + Dtool_SequenceWrapper_contains, + nullptr, // sq_inplace_concat + nullptr, // sq_inplace_repeat + }; + + static PyTypeObject wrapper_type = { + PyVarObject_HEAD_INIT(nullptr, 0) + "sequence wrapper", + sizeof(Dtool_SequenceWrapper), + 0, // tp_itemsize + Dtool_WrapperBase_dealloc, + nullptr, // tp_print + nullptr, // tp_getattr + nullptr, // tp_setattr + nullptr, // tp_compare + Dtool_MappingWrapper_Keys_repr, + nullptr, // tp_as_number + &seq_methods, + nullptr, // tp_as_mapping + nullptr, // tp_hash + nullptr, // tp_call + nullptr, // tp_str + PyObject_GenericGetAttr, + PyObject_GenericSetAttr, + nullptr, // tp_as_buffer + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES, + nullptr, // tp_doc + nullptr, // tp_traverse + nullptr, // tp_clear + nullptr, // tp_richcompare + 0, // tp_weaklistoffset + PySeqIter_New, + nullptr, // tp_iternext + nullptr, // tp_methods + nullptr, // tp_members + nullptr, // tp_getset + nullptr, // tp_base + nullptr, // tp_dict + nullptr, // tp_descr_get + nullptr, // tp_descr_set + 0, // tp_dictoffset + nullptr, // tp_init + PyType_GenericAlloc, + nullptr, // tp_new + PyObject_Del, + nullptr, // tp_is_gc + nullptr, // tp_bases + nullptr, // tp_mro + nullptr, // tp_cache + nullptr, // tp_subclasses + nullptr, // tp_weaklist + nullptr, // tp_del + }; + static bool registered = false; if (!registered) { registered = true; - _register_collection((PyTypeObject *)&Dtool_MappingWrapper_Keys_Type, "MappingView"); + + if (PyType_Ready(&wrapper_type) < 0) { + return nullptr; + } + + // If the collections.abc module is loaded, register this as a subclass. + _register_collection((PyTypeObject *)&wrapper_type, "MappingView"); } - (void)PyObject_INIT(keys, &Dtool_MappingWrapper_Keys_Type); + (void)PyObject_INIT(keys, &wrapper_type); Py_XINCREF(wrap->_base._self); keys->_base._self = wrap->_base._self; keys->_base._name = wrap->_base._name; @@ -528,6 +606,38 @@ static PyObject *Dtool_MappingWrapper_keys(PyObject *self, PyObject *) { return (PyObject *)keys; } +/** + * This is returned by mapping.values(). + */ +static PyObject *Dtool_MappingWrapper_Values_repr(PyObject *self) { + Dtool_WrapperBase *wrap = (Dtool_WrapperBase *)self; + nassertr(wrap, nullptr); + + PyObject *repr = PyObject_Repr(wrap->_self); + PyObject *result; +#if PY_MAJOR_VERSION >= 3 + result = PyUnicode_FromFormat("<%s.values() of %s>", wrap->_name, PyUnicode_AsUTF8(repr)); +#else + result = PyString_FromFormat("<%s.values() of %s>", wrap->_name, PyString_AS_STRING(repr)); +#endif + Py_DECREF(repr); + return result; +} + +static PyObject *Dtool_MappingWrapper_Values_getitem(PyObject *self, Py_ssize_t index) { + Dtool_MappingWrapper *wrap = (Dtool_MappingWrapper *)self; + nassertr(wrap, nullptr); + nassertr(wrap->_keys._getitem_func, nullptr); + + PyObject *key = wrap->_keys._getitem_func(wrap->_base._self, index); + if (key != nullptr) { + PyObject *value = wrap->_getitem_func(wrap->_base._self, key); + Py_DECREF(key); + return value; + } + return nullptr; +} + /** * Implementation of property.values(...) that returns a view of the values. */ @@ -545,14 +655,81 @@ static PyObject *Dtool_MappingWrapper_values(PyObject *self, PyObject *) { return PyErr_NoMemory(); } - // If the collections.abc module is loaded, register this as a subclass. + static PySequenceMethods seq_methods = { + Dtool_SequenceWrapper_length, + nullptr, // sq_concat + nullptr, // sq_repeat + Dtool_MappingWrapper_Values_getitem, + nullptr, // sq_slice + nullptr, // sq_ass_item + nullptr, // sq_ass_slice + Dtool_MappingWrapper_contains, + nullptr, // sq_inplace_concat + nullptr, // sq_inplace_repeat + }; + + static PyTypeObject wrapper_type = { + PyVarObject_HEAD_INIT(nullptr, 0) + "sequence wrapper", + sizeof(Dtool_MappingWrapper), + 0, // tp_itemsize + Dtool_WrapperBase_dealloc, + nullptr, // tp_print + nullptr, // tp_getattr + nullptr, // tp_setattr + nullptr, // tp_compare + Dtool_MappingWrapper_Values_repr, + nullptr, // tp_as_number + &seq_methods, + nullptr, // tp_as_mapping + nullptr, // tp_hash + nullptr, // tp_call + nullptr, // tp_str + PyObject_GenericGetAttr, + PyObject_GenericSetAttr, + nullptr, // tp_as_buffer + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES, + nullptr, // tp_doc + nullptr, // tp_traverse + nullptr, // tp_clear + nullptr, // tp_richcompare + 0, // tp_weaklistoffset + PySeqIter_New, + nullptr, // tp_iternext + nullptr, // tp_methods + nullptr, // tp_members + nullptr, // tp_getset + nullptr, // tp_base + nullptr, // tp_dict + nullptr, // tp_descr_get + nullptr, // tp_descr_set + 0, // tp_dictoffset + nullptr, // tp_init + PyType_GenericAlloc, + nullptr, // tp_new + PyObject_Del, + nullptr, // tp_is_gc + nullptr, // tp_bases + nullptr, // tp_mro + nullptr, // tp_cache + nullptr, // tp_subclasses + nullptr, // tp_weaklist + nullptr, // tp_del + }; + static bool registered = false; if (!registered) { registered = true; - _register_collection((PyTypeObject *)&Dtool_MappingWrapper_Values_Type, "ValuesView"); + + if (PyType_Ready(&wrapper_type) < 0) { + return nullptr; + } + + // If the collections.abc module is loaded, register this as a subclass. + _register_collection((PyTypeObject *)&wrapper_type, "ValuesView"); } - (void)PyObject_INIT(values, &Dtool_MappingWrapper_Values_Type); + (void)PyObject_INIT(values, &wrapper_type); Py_XINCREF(wrap->_base._self); values->_base._self = wrap->_base._self; values->_base._name = wrap->_base._name; @@ -563,6 +740,45 @@ static PyObject *Dtool_MappingWrapper_values(PyObject *self, PyObject *) { return (PyObject *)values; } +/** + * This is returned by mapping.items(). + */ +static PyObject *Dtool_MappingWrapper_Items_repr(PyObject *self) { + Dtool_WrapperBase *wrap = (Dtool_WrapperBase *)self; + nassertr(wrap, nullptr); + + PyObject *repr = PyObject_Repr(wrap->_self); + PyObject *result; +#if PY_MAJOR_VERSION >= 3 + result = PyUnicode_FromFormat("<%s.items() of %s>", wrap->_name, PyUnicode_AsUTF8(repr)); +#else + result = PyString_FromFormat("<%s.items() of %s>", wrap->_name, PyString_AS_STRING(repr)); +#endif + Py_DECREF(repr); + return result; +} + +static PyObject *Dtool_MappingWrapper_Items_getitem(PyObject *self, Py_ssize_t index) { + Dtool_MappingWrapper *wrap = (Dtool_MappingWrapper *)self; + nassertr(wrap, nullptr); + nassertr(wrap->_keys._getitem_func, nullptr); + + PyObject *key = wrap->_keys._getitem_func(wrap->_base._self, index); + if (key != nullptr) { + PyObject *value = wrap->_getitem_func(wrap->_base._self, key); + if (value != nullptr) { + // PyTuple_SET_ITEM steals the reference. + PyObject *item = PyTuple_New(2); + PyTuple_SET_ITEM(item, 0, key); + PyTuple_SET_ITEM(item, 1, value); + return item; + } else { + Py_DECREF(key); + } + } + return nullptr; +} + /** * Implementation of property.items(...) that returns an iterable yielding a * `(key, value)` tuple for every item. @@ -581,14 +797,81 @@ static PyObject *Dtool_MappingWrapper_items(PyObject *self, PyObject *) { return PyErr_NoMemory(); } - // If the collections.abc module is loaded, register this as a subclass. + static PySequenceMethods seq_methods = { + Dtool_SequenceWrapper_length, + nullptr, // sq_concat + nullptr, // sq_repeat + Dtool_MappingWrapper_Items_getitem, + nullptr, // sq_slice + nullptr, // sq_ass_item + nullptr, // sq_ass_slice + Dtool_MappingWrapper_contains, + nullptr, // sq_inplace_concat + nullptr, // sq_inplace_repeat + }; + + static PyTypeObject wrapper_type = { + PyVarObject_HEAD_INIT(nullptr, 0) + "sequence wrapper", + sizeof(Dtool_MappingWrapper), + 0, // tp_itemsize + Dtool_WrapperBase_dealloc, + nullptr, // tp_print + nullptr, // tp_getattr + nullptr, // tp_setattr + nullptr, // tp_compare + Dtool_MappingWrapper_Items_repr, + nullptr, // tp_as_number + &seq_methods, + nullptr, // tp_as_mapping + nullptr, // tp_hash + nullptr, // tp_call + nullptr, // tp_str + PyObject_GenericGetAttr, + PyObject_GenericSetAttr, + nullptr, // tp_as_buffer + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES, + nullptr, // tp_doc + nullptr, // tp_traverse + nullptr, // tp_clear + nullptr, // tp_richcompare + 0, // tp_weaklistoffset + PySeqIter_New, + nullptr, // tp_iternext + nullptr, // tp_methods + nullptr, // tp_members + nullptr, // tp_getset + nullptr, // tp_base + nullptr, // tp_dict + nullptr, // tp_descr_get + nullptr, // tp_descr_set + 0, // tp_dictoffset + nullptr, // tp_init + PyType_GenericAlloc, + nullptr, // tp_new + PyObject_Del, + nullptr, // tp_is_gc + nullptr, // tp_bases + nullptr, // tp_mro + nullptr, // tp_cache + nullptr, // tp_subclasses + nullptr, // tp_weaklist + nullptr, // tp_del + }; + static bool registered = false; if (!registered) { registered = true; - _register_collection((PyTypeObject *)&Dtool_MappingWrapper_Items_Type, "MappingView"); + + if (PyType_Ready(&wrapper_type) < 0) { + return nullptr; + } + + // If the collections.abc module is loaded, register this as a subclass. + _register_collection((PyTypeObject *)&wrapper_type, "MappingView"); } - (void)PyObject_INIT(items, &Dtool_MappingWrapper_Items_Type); + (void)PyObject_INIT(items, &wrapper_type); Py_XINCREF(wrap->_base._self); items->_base._self = wrap->_base._self; items->_base._name = wrap->_base._name; @@ -792,566 +1075,6 @@ static PyObject *Dtool_MutableMappingWrapper_update(PyObject *self, PyObject *ar return Py_None; } -/** - * This variant defines only a sequence interface. - */ -static PySequenceMethods Dtool_SequenceWrapper_SequenceMethods = { - Dtool_SequenceWrapper_length, - nullptr, // sq_concat - nullptr, // sq_repeat - Dtool_SequenceWrapper_getitem, - nullptr, // sq_slice - nullptr, // sq_ass_item - nullptr, // sq_ass_slice - Dtool_SequenceWrapper_contains, - nullptr, // sq_inplace_concat - nullptr, // sq_inplace_repeat -}; - -static PyMethodDef Dtool_SequenceWrapper_Methods[] = { - {"index", &Dtool_SequenceWrapper_index, METH_O, nullptr}, - {"count", &Dtool_SequenceWrapper_count, METH_O, nullptr}, - {nullptr, nullptr, 0, nullptr} -}; - -PyTypeObject Dtool_SequenceWrapper_Type = { - PyVarObject_HEAD_INIT(nullptr, 0) - "sequence wrapper", - sizeof(Dtool_SequenceWrapper), - 0, // tp_itemsize - Dtool_WrapperBase_dealloc, - nullptr, // tp_print - nullptr, // tp_getattr - nullptr, // tp_setattr - nullptr, // tp_compare - Dtool_SequenceWrapper_repr, - nullptr, // tp_as_number - &Dtool_SequenceWrapper_SequenceMethods, - nullptr, // tp_as_mapping - nullptr, // tp_hash - nullptr, // tp_call - nullptr, // tp_str - PyObject_GenericGetAttr, - PyObject_GenericSetAttr, - nullptr, // tp_as_buffer - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES, - nullptr, // tp_doc - nullptr, // tp_traverse - nullptr, // tp_clear - nullptr, // tp_richcompare - 0, // tp_weaklistoffset - PySeqIter_New, - nullptr, // tp_iternext - Dtool_SequenceWrapper_Methods, - nullptr, // tp_members - nullptr, // tp_getset - nullptr, // tp_base - nullptr, // tp_dict - nullptr, // tp_descr_get - nullptr, // tp_descr_set - 0, // tp_dictoffset - nullptr, // tp_init - PyType_GenericAlloc, - nullptr, // tp_new - PyObject_Del, - nullptr, // tp_is_gc - nullptr, // tp_bases - nullptr, // tp_mro - nullptr, // tp_cache - nullptr, // tp_subclasses - nullptr, // tp_weaklist - nullptr, // tp_del -}; - -/** - * This is a variant on SequenceWrapper that also has an insert() method. - */ -static PySequenceMethods Dtool_MutableSequenceWrapper_SequenceMethods = { - Dtool_SequenceWrapper_length, - nullptr, // sq_concat - nullptr, // sq_repeat - Dtool_SequenceWrapper_getitem, - nullptr, // sq_slice - Dtool_MutableSequenceWrapper_setitem, - nullptr, // sq_ass_slice - Dtool_SequenceWrapper_contains, - Dtool_MutableSequenceWrapper_extend, - nullptr, // sq_inplace_repeat -}; - -static PyMethodDef Dtool_MutableSequenceWrapper_Methods[] = { - {"index", &Dtool_SequenceWrapper_index, METH_O, nullptr}, - {"count", &Dtool_SequenceWrapper_count, METH_O, nullptr}, - {"clear", &Dtool_MutableSequenceWrapper_clear, METH_NOARGS, nullptr}, - {"pop", &Dtool_MutableSequenceWrapper_pop, METH_VARARGS, nullptr}, - {"remove", &Dtool_MutableSequenceWrapper_remove, METH_O, nullptr}, - {"append", &Dtool_MutableSequenceWrapper_append, METH_O, nullptr}, - {"insert", &Dtool_MutableSequenceWrapper_insert, METH_VARARGS, nullptr}, - {"extend", &Dtool_MutableSequenceWrapper_extend, METH_O, nullptr}, - {nullptr, nullptr, 0, nullptr} -}; - -PyTypeObject Dtool_MutableSequenceWrapper_Type = { - PyVarObject_HEAD_INIT(nullptr, 0) - "sequence wrapper", - sizeof(Dtool_MutableSequenceWrapper), - 0, // tp_itemsize - Dtool_WrapperBase_dealloc, - nullptr, // tp_print - nullptr, // tp_getattr - nullptr, // tp_setattr - nullptr, // tp_compare - Dtool_SequenceWrapper_repr, - nullptr, // tp_as_number - &Dtool_MutableSequenceWrapper_SequenceMethods, - nullptr, // tp_as_mapping - nullptr, // tp_hash - nullptr, // tp_call - nullptr, // tp_str - PyObject_GenericGetAttr, - PyObject_GenericSetAttr, - nullptr, // tp_as_buffer - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES, - nullptr, // tp_doc - nullptr, // tp_traverse - nullptr, // tp_clear - nullptr, // tp_richcompare - 0, // tp_weaklistoffset - PySeqIter_New, - nullptr, // tp_iternext - Dtool_MutableSequenceWrapper_Methods, - nullptr, // tp_members - nullptr, // tp_getset - nullptr, // tp_base - nullptr, // tp_dict - nullptr, // tp_descr_get - nullptr, // tp_descr_set - 0, // tp_dictoffset - nullptr, // tp_init - PyType_GenericAlloc, - nullptr, // tp_new - PyObject_Del, - nullptr, // tp_is_gc - nullptr, // tp_bases - nullptr, // tp_mro - nullptr, // tp_cache - nullptr, // tp_subclasses - nullptr, // tp_weaklist - nullptr, // tp_del -}; - -/** - * This variant defines only a mapping interface. - */ -static PySequenceMethods Dtool_MappingWrapper_SequenceMethods = { - Dtool_SequenceWrapper_length, - nullptr, // sq_concat - nullptr, // sq_repeat - nullptr, // sq_item - nullptr, // sq_slice - nullptr, // sq_ass_item - nullptr, // sq_ass_slice - Dtool_MappingWrapper_contains, - nullptr, // sq_inplace_concat - nullptr, // sq_inplace_repeat -}; - -static PyMappingMethods Dtool_MappingWrapper_MappingMethods = { - Dtool_SequenceWrapper_length, - Dtool_MappingWrapper_getitem, - nullptr, // mp_ass_subscript -}; - -static PyMethodDef Dtool_MappingWrapper_Methods[] = { - {"get", &Dtool_MappingWrapper_get, METH_VARARGS, nullptr}, - {"keys", &Dtool_MappingWrapper_keys, METH_NOARGS, nullptr}, - {"values", &Dtool_MappingWrapper_values, METH_NOARGS, nullptr}, - {"items", &Dtool_MappingWrapper_items, METH_NOARGS, nullptr}, - {nullptr, nullptr, 0, nullptr} -}; - -PyTypeObject Dtool_MappingWrapper_Type = { - PyVarObject_HEAD_INIT(nullptr, 0) - "mapping wrapper", - sizeof(Dtool_MappingWrapper), - 0, // tp_itemsize - Dtool_WrapperBase_dealloc, - nullptr, // tp_print - nullptr, // tp_getattr - nullptr, // tp_setattr - nullptr, // tp_compare - Dtool_WrapperBase_repr, - nullptr, // tp_as_number - &Dtool_MappingWrapper_SequenceMethods, - &Dtool_MappingWrapper_MappingMethods, - nullptr, // tp_hash - nullptr, // tp_call - nullptr, // tp_str - PyObject_GenericGetAttr, - PyObject_GenericSetAttr, - nullptr, // tp_as_buffer - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES, - nullptr, // tp_doc - nullptr, // tp_traverse - nullptr, // tp_clear - nullptr, // tp_richcompare - 0, // tp_weaklistoffset - Dtool_MappingWrapper_iter, - nullptr, // tp_iternext - Dtool_MappingWrapper_Methods, - nullptr, // tp_members - nullptr, // tp_getset - nullptr, // tp_base - nullptr, // tp_dict - nullptr, // tp_descr_get - nullptr, // tp_descr_set - 0, // tp_dictoffset - nullptr, // tp_init - PyType_GenericAlloc, - nullptr, // tp_new - PyObject_Del, - nullptr, // tp_is_gc - nullptr, // tp_bases - nullptr, // tp_mro - nullptr, // tp_cache - nullptr, // tp_subclasses - nullptr, // tp_weaklist - nullptr, // tp_del -}; - -/** - * This variant defines only a mutable mapping interface. - */ -static PyMappingMethods Dtool_MutableMappingWrapper_MappingMethods = { - Dtool_SequenceWrapper_length, - Dtool_MappingWrapper_getitem, - Dtool_MutableMappingWrapper_setitem, -}; - -static PyMethodDef Dtool_MutableMappingWrapper_Methods[] = { - {"get", &Dtool_MappingWrapper_get, METH_VARARGS, nullptr}, - {"pop", &Dtool_MutableMappingWrapper_pop, METH_VARARGS, nullptr}, - {"popitem", &Dtool_MutableMappingWrapper_popitem, METH_NOARGS, nullptr}, - {"clear", &Dtool_MutableMappingWrapper_clear, METH_VARARGS, nullptr}, - {"setdefault", &Dtool_MutableMappingWrapper_setdefault, METH_VARARGS, nullptr}, - {"update", (PyCFunction) &Dtool_MutableMappingWrapper_update, METH_VARARGS | METH_KEYWORDS, nullptr}, - {"keys", &Dtool_MappingWrapper_keys, METH_NOARGS, nullptr}, - {"values", &Dtool_MappingWrapper_values, METH_NOARGS, nullptr}, - {"items", &Dtool_MappingWrapper_items, METH_NOARGS, nullptr}, - {nullptr, nullptr, 0, nullptr} -}; - -PyTypeObject Dtool_MutableMappingWrapper_Type = { - PyVarObject_HEAD_INIT(nullptr, 0) - "mapping wrapper", - sizeof(Dtool_MappingWrapper), - 0, // tp_itemsize - Dtool_WrapperBase_dealloc, - nullptr, // tp_print - nullptr, // tp_getattr - nullptr, // tp_setattr - nullptr, // tp_compare - Dtool_WrapperBase_repr, - nullptr, // tp_as_number - &Dtool_MappingWrapper_SequenceMethods, - &Dtool_MutableMappingWrapper_MappingMethods, - nullptr, // tp_hash - nullptr, // tp_call - nullptr, // tp_str - PyObject_GenericGetAttr, - PyObject_GenericSetAttr, - nullptr, // tp_as_buffer - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES, - nullptr, // tp_doc - nullptr, // tp_traverse - nullptr, // tp_clear - nullptr, // tp_richcompare - 0, // tp_weaklistoffset - Dtool_MappingWrapper_iter, - nullptr, // tp_iternext - Dtool_MutableMappingWrapper_Methods, - nullptr, // tp_members - nullptr, // tp_getset - nullptr, // tp_base - nullptr, // tp_dict - nullptr, // tp_descr_get - nullptr, // tp_descr_set - 0, // tp_dictoffset - nullptr, // tp_init - PyType_GenericAlloc, - nullptr, // tp_new - PyObject_Del, - nullptr, // tp_is_gc - nullptr, // tp_bases - nullptr, // tp_mro - nullptr, // tp_cache - nullptr, // tp_subclasses - nullptr, // tp_weaklist - nullptr, // tp_del -}; - -/** - * This is returned by mapping.items(). - */ -static PyObject *Dtool_MappingWrapper_Items_repr(PyObject *self) { - Dtool_WrapperBase *wrap = (Dtool_WrapperBase *)self; - nassertr(wrap, nullptr); - - PyObject *repr = PyObject_Repr(wrap->_self); - PyObject *result; -#if PY_MAJOR_VERSION >= 3 - result = PyUnicode_FromFormat("<%s.items() of %s>", wrap->_name, PyUnicode_AsUTF8(repr)); -#else - result = PyString_FromFormat("<%s.items() of %s>", wrap->_name, PyString_AS_STRING(repr)); -#endif - Py_DECREF(repr); - return result; -} - -static PyObject *Dtool_MappingWrapper_Items_getitem(PyObject *self, Py_ssize_t index) { - Dtool_MappingWrapper *wrap = (Dtool_MappingWrapper *)self; - nassertr(wrap, nullptr); - nassertr(wrap->_keys._getitem_func, nullptr); - - PyObject *key = wrap->_keys._getitem_func(wrap->_base._self, index); - if (key != nullptr) { - PyObject *value = wrap->_getitem_func(wrap->_base._self, key); - if (value != nullptr) { - // PyTuple_SET_ITEM steals the reference. - PyObject *item = PyTuple_New(2); - PyTuple_SET_ITEM(item, 0, key); - PyTuple_SET_ITEM(item, 1, value); - return item; - } else { - Py_DECREF(key); - } - } - return nullptr; -} - -static PySequenceMethods Dtool_MappingWrapper_Items_SequenceMethods = { - Dtool_SequenceWrapper_length, - nullptr, // sq_concat - nullptr, // sq_repeat - Dtool_MappingWrapper_Items_getitem, - nullptr, // sq_slice - nullptr, // sq_ass_item - nullptr, // sq_ass_slice - Dtool_MappingWrapper_contains, - nullptr, // sq_inplace_concat - nullptr, // sq_inplace_repeat -}; - -PyTypeObject Dtool_MappingWrapper_Items_Type = { - PyVarObject_HEAD_INIT(nullptr, 0) - "sequence wrapper", - sizeof(Dtool_MappingWrapper), - 0, // tp_itemsize - Dtool_WrapperBase_dealloc, - nullptr, // tp_print - nullptr, // tp_getattr - nullptr, // tp_setattr - nullptr, // tp_compare - Dtool_MappingWrapper_Items_repr, - nullptr, // tp_as_number - &Dtool_MappingWrapper_Items_SequenceMethods, - nullptr, // tp_as_mapping - nullptr, // tp_hash - nullptr, // tp_call - nullptr, // tp_str - PyObject_GenericGetAttr, - PyObject_GenericSetAttr, - nullptr, // tp_as_buffer - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES, - nullptr, // tp_doc - nullptr, // tp_traverse - nullptr, // tp_clear - nullptr, // tp_richcompare - 0, // tp_weaklistoffset - PySeqIter_New, - nullptr, // tp_iternext - nullptr, // tp_methods - nullptr, // tp_members - nullptr, // tp_getset - nullptr, // tp_base - nullptr, // tp_dict - nullptr, // tp_descr_get - nullptr, // tp_descr_set - 0, // tp_dictoffset - nullptr, // tp_init - PyType_GenericAlloc, - nullptr, // tp_new - PyObject_Del, - nullptr, // tp_is_gc - nullptr, // tp_bases - nullptr, // tp_mro - nullptr, // tp_cache - nullptr, // tp_subclasses - nullptr, // tp_weaklist - nullptr, // tp_del -}; - -/** - * This is returned by mapping.keys(). - */ -static PyObject *Dtool_MappingWrapper_Keys_repr(PyObject *self) { - Dtool_WrapperBase *wrap = (Dtool_WrapperBase *)self; - nassertr(wrap, nullptr); - - PyObject *repr = PyObject_Repr(wrap->_self); - PyObject *result; -#if PY_MAJOR_VERSION >= 3 - result = PyUnicode_FromFormat("<%s.keys() of %s>", wrap->_name, PyUnicode_AsUTF8(repr)); -#else - result = PyString_FromFormat("<%s.keys() of %s>", wrap->_name, PyString_AS_STRING(repr)); -#endif - Py_DECREF(repr); - return result; -} - -PyTypeObject Dtool_MappingWrapper_Keys_Type = { - PyVarObject_HEAD_INIT(nullptr, 0) - "sequence wrapper", - sizeof(Dtool_SequenceWrapper), - 0, // tp_itemsize - Dtool_WrapperBase_dealloc, - nullptr, // tp_print - nullptr, // tp_getattr - nullptr, // tp_setattr - nullptr, // tp_compare - Dtool_MappingWrapper_Keys_repr, - nullptr, // tp_as_number - &Dtool_SequenceWrapper_SequenceMethods, - nullptr, // tp_as_mapping - nullptr, // tp_hash - nullptr, // tp_call - nullptr, // tp_str - PyObject_GenericGetAttr, - PyObject_GenericSetAttr, - nullptr, // tp_as_buffer - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES, - nullptr, // tp_doc - nullptr, // tp_traverse - nullptr, // tp_clear - nullptr, // tp_richcompare - 0, // tp_weaklistoffset - PySeqIter_New, - nullptr, // tp_iternext - nullptr, // tp_methods - nullptr, // tp_members - nullptr, // tp_getset - nullptr, // tp_base - nullptr, // tp_dict - nullptr, // tp_descr_get - nullptr, // tp_descr_set - 0, // tp_dictoffset - nullptr, // tp_init - PyType_GenericAlloc, - nullptr, // tp_new - PyObject_Del, - nullptr, // tp_is_gc - nullptr, // tp_bases - nullptr, // tp_mro - nullptr, // tp_cache - nullptr, // tp_subclasses - nullptr, // tp_weaklist - nullptr, // tp_del -}; - -/** - * This is returned by mapping.values(). - */ -static PyObject *Dtool_MappingWrapper_Values_repr(PyObject *self) { - Dtool_WrapperBase *wrap = (Dtool_WrapperBase *)self; - nassertr(wrap, nullptr); - - PyObject *repr = PyObject_Repr(wrap->_self); - PyObject *result; -#if PY_MAJOR_VERSION >= 3 - result = PyUnicode_FromFormat("<%s.values() of %s>", wrap->_name, PyUnicode_AsUTF8(repr)); -#else - result = PyString_FromFormat("<%s.values() of %s>", wrap->_name, PyString_AS_STRING(repr)); -#endif - Py_DECREF(repr); - return result; -} - -static PyObject *Dtool_MappingWrapper_Values_getitem(PyObject *self, Py_ssize_t index) { - Dtool_MappingWrapper *wrap = (Dtool_MappingWrapper *)self; - nassertr(wrap, nullptr); - nassertr(wrap->_keys._getitem_func, nullptr); - - PyObject *key = wrap->_keys._getitem_func(wrap->_base._self, index); - if (key != nullptr) { - PyObject *value = wrap->_getitem_func(wrap->_base._self, key); - Py_DECREF(key); - return value; - } - return nullptr; -} - -static PySequenceMethods Dtool_MappingWrapper_Values_SequenceMethods = { - Dtool_SequenceWrapper_length, - nullptr, // sq_concat - nullptr, // sq_repeat - Dtool_MappingWrapper_Values_getitem, - nullptr, // sq_slice - nullptr, // sq_ass_item - nullptr, // sq_ass_slice - Dtool_MappingWrapper_contains, - nullptr, // sq_inplace_concat - nullptr, // sq_inplace_repeat -}; - -PyTypeObject Dtool_MappingWrapper_Values_Type = { - PyVarObject_HEAD_INIT(nullptr, 0) - "sequence wrapper", - sizeof(Dtool_MappingWrapper), - 0, // tp_itemsize - Dtool_WrapperBase_dealloc, - nullptr, // tp_print - nullptr, // tp_getattr - nullptr, // tp_setattr - nullptr, // tp_compare - Dtool_MappingWrapper_Values_repr, - nullptr, // tp_as_number - &Dtool_MappingWrapper_Values_SequenceMethods, - nullptr, // tp_as_mapping - nullptr, // tp_hash - nullptr, // tp_call - nullptr, // tp_str - PyObject_GenericGetAttr, - PyObject_GenericSetAttr, - nullptr, // tp_as_buffer - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES, - nullptr, // tp_doc - nullptr, // tp_traverse - nullptr, // tp_clear - nullptr, // tp_richcompare - 0, // tp_weaklistoffset - PySeqIter_New, - nullptr, // tp_iternext - nullptr, // tp_methods - nullptr, // tp_members - nullptr, // tp_getset - nullptr, // tp_base - nullptr, // tp_dict - nullptr, // tp_descr_get - nullptr, // tp_descr_set - 0, // tp_dictoffset - nullptr, // tp_init - PyType_GenericAlloc, - nullptr, // tp_new - PyObject_Del, - nullptr, // tp_is_gc - nullptr, // tp_bases - nullptr, // tp_mro - nullptr, // tp_cache - nullptr, // tp_subclasses - nullptr, // tp_weaklist - nullptr, // tp_del -}; - /** * This variant defines only a generator interface. */ @@ -1362,55 +1085,6 @@ static PyObject *Dtool_GeneratorWrapper_iternext(PyObject *self) { return wrap->_iternext_func(wrap->_base._self); } -PyTypeObject Dtool_GeneratorWrapper_Type = { - PyVarObject_HEAD_INIT(nullptr, 0) - "generator wrapper", - sizeof(Dtool_GeneratorWrapper), - 0, // tp_itemsize - Dtool_WrapperBase_dealloc, - nullptr, // tp_print - nullptr, // tp_getattr - nullptr, // tp_setattr - nullptr, // tp_compare - nullptr, // tp_repr - nullptr, // tp_as_number - nullptr, // tp_as_sequence - nullptr, // tp_as_mapping - nullptr, // tp_hash - nullptr, // tp_call - nullptr, // tp_str - PyObject_GenericGetAttr, - PyObject_GenericSetAttr, - nullptr, // tp_as_buffer - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES, - nullptr, // tp_doc - nullptr, // tp_traverse - nullptr, // tp_clear - nullptr, // tp_richcompare - 0, // tp_weaklistoffset - PyObject_SelfIter, - Dtool_GeneratorWrapper_iternext, - nullptr, // tp_methods - nullptr, // tp_members - nullptr, // tp_getset - nullptr, // tp_base - nullptr, // tp_dict - nullptr, // tp_descr_get - nullptr, // tp_descr_set - 0, // tp_dictoffset - nullptr, // tp_init - PyType_GenericAlloc, - nullptr, // tp_new - PyObject_Del, - nullptr, // tp_is_gc - nullptr, // tp_bases - nullptr, // tp_mro - nullptr, // tp_cache - nullptr, // tp_subclasses - nullptr, // tp_weaklist - nullptr, // tp_del -}; - /** * This is a variant of the Python getset mechanism that permits static * properties. @@ -1479,55 +1153,6 @@ Dtool_StaticProperty_set(PyGetSetDescrObject *descr, PyObject *obj, PyObject *va } } -PyTypeObject Dtool_StaticProperty_Type = { - PyVarObject_HEAD_INIT(&PyType_Type, 0) - "getset_descriptor", - sizeof(PyGetSetDescrObject), - 0, // tp_itemsize - (destructor)Dtool_StaticProperty_dealloc, - nullptr, // tp_print - nullptr, // tp_getattr - nullptr, // tp_setattr - nullptr, // tp_reserved - (reprfunc)Dtool_StaticProperty_repr, - nullptr, // tp_as_number - nullptr, // tp_as_sequence - nullptr, // tp_as_mapping - nullptr, // tp_hash - nullptr, // tp_call - nullptr, // tp_str - PyObject_GenericGetAttr, - nullptr, // tp_setattro - nullptr, // tp_as_buffer - Py_TPFLAGS_DEFAULT, - nullptr, // tp_doc - Dtool_StaticProperty_traverse, - nullptr, // tp_clear - nullptr, // tp_richcompare - 0, // tp_weaklistoffset - nullptr, // tp_iter - nullptr, // tp_iternext - nullptr, // tp_methods - nullptr, // tp_members - nullptr, // tp_getset - nullptr, // tp_base - nullptr, // tp_dict - (descrgetfunc)Dtool_StaticProperty_get, - (descrsetfunc)Dtool_StaticProperty_set, - 0, // tp_dictoffset - nullptr, // tp_init - nullptr, // tp_alloc - nullptr, // tp_new - nullptr, // tp_del - nullptr, // tp_is_gc - nullptr, // tp_bases - nullptr, // tp_mro - nullptr, // tp_cache - nullptr, // tp_subclasses - nullptr, // tp_weaklist - nullptr, // tp_del -}; - /** * This wraps around a property that exposes a sequence interface. */ @@ -1537,14 +1162,87 @@ Dtool_SequenceWrapper *Dtool_NewSequenceWrapper(PyObject *self, const char *name return (Dtool_SequenceWrapper *)PyErr_NoMemory(); } - // If the collections.abc module is loaded, register this as a subclass. + static PySequenceMethods seq_methods = { + Dtool_SequenceWrapper_length, + nullptr, // sq_concat + nullptr, // sq_repeat + Dtool_SequenceWrapper_getitem, + nullptr, // sq_slice + nullptr, // sq_ass_item + nullptr, // sq_ass_slice + Dtool_SequenceWrapper_contains, + nullptr, // sq_inplace_concat + nullptr, // sq_inplace_repeat + }; + + static PyMethodDef methods[] = { + {"index", &Dtool_SequenceWrapper_index, METH_O, nullptr}, + {"count", &Dtool_SequenceWrapper_count, METH_O, nullptr}, + {nullptr, nullptr, 0, nullptr} + }; + + static PyTypeObject wrapper_type = { + PyVarObject_HEAD_INIT(nullptr, 0) + "sequence wrapper", + sizeof(Dtool_SequenceWrapper), + 0, // tp_itemsize + Dtool_WrapperBase_dealloc, + nullptr, // tp_print + nullptr, // tp_getattr + nullptr, // tp_setattr + nullptr, // tp_compare + Dtool_SequenceWrapper_repr, + nullptr, // tp_as_number + &seq_methods, + nullptr, // tp_as_mapping + nullptr, // tp_hash + nullptr, // tp_call + nullptr, // tp_str + PyObject_GenericGetAttr, + PyObject_GenericSetAttr, + nullptr, // tp_as_buffer + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES, + nullptr, // tp_doc + nullptr, // tp_traverse + nullptr, // tp_clear + nullptr, // tp_richcompare + 0, // tp_weaklistoffset + PySeqIter_New, + nullptr, // tp_iternext + methods, + nullptr, // tp_members + nullptr, // tp_getset + nullptr, // tp_base + nullptr, // tp_dict + nullptr, // tp_descr_get + nullptr, // tp_descr_set + 0, // tp_dictoffset + nullptr, // tp_init + PyType_GenericAlloc, + nullptr, // tp_new + PyObject_Del, + nullptr, // tp_is_gc + nullptr, // tp_bases + nullptr, // tp_mro + nullptr, // tp_cache + nullptr, // tp_subclasses + nullptr, // tp_weaklist + nullptr, // tp_del + }; + static bool registered = false; if (!registered) { registered = true; - _register_collection((PyTypeObject *)&Dtool_MutableSequenceWrapper_Type, "Sequence"); + + if (PyType_Ready(&wrapper_type) < 0) { + return nullptr; + } + + // If the collections.abc module is loaded, register this as a subclass. + _register_collection((PyTypeObject *)&wrapper_type, "Sequence"); } - (void)PyObject_INIT(wrap, &Dtool_SequenceWrapper_Type); + (void)PyObject_INIT(wrap, &wrapper_type); Py_XINCREF(self); wrap->_base._self = self; wrap->_base._name = name; @@ -1562,14 +1260,93 @@ Dtool_MutableSequenceWrapper *Dtool_NewMutableSequenceWrapper(PyObject *self, co return (Dtool_MutableSequenceWrapper *)PyErr_NoMemory(); } - // If the collections.abc module is loaded, register this as a subclass. + static PySequenceMethods seq_methods = { + Dtool_SequenceWrapper_length, + nullptr, // sq_concat + nullptr, // sq_repeat + Dtool_SequenceWrapper_getitem, + nullptr, // sq_slice + Dtool_MutableSequenceWrapper_setitem, + nullptr, // sq_ass_slice + Dtool_SequenceWrapper_contains, + Dtool_MutableSequenceWrapper_extend, + nullptr, // sq_inplace_repeat + }; + + static PyMethodDef methods[] = { + {"index", &Dtool_SequenceWrapper_index, METH_O, nullptr}, + {"count", &Dtool_SequenceWrapper_count, METH_O, nullptr}, + {"clear", &Dtool_MutableSequenceWrapper_clear, METH_NOARGS, nullptr}, + {"pop", &Dtool_MutableSequenceWrapper_pop, METH_VARARGS, nullptr}, + {"remove", &Dtool_MutableSequenceWrapper_remove, METH_O, nullptr}, + {"append", &Dtool_MutableSequenceWrapper_append, METH_O, nullptr}, + {"insert", &Dtool_MutableSequenceWrapper_insert, METH_VARARGS, nullptr}, + {"extend", &Dtool_MutableSequenceWrapper_extend, METH_O, nullptr}, + {nullptr, nullptr, 0, nullptr} + }; + + static PyTypeObject wrapper_type = { + PyVarObject_HEAD_INIT(nullptr, 0) + "sequence wrapper", + sizeof(Dtool_MutableSequenceWrapper), + 0, // tp_itemsize + Dtool_WrapperBase_dealloc, + nullptr, // tp_print + nullptr, // tp_getattr + nullptr, // tp_setattr + nullptr, // tp_compare + Dtool_SequenceWrapper_repr, + nullptr, // tp_as_number + &seq_methods, + nullptr, // tp_as_mapping + nullptr, // tp_hash + nullptr, // tp_call + nullptr, // tp_str + PyObject_GenericGetAttr, + PyObject_GenericSetAttr, + nullptr, // tp_as_buffer + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES, + nullptr, // tp_doc + nullptr, // tp_traverse + nullptr, // tp_clear + nullptr, // tp_richcompare + 0, // tp_weaklistoffset + PySeqIter_New, + nullptr, // tp_iternext + methods, + nullptr, // tp_members + nullptr, // tp_getset + nullptr, // tp_base + nullptr, // tp_dict + nullptr, // tp_descr_get + nullptr, // tp_descr_set + 0, // tp_dictoffset + nullptr, // tp_init + PyType_GenericAlloc, + nullptr, // tp_new + PyObject_Del, + nullptr, // tp_is_gc + nullptr, // tp_bases + nullptr, // tp_mro + nullptr, // tp_cache + nullptr, // tp_subclasses + nullptr, // tp_weaklist + nullptr, // tp_del + }; + static bool registered = false; if (!registered) { registered = true; - _register_collection((PyTypeObject *)&Dtool_MutableSequenceWrapper_Type, "MutableSequence"); + + if (PyType_Ready(&wrapper_type) < 0) { + return nullptr; + } + + // If the collections.abc module is loaded, register this as a subclass. + _register_collection((PyTypeObject *)&wrapper_type, "MutableSequence"); } - (void)PyObject_INIT(wrap, &Dtool_MutableSequenceWrapper_Type); + (void)PyObject_INIT(wrap, &wrapper_type); Py_XINCREF(self); wrap->_base._self = self; wrap->_base._name = name; @@ -1589,14 +1366,95 @@ Dtool_MappingWrapper *Dtool_NewMappingWrapper(PyObject *self, const char *name) return (Dtool_MappingWrapper *)PyErr_NoMemory(); } - // If the collections.abc module is loaded, register this as a subclass. + static PySequenceMethods seq_methods = { + Dtool_SequenceWrapper_length, + nullptr, // sq_concat + nullptr, // sq_repeat + nullptr, // sq_item + nullptr, // sq_slice + nullptr, // sq_ass_item + nullptr, // sq_ass_slice + Dtool_MappingWrapper_contains, + nullptr, // sq_inplace_concat + nullptr, // sq_inplace_repeat + }; + + static PyMappingMethods map_methods = { + Dtool_SequenceWrapper_length, + Dtool_MappingWrapper_getitem, + nullptr, // mp_ass_subscript + }; + + static PyMethodDef methods[] = { + {"get", &Dtool_MappingWrapper_get, METH_VARARGS, nullptr}, + {"keys", &Dtool_MappingWrapper_keys, METH_NOARGS, nullptr}, + {"values", &Dtool_MappingWrapper_values, METH_NOARGS, nullptr}, + {"items", &Dtool_MappingWrapper_items, METH_NOARGS, nullptr}, + {nullptr, nullptr, 0, nullptr} + }; + + static PyTypeObject wrapper_type = { + PyVarObject_HEAD_INIT(nullptr, 0) + "mapping wrapper", + sizeof(Dtool_MappingWrapper), + 0, // tp_itemsize + Dtool_WrapperBase_dealloc, + nullptr, // tp_print + nullptr, // tp_getattr + nullptr, // tp_setattr + nullptr, // tp_compare + Dtool_WrapperBase_repr, + nullptr, // tp_as_number + &seq_methods, + &map_methods, + nullptr, // tp_hash + nullptr, // tp_call + nullptr, // tp_str + PyObject_GenericGetAttr, + PyObject_GenericSetAttr, + nullptr, // tp_as_buffer + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES, + nullptr, // tp_doc + nullptr, // tp_traverse + nullptr, // tp_clear + nullptr, // tp_richcompare + 0, // tp_weaklistoffset + Dtool_MappingWrapper_iter, + nullptr, // tp_iternext + methods, + nullptr, // tp_members + nullptr, // tp_getset + nullptr, // tp_base + nullptr, // tp_dict + nullptr, // tp_descr_get + nullptr, // tp_descr_set + 0, // tp_dictoffset + nullptr, // tp_init + PyType_GenericAlloc, + nullptr, // tp_new + PyObject_Del, + nullptr, // tp_is_gc + nullptr, // tp_bases + nullptr, // tp_mro + nullptr, // tp_cache + nullptr, // tp_subclasses + nullptr, // tp_weaklist + nullptr, // tp_del + }; + static bool registered = false; if (!registered) { registered = true; - _register_collection((PyTypeObject *)&Dtool_MappingWrapper_Type, "Mapping"); + + if (PyType_Ready(&wrapper_type) < 0) { + return nullptr; + } + + // If the collections.abc module is loaded, register this as a subclass. + _register_collection((PyTypeObject *)&wrapper_type, "Mapping"); } - (void)PyObject_INIT(wrap, &Dtool_MappingWrapper_Type); + (void)PyObject_INIT(wrap, &wrapper_type); Py_XINCREF(self); wrap->_base._self = self; wrap->_base._name = name; @@ -1616,14 +1474,100 @@ Dtool_MappingWrapper *Dtool_NewMutableMappingWrapper(PyObject *self, const char return (Dtool_MappingWrapper *)PyErr_NoMemory(); } - // If the collections.abc module is loaded, register this as a subclass. + static PySequenceMethods seq_methods = { + Dtool_SequenceWrapper_length, + nullptr, // sq_concat + nullptr, // sq_repeat + nullptr, // sq_item + nullptr, // sq_slice + nullptr, // sq_ass_item + nullptr, // sq_ass_slice + Dtool_MappingWrapper_contains, + nullptr, // sq_inplace_concat + nullptr, // sq_inplace_repeat + }; + + static PyMappingMethods map_methods = { + Dtool_SequenceWrapper_length, + Dtool_MappingWrapper_getitem, + Dtool_MutableMappingWrapper_setitem, + }; + + static PyMethodDef methods[] = { + {"get", &Dtool_MappingWrapper_get, METH_VARARGS, nullptr}, + {"pop", &Dtool_MutableMappingWrapper_pop, METH_VARARGS, nullptr}, + {"popitem", &Dtool_MutableMappingWrapper_popitem, METH_NOARGS, nullptr}, + {"clear", &Dtool_MutableMappingWrapper_clear, METH_VARARGS, nullptr}, + {"setdefault", &Dtool_MutableMappingWrapper_setdefault, METH_VARARGS, nullptr}, + {"update", (PyCFunction) &Dtool_MutableMappingWrapper_update, METH_VARARGS | METH_KEYWORDS, nullptr}, + {"keys", &Dtool_MappingWrapper_keys, METH_NOARGS, nullptr}, + {"values", &Dtool_MappingWrapper_values, METH_NOARGS, nullptr}, + {"items", &Dtool_MappingWrapper_items, METH_NOARGS, nullptr}, + {nullptr, nullptr, 0, nullptr} + }; + + static PyTypeObject wrapper_type = { + PyVarObject_HEAD_INIT(nullptr, 0) + "mapping wrapper", + sizeof(Dtool_MappingWrapper), + 0, // tp_itemsize + Dtool_WrapperBase_dealloc, + nullptr, // tp_print + nullptr, // tp_getattr + nullptr, // tp_setattr + nullptr, // tp_compare + Dtool_WrapperBase_repr, + nullptr, // tp_as_number + &seq_methods, + &map_methods, + nullptr, // tp_hash + nullptr, // tp_call + nullptr, // tp_str + PyObject_GenericGetAttr, + PyObject_GenericSetAttr, + nullptr, // tp_as_buffer + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES, + nullptr, // tp_doc + nullptr, // tp_traverse + nullptr, // tp_clear + nullptr, // tp_richcompare + 0, // tp_weaklistoffset + Dtool_MappingWrapper_iter, + nullptr, // tp_iternext + methods, + nullptr, // tp_members + nullptr, // tp_getset + nullptr, // tp_base + nullptr, // tp_dict + nullptr, // tp_descr_get + nullptr, // tp_descr_set + 0, // tp_dictoffset + nullptr, // tp_init + PyType_GenericAlloc, + nullptr, // tp_new + PyObject_Del, + nullptr, // tp_is_gc + nullptr, // tp_bases + nullptr, // tp_mro + nullptr, // tp_cache + nullptr, // tp_subclasses + nullptr, // tp_weaklist + nullptr, // tp_del + }; + static bool registered = false; if (!registered) { registered = true; - _register_collection((PyTypeObject *)&Dtool_MutableMappingWrapper_Type, "MutableMapping"); + + if (PyType_Ready(&wrapper_type) < 0) { + return nullptr; + } + + // If the collections.abc module is loaded, register this as a subclass. + _register_collection((PyTypeObject *)&wrapper_type, "MutableMapping"); } - (void)PyObject_INIT(wrap, &Dtool_MutableMappingWrapper_Type); + (void)PyObject_INIT(wrap, &wrapper_type); Py_XINCREF(self); wrap->_base._self = self; wrap->_base._name = name; @@ -1634,14 +1578,135 @@ Dtool_MappingWrapper *Dtool_NewMutableMappingWrapper(PyObject *self, const char return wrap; } +/** + * Creates a generator that invokes a given function with the given self arg. + */ +PyObject * +Dtool_NewGenerator(PyObject *self, iternextfunc gen_next) { + static PyTypeObject wrapper_type = { + PyVarObject_HEAD_INIT(nullptr, 0) + "generator wrapper", + sizeof(Dtool_GeneratorWrapper), + 0, // tp_itemsize + Dtool_WrapperBase_dealloc, + nullptr, // tp_print + nullptr, // tp_getattr + nullptr, // tp_setattr + nullptr, // tp_compare + nullptr, // tp_repr + nullptr, // tp_as_number + nullptr, // tp_as_sequence + nullptr, // tp_as_mapping + nullptr, // tp_hash + nullptr, // tp_call + nullptr, // tp_str + PyObject_GenericGetAttr, + PyObject_GenericSetAttr, + nullptr, // tp_as_buffer + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES, + nullptr, // tp_doc + nullptr, // tp_traverse + nullptr, // tp_clear + nullptr, // tp_richcompare + 0, // tp_weaklistoffset + PyObject_SelfIter, + Dtool_GeneratorWrapper_iternext, + nullptr, // tp_methods + nullptr, // tp_members + nullptr, // tp_getset + nullptr, // tp_base + nullptr, // tp_dict + nullptr, // tp_descr_get + nullptr, // tp_descr_set + 0, // tp_dictoffset + nullptr, // tp_init + PyType_GenericAlloc, + nullptr, // tp_new + PyObject_Del, + nullptr, // tp_is_gc + nullptr, // tp_bases + nullptr, // tp_mro + nullptr, // tp_cache + nullptr, // tp_subclasses + nullptr, // tp_weaklist + nullptr, // tp_del + }; + + if (PyType_Ready(&wrapper_type) < 0) { + return nullptr; + } + + Dtool_GeneratorWrapper *gen; + gen = (Dtool_GeneratorWrapper *)PyType_GenericAlloc(&wrapper_type, 0); + if (gen != nullptr) { + Py_INCREF(self); + gen->_base._self = self; + gen->_iternext_func = gen_next; + } + return (PyObject *)gen; +} + /** * This is a variant of the Python getset mechanism that permits static * properties. */ PyObject * Dtool_NewStaticProperty(PyTypeObject *type, const PyGetSetDef *getset) { + static PyTypeObject wrapper_type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "getset_descriptor", + sizeof(PyGetSetDescrObject), + 0, // tp_itemsize + (destructor)Dtool_StaticProperty_dealloc, + nullptr, // tp_print + nullptr, // tp_getattr + nullptr, // tp_setattr + nullptr, // tp_reserved + (reprfunc)Dtool_StaticProperty_repr, + nullptr, // tp_as_number + nullptr, // tp_as_sequence + nullptr, // tp_as_mapping + nullptr, // tp_hash + nullptr, // tp_call + nullptr, // tp_str + PyObject_GenericGetAttr, + nullptr, // tp_setattro + nullptr, // tp_as_buffer + Py_TPFLAGS_DEFAULT, + nullptr, // tp_doc + Dtool_StaticProperty_traverse, + nullptr, // tp_clear + nullptr, // tp_richcompare + 0, // tp_weaklistoffset + nullptr, // tp_iter + nullptr, // tp_iternext + nullptr, // tp_methods + nullptr, // tp_members + nullptr, // tp_getset + nullptr, // tp_base + nullptr, // tp_dict + (descrgetfunc)Dtool_StaticProperty_get, + (descrsetfunc)Dtool_StaticProperty_set, + 0, // tp_dictoffset + nullptr, // tp_init + nullptr, // tp_alloc + nullptr, // tp_new + nullptr, // tp_del + nullptr, // tp_is_gc + nullptr, // tp_bases + nullptr, // tp_mro + nullptr, // tp_cache + nullptr, // tp_subclasses + nullptr, // tp_weaklist + nullptr, // tp_del + }; + + if (PyType_Ready(&wrapper_type) < 0) { + return nullptr; + } + PyGetSetDescrObject *descr; - descr = (PyGetSetDescrObject *)PyType_GenericAlloc(&Dtool_StaticProperty_Type, 0); + descr = (PyGetSetDescrObject *)PyType_GenericAlloc(&wrapper_type, 0); if (descr != nullptr) { Py_XINCREF(type); descr->d_getset = (PyGetSetDef *)getset; diff --git a/dtool/src/interrogatedb/py_wrappers.h b/dtool/src/interrogatedb/py_wrappers.h index 7bf2c2e19f..96375d3598 100644 --- a/dtool/src/interrogatedb/py_wrappers.h +++ b/dtool/src/interrogatedb/py_wrappers.h @@ -1,11 +1,4 @@ /** - * PANDA 3D SOFTWARE - * Copyright (c) Carnegie Mellon University. All rights reserved. - * - * All use of this software is subject to the terms of the revised BSD - * license. You should have received a copy of this license along - * with this source code in a file named "LICENSE." - * * @file py_wrappers.h * @author rdb * @date 2017-11-26 @@ -56,22 +49,12 @@ struct Dtool_GeneratorWrapper { iternextfunc _iternext_func; }; -EXPCL_INTERROGATEDB extern PyTypeObject Dtool_SequenceWrapper_Type; -EXPCL_INTERROGATEDB extern PyTypeObject Dtool_MutableSequenceWrapper_Type; -EXPCL_INTERROGATEDB extern PyTypeObject Dtool_MappingWrapper_Type; -EXPCL_INTERROGATEDB extern PyTypeObject Dtool_MutableMappingWrapper_Type; -EXPCL_INTERROGATEDB extern PyTypeObject Dtool_MappingWrapper_Items_Type; -EXPCL_INTERROGATEDB extern PyTypeObject Dtool_MappingWrapper_Keys_Type; -EXPCL_INTERROGATEDB extern PyTypeObject Dtool_MappingWrapper_Values_Type; -EXPCL_INTERROGATEDB extern PyTypeObject Dtool_GeneratorWrapper_Type; -EXPCL_INTERROGATEDB extern PyTypeObject Dtool_StaticProperty_Type; - -EXPCL_INTERROGATEDB Dtool_SequenceWrapper *Dtool_NewSequenceWrapper(PyObject *self, const char *name); -EXPCL_INTERROGATEDB Dtool_MutableSequenceWrapper *Dtool_NewMutableSequenceWrapper(PyObject *self, const char *name); -EXPCL_INTERROGATEDB Dtool_MappingWrapper *Dtool_NewMappingWrapper(PyObject *self, const char *name); -EXPCL_INTERROGATEDB Dtool_MappingWrapper *Dtool_NewMutableMappingWrapper(PyObject *self, const char *name); -EXPCL_INTERROGATEDB PyObject *Dtool_NewGenerator(PyObject *self, const char *name, iternextfunc func); -EXPCL_INTERROGATEDB PyObject *Dtool_NewStaticProperty(PyTypeObject *obj, const PyGetSetDef *getset); +Dtool_SequenceWrapper *Dtool_NewSequenceWrapper(PyObject *self, const char *name); +Dtool_MutableSequenceWrapper *Dtool_NewMutableSequenceWrapper(PyObject *self, const char *name); +Dtool_MappingWrapper *Dtool_NewMappingWrapper(PyObject *self, const char *name); +Dtool_MappingWrapper *Dtool_NewMutableMappingWrapper(PyObject *self, const char *name); +PyObject *Dtool_NewGenerator(PyObject *self, iternextfunc func); +PyObject *Dtool_NewStaticProperty(PyTypeObject *obj, const PyGetSetDef *getset); #endif // HAVE_PYTHON diff --git a/makepanda/makepanda.py b/makepanda/makepanda.py index 96effc4c43..eae006b2ec 100755 --- a/makepanda/makepanda.py +++ b/makepanda/makepanda.py @@ -3442,14 +3442,13 @@ TargetAdd('libp3dtoolconfig.dll', opts=['ADVAPI', 'OPENSSL', 'WINGDI', 'WINUSER' # DIRECTORY: dtool/src/interrogatedb/ # -OPTS=['DIR:dtool/src/interrogatedb', 'BUILDING:INTERROGATEDB', 'PYTHON'] +OPTS=['DIR:dtool/src/interrogatedb', 'BUILDING:INTERROGATEDB'] TargetAdd('p3interrogatedb_composite1.obj', opts=OPTS, input='p3interrogatedb_composite1.cxx') TargetAdd('p3interrogatedb_composite2.obj', opts=OPTS, input='p3interrogatedb_composite2.cxx') TargetAdd('libp3interrogatedb.dll', input='p3interrogatedb_composite1.obj') TargetAdd('libp3interrogatedb.dll', input='p3interrogatedb_composite2.obj') TargetAdd('libp3interrogatedb.dll', input='libp3dtool.dll') TargetAdd('libp3interrogatedb.dll', input='libp3dtoolconfig.dll') -TargetAdd('libp3interrogatedb.dll', opts=['PYTHON']) if not PkgSkip("PYTHON"): # This used to be called dtoolconfig.pyd, but it just contains the interrogatedb @@ -3489,8 +3488,16 @@ if (not RUNTIME): TargetAdd('interrogate.exe', input='libp3pystub.lib') TargetAdd('interrogate.exe', opts=['ADVAPI', 'OPENSSL', 'WINSHELL', 'WINGDI', 'WINUSER']) + preamble = WriteEmbeddedStringFile('interrogate_preamble_python_native', inputs=[ + 'dtool/src/interrogatedb/py_panda.cxx', + 'dtool/src/interrogatedb/py_compat.cxx', + 'dtool/src/interrogatedb/py_wrappers.cxx', + 'dtool/src/interrogatedb/dtool_super_base.cxx', + ]) + TargetAdd('interrogate_module_preamble_python_native.obj', opts=OPTS, input=preamble) TargetAdd('interrogate_module_interrogate_module.obj', opts=OPTS, input='interrogate_module.cxx') TargetAdd('interrogate_module.exe', input='interrogate_module_interrogate_module.obj') + TargetAdd('interrogate_module.exe', input='interrogate_module_preamble_python_native.obj') TargetAdd('interrogate_module.exe', input='libp3cppParser.ilb') TargetAdd('interrogate_module.exe', input=COMMON_DTOOL_LIBS) TargetAdd('interrogate_module.exe', input='libp3interrogatedb.dll') diff --git a/makepanda/makepandacore.py b/makepanda/makepandacore.py index 76dec39406..cf89b85e59 100644 --- a/makepanda/makepandacore.py +++ b/makepanda/makepandacore.py @@ -3190,6 +3190,48 @@ def WriteResourceFile(basename, **kwargs): ConditionalWriteFile(basename, GenerateResourceFile(**kwargs)) return basename + +def WriteEmbeddedStringFile(basename, inputs, string_name=None): + if os.path.splitext(basename)[1] not in SUFFIX_INC: + basename += '.cxx' + target = GetOutputDir() + "/tmp/" + basename + + if string_name is None: + string_name = os.path.basename(os.path.splitext(target)[0]) + string_name = string_name.replace('-', '_') + + data = bytearray() + for input in inputs: + fp = open(input, 'rb') + + # Insert a #line so that we get meaningful compile/assert errors when + # the result is inserted by interrogate_module into generated code. + if os.path.splitext(input)[1] in SUFFIX_INC: + line = '#line 1 "%s"\n' % (input) + data += bytearray(line.encode('ascii', 'replace')) + + data += bytearray(fp.read()) + fp.close() + + data.append(0) + + output = 'extern const char %s[] = {\n' % (string_name) + + i = 0 + for byte in data: + if i == 0: + output += ' ' + + output += ' 0x%02x,' % (byte) + i += 1 + if i >= 12: + output += '\n' + i = 0 + + output += '\n};\n' + ConditionalWriteFile(target, output) + return target + ######################################################################## ## ## FindLocation diff --git a/panda/src/event/asyncFuture_ext.cxx b/panda/src/event/asyncFuture_ext.cxx index 00ee3516b1..5bf7cb3c94 100644 --- a/panda/src/event/asyncFuture_ext.cxx +++ b/panda/src/event/asyncFuture_ext.cxx @@ -168,14 +168,7 @@ static PyObject *gen_next(PyObject *self) { */ PyObject *Extension:: __await__(PyObject *self) { - Dtool_GeneratorWrapper *gen; - gen = (Dtool_GeneratorWrapper *)PyType_GenericAlloc(&Dtool_GeneratorWrapper_Type, 0); - if (gen != nullptr) { - Py_INCREF(self); - gen->_base._self = self; - gen->_iternext_func = &gen_next; - } - return (PyObject *)gen; + return Dtool_NewGenerator(self, &gen_next); } /** From 82459fa21b47e89a301f5d7e394d868bb254f503 Mon Sep 17 00:00:00 2001 From: rdb Date: Tue, 6 Nov 2018 17:22:41 +0100 Subject: [PATCH 20/26] ode: remove dependency on Python.h from odeBody.h --- panda/src/ode/odeBody.I | 4 +-- panda/src/ode/odeBody.cxx | 27 +++---------------- panda/src/ode/odeBody.h | 15 ++++++----- panda/src/ode/odeBody_ext.I | 13 ++++++++++ panda/src/ode/odeBody_ext.cxx | 37 +++++++++++++++++++++++++++ panda/src/ode/odeBody_ext.h | 3 +++ panda/src/ode/p3ode_ext_composite.cxx | 1 + 7 files changed, 67 insertions(+), 33 deletions(-) create mode 100644 panda/src/ode/odeBody_ext.cxx diff --git a/panda/src/ode/odeBody.I b/panda/src/ode/odeBody.I index ab241fb455..72ecafd754 100644 --- a/panda/src/ode/odeBody.I +++ b/panda/src/ode/odeBody.I @@ -89,12 +89,10 @@ set_data(void *data) { dBodySetData(_id, data); } -#ifndef HAVE_PYTHON -INLINE void* OdeBody:: +INLINE void *OdeBody:: get_data() const { return dBodyGetData(_id); } -#endif INLINE void OdeBody:: set_position(dReal x, dReal y, dReal z) { diff --git a/panda/src/ode/odeBody.cxx b/panda/src/ode/odeBody.cxx index 70ad46169d..3f8e5d671a 100644 --- a/panda/src/ode/odeBody.cxx +++ b/panda/src/ode/odeBody.cxx @@ -15,10 +15,6 @@ #include "odeBody.h" #include "odeJoint.h" -#ifdef HAVE_PYTHON -#include "py_panda.h" -#endif - TypeHandle OdeBody::_type_handle; OdeBody:: @@ -38,29 +34,14 @@ OdeBody:: void OdeBody:: destroy() { -#ifdef HAVE_PYTHON - Py_XDECREF((PyObject*) dBodyGetData(_id)); -#endif + if (_destroy_callback != nullptr) { + _destroy_callback(*this); + _destroy_callback = nullptr; + } nassertv(_id); dBodyDestroy(_id); } -#ifdef HAVE_PYTHON -void OdeBody:: -set_data(PyObject *data) { - Py_XDECREF((PyObject*) dBodyGetData(_id)); - Py_XINCREF(data); - dBodySetData(_id, data); -} - -PyObject* OdeBody:: -get_data() const { - PyObject* data = (PyObject*) dBodyGetData(_id); - Py_XINCREF(data); - return data; -} -#endif - OdeJoint OdeBody:: get_joint(int index) const { nassertr(_id != nullptr, OdeJoint(nullptr)); diff --git a/panda/src/ode/odeBody.h b/panda/src/ode/odeBody.h index 8e27dd8802..f1cd9dae68 100644 --- a/panda/src/ode/odeBody.h +++ b/panda/src/ode/odeBody.h @@ -51,9 +51,7 @@ PUBLISHED: INLINE void set_auto_disable_flag(int do_auto_disable); INLINE void set_auto_disable_defaults(); INLINE void set_data(void *data); -#ifdef HAVE_PYTHON - void set_data(PyObject *data); -#endif + EXTENSION(void set_data(PyObject *data)); INLINE void set_position(dReal x, dReal y, dReal z); INLINE void set_position(const LVecBase3f &pos); @@ -71,11 +69,10 @@ PUBLISHED: INLINE int get_auto_disable_steps() const; INLINE dReal get_auto_disable_time() const; INLINE int get_auto_disable_flag() const; -#ifdef HAVE_PYTHON - PyObject* get_data() const; -#else - INLINE void* get_data() const; +#ifndef CPPPARSER + INLINE void *get_data() const; #endif + EXTENSION(PyObject *get_data() const); INLINE LVecBase3f get_position() const; INLINE LMatrix3f get_rotation() const; @@ -150,6 +147,10 @@ PUBLISHED: private: dBodyID _id; +public: + typedef void (*DestroyCallback)(OdeBody &body); + DestroyCallback _destroy_callback = nullptr; + public: static TypeHandle get_class_type() { return _type_handle; diff --git a/panda/src/ode/odeBody_ext.I b/panda/src/ode/odeBody_ext.I index a26eba5b41..5535b900dd 100644 --- a/panda/src/ode/odeBody_ext.I +++ b/panda/src/ode/odeBody_ext.I @@ -13,6 +13,19 @@ #include "odeJoint_ext.h" +/** + * Returns the custom data associated with the OdeBody. + */ +INLINE PyObject *Extension:: +get_data() const { + PyObject *data = (PyObject *)_this->get_data(); + if (data == nullptr) { + data = Py_None; + } + Py_INCREF(data); + return data; +} + /** * Equivalent to get_joint().convert() */ diff --git a/panda/src/ode/odeBody_ext.cxx b/panda/src/ode/odeBody_ext.cxx new file mode 100644 index 0000000000..59361c5fa1 --- /dev/null +++ b/panda/src/ode/odeBody_ext.cxx @@ -0,0 +1,37 @@ +/** + * PANDA 3D SOFTWARE + * Copyright (c) Carnegie Mellon University. All rights reserved. + * + * All use of this software is subject to the terms of the revised BSD + * license. You should have received a copy of this license along + * with this source code in a file named "LICENSE." + * + * @file odeBody_ext.cxx + * @author rdb + * @date 2018-11-06 + */ + +#include "odeBody_ext.h" + +static void destroy_callback(OdeBody &body) { + Py_XDECREF((PyObject *)body.get_data()); +} + +/** + * Sets custom data to be associated with the OdeBody. + */ +void Extension:: +set_data(PyObject *data) { + void *old_data = _this->get_data(); + + if (data != nullptr && data != Py_None) { + Py_INCREF(data); + _this->set_data((void *)data); + _this->_destroy_callback = &destroy_callback; + } else { + _this->set_data(nullptr); + _this->_destroy_callback = nullptr; + } + + Py_XDECREF((PyObject *)old_data); +} diff --git a/panda/src/ode/odeBody_ext.h b/panda/src/ode/odeBody_ext.h index 04c2244324..125c7fe509 100644 --- a/panda/src/ode/odeBody_ext.h +++ b/panda/src/ode/odeBody_ext.h @@ -30,6 +30,9 @@ template<> class Extension : public ExtensionBase { public: + void set_data(PyObject *); + INLINE PyObject *get_data() const; + INLINE PyObject *get_converted_joint(int i) const; }; diff --git a/panda/src/ode/p3ode_ext_composite.cxx b/panda/src/ode/p3ode_ext_composite.cxx index 02ebaec64c..ac054bdc49 100644 --- a/panda/src/ode/p3ode_ext_composite.cxx +++ b/panda/src/ode/p3ode_ext_composite.cxx @@ -1,3 +1,4 @@ +#include "odeBody_ext.cxx" #include "odeGeom_ext.cxx" #include "odeJoint_ext.cxx" #include "odeSpace_ext.cxx" From f43bd1a40962b07b543b0fc9835435b71c7743fa Mon Sep 17 00:00:00 2001 From: rdb Date: Tue, 6 Nov 2018 18:08:48 +0100 Subject: [PATCH 21/26] gobj: remove use of PY_MAJOR_VERSION in internalName.h We should not use this symbol in the interrogated headers as it means we cannot reuse the output of interrogate with different versions of Python. --- panda/src/gobj/internalName.h | 6 +----- panda/src/gobj/internalName_ext.cxx | 14 ++++++++++++-- panda/src/gobj/internalName_ext.h | 6 +----- 3 files changed, 14 insertions(+), 12 deletions(-) diff --git a/panda/src/gobj/internalName.h b/panda/src/gobj/internalName.h index 729ec15ab8..5e61e81916 100644 --- a/panda/src/gobj/internalName.h +++ b/panda/src/gobj/internalName.h @@ -96,11 +96,7 @@ PUBLISHED: #ifdef HAVE_PYTHON // These versions are exposed to Python, which have additional logic to map // from Python interned strings. -#if PY_MAJOR_VERSION >= 3 - EXTENSION(static PT(InternalName) make(PyUnicodeObject *str)); -#else - EXTENSION(static PT(InternalName) make(PyStringObject *str)); -#endif + EXTENSION(static PT(InternalName) make(PyObject *str)); #endif public: diff --git a/panda/src/gobj/internalName_ext.cxx b/panda/src/gobj/internalName_ext.cxx index f1cdf0a725..4821880677 100644 --- a/panda/src/gobj/internalName_ext.cxx +++ b/panda/src/gobj/internalName_ext.cxx @@ -24,7 +24,12 @@ using std::string; */ #if PY_MAJOR_VERSION >= 3 PT(InternalName) Extension:: -make(PyUnicodeObject *str) { +make(PyObject *str) { + if (!PyUnicode_Check(str)) { + Dtool_Raise_ArgTypeError(str, 0, "InternalName.make", "str"); + return nullptr; + } + if (!PyUnicode_CHECK_INTERNED(str)) { // Not an interned string; don't bother. Py_ssize_t len = 0; @@ -50,7 +55,12 @@ make(PyUnicodeObject *str) { #else PT(InternalName) Extension:: -make(PyStringObject *str) { +make(PyObject *str) { + if (!PyString_Check(str)) { + Dtool_Raise_ArgTypeError(str, 0, "InternalName.make", "str"); + return nullptr; + } + if (!PyString_CHECK_INTERNED(str)) { // Not an interned string; don't bother. string name(PyString_AS_STRING(str), PyString_GET_SIZE(str)); diff --git a/panda/src/gobj/internalName_ext.h b/panda/src/gobj/internalName_ext.h index 20016abd60..8637eae16e 100644 --- a/panda/src/gobj/internalName_ext.h +++ b/panda/src/gobj/internalName_ext.h @@ -29,11 +29,7 @@ template<> class Extension : public ExtensionBase { public: -#if PY_MAJOR_VERSION >= 3 - static PT(InternalName) make(PyUnicodeObject *str); -#else - static PT(InternalName) make(PyStringObject *str); -#endif + static PT(InternalName) make(PyObject *str); }; #endif // HAVE_PYTHON From 995ba28650e6f1e346552a4a6e8894f69006bf20 Mon Sep 17 00:00:00 2001 From: rdb Date: Tue, 6 Nov 2018 18:43:51 +0100 Subject: [PATCH 22/26] makepanda: allow building multiple Python versions in one built dir This is done by adding a PyTargetAdd function, which builds the target into a Python ABI-specific temporary directory, allowing multiple Python versions to be built into the same built dir side-by-side. This could greatly speed up buildbot builds. It also paves the way for building multiple Python versions in the same makepanda call / installer by changing PyTargetAdd to add one target per enabled Python version. --- makepanda/installer.nsi | 21 +- makepanda/installpanda.py | 7 +- makepanda/makepanda.py | 798 +++++++++++++++++-------------------- makepanda/makepandacore.py | 95 ++++- makepanda/makewheel.py | 2 +- 5 files changed, 473 insertions(+), 450 deletions(-) diff --git a/makepanda/installer.nsi b/makepanda/installer.nsi index 1dab5196da..7b1d6ea25e 100644 --- a/makepanda/installer.nsi +++ b/makepanda/installer.nsi @@ -331,13 +331,24 @@ SectionGroup "Python support" SetOutPath $INSTDIR\panda3d File /r "${BUILT}\panda3d\*.py" - File /r /x bullet.pyd /x ode.pyd /x physx.pyd /x rocket.pyd "${BUILT}\panda3d\*.pyd" + File /nonfatal /r "${BUILT}\panda3d\core${EXT_SUFFIX}" + File /nonfatal /r "${BUILT}\panda3d\ai${EXT_SUFFIX}" + File /nonfatal /r "${BUILT}\panda3d\awesomium${EXT_SUFFIX}" + File /nonfatal /r "${BUILT}\panda3d\direct${EXT_SUFFIX}" + File /nonfatal /r "${BUILT}\panda3d\egg${EXT_SUFFIX}" + File /nonfatal /r "${BUILT}\panda3d\fx${EXT_SUFFIX}" + File /nonfatal /r "${BUILT}\panda3d\interrogatedb${EXT_SUFFIX}" + File /nonfatal /r "${BUILT}\panda3d\physics${EXT_SUFFIX}" + File /nonfatal /r "${BUILT}\panda3d\_rplight${EXT_SUFFIX}" + File /nonfatal /r "${BUILT}\panda3d\skel${EXT_SUFFIX}" + File /nonfatal /r "${BUILT}\panda3d\vision${EXT_SUFFIX}" + File /nonfatal /r "${BUILT}\panda3d\vrpn${EXT_SUFFIX}" !ifdef HAVE_BULLET SectionGetFlags ${SecBullet} $R0 IntOp $R0 $R0 & ${SF_SELECTED} StrCmp $R0 ${SF_SELECTED} 0 SkipBulletPyd - File /nonfatal /r "${BUILT}\panda3d\bullet.pyd" + File /nonfatal /r "${BUILT}\panda3d\bullet${EXT_SUFFIX}" SkipBulletPyd: !endif @@ -345,7 +356,7 @@ SectionGroup "Python support" SectionGetFlags ${SecODE} $R0 IntOp $R0 $R0 & ${SF_SELECTED} StrCmp $R0 ${SF_SELECTED} 0 SkipODEPyd - File /nonfatal /r "${BUILT}\panda3d\ode.pyd" + File /nonfatal /r "${BUILT}\panda3d\ode${EXT_SUFFIX}" SkipODEPyd: !endif @@ -353,7 +364,7 @@ SectionGroup "Python support" SectionGetFlags ${SecPhysX} $R0 IntOp $R0 $R0 & ${SF_SELECTED} StrCmp $R0 ${SF_SELECTED} 0 SkipPhysXPyd - File /nonfatal /r "${BUILT}\panda3d\physx.pyd" + File /nonfatal /r "${BUILT}\panda3d\physx${EXT_SUFFIX}" SkipPhysXPyd: !endif @@ -361,7 +372,7 @@ SectionGroup "Python support" SectionGetFlags ${SecRocket} $R0 IntOp $R0 $R0 & ${SF_SELECTED} StrCmp $R0 ${SF_SELECTED} 0 SkipRocketPyd - File /nonfatal /r "${BUILT}\panda3d\rocket.pyd" + File /nonfatal /r "${BUILT}\panda3d\rocket${EXT_SUFFIX}" SkipRocketPyd: !endif diff --git a/makepanda/installpanda.py b/makepanda/installpanda.py index 63a4601ee6..410847efc7 100644 --- a/makepanda/installpanda.py +++ b/makepanda/installpanda.py @@ -175,6 +175,7 @@ def InstallPanda(destdir="", prefix="/usr", outputdir="built", libdir=GetLibDir( oscmd("mkdir -m 0755 -p "+destdir+prefix+"/share/applications") oscmd("mkdir -m 0755 -p "+destdir+libdir+"/panda3d") oscmd("mkdir -m 0755 -p "+destdir+PPATH) + oscmd("mkdir -m 0755 -p "+destdir+PPATH+"/panda3d") if (sys.platform.startswith("freebsd")): oscmd("mkdir -m 0755 -p "+destdir+prefix+"/etc") @@ -194,13 +195,17 @@ def InstallPanda(destdir="", prefix="/usr", outputdir="built", libdir=GetLibDir( oscmd("cp -R "+outputdir+"/include "+destdir+prefix+"/include/panda3d") oscmd("cp -R "+outputdir+"/pandac "+destdir+prefix+"/share/panda3d/") - oscmd("cp -R "+outputdir+"/panda3d "+destdir+PPATH+"/") oscmd("cp -R "+outputdir+"/models "+destdir+prefix+"/share/panda3d/") if os.path.isdir("samples"): oscmd("cp -R samples "+destdir+prefix+"/share/panda3d/") if os.path.isdir(outputdir+"/direct"): oscmd("cp -R "+outputdir+"/direct "+destdir+prefix+"/share/panda3d/") if os.path.isdir(outputdir+"/Pmw"): oscmd("cp -R "+outputdir+"/Pmw "+destdir+prefix+"/share/panda3d/") if os.path.isdir(outputdir+"/plugins"): oscmd("cp -R "+outputdir+"/plugins "+destdir+prefix+"/share/panda3d/") + suffix = GetExtensionSuffix() + for base in os.listdir(outputdir + "/panda3d"): + if base.endswith(".py") or (base.endswith(suffix) and '.' not in base[:-len(suffix)]): + oscmd("cp "+outputdir+"/panda3d/"+base+" "+destdir+PPATH+"/panda3d/"+base) + WriteMimeFile(destdir+prefix+"/share/mime-info/panda3d.mime", MIME_INFO) WriteKeysFile(destdir+prefix+"/share/mime-info/panda3d.keys", MIME_INFO) WriteMimeXMLFile(destdir+prefix+"/share/mime/packages/panda3d.xml", MIME_INFO) diff --git a/makepanda/makepanda.py b/makepanda/makepanda.py index eae006b2ec..2689205461 100755 --- a/makepanda/makepanda.py +++ b/makepanda/makepanda.py @@ -1448,7 +1448,6 @@ def CompileFlex(wobj,wsrc,opts): def CompileIgate(woutd,wsrc,opts): outbase = os.path.basename(woutd)[:-3] woutc = GetOutputDir()+"/tmp/"+outbase+"_igate.cxx" - wobj = FindLocation(outbase + "_igate.obj", []) srcdir = GetValueOption(opts, "SRCDIR:") module = GetValueOption(opts, "IMOD:") library = GetValueOption(opts, "ILIB:") @@ -1457,7 +1456,7 @@ def CompileIgate(woutd,wsrc,opts): WriteFile(woutc, "") WriteFile(woutd, "") ConditionalWriteFile(woutd, "") - return (wobj, woutc, opts) + return if not CrossCompiling(): # If we're compiling for this platform, we can use the one we've built. @@ -1524,8 +1523,6 @@ def CompileIgate(woutd,wsrc,opts): cmd += ' ' + BracketNameWithQuotes(os.path.basename(x)) oscmd(cmd) - return (wobj, woutc, opts) - ######################################################################## ## ## CompileImod @@ -2198,9 +2195,7 @@ def CompileAnything(target, inputs, opts, progress = None): return CompileLink(target, inputs, opts) elif (origsuffix==".in"): ProgressOutput(progress, "Building Interrogate database", target) - args = CompileIgate(target, inputs, opts) - ProgressOutput(progress, "Building C++ object", args[0]) - return CompileCxx(*args) + return CompileIgate(target, inputs, opts) elif (origsuffix==".plugin" and GetTarget() == "darwin"): ProgressOutput(progress, "Building plugin bundle", target) return CompileBundle(target, inputs, opts) @@ -3450,16 +3445,14 @@ TargetAdd('libp3interrogatedb.dll', input='p3interrogatedb_composite2.obj') TargetAdd('libp3interrogatedb.dll', input='libp3dtool.dll') TargetAdd('libp3interrogatedb.dll', input='libp3dtoolconfig.dll') -if not PkgSkip("PYTHON"): - # This used to be called dtoolconfig.pyd, but it just contains the interrogatedb - # stuff, so it has been renamed appropriately. - OPTS=['DIR:dtool/metalibs/dtoolconfig', 'PYTHON'] - TargetAdd('interrogatedb_pydtool.obj', opts=OPTS, input="pydtool.cxx") - TargetAdd('interrogatedb.pyd', input='interrogatedb_pydtool.obj') - TargetAdd('interrogatedb.pyd', input='libp3dtool.dll') - TargetAdd('interrogatedb.pyd', input='libp3dtoolconfig.dll') - TargetAdd('interrogatedb.pyd', input='libp3interrogatedb.dll') - TargetAdd('interrogatedb.pyd', opts=['PYTHON']) +# This used to be called dtoolconfig.pyd, but it just contains the interrogatedb +# stuff, so it has been renamed appropriately. +OPTS=['DIR:dtool/metalibs/dtoolconfig'] +PyTargetAdd('interrogatedb_pydtool.obj', opts=OPTS, input="pydtool.cxx") +PyTargetAdd('interrogatedb.pyd', input='interrogatedb_pydtool.obj') +PyTargetAdd('interrogatedb.pyd', input='libp3dtool.dll') +PyTargetAdd('interrogatedb.pyd', input='libp3dtoolconfig.dll') +PyTargetAdd('interrogatedb.pyd', input='libp3interrogatedb.dll') # # DIRECTORY: dtool/src/pystub/ @@ -3541,7 +3534,7 @@ if (not RTDIST and not RUNTIME): # DIRECTORY: dtool/src/dtoolbase/ # -OPTS=['DIR:dtool/src/dtoolbase', 'PYTHON'] +OPTS=['DIR:dtool/src/dtoolbase'] IGATEFILES=GetDirectoryContents('dtool/src/dtoolbase', ["*_composite*.cxx"]) IGATEFILES += [ "typeHandle.h", @@ -3552,14 +3545,13 @@ IGATEFILES += [ ] TargetAdd('libp3dtoolbase.in', opts=OPTS, input=IGATEFILES) TargetAdd('libp3dtoolbase.in', opts=['IMOD:panda3d.core', 'ILIB:libp3dtoolbase', 'SRCDIR:dtool/src/dtoolbase']) -TargetAdd('libp3dtoolbase_igate.obj', input='libp3dtoolbase.in', opts=["DEPENDENCYONLY"]) -TargetAdd('p3dtoolbase_typeHandle_ext.obj', opts=OPTS, input='typeHandle_ext.cxx') +PyTargetAdd('p3dtoolbase_typeHandle_ext.obj', opts=OPTS, input='typeHandle_ext.cxx') # # DIRECTORY: dtool/src/dtoolutil/ # -OPTS=['DIR:dtool/src/dtoolutil', 'PYTHON'] +OPTS=['DIR:dtool/src/dtoolutil'] IGATEFILES=GetDirectoryContents('dtool/src/dtoolutil', ["*_composite*.cxx"]) IGATEFILES += [ "config_dtoolutil.h", @@ -3577,19 +3569,17 @@ IGATEFILES += [ ] TargetAdd('libp3dtoolutil.in', opts=OPTS, input=IGATEFILES) TargetAdd('libp3dtoolutil.in', opts=['IMOD:panda3d.core', 'ILIB:libp3dtoolutil', 'SRCDIR:dtool/src/dtoolutil']) -TargetAdd('libp3dtoolutil_igate.obj', input='libp3dtoolutil.in', opts=["DEPENDENCYONLY"]) -TargetAdd('p3dtoolutil_ext_composite.obj', opts=OPTS, input='p3dtoolutil_ext_composite.cxx') +PyTargetAdd('p3dtoolutil_ext_composite.obj', opts=OPTS, input='p3dtoolutil_ext_composite.cxx') # # DIRECTORY: dtool/src/prc/ # -OPTS=['DIR:dtool/src/prc', 'PYTHON'] +OPTS=['DIR:dtool/src/prc'] IGATEFILES=GetDirectoryContents('dtool/src/prc', ["*.h", "*_composite*.cxx"]) TargetAdd('libp3prc.in', opts=OPTS, input=IGATEFILES) TargetAdd('libp3prc.in', opts=['IMOD:panda3d.core', 'ILIB:libp3prc', 'SRCDIR:dtool/src/prc']) -TargetAdd('libp3prc_igate.obj', input='libp3prc.in', opts=["DEPENDENCYONLY"]) -TargetAdd('p3prc_ext_composite.obj', opts=OPTS, input='p3prc_ext_composite.cxx') +PyTargetAdd('p3prc_ext_composite.obj', opts=OPTS, input='p3prc_ext_composite.cxx') # # DIRECTORY: panda/src/pandabase/ @@ -3606,12 +3596,11 @@ OPTS=['DIR:panda/src/express', 'BUILDING:PANDAEXPRESS', 'OPENSSL', 'ZLIB'] TargetAdd('p3express_composite1.obj', opts=OPTS, input='p3express_composite1.cxx') TargetAdd('p3express_composite2.obj', opts=OPTS, input='p3express_composite2.cxx') -OPTS=['DIR:panda/src/express', 'OPENSSL', 'ZLIB', 'PYTHON'] +OPTS=['DIR:panda/src/express', 'OPENSSL', 'ZLIB'] IGATEFILES=GetDirectoryContents('panda/src/express', ["*.h", "*_composite*.cxx"]) TargetAdd('libp3express.in', opts=OPTS, input=IGATEFILES) TargetAdd('libp3express.in', opts=['IMOD:panda3d.core', 'ILIB:libp3express', 'SRCDIR:panda/src/express']) -TargetAdd('libp3express_igate.obj', input='libp3express.in', opts=["DEPENDENCYONLY"]) -TargetAdd('p3express_ext_composite.obj', opts=OPTS, input='p3express_ext_composite.cxx') +PyTargetAdd('p3express_ext_composite.obj', opts=OPTS, input='p3express_ext_composite.cxx') # # DIRECTORY: panda/src/downloader/ @@ -3621,12 +3610,11 @@ OPTS=['DIR:panda/src/downloader', 'BUILDING:PANDAEXPRESS', 'OPENSSL', 'ZLIB'] TargetAdd('p3downloader_composite1.obj', opts=OPTS, input='p3downloader_composite1.cxx') TargetAdd('p3downloader_composite2.obj', opts=OPTS, input='p3downloader_composite2.cxx') -OPTS=['DIR:panda/src/downloader', 'OPENSSL', 'ZLIB', 'PYTHON'] +OPTS=['DIR:panda/src/downloader', 'OPENSSL', 'ZLIB'] IGATEFILES=GetDirectoryContents('panda/src/downloader', ["*.h", "*_composite*.cxx"]) TargetAdd('libp3downloader.in', opts=OPTS, input=IGATEFILES) TargetAdd('libp3downloader.in', opts=['IMOD:panda3d.core', 'ILIB:libp3downloader', 'SRCDIR:panda/src/downloader']) -TargetAdd('libp3downloader_igate.obj', input='libp3downloader.in', opts=["DEPENDENCYONLY"]) -TargetAdd('p3downloader_stringStream_ext.obj', opts=OPTS, input='stringStream_ext.cxx') +PyTargetAdd('p3downloader_stringStream_ext.obj', opts=OPTS, input='stringStream_ext.cxx') # # DIRECTORY: panda/metalibs/pandaexpress/ @@ -3653,12 +3641,11 @@ if (not RUNTIME): TargetAdd('p3pipeline_composite2.obj', opts=OPTS, input='p3pipeline_composite2.cxx') TargetAdd('p3pipeline_contextSwitch.obj', opts=OPTS, input='contextSwitch.c') - OPTS=['DIR:panda/src/pipeline', 'PYTHON'] + OPTS=['DIR:panda/src/pipeline'] IGATEFILES=GetDirectoryContents('panda/src/pipeline', ["*.h", "*_composite*.cxx"]) TargetAdd('libp3pipeline.in', opts=OPTS, input=IGATEFILES) TargetAdd('libp3pipeline.in', opts=['IMOD:panda3d.core', 'ILIB:libp3pipeline', 'SRCDIR:panda/src/pipeline']) - TargetAdd('libp3pipeline_igate.obj', input='libp3pipeline.in', opts=["DEPENDENCYONLY"]) - TargetAdd('p3pipeline_pythonThread.obj', opts=OPTS, input='pythonThread.cxx') + PyTargetAdd('p3pipeline_pythonThread.obj', opts=OPTS, input='pythonThread.cxx') # # DIRECTORY: panda/src/linmath/ @@ -3669,7 +3656,7 @@ if (not RUNTIME): TargetAdd('p3linmath_composite1.obj', opts=OPTS, input='p3linmath_composite1.cxx') TargetAdd('p3linmath_composite2.obj', opts=OPTS, input='p3linmath_composite2.cxx') - OPTS=['DIR:panda/src/linmath', 'PYTHON'] + OPTS=['DIR:panda/src/linmath'] IGATEFILES=GetDirectoryContents('panda/src/linmath', ["*.h", "*_composite*.cxx"]) for ifile in IGATEFILES[:]: if "_src." in ifile: @@ -3679,7 +3666,6 @@ if (not RUNTIME): IGATEFILES.remove('cast_to_float.h') TargetAdd('libp3linmath.in', opts=OPTS, input=IGATEFILES) TargetAdd('libp3linmath.in', opts=['IMOD:panda3d.core', 'ILIB:libp3linmath', 'SRCDIR:panda/src/linmath']) - TargetAdd('libp3linmath_igate.obj', input='libp3linmath.in', opts=["DEPENDENCYONLY"]) # # DIRECTORY: panda/src/putil/ @@ -3690,14 +3676,13 @@ if (not RUNTIME): TargetAdd('p3putil_composite1.obj', opts=OPTS, input='p3putil_composite1.cxx') TargetAdd('p3putil_composite2.obj', opts=OPTS, input='p3putil_composite2.cxx') - OPTS=['DIR:panda/src/putil', 'ZLIB', 'PYTHON'] + OPTS=['DIR:panda/src/putil', 'ZLIB'] IGATEFILES=GetDirectoryContents('panda/src/putil', ["*.h", "*_composite*.cxx"]) IGATEFILES.remove("test_bam.h") IGATEFILES.remove("config_util.h") TargetAdd('libp3putil.in', opts=OPTS, input=IGATEFILES) TargetAdd('libp3putil.in', opts=['IMOD:panda3d.core', 'ILIB:libp3putil', 'SRCDIR:panda/src/putil']) - TargetAdd('libp3putil_igate.obj', input='libp3putil.in', opts=["DEPENDENCYONLY"]) - TargetAdd('p3putil_ext_composite.obj', opts=OPTS, input='p3putil_ext_composite.cxx') + PyTargetAdd('p3putil_ext_composite.obj', opts=OPTS, input='p3putil_ext_composite.cxx') # # DIRECTORY: panda/src/audio/ @@ -3707,11 +3692,10 @@ if (not RUNTIME): OPTS=['DIR:panda/src/audio', 'BUILDING:PANDA'] TargetAdd('p3audio_composite1.obj', opts=OPTS, input='p3audio_composite1.cxx') - OPTS=['DIR:panda/src/audio', 'PYTHON'] + OPTS=['DIR:panda/src/audio'] IGATEFILES=["audio.h"] TargetAdd('libp3audio.in', opts=OPTS, input=IGATEFILES) TargetAdd('libp3audio.in', opts=['IMOD:panda3d.core', 'ILIB:libp3audio', 'SRCDIR:panda/src/audio']) - TargetAdd('libp3audio_igate.obj', input='libp3audio.in', opts=["DEPENDENCYONLY"]) # # DIRECTORY: panda/src/event/ @@ -3722,13 +3706,12 @@ if (not RUNTIME): TargetAdd('p3event_composite1.obj', opts=OPTS, input='p3event_composite1.cxx') TargetAdd('p3event_composite2.obj', opts=OPTS, input='p3event_composite2.cxx') - OPTS=['DIR:panda/src/event', 'PYTHON'] - TargetAdd('p3event_asyncFuture_ext.obj', opts=OPTS, input='asyncFuture_ext.cxx') - TargetAdd('p3event_pythonTask.obj', opts=OPTS, input='pythonTask.cxx') + OPTS=['DIR:panda/src/event'] + PyTargetAdd('p3event_asyncFuture_ext.obj', opts=OPTS, input='asyncFuture_ext.cxx') + PyTargetAdd('p3event_pythonTask.obj', opts=OPTS, input='pythonTask.cxx') IGATEFILES=GetDirectoryContents('panda/src/event', ["*.h", "*_composite*.cxx"]) TargetAdd('libp3event.in', opts=OPTS, input=IGATEFILES) TargetAdd('libp3event.in', opts=['IMOD:panda3d.core', 'ILIB:libp3event', 'SRCDIR:panda/src/event']) - TargetAdd('libp3event_igate.obj', input='libp3event.in', opts=["DEPENDENCYONLY"]) # # DIRECTORY: panda/src/mathutil/ @@ -3739,14 +3722,13 @@ if (not RUNTIME): TargetAdd('p3mathutil_composite1.obj', opts=OPTS, input='p3mathutil_composite1.cxx') TargetAdd('p3mathutil_composite2.obj', opts=OPTS, input='p3mathutil_composite2.cxx') - OPTS=['DIR:panda/src/mathutil', 'FFTW', 'PYTHON'] + OPTS=['DIR:panda/src/mathutil', 'FFTW'] IGATEFILES=GetDirectoryContents('panda/src/mathutil', ["*.h", "*_composite*.cxx"]) for ifile in IGATEFILES[:]: if "_src." in ifile: IGATEFILES.remove(ifile) TargetAdd('libp3mathutil.in', opts=OPTS, input=IGATEFILES) TargetAdd('libp3mathutil.in', opts=['IMOD:panda3d.core', 'ILIB:libp3mathutil', 'SRCDIR:panda/src/mathutil']) - TargetAdd('libp3mathutil_igate.obj', input='libp3mathutil.in', opts=["DEPENDENCYONLY"]) # # DIRECTORY: panda/src/gsgbase/ @@ -3756,11 +3738,10 @@ if (not RUNTIME): OPTS=['DIR:panda/src/gsgbase', 'BUILDING:PANDA'] TargetAdd('p3gsgbase_composite1.obj', opts=OPTS, input='p3gsgbase_composite1.cxx') - OPTS=['DIR:panda/src/gsgbase', 'PYTHON'] + OPTS=['DIR:panda/src/gsgbase'] IGATEFILES=GetDirectoryContents('panda/src/gsgbase', ["*.h", "*_composite*.cxx"]) TargetAdd('libp3gsgbase.in', opts=OPTS, input=IGATEFILES) TargetAdd('libp3gsgbase.in', opts=['IMOD:panda3d.core', 'ILIB:libp3gsgbase', 'SRCDIR:panda/src/gsgbase']) - TargetAdd('libp3gsgbase_igate.obj', input='libp3gsgbase.in', opts=["DEPENDENCYONLY"]) # # DIRECTORY: panda/src/pnmimage/ @@ -3772,12 +3753,11 @@ if (not RUNTIME): TargetAdd('p3pnmimage_composite2.obj', opts=OPTS, input='p3pnmimage_composite2.cxx') TargetAdd('p3pnmimage_convert_srgb_sse2.obj', opts=OPTS+['SSE2'], input='convert_srgb_sse2.cxx') - OPTS=['DIR:panda/src/pnmimage', 'ZLIB', 'PYTHON'] + OPTS=['DIR:panda/src/pnmimage', 'ZLIB'] IGATEFILES=GetDirectoryContents('panda/src/pnmimage', ["*.h", "*_composite*.cxx"]) TargetAdd('libp3pnmimage.in', opts=OPTS, input=IGATEFILES) TargetAdd('libp3pnmimage.in', opts=['IMOD:panda3d.core', 'ILIB:libp3pnmimage', 'SRCDIR:panda/src/pnmimage']) - TargetAdd('libp3pnmimage_igate.obj', input='libp3pnmimage.in', opts=["DEPENDENCYONLY"]) - TargetAdd('p3pnmimage_pfmFile_ext.obj', opts=OPTS, input='pfmFile_ext.cxx') + PyTargetAdd('p3pnmimage_pfmFile_ext.obj', opts=OPTS, input='pfmFile_ext.cxx') # # DIRECTORY: panda/src/nativenet/ @@ -3787,11 +3767,10 @@ if (not RUNTIME): OPTS=['DIR:panda/src/nativenet', 'OPENSSL', 'BUILDING:PANDA'] TargetAdd('p3nativenet_composite1.obj', opts=OPTS, input='p3nativenet_composite1.cxx') - OPTS=['DIR:panda/src/nativenet', 'OPENSSL', 'PYTHON'] + OPTS=['DIR:panda/src/nativenet', 'OPENSSL'] IGATEFILES=GetDirectoryContents('panda/src/nativenet', ["*.h", "*_composite*.cxx"]) TargetAdd('libp3nativenet.in', opts=OPTS, input=IGATEFILES) TargetAdd('libp3nativenet.in', opts=['IMOD:panda3d.core', 'ILIB:libp3nativenet', 'SRCDIR:panda/src/nativenet']) - TargetAdd('libp3nativenet_igate.obj', input='libp3nativenet.in', opts=["DEPENDENCYONLY"]) # # DIRECTORY: panda/src/net/ @@ -3802,12 +3781,11 @@ if (not RUNTIME): TargetAdd('p3net_composite1.obj', opts=OPTS, input='p3net_composite1.cxx') TargetAdd('p3net_composite2.obj', opts=OPTS, input='p3net_composite2.cxx') - OPTS=['DIR:panda/src/net', 'PYTHON'] + OPTS=['DIR:panda/src/net'] IGATEFILES=GetDirectoryContents('panda/src/net', ["*.h", "*_composite*.cxx"]) IGATEFILES.remove("datagram_ui.h") TargetAdd('libp3net.in', opts=OPTS, input=IGATEFILES) TargetAdd('libp3net.in', opts=['IMOD:panda3d.core', 'ILIB:libp3net', 'SRCDIR:panda/src/net']) - TargetAdd('libp3net_igate.obj', input='libp3net.in', opts=["DEPENDENCYONLY"]) # # DIRECTORY: panda/src/pstatclient/ @@ -3818,12 +3796,11 @@ if (not RUNTIME): TargetAdd('p3pstatclient_composite1.obj', opts=OPTS, input='p3pstatclient_composite1.cxx') TargetAdd('p3pstatclient_composite2.obj', opts=OPTS, input='p3pstatclient_composite2.cxx') - OPTS=['DIR:panda/src/pstatclient', 'PYTHON'] + OPTS=['DIR:panda/src/pstatclient'] IGATEFILES=GetDirectoryContents('panda/src/pstatclient', ["*.h", "*_composite*.cxx"]) IGATEFILES.remove("config_pstats.h") TargetAdd('libp3pstatclient.in', opts=OPTS, input=IGATEFILES) TargetAdd('libp3pstatclient.in', opts=['IMOD:panda3d.core', 'ILIB:libp3pstatclient', 'SRCDIR:panda/src/pstatclient']) - TargetAdd('libp3pstatclient_igate.obj', input='libp3pstatclient.in', opts=["DEPENDENCYONLY"]) # # DIRECTORY: panda/src/gobj/ @@ -3834,13 +3811,12 @@ if (not RUNTIME): TargetAdd('p3gobj_composite1.obj', opts=OPTS, input='p3gobj_composite1.cxx') TargetAdd('p3gobj_composite2.obj', opts=OPTS+['BIGOBJ'], input='p3gobj_composite2.cxx') - OPTS=['DIR:panda/src/gobj', 'NVIDIACG', 'ZLIB', 'SQUISH', 'PYTHON'] + OPTS=['DIR:panda/src/gobj', 'NVIDIACG', 'ZLIB', 'SQUISH'] IGATEFILES=GetDirectoryContents('panda/src/gobj', ["*.h", "*_composite*.cxx"]) if ("cgfx_states.h" in IGATEFILES): IGATEFILES.remove("cgfx_states.h") TargetAdd('libp3gobj.in', opts=OPTS, input=IGATEFILES) TargetAdd('libp3gobj.in', opts=['IMOD:panda3d.core', 'ILIB:libp3gobj', 'SRCDIR:panda/src/gobj']) - TargetAdd('libp3gobj_igate.obj', input='libp3gobj.in', opts=["DEPENDENCYONLY"]) - TargetAdd('p3gobj_ext_composite.obj', opts=OPTS, input='p3gobj_ext_composite.cxx') + PyTargetAdd('p3gobj_ext_composite.obj', opts=OPTS, input='p3gobj_ext_composite.cxx') # # DIRECTORY: panda/src/pgraphnodes/ @@ -3851,11 +3827,10 @@ if (not RUNTIME): TargetAdd('p3pgraphnodes_composite1.obj', opts=OPTS, input='p3pgraphnodes_composite1.cxx') TargetAdd('p3pgraphnodes_composite2.obj', opts=OPTS, input='p3pgraphnodes_composite2.cxx') - OPTS=['DIR:panda/src/pgraphnodes', 'PYTHON'] + OPTS=['DIR:panda/src/pgraphnodes'] IGATEFILES=GetDirectoryContents('panda/src/pgraphnodes', ["*.h", "*_composite*.cxx"]) TargetAdd('libp3pgraphnodes.in', opts=OPTS, input=IGATEFILES) TargetAdd('libp3pgraphnodes.in', opts=['IMOD:panda3d.core', 'ILIB:libp3pgraphnodes', 'SRCDIR:panda/src/pgraphnodes']) - TargetAdd('libp3pgraphnodes_igate.obj', input='libp3pgraphnodes.in', opts=["DEPENDENCYONLY"]) # # DIRECTORY: panda/src/pgraph/ @@ -3869,12 +3844,11 @@ if (not RUNTIME): TargetAdd('p3pgraph_composite3.obj', opts=OPTS, input='p3pgraph_composite3.cxx') TargetAdd('p3pgraph_composite4.obj', opts=OPTS, input='p3pgraph_composite4.cxx') - OPTS=['DIR:panda/src/pgraph', 'PYTHON'] + OPTS=['DIR:panda/src/pgraph'] IGATEFILES=GetDirectoryContents('panda/src/pgraph', ["*.h", "nodePath.cxx", "*_composite*.cxx"]) TargetAdd('libp3pgraph.in', opts=OPTS, input=IGATEFILES) TargetAdd('libp3pgraph.in', opts=['IMOD:panda3d.core', 'ILIB:libp3pgraph', 'SRCDIR:panda/src/pgraph']) - TargetAdd('libp3pgraph_igate.obj', input='libp3pgraph.in', opts=["DEPENDENCYONLY","BIGOBJ"]) - TargetAdd('p3pgraph_ext_composite.obj', opts=OPTS, input='p3pgraph_ext_composite.cxx') + PyTargetAdd('p3pgraph_ext_composite.obj', opts=OPTS, input='p3pgraph_ext_composite.cxx') # # DIRECTORY: panda/src/cull/ @@ -3885,11 +3859,10 @@ if (not RUNTIME): TargetAdd('p3cull_composite1.obj', opts=OPTS, input='p3cull_composite1.cxx') TargetAdd('p3cull_composite2.obj', opts=OPTS, input='p3cull_composite2.cxx') - OPTS=['DIR:panda/src/cull', 'PYTHON'] + OPTS=['DIR:panda/src/cull'] IGATEFILES=GetDirectoryContents('panda/src/cull', ["*.h", "*_composite*.cxx"]) TargetAdd('libp3cull.in', opts=OPTS, input=IGATEFILES) TargetAdd('libp3cull.in', opts=['IMOD:panda3d.core', 'ILIB:libp3cull', 'SRCDIR:panda/src/cull']) - TargetAdd('libp3cull_igate.obj', input='libp3cull.in', opts=["DEPENDENCYONLY"]) # # DIRECTORY: panda/src/display/ @@ -3901,15 +3874,14 @@ if (not RUNTIME): TargetAdd('p3display_composite1.obj', opts=OPTS, input='p3display_composite1.cxx') TargetAdd('p3display_composite2.obj', opts=OPTS, input='p3display_composite2.cxx') - OPTS=['DIR:panda/src/display', 'PYTHON'] + OPTS=['DIR:panda/src/display'] IGATEFILES=GetDirectoryContents('panda/src/display', ["*.h", "*_composite*.cxx"]) IGATEFILES.remove("renderBuffer.h") TargetAdd('libp3display.in', opts=OPTS, input=IGATEFILES) TargetAdd('libp3display.in', opts=['IMOD:panda3d.core', 'ILIB:libp3display', 'SRCDIR:panda/src/display']) - TargetAdd('libp3display_igate.obj', input='libp3display.in', opts=["DEPENDENCYONLY"]) - TargetAdd('p3display_graphicsStateGuardian_ext.obj', opts=OPTS, input='graphicsStateGuardian_ext.cxx') - TargetAdd('p3display_graphicsWindow_ext.obj', opts=OPTS, input='graphicsWindow_ext.cxx') - TargetAdd('p3display_pythonGraphicsWindowProc.obj', opts=OPTS, input='pythonGraphicsWindowProc.cxx') + PyTargetAdd('p3display_graphicsStateGuardian_ext.obj', opts=OPTS, input='graphicsStateGuardian_ext.cxx') + PyTargetAdd('p3display_graphicsWindow_ext.obj', opts=OPTS, input='graphicsWindow_ext.cxx') + PyTargetAdd('p3display_pythonGraphicsWindowProc.obj', opts=OPTS, input='pythonGraphicsWindowProc.cxx') if RTDIST and GetTarget() == 'darwin': OPTS=['DIR:panda/src/display'] @@ -3925,13 +3897,12 @@ if (not RUNTIME): TargetAdd('p3chan_composite1.obj', opts=OPTS, input='p3chan_composite1.cxx') TargetAdd('p3chan_composite2.obj', opts=OPTS, input='p3chan_composite2.cxx') - OPTS=['DIR:panda/src/chan', 'PYTHON'] + OPTS=['DIR:panda/src/chan'] IGATEFILES=GetDirectoryContents('panda/src/chan', ["*.h", "*_composite*.cxx"]) IGATEFILES.remove('movingPart.h') IGATEFILES.remove('animChannelFixed.h') TargetAdd('libp3chan.in', opts=OPTS, input=IGATEFILES) TargetAdd('libp3chan.in', opts=['IMOD:panda3d.core', 'ILIB:libp3chan', 'SRCDIR:panda/src/chan']) - TargetAdd('libp3chan_igate.obj', input='libp3chan.in', opts=["DEPENDENCYONLY"]) # DIRECTORY: panda/src/char/ @@ -3942,11 +3913,10 @@ if (not RUNTIME): TargetAdd('p3char_composite1.obj', opts=OPTS, input='p3char_composite1.cxx') TargetAdd('p3char_composite2.obj', opts=OPTS, input='p3char_composite2.cxx') - OPTS=['DIR:panda/src/char', 'PYTHON'] + OPTS=['DIR:panda/src/char'] IGATEFILES=GetDirectoryContents('panda/src/char', ["*.h", "*_composite*.cxx"]) TargetAdd('libp3char.in', opts=OPTS, input=IGATEFILES) TargetAdd('libp3char.in', opts=['IMOD:panda3d.core', 'ILIB:libp3char', 'SRCDIR:panda/src/char']) - TargetAdd('libp3char_igate.obj', input='libp3char.in', opts=["DEPENDENCYONLY"]) # # DIRECTORY: panda/src/dgraph/ @@ -3957,11 +3927,10 @@ if (not RUNTIME): TargetAdd('p3dgraph_composite1.obj', opts=OPTS, input='p3dgraph_composite1.cxx') TargetAdd('p3dgraph_composite2.obj', opts=OPTS, input='p3dgraph_composite2.cxx') - OPTS=['DIR:panda/src/dgraph', 'PYTHON'] + OPTS=['DIR:panda/src/dgraph'] IGATEFILES=GetDirectoryContents('panda/src/dgraph', ["*.h", "*_composite*.cxx"]) TargetAdd('libp3dgraph.in', opts=OPTS, input=IGATEFILES) TargetAdd('libp3dgraph.in', opts=['IMOD:panda3d.core', 'ILIB:libp3dgraph', 'SRCDIR:panda/src/dgraph']) - TargetAdd('libp3dgraph_igate.obj', input='libp3dgraph.in', opts=["DEPENDENCYONLY"]) # # DIRECTORY: panda/src/device/ @@ -3972,11 +3941,10 @@ if (not RUNTIME): TargetAdd('p3device_composite1.obj', opts=OPTS, input='p3device_composite1.cxx') TargetAdd('p3device_composite2.obj', opts=OPTS, input='p3device_composite2.cxx') - OPTS=['DIR:panda/src/device', 'PYTHON'] + OPTS=['DIR:panda/src/device'] IGATEFILES=GetDirectoryContents('panda/src/device', ["*.h", "*_composite*.cxx"]) TargetAdd('libp3device.in', opts=OPTS, input=IGATEFILES) TargetAdd('libp3device.in', opts=['IMOD:panda3d.core', 'ILIB:libp3device', 'SRCDIR:panda/src/device']) - TargetAdd('libp3device_igate.obj', input='libp3device.in', opts=["DEPENDENCYONLY"]) # # DIRECTORY: panda/src/pnmtext/ @@ -3986,11 +3954,10 @@ if (PkgSkip("FREETYPE")==0 and not RUNTIME): OPTS=['DIR:panda/src/pnmtext', 'BUILDING:PANDA', 'FREETYPE'] TargetAdd('p3pnmtext_composite1.obj', opts=OPTS, input='p3pnmtext_composite1.cxx') - OPTS=['DIR:panda/src/pnmtext', 'FREETYPE', 'PYTHON'] + OPTS=['DIR:panda/src/pnmtext', 'FREETYPE'] IGATEFILES=GetDirectoryContents('panda/src/pnmtext', ["*.h", "*_composite*.cxx"]) TargetAdd('libp3pnmtext.in', opts=OPTS, input=IGATEFILES) TargetAdd('libp3pnmtext.in', opts=['IMOD:panda3d.core', 'ILIB:libp3pnmtext', 'SRCDIR:panda/src/pnmtext']) - TargetAdd('libp3pnmtext_igate.obj', input='libp3pnmtext.in', opts=["DEPENDENCYONLY"]) # # DIRECTORY: panda/src/text/ @@ -4004,11 +3971,10 @@ if (not RUNTIME): TargetAdd('p3text_composite1.obj', opts=OPTS, input='p3text_composite1.cxx') TargetAdd('p3text_composite2.obj', opts=OPTS, input='p3text_composite2.cxx') - OPTS=['DIR:panda/src/text', 'ZLIB', 'FREETYPE', 'PYTHON'] + OPTS=['DIR:panda/src/text', 'ZLIB', 'FREETYPE'] IGATEFILES=GetDirectoryContents('panda/src/text', ["*.h", "*_composite*.cxx"]) TargetAdd('libp3text.in', opts=OPTS, input=IGATEFILES) TargetAdd('libp3text.in', opts=['IMOD:panda3d.core', 'ILIB:libp3text', 'SRCDIR:panda/src/text']) - TargetAdd('libp3text_igate.obj', input='libp3text.in', opts=["DEPENDENCYONLY"]) # # DIRECTORY: panda/src/movies/ @@ -4018,11 +3984,10 @@ if (not RUNTIME): OPTS=['DIR:panda/src/movies', 'BUILDING:PANDA', 'VORBIS', 'OPUS'] TargetAdd('p3movies_composite1.obj', opts=OPTS, input='p3movies_composite1.cxx') - OPTS=['DIR:panda/src/movies', 'VORBIS', 'OPUS', 'PYTHON'] + OPTS=['DIR:panda/src/movies', 'VORBIS', 'OPUS'] IGATEFILES=GetDirectoryContents('panda/src/movies', ["*.h", "*_composite*.cxx"]) TargetAdd('libp3movies.in', opts=OPTS, input=IGATEFILES) TargetAdd('libp3movies.in', opts=['IMOD:panda3d.core', 'ILIB:libp3movies', 'SRCDIR:panda/src/movies']) - TargetAdd('libp3movies_igate.obj', input='libp3movies.in', opts=["DEPENDENCYONLY"]) # # DIRECTORY: panda/src/grutil/ @@ -4034,12 +3999,11 @@ if (not RUNTIME): TargetAdd('p3grutil_composite1.obj', opts=OPTS, input='p3grutil_composite1.cxx') TargetAdd('p3grutil_composite2.obj', opts=OPTS, input='p3grutil_composite2.cxx') - OPTS=['DIR:panda/src/grutil', 'PYTHON'] + OPTS=['DIR:panda/src/grutil'] IGATEFILES=GetDirectoryContents('panda/src/grutil', ["*.h", "*_composite*.cxx"]) if 'convexHull.h' in IGATEFILES: IGATEFILES.remove('convexHull.h') TargetAdd('libp3grutil.in', opts=OPTS, input=IGATEFILES) TargetAdd('libp3grutil.in', opts=['IMOD:panda3d.core', 'ILIB:libp3grutil', 'SRCDIR:panda/src/grutil']) - TargetAdd('libp3grutil_igate.obj', input='libp3grutil.in', opts=["DEPENDENCYONLY"]) # # DIRECTORY: panda/src/tform/ @@ -4050,11 +4014,10 @@ if (not RUNTIME): TargetAdd('p3tform_composite1.obj', opts=OPTS, input='p3tform_composite1.cxx') TargetAdd('p3tform_composite2.obj', opts=OPTS, input='p3tform_composite2.cxx') - OPTS=['DIR:panda/src/tform', 'PYTHON'] + OPTS=['DIR:panda/src/tform'] IGATEFILES=GetDirectoryContents('panda/src/tform', ["*.h", "*_composite*.cxx"]) TargetAdd('libp3tform.in', opts=OPTS, input=IGATEFILES) TargetAdd('libp3tform.in', opts=['IMOD:panda3d.core', 'ILIB:libp3tform', 'SRCDIR:panda/src/tform']) - TargetAdd('libp3tform_igate.obj', input='libp3tform.in', opts=["DEPENDENCYONLY"]) # # DIRECTORY: panda/src/collide/ @@ -4065,11 +4028,10 @@ if (not RUNTIME): TargetAdd('p3collide_composite1.obj', opts=OPTS, input='p3collide_composite1.cxx') TargetAdd('p3collide_composite2.obj', opts=OPTS, input='p3collide_composite2.cxx') - OPTS=['DIR:panda/src/collide', 'PYTHON'] + OPTS=['DIR:panda/src/collide'] IGATEFILES=GetDirectoryContents('panda/src/collide', ["*.h", "*_composite*.cxx"]) TargetAdd('libp3collide.in', opts=OPTS, input=IGATEFILES) TargetAdd('libp3collide.in', opts=['IMOD:panda3d.core', 'ILIB:libp3collide', 'SRCDIR:panda/src/collide']) - TargetAdd('libp3collide_igate.obj', input='libp3collide.in', opts=["DEPENDENCYONLY"]) # # DIRECTORY: panda/src/parametrics/ @@ -4080,11 +4042,10 @@ if (not RUNTIME): TargetAdd('p3parametrics_composite1.obj', opts=OPTS, input='p3parametrics_composite1.cxx') TargetAdd('p3parametrics_composite2.obj', opts=OPTS, input='p3parametrics_composite2.cxx') - OPTS=['DIR:panda/src/parametrics', 'PYTHON'] + OPTS=['DIR:panda/src/parametrics'] IGATEFILES=GetDirectoryContents('panda/src/parametrics', ["*.h", "*_composite*.cxx"]) TargetAdd('libp3parametrics.in', opts=OPTS, input=IGATEFILES) TargetAdd('libp3parametrics.in', opts=['IMOD:panda3d.core', 'ILIB:libp3parametrics', 'SRCDIR:panda/src/parametrics']) - TargetAdd('libp3parametrics_igate.obj', input='libp3parametrics.in', opts=["DEPENDENCYONLY"]) # # DIRECTORY: panda/src/pgui/ @@ -4095,11 +4056,10 @@ if (not RUNTIME): TargetAdd('p3pgui_composite1.obj', opts=OPTS, input='p3pgui_composite1.cxx') TargetAdd('p3pgui_composite2.obj', opts=OPTS, input='p3pgui_composite2.cxx') - OPTS=['DIR:panda/src/pgui', 'PYTHON'] + OPTS=['DIR:panda/src/pgui'] IGATEFILES=GetDirectoryContents('panda/src/pgui', ["*.h", "*_composite*.cxx"]) TargetAdd('libp3pgui.in', opts=OPTS, input=IGATEFILES) TargetAdd('libp3pgui.in', opts=['IMOD:panda3d.core', 'ILIB:libp3pgui', 'SRCDIR:panda/src/pgui']) - TargetAdd('libp3pgui_igate.obj', input='libp3pgui.in', opts=["DEPENDENCYONLY"]) # # DIRECTORY: panda/src/pnmimagetypes/ @@ -4119,11 +4079,10 @@ if (not RUNTIME): TargetAdd('p3recorder_composite1.obj', opts=OPTS, input='p3recorder_composite1.cxx') TargetAdd('p3recorder_composite2.obj', opts=OPTS, input='p3recorder_composite2.cxx') - OPTS=['DIR:panda/src/recorder', 'PYTHON'] + OPTS=['DIR:panda/src/recorder'] IGATEFILES=GetDirectoryContents('panda/src/recorder', ["*.h", "*_composite*.cxx"]) TargetAdd('libp3recorder.in', opts=OPTS, input=IGATEFILES) TargetAdd('libp3recorder.in', opts=['IMOD:panda3d.core', 'ILIB:libp3recorder', 'SRCDIR:panda/src/recorder']) - TargetAdd('libp3recorder_igate.obj', input='libp3recorder.in', opts=["DEPENDENCYONLY"]) # # DIRECTORY: panda/src/dxml/ @@ -4139,11 +4098,10 @@ if (not RUNTIME): OPTS=['DIR:panda/src/dxml', 'BUILDING:PANDA', 'TINYXML'] TargetAdd('p3dxml_composite1.obj', opts=OPTS, input='p3dxml_composite1.cxx') - OPTS=['DIR:panda/src/dxml', 'TINYXML', 'PYTHON'] + OPTS=['DIR:panda/src/dxml', 'TINYXML'] IGATEFILES=GetDirectoryContents('panda/src/dxml', ["*.h", "p3dxml_composite1.cxx"]) TargetAdd('libp3dxml.in', opts=OPTS, input=IGATEFILES) TargetAdd('libp3dxml.in', opts=['IMOD:panda3d.core', 'ILIB:libp3dxml', 'SRCDIR:panda/src/dxml']) - TargetAdd('libp3dxml_igate.obj', input='libp3dxml.in', opts=["DEPENDENCYONLY"]) # # DIRECTORY: panda/metalibs/panda/ @@ -4230,110 +4188,109 @@ if (not RUNTIME): TargetAdd('libpanda.dll', dep='dtool_have_freetype.dat') TargetAdd('libpanda.dll', opts=OPTS) - TargetAdd('core_module.obj', input='libp3dtoolbase.in') - TargetAdd('core_module.obj', input='libp3dtoolutil.in') - TargetAdd('core_module.obj', input='libp3prc.in') + PyTargetAdd('core_module.obj', input='libp3dtoolbase.in') + PyTargetAdd('core_module.obj', input='libp3dtoolutil.in') + PyTargetAdd('core_module.obj', input='libp3prc.in') - TargetAdd('core_module.obj', input='libp3downloader.in') - TargetAdd('core_module.obj', input='libp3express.in') + PyTargetAdd('core_module.obj', input='libp3downloader.in') + PyTargetAdd('core_module.obj', input='libp3express.in') - TargetAdd('core_module.obj', input='libp3recorder.in') - TargetAdd('core_module.obj', input='libp3pgraphnodes.in') - TargetAdd('core_module.obj', input='libp3pgraph.in') - TargetAdd('core_module.obj', input='libp3cull.in') - TargetAdd('core_module.obj', input='libp3grutil.in') - TargetAdd('core_module.obj', input='libp3chan.in') - TargetAdd('core_module.obj', input='libp3pstatclient.in') - TargetAdd('core_module.obj', input='libp3char.in') - TargetAdd('core_module.obj', input='libp3collide.in') - TargetAdd('core_module.obj', input='libp3device.in') - TargetAdd('core_module.obj', input='libp3dgraph.in') - TargetAdd('core_module.obj', input='libp3display.in') - TargetAdd('core_module.obj', input='libp3pipeline.in') - TargetAdd('core_module.obj', input='libp3event.in') - TargetAdd('core_module.obj', input='libp3gobj.in') - TargetAdd('core_module.obj', input='libp3gsgbase.in') - TargetAdd('core_module.obj', input='libp3linmath.in') - TargetAdd('core_module.obj', input='libp3mathutil.in') - TargetAdd('core_module.obj', input='libp3parametrics.in') - TargetAdd('core_module.obj', input='libp3pnmimage.in') - TargetAdd('core_module.obj', input='libp3text.in') - TargetAdd('core_module.obj', input='libp3tform.in') - TargetAdd('core_module.obj', input='libp3putil.in') - TargetAdd('core_module.obj', input='libp3audio.in') - TargetAdd('core_module.obj', input='libp3nativenet.in') - TargetAdd('core_module.obj', input='libp3net.in') - TargetAdd('core_module.obj', input='libp3pgui.in') - TargetAdd('core_module.obj', input='libp3movies.in') - TargetAdd('core_module.obj', input='libp3dxml.in') + PyTargetAdd('core_module.obj', input='libp3recorder.in') + PyTargetAdd('core_module.obj', input='libp3pgraphnodes.in') + PyTargetAdd('core_module.obj', input='libp3pgraph.in') + PyTargetAdd('core_module.obj', input='libp3cull.in') + PyTargetAdd('core_module.obj', input='libp3grutil.in') + PyTargetAdd('core_module.obj', input='libp3chan.in') + PyTargetAdd('core_module.obj', input='libp3pstatclient.in') + PyTargetAdd('core_module.obj', input='libp3char.in') + PyTargetAdd('core_module.obj', input='libp3collide.in') + PyTargetAdd('core_module.obj', input='libp3device.in') + PyTargetAdd('core_module.obj', input='libp3dgraph.in') + PyTargetAdd('core_module.obj', input='libp3display.in') + PyTargetAdd('core_module.obj', input='libp3pipeline.in') + PyTargetAdd('core_module.obj', input='libp3event.in') + PyTargetAdd('core_module.obj', input='libp3gobj.in') + PyTargetAdd('core_module.obj', input='libp3gsgbase.in') + PyTargetAdd('core_module.obj', input='libp3linmath.in') + PyTargetAdd('core_module.obj', input='libp3mathutil.in') + PyTargetAdd('core_module.obj', input='libp3parametrics.in') + PyTargetAdd('core_module.obj', input='libp3pnmimage.in') + PyTargetAdd('core_module.obj', input='libp3text.in') + PyTargetAdd('core_module.obj', input='libp3tform.in') + PyTargetAdd('core_module.obj', input='libp3putil.in') + PyTargetAdd('core_module.obj', input='libp3audio.in') + PyTargetAdd('core_module.obj', input='libp3nativenet.in') + PyTargetAdd('core_module.obj', input='libp3net.in') + PyTargetAdd('core_module.obj', input='libp3pgui.in') + PyTargetAdd('core_module.obj', input='libp3movies.in') + PyTargetAdd('core_module.obj', input='libp3dxml.in') if PkgSkip("FREETYPE")==0: - TargetAdd('core_module.obj', input='libp3pnmtext.in') + PyTargetAdd('core_module.obj', input='libp3pnmtext.in') - TargetAdd('core_module.obj', opts=['PYTHON']) - TargetAdd('core_module.obj', opts=['IMOD:panda3d.core', 'ILIB:core']) + PyTargetAdd('core_module.obj', opts=['IMOD:panda3d.core', 'ILIB:core']) - TargetAdd('core.pyd', input='libp3dtoolbase_igate.obj') - TargetAdd('core.pyd', input='p3dtoolbase_typeHandle_ext.obj') - TargetAdd('core.pyd', input='libp3dtoolutil_igate.obj') - TargetAdd('core.pyd', input='p3dtoolutil_ext_composite.obj') - TargetAdd('core.pyd', input='libp3prc_igate.obj') - TargetAdd('core.pyd', input='p3prc_ext_composite.obj') + PyTargetAdd('core.pyd', input='libp3dtoolbase_igate.obj') + PyTargetAdd('core.pyd', input='p3dtoolbase_typeHandle_ext.obj') + PyTargetAdd('core.pyd', input='libp3dtoolutil_igate.obj') + PyTargetAdd('core.pyd', input='p3dtoolutil_ext_composite.obj') + PyTargetAdd('core.pyd', input='libp3prc_igate.obj') + PyTargetAdd('core.pyd', input='p3prc_ext_composite.obj') - TargetAdd('core.pyd', input='libp3downloader_igate.obj') - TargetAdd('core.pyd', input='p3downloader_stringStream_ext.obj') - TargetAdd('core.pyd', input='p3express_ext_composite.obj') - TargetAdd('core.pyd', input='libp3express_igate.obj') + PyTargetAdd('core.pyd', input='libp3downloader_igate.obj') + PyTargetAdd('core.pyd', input='p3downloader_stringStream_ext.obj') + PyTargetAdd('core.pyd', input='p3express_ext_composite.obj') + PyTargetAdd('core.pyd', input='libp3express_igate.obj') - TargetAdd('core.pyd', input='libp3recorder_igate.obj') - TargetAdd('core.pyd', input='libp3pgraphnodes_igate.obj') - TargetAdd('core.pyd', input='libp3pgraph_igate.obj') - TargetAdd('core.pyd', input='libp3movies_igate.obj') - TargetAdd('core.pyd', input='libp3grutil_igate.obj') - TargetAdd('core.pyd', input='libp3chan_igate.obj') - TargetAdd('core.pyd', input='libp3pstatclient_igate.obj') - TargetAdd('core.pyd', input='libp3char_igate.obj') - TargetAdd('core.pyd', input='libp3collide_igate.obj') - TargetAdd('core.pyd', input='libp3device_igate.obj') - TargetAdd('core.pyd', input='libp3dgraph_igate.obj') - TargetAdd('core.pyd', input='libp3display_igate.obj') - TargetAdd('core.pyd', input='libp3pipeline_igate.obj') - TargetAdd('core.pyd', input='libp3event_igate.obj') - TargetAdd('core.pyd', input='libp3gobj_igate.obj') - TargetAdd('core.pyd', input='libp3gsgbase_igate.obj') - TargetAdd('core.pyd', input='libp3linmath_igate.obj') - TargetAdd('core.pyd', input='libp3mathutil_igate.obj') - TargetAdd('core.pyd', input='libp3parametrics_igate.obj') - TargetAdd('core.pyd', input='libp3pnmimage_igate.obj') - TargetAdd('core.pyd', input='libp3text_igate.obj') - TargetAdd('core.pyd', input='libp3tform_igate.obj') - TargetAdd('core.pyd', input='libp3putil_igate.obj') - TargetAdd('core.pyd', input='libp3audio_igate.obj') - TargetAdd('core.pyd', input='libp3pgui_igate.obj') - TargetAdd('core.pyd', input='libp3net_igate.obj') - TargetAdd('core.pyd', input='libp3nativenet_igate.obj') - TargetAdd('core.pyd', input='libp3dxml_igate.obj') + PyTargetAdd('core.pyd', input='libp3recorder_igate.obj') + PyTargetAdd('core.pyd', input='libp3pgraphnodes_igate.obj') + PyTargetAdd('core.pyd', input='libp3pgraph_igate.obj') + PyTargetAdd('core.pyd', input='libp3movies_igate.obj') + PyTargetAdd('core.pyd', input='libp3grutil_igate.obj') + PyTargetAdd('core.pyd', input='libp3chan_igate.obj') + PyTargetAdd('core.pyd', input='libp3pstatclient_igate.obj') + PyTargetAdd('core.pyd', input='libp3char_igate.obj') + PyTargetAdd('core.pyd', input='libp3collide_igate.obj') + PyTargetAdd('core.pyd', input='libp3device_igate.obj') + PyTargetAdd('core.pyd', input='libp3dgraph_igate.obj') + PyTargetAdd('core.pyd', input='libp3display_igate.obj') + PyTargetAdd('core.pyd', input='libp3pipeline_igate.obj') + PyTargetAdd('core.pyd', input='libp3event_igate.obj') + PyTargetAdd('core.pyd', input='libp3gobj_igate.obj') + PyTargetAdd('core.pyd', input='libp3gsgbase_igate.obj') + PyTargetAdd('core.pyd', input='libp3linmath_igate.obj') + PyTargetAdd('core.pyd', input='libp3mathutil_igate.obj') + PyTargetAdd('core.pyd', input='libp3parametrics_igate.obj') + PyTargetAdd('core.pyd', input='libp3pnmimage_igate.obj') + PyTargetAdd('core.pyd', input='libp3text_igate.obj') + PyTargetAdd('core.pyd', input='libp3tform_igate.obj') + PyTargetAdd('core.pyd', input='libp3putil_igate.obj') + PyTargetAdd('core.pyd', input='libp3audio_igate.obj') + PyTargetAdd('core.pyd', input='libp3pgui_igate.obj') + PyTargetAdd('core.pyd', input='libp3net_igate.obj') + PyTargetAdd('core.pyd', input='libp3nativenet_igate.obj') + PyTargetAdd('core.pyd', input='libp3dxml_igate.obj') if PkgSkip("FREETYPE")==0: - TargetAdd('core.pyd', input="libp3pnmtext_igate.obj") + PyTargetAdd('core.pyd', input="libp3pnmtext_igate.obj") - TargetAdd('core.pyd', input='p3pipeline_pythonThread.obj') - TargetAdd('core.pyd', input='p3putil_ext_composite.obj') - TargetAdd('core.pyd', input='p3pnmimage_pfmFile_ext.obj') - TargetAdd('core.pyd', input='p3event_asyncFuture_ext.obj') - TargetAdd('core.pyd', input='p3event_pythonTask.obj') - TargetAdd('core.pyd', input='p3gobj_ext_composite.obj') - TargetAdd('core.pyd', input='p3pgraph_ext_composite.obj') - TargetAdd('core.pyd', input='p3display_graphicsStateGuardian_ext.obj') - TargetAdd('core.pyd', input='p3display_graphicsWindow_ext.obj') - TargetAdd('core.pyd', input='p3display_pythonGraphicsWindowProc.obj') + PyTargetAdd('core.pyd', input='p3pipeline_pythonThread.obj') + PyTargetAdd('core.pyd', input='p3putil_ext_composite.obj') + PyTargetAdd('core.pyd', input='p3pnmimage_pfmFile_ext.obj') + PyTargetAdd('core.pyd', input='p3event_asyncFuture_ext.obj') + PyTargetAdd('core.pyd', input='p3event_pythonTask.obj') + PyTargetAdd('core.pyd', input='p3gobj_ext_composite.obj') + PyTargetAdd('core.pyd', input='p3pgraph_ext_composite.obj') + PyTargetAdd('core.pyd', input='p3display_graphicsStateGuardian_ext.obj') + PyTargetAdd('core.pyd', input='p3display_graphicsWindow_ext.obj') + PyTargetAdd('core.pyd', input='p3display_pythonGraphicsWindowProc.obj') - TargetAdd('core.pyd', input='core_module.obj') + PyTargetAdd('core.pyd', input='core_module.obj') if not GetLinkAllStatic() and GetTarget() != 'emscripten': - TargetAdd('core.pyd', input='libp3tinyxml.ilb') - TargetAdd('core.pyd', input='libp3interrogatedb.dll') - TargetAdd('core.pyd', input=COMMON_PANDA_LIBS) - TargetAdd('core.pyd', opts=['PYTHON', 'WINSOCK2']) + PyTargetAdd('core.pyd', input='libp3tinyxml.ilb') + PyTargetAdd('core.pyd', input='libp3interrogatedb.dll') + PyTargetAdd('core.pyd', input=COMMON_PANDA_LIBS) + PyTargetAdd('core.pyd', opts=['WINSOCK2']) # # DIRECTORY: panda/src/vision/ @@ -4359,22 +4316,21 @@ if (PkgSkip("VISION") == 0) and (not RUNTIME): TargetAdd('libp3vision.dll', input=COMMON_PANDA_LIBS) TargetAdd('libp3vision.dll', opts=OPTS) - OPTS=['DIR:panda/src/vision', 'ARTOOLKIT', 'OPENCV', 'DX9', 'DIRECTCAM', 'JPEG', 'EXCEPTIONS', 'PYTHON'] + OPTS=['DIR:panda/src/vision', 'ARTOOLKIT', 'OPENCV', 'DX9', 'DIRECTCAM', 'JPEG', 'EXCEPTIONS'] IGATEFILES=GetDirectoryContents('panda/src/vision', ["*.h", "*_composite*.cxx"]) TargetAdd('libp3vision.in', opts=OPTS, input=IGATEFILES) TargetAdd('libp3vision.in', opts=['IMOD:panda3d.vision', 'ILIB:libp3vision', 'SRCDIR:panda/src/vision']) - TargetAdd('libp3vision_igate.obj', input='libp3vision.in', opts=["DEPENDENCYONLY"]) - TargetAdd('vision_module.obj', input='libp3vision.in') - TargetAdd('vision_module.obj', opts=OPTS) - TargetAdd('vision_module.obj', opts=['IMOD:panda3d.vision', 'ILIB:vision', 'IMPORT:panda3d.core']) - TargetAdd('vision.pyd', input='vision_module.obj') - TargetAdd('vision.pyd', input='libp3vision_igate.obj') - TargetAdd('vision.pyd', input='libp3vision.dll') - TargetAdd('vision.pyd', input='libp3interrogatedb.dll') - TargetAdd('vision.pyd', input=COMMON_PANDA_LIBS) - TargetAdd('vision.pyd', opts=['PYTHON']) + PyTargetAdd('vision_module.obj', input='libp3vision.in') + PyTargetAdd('vision_module.obj', opts=OPTS) + PyTargetAdd('vision_module.obj', opts=['IMOD:panda3d.vision', 'ILIB:vision', 'IMPORT:panda3d.core']) + + PyTargetAdd('vision.pyd', input='vision_module.obj') + PyTargetAdd('vision.pyd', input='libp3vision_igate.obj') + PyTargetAdd('vision.pyd', input='libp3vision.dll') + PyTargetAdd('vision.pyd', input='libp3interrogatedb.dll') + PyTargetAdd('vision.pyd', input=COMMON_PANDA_LIBS) # # DIRECTORY: panda/src/rocket/ @@ -4388,25 +4344,25 @@ if (PkgSkip("ROCKET") == 0) and (not RUNTIME): TargetAdd('libp3rocket.dll', input=COMMON_PANDA_LIBS) TargetAdd('libp3rocket.dll', opts=OPTS) - OPTS=['DIR:panda/src/rocket', 'ROCKET', 'RTTI', 'EXCEPTIONS', 'PYTHON'] + OPTS=['DIR:panda/src/rocket', 'ROCKET', 'RTTI', 'EXCEPTIONS'] IGATEFILES=GetDirectoryContents('panda/src/rocket', ["rocketInputHandler.h", "rocketInputHandler.cxx", "rocketRegion.h", "rocketRegion.cxx", "rocketRegion_ext.h"]) TargetAdd('libp3rocket.in', opts=OPTS, input=IGATEFILES) TargetAdd('libp3rocket.in', opts=['IMOD:panda3d.rocket', 'ILIB:libp3rocket', 'SRCDIR:panda/src/rocket']) - TargetAdd('libp3rocket_igate.obj', input='libp3rocket.in', opts=["DEPENDENCYONLY"]) - TargetAdd('p3rocket_rocketRegion_ext.obj', opts=OPTS, input='rocketRegion_ext.cxx') - TargetAdd('rocket_module.obj', input='libp3rocket.in') - TargetAdd('rocket_module.obj', opts=OPTS) - TargetAdd('rocket_module.obj', opts=['IMOD:panda3d.rocket', 'ILIB:rocket', 'IMPORT:panda3d.core']) + PyTargetAdd('p3rocket_rocketRegion_ext.obj', opts=OPTS, input='rocketRegion_ext.cxx') - TargetAdd('rocket.pyd', input='rocket_module.obj') - TargetAdd('rocket.pyd', input='libp3rocket_igate.obj') - TargetAdd('rocket.pyd', input='p3rocket_rocketRegion_ext.obj') - TargetAdd('rocket.pyd', input='libp3rocket.dll') - TargetAdd('rocket.pyd', input='libp3interrogatedb.dll') - TargetAdd('rocket.pyd', input=COMMON_PANDA_LIBS) - TargetAdd('rocket.pyd', opts=['PYTHON', 'ROCKET']) + PyTargetAdd('rocket_module.obj', input='libp3rocket.in') + PyTargetAdd('rocket_module.obj', opts=OPTS) + PyTargetAdd('rocket_module.obj', opts=['IMOD:panda3d.rocket', 'ILIB:rocket', 'IMPORT:panda3d.core']) + + PyTargetAdd('rocket.pyd', input='rocket_module.obj') + PyTargetAdd('rocket.pyd', input='libp3rocket_igate.obj') + PyTargetAdd('rocket.pyd', input='p3rocket_rocketRegion_ext.obj') + PyTargetAdd('rocket.pyd', input='libp3rocket.dll') + PyTargetAdd('rocket.pyd', input='libp3interrogatedb.dll') + PyTargetAdd('rocket.pyd', input=COMMON_PANDA_LIBS) + PyTargetAdd('rocket.pyd', opts=['ROCKET']) # # DIRECTORY: panda/src/p3awesomium @@ -4418,22 +4374,21 @@ if PkgSkip("AWESOMIUM") == 0 and not RUNTIME: TargetAdd('libp3awesomium.dll', input=COMMON_PANDA_LIBS) TargetAdd('libp3awesomium.dll', opts=OPTS) - OPTS=['DIR:panda/src/awesomium', 'AWESOMIUM', 'PYTHON'] + OPTS=['DIR:panda/src/awesomium', 'AWESOMIUM'] IGATEFILES=GetDirectoryContents('panda/src/awesomium', ["*.h", "*_composite1.cxx"]) TargetAdd('libp3awesomium.in', opts=OPTS, input=IGATEFILES) TargetAdd('libp3awesomium.in', opts=['IMOD:panda3d.awesomium', 'ILIB:libp3awesomium', 'SRCDIR:panda/src/awesomium']) - TargetAdd('libp3awesomium_igate.obj', input='libp3awesomium.in', opts=["DEPENDENCYONLY"]) - TargetAdd('awesomium_module.obj', input='libp3awesomium.in') - TargetAdd('awesomium_module.obj', opts=OPTS) - TargetAdd('awesomium_module.obj', opts=['IMOD:panda3d.awesomium', 'ILIB:awesomium', 'IMPORT:panda3d.core']) - TargetAdd('awesomium.pyd', input='awesomium_module.obj') - TargetAdd('awesomium.pyd', input='libp3awesomium_igate.obj') - TargetAdd('awesomium.pyd', input='libp3awesomium.dll') - TargetAdd('awesomium.pyd', input='libp3interrogatedb.dll') - TargetAdd('awesomium.pyd', input=COMMON_PANDA_LIBS) - TargetAdd('awesomium.pyd', opts=['PYTHON']) + PyTargetAdd('awesomium_module.obj', input='libp3awesomium.in') + PyTargetAdd('awesomium_module.obj', opts=OPTS) + PyTargetAdd('awesomium_module.obj', opts=['IMOD:panda3d.awesomium', 'ILIB:awesomium', 'IMPORT:panda3d.core']) + + PyTargetAdd('awesomium.pyd', input='awesomium_module.obj') + PyTargetAdd('awesomium.pyd', input='libp3awesomium_igate.obj') + PyTargetAdd('awesomium.pyd', input='libp3awesomium.dll') + PyTargetAdd('awesomium.pyd', input='libp3interrogatedb.dll') + PyTargetAdd('awesomium.pyd', input=COMMON_PANDA_LIBS) # # DIRECTORY: panda/src/p3skel @@ -4443,11 +4398,10 @@ if (PkgSkip('SKEL')==0) and (not RUNTIME): OPTS=['DIR:panda/src/skel', 'BUILDING:PANDASKEL', 'ADVAPI'] TargetAdd('p3skel_composite1.obj', opts=OPTS, input='p3skel_composite1.cxx') - OPTS=['DIR:panda/src/skel', 'ADVAPI', 'PYTHON'] + OPTS=['DIR:panda/src/skel', 'ADVAPI'] IGATEFILES=GetDirectoryContents("panda/src/skel", ["*.h", "*_composite*.cxx"]) TargetAdd('libp3skel.in', opts=OPTS, input=IGATEFILES) TargetAdd('libp3skel.in', opts=['IMOD:panda3d.skel', 'ILIB:libp3skel', 'SRCDIR:panda/src/skel']) - TargetAdd('libp3skel_igate.obj', input='libp3skel.in', opts=["DEPENDENCYONLY"]) # # DIRECTORY: panda/src/p3skel @@ -4459,17 +4413,14 @@ if (PkgSkip('SKEL')==0) and (not RUNTIME): TargetAdd('libpandaskel.dll', input=COMMON_PANDA_LIBS) TargetAdd('libpandaskel.dll', opts=OPTS) - OPTS=['PYTHON'] - TargetAdd('skel_module.obj', input='libp3skel.in') - TargetAdd('skel_module.obj', opts=OPTS) - TargetAdd('skel_module.obj', opts=['IMOD:panda3d.skel', 'ILIB:skel', 'IMPORT:panda3d.core']) + PyTargetAdd('skel_module.obj', input='libp3skel.in') + PyTargetAdd('skel_module.obj', opts=['IMOD:panda3d.skel', 'ILIB:skel', 'IMPORT:panda3d.core']) - TargetAdd('skel.pyd', input='skel_module.obj') - TargetAdd('skel.pyd', input='libp3skel_igate.obj') - TargetAdd('skel.pyd', input='libpandaskel.dll') - TargetAdd('skel.pyd', input='libp3interrogatedb.dll') - TargetAdd('skel.pyd', input=COMMON_PANDA_LIBS) - TargetAdd('skel.pyd', opts=['PYTHON']) + PyTargetAdd('skel.pyd', input='skel_module.obj') + PyTargetAdd('skel.pyd', input='libp3skel_igate.obj') + PyTargetAdd('skel.pyd', input='libpandaskel.dll') + PyTargetAdd('skel.pyd', input='libp3interrogatedb.dll') + PyTargetAdd('skel.pyd', input=COMMON_PANDA_LIBS) # # DIRECTORY: panda/src/distort/ @@ -4479,11 +4430,10 @@ if (PkgSkip('PANDAFX')==0) and (not RUNTIME): OPTS=['DIR:panda/src/distort', 'BUILDING:PANDAFX'] TargetAdd('p3distort_composite1.obj', opts=OPTS, input='p3distort_composite1.cxx') - OPTS=['DIR:panda/metalibs/pandafx', 'DIR:panda/src/distort', 'NVIDIACG', 'PYTHON'] + OPTS=['DIR:panda/metalibs/pandafx', 'DIR:panda/src/distort', 'NVIDIACG'] IGATEFILES=GetDirectoryContents('panda/src/distort', ["*.h", "*_composite*.cxx"]) TargetAdd('libp3distort.in', opts=OPTS, input=IGATEFILES) TargetAdd('libp3distort.in', opts=['IMOD:panda3d.fx', 'ILIB:libp3distort', 'SRCDIR:panda/src/distort']) - TargetAdd('libp3distort_igate.obj', input='libp3distort.in', opts=["DEPENDENCYONLY"]) # # DIRECTORY: panda/metalibs/pandafx/ @@ -4498,17 +4448,16 @@ if (PkgSkip('PANDAFX')==0) and (not RUNTIME): TargetAdd('libpandafx.dll', input=COMMON_PANDA_LIBS) TargetAdd('libpandafx.dll', opts=['ADVAPI', 'NVIDIACG']) - OPTS=['DIR:panda/metalibs/pandafx', 'DIR:panda/src/distort', 'NVIDIACG', 'PYTHON'] - TargetAdd('fx_module.obj', input='libp3distort.in') - TargetAdd('fx_module.obj', opts=OPTS) - TargetAdd('fx_module.obj', opts=['IMOD:panda3d.fx', 'ILIB:fx', 'IMPORT:panda3d.core']) + OPTS=['DIR:panda/metalibs/pandafx', 'DIR:panda/src/distort', 'NVIDIACG'] + PyTargetAdd('fx_module.obj', input='libp3distort.in') + PyTargetAdd('fx_module.obj', opts=OPTS) + PyTargetAdd('fx_module.obj', opts=['IMOD:panda3d.fx', 'ILIB:fx', 'IMPORT:panda3d.core']) - TargetAdd('fx.pyd', input='fx_module.obj') - TargetAdd('fx.pyd', input='libp3distort_igate.obj') - TargetAdd('fx.pyd', input='libpandafx.dll') - TargetAdd('fx.pyd', input='libp3interrogatedb.dll') - TargetAdd('fx.pyd', input=COMMON_PANDA_LIBS) - TargetAdd('fx.pyd', opts=['PYTHON']) + PyTargetAdd('fx.pyd', input='fx_module.obj') + PyTargetAdd('fx.pyd', input='libp3distort_igate.obj') + PyTargetAdd('fx.pyd', input='libpandafx.dll') + PyTargetAdd('fx.pyd', input='libp3interrogatedb.dll') + PyTargetAdd('fx.pyd', input=COMMON_PANDA_LIBS) # # DIRECTORY: panda/src/vrpn/ @@ -4521,22 +4470,21 @@ if (PkgSkip("VRPN")==0 and not RUNTIME): TargetAdd('libp3vrpn.dll', input=COMMON_PANDA_LIBS) TargetAdd('libp3vrpn.dll', opts=['VRPN']) - OPTS=['DIR:panda/src/vrpn', 'VRPN', 'PYTHON'] + OPTS=['DIR:panda/src/vrpn', 'VRPN'] IGATEFILES=GetDirectoryContents('panda/src/vrpn', ["*.h", "*_composite*.cxx"]) TargetAdd('libp3vrpn.in', opts=OPTS, input=IGATEFILES) TargetAdd('libp3vrpn.in', opts=['IMOD:panda3d.vrpn', 'ILIB:libp3vrpn', 'SRCDIR:panda/src/vrpn']) - TargetAdd('libp3vrpn_igate.obj', input='libp3vrpn.in', opts=["DEPENDENCYONLY"]) - TargetAdd('vrpn_module.obj', input='libp3vrpn.in') - TargetAdd('vrpn_module.obj', opts=OPTS) - TargetAdd('vrpn_module.obj', opts=['IMOD:panda3d.vrpn', 'ILIB:vrpn', 'IMPORT:panda3d.core']) - TargetAdd('vrpn.pyd', input='vrpn_module.obj') - TargetAdd('vrpn.pyd', input='libp3vrpn_igate.obj') - TargetAdd('vrpn.pyd', input='libp3vrpn.dll') - TargetAdd('vrpn.pyd', input='libp3interrogatedb.dll') - TargetAdd('vrpn.pyd', input=COMMON_PANDA_LIBS) - TargetAdd('vrpn.pyd', opts=['PYTHON']) + PyTargetAdd('vrpn_module.obj', input='libp3vrpn.in') + PyTargetAdd('vrpn_module.obj', opts=OPTS) + PyTargetAdd('vrpn_module.obj', opts=['IMOD:panda3d.vrpn', 'ILIB:vrpn', 'IMPORT:panda3d.core']) + + PyTargetAdd('vrpn.pyd', input='vrpn_module.obj') + PyTargetAdd('vrpn.pyd', input='libp3vrpn_igate.obj') + PyTargetAdd('vrpn.pyd', input='libp3vrpn.dll') + PyTargetAdd('vrpn.pyd', input='libp3interrogatedb.dll') + PyTargetAdd('vrpn.pyd', input=COMMON_PANDA_LIBS) # # DIRECTORY: panda/src/ffmpeg @@ -4686,13 +4634,12 @@ if not RUNTIME and not PkgSkip("EGG"): TargetAdd('p3egg_composite1.obj', opts=OPTS, input='p3egg_composite1.cxx') TargetAdd('p3egg_composite2.obj', opts=OPTS, input='p3egg_composite2.cxx') - OPTS=['DIR:panda/src/egg', 'ZLIB', 'PYTHON'] + OPTS=['DIR:panda/src/egg', 'ZLIB'] IGATEFILES=GetDirectoryContents('panda/src/egg', ["*.h", "*_composite*.cxx"]) if "parser.h" in IGATEFILES: IGATEFILES.remove("parser.h") TargetAdd('libp3egg.in', opts=OPTS, input=IGATEFILES) TargetAdd('libp3egg.in', opts=['IMOD:panda3d.egg', 'ILIB:libp3egg', 'SRCDIR:panda/src/egg']) - TargetAdd('libp3egg_igate.obj', input='libp3egg.in', opts=["DEPENDENCYONLY"]) - TargetAdd('p3egg_eggGroupNode_ext.obj', opts=OPTS, input='eggGroupNode_ext.cxx') + PyTargetAdd('p3egg_eggGroupNode_ext.obj', opts=OPTS, input='eggGroupNode_ext.cxx') # # DIRECTORY: panda/src/egg2pg/ @@ -4703,11 +4650,10 @@ if not RUNTIME and not PkgSkip("EGG"): TargetAdd('p3egg2pg_composite1.obj', opts=OPTS, input='p3egg2pg_composite1.cxx') TargetAdd('p3egg2pg_composite2.obj', opts=OPTS, input='p3egg2pg_composite2.cxx') - OPTS=['DIR:panda/src/egg2pg', 'PYTHON'] + OPTS=['DIR:panda/src/egg2pg'] IGATEFILES=['load_egg_file.h'] TargetAdd('libp3egg2pg.in', opts=OPTS, input=IGATEFILES) TargetAdd('libp3egg2pg.in', opts=['IMOD:panda3d.egg', 'ILIB:libp3egg2pg', 'SRCDIR:panda/src/egg2pg']) - TargetAdd('libp3egg2pg_igate.obj', input='libp3egg2pg.in', opts=["DEPENDENCYONLY"]) # # DIRECTORY: panda/src/framework/ @@ -4776,20 +4722,19 @@ if not RUNTIME and not PkgSkip("EGG"): TargetAdd('libpandaegg.dll', input=COMMON_PANDA_LIBS) TargetAdd('libpandaegg.dll', opts=['ADVAPI']) - OPTS=['DIR:panda/metalibs/pandaegg', 'DIR:panda/src/egg', 'PYTHON'] - TargetAdd('egg_module.obj', input='libp3egg2pg.in') - TargetAdd('egg_module.obj', input='libp3egg.in') - TargetAdd('egg_module.obj', opts=OPTS) - TargetAdd('egg_module.obj', opts=['IMOD:panda3d.egg', 'ILIB:egg', 'IMPORT:panda3d.core']) + OPTS=['DIR:panda/metalibs/pandaegg', 'DIR:panda/src/egg'] + PyTargetAdd('egg_module.obj', input='libp3egg2pg.in') + PyTargetAdd('egg_module.obj', input='libp3egg.in') + PyTargetAdd('egg_module.obj', opts=OPTS) + PyTargetAdd('egg_module.obj', opts=['IMOD:panda3d.egg', 'ILIB:egg', 'IMPORT:panda3d.core']) - TargetAdd('egg.pyd', input='egg_module.obj') - TargetAdd('egg.pyd', input='p3egg_eggGroupNode_ext.obj') - TargetAdd('egg.pyd', input='libp3egg_igate.obj') - TargetAdd('egg.pyd', input='libp3egg2pg_igate.obj') - TargetAdd('egg.pyd', input='libpandaegg.dll') - TargetAdd('egg.pyd', input='libp3interrogatedb.dll') - TargetAdd('egg.pyd', input=COMMON_PANDA_LIBS) - TargetAdd('egg.pyd', opts=['PYTHON']) + PyTargetAdd('egg.pyd', input='egg_module.obj') + PyTargetAdd('egg.pyd', input='p3egg_eggGroupNode_ext.obj') + PyTargetAdd('egg.pyd', input='libp3egg_igate.obj') + PyTargetAdd('egg.pyd', input='libp3egg2pg_igate.obj') + PyTargetAdd('egg.pyd', input='libpandaegg.dll') + PyTargetAdd('egg.pyd', input='libp3interrogatedb.dll') + PyTargetAdd('egg.pyd', input=COMMON_PANDA_LIBS) # # DIRECTORY: panda/src/x11display/ @@ -4913,20 +4858,19 @@ if (PkgSkip("EGL")==0 and PkgSkip("GLES2")==0 and PkgSkip("X11")==0 and not RUNT # DIRECTORY: panda/src/ode/ # if (PkgSkip("ODE")==0 and not RUNTIME): - OPTS=['DIR:panda/src/ode', 'BUILDING:PANDAODE', 'ODE', 'PYTHON'] + OPTS=['DIR:panda/src/ode', 'BUILDING:PANDAODE', 'ODE'] TargetAdd('p3ode_composite1.obj', opts=OPTS, input='p3ode_composite1.cxx') TargetAdd('p3ode_composite2.obj', opts=OPTS, input='p3ode_composite2.cxx') TargetAdd('p3ode_composite3.obj', opts=OPTS, input='p3ode_composite3.cxx') - OPTS=['DIR:panda/src/ode', 'ODE', 'PYTHON'] + OPTS=['DIR:panda/src/ode', 'ODE'] IGATEFILES=GetDirectoryContents('panda/src/ode', ["*.h", "*_composite*.cxx"]) IGATEFILES.remove("odeConvexGeom.h") IGATEFILES.remove("odeHeightFieldGeom.h") IGATEFILES.remove("odeHelperStructs.h") TargetAdd('libpandaode.in', opts=OPTS, input=IGATEFILES) TargetAdd('libpandaode.in', opts=['IMOD:panda3d.ode', 'ILIB:libpandaode', 'SRCDIR:panda/src/ode']) - TargetAdd('libpandaode_igate.obj', input='libpandaode.in', opts=["DEPENDENCYONLY"]) - TargetAdd('p3ode_ext_composite.obj', opts=OPTS, input='p3ode_ext_composite.cxx') + PyTargetAdd('p3ode_ext_composite.obj', opts=OPTS, input='p3ode_ext_composite.cxx') # # DIRECTORY: panda/metalibs/pandaode/ @@ -4942,18 +4886,18 @@ if (PkgSkip("ODE")==0 and not RUNTIME): TargetAdd('libpandaode.dll', input=COMMON_PANDA_LIBS) TargetAdd('libpandaode.dll', opts=['WINUSER', 'ODE']) - OPTS=['DIR:panda/metalibs/pandaode', 'ODE', 'PYTHON'] - TargetAdd('ode_module.obj', input='libpandaode.in') - TargetAdd('ode_module.obj', opts=OPTS) - TargetAdd('ode_module.obj', opts=['IMOD:panda3d.ode', 'ILIB:ode', 'IMPORT:panda3d.core']) + OPTS=['DIR:panda/metalibs/pandaode', 'ODE'] + PyTargetAdd('ode_module.obj', input='libpandaode.in') + PyTargetAdd('ode_module.obj', opts=OPTS) + PyTargetAdd('ode_module.obj', opts=['IMOD:panda3d.ode', 'ILIB:ode', 'IMPORT:panda3d.core']) - TargetAdd('ode.pyd', input='ode_module.obj') - TargetAdd('ode.pyd', input='libpandaode_igate.obj') - TargetAdd('ode.pyd', input='p3ode_ext_composite.obj') - TargetAdd('ode.pyd', input='libpandaode.dll') - TargetAdd('ode.pyd', input='libp3interrogatedb.dll') - TargetAdd('ode.pyd', input=COMMON_PANDA_LIBS) - TargetAdd('ode.pyd', opts=['PYTHON', 'WINUSER', 'ODE']) + PyTargetAdd('ode.pyd', input='ode_module.obj') + PyTargetAdd('ode.pyd', input='libpandaode_igate.obj') + PyTargetAdd('ode.pyd', input='p3ode_ext_composite.obj') + PyTargetAdd('ode.pyd', input='libpandaode.dll') + PyTargetAdd('ode.pyd', input='libp3interrogatedb.dll') + PyTargetAdd('ode.pyd', input=COMMON_PANDA_LIBS) + PyTargetAdd('ode.pyd', opts=['WINUSER', 'ODE']) # # DIRECTORY: panda/src/bullet/ @@ -4962,11 +4906,10 @@ if (PkgSkip("BULLET")==0 and not RUNTIME): OPTS=['DIR:panda/src/bullet', 'BUILDING:PANDABULLET', 'BULLET'] TargetAdd('p3bullet_composite.obj', opts=OPTS, input='p3bullet_composite.cxx') - OPTS=['DIR:panda/src/bullet', 'BULLET', 'PYTHON'] + OPTS=['DIR:panda/src/bullet', 'BULLET'] IGATEFILES=GetDirectoryContents('panda/src/bullet', ["*.h", "*_composite*.cxx"]) TargetAdd('libpandabullet.in', opts=OPTS, input=IGATEFILES) TargetAdd('libpandabullet.in', opts=['IMOD:panda3d.bullet', 'ILIB:libpandabullet', 'SRCDIR:panda/src/bullet']) - TargetAdd('libpandabullet_igate.obj', input='libpandabullet.in', opts=["DEPENDENCYONLY"]) # # DIRECTORY: panda/metalibs/pandabullet/ @@ -4980,56 +4923,55 @@ if (PkgSkip("BULLET")==0 and not RUNTIME): TargetAdd('libpandabullet.dll', input=COMMON_PANDA_LIBS) TargetAdd('libpandabullet.dll', opts=['WINUSER', 'BULLET']) - OPTS=['DIR:panda/metalibs/pandabullet', 'BULLET', 'PYTHON'] - TargetAdd('bullet_module.obj', input='libpandabullet.in') - TargetAdd('bullet_module.obj', opts=OPTS) - TargetAdd('bullet_module.obj', opts=['IMOD:panda3d.bullet', 'ILIB:bullet', 'IMPORT:panda3d.core']) + OPTS=['DIR:panda/metalibs/pandabullet', 'BULLET'] + PyTargetAdd('bullet_module.obj', input='libpandabullet.in') + PyTargetAdd('bullet_module.obj', opts=OPTS) + PyTargetAdd('bullet_module.obj', opts=['IMOD:panda3d.bullet', 'ILIB:bullet', 'IMPORT:panda3d.core']) - TargetAdd('bullet.pyd', input='bullet_module.obj') - TargetAdd('bullet.pyd', input='libpandabullet_igate.obj') - TargetAdd('bullet.pyd', input='libpandabullet.dll') - TargetAdd('bullet.pyd', input='libp3interrogatedb.dll') - TargetAdd('bullet.pyd', input=COMMON_PANDA_LIBS) - TargetAdd('bullet.pyd', opts=['PYTHON', 'WINUSER', 'BULLET']) + PyTargetAdd('bullet.pyd', input='bullet_module.obj') + PyTargetAdd('bullet.pyd', input='libpandabullet_igate.obj') + PyTargetAdd('bullet.pyd', input='libpandabullet.dll') + PyTargetAdd('bullet.pyd', input='libp3interrogatedb.dll') + PyTargetAdd('bullet.pyd', input=COMMON_PANDA_LIBS) + PyTargetAdd('bullet.pyd', opts=['WINUSER', 'BULLET']) # # DIRECTORY: panda/src/physx/ # if (PkgSkip("PHYSX")==0): - OPTS=['DIR:panda/src/physx', 'BUILDING:PANDAPHYSX', 'PHYSX', 'NOARCH:PPC', 'PYTHON'] + OPTS=['DIR:panda/src/physx', 'BUILDING:PANDAPHYSX', 'PHYSX', 'NOARCH:PPC'] TargetAdd('p3physx_composite.obj', opts=OPTS, input='p3physx_composite.cxx') - OPTS=['DIR:panda/src/physx', 'PHYSX', 'NOARCH:PPC', 'PYTHON'] + OPTS=['DIR:panda/src/physx', 'PHYSX', 'NOARCH:PPC'] IGATEFILES=GetDirectoryContents('panda/src/physx', ["*.h", "*_composite*.cxx"]) TargetAdd('libpandaphysx.in', opts=OPTS, input=IGATEFILES) TargetAdd('libpandaphysx.in', opts=['IMOD:panda3d.physx', 'ILIB:libpandaphysx', 'SRCDIR:panda/src/physx']) - TargetAdd('libpandaphysx_igate.obj', input='libpandaphysx.in', opts=["DEPENDENCYONLY"]) # # DIRECTORY: panda/metalibs/pandaphysx/ # if (PkgSkip("PHYSX")==0): - OPTS=['DIR:panda/metalibs/pandaphysx', 'BUILDING:PANDAPHYSX', 'PHYSX', 'NOARCH:PPC'] + OPTS=['DIR:panda/metalibs/pandaphysx', 'BUILDING:PANDAPHYSX', 'PHYSX', 'NOARCH:PPC', 'PYTHON'] TargetAdd('pandaphysx_pandaphysx.obj', opts=OPTS, input='pandaphysx.cxx') TargetAdd('libpandaphysx.dll', input='pandaphysx_pandaphysx.obj') TargetAdd('libpandaphysx.dll', input='p3physx_composite.obj') TargetAdd('libpandaphysx.dll', input=COMMON_PANDA_LIBS) - TargetAdd('libpandaphysx.dll', opts=['WINUSER', 'PHYSX', 'NOARCH:PPC', 'PYTHON']) + TargetAdd('libpandaphysx.dll', opts=['WINUSER', 'PHYSX', 'NOARCH:PPC']) - OPTS=['DIR:panda/metalibs/pandaphysx', 'PHYSX', 'NOARCH:PPC', 'PYTHON'] - TargetAdd('physx_module.obj', input='libpandaphysx.in') - TargetAdd('physx_module.obj', opts=OPTS) - TargetAdd('physx_module.obj', opts=['IMOD:panda3d.physx', 'ILIB:physx', 'IMPORT:panda3d.core']) + OPTS=['DIR:panda/metalibs/pandaphysx', 'PHYSX', 'NOARCH:PPC'] + PyTargetAdd('physx_module.obj', input='libpandaphysx.in') + PyTargetAdd('physx_module.obj', opts=OPTS) + PyTargetAdd('physx_module.obj', opts=['IMOD:panda3d.physx', 'ILIB:physx', 'IMPORT:panda3d.core']) - TargetAdd('physx.pyd', input='physx_module.obj') - TargetAdd('physx.pyd', input='libpandaphysx_igate.obj') - TargetAdd('physx.pyd', input='libpandaphysx.dll') - TargetAdd('physx.pyd', input='libp3interrogatedb.dll') - TargetAdd('physx.pyd', input=COMMON_PANDA_LIBS) - TargetAdd('physx.pyd', opts=['PYTHON', 'WINUSER', 'PHYSX', 'NOARCH:PPC']) + PyTargetAdd('physx.pyd', input='physx_module.obj') + PyTargetAdd('physx.pyd', input='libpandaphysx_igate.obj') + PyTargetAdd('physx.pyd', input='libpandaphysx.dll') + PyTargetAdd('physx.pyd', input='libp3interrogatedb.dll') + PyTargetAdd('physx.pyd', input=COMMON_PANDA_LIBS) + PyTargetAdd('physx.pyd', opts=['WINUSER', 'PHYSX', 'NOARCH:PPC']) # # DIRECTORY: panda/src/physics/ @@ -5040,12 +4982,11 @@ if (PkgSkip("PANDAPHYSICS")==0) and (not RUNTIME): TargetAdd('p3physics_composite1.obj', opts=OPTS, input='p3physics_composite1.cxx') TargetAdd('p3physics_composite2.obj', opts=OPTS, input='p3physics_composite2.cxx') - OPTS=['DIR:panda/src/physics', 'PYTHON'] + OPTS=['DIR:panda/src/physics'] IGATEFILES=GetDirectoryContents('panda/src/physics', ["*.h", "*_composite*.cxx"]) IGATEFILES.remove("forces.h") TargetAdd('libp3physics.in', opts=OPTS, input=IGATEFILES) TargetAdd('libp3physics.in', opts=['IMOD:panda3d.physics', 'ILIB:libp3physics', 'SRCDIR:panda/src/physics']) - TargetAdd('libp3physics_igate.obj', input='libp3physics.in', opts=["DEPENDENCYONLY"]) # # DIRECTORY: panda/src/particlesystem/ @@ -5056,7 +4997,7 @@ if (PkgSkip("PANDAPHYSICS")==0) and (PkgSkip("PANDAPARTICLESYSTEM")==0) and (not TargetAdd('p3particlesystem_composite1.obj', opts=OPTS, input='p3particlesystem_composite1.cxx') TargetAdd('p3particlesystem_composite2.obj', opts=OPTS, input='p3particlesystem_composite2.cxx') - OPTS=['DIR:panda/src/particlesystem', 'PYTHON'] + OPTS=['DIR:panda/src/particlesystem'] IGATEFILES=GetDirectoryContents('panda/src/particlesystem', ["*.h", "*_composite*.cxx"]) IGATEFILES.remove('orientedParticle.h') IGATEFILES.remove('orientedParticleFactory.h') @@ -5065,7 +5006,6 @@ if (PkgSkip("PANDAPHYSICS")==0) and (PkgSkip("PANDAPARTICLESYSTEM")==0) and (not IGATEFILES.remove('particles.h') TargetAdd('libp3particlesystem.in', opts=OPTS, input=IGATEFILES) TargetAdd('libp3particlesystem.in', opts=['IMOD:panda3d.physics', 'ILIB:libp3particlesystem', 'SRCDIR:panda/src/particlesystem']) - TargetAdd('libp3particlesystem_igate.obj', input='libp3particlesystem.in', opts=["DEPENDENCYONLY"]) # # DIRECTORY: panda/metalibs/pandaphysics/ @@ -5083,38 +5023,37 @@ if (PkgSkip("PANDAPHYSICS")==0) and (not RUNTIME): TargetAdd('libpandaphysics.dll', input=COMMON_PANDA_LIBS) TargetAdd('libpandaphysics.dll', opts=['ADVAPI']) - OPTS=['DIR:panda/metalibs/pandaphysics', 'PYTHON'] - TargetAdd('physics_module.obj', input='libp3physics.in') + OPTS=['DIR:panda/metalibs/pandaphysics'] + PyTargetAdd('physics_module.obj', input='libp3physics.in') if (PkgSkip("PANDAPARTICLESYSTEM")==0): - TargetAdd('physics_module.obj', input='libp3particlesystem.in') - TargetAdd('physics_module.obj', opts=OPTS) - TargetAdd('physics_module.obj', opts=['IMOD:panda3d.physics', 'ILIB:physics', 'IMPORT:panda3d.core']) + PyTargetAdd('physics_module.obj', input='libp3particlesystem.in') + PyTargetAdd('physics_module.obj', opts=OPTS) + PyTargetAdd('physics_module.obj', opts=['IMOD:panda3d.physics', 'ILIB:physics', 'IMPORT:panda3d.core']) - TargetAdd('physics.pyd', input='physics_module.obj') - TargetAdd('physics.pyd', input='libp3physics_igate.obj') + PyTargetAdd('physics.pyd', input='physics_module.obj') + PyTargetAdd('physics.pyd', input='libp3physics_igate.obj') if (PkgSkip("PANDAPARTICLESYSTEM")==0): - TargetAdd('physics.pyd', input='libp3particlesystem_igate.obj') - TargetAdd('physics.pyd', input='libpandaphysics.dll') - TargetAdd('physics.pyd', input='libp3interrogatedb.dll') - TargetAdd('physics.pyd', input=COMMON_PANDA_LIBS) - TargetAdd('physics.pyd', opts=['PYTHON']) + PyTargetAdd('physics.pyd', input='libp3particlesystem_igate.obj') + PyTargetAdd('physics.pyd', input='libpandaphysics.dll') + PyTargetAdd('physics.pyd', input='libp3interrogatedb.dll') + PyTargetAdd('physics.pyd', input=COMMON_PANDA_LIBS) # # DIRECTORY: panda/src/speedtree/ # if (PkgSkip("SPEEDTREE")==0): - OPTS=['DIR:panda/src/speedtree', 'BUILDING:PANDASPEEDTREE', 'SPEEDTREE', 'PYTHON'] + OPTS=['DIR:panda/src/speedtree', 'BUILDING:PANDASPEEDTREE', 'SPEEDTREE'] TargetAdd('pandaspeedtree_composite1.obj', opts=OPTS, input='pandaspeedtree_composite1.cxx') IGATEFILES=GetDirectoryContents('panda/src/speedtree', ["*.h", "*_composite*.cxx"]) TargetAdd('libpandaspeedtree.in', opts=OPTS, input=IGATEFILES) TargetAdd('libpandaspeedtree.in', opts=['IMOD:libpandaspeedtree', 'ILIB:libpandaspeedtree', 'SRCDIR:panda/src/speedtree']) - TargetAdd('libpandaspeedtree_igate.obj', input='libpandaspeedtree.in', opts=["DEPENDENCYONLY"]) - TargetAdd('libpandaspeedtree_module.obj', input='libpandaspeedtree.in') - TargetAdd('libpandaspeedtree_module.obj', opts=OPTS) - TargetAdd('libpandaspeedtree_module.obj', opts=['IMOD:libpandaspeedtree', 'ILIB:libpandaspeedtree']) + + PyTargetAdd('libpandaspeedtree_module.obj', input='libpandaspeedtree.in') + PyTargetAdd('libpandaspeedtree_module.obj', opts=OPTS) + PyTargetAdd('libpandaspeedtree_module.obj', opts=['IMOD:libpandaspeedtree', 'ILIB:libpandaspeedtree']) TargetAdd('libpandaspeedtree.dll', input='pandaspeedtree_composite1.obj') - TargetAdd('libpandaspeedtree.dll', input='libpandaspeedtree_igate.obj') + PyTargetAdd('libpandaspeedtree.dll', input='libpandaspeedtree_igate.obj') TargetAdd('libpandaspeedtree.dll', input='libpandaspeedtree_module.obj') TargetAdd('libpandaspeedtree.dll', input=COMMON_PANDA_LIBS) TargetAdd('libpandaspeedtree.dll', opts=['SPEEDTREE']) @@ -5177,7 +5116,7 @@ if (not RUNTIME and GetTarget() == 'android'): TargetAdd('libppython.dll', input='libp3framework.dll') TargetAdd('libppython.dll', input='libp3android.dll') TargetAdd('libppython.dll', input=COMMON_PANDA_LIBS) - TargetAdd('libppython.dll', opts=['MODULE', 'ANDROID', 'PYTHON']) + TargetAdd('libppython.dll', opts=['MODULE', 'ANDROID']) # # DIRECTORY: panda/src/androiddisplay/ @@ -5234,7 +5173,7 @@ if (not RUNTIME and (GetTarget() in ('windows', 'darwin') or PkgSkip("X11")==0) # if (PkgSkip("DIRECT")==0): - OPTS=['DIR:direct/src/directbase', 'PYTHON'] + OPTS=['DIR:direct/src/directbase'] TargetAdd('p3directbase_directbase.obj', opts=OPTS+['BUILDING:DIRECT'], input='directbase.cxx') # @@ -5242,21 +5181,20 @@ if (PkgSkip("DIRECT")==0): # if (PkgSkip("DIRECT")==0): - OPTS=['DIR:direct/src/dcparser', 'BUILDING:DIRECT_DCPARSER', 'WITHINPANDA', 'BISONPREFIX_dcyy', 'PYTHON'] + OPTS=['DIR:direct/src/dcparser', 'BUILDING:DIRECT_DCPARSER', 'WITHINPANDA', 'BISONPREFIX_dcyy'] CreateFile(GetOutputDir()+"/include/dcParser.h") - TargetAdd('p3dcparser_dcParser.obj', opts=OPTS, input='dcParser.yxx') - TargetAdd('dcParser.h', input='p3dcparser_dcParser.obj', opts=['DEPENDENCYONLY']) - TargetAdd('p3dcparser_dcLexer.obj', opts=OPTS, input='dcLexer.lxx') - TargetAdd('p3dcparser_composite1.obj', opts=OPTS, input='p3dcparser_composite1.cxx') - TargetAdd('p3dcparser_composite2.obj', opts=OPTS, input='p3dcparser_composite2.cxx') + PyTargetAdd('p3dcparser_dcParser.obj', opts=OPTS, input='dcParser.yxx') + #TargetAdd('dcParser.h', input='p3dcparser_dcParser.obj', opts=['DEPENDENCYONLY']) + PyTargetAdd('p3dcparser_dcLexer.obj', opts=OPTS, input='dcLexer.lxx') + PyTargetAdd('p3dcparser_composite1.obj', opts=OPTS, input='p3dcparser_composite1.cxx') + PyTargetAdd('p3dcparser_composite2.obj', opts=OPTS, input='p3dcparser_composite2.cxx') - OPTS=['DIR:direct/src/dcparser', 'WITHINPANDA', 'PYTHON'] + OPTS=['DIR:direct/src/dcparser', 'WITHINPANDA'] IGATEFILES=GetDirectoryContents('direct/src/dcparser', ["*.h", "*_composite*.cxx"]) if "dcParser.h" in IGATEFILES: IGATEFILES.remove("dcParser.h") if "dcmsgtypes.h" in IGATEFILES: IGATEFILES.remove('dcmsgtypes.h') TargetAdd('libp3dcparser.in', opts=OPTS, input=IGATEFILES) TargetAdd('libp3dcparser.in', opts=['IMOD:panda3d.direct', 'ILIB:libp3dcparser', 'SRCDIR:direct/src/dcparser']) - TargetAdd('libp3dcparser_igate.obj', input='libp3dcparser.in', opts=["DEPENDENCYONLY"]) # # DIRECTORY: direct/src/deadrec/ @@ -5266,27 +5204,25 @@ if (PkgSkip("DIRECT")==0): OPTS=['DIR:direct/src/deadrec', 'BUILDING:DIRECT'] TargetAdd('p3deadrec_composite1.obj', opts=OPTS, input='p3deadrec_composite1.cxx') - OPTS=['DIR:direct/src/deadrec', 'PYTHON'] + OPTS=['DIR:direct/src/deadrec'] IGATEFILES=GetDirectoryContents('direct/src/deadrec', ["*.h", "*_composite*.cxx"]) TargetAdd('libp3deadrec.in', opts=OPTS, input=IGATEFILES) TargetAdd('libp3deadrec.in', opts=['IMOD:panda3d.direct', 'ILIB:libp3deadrec', 'SRCDIR:direct/src/deadrec']) - TargetAdd('libp3deadrec_igate.obj', input='libp3deadrec.in', opts=["DEPENDENCYONLY"]) # # DIRECTORY: direct/src/distributed/ # if (PkgSkip("DIRECT")==0): - OPTS=['DIR:direct/src/distributed', 'DIR:direct/src/dcparser', 'WITHINPANDA', 'BUILDING:DIRECT', 'OPENSSL', 'PYTHON'] + OPTS=['DIR:direct/src/distributed', 'DIR:direct/src/dcparser', 'WITHINPANDA', 'BUILDING:DIRECT', 'OPENSSL'] TargetAdd('p3distributed_config_distributed.obj', opts=OPTS, input='config_distributed.cxx') - TargetAdd('p3distributed_cConnectionRepository.obj', opts=OPTS, input='cConnectionRepository.cxx') - TargetAdd('p3distributed_cDistributedSmoothNodeBase.obj', opts=OPTS, input='cDistributedSmoothNodeBase.cxx') + PyTargetAdd('p3distributed_cConnectionRepository.obj', opts=OPTS, input='cConnectionRepository.cxx') + PyTargetAdd('p3distributed_cDistributedSmoothNodeBase.obj', opts=OPTS, input='cDistributedSmoothNodeBase.cxx') - OPTS=['DIR:direct/src/distributed', 'WITHINPANDA', 'OPENSSL', 'PYTHON'] + OPTS=['DIR:direct/src/distributed', 'WITHINPANDA', 'OPENSSL'] IGATEFILES=GetDirectoryContents('direct/src/distributed', ["*.h", "*.cxx"]) TargetAdd('libp3distributed.in', opts=OPTS, input=IGATEFILES) TargetAdd('libp3distributed.in', opts=['IMOD:panda3d.direct', 'ILIB:libp3distributed', 'SRCDIR:direct/src/distributed']) - TargetAdd('libp3distributed_igate.obj', input='libp3distributed.in', opts=["DEPENDENCYONLY"]) # # DIRECTORY: direct/src/interval/ @@ -5296,11 +5232,10 @@ if (PkgSkip("DIRECT")==0): OPTS=['DIR:direct/src/interval', 'BUILDING:DIRECT'] TargetAdd('p3interval_composite1.obj', opts=OPTS, input='p3interval_composite1.cxx') - OPTS=['DIR:direct/src/interval', 'PYTHON'] + OPTS=['DIR:direct/src/interval'] IGATEFILES=GetDirectoryContents('direct/src/interval', ["*.h", "*_composite*.cxx"]) TargetAdd('libp3interval.in', opts=OPTS, input=IGATEFILES) TargetAdd('libp3interval.in', opts=['IMOD:panda3d.direct', 'ILIB:libp3interval', 'SRCDIR:direct/src/interval']) - TargetAdd('libp3interval_igate.obj', input='libp3interval.in', opts=["DEPENDENCYONLY"]) # # DIRECTORY: direct/src/showbase/ @@ -5312,11 +5247,10 @@ if (PkgSkip("DIRECT")==0): if GetTarget() == 'darwin': TargetAdd('p3showbase_showBase_assist.obj', opts=OPTS, input='showBase_assist.mm') - OPTS=['DIR:direct/src/showbase', 'PYTHON'] + OPTS=['DIR:direct/src/showbase'] IGATEFILES=GetDirectoryContents('direct/src/showbase', ["*.h", "showBase.cxx"]) TargetAdd('libp3showbase.in', opts=OPTS, input=IGATEFILES) TargetAdd('libp3showbase.in', opts=['IMOD:panda3d.direct', 'ILIB:libp3showbase', 'SRCDIR:direct/src/showbase']) - TargetAdd('libp3showbase_igate.obj', input='libp3showbase.in', opts=["DEPENDENCYONLY"]) # # DIRECTORY: direct/src/motiontrail/ @@ -5327,11 +5261,10 @@ if (PkgSkip("DIRECT")==0): TargetAdd('p3motiontrail_cMotionTrail.obj', opts=OPTS, input='cMotionTrail.cxx') TargetAdd('p3motiontrail_config_motiontrail.obj', opts=OPTS, input='config_motiontrail.cxx') - OPTS=['DIR:direct/src/motiontrail', 'PYTHON'] + OPTS=['DIR:direct/src/motiontrail'] IGATEFILES=GetDirectoryContents('direct/src/motiontrail', ["*.h", "cMotionTrail.cxx"]) TargetAdd('libp3motiontrail.in', opts=OPTS, input=IGATEFILES) TargetAdd('libp3motiontrail.in', opts=['IMOD:panda3d.direct', 'ILIB:libp3motiontrail', 'SRCDIR:direct/src/motiontrail']) - TargetAdd('libp3motiontrail_igate.obj', input='libp3motiontrail.in', opts=["DEPENDENCYONLY"]) # # DIRECTORY: direct/metalibs/direct/ @@ -5349,56 +5282,54 @@ if (PkgSkip("DIRECT")==0): TargetAdd('libp3direct.dll', input=COMMON_PANDA_LIBS) TargetAdd('libp3direct.dll', opts=['ADVAPI', 'OPENSSL', 'WINUSER', 'WINGDI']) - OPTS=['PYTHON'] - TargetAdd('direct_module.obj', input='libp3dcparser.in') - TargetAdd('direct_module.obj', input='libp3showbase.in') - TargetAdd('direct_module.obj', input='libp3deadrec.in') - TargetAdd('direct_module.obj', input='libp3interval.in') - TargetAdd('direct_module.obj', input='libp3distributed.in') - TargetAdd('direct_module.obj', input='libp3motiontrail.in') - TargetAdd('direct_module.obj', opts=OPTS) - TargetAdd('direct_module.obj', opts=['IMOD:panda3d.direct', 'ILIB:direct', 'IMPORT:panda3d.core']) + PyTargetAdd('direct_module.obj', input='libp3dcparser.in') + PyTargetAdd('direct_module.obj', input='libp3showbase.in') + PyTargetAdd('direct_module.obj', input='libp3deadrec.in') + PyTargetAdd('direct_module.obj', input='libp3interval.in') + PyTargetAdd('direct_module.obj', input='libp3distributed.in') + PyTargetAdd('direct_module.obj', input='libp3motiontrail.in') + PyTargetAdd('direct_module.obj', opts=['IMOD:panda3d.direct', 'ILIB:direct', 'IMPORT:panda3d.core']) - TargetAdd('direct.pyd', input='libp3dcparser_igate.obj') - TargetAdd('direct.pyd', input='libp3showbase_igate.obj') - TargetAdd('direct.pyd', input='libp3deadrec_igate.obj') - TargetAdd('direct.pyd', input='libp3interval_igate.obj') - TargetAdd('direct.pyd', input='libp3distributed_igate.obj') - TargetAdd('direct.pyd', input='libp3motiontrail_igate.obj') + PyTargetAdd('direct.pyd', input='libp3dcparser_igate.obj') + PyTargetAdd('direct.pyd', input='libp3showbase_igate.obj') + PyTargetAdd('direct.pyd', input='libp3deadrec_igate.obj') + PyTargetAdd('direct.pyd', input='libp3interval_igate.obj') + PyTargetAdd('direct.pyd', input='libp3distributed_igate.obj') + PyTargetAdd('direct.pyd', input='libp3motiontrail_igate.obj') # These are part of direct.pyd, not libp3direct.dll, because they rely on # the Python libraries. If a C++ user needs these modules, we can move them # back and filter out the Python-specific code. - TargetAdd('direct.pyd', input='p3dcparser_composite1.obj') - TargetAdd('direct.pyd', input='p3dcparser_composite2.obj') - TargetAdd('direct.pyd', input='p3dcparser_dcParser.obj') - TargetAdd('direct.pyd', input='p3dcparser_dcLexer.obj') - TargetAdd('direct.pyd', input='p3distributed_config_distributed.obj') - TargetAdd('direct.pyd', input='p3distributed_cConnectionRepository.obj') - TargetAdd('direct.pyd', input='p3distributed_cDistributedSmoothNodeBase.obj') + PyTargetAdd('direct.pyd', input='p3dcparser_composite1.obj') + PyTargetAdd('direct.pyd', input='p3dcparser_composite2.obj') + PyTargetAdd('direct.pyd', input='p3dcparser_dcParser.obj') + PyTargetAdd('direct.pyd', input='p3dcparser_dcLexer.obj') + PyTargetAdd('direct.pyd', input='p3distributed_config_distributed.obj') + PyTargetAdd('direct.pyd', input='p3distributed_cConnectionRepository.obj') + PyTargetAdd('direct.pyd', input='p3distributed_cDistributedSmoothNodeBase.obj') - TargetAdd('direct.pyd', input='direct_module.obj') - TargetAdd('direct.pyd', input='libp3direct.dll') - TargetAdd('direct.pyd', input='libp3interrogatedb.dll') - TargetAdd('direct.pyd', input=COMMON_PANDA_LIBS) - TargetAdd('direct.pyd', opts=['PYTHON', 'OPENSSL', 'WINUSER', 'WINGDI', 'WINSOCK2']) + PyTargetAdd('direct.pyd', input='direct_module.obj') + PyTargetAdd('direct.pyd', input='libp3direct.dll') + PyTargetAdd('direct.pyd', input='libp3interrogatedb.dll') + PyTargetAdd('direct.pyd', input=COMMON_PANDA_LIBS) + PyTargetAdd('direct.pyd', opts=['OPENSSL', 'WINUSER', 'WINGDI', 'WINSOCK2']) # # DIRECTORY: direct/src/dcparse/ # if (PkgSkip("PYTHON")==0 and PkgSkip("DIRECT")==0 and not RTDIST and not RUNTIME): - OPTS=['DIR:direct/src/dcparse', 'DIR:direct/src/dcparser', 'WITHINPANDA', 'ADVAPI', 'PYTHON'] - TargetAdd('dcparse_dcparse.obj', opts=OPTS, input='dcparse.cxx') - TargetAdd('p3dcparse.exe', input='p3dcparser_composite1.obj') - TargetAdd('p3dcparse.exe', input='p3dcparser_composite2.obj') - TargetAdd('p3dcparse.exe', input='p3dcparser_dcParser.obj') - TargetAdd('p3dcparse.exe', input='p3dcparser_dcLexer.obj') - TargetAdd('p3dcparse.exe', input='dcparse_dcparse.obj') - TargetAdd('p3dcparse.exe', input='libp3direct.dll') - TargetAdd('p3dcparse.exe', input=COMMON_PANDA_LIBS) - TargetAdd('p3dcparse.exe', input='libp3pystub.lib') - TargetAdd('p3dcparse.exe', opts=['ADVAPI', 'PYTHON']) + OPTS=['DIR:direct/src/dcparse', 'DIR:direct/src/dcparser', 'WITHINPANDA', 'ADVAPI'] + PyTargetAdd('dcparse_dcparse.obj', opts=OPTS, input='dcparse.cxx') + PyTargetAdd('p3dcparse.exe', input='p3dcparser_composite1.obj') + PyTargetAdd('p3dcparse.exe', input='p3dcparser_composite2.obj') + PyTargetAdd('p3dcparse.exe', input='p3dcparser_dcParser.obj') + PyTargetAdd('p3dcparse.exe', input='p3dcparser_dcLexer.obj') + PyTargetAdd('p3dcparse.exe', input='dcparse_dcparse.obj') + PyTargetAdd('p3dcparse.exe', input='libp3direct.dll') + PyTargetAdd('p3dcparse.exe', input=COMMON_PANDA_LIBS) + PyTargetAdd('p3dcparse.exe', input='libp3pystub.lib') + PyTargetAdd('p3dcparse.exe', opts=['ADVAPI']) # # DIRECTORY: direct/src/plugin/ @@ -5447,7 +5378,7 @@ if (RTDIST or RUNTIME): if (PkgSkip("PYTHON")==0 and RTDIST): # Freeze VFSImporter and its dependency modules into p3dpython. # Mark panda3d.core as a dependency to make sure to build that first. - TargetAdd('p3dpython_frozen.obj', input='VFSImporter.py', opts=['DIR:direct/src/showbase', 'FREEZE_STARTUP', 'PYTHON']) + TargetAdd('p3dpython_frozen.obj', input='VFSImporter.py', opts=['DIR:direct/src/showbase', 'FREEZE_STARTUP']) TargetAdd('p3dpython_frozen.obj', dep='core.pyd') OPTS += ['PYTHON'] @@ -5479,7 +5410,7 @@ if (RTDIST or RUNTIME): TargetAdd('p3dpythonw.exe', input=COMMON_PANDA_LIBS) TargetAdd('p3dpythonw.exe', input='libp3tinyxml.ilb') TargetAdd('p3dpythonw.exe', input='libp3interrogatedb.dll') - TargetAdd('p3dpythonw.exe', opts=['SUBSYSTEM:WINDOWS', 'PYTHON', 'WINUSER']) + TargetAdd('p3dpythonw.exe', opts=['SUBSYSTEM:WINDOWS', 'WINUSER']) if (PkgSkip("OPENSSL")==0 and RTDIST and False): OPTS=['DIR:direct/src/plugin', 'DIR:panda/src/express', 'OPENSSL'] @@ -6570,45 +6501,41 @@ if (PkgSkip("CONTRIB")==0 and not RUNTIME): TargetAdd('libpandaai.dll', input='p3ai_composite1.obj') TargetAdd('libpandaai.dll', input=COMMON_PANDA_LIBS) - OPTS=['DIR:contrib/src/ai', 'PYTHON'] + OPTS=['DIR:contrib/src/ai'] IGATEFILES=GetDirectoryContents('contrib/src/ai', ["*.h", "*_composite*.cxx"]) TargetAdd('libpandaai.in', opts=OPTS, input=IGATEFILES) TargetAdd('libpandaai.in', opts=['IMOD:panda3d.ai', 'ILIB:libpandaai', 'SRCDIR:contrib/src/ai']) - TargetAdd('libpandaai_igate.obj', input='libpandaai.in', opts=["DEPENDENCYONLY"]) - TargetAdd('ai_module.obj', input='libpandaai.in') - TargetAdd('ai_module.obj', opts=OPTS) - TargetAdd('ai_module.obj', opts=['IMOD:panda3d.ai', 'ILIB:ai', 'IMPORT:panda3d.core']) + PyTargetAdd('ai_module.obj', input='libpandaai.in') + PyTargetAdd('ai_module.obj', opts=OPTS) + PyTargetAdd('ai_module.obj', opts=['IMOD:panda3d.ai', 'ILIB:ai', 'IMPORT:panda3d.core']) - TargetAdd('ai.pyd', input='ai_module.obj') - TargetAdd('ai.pyd', input='libpandaai_igate.obj') - TargetAdd('ai.pyd', input='libpandaai.dll') - TargetAdd('ai.pyd', input='libp3interrogatedb.dll') - TargetAdd('ai.pyd', input=COMMON_PANDA_LIBS) - TargetAdd('ai.pyd', opts=['PYTHON']) + PyTargetAdd('ai.pyd', input='ai_module.obj') + PyTargetAdd('ai.pyd', input='libpandaai_igate.obj') + PyTargetAdd('ai.pyd', input='libpandaai.dll') + PyTargetAdd('ai.pyd', input='libp3interrogatedb.dll') + PyTargetAdd('ai.pyd', input=COMMON_PANDA_LIBS) # # DIRECTORY: contrib/src/rplight/ # if not PkgSkip("CONTRIB") and not PkgSkip("PYTHON") and not RUNTIME: - OPTS=['DIR:contrib/src/rplight', 'BUILDING:RPLIGHT', 'PYTHON'] + OPTS=['DIR:contrib/src/rplight', 'BUILDING:RPLIGHT'] TargetAdd('p3rplight_composite1.obj', opts=OPTS, input='p3rplight_composite1.cxx') IGATEFILES=GetDirectoryContents('contrib/src/rplight', ["*.h", "*_composite*.cxx"]) TargetAdd('libp3rplight.in', opts=OPTS, input=IGATEFILES) TargetAdd('libp3rplight.in', opts=['IMOD:panda3d._rplight', 'ILIB:libp3rplight', 'SRCDIR:contrib/src/rplight']) - TargetAdd('libp3rplight_igate.obj', input='libp3rplight.in', opts=["DEPENDENCYONLY"]) - TargetAdd('rplight_module.obj', input='libp3rplight.in') - TargetAdd('rplight_module.obj', opts=OPTS) - TargetAdd('rplight_module.obj', opts=['IMOD:panda3d._rplight', 'ILIB:_rplight', 'IMPORT:panda3d.core']) + PyTargetAdd('rplight_module.obj', input='libp3rplight.in') + PyTargetAdd('rplight_module.obj', opts=OPTS) + PyTargetAdd('rplight_module.obj', opts=['IMOD:panda3d._rplight', 'ILIB:_rplight', 'IMPORT:panda3d.core']) - TargetAdd('_rplight.pyd', input='rplight_module.obj') - TargetAdd('_rplight.pyd', input='libp3rplight_igate.obj') - TargetAdd('_rplight.pyd', input='p3rplight_composite1.obj') - TargetAdd('_rplight.pyd', input='libp3interrogatedb.dll') - TargetAdd('_rplight.pyd', input=COMMON_PANDA_LIBS) - TargetAdd('_rplight.pyd', opts=['PYTHON']) + PyTargetAdd('_rplight.pyd', input='rplight_module.obj') + PyTargetAdd('_rplight.pyd', input='libp3rplight_igate.obj') + PyTargetAdd('_rplight.pyd', input='p3rplight_composite1.obj') + PyTargetAdd('_rplight.pyd', input='libp3interrogatedb.dll') + PyTargetAdd('_rplight.pyd', input=COMMON_PANDA_LIBS) # # Generate the models directory and samples directory @@ -6876,6 +6803,7 @@ def MakeInstallerNSIS(file, title, installdir): 'SOURCE' : '..', 'PYVER' : SDK["PYTHONVERSION"][6:9], 'REGVIEW' : regview, + 'EXT_SUFFIX' : GetExtensionSuffix(), } if GetHost() == 'windows': @@ -6887,7 +6815,7 @@ def MakeInstallerNSIS(file, title, installdir): for item in nsis_defs.items(): cmd += ' -D%s="%s"' % item - cmd += ' "makepanda\installer.nsi"' + cmd += ' "makepanda\\installer.nsi"' oscmd(cmd) def MakeDebugSymbolArchive(zipname, dirname): @@ -7288,8 +7216,9 @@ def MakeInstallerOSX(): if ((base != "extensions") and (base != "extensions_native")): compileall.compile_dir("dstroot/pythoncode/Developer/Panda3D/direct/"+base) + suffix = GetExtensionSuffix() for base in os.listdir(GetOutputDir()+"/panda3d"): - if base.endswith('.py') or base.endswith('.so'): + if base.endswith('.py') or (base.endswith(suffix) and '.' not in base[:-len(suffix)]): libname = "dstroot/pythoncode/Developer/Panda3D/panda3d/" + base # We really need to specify -R in order not to follow symlinks # On OSX, just specifying -P is not enough to do that. @@ -7577,8 +7506,9 @@ def MakeInstallerAndroid(): if not base.endswith(suffix): continue modname = base[:-len(suffix)] - source = os.path.join(source_dir, base) - copy_library(source, "libpy.panda3d.{}.so".format(modname)) + if '.' not in modname: + source = os.path.join(source_dir, base) + copy_library(source, "libpy.panda3d.{}.so".format(modname)) # Same for standard Python modules. import _ctypes diff --git a/makepanda/makepandacore.py b/makepanda/makepandacore.py index cf89b85e59..7d19a00a19 100644 --- a/makepanda/makepandacore.py +++ b/makepanda/makepandacore.py @@ -3239,6 +3239,8 @@ def WriteEmbeddedStringFile(basename, inputs, string_name=None): ######################################################################## ORIG_EXT = {} +PYABI_SPECIFIC = set() +WARNED_FILES = set() def GetOrigExt(x): return ORIG_EXT[x] @@ -3249,14 +3251,42 @@ def SetOrigExt(x, v): def GetExtensionSuffix(): if sys.version_info >= (3, 0): suffix = sysconfig.get_config_var('EXT_SUFFIX') - if suffix: + if suffix == '.so': + # On my FreeBSD system, this is not set correctly, but SOABI is. + soabi = sysconfig.get_config_var('SOABI') + if soabi: + return '.%s.so' % (soabi) + elif suffix: return suffix + target = GetTarget() if target == 'windows': return '.pyd' else: return '.so' +def GetPythonABI(): + soabi = sysconfig.get_config_var('SOABI') + if soabi: + return soabi + + soabi = 'cpython-%d%d' % (sys.version_info[:2]) + + debug_flag = sysconfig.get_config_var('Py_DEBUG') + if (debug_flag is None and hasattr(sys, 'gettotalrefcount')) or debug_flag: + soabi += 'd' + + malloc_flag = sysconfig.get_config_var('WITH_PYMALLOC') + if malloc_flag is None or malloc_flag: + soabi += 'm' + + if sys.version_info < (3, 3): + usize = sysconfig.get_config_var('Py_UNICODE_SIZE') + if (usize is None and sys.maxunicode == 0x10ffff) or usize == 4: + soabi += 'u' + + return soabi + def CalcLocation(fn, ipath): if fn.startswith("panda3d/") and fn.endswith(".py"): return OUTPUTDIR + "/" + fn @@ -3327,11 +3357,25 @@ def CalcLocation(fn, ipath): return fn -def FindLocation(fn, ipath): +def FindLocation(fn, ipath, pyabi=None): if (GetLinkAllStatic() and fn.endswith(".dll")): fn = fn[:-4] + ".lib" loc = CalcLocation(fn, ipath) base, ext = os.path.splitext(fn) + + # If this is a target created with PyTargetAdd, we need to make sure it + # it put in a Python-version-specific directory. + if loc in PYABI_SPECIFIC: + if loc.startswith(OUTPUTDIR + "/tmp"): + if pyabi is not None: + loc = OUTPUTDIR + "/tmp/" + pyabi + loc[len(OUTPUTDIR) + 4:] + else: + raise RuntimeError("%s is a Python-specific target, use PyTargetAdd instead of TargetAdd" % (fn)) + + elif ext != ".pyd" and loc not in WARNED_FILES: + WARNED_FILES.add(loc) + print("%sWARNING:%s file depends on Python but is not in an ABI-specific directory: %s%s%s" % (GetColor("red"), GetColor(), GetColor("green"), loc, GetColor())) + ORIG_EXT[loc] = ext return loc @@ -3377,6 +3421,11 @@ def FindLocation(fn, ipath): ## be inserted: bison generates an OBJ and a secondary header ## file, interrogate generates an IN and a secondary IGATE.OBJ. ## +## PyTargetAdd is a special version for targets that depend on Python. +## It will create a target for each Python version we are building with, +## ensuring that builds with different Python versions won't conflict +## when we build for multiple Python ABIs side-by-side. +## ######################################################################## class Target: @@ -3385,7 +3434,7 @@ class Target: TARGET_LIST = [] TARGET_TABLE = {} -def TargetAdd(target, dummy=0, opts=[], input=[], dep=[], ipath=None, winrc=None): +def TargetAdd(target, dummy=0, opts=[], input=[], dep=[], ipath=None, winrc=None, pyabi=None): if (dummy != 0): exit("Syntax error in TargetAdd "+target) if ipath is None: ipath = opts @@ -3393,11 +3442,10 @@ def TargetAdd(target, dummy=0, opts=[], input=[], dep=[], ipath=None, winrc=None if (type(input) == str): input = [input] if (type(dep) == str): dep = [dep] - if os.path.splitext(target)[1] == '.pyd' and PkgSkip("PYTHON"): - # It makes no sense to build Python modules with python disabled. - return + if target.endswith(".pyd") and not pyabi: + raise RuntimeError("Use PyTargetAdd to build .pyd targets") - full = FindLocation(target, [OUTPUTDIR + "/include"]) + full = FindLocation(target, [OUTPUTDIR + "/include"], pyabi=pyabi) if (full not in TARGET_TABLE): t = Target() @@ -3416,7 +3464,7 @@ def TargetAdd(target, dummy=0, opts=[], input=[], dep=[], ipath=None, winrc=None ipath = [OUTPUTDIR + "/tmp"] + GetListOption(ipath, "DIR:") + [OUTPUTDIR+"/include"] for x in input: - fullinput = FindLocation(x, ipath) + fullinput = FindLocation(x, ipath, pyabi=pyabi) t.inputs.append(fullinput) # Don't re-link a library or binary if just its dependency dlls have been altered. # This should work out fine in most cases, and often reduces recompilation time. @@ -3455,7 +3503,7 @@ def TargetAdd(target, dummy=0, opts=[], input=[], dep=[], ipath=None, winrc=None t.deps[fulln] = 1 for x in dep: - fulldep = FindLocation(x, ipath) + fulldep = FindLocation(x, ipath, pyabi=pyabi) t.deps[fulldep] = 1 if winrc and GetTarget() == 'windows': @@ -3472,3 +3520,32 @@ def TargetAdd(target, dummy=0, opts=[], input=[], dep=[], ipath=None, winrc=None if target.endswith(".pz") and not CrossCompiling(): t.deps[FindLocation("pzip.exe", [])] = 1 + + if target.endswith(".in"): + # Also add a target to compile the _igate.cxx file into an _igate.obj. + outbase = os.path.basename(target)[:-3] + woutc = OUTPUTDIR + "/tmp/" + outbase + "_igate.cxx" + CxxDependencyCache[woutc] = [] + PyTargetAdd(outbase + "_igate.obj", opts=opts+['PYTHON','BIGOBJ'], input=woutc, dep=target) + + +def PyTargetAdd(target, opts=[], **kwargs): + if PkgSkip("PYTHON"): + return + + if 'PYTHON' not in opts: + opts = opts + ['PYTHON'] + + abi = GetPythonABI() + + MakeDirectory(OUTPUTDIR + "/tmp/" + abi) + + # Mark this target as being a Python-specific target. + orig = CalcLocation(target, [OUTPUTDIR + "/include"]) + PYABI_SPECIFIC.add(orig) + + if orig.startswith(OUTPUTDIR + "/tmp/") and os.path.exists(orig): + print("Removing file %s" % (orig)) + os.unlink(orig) + + TargetAdd(target, opts=opts, pyabi=abi, **kwargs) diff --git a/makepanda/makewheel.py b/makepanda/makewheel.py index 74ee15d7f1..b74ad0116d 100644 --- a/makepanda/makewheel.py +++ b/makepanda/makewheel.py @@ -498,7 +498,7 @@ __version__ = '{0}' for file in os.listdir(panda3d_dir): if file == '__init__.py': pass - elif file.endswith(ext_suffix) or file.endswith('.py'): + elif file.endswith('.py') or (file.endswith(ext_suffix) and '.' not in file[:-len(ext_suffix)]): source_path = os.path.join(panda3d_dir, file) if file.endswith('.pyd') and platform.startswith('cygwin'): From 6e8cb98861c28110e065cc4e1709d90f98708a39 Mon Sep 17 00:00:00 2001 From: rdb Date: Tue, 6 Nov 2018 20:32:37 +0100 Subject: [PATCH 23/26] dtoolbase: fix compile errors with --no-python --- dtool/src/dtoolbase/dtoolbase.h | 2 -- dtool/src/dtoolbase/typeHandle.cxx | 2 ++ dtool/src/dtoolbase/typeHandle.h | 2 ++ dtool/src/dtoolbase/typeRegistry.cxx | 2 ++ dtool/src/dtoolbase/typeRegistry.h | 2 ++ 5 files changed, 8 insertions(+), 2 deletions(-) diff --git a/dtool/src/dtoolbase/dtoolbase.h b/dtool/src/dtoolbase/dtoolbase.h index 2f8e7ca05d..66142427cc 100644 --- a/dtool/src/dtoolbase/dtoolbase.h +++ b/dtool/src/dtoolbase/dtoolbase.h @@ -138,12 +138,10 @@ #endif #endif -#ifdef HAVE_PYTHON // Instead of including the Python headers, which will implicitly add a linker // flag to link in Python, we'll just excerpt the forward declaration of // PyObject. typedef struct _object PyObject; -#endif #ifndef HAVE_EIGEN // If we don't have the Eigen library, don't define LINMATH_ALIGN. diff --git a/dtool/src/dtoolbase/typeHandle.cxx b/dtool/src/dtoolbase/typeHandle.cxx index 30d499bf01..c72c3f9d99 100644 --- a/dtool/src/dtoolbase/typeHandle.cxx +++ b/dtool/src/dtoolbase/typeHandle.cxx @@ -153,6 +153,7 @@ deallocate_array(void *ptr) { PANDA_FREE_ARRAY(ptr); } +#ifdef HAVE_PYTHON /** * Returns the internal void pointer that is stored for interrogate's benefit. */ @@ -165,6 +166,7 @@ get_python_type() const { return nullptr; } } +#endif /** * Return the Index of the BEst fit Classs from a set diff --git a/dtool/src/dtoolbase/typeHandle.h b/dtool/src/dtoolbase/typeHandle.h index ed5ab3f586..094d4abf4a 100644 --- a/dtool/src/dtoolbase/typeHandle.h +++ b/dtool/src/dtoolbase/typeHandle.h @@ -138,7 +138,9 @@ PUBLISHED: MAKE_SEQ_PROPERTY(child_classes, get_num_child_classes, get_child_class); public: +#ifdef HAVE_PYTHON PyObject *get_python_type() const; +#endif void *allocate_array(size_t size) RETURNS_ALIGNED(MEMORY_HOOK_ALIGNMENT); void *reallocate_array(void *ptr, size_t size) RETURNS_ALIGNED(MEMORY_HOOK_ALIGNMENT); diff --git a/dtool/src/dtoolbase/typeRegistry.cxx b/dtool/src/dtoolbase/typeRegistry.cxx index d18ca61244..360dfcd9e4 100644 --- a/dtool/src/dtoolbase/typeRegistry.cxx +++ b/dtool/src/dtoolbase/typeRegistry.cxx @@ -207,6 +207,7 @@ record_alternate_name(TypeHandle type, const string &name) { _lock->unlock(); } +#ifdef HAVE_PYTHON /** * Records the given Python type pointer in the type registry for the benefit * of interrogate. @@ -222,6 +223,7 @@ record_python_type(TypeHandle type, PyObject *python_type) { _lock->unlock(); } +#endif /** * Looks for a previously-registered type of the given name. Returns its diff --git a/dtool/src/dtoolbase/typeRegistry.h b/dtool/src/dtoolbase/typeRegistry.h index 4a6bd5d1e0..43b1b8e41f 100644 --- a/dtool/src/dtoolbase/typeRegistry.h +++ b/dtool/src/dtoolbase/typeRegistry.h @@ -45,7 +45,9 @@ PUBLISHED: void record_derivation(TypeHandle child, TypeHandle parent); void record_alternate_name(TypeHandle type, const std::string &name); +#ifdef HAVE_PYTHON void record_python_type(TypeHandle type, PyObject *python_type); +#endif TypeHandle find_type(const std::string &name) const; TypeHandle find_type_by_id(int id) const; From cb2329b3f1c3094fed5122bc05003d31984b8a43 Mon Sep 17 00:00:00 2001 From: rdb Date: Tue, 6 Nov 2018 20:32:52 +0100 Subject: [PATCH 24/26] travis: add build with --no-python --- .travis.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 728367f785..64cc557d5b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,6 +11,8 @@ matrix: before_install: - export CC=gcc-4.7 - export CXX=g++-4.7 + - compiler: clang + env: PYTHONV=python3 FLAGS=--no-python SKIP_TESTS=1 addons: apt: sources: @@ -42,8 +44,8 @@ install: - $PYTHONV -m pip install pytest script: - $PYTHONV makepanda/makepanda.py --everything --git-commit $TRAVIS_COMMIT $FLAGS --threads 4 - - LD_LIBRARY_PATH=built/lib PYTHONPATH=built $PYTHONV makepanda/test_imports.py - - LD_LIBRARY_PATH=built/lib PYTHONPATH=built $PYTHONV -m pytest -v tests + - test -n "$SKIP_TESTS" || LD_LIBRARY_PATH=built/lib PYTHONPATH=built $PYTHONV makepanda/test_imports.py + - test -n "$SKIP_TESTS" || LD_LIBRARY_PATH=built/lib PYTHONPATH=built $PYTHONV -m pytest -v tests notifications: irc: channels: From 98e767c3709e406f5ada64463578cc69c6cc9495 Mon Sep 17 00:00:00 2001 From: rdb Date: Tue, 6 Nov 2018 20:33:56 +0100 Subject: [PATCH 25/26] fmod: fix FmodAudioSound::get_speaker_mix() --- panda/src/audiotraits/fmodAudioSound.cxx | 2 +- panda/src/audiotraits/fmodAudioSound.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/panda/src/audiotraits/fmodAudioSound.cxx b/panda/src/audiotraits/fmodAudioSound.cxx index dd060844e9..d8560658a7 100644 --- a/panda/src/audiotraits/fmodAudioSound.cxx +++ b/panda/src/audiotraits/fmodAudioSound.cxx @@ -651,7 +651,7 @@ get_3d_max_distance() const { * a balance [pan] function what is the point? */ PN_stdfloat FmodAudioSound:: -get_speaker_mix(AudioManager::SpeakerId speaker) { +get_speaker_mix(int speaker) { ReMutexHolder holder(FmodAudioManager::_lock); if (_channel == 0) { return 0.0; diff --git a/panda/src/audiotraits/fmodAudioSound.h b/panda/src/audiotraits/fmodAudioSound.h index 40de00823d..922ee976b7 100644 --- a/panda/src/audiotraits/fmodAudioSound.h +++ b/panda/src/audiotraits/fmodAudioSound.h @@ -126,7 +126,7 @@ public: AudioSound::SoundStatus status() const; - virtual PN_stdfloat get_speaker_mix(AudioManager::SpeakerId speaker); + virtual PN_stdfloat get_speaker_mix(int speaker); virtual void set_speaker_mix(PN_stdfloat frontleft, PN_stdfloat frontright, PN_stdfloat center, PN_stdfloat sub, PN_stdfloat backleft, PN_stdfloat backright, PN_stdfloat sideleft, PN_stdfloat sideright); void set_active(bool active=true); From b8ed9b1275a6aad914d9790f4e2cc2aa8b2d36f1 Mon Sep 17 00:00:00 2001 From: rdb Date: Tue, 6 Nov 2018 21:49:17 +0100 Subject: [PATCH 26/26] Remove pystub dependency from interrogate and friends --- dtool/src/interrogate/interrogate.cxx | 3 --- dtool/src/interrogate/interrogate_module.cxx | 3 --- dtool/src/interrogate/parse_file.cxx | 3 --- dtool/src/test_interrogate/test_interrogate.cxx | 3 --- makepanda/makepanda.py | 5 ----- 5 files changed, 17 deletions(-) diff --git a/dtool/src/interrogate/interrogate.cxx b/dtool/src/interrogate/interrogate.cxx index 964d38020c..ef06833324 100644 --- a/dtool/src/interrogate/interrogate.cxx +++ b/dtool/src/interrogate/interrogate.cxx @@ -19,7 +19,6 @@ #include "pnotify.h" #include "panda_getopt_long.h" #include "preprocess_argv.h" -#include "pystub.h" #include using std::cerr; @@ -309,8 +308,6 @@ predefine_macro(CPPParser& parser, const string& inoption) { int main(int argc, char **argv) { - pystub(); - preprocess_argv(argc, argv); string command_line; int i; diff --git a/dtool/src/interrogate/interrogate_module.cxx b/dtool/src/interrogate/interrogate_module.cxx index 586889ed77..6f7bc4bfeb 100644 --- a/dtool/src/interrogate/interrogate_module.cxx +++ b/dtool/src/interrogate/interrogate_module.cxx @@ -19,7 +19,6 @@ #include "interrogate_interface.h" #include "interrogate_request.h" #include "load_dso.h" -#include "pystub.h" #include "pnotify.h" #include "panda_getopt_long.h" #include "preprocess_argv.h" @@ -541,8 +540,6 @@ int main(int argc, char *argv[]) { extern int optind; int flag; - pystub(); - preprocess_argv(argc, argv); flag = getopt_long_only(argc, argv, short_options, long_options, nullptr); while (flag != EOF) { diff --git a/dtool/src/interrogate/parse_file.cxx b/dtool/src/interrogate/parse_file.cxx index aa903407d1..0b8ff924ec 100644 --- a/dtool/src/interrogate/parse_file.cxx +++ b/dtool/src/interrogate/parse_file.cxx @@ -22,7 +22,6 @@ #include "cppGlobals.h" #include "panda_getopt_long.h" #include "preprocess_argv.h" -#include "pystub.h" #include using std::cerr; @@ -206,8 +205,6 @@ show_nested_types(const string &str) { int main(int argc, char **argv) { - pystub(); - extern char *optarg; extern int optind; const char *optstr = "I:S:D:o:l:vp"; diff --git a/dtool/src/test_interrogate/test_interrogate.cxx b/dtool/src/test_interrogate/test_interrogate.cxx index 590b8ac873..426de102de 100644 --- a/dtool/src/test_interrogate/test_interrogate.cxx +++ b/dtool/src/test_interrogate/test_interrogate.cxx @@ -17,7 +17,6 @@ #include "interrogate_request.h" #include "load_dso.h" #include "filename.h" -#include "pystub.h" #include "panda_getopt.h" #include "preprocess_argv.h" @@ -526,8 +525,6 @@ main(int argc, char **argv) { extern int optind; const char *optstr = "p:ftqh"; - pystub(); - bool all_functions = false; bool all_types = false; bool quick_load = false; diff --git a/makepanda/makepanda.py b/makepanda/makepanda.py index 2689205461..2983b845e3 100755 --- a/makepanda/makepanda.py +++ b/makepanda/makepanda.py @@ -3478,7 +3478,6 @@ if (not RUNTIME): TargetAdd('interrogate.exe', input='libp3cppParser.ilb') TargetAdd('interrogate.exe', input=COMMON_DTOOL_LIBS) TargetAdd('interrogate.exe', input='libp3interrogatedb.dll') - TargetAdd('interrogate.exe', input='libp3pystub.lib') TargetAdd('interrogate.exe', opts=['ADVAPI', 'OPENSSL', 'WINSHELL', 'WINGDI', 'WINUSER']) preamble = WriteEmbeddedStringFile('interrogate_preamble_python_native', inputs=[ @@ -3494,7 +3493,6 @@ if (not RUNTIME): TargetAdd('interrogate_module.exe', input='libp3cppParser.ilb') TargetAdd('interrogate_module.exe', input=COMMON_DTOOL_LIBS) TargetAdd('interrogate_module.exe', input='libp3interrogatedb.dll') - TargetAdd('interrogate_module.exe', input='libp3pystub.lib') TargetAdd('interrogate_module.exe', opts=['ADVAPI', 'OPENSSL', 'WINSHELL', 'WINGDI', 'WINUSER']) if (not RTDIST): @@ -3503,7 +3501,6 @@ if (not RUNTIME): TargetAdd('parse_file.exe', input='libp3cppParser.ilb') TargetAdd('parse_file.exe', input=COMMON_DTOOL_LIBS) TargetAdd('parse_file.exe', input='libp3interrogatedb.dll') - TargetAdd('parse_file.exe', input='libp3pystub.lib') TargetAdd('parse_file.exe', opts=['ADVAPI', 'OPENSSL', 'WINSHELL', 'WINGDI', 'WINUSER']) # @@ -3527,7 +3524,6 @@ if (not RTDIST and not RUNTIME): TargetAdd('test_interrogate.exe', input='test_interrogate_test_interrogate.obj') TargetAdd('test_interrogate.exe', input='libp3interrogatedb.dll') TargetAdd('test_interrogate.exe', input=COMMON_DTOOL_LIBS) - TargetAdd('test_interrogate.exe', input='libp3pystub.lib') TargetAdd('test_interrogate.exe', opts=['ADVAPI', 'OPENSSL', 'WINSHELL', 'WINGDI', 'WINUSER']) # @@ -6280,7 +6276,6 @@ if not PkgSkip("PANDATOOL") and not PkgSkip("EGG"): # TargetAdd('bin2c.exe', input='libp3progbase.lib') # TargetAdd('bin2c.exe', input='libp3pandatoolbase.lib') # TargetAdd('bin2c.exe', input=COMMON_PANDA_LIBS) -# TargetAdd('bin2c.exe', input='libp3pystub.lib') # TargetAdd('bin2c.exe', opts=['ADVAPI']) #