From c03a75d755eb3aa79e2d6364b9d8e638d6ac5004 Mon Sep 17 00:00:00 2001 From: rdb Date: Sat, 30 Jun 2018 17:18:14 +0200 Subject: [PATCH 001/125] interrogate: use range for in various places for code cleanliness --- .../interfaceMakerPythonNative.cxx | 199 +++++------------- 1 file changed, 53 insertions(+), 146 deletions(-) diff --git a/dtool/src/interrogate/interfaceMakerPythonNative.cxx b/dtool/src/interrogate/interfaceMakerPythonNative.cxx index 6a47257eda..7961286874 100644 --- a/dtool/src/interrogate/interfaceMakerPythonNative.cxx +++ b/dtool/src/interrogate/interfaceMakerPythonNative.cxx @@ -673,12 +673,7 @@ get_valid_child_classes(std::map &answer, CPPStructTyp return; } - CPPStructType::Derivation::const_iterator bi; - for (bi = inclass->_derivation.begin(); - bi != inclass->_derivation.end(); - ++bi) { - - const CPPStructType::Base &base = (*bi); + for (const CPPStructType::Base &base : inclass->_derivation) { // if (base._vis <= V_public) can_downcast = false; CPPStructType *base_type = TypeManager::resolve_type(base._base)->as_struct_type(); if (base_type != nullptr) { @@ -801,11 +796,10 @@ write_prototypes(ostream &out_code, ostream *out_h) { } /* - for (fi = _functions.begin(); fi != _functions.end(); ++fi) - { - Function *func = (*fi); - if (!func->_itype.is_global() && is_function_legal(func)) - write_prototype_for (out_code, func); + for (Function *func : _functions) { + if (!func->_itype.is_global() && is_function_legal(func)) { + write_prototype_for(out_code, func); + } } */ @@ -828,8 +822,7 @@ write_prototypes(ostream &out_code, ostream *out_h) { out_code << " * Extern declarations for imported classes\n"; out_code << " */\n"; - for (std::set::iterator ii = _external_imports.begin(); ii != _external_imports.end(); ii++) { - CPPType *type = (*ii); + for (CPPType *type : _external_imports) { string class_name = type->get_local_name(&parser); string safe_name = make_safe_name(class_name); @@ -926,15 +919,13 @@ write_prototypes_class(ostream &out_code, ostream *out_h, Object *obj) { out_code << " */\n"; /* - for (fi = obj->_methods.begin(); fi != obj->_methods.end(); ++fi) { - Function *func = (*fi); + for (Function *func : obj->_methods) { write_prototype_for(out_code, func); } */ /* - for (fi = obj->_constructors.begin(); fi != obj->_constructors.end(); ++fi) { - Function *func = (*fi); + for (Function *func : obj->_constructors) { std::string fname = "int Dtool_Init_" + ClassName + "(PyObject *self, PyObject *args, PyObject *kwds)"; write_prototype_for_name(out_code, obj, func, fname); } @@ -993,9 +984,6 @@ write_functions(ostream &out) { */ void InterfaceMakerPythonNative:: write_class_details(ostream &out, Object *obj) { - Functions::iterator fi; - Function::Remaps::const_iterator ri; - // std::string cClassName = obj->_itype.get_scoped_name(); std::string ClassName = make_safe_name(obj->_itype.get_scoped_name()); std::string cClassName = obj->_itype.get_true_name(); @@ -1005,8 +993,7 @@ write_class_details(ostream &out, Object *obj) { out << " */\n"; // First write out all the wrapper functions for the methods. - for (fi = obj->_methods.begin(); fi != obj->_methods.end(); ++fi) { - Function *func = (*fi); + for (Function *func : obj->_methods) { if (func) { // Write the definition of the generic wrapper function for this // function. @@ -1015,18 +1002,13 @@ write_class_details(ostream &out, Object *obj) { } // Now write out generated getters and setters for the properties. - Properties::const_iterator pit; - for (pit = obj->_properties.begin(); pit != obj->_properties.end(); ++pit) { - Property *property = (*pit); - + for (Property *property : obj->_properties) { write_getset(out, obj, property); } // Write the constructors. std::string fname = "static int Dtool_Init_" + ClassName + "(PyObject *self, PyObject *args, PyObject *kwds)"; - for (fi = obj->_constructors.begin(); fi != obj->_constructors.end(); ++fi) { - Function *func = (*fi); - + for (Function *func : obj->_constructors) { string expected_params; write_function_for_name(out, obj, func->_remaps, fname, expected_params, true, AT_keyword_args, RF_int); } @@ -1052,17 +1034,16 @@ write_class_details(ostream &out, Object *obj) { } // Write make seqs: generated methods that return a sequence of items. - MakeSeqs::iterator msi; - for (msi = obj->_make_seqs.begin(); msi != obj->_make_seqs.end(); ++msi) { - if (is_function_legal((*msi)->_length_getter) && - is_function_legal((*msi)->_element_getter)) { - write_make_seq(out, obj, ClassName, cClassName, *msi); + for (MakeSeq *make_seq : obj->_make_seqs) { + if (is_function_legal(make_seq->_length_getter) && + is_function_legal(make_seq->_element_getter)) { + write_make_seq(out, obj, ClassName, cClassName, make_seq); } else { - if (!is_function_legal((*msi)->_length_getter)) { - std::cerr << "illegal length function for MAKE_SEQ: " << (*msi)->_length_getter->_name << "\n"; + if (!is_function_legal(make_seq->_length_getter)) { + std::cerr << "illegal length function for MAKE_SEQ: " << make_seq->_length_getter->_name << "\n"; } - if (!is_function_legal((*msi)->_element_getter)) { - std::cerr << "illegal element function for MAKE_SEQ: " << (*msi)->_element_getter->_name << "\n"; + if (!is_function_legal(make_seq->_element_getter)) { + std::cerr << "illegal element function for MAKE_SEQ: " << make_seq->_element_getter->_name << "\n"; } } } @@ -1297,11 +1278,11 @@ write_module_support(ostream &out, ostream *out_h, InterrogateModuleDef *def) { out << "#ifndef LINK_ALL_STATIC\n"; out << " // Resolve externally imported types.\n"; - for (std::set::iterator ii = _external_imports.begin(); ii != _external_imports.end(); ++ii) { - string class_name = (*ii)->get_local_name(&parser); + 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(*ii)) { + 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"; @@ -1555,7 +1536,6 @@ write_module_class(ostream &out, Object *obj) { is_runtime_typed = true; } - Functions::iterator fi; out << "/**\n"; out << " * Python method tables for " << ClassName << " (" << export_class_name << ")\n" ; out << " */\n"; @@ -1566,8 +1546,7 @@ write_module_class(ostream &out, Object *obj) { bool got_copy = false; bool got_deepcopy = false; - for (fi = obj->_methods.begin(); fi != obj->_methods.end(); ++fi) { - Function *func = (*fi); + for (Function *func : obj->_methods) { if (func->_name == "__copy__") { got_copy = true; } else if (func->_name == "__deepcopy__") { @@ -1604,9 +1583,7 @@ write_module_class(ostream &out, Object *obj) { bool has_nonslotted = false; - Function::Remaps::const_iterator ri; - for (ri = func->_remaps.begin(); ri != func->_remaps.end(); ++ri) { - FunctionRemap *remap = (*ri); + for (FunctionRemap *remap : func->_remaps) { if (!is_remap_legal(remap)) { continue; } @@ -1698,9 +1675,7 @@ write_module_class(ostream &out, Object *obj) { out << " {\"__deepcopy__\", &map_deepcopy_to_copy, METH_VARARGS, nullptr},\n"; } - MakeSeqs::iterator msi; - for (msi = obj->_make_seqs.begin(); msi != obj->_make_seqs.end(); ++msi) { - MakeSeq *make_seq = (*msi); + for (MakeSeq *make_seq : obj->_make_seqs) { if (!is_function_legal(make_seq->_length_getter) || !is_function_legal(make_seq->_element_getter)) { continue; @@ -1876,10 +1851,7 @@ write_module_class(ostream &out, Object *obj) { // This function handles both delattr and setattr. Fish out the // remaps for both types. - set::const_iterator ri; - for (ri = def._remaps.begin(); ri != def._remaps.end(); ++ri) { - FunctionRemap *remap = (*ri); - + for (FunctionRemap *remap : def._remaps) { if (remap->_cppfunc->get_simple_name() == "__delattr__" && remap->_parameters.size() == 2) { delattr_remaps.insert(remap); @@ -2029,10 +2001,7 @@ write_module_class(ostream &out, Object *obj) { // This function handles both delitem and setitem. Fish out the // remaps for either one. - set::const_iterator ri; - for (ri = def._remaps.begin(); ri != def._remaps.end(); ++ri) { - FunctionRemap *remap = (*ri); - + for (FunctionRemap *remap : def._remaps) { if (remap->_flags & FunctionRemap::F_setitem_int) { setitem_remaps.insert(remap); @@ -2098,10 +2067,7 @@ write_module_class(ostream &out, Object *obj) { // This function handles both delitem and setitem. Fish out the // remaps for either one. - set::const_iterator ri; - for (ri = def._remaps.begin(); ri != def._remaps.end(); ++ri) { - FunctionRemap *remap = (*ri); - + for (FunctionRemap *remap : def._remaps) { if (remap->_flags & FunctionRemap::F_setitem) { setitem_remaps.insert(remap); @@ -2185,9 +2151,7 @@ write_module_class(ostream &out, Object *obj) { // Iterate through the remaps to find the one that matches our // parameters. - set::const_iterator ri; - for (ri = def._remaps.begin(); ri != def._remaps.end(); ++ri) { - FunctionRemap *remap = (*ri); + for (FunctionRemap *remap : def._remaps) { if (remap->_const_method) { if ((remap->_flags & FunctionRemap::F_explicit_self) == 0) { params_const.push_back("self"); @@ -2254,9 +2218,7 @@ write_module_class(ostream &out, Object *obj) { // Iterate through the remaps to find the one that matches our // parameters. - set::const_iterator ri; - for (ri = def._remaps.begin(); ri != def._remaps.end(); ++ri) { - FunctionRemap *remap = (*ri); + for (FunctionRemap *remap : def._remaps) { if (remap->_const_method) { if ((remap->_flags & FunctionRemap::F_explicit_self) == 0) { params_const.push_back("self"); @@ -2340,10 +2302,7 @@ write_module_class(ostream &out, Object *obj) { set one_param_remaps; set two_param_remaps; - set::const_iterator ri; - for (ri = def._remaps.begin(); ri != def._remaps.end(); ++ri) { - FunctionRemap *remap = (*ri); - + for (FunctionRemap *remap : def._remaps) { if (remap->_parameters.size() == 2) { one_param_remaps.insert(remap); @@ -2537,17 +2496,14 @@ write_module_class(ostream &out, Object *obj) { out << " return nullptr;\n"; out << " }\n\n"; - for (fi = obj->_methods.begin(); fi != obj->_methods.end(); ++fi) { + for (Function *func : obj->_methods) { std::set remaps; - Function *func = (*fi); if (!func) { continue; } // We only accept comparison operators that take one parameter (besides // 'this'). - Function::Remaps::const_iterator ri; - for (ri = func->_remaps.begin(); ri != func->_remaps.end(); ++ri) { - FunctionRemap *remap = (*ri); + for (FunctionRemap *remap : func->_remaps) { if (is_remap_legal(remap) && remap->_has_this && (remap->_args_type == AT_single_arg)) { remaps.insert(remap); } @@ -2634,9 +2590,7 @@ write_module_class(ostream &out, Object *obj) { if (obj->_properties.size() > 0) { // Write out the array of properties, telling Python which getter and // setter to call when they are assigned or queried in Python code. - Properties::const_iterator pit; - for (pit = obj->_properties.begin(); pit != obj->_properties.end(); ++pit) { - Property *property = (*pit); + for (Property *property : obj->_properties) { const InterrogateElement &ielem = property->_ielement; if (!property->_has_this || property->_getter_remaps.empty()) { continue; @@ -3060,10 +3014,10 @@ write_module_class(ostream &out, Object *obj) { out << " // Dependent objects\n"; if (bases.size() > 0) { string baseargs; - for (std::vector::iterator bi = bases.begin(); bi != bases.end(); ++bi) { - string safe_name = make_safe_name((*bi)->get_local_name(&parser)); + for (CPPType *base : bases) { + string safe_name = make_safe_name(base->get_local_name(&parser)); - if (isExportThisRun(*bi)) { + if (isExportThisRun(base)) { baseargs += ", (PyTypeObject *)&Dtool_" + safe_name; out << " Dtool_PyModuleClassInit_" << safe_name << "(nullptr);\n"; @@ -3207,9 +3161,7 @@ write_module_class(ostream &out, Object *obj) { } // Also add the static properties, which can't be added via getset. - Properties::const_iterator pit; - for (pit = obj->_properties.begin(); pit != obj->_properties.end(); ++pit) { - Property *property = (*pit); + for (Property *property : obj->_properties) { const InterrogateElement &ielem = property->_ielement; if (property->_has_this || property->_getter_remaps.empty()) { continue; @@ -3354,9 +3306,7 @@ write_function_for_top(ostream &out, InterfaceMaker::Object *obj, InterfaceMaker // should even write it. bool has_remaps = false; - Function::Remaps::const_iterator ri; - for (ri = func->_remaps.begin(); ri != func->_remaps.end(); ++ri) { - FunctionRemap *remap = (*ri); + for (FunctionRemap *remap : func->_remaps) { if (!is_remap_legal(remap)) { continue; } @@ -3805,18 +3755,12 @@ void InterfaceMakerPythonNative:: write_coerce_constructor(ostream &out, Object *obj, bool is_const) { std::map > map_sets; std::map >::iterator mii; - std::set::iterator sii; int max_required_args = 0; - Functions::iterator fi; - Function::Remaps::const_iterator ri; - // Go through the methods and find appropriate static make() functions. - for (fi = obj->_methods.begin(); fi != obj->_methods.end(); ++fi) { - Function *func = (*fi); - for (ri = func->_remaps.begin(); ri != func->_remaps.end(); ++ri) { - FunctionRemap *remap = (*ri); + for (Function *func : obj->_methods) { + for (FunctionRemap *remap : func->_remaps) { if (is_remap_legal(remap) && remap->_flags & FunctionRemap::F_coerce_constructor) { nassertd(!remap->_has_this) continue; @@ -3850,10 +3794,8 @@ write_coerce_constructor(ostream &out, Object *obj, bool is_const) { // Now go through the constructors that are suitable for coercion. This // excludes copy constructors and ones marked "explicit". - for (fi = obj->_constructors.begin(); fi != obj->_constructors.end(); ++fi) { - Function *func = (*fi); - for (ri = func->_remaps.begin(); ri != func->_remaps.end(); ++ri) { - FunctionRemap *remap = (*ri); + for (Function *func : obj->_constructors) { + for (FunctionRemap *remap : func->_remaps) { if (is_remap_legal(remap) && remap->_flags & FunctionRemap::F_coerce_constructor) { nassertd(!remap->_has_this) continue; @@ -6504,11 +6446,7 @@ write_getset(ostream &out, Object *obj, Property *property) { std::set remaps; // Extract only the getters that take one integral argument. - Function::Remaps::iterator it; - for (it = property->_getter_remaps.begin(); - it != property->_getter_remaps.end(); - ++it) { - FunctionRemap *remap = *it; + for (FunctionRemap *remap : property->_getter_remaps) { int min_num_args = remap->get_min_num_args(); int max_num_args = remap->get_max_num_args(); if (min_num_args <= 1 && max_num_args >= 1 && @@ -6573,11 +6511,7 @@ write_getset(ostream &out, Object *obj, Property *property) { std::set remaps; // Extract only the setters that take two arguments. - Function::Remaps::iterator it; - for (it = property->_setter_remaps.begin(); - it != property->_setter_remaps.end(); - ++it) { - FunctionRemap *remap = *it; + for (FunctionRemap *remap : property->_setter_remaps) { int min_num_args = remap->get_min_num_args(); int max_num_args = remap->get_max_num_args(); if (min_num_args <= 2 && max_num_args >= 2 && @@ -6675,11 +6609,7 @@ write_getset(ostream &out, Object *obj, Property *property) { std::set remaps; // Extract only the getters that take one argument. Fish out the ones // already taken by the sequence getter. - Function::Remaps::iterator it; - for (it = property->_getter_remaps.begin(); - it != property->_getter_remaps.end(); - ++it) { - FunctionRemap *remap = *it; + for (FunctionRemap *remap : property->_getter_remaps) { int min_num_args = remap->get_min_num_args(); int max_num_args = remap->get_max_num_args(); if (min_num_args <= 1 && max_num_args >= 1 && @@ -6808,11 +6738,7 @@ write_getset(ostream &out, Object *obj, Property *property) { std::set remaps; // Extract only the getters that take one integral argument. - Function::Remaps::iterator it; - for (it = property->_getkey_function->_remaps.begin(); - it != property->_getkey_function->_remaps.end(); - ++it) { - FunctionRemap *remap = *it; + for (FunctionRemap *remap : property->_getkey_function->_remaps) { int min_num_args = remap->get_min_num_args(); int max_num_args = remap->get_max_num_args(); if (min_num_args <= 1 && max_num_args >= 1 && @@ -6969,11 +6895,7 @@ write_getset(ostream &out, Object *obj, Property *property) { std::set remaps; // Extract only the setters that take one argument. - Function::Remaps::iterator it; - for (it = property->_setter_remaps.begin(); - it != property->_setter_remaps.end(); - ++it) { - FunctionRemap *remap = *it; + for (FunctionRemap *remap : property->_setter_remaps) { int min_num_args = remap->get_min_num_args(); int max_num_args = remap->get_max_num_args(); if (min_num_args <= 1 && max_num_args >= 1) { @@ -7362,9 +7284,7 @@ isExportThisRun(Function *func) { return false; } - Function::Remaps::const_iterator ri; - for (ri = func->_remaps.begin(); ri != func->_remaps.end();) { - FunctionRemap *remap = (*ri); + for (FunctionRemap *remap : func->_remaps) { return isExportThisRun(remap->_cpptype); } @@ -7439,10 +7359,7 @@ has_coerce_constructor(CPPStructType *type) { CPPScope::Functions::iterator fgi; for (fgi = scope->_functions.begin(); fgi != scope->_functions.end(); ++fgi) { CPPFunctionGroup *fgroup = fgi->second; - - CPPFunctionGroup::Instances::iterator ii; - for (ii = fgroup->_instances.begin(); ii != fgroup->_instances.end(); ++ii) { - CPPInstance *inst = (*ii); + for (CPPInstance *inst : fgroup->_instances) { CPPFunctionType *ftype = inst->_type->as_function_type(); if (ftype == nullptr) { continue; @@ -7527,9 +7444,7 @@ is_remap_coercion_possible(FunctionRemap *remap) { */ bool InterfaceMakerPythonNative:: is_function_legal(Function *func) { - Function::Remaps::const_iterator ri; - for (ri = func->_remaps.begin(); ri != func->_remaps.end(); ++ri) { - FunctionRemap *remap = (*ri); + for (FunctionRemap *remap : func->_remaps) { if (is_remap_legal(remap)) { // printf(" Function Is Marked Legal %s\n",func->_name.c_str()); @@ -7575,13 +7490,7 @@ DoesInheritFromIsClass(const CPPStructType *inclass, const std::string &name) { return true; } - CPPStructType::Derivation::const_iterator bi; - for (bi = inclass->_derivation.begin(); - bi != inclass->_derivation.end(); - ++bi) { - - const CPPStructType::Base &base = (*bi); - + for (const CPPStructType::Base &base : inclass->_derivation) { CPPStructType *base_type = TypeManager::resolve_type(base._base)->as_struct_type(); if (base_type != nullptr) { if (DoesInheritFromIsClass(base_type, name)) { @@ -7632,9 +7541,7 @@ has_init_type_function(CPPType *type) { } const CPPFunctionGroup *group = it->second; - CPPFunctionGroup::Instances::const_iterator ii; - for (ii = group->_instances.begin(); ii != group->_instances.end(); ++ii) { - const CPPInstance *cppinst = *ii; + for (const CPPInstance *cppinst : group->_instances) { const CPPFunctionType *cppfunc = cppinst->_type->as_function_type(); if (cppfunc != nullptr && From 94cbdc563b0ddf802e7b3ba0ed6578c4c6d0316b Mon Sep 17 00:00:00 2001 From: rdb Date: Sat, 30 Jun 2018 17:19:23 +0200 Subject: [PATCH 002/125] general: fix a few more compiler warnings --- panda/src/glstuff/glCgShaderContext_src.cxx | 2 +- panda/src/glstuff/glGraphicsStateGuardian_src.cxx | 4 +++- panda/src/x11display/x11GraphicsWindow.cxx | 4 +--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/panda/src/glstuff/glCgShaderContext_src.cxx b/panda/src/glstuff/glCgShaderContext_src.cxx index 353c68dc46..c7ba6ad3e7 100644 --- a/panda/src/glstuff/glCgShaderContext_src.cxx +++ b/panda/src/glstuff/glCgShaderContext_src.cxx @@ -525,7 +525,7 @@ issue_parameters(int altered) { } // Check if the size of the shader input and ptr_data match - int input_size = spec._dim[0] * spec._dim[1] * spec._dim[2]; + size_t input_size = spec._dim[0] * spec._dim[1] * spec._dim[2]; // dimension is negative only if the parameter had the (deprecated)k_ // prefix. diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx index 6958c4ff9a..cde43352bc 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx @@ -11610,17 +11610,18 @@ do_issue_tex_gen() { // effectively define an identity matrix that maps the spatial coordinates // one-for-one to UV's. If you want a mapping other than identity, use a // TexMatrixAttrib (or a TexProjectorEffect). +#ifndef OPENGLES static const PN_stdfloat s_data[4] = { 1, 0, 0, 0 }; static const PN_stdfloat t_data[4] = { 0, 1, 0, 0 }; static const PN_stdfloat r_data[4] = { 0, 0, 1, 0 }; static const PN_stdfloat q_data[4] = { 0, 0, 0, 1 }; +#endif _tex_gen_modifies_mat = false; bool got_point_sprites = false; for (int i = 0; i < _num_active_texture_stages; i++) { - TextureStage *stage = _target_texture->get_on_ff_stage(i); set_active_texture_stage(i); if (_supports_point_sprite) { #ifdef OPENGLES @@ -11636,6 +11637,7 @@ do_issue_tex_gen() { glDisable(GL_TEXTURE_GEN_R); glDisable(GL_TEXTURE_GEN_Q); + TextureStage *stage = _target_texture->get_on_ff_stage(i); TexGenAttrib::Mode mode = _target_tex_gen->get_mode(stage); switch (mode) { case TexGenAttrib::M_off: diff --git a/panda/src/x11display/x11GraphicsWindow.cxx b/panda/src/x11display/x11GraphicsWindow.cxx index 41fa95571d..5eef6b2ea5 100644 --- a/panda/src/x11display/x11GraphicsWindow.cxx +++ b/panda/src/x11display/x11GraphicsWindow.cxx @@ -1382,9 +1382,7 @@ open_raw_mice() { void x11GraphicsWindow:: poll_raw_mice() { #ifdef PHAVE_LINUX_INPUT_H - for (int di = 0; di < _mouse_device_info.size(); ++di) { - MouseDeviceInfo &inf = _mouse_device_info[di]; - + for (MouseDeviceInfo &inf : _mouse_device_info) { // Read all bytes into buffer. if (inf._fd >= 0) { while (1) { From b2c04a8c7acde07c76fad045db75a7eb975c12d2 Mon Sep 17 00:00:00 2001 From: rdb Date: Sat, 30 Jun 2018 17:33:09 +0200 Subject: [PATCH 003/125] interrogate: support scoped enum args and return values --- .../interfaceMakerPythonNative.cxx | 86 +++++++++++++++++-- dtool/src/interrogate/typeManager.cxx | 20 +++++ dtool/src/interrogate/typeManager.h | 1 + dtool/src/interrogatedb/py_panda.I | 14 +++ dtool/src/interrogatedb/py_panda.cxx | 5 +- dtool/src/interrogatedb/py_panda.h | 6 +- 6 files changed, 121 insertions(+), 11 deletions(-) diff --git a/dtool/src/interrogate/interfaceMakerPythonNative.cxx b/dtool/src/interrogate/interfaceMakerPythonNative.cxx index 7961286874..6f300eed03 100644 --- a/dtool/src/interrogate/interfaceMakerPythonNative.cxx +++ b/dtool/src/interrogate/interfaceMakerPythonNative.cxx @@ -815,6 +815,11 @@ write_prototypes(ostream &out_code, ostream *out_h) { // _external_imports.insert(object->_itype._cpptype); } } + } else if (object->_itype.is_scoped_enum() && isExportThisRun(object->_itype._cpptype)) { + // Forward declare where we will put the scoped enum type. + string class_name = object->_itype._cpptype->get_local_name(&parser); + string safe_name = make_safe_name(class_name); + out_code << "static PyTypeObject *Dtool_Ptr_" << safe_name << " = nullptr;\n"; } } @@ -1301,7 +1306,10 @@ write_module_support(ostream &out, ostream *out_h, InterrogateModuleDef *def) { int enum_count = object->_itype.number_of_enum_values(); if (object->_itype.is_scoped_enum()) { - // Convert as Python 3.4 enum. + // Convert as Python 3.4-style enum. + string class_name = object->_itype._cpptype->get_local_name(&parser); + string safe_name = make_safe_name(class_name); + CPPType *underlying_type = TypeManager::unwrap_const(object->_itype._cpptype->as_enum_type()->get_underlying_type()); string cast_to = underlying_type->get_local_name(&parser); out << "#if PY_VERSION_HEX >= 0x03040000\n\n"; @@ -1318,9 +1326,11 @@ write_module_support(ostream &out, ostream *out_h, InterrogateModuleDef *def) { << object->_itype.get_enum_value_name(xx) << "));\n" " PyTuple_SET_ITEM(members, " << xx << ", member);\n"; } + out << " Dtool_Ptr_" << safe_name << " = Dtool_EnumType_Create(\"" + << object->_itype.get_name() << "\", members, \"" + << _def->module_name << "\");\n"; out << " PyModule_AddObject(module, \"" << object->_itype.get_name() - << "\", Dtool_EnumType_Create(\"" << object->_itype.get_name() - << "\", members, \"" << _def->module_name << "\"));\n"; + << "\", (PyObject *)Dtool_Ptr_" << safe_name << ");\n"; out << " }\n"; out << "#endif\n"; } else { @@ -3112,7 +3122,10 @@ write_module_class(ostream &out, Object *obj) { // support recently. } else if (nested_obj->_itype.is_scoped_enum()) { - // Convert enum class as Python 3.4 enum. + // Convert enum class as Python 3.4-style enum. + string class_name = nested_obj->_itype._cpptype->get_local_name(&parser); + string safe_name = make_safe_name(class_name); + int enum_count = nested_obj->_itype.number_of_enum_values(); CPPType *underlying_type = TypeManager::unwrap_const(nested_obj->_itype._cpptype->as_enum_type()->get_underlying_type()); string cast_to = underlying_type->get_local_name(&parser); @@ -3130,9 +3143,11 @@ write_module_class(ostream &out, Object *obj) { << nested_obj->_itype.get_enum_value_name(xx) << "));\n" " PyTuple_SET_ITEM(members, " << xx << ", member);\n"; } + out << " Dtool_Ptr_" << safe_name << " = Dtool_EnumType_Create(\"" + << nested_obj->_itype.get_name() << "\", members, \"" + << _def->module_name << "\");\n"; out << " PyDict_SetItemString(dict, \"" << nested_obj->_itype.get_name() - << "\", Dtool_EnumType_Create(\"" << nested_obj->_itype.get_name() - << "\", members, \"" << _def->module_name << "\"));\n"; + << "\", (PyObject *)Dtool_Ptr_" << safe_name << ");\n"; out << " }\n"; out << "#endif\n"; @@ -4821,6 +4836,46 @@ write_function_instance(ostream &out, FunctionRemap *remap, clear_error = true; only_pyobjects = false; + } else if (TypeManager::is_scoped_enum(type)) { + if (args_type == AT_single_arg) { + param_name = "arg"; + } else { + indent(out, indent_level) << "PyObject *" << param_name; + if (default_value != nullptr) { + out << " = nullptr"; + } + out << ";\n"; + format_specifiers += "O"; + parameter_list += ", &" + param_name; + } + + CPPEnumType *enum_type = (CPPEnumType *)TypeManager::unwrap(type); + CPPType *underlying_type = enum_type->get_underlying_type(); + underlying_type = TypeManager::unwrap_const(underlying_type); + + //indent(out, indent_level); + //underlying_type->output_instance(out, param_name + "_val", &parser); + //out << default_expr << ";\n"; + extra_convert << "long " << param_name << "_val"; + + if (default_value != nullptr) { + extra_convert << " = (long)"; + default_value->output(extra_convert, 0, &parser, false); + extra_convert << + ";\nif (" << param_name << " != nullptr) {\n" + " " << param_name << "_val = Dtool_EnumValue_AsLong(" + param_name + ");\n" + "}"; + } else { + extra_convert + << ";\n" + << param_name << "_val = Dtool_EnumValue_AsLong(" + param_name + ");\n"; + } + + pexpr_string = "(" + enum_type->get_local_name(&parser) + ")" + param_name + "_val"; + expected_params += classNameFromCppName(enum_type->get_simple_name(), false); + extra_param_check << " && " << param_name << "_val != -1"; + clear_error = true; + } else if (TypeManager::is_bool(type)) { if (args_type == AT_single_arg) { param_name = "arg"; @@ -6220,7 +6275,24 @@ pack_return_value(ostream &out, int indent_level, FunctionRemap *remap, CPPType *orig_type = return_type->get_orig_type(); CPPType *type = return_type->get_new_type(); - if (return_type->new_type_is_atomic_string() || + if (TypeManager::is_scoped_enum(type)) { + InterrogateDatabase *idb = InterrogateDatabase::get_ptr(); + TypeIndex type_index = builder.get_type(TypeManager::unwrap(TypeManager::resolve_type(orig_type)), false); + const InterrogateType &itype = idb->get_type(type_index); + string safe_name = make_safe_name(itype.get_scoped_name()); + + indent(out, indent_level) + << "return PyObject_CallFunction((PyObject *)Dtool_Ptr_" << safe_name; + + CPPType *underlying_type = ((CPPEnumType *)itype._cpptype)->get_underlying_type(); + if (TypeManager::is_unsigned_integer(underlying_type)) { + out << ", \"k\", (unsigned long)"; + } else { + out << ", \"l\", (long)"; + } + out << "(" << return_expr << "));\n"; + + } else if (return_type->new_type_is_atomic_string() || TypeManager::is_simple(type) || TypeManager::is_char_pointer(type) || TypeManager::is_wchar_pointer(type) || diff --git a/dtool/src/interrogate/typeManager.cxx b/dtool/src/interrogate/typeManager.cxx index b7b744aa86..f12541111d 100644 --- a/dtool/src/interrogate/typeManager.cxx +++ b/dtool/src/interrogate/typeManager.cxx @@ -310,6 +310,26 @@ is_struct(CPPType *type) { } } +/** + * Returns true if the indicated type is an enum class, const or otherwise. + */ +bool TypeManager:: +is_scoped_enum(CPPType *type) { + switch (type->get_subtype()) { + case CPPDeclaration::ST_enum: + return ((CPPEnumType *)type)->is_scoped(); + + case CPPDeclaration::ST_const: + return is_scoped_enum(type->as_const_type()->_wrapped_around); + + case CPPDeclaration::ST_typedef: + return is_scoped_enum(type->as_typedef_type()->_type); + + default: + return false; + } +} + /** * Returns true if the indicated type is some kind of enumerated type, const * or otherwise. diff --git a/dtool/src/interrogate/typeManager.h b/dtool/src/interrogate/typeManager.h index d507e947ef..db831cdafc 100644 --- a/dtool/src/interrogate/typeManager.h +++ b/dtool/src/interrogate/typeManager.h @@ -52,6 +52,7 @@ public: static bool is_pointer(CPPType *type); static bool is_const(CPPType *type); static bool is_struct(CPPType *type); + static bool is_scoped_enum(CPPType *type); static bool is_enum(CPPType *type); static bool is_const_enum(CPPType *type); static bool is_const_ref_to_enum(CPPType *type); diff --git a/dtool/src/interrogatedb/py_panda.I b/dtool/src/interrogatedb/py_panda.I index 540e9ee58d..69f8961463 100644 --- a/dtool/src/interrogatedb/py_panda.I +++ b/dtool/src/interrogatedb/py_panda.I @@ -97,6 +97,20 @@ INLINE PyObject *DtoolInstance_RichComparePointers(PyObject *v1, PyObject *v2, i Py_RETURN_RICHCOMPARE(cmpval, 0, op); } +/** + * Converts the enum value to a C long. + */ +INLINE long Dtool_EnumValue_AsLong(PyObject *value) { + PyObject *val = PyObject_GetAttrString(value, "value"); + if (val != nullptr) { + long as_long = PyLongOrInt_AS_LONG(val); + Py_DECREF(val); + return as_long; + } else { + return -1; + } +} + /** * These functions wrap a pointer for a class that defines get_type_handle(). */ diff --git a/dtool/src/interrogatedb/py_panda.cxx b/dtool/src/interrogatedb/py_panda.cxx index 7e867aacad..9e7563036d 100644 --- a/dtool/src/interrogatedb/py_panda.cxx +++ b/dtool/src/interrogatedb/py_panda.cxx @@ -309,7 +309,7 @@ PyObject *_Dtool_Return(PyObject *value) { /** * Creates a Python 3.4-style enum type. Steals reference to 'names'. */ -PyObject *Dtool_EnumType_Create(const char *name, PyObject *names, const char *module) { +PyTypeObject *Dtool_EnumType_Create(const char *name, PyObject *names, const char *module) { static PyObject *enum_class = nullptr; static PyObject *enum_meta = nullptr; static PyObject *enum_create = nullptr; @@ -330,7 +330,8 @@ PyObject *Dtool_EnumType_Create(const char *name, PyObject *names, const char *m PyObject_SetAttrString(result, "__module__", modstr); Py_DECREF(modstr); } - return result; + nassertr(PyType_Check(result), nullptr); + return (PyTypeObject *)result; } /** diff --git a/dtool/src/interrogatedb/py_panda.h b/dtool/src/interrogatedb/py_panda.h index 258ff66484..7916147e4d 100644 --- a/dtool/src/interrogatedb/py_panda.h +++ b/dtool/src/interrogatedb/py_panda.h @@ -258,8 +258,10 @@ EXPCL_INTERROGATEDB PyObject *_Dtool_Return(PyObject *value); /** * Wrapper around Python 3.4's enum library, which does not have a C API. */ -EXPCL_INTERROGATEDB PyObject *Dtool_EnumType_Create(const char *name, PyObject *names, - const char *module = nullptr); +EXPCL_INTERROGATEDB PyTypeObject *Dtool_EnumType_Create(const char *name, PyObject *names, + const char *module = nullptr); +EXPCL_INTERROGATEDB INLINE long Dtool_EnumValue_AsLong(PyObject *value); + /** From e191ee84f4075bfe103b67bef9b763a2ad1f1a2e Mon Sep 17 00:00:00 2001 From: rdb Date: Sat, 30 Jun 2018 17:34:20 +0200 Subject: [PATCH 004/125] cppparser: class is not implicitly copyable if it has a move ctor --- dtool/src/cppparser/cppStructType.cxx | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/dtool/src/cppparser/cppStructType.cxx b/dtool/src/cppparser/cppStructType.cxx index aba4bdbb60..d0707c4404 100644 --- a/dtool/src/cppparser/cppStructType.cxx +++ b/dtool/src/cppparser/cppStructType.cxx @@ -545,6 +545,13 @@ is_copy_constructible(CPPVisibility min_vis) const { return true; } + if (get_move_constructor() != nullptr || + get_move_assignment_operator() != nullptr) { + // A user-declared move constructor or move assignment operator means that + // the implicitly-declared copy constructor is deleted. + return false; + } + CPPInstance *destructor = get_destructor(); if (destructor != nullptr) { if (destructor->_vis > min_vis) { From 9441c28f61f622dbc7db9bc662914cc7d984e31e Mon Sep 17 00:00:00 2001 From: rdb Date: Sat, 30 Jun 2018 17:34:54 +0200 Subject: [PATCH 005/125] interrogate: do not wrap methods with rvalue arguments This could in theory be supported, but this is not really intuitive from a Python user's point of view. --- .../interfaceMakerPythonNative.cxx | 4 ++++ dtool/src/interrogate/typeManager.cxx | 20 +++++++++++++++++++ dtool/src/interrogate/typeManager.h | 1 + 3 files changed, 25 insertions(+) diff --git a/dtool/src/interrogate/interfaceMakerPythonNative.cxx b/dtool/src/interrogate/interfaceMakerPythonNative.cxx index 6f300eed03..c3611fb4df 100644 --- a/dtool/src/interrogate/interfaceMakerPythonNative.cxx +++ b/dtool/src/interrogate/interfaceMakerPythonNative.cxx @@ -7298,6 +7298,10 @@ is_cpp_type_legal(CPPType *in_ctype) { // bool answer = false; CPPType *type = TypeManager::resolve_type(in_ctype); + if (TypeManager::is_rvalue_reference(type)) { + return false; + } + type = TypeManager::unwrap(type); if (TypeManager::is_void(type)) { diff --git a/dtool/src/interrogate/typeManager.cxx b/dtool/src/interrogate/typeManager.cxx index f12541111d..ab1fbffce3 100644 --- a/dtool/src/interrogate/typeManager.cxx +++ b/dtool/src/interrogate/typeManager.cxx @@ -124,6 +124,26 @@ is_reference(CPPType *type) { } } +/** + * Returns true if the indicated type is some kind of an rvalue reference. + */ +bool TypeManager:: +is_rvalue_reference(CPPType *type) { + switch (type->get_subtype()) { + case CPPDeclaration::ST_const: + return is_rvalue_reference(type->as_const_type()->_wrapped_around); + + case CPPDeclaration::ST_reference: + return type->as_reference_type()->_value_category == CPPReferenceType::VC_rvalue; + + case CPPDeclaration::ST_typedef: + return is_rvalue_reference(type->as_typedef_type()->_type); + + default: + return false; + } +} + /** * Returns true if the indicated type is some kind of a reference or const * reference type at all, false otherwise. diff --git a/dtool/src/interrogate/typeManager.h b/dtool/src/interrogate/typeManager.h index db831cdafc..f1aa2908b1 100644 --- a/dtool/src/interrogate/typeManager.h +++ b/dtool/src/interrogate/typeManager.h @@ -44,6 +44,7 @@ public: static bool is_assignable(CPPType *type); static bool is_reference(CPPType *type); + static bool is_rvalue_reference(CPPType *type); static bool is_ref_to_anything(CPPType *type); static bool is_const_ref_to_anything(CPPType *type); static bool is_const_pointer_to_anything(CPPType *type); From f5a78d599d0ad93dffd53ba8809774cc887fe145 Mon Sep 17 00:00:00 2001 From: rdb Date: Sat, 30 Jun 2018 17:36:08 +0200 Subject: [PATCH 006/125] putil: make LinkedListNode moveable --- panda/src/putil/linkedListNode.I | 36 ++++++++++++++++++++++++++++++++ panda/src/putil/linkedListNode.h | 3 +++ 2 files changed, 39 insertions(+) diff --git a/panda/src/putil/linkedListNode.I b/panda/src/putil/linkedListNode.I index faed3b5c96..a61aaa854c 100644 --- a/panda/src/putil/linkedListNode.I +++ b/panda/src/putil/linkedListNode.I @@ -33,6 +33,25 @@ LinkedListNode(bool) { _prev = this; } +/** + * This move constructor replaces the other link with this one. + */ +INLINE LinkedListNode:: +LinkedListNode(LinkedListNode &&from) noexcept { + if (from._prev != nullptr) { + nassertv(from._prev->_next == &from); + from._prev->_next = this; + } + _prev = from._prev; + if (from._next != nullptr) { + nassertv(from._next->_prev == &from); + from._next->_prev = this; + } + _next = from._next; + from._next = nullptr; + from._prev = nullptr; +} + /** * */ @@ -41,6 +60,23 @@ INLINE LinkedListNode:: nassertv((_next == nullptr && _prev == nullptr) || (_next == this && _prev == this)); } +/** + * Replaces the given other node with this node. + */ +INLINE LinkedListNode &LinkedListNode:: +operator = (LinkedListNode &&from) { + nassertr((_next == nullptr && _prev == nullptr) || (_next == this && _prev == this), *this); + nassertr(from._prev != nullptr && from._next != nullptr, *this); + nassertr(from._prev->_next == &from && from._next->_prev == &from, *this); + from._prev->_next = this; + from._next->_prev = this; + _prev = from._prev; + _next = from._next; + from._next = nullptr; + from._prev = nullptr; + return *this; +} + /** * Returns true if the node is member of any list, false if it has been * removed or never added. The head of a list generally appears to to always diff --git a/panda/src/putil/linkedListNode.h b/panda/src/putil/linkedListNode.h index 9dedbe9e4d..5f8e6f1909 100644 --- a/panda/src/putil/linkedListNode.h +++ b/panda/src/putil/linkedListNode.h @@ -32,8 +32,11 @@ class EXPCL_PANDA_PUTIL LinkedListNode { protected: INLINE LinkedListNode(); INLINE LinkedListNode(bool); + INLINE LinkedListNode(LinkedListNode &&from) noexcept; INLINE ~LinkedListNode(); + INLINE LinkedListNode &operator = (LinkedListNode &&from); + INLINE bool is_on_list() const; INLINE void remove_from_list(); INLINE void insert_before(LinkedListNode *node); From cce21a5bee05b76a52fb4f5b7b13cdedca531e2c Mon Sep 17 00:00:00 2001 From: rdb Date: Mon, 2 Jul 2018 11:54:27 +0200 Subject: [PATCH 007/125] Add .pytest_cache/ directory to .gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index f99867f73a..0b40b42f79 100644 --- a/.gitignore +++ b/.gitignore @@ -59,3 +59,4 @@ __pycache__/ # Test tool cache directories .tox/ .cache/ +.pytest_cache/ From 68e7f681f48e91451d5d42862340a17e74cf9e71 Mon Sep 17 00:00:00 2001 From: rdb Date: Mon, 2 Jul 2018 12:16:35 +0200 Subject: [PATCH 008/125] interrogate: support enum class to limited extent in Python 2 Only the basics are supported; the __members__ or iter interface is not supported at this time. See also #351 for discussion on pulling in enum34 module. --- .../interfaceMakerPythonNative.cxx | 22 +++-- dtool/src/interrogatedb/py_panda.cxx | 86 ++++++++++++++++++- dtool/src/pystub/pystub.cxx | 2 + 3 files changed, 101 insertions(+), 9 deletions(-) diff --git a/dtool/src/interrogate/interfaceMakerPythonNative.cxx b/dtool/src/interrogate/interfaceMakerPythonNative.cxx index c3611fb4df..3134fcb2eb 100644 --- a/dtool/src/interrogate/interfaceMakerPythonNative.cxx +++ b/dtool/src/interrogate/interfaceMakerPythonNative.cxx @@ -1312,15 +1312,19 @@ write_module_support(ostream &out, ostream *out_h, InterrogateModuleDef *def) { CPPType *underlying_type = TypeManager::unwrap_const(object->_itype._cpptype->as_enum_type()->get_underlying_type()); string cast_to = underlying_type->get_local_name(&parser); - out << "#if PY_VERSION_HEX >= 0x03040000\n\n"; out << " // enum class " << object->_itype.get_scoped_name() << "\n"; out << " {\n"; out << " PyObject *members = PyTuple_New(" << enum_count << ");\n"; out << " PyObject *member;\n"; for (int xx = 0; xx < enum_count; xx++) { out << " member = PyTuple_New(2);\n" - " PyTuple_SET_ITEM(member, 0, PyUnicode_FromString(\"" + "#if PY_MAJOR_VERSION >= 3\n" + " PyTuple_SET_ITEM(member, 0, PyUnicode_FromString(\"" << object->_itype.get_enum_value_name(xx) << "\"));\n" + "#else\n" + " PyTuple_SET_ITEM(member, 0, PyString_FromString(\"" + << object->_itype.get_enum_value_name(xx) << "\"));\n" + "#endif\n" " PyTuple_SET_ITEM(member, 1, Dtool_WrapValue((" << cast_to << ")" << object->_itype.get_scoped_name() << "::" << object->_itype.get_enum_value_name(xx) << "));\n" @@ -1332,7 +1336,6 @@ write_module_support(ostream &out, ostream *out_h, InterrogateModuleDef *def) { out << " PyModule_AddObject(module, \"" << object->_itype.get_name() << "\", (PyObject *)Dtool_Ptr_" << safe_name << ");\n"; out << " }\n"; - out << "#endif\n"; } else { out << " // enum " << object->_itype.get_scoped_name() << "\n"; for (int xx = 0; xx < enum_count; xx++) { @@ -3129,27 +3132,30 @@ write_module_class(ostream &out, Object *obj) { int enum_count = nested_obj->_itype.number_of_enum_values(); CPPType *underlying_type = TypeManager::unwrap_const(nested_obj->_itype._cpptype->as_enum_type()->get_underlying_type()); string cast_to = underlying_type->get_local_name(&parser); - out << "#if PY_VERSION_HEX >= 0x03040000\n\n"; out << " // enum class " << nested_obj->_itype.get_scoped_name() << ";\n"; out << " {\n"; out << " PyObject *members = PyTuple_New(" << enum_count << ");\n"; out << " PyObject *member;\n"; for (int xx = 0; xx < enum_count; xx++) { out << " member = PyTuple_New(2);\n" + "#if PY_MAJOR_VERSION >= 3\n" " PyTuple_SET_ITEM(member, 0, PyUnicode_FromString(\"" << nested_obj->_itype.get_enum_value_name(xx) << "\"));\n" + "#else\n" + " PyTuple_SET_ITEM(member, 0, PyString_FromString(\"" + << nested_obj->_itype.get_enum_value_name(xx) << "\"));\n" + "#endif\n" " PyTuple_SET_ITEM(member, 1, Dtool_WrapValue((" << cast_to << ")" << nested_obj->_itype.get_scoped_name() << "::" << nested_obj->_itype.get_enum_value_name(xx) << "));\n" " PyTuple_SET_ITEM(members, " << xx << ", member);\n"; } - out << " Dtool_Ptr_" << safe_name << " = Dtool_EnumType_Create(\"" - << nested_obj->_itype.get_name() << "\", members, \"" - << _def->module_name << "\");\n"; + out << " Dtool_Ptr_" << safe_name << " = Dtool_EnumType_Create(\"" + << nested_obj->_itype.get_name() << "\", members, \"" + << _def->module_name << "\");\n"; out << " PyDict_SetItemString(dict, \"" << nested_obj->_itype.get_name() << "\", (PyObject *)Dtool_Ptr_" << safe_name << ");\n"; out << " }\n"; - out << "#endif\n"; } else if (nested_obj->_itype.is_enum()) { out << " // enum " << nested_obj->_itype.get_scoped_name() << ";\n"; diff --git a/dtool/src/interrogatedb/py_panda.cxx b/dtool/src/interrogatedb/py_panda.cxx index 9e7563036d..e900ab0e7f 100644 --- a/dtool/src/interrogatedb/py_panda.cxx +++ b/dtool/src/interrogatedb/py_panda.cxx @@ -306,11 +306,39 @@ PyObject *_Dtool_Return(PyObject *value) { return value; } +#if PY_VERSION_HEX < 0x03040000 +static PyObject *Dtool_EnumType_Str(PyObject *self) { + PyObject *name = PyObject_GetAttrString(self, "name"); +#if PY_MAJOR_VERSION >= 3 + PyObject *repr = PyUnicode_FromFormat("%s.%s", Py_TYPE(self)->tp_name, PyString_AS_STRING(name)); +#else + PyObject *repr = PyString_FromFormat("%s.%s", Py_TYPE(self)->tp_name, PyString_AS_STRING(name)); +#endif + Py_DECREF(name); + return repr; +} + +static PyObject *Dtool_EnumType_Repr(PyObject *self) { + PyObject *name = PyObject_GetAttrString(self, "name"); + PyObject *value = PyObject_GetAttrString(self, "value"); +#if PY_MAJOR_VERSION >= 3 + PyObject *repr = PyUnicode_FromFormat("<%s.%s: %ld>", Py_TYPE(self)->tp_name, PyString_AS_STRING(name), PyLongOrInt_AS_LONG(value)); +#else + PyObject *repr = PyString_FromFormat("<%s.%s: %ld>", Py_TYPE(self)->tp_name, PyString_AS_STRING(name), PyLongOrInt_AS_LONG(value)); +#endif + Py_DECREF(name); + Py_DECREF(value); + return repr; +} +#endif + /** - * Creates a Python 3.4-style enum type. Steals reference to 'names'. + * Creates a Python 3.4-style enum type. Steals reference to 'names', which + * should be a tuple of (name, value) pairs. */ PyTypeObject *Dtool_EnumType_Create(const char *name, PyObject *names, const char *module) { static PyObject *enum_class = nullptr; +#if PY_VERSION_HEX >= 0x03040000 static PyObject *enum_meta = nullptr; static PyObject *enum_create = nullptr; if (enum_meta == nullptr) { @@ -325,6 +353,62 @@ PyTypeObject *Dtool_EnumType_Create(const char *name, PyObject *names, const cha PyObject *result = PyObject_CallFunction(enum_create, (char *)"OsN", enum_class, name, names); nassertr(result != nullptr, nullptr); +#else + static PyObject *name_str; + static PyObject *name_sunder_str; + static PyObject *value_str; + static PyObject *value_sunder_str; + // Emulate something vaguely like the enum module. + if (enum_class == nullptr) { +#if PY_MAJOR_VERSION >= 3 + name_str = PyUnicode_InternFromString("name"); + value_str = PyUnicode_InternFromString("value"); + name_sunder_str = PyUnicode_InternFromString("_name_"); + value_sunder_str = PyUnicode_InternFromString("_value_"); +#else + name_str = PyString_InternFromString("name"); + value_str = PyString_InternFromString("value"); + name_sunder_str = PyString_InternFromString("_name_"); + value_sunder_str = PyString_InternFromString("_value_"); +#endif + PyObject *name_value_tuple = PyTuple_New(4); + PyTuple_SET_ITEM(name_value_tuple, 0, name_str); + PyTuple_SET_ITEM(name_value_tuple, 1, value_str); + PyTuple_SET_ITEM(name_value_tuple, 2, name_sunder_str); + PyTuple_SET_ITEM(name_value_tuple, 3, value_sunder_str); + Py_INCREF(name_str); + Py_INCREF(value_str); + + PyObject *slots_dict = PyDict_New(); + PyDict_SetItemString(slots_dict, "__slots__", name_value_tuple); + Py_DECREF(name_value_tuple); + + enum_class = PyObject_CallFunction((PyObject *)&PyType_Type, (char *)"s()N", "Enum", slots_dict); + nassertr(enum_class != nullptr, nullptr); + } + PyObject *result = PyObject_CallFunction((PyObject *)&PyType_Type, (char *)"s(O)N", name, enum_class, PyDict_New()); + nassertr(result != nullptr, nullptr); + + ((PyTypeObject *)result)->tp_str = Dtool_EnumType_Str; + ((PyTypeObject *)result)->tp_repr = Dtool_EnumType_Repr; + + // Copy the names as instances of the above to the class dict. + Py_ssize_t size = PyTuple_GET_SIZE(names); + for (Py_ssize_t i = 0; i < size; ++i) { + PyObject *item = PyTuple_GET_ITEM(names, i); + PyObject *name = PyTuple_GET_ITEM(item, 0); + PyObject *value = PyTuple_GET_ITEM(item, 1); + PyObject *member = _PyObject_CallNoArg(result); + PyObject_SetAttr(member, name_str, name); + PyObject_SetAttr(member, name_sunder_str, name); + PyObject_SetAttr(member, value_str, value); + PyObject_SetAttr(member, value_sunder_str, value); + PyObject_SetAttr(result, name, member); + Py_DECREF(member); + } + Py_DECREF(names); +#endif + if (module != nullptr) { PyObject *modstr = PyUnicode_FromString(module); PyObject_SetAttrString(result, "__module__", modstr); diff --git a/dtool/src/pystub/pystub.cxx b/dtool/src/pystub/pystub.cxx index cf617cd6f7..ac6586c6ff 100644 --- a/dtool/src/pystub/pystub.cxx +++ b/dtool/src/pystub/pystub.cxx @@ -121,6 +121,7 @@ extern "C" { EXPCL_PYSTUB int PyObject_Repr(...); EXPCL_PYSTUB int PyObject_RichCompareBool(...); EXPCL_PYSTUB int PyObject_SelfIter(...); + EXPCL_PYSTUB int PyObject_SetAttr(...); EXPCL_PYSTUB int PyObject_SetAttrString(...); EXPCL_PYSTUB int PyObject_Str(...); EXPCL_PYSTUB int PyObject_Type(...); @@ -351,6 +352,7 @@ int PyObject_Malloc(...) { return 0; } int PyObject_Repr(...) { return 0; } int PyObject_RichCompareBool(...) { return 0; } int PyObject_SelfIter(...) { return 0; } +int PyObject_SetAttr(...) { return 0; } int PyObject_SetAttrString(...) { return 0; } int PyObject_Str(...) { return 0; } int PyObject_Type(...) { return 0; } From f2976b03ecdde973d1fcfaa671246565e4138a90 Mon Sep 17 00:00:00 2001 From: rdb Date: Mon, 2 Jul 2018 12:55:18 +0200 Subject: [PATCH 009/125] gobj: add alignment support and move semantics to SimpleAllocator --- panda/src/gobj/simpleAllocator.I | 44 ++++++++++++++++++++++++++-- panda/src/gobj/simpleAllocator.cxx | 47 +++++++++++++++++++++++++----- panda/src/gobj/simpleAllocator.h | 19 ++++++++---- 3 files changed, 96 insertions(+), 14 deletions(-) diff --git a/panda/src/gobj/simpleAllocator.I b/panda/src/gobj/simpleAllocator.I index 2129ba6681..1f8bf4e01c 100644 --- a/panda/src/gobj/simpleAllocator.I +++ b/panda/src/gobj/simpleAllocator.I @@ -32,9 +32,9 @@ SimpleAllocator(size_t max_size, Mutex &lock) : * pointer. */ SimpleAllocatorBlock *SimpleAllocator:: -alloc(size_t size) { +alloc(size_t size, size_t alignment) { MutexHolder holder(_lock); - return do_alloc(size); + return do_alloc(size, alignment); } /** @@ -148,6 +148,24 @@ SimpleAllocatorBlock(SimpleAllocator *alloc, { } +/** + * Transfers ownership from the given SimpleAllocatorBlock to this one. + */ +INLINE SimpleAllocatorBlock:: +SimpleAllocatorBlock(SimpleAllocatorBlock &&from) : + _allocator(from._allocator) +{ + if (_allocator == nullptr) { + return; + } + + MutexHolder holder(_allocator->_lock); + _start = from._start; + _size = from._size; + LinkedListNode::operator = (std::move(from)); + from._allocator = nullptr; +} + /** * The block automatically frees itself when it destructs. */ @@ -156,6 +174,28 @@ INLINE SimpleAllocatorBlock:: free(); } +/** + * Frees this block and instead takes ownership of the given other block. + */ +INLINE SimpleAllocatorBlock &SimpleAllocatorBlock:: +operator = (SimpleAllocatorBlock &&from) { + free(); + + _allocator = from._allocator; + if (_allocator == nullptr) { + _start = 0; + _size = 0; + return *this; + } + + MutexHolder holder(_allocator->_lock); + _start = from._start; + _size = from._size; + LinkedListNode::operator = (std::move(from)); + from._allocator = nullptr; + return *this; +} + /** * Releases the allocated space. */ diff --git a/panda/src/gobj/simpleAllocator.cxx b/panda/src/gobj/simpleAllocator.cxx index 0cc087e2d7..fa6b20d1a3 100644 --- a/panda/src/gobj/simpleAllocator.cxx +++ b/panda/src/gobj/simpleAllocator.cxx @@ -13,6 +13,37 @@ #include "simpleAllocator.h" +/** + * Move constructor. + */ +SimpleAllocator:: +SimpleAllocator(SimpleAllocator &&from) noexcept : + LinkedListNode(std::move(from)), + _total_size(from._total_size), + _max_size(from._max_size), + _contiguous(from._contiguous), + _lock(from._lock) +{ + MutexHolder holder(_lock); + from._total_size = 0; + from._max_size = 0; + from._contiguous = 0; + + // We still need to leave the list in a valid state. + from._prev = &from; + from._next = &from; + + // Change all the blocks to point to the new allocator. + LinkedListNode *next = _next; + while (next != this) { + SimpleAllocatorBlock *block = (SimpleAllocatorBlock *)next; + nassertv(block->_allocator == &from); + block->_allocator = this; + + next = block->_next; + } +} + /** * */ @@ -66,7 +97,7 @@ write(std::ostream &out) const { * Assumes the lock is already held. */ SimpleAllocatorBlock *SimpleAllocator:: -do_alloc(size_t size) { +do_alloc(size_t size, size_t alignment) { if (size > _contiguous) { // Don't even bother. return nullptr; @@ -86,9 +117,9 @@ do_alloc(size_t size) { // Scan until we have reached the last allocated block. while (block->_next != this) { SimpleAllocatorBlock *next = (SimpleAllocatorBlock *)block->_next; - size_t free_size = next->_start - end; - if (size <= free_size) { - SimpleAllocatorBlock *new_block = make_block(end, size); + size_t start = end + ((alignment - end) % alignment); + if (start + size <= next->_start) { + SimpleAllocatorBlock *new_block = make_block(start, size); nassertr(new_block->get_allocator() == this, nullptr); new_block->insert_before(next); @@ -103,6 +134,7 @@ do_alloc(size_t size) { } return new_block; } + size_t free_size = next->_start - end; if (free_size > best) { best = free_size; } @@ -113,9 +145,9 @@ do_alloc(size_t size) { } // No free blocks; check for room at the end. - size_t free_size = _max_size - end; - if (size <= free_size) { - SimpleAllocatorBlock *new_block = make_block(end, size); + size_t start = end + ((alignment - end) % alignment); + if (start + size <= _max_size) { + SimpleAllocatorBlock *new_block = make_block(start, size); nassertr(new_block->get_allocator() == this, nullptr); new_block->insert_before(this); @@ -131,6 +163,7 @@ do_alloc(size_t size) { return new_block; } + size_t free_size = _max_size - end; if (free_size > best) { best = free_size; } diff --git a/panda/src/gobj/simpleAllocator.h b/panda/src/gobj/simpleAllocator.h index 9e4cb7661b..5a9ca7b616 100644 --- a/panda/src/gobj/simpleAllocator.h +++ b/panda/src/gobj/simpleAllocator.h @@ -29,9 +29,10 @@ class SimpleAllocatorBlock; class EXPCL_PANDA_GOBJ SimpleAllocator : public LinkedListNode { PUBLISHED: INLINE explicit SimpleAllocator(size_t max_size, Mutex &lock); + SimpleAllocator(SimpleAllocator &&from) noexcept; virtual ~SimpleAllocator(); - INLINE SimpleAllocatorBlock *alloc(size_t size); + INLINE SimpleAllocatorBlock *alloc(size_t size, size_t alignment=1); INLINE bool is_empty() const; INLINE size_t get_total_size() const; @@ -45,7 +46,7 @@ PUBLISHED: void write(std::ostream &out) const; protected: - SimpleAllocatorBlock *do_alloc(size_t size); + SimpleAllocatorBlock *do_alloc(size_t size, size_t alignment=1); INLINE bool do_is_empty() const; virtual SimpleAllocatorBlock *make_block(size_t start, size_t size); @@ -91,6 +92,14 @@ protected: INLINE SimpleAllocatorBlock(SimpleAllocator *alloc, size_t start, size_t size); +public: + SimpleAllocatorBlock() = default; + SimpleAllocatorBlock(const SimpleAllocatorBlock ©) = delete; + INLINE SimpleAllocatorBlock(SimpleAllocatorBlock &&from); + + SimpleAllocatorBlock &operator = (const SimpleAllocatorBlock ©) = delete; + INLINE SimpleAllocatorBlock &operator = (SimpleAllocatorBlock &&from); + PUBLISHED: INLINE ~SimpleAllocatorBlock(); INLINE void free(); @@ -114,9 +123,9 @@ protected: INLINE bool do_realloc(size_t size); private: - SimpleAllocator *_allocator; - size_t _start; - size_t _size; + SimpleAllocator *_allocator = nullptr; + size_t _start = 0; + size_t _size = 0; friend class SimpleAllocator; }; From 66c5d65bf69fa267270c70c2815cf4f08ed3dc9b Mon Sep 17 00:00:00 2001 From: rdb Date: Wed, 4 Jul 2018 19:11:59 +0200 Subject: [PATCH 010/125] maxegg: fix compilation errors with min/max --- pandatool/src/maxegg/maxEgg.h | 4 ++++ pandatool/src/maxegg/maxEggLoader.cxx | 3 +++ pandatool/src/maxprogs/maxEggImport.cxx | 3 +++ 3 files changed, 10 insertions(+) diff --git a/pandatool/src/maxegg/maxEgg.h b/pandatool/src/maxegg/maxEgg.h index 88ae826490..2d9765ee01 100644 --- a/pandatool/src/maxegg/maxEgg.h +++ b/pandatool/src/maxegg/maxEgg.h @@ -19,6 +19,10 @@ #include #include #include "errno.h" + +using std::min; +using std::max; + #include "Max.h" #include "eggGroup.h" #include "eggTable.h" diff --git a/pandatool/src/maxegg/maxEggLoader.cxx b/pandatool/src/maxegg/maxEggLoader.cxx index dca954c6f1..a6855657e6 100644 --- a/pandatool/src/maxegg/maxEggLoader.cxx +++ b/pandatool/src/maxegg/maxEggLoader.cxx @@ -26,6 +26,9 @@ #include "eggPolysetMaker.h" #include "eggBin.h" +using std::min; +using std::max; + #include #include "Max.h" #include "istdplug.h" diff --git a/pandatool/src/maxprogs/maxEggImport.cxx b/pandatool/src/maxprogs/maxEggImport.cxx index b180b12ca8..08a0184a8e 100644 --- a/pandatool/src/maxprogs/maxEggImport.cxx +++ b/pandatool/src/maxprogs/maxEggImport.cxx @@ -22,6 +22,9 @@ // Include this before everything #include "pandatoolbase.h" +using std::min; +using std::max; + // MAX includes #include "maxEggLoader.h" #include "Max.h" From e9e18c22770122a9b560ce19457522eff6535905 Mon Sep 17 00:00:00 2001 From: rdb Date: Wed, 4 Jul 2018 20:29:31 +0200 Subject: [PATCH 011/125] dtoolutil: fix PandaSystem TypeHandle static init issue --- dtool/src/dtoolutil/pandaSystem.cxx | 1 + 1 file changed, 1 insertion(+) diff --git a/dtool/src/dtoolutil/pandaSystem.cxx b/dtool/src/dtoolutil/pandaSystem.cxx index d09fecb663..3d80d0f6b5 100644 --- a/dtool/src/dtoolutil/pandaSystem.cxx +++ b/dtool/src/dtoolutil/pandaSystem.cxx @@ -435,6 +435,7 @@ write(std::ostream &out) const { PandaSystem *PandaSystem:: get_global_ptr() { if (_global_ptr == nullptr) { + init_type(); _global_ptr = new PandaSystem; } From 00888518fe3c25a414267d6e5728478a9baa853f Mon Sep 17 00:00:00 2001 From: rdb Date: Wed, 4 Jul 2018 20:31:08 +0200 Subject: [PATCH 012/125] gobj: add F_r32i and F_r32 to TexturePeeker --- panda/src/gobj/texturePeeker.cxx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/panda/src/gobj/texturePeeker.cxx b/panda/src/gobj/texturePeeker.cxx index 5dc3368909..ef007d91dd 100644 --- a/panda/src/gobj/texturePeeker.cxx +++ b/panda/src/gobj/texturePeeker.cxx @@ -108,6 +108,8 @@ TexturePeeker(Texture *tex, Texture::CData *cdata) { case Texture::F_depth_component32: case Texture::F_red: case Texture::F_r16: + case Texture::F_r32: + case Texture::F_r32i: _get_texel = get_texel_r; break; From c5dd683366ec6ef61b554f1db71f6b8aebd6cc00 Mon Sep 17 00:00:00 2001 From: rdb Date: Wed, 4 Jul 2018 20:36:48 +0200 Subject: [PATCH 013/125] tests: add unit test for writing to and extracting buffer textures --- tests/display/test_glsl_shader.py | 39 +++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/tests/display/test_glsl_shader.py b/tests/display/test_glsl_shader.py index f4ff2d7ea0..33bcf969f0 100644 --- a/tests/display/test_glsl_shader.py +++ b/tests/display/test_glsl_shader.py @@ -1,4 +1,5 @@ from panda3d import core +import struct import pytest from _pytest.outcomes import Failed @@ -18,6 +19,7 @@ layout(r8ui) uniform writeonly uimageBuffer _triggered; void _reset() {{ imageStore(_triggered, 0, uvec4(0, 0, 0, 0)); + memoryBarrier(); }} void _assert(bool cond, int line) {{ @@ -275,3 +277,40 @@ def test_glsl_pta_mat4(gsg): assert(pta[1][3] == vec4(28, 29, 30, 31)); """ run_glsl_test(gsg, code, preamble, {'pta': pta}), code + + +def test_glsl_write_extract_image_buffer(gsg): + # Tests that we can write to a buffer texture on the GPU, and then extract + # the data on the CPU. We test two textures since there was in the past a + # where it would only work correctly for one texture. + tex1 = core.Texture("tex1") + tex1.set_clear_color(0) + tex1.setup_buffer_texture(1, core.Texture.T_unsigned_int, core.Texture.F_r32i, + core.GeomEnums.UH_static) + tex2 = core.Texture("tex2") + tex2.set_clear_color(0) + tex2.setup_buffer_texture(1, core.Texture.T_int, core.Texture.F_r32i, + core.GeomEnums.UH_static) + + preamble = """ + layout(r32ui) uniform uimageBuffer tex1; + layout(r32i) uniform iimageBuffer tex2; + """ + code = """ + assert(imageLoad(tex1, 0).r == 0); + assert(imageLoad(tex2, 0).r == 0); + imageStore(tex1, 0, uvec4(123)); + imageStore(tex2, 0, ivec4(-456)); + memoryBarrier(); + assert(imageLoad(tex1, 0).r == 123); + assert(imageLoad(tex2, 0).r == -456); + """ + + run_glsl_test(gsg, code, preamble, {'tex1': tex1, 'tex2': tex2}) + + engine = core.GraphicsEngine.get_global_ptr() + assert engine.extract_texture_data(tex1, gsg) + assert engine.extract_texture_data(tex2, gsg) + + assert struct.unpack('I', tex1.get_ram_image()) == (123,) + assert struct.unpack('i', tex2.get_ram_image()) == (-456,) From 96a48a684878d169e2eefacb5d737e8be2de3fcd Mon Sep 17 00:00:00 2001 From: rdb Date: Wed, 4 Jul 2018 20:55:30 +0200 Subject: [PATCH 014/125] glgsg: fix issue with extract_texture_data and buffer textures It would always extract the last-created buffer texture, not the texture in question. --- panda/src/glstuff/glGraphicsStateGuardian_src.cxx | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx index cde43352bc..b167f1baa8 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx @@ -13309,6 +13309,12 @@ do_extract_texture_data(CLP(TextureContext) *gtc) { << "glBindTexture(0x" << hex << target << dec << ", " << gtc->_index << "): " << *tex << "\n"; } +#ifndef OPENGLES + if (target == GL_TEXTURE_BUFFER) { + _glBindBuffer(GL_TEXTURE_BUFFER, gtc->_buffer); + } +#endif + GLint wrap_u, wrap_v, wrap_w; GLint minfilter, magfilter; From 5fe294a467f63852f9d038025885afe38f4b0905 Mon Sep 17 00:00:00 2001 From: rdb Date: Thu, 5 Jul 2018 10:08:50 +0200 Subject: [PATCH 015/125] bullet: prevent softbody with AABB out of bounds from asserting See #357 --- panda/src/bullet/bulletSoftBodyNode.cxx | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/panda/src/bullet/bulletSoftBodyNode.cxx b/panda/src/bullet/bulletSoftBodyNode.cxx index 9687935412..cf027f208d 100644 --- a/panda/src/bullet/bulletSoftBodyNode.cxx +++ b/panda/src/bullet/bulletSoftBodyNode.cxx @@ -276,8 +276,15 @@ do_sync_b2p() { // Update the synchronized transform with the current approximate center of // the soft body - LVecBase3 pos = this->do_get_aabb().get_approx_center(); - CPT(TransformState) ts = TransformState::make_pos(pos); + btVector3 pMin, pMax; + _soft->getAabb(pMin, pMax); + LPoint3 pos = (btVector3_to_LPoint3(pMin) + btVector3_to_LPoint3(pMax)) * 0.5; + CPT(TransformState) ts; + if (!pos.is_nan()) { + ts = TransformState::make_pos(pos); + } else { + ts = TransformState::make_identity(); + } NodePath np = NodePath::any_path((PandaNode *)this); LVecBase3 scale = np.get_net_transform()->get_scale(); From ec06d3f4f8d8ba387d79d95d988937866a7794df Mon Sep 17 00:00:00 2001 From: rdb Date: Thu, 5 Jul 2018 12:59:02 +0200 Subject: [PATCH 016/125] tests: fix occasional timing issue in future test --- tests/event/test_futures.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/tests/event/test_futures.py b/tests/event/test_futures.py index 0778605da4..e120a2ab8e 100644 --- a/tests/event/test_futures.py +++ b/tests/event/test_futures.py @@ -48,10 +48,9 @@ def test_future_wait(): fut.set_result(None) thread = threading.Thread(target=thread_main) - thread.start() - # Make sure it didn't sneakily already run the thread assert not fut.done() + thread.start() assert fut.result() is None @@ -69,10 +68,9 @@ def test_future_wait_cancel(): fut.cancel() thread = threading.Thread(target=thread_main) - thread.start() - # Make sure it didn't sneakily already run the thread assert not fut.done() + thread.start() with pytest.raises(CancelledError): fut.result() From b85fead09d99c61d9c20c54e2b97df4ab67d69d4 Mon Sep 17 00:00:00 2001 From: rdb Date: Thu, 5 Jul 2018 17:55:39 +0200 Subject: [PATCH 017/125] wgldisplay: report context binding error, keep track of thread This isn't really a complete solution, just a stopgap measure to prevent a crash. --- panda/src/wgldisplay/wglGraphicsPipe.cxx | 11 ++++++++--- panda/src/wgldisplay/wglGraphicsPipe.h | 3 ++- panda/src/wgldisplay/wglGraphicsStateGuardian.cxx | 7 ++++++- panda/src/wgldisplay/wglGraphicsWindow.cxx | 6 +++++- 4 files changed, 21 insertions(+), 6 deletions(-) diff --git a/panda/src/wgldisplay/wglGraphicsPipe.cxx b/panda/src/wgldisplay/wglGraphicsPipe.cxx index 1a55059dbd..4186c35a35 100644 --- a/panda/src/wgldisplay/wglGraphicsPipe.cxx +++ b/panda/src/wgldisplay/wglGraphicsPipe.cxx @@ -22,6 +22,7 @@ TypeHandle wglGraphicsPipe::_type_handle; bool wglGraphicsPipe::_current_valid; HDC wglGraphicsPipe::_current_hdc; HGLRC wglGraphicsPipe::_current_hglrc; +Thread *wglGraphicsPipe::_current_thread; /** * @@ -41,16 +42,19 @@ wglGraphicsPipe:: /** * a thin wrapper around wglMakeCurrent to avoid unnecessary OS-call overhead. */ -void wglGraphicsPipe:: +bool wglGraphicsPipe:: wgl_make_current(HDC hdc, HGLRC hglrc, PStatCollector *collector) { + Thread *thread = Thread::get_current_thread(); if ((_current_valid) && (_current_hdc == hdc) && - (_current_hglrc == hglrc)) { - return; + (_current_hglrc == hglrc) && + (_current_thread == thread)) { + return true; } _current_valid = true; _current_hdc = hdc; _current_hglrc = hglrc; + _current_thread = thread; BOOL res; if (collector) { PStatTimer timer(*collector); @@ -58,6 +62,7 @@ wgl_make_current(HDC hdc, HGLRC hglrc, PStatCollector *collector) { } else { res = wglMakeCurrent(hdc, hglrc); } + return (res != 0); } /** diff --git a/panda/src/wgldisplay/wglGraphicsPipe.h b/panda/src/wgldisplay/wglGraphicsPipe.h index 176483f92c..49ff95cd5a 100644 --- a/panda/src/wgldisplay/wglGraphicsPipe.h +++ b/panda/src/wgldisplay/wglGraphicsPipe.h @@ -46,11 +46,12 @@ protected: private: static std::string format_pfd_flags(DWORD pfd_flags); - static void wgl_make_current(HDC hdc, HGLRC hglrc, PStatCollector *collector); + static bool wgl_make_current(HDC hdc, HGLRC hglrc, PStatCollector *collector); static bool _current_valid; static HDC _current_hdc; static HGLRC _current_hglrc; + static Thread *_current_thread; public: static TypeHandle get_class_type() { diff --git a/panda/src/wgldisplay/wglGraphicsStateGuardian.cxx b/panda/src/wgldisplay/wglGraphicsStateGuardian.cxx index b1dc143da5..735f7fc409 100644 --- a/panda/src/wgldisplay/wglGraphicsStateGuardian.cxx +++ b/panda/src/wgldisplay/wglGraphicsStateGuardian.cxx @@ -319,7 +319,12 @@ choose_pixel_format(const FrameBufferProperties &properties, return; } - wglGraphicsPipe::wgl_make_current(twindow_dc, twindow_ctx, nullptr); + if (!wglGraphicsPipe::wgl_make_current(twindow_dc, twindow_ctx, nullptr)) { + wgldisplay_cat.error() + << "Failed to make WGL context current.\n"; + wglDeleteContext(twindow_ctx); + return; + } _extensions.clear(); save_extensions((const char *)GLP(GetString)(GL_EXTENSIONS)); diff --git a/panda/src/wgldisplay/wglGraphicsWindow.cxx b/panda/src/wgldisplay/wglGraphicsWindow.cxx index d6a892ee30..6ff5b88c36 100644 --- a/panda/src/wgldisplay/wglGraphicsWindow.cxx +++ b/panda/src/wgldisplay/wglGraphicsWindow.cxx @@ -79,7 +79,11 @@ begin_frame(FrameMode mode, Thread *current_thread) { HGLRC context = wglgsg->get_context(_hdc); nassertr(context, false); - wglGraphicsPipe::wgl_make_current(_hdc, context, &_make_current_pcollector); + if (!wglGraphicsPipe::wgl_make_current(_hdc, context, &_make_current_pcollector)) { + wgldisplay_cat.error() + << "Failed to make WGL context current.\n"; + return false; + } wglgsg->reset_if_new(); if (mode == FM_render) { From d4d582484fff0ddfdd1ec03e80dfb2cfd66da66d Mon Sep 17 00:00:00 2001 From: rdb Date: Thu, 5 Jul 2018 19:02:37 +0200 Subject: [PATCH 018/125] display: fix ability to make screenshots in multithreaded pipeline Problem is that WGL is strict about binding context in different thread while it is still bound in another thread. Either way we need to make sure the draw thread is not rendering, so if you call get_screenshot() from a thread other than the draw thread, it uses the GraphicsEngine to wait until the draw thread is idle and then asks it to do the get_screenshot(). Fixes #360 --- panda/src/display/displayRegion.cxx | 8 ++++++ panda/src/display/graphicsEngine.cxx | 42 ++++++++++++++++++++++++++++ panda/src/display/graphicsEngine.h | 5 +++- 3 files changed, 54 insertions(+), 1 deletion(-) diff --git a/panda/src/display/displayRegion.cxx b/panda/src/display/displayRegion.cxx index e32b0f5a50..e1765861e1 100644 --- a/panda/src/display/displayRegion.cxx +++ b/panda/src/display/displayRegion.cxx @@ -483,6 +483,14 @@ get_screenshot() { GraphicsStateGuardian *gsg = window->get_gsg(); nassertr(gsg != nullptr, nullptr); + // Are we on the draw thread? + if (gsg->get_threading_model().get_draw_stage() != current_thread->get_pipeline_stage()) { + // Ask the engine to do on the draw thread. + GraphicsEngine *engine = window->get_engine(); + return engine->do_get_screenshot(this, gsg); + } + + // We are on the draw thread. if (!window->begin_frame(GraphicsOutput::FM_refresh, current_thread)) { return nullptr; } diff --git a/panda/src/display/graphicsEngine.cxx b/panda/src/display/graphicsEngine.cxx index 0b4e8448b1..dd637d7a9a 100644 --- a/panda/src/display/graphicsEngine.cxx +++ b/panda/src/display/graphicsEngine.cxx @@ -1249,6 +1249,43 @@ texture_uploaded(Texture *tex) { // Usually only called by DisplayRegion::do_cull. } +/** + * Called by DisplayRegion::do_get_screenshot + */ +PT(Texture) GraphicsEngine:: +do_get_screenshot(DisplayRegion *region, GraphicsStateGuardian *gsg) { + // A multi-threaded environment. We have to wait until the draw thread + // has finished its current task. + + ReMutexHolder holder(_lock); + + const std::string &draw_name = gsg->get_threading_model().get_draw_name(); + WindowRenderer *wr = get_window_renderer(draw_name, 0); + RenderThread *thread = (RenderThread *)wr; + MutexHolder cv_holder(thread->_cv_mutex); + + while (thread->_thread_state != TS_wait) { + thread->_cv_done.wait(); + } + + // Now that the draw thread is idle, signal it to do the extraction task. + thread->_region = region; + thread->_thread_state = TS_do_screenshot; + thread->_cv_start.notify(); + thread->_cv_mutex.release(); + thread->_cv_mutex.acquire(); + + //XXX is this necessary, or is acquiring the mutex enough? + while (thread->_thread_state != TS_wait) { + thread->_cv_done.wait(); + } + + PT(Texture) tex = std::move(thread->_texture); + thread->_region = nullptr; + thread->_texture = nullptr; + return tex; +} + /** * Fires off a cull traversal using the indicated camera. */ @@ -2633,6 +2670,11 @@ thread_main() { _result = _gsg->extract_texture_data(_texture); break; + case TS_do_screenshot: + nassertd(_region != nullptr) break; + _texture = _region->get_screenshot(); + break; + case TS_terminate: do_pending(_engine, current_thread); do_close(_engine, current_thread); diff --git a/panda/src/display/graphicsEngine.h b/panda/src/display/graphicsEngine.h index 667490b3d3..3371f20b39 100644 --- a/panda/src/display/graphicsEngine.h +++ b/panda/src/display/graphicsEngine.h @@ -125,11 +125,13 @@ public: TS_do_windows, TS_do_compute, TS_do_extract, + TS_do_screenshot, TS_terminate, TS_done }; void texture_uploaded(Texture *tex); + PT(Texture) do_get_screenshot(DisplayRegion *region, GraphicsStateGuardian *gsg); public: static void do_cull(CullHandler *cull_handler, SceneSetup *scene_setup, @@ -304,8 +306,9 @@ private: // These are stored for extract_texture_data and dispatch_compute. GraphicsStateGuardian *_gsg; - Texture *_texture; + PT(Texture) _texture; const RenderState *_state; + DisplayRegion *_region; LVecBase3i _work_groups; bool _result; }; From fd227f64922112c82766a5dd550e7f74d00e74d6 Mon Sep 17 00:00:00 2001 From: Brian Lach Date: Fri, 6 Jul 2018 13:31:00 -0400 Subject: [PATCH 019/125] bullet: allow creation of BulletCapsuleShape from CollisionTube --- panda/src/bullet/bulletBodyNode.cxx | 9 +++++++++ panda/src/bullet/bulletCapsuleShape.cxx | 16 ++++++++++++++++ panda/src/bullet/bulletCapsuleShape.h | 4 ++++ 3 files changed, 29 insertions(+) diff --git a/panda/src/bullet/bulletBodyNode.cxx b/panda/src/bullet/bulletBodyNode.cxx index 0a4bbc40c8..9067999599 100644 --- a/panda/src/bullet/bulletBodyNode.cxx +++ b/panda/src/bullet/bulletBodyNode.cxx @@ -20,6 +20,7 @@ #include "collisionPlane.h" #include "collisionSphere.h" #include "collisionPolygon.h" +#include "collisionTube.h" TypeHandle BulletBodyNode::_type_handle; @@ -804,6 +805,14 @@ add_shapes_from_collision_solids(CollisionNode *cnode) { do_add_shape(BulletBoxShape::make_from_solid(box), ts); } + // CollisionTube + else if (CollisionTube::get_class_type() == type) { + CPT(CollisionTube) tube = DCAST(CollisionTube, solid); + CPT(TransformState) ts = TransformState::make_pos((tube->get_point_b() + tube->get_point_a()) / 2.0); + + do_add_shape(BulletCapsuleShape::make_from_solid(tube), ts); + } + // CollisionPlane else if (CollisionPlane::get_class_type() == type) { CPT(CollisionPlane) plane = DCAST(CollisionPlane, solid); diff --git a/panda/src/bullet/bulletCapsuleShape.cxx b/panda/src/bullet/bulletCapsuleShape.cxx index 85171d9b46..ba9e02ab83 100644 --- a/panda/src/bullet/bulletCapsuleShape.cxx +++ b/panda/src/bullet/bulletCapsuleShape.cxx @@ -82,6 +82,22 @@ ptr() const { return _shape; } + +/** + * Constructs a new BulletCapsuleShape using the information from a + * CollisionTube from the builtin collision system. + */ +BulletCapsuleShape *BulletCapsuleShape:: +make_from_solid(const CollisionTube *solid) { + + PN_stdfloat radius = solid->get_radius(); + // CollisionTube height includes the hemispheres, Bullet only wants the cylinder height. + PN_stdfloat height = (solid->get_point_b() - solid->get_point_a()).length() - (radius * 2); + + // CollisionTubes are always Z-Up. + return new BulletCapsuleShape(radius, height, Z_up); +} + /** * Tells the BamReader how to create objects of type BulletShape. */ diff --git a/panda/src/bullet/bulletCapsuleShape.h b/panda/src/bullet/bulletCapsuleShape.h index 9994d9f1dc..f8eecfe3d7 100644 --- a/panda/src/bullet/bulletCapsuleShape.h +++ b/panda/src/bullet/bulletCapsuleShape.h @@ -20,6 +20,8 @@ #include "bullet_utils.h" #include "bulletShape.h" +#include "collisionTube.h" + /** * */ @@ -33,6 +35,8 @@ PUBLISHED: BulletCapsuleShape(const BulletCapsuleShape ©); INLINE ~BulletCapsuleShape(); + static BulletCapsuleShape *make_from_solid(const CollisionTube *solid); + INLINE PN_stdfloat get_radius() const; INLINE PN_stdfloat get_half_height() const; From 0c1fa6a765871a04561c45c77bddbdeaae8fd3e5 Mon Sep 17 00:00:00 2001 From: Tohka Date: Sat, 7 Jul 2018 18:08:41 +0300 Subject: [PATCH 020/125] nsis: Correct building on NSIS 3.0 LVM_GETITEMCOUNT and LVM_GETITEMTEXT are already defined post NSIS 3.0. --- makepanda/installer.nsi | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/makepanda/installer.nsi b/makepanda/installer.nsi index 39b7dd3518..976bfd84f5 100644 --- a/makepanda/installer.nsi +++ b/makepanda/installer.nsi @@ -1239,8 +1239,13 @@ done: FunctionEnd +!ifndef LVM_GETITEMCOUNT !define LVM_GETITEMCOUNT 0x1004 +!endif + +!ifndef LVM_GETITEMTEXT !define LVM_GETITEMTEXT 0x102D +!endif Function DumpLog Exch $5 From 835a895c5151f0b219fee776559db9ff0efb427b Mon Sep 17 00:00:00 2001 From: rdb Date: Sat, 7 Jul 2018 22:55:45 +0200 Subject: [PATCH 021/125] windisplay: don't adjust in_window during get_pointer This restores the old behaviour from before 29a08932ea92bcf0e953994c524cafc1717930b5, which makes in_window true during pointer capture (ie. click-and-drag) even if the cursor leaves the window. X11 behaviour is already not to adjust in_window. Fixes #363 --- panda/src/windisplay/winGraphicsWindow.cxx | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/panda/src/windisplay/winGraphicsWindow.cxx b/panda/src/windisplay/winGraphicsWindow.cxx index 4370621815..954d8aca41 100644 --- a/panda/src/windisplay/winGraphicsWindow.cxx +++ b/panda/src/windisplay/winGraphicsWindow.cxx @@ -134,15 +134,11 @@ get_pointer(int device) const { // We recheck this immediately to get the most up-to-date value. POINT cpos; - if (device == 0 && GetCursorPos(&cpos) && ScreenToClient(_hWnd, &cpos)) { + if (device == 0 && result._in_window && GetCursorPos(&cpos) && ScreenToClient(_hWnd, &cpos)) { double time = ClockObject::get_global_clock()->get_real_time(); - RECT view_rect; - if (GetClientRect(_hWnd, &view_rect)) { - result._in_window = PtInRect(&view_rect, cpos); - result._xpos = cpos.x; - result._ypos = cpos.y; - ((GraphicsWindowInputDevice &)_input_devices[0]).set_pointer(result._in_window, result._xpos, result._ypos, time); - } + result._xpos = cpos.x; + result._ypos = cpos.y; + ((GraphicsWindowInputDevice &)_input_devices[0]).set_pointer(result._in_window, result._xpos, result._ypos, time); } } return result; From cf451bde23822b1cd8b51b42cca8ebb597691458 Mon Sep 17 00:00:00 2001 From: rdb Date: Sun, 8 Jul 2018 21:11:36 +0200 Subject: [PATCH 022/125] tests: add some fuzz to bullet plane shape testing Needed to unbreak the test suite on macOS. --- tests/bullet/test_bullet_bam.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/bullet/test_bullet_bam.py b/tests/bullet/test_bullet_bam.py index e22aa57ba2..386e044f9f 100644 --- a/tests/bullet/test_bullet_bam.py +++ b/tests/bullet/test_bullet_bam.py @@ -117,7 +117,7 @@ def test_plane_shape(): assert type(shape) is type(shape2) assert shape.margin == shape2.margin assert shape.name == shape2.name - assert shape.plane_normal == shape2.plane_normal + assert shape.plane_normal.almost_equal(shape2.plane_normal, 0.1) assert shape.plane_constant == shape2.plane_constant From eda47c7f3b4cf155442527e265ca80d4aafee040 Mon Sep 17 00:00:00 2001 From: rdb Date: Sun, 8 Jul 2018 21:13:13 +0200 Subject: [PATCH 023/125] bullet: support Plane class in BulletPlaneShape --- panda/src/bullet/bulletPlaneShape.cxx | 23 +++++++++++++++++++++++ panda/src/bullet/bulletPlaneShape.h | 3 +++ 2 files changed, 26 insertions(+) diff --git a/panda/src/bullet/bulletPlaneShape.cxx b/panda/src/bullet/bulletPlaneShape.cxx index 0d1a97fd4e..98dce53577 100644 --- a/panda/src/bullet/bulletPlaneShape.cxx +++ b/panda/src/bullet/bulletPlaneShape.cxx @@ -15,6 +15,18 @@ TypeHandle BulletPlaneShape::_type_handle; +/** + * Creates a plane shape from a plane definition. + */ +BulletPlaneShape:: +BulletPlaneShape(LPlane plane) { + + btVector3 btNormal = LVecBase3_to_btVector3(plane.get_normal()); + + _shape = new btStaticPlaneShape(btNormal, plane.get_w()); + _shape->setUserPointer(this); +} + /** * */ @@ -50,6 +62,17 @@ ptr() const { return _shape; } +/** + * + */ +LPlane BulletPlaneShape:: +get_plane() const { + LightMutexHolder holder(BulletWorld::get_global_lock()); + + btVector3 normal = _shape->getPlaneNormal(); + return LPlane(normal[0], normal[1], normal[2], (PN_stdfloat)_shape->getPlaneConstant()); +} + /** * */ diff --git a/panda/src/bullet/bulletPlaneShape.h b/panda/src/bullet/bulletPlaneShape.h index 95aa16d9ef..4521007ecb 100644 --- a/panda/src/bullet/bulletPlaneShape.h +++ b/panda/src/bullet/bulletPlaneShape.h @@ -32,15 +32,18 @@ private: INLINE BulletPlaneShape() : _shape(nullptr) {}; PUBLISHED: + explicit BulletPlaneShape(LPlane plane); explicit BulletPlaneShape(const LVector3 &normal, PN_stdfloat constant); BulletPlaneShape(const BulletPlaneShape ©); INLINE ~BulletPlaneShape(); + LPlane get_plane() const; LVector3 get_plane_normal() const; PN_stdfloat get_plane_constant() const; static BulletPlaneShape *make_from_solid(const CollisionPlane *solid); + MAKE_PROPERTY(plane, get_plane); MAKE_PROPERTY(plane_normal, get_plane_normal); MAKE_PROPERTY(plane_constant, get_plane_constant); From 269d154aea28e69dd6f2ac454a2b729c19c06487 Mon Sep 17 00:00:00 2001 From: rdb Date: Sun, 8 Jul 2018 21:15:40 +0200 Subject: [PATCH 024/125] chan: fix thread-unsafe access of WeakPointerTo --- panda/src/chan/partBundle.cxx | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/panda/src/chan/partBundle.cxx b/panda/src/chan/partBundle.cxx index dffed55d50..966987995a 100644 --- a/panda/src/chan/partBundle.cxx +++ b/panda/src/chan/partBundle.cxx @@ -154,10 +154,11 @@ apply_transform(const TransformState *transform) { AppliedTransforms::iterator ati = _applied_transforms.find(transform); if (ati != _applied_transforms.end()) { - if ((*ati).first.is_valid_pointer() && - (*ati).second.is_valid_pointer()) { - // Here's our cached result. - return (*ati).second.lock(); + if ((*ati).first.is_valid_pointer()) { + if (auto new_bundle = (*ati).second.lock()) { + // Here's our cached result. + return new_bundle; + } } } From fb82a1c557d02f331fe1ccee46987ffa16232c16 Mon Sep 17 00:00:00 2001 From: rdb Date: Sun, 8 Jul 2018 21:22:25 +0200 Subject: [PATCH 025/125] express: enable WeakPointerToBase comparison operators on Win32 I'm not sure why they were ifdeffed out, but they should certainly be available so that it is possible to compare WeakPointerTo in a thread-safe manner. --- panda/src/express/weakPointerToBase.I | 2 -- panda/src/express/weakPointerToBase.h | 3 +-- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/panda/src/express/weakPointerToBase.I b/panda/src/express/weakPointerToBase.I index 30690458be..2e537c9639 100644 --- a/panda/src/express/weakPointerToBase.I +++ b/panda/src/express/weakPointerToBase.I @@ -202,7 +202,6 @@ update_type(To *ptr) { } #ifndef CPPPARSER -#ifndef WIN32_VC /** * */ @@ -426,7 +425,6 @@ INLINE bool WeakPointerToBase:: operator >= (const PointerToBase &other) const { return (To *)_void_ptr >= (To *)((WeakPointerToBase *)&other)->_void_ptr; } -#endif // WIN32_VC /** * diff --git a/panda/src/express/weakPointerToBase.h b/panda/src/express/weakPointerToBase.h index b1267c448a..a34b39bdb5 100644 --- a/panda/src/express/weakPointerToBase.h +++ b/panda/src/express/weakPointerToBase.h @@ -48,7 +48,6 @@ public: // These comparison functions are common to all things PointerTo, so they're // defined up here. #ifndef CPPPARSER -#ifndef WIN32_VC INLINE bool operator == (const To *other) const; INLINE bool operator != (const To *other) const; INLINE bool operator > (const To *other) const; @@ -77,7 +76,7 @@ public: INLINE bool operator > (const PointerToBase &other) const; INLINE bool operator <= (const PointerToBase &other) const; INLINE bool operator >= (const PointerToBase &other) const; -#endif // WIN32_VC + INLINE bool operator < (const To *other) const; INLINE bool operator < (std::nullptr_t) const; INLINE bool operator < (const WeakPointerToBase &other) const; From 409231d214ebfce847d6242cee587ab7f9f72f85 Mon Sep 17 00:00:00 2001 From: rdb Date: Sun, 8 Jul 2018 21:25:08 +0200 Subject: [PATCH 026/125] express: make WeakPointerTo cast operators explicit This prevents accidentally (and unsafely) decaying a WeakPointerTo to a regular pointer. --- panda/src/express/weakPointerTo.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/panda/src/express/weakPointerTo.h b/panda/src/express/weakPointerTo.h index 5834113b7a..2e8c6029a5 100644 --- a/panda/src/express/weakPointerTo.h +++ b/panda/src/express/weakPointerTo.h @@ -38,7 +38,7 @@ public: INLINE To &operator *() const; INLINE To *operator -> () const; // MSVC.NET 2005 insists that we use T *, and not To *, here. - INLINE operator T *() const; + INLINE explicit operator T *() const; PUBLISHED: INLINE PointerTo lock() const; @@ -75,7 +75,7 @@ PUBLISHED: public: INLINE const To &operator *() const; INLINE const To *operator -> () const; - INLINE operator const T *() const; + INLINE explicit operator const T *() const; PUBLISHED: INLINE ConstPointerTo lock() const; From 23128e4695d2e8581551be161f20cf7d53ca87b5 Mon Sep 17 00:00:00 2001 From: rdb Date: Sun, 8 Jul 2018 21:33:49 +0200 Subject: [PATCH 027/125] express: support casting between compatible PointerTo types This makes it possible to implicitly convert a PT of a derived type to a (C)PT of a base type, without needing to first convert it to a regular pointer. This also applies to moves, which are now more efficient due to the lack of need for ref/unref pair even if the pointer type is not exactly the same. --- panda/src/express/pointerTo.I | 162 ++++++++++++++++++++++++++++++ panda/src/express/pointerTo.h | 34 +++++++ panda/src/express/pointerToBase.I | 56 +++++++++-- panda/src/express/pointerToBase.h | 8 ++ 4 files changed, 252 insertions(+), 8 deletions(-) diff --git a/panda/src/express/pointerTo.I b/panda/src/express/pointerTo.I index e0f8c85046..8c7aa38a4e 100644 --- a/panda/src/express/pointerTo.I +++ b/panda/src/express/pointerTo.I @@ -39,6 +39,41 @@ PointerTo(PointerTo &&from) noexcept : { } +#ifndef CPPPARSER +/** + * + */ +template +template +ALWAYS_INLINE PointerTo:: +PointerTo(Y *ptr) noexcept : + PointerToBase(ptr) +{ +} + +/** + * + */ +template +template +ALWAYS_INLINE PointerTo:: +PointerTo(const PointerTo &r) noexcept : + PointerToBase(r.p()) +{ +} + +/** + * + */ +template +template +ALWAYS_INLINE PointerTo:: +PointerTo(PointerTo &&r) noexcept : + PointerToBase(std::move(r)) +{ +} +#endif // !CPPPARSER + /** * */ @@ -49,6 +84,30 @@ operator = (PointerTo &&from) noexcept { return *this; } +#ifndef CPPPARSER +/** + * + */ +template +template +ALWAYS_INLINE PointerTo &PointerTo:: +operator = (const PointerTo &r) noexcept { + this->reassign(r.p()); + return *this; +} + +/** + * + */ +template +template +ALWAYS_INLINE PointerTo &PointerTo:: +operator = (PointerTo &&r) noexcept { + this->reassign(std::move(r)); + return *this; +} +#endif // !CPPPARSER + /** * */ @@ -172,6 +231,63 @@ ConstPointerTo(ConstPointerTo &&from) noexcept : { } +#ifndef CPPPARSER +/** + * + */ +template +template +ALWAYS_INLINE ConstPointerTo:: +ConstPointerTo(const Y *ptr) noexcept : + PointerToBase((Y *)ptr) +{ +} + +/** + * + */ +template +template +ALWAYS_INLINE ConstPointerTo:: +ConstPointerTo(const PointerTo &r) noexcept : + PointerToBase(r.p()) +{ +} + +/** + * + */ +template +template +ALWAYS_INLINE ConstPointerTo:: +ConstPointerTo(const ConstPointerTo &r) noexcept : + PointerToBase((Y *)r.p()) +{ +} + +/** + * + */ +template +template +ALWAYS_INLINE ConstPointerTo:: +ConstPointerTo(PointerTo &&r) noexcept : + PointerToBase(std::move(r)) +{ +} + +/** + * + */ +template +template +ALWAYS_INLINE ConstPointerTo:: +ConstPointerTo(ConstPointerTo &&r) noexcept : + PointerToBase(std::move(r)) +{ +} +#endif // !CPPPARSER + /** * */ @@ -192,6 +308,52 @@ operator = (ConstPointerTo &&from) noexcept { return *this; } +#ifndef CPPPARSER +/** + * + */ +template +template +ALWAYS_INLINE ConstPointerTo &ConstPointerTo:: +operator = (const PointerTo &r) noexcept { + this->reassign(r.p()); + return *this; +} + +/** + * + */ +template +template +ALWAYS_INLINE ConstPointerTo &ConstPointerTo:: +operator = (const ConstPointerTo &r) noexcept { + this->reassign((Y *)r.p()); + return *this; +} + +/** + * + */ +template +template +ALWAYS_INLINE ConstPointerTo &ConstPointerTo:: +operator = (PointerTo &&r) noexcept { + this->reassign(std::move(r)); + return *this; +} + +/** + * + */ +template +template +ALWAYS_INLINE ConstPointerTo &ConstPointerTo:: +operator = (ConstPointerTo &&r) noexcept { + this->reassign(std::move(r)); + return *this; +} +#endif // !CPPPARSER + /** * */ diff --git a/panda/src/express/pointerTo.h b/panda/src/express/pointerTo.h index 1f9704c3f3..e9250a2f8a 100644 --- a/panda/src/express/pointerTo.h +++ b/panda/src/express/pointerTo.h @@ -77,8 +77,21 @@ PUBLISHED: public: INLINE PointerTo(PointerTo &&from) noexcept; + + template + ALWAYS_INLINE explicit PointerTo(Y *ptr) noexcept; + template + ALWAYS_INLINE PointerTo(const PointerTo &r) noexcept; + template + ALWAYS_INLINE PointerTo(PointerTo &&r) noexcept; + INLINE PointerTo &operator = (PointerTo &&from) noexcept; + template + ALWAYS_INLINE PointerTo &operator = (const PointerTo &r) noexcept; + template + ALWAYS_INLINE PointerTo &operator = (PointerTo &&r) noexcept; + constexpr To &operator *() const noexcept; constexpr To *operator -> () const noexcept; // MSVC.NET 2005 insists that we use T *, and not To *, here. @@ -141,9 +154,30 @@ PUBLISHED: public: INLINE ConstPointerTo(PointerTo &&from) noexcept; INLINE ConstPointerTo(ConstPointerTo &&from) noexcept; + + template + ALWAYS_INLINE explicit ConstPointerTo(const Y *ptr) noexcept; + template + ALWAYS_INLINE ConstPointerTo(const PointerTo &r) noexcept; + template + ALWAYS_INLINE ConstPointerTo(const ConstPointerTo &r) noexcept; + template + ALWAYS_INLINE ConstPointerTo(PointerTo &&r) noexcept; + template + ALWAYS_INLINE ConstPointerTo(ConstPointerTo &&r) noexcept; + INLINE ConstPointerTo &operator = (PointerTo &&from) noexcept; INLINE ConstPointerTo &operator = (ConstPointerTo &&from) noexcept; + template + ALWAYS_INLINE ConstPointerTo &operator = (const PointerTo &r) noexcept; + template + ALWAYS_INLINE ConstPointerTo &operator = (const ConstPointerTo &r) noexcept; + template + ALWAYS_INLINE ConstPointerTo &operator = (PointerTo &&r) noexcept; + template + ALWAYS_INLINE ConstPointerTo &operator = (ConstPointerTo &&r) noexcept; + constexpr const To &operator *() const noexcept; constexpr const To *operator -> () const noexcept; constexpr operator const T *() const noexcept; diff --git a/panda/src/express/pointerToBase.I b/panda/src/express/pointerToBase.I index e6e749f1f4..819e16efec 100644 --- a/panda/src/express/pointerToBase.I +++ b/panda/src/express/pointerToBase.I @@ -44,11 +44,24 @@ PointerToBase(const PointerToBase ©) { */ template INLINE PointerToBase:: -~PointerToBase() { - if (_void_ptr != nullptr) { - unref_delete((To *)_void_ptr); - _void_ptr = nullptr; - } +PointerToBase(PointerToBase &&from) noexcept { + _void_ptr = from._void_ptr; + from._void_ptr = nullptr; +} + +/** + * + */ +template +template +INLINE PointerToBase:: +PointerToBase(PointerToBase &&r) noexcept { + // If this next line gives an error, you are trying to convert a PointerTo + // from an incompatible type of another PointerTo. + To *ptr = (Y *)r._void_ptr; + + this->_void_ptr = ptr; + r._void_ptr = nullptr; } /** @@ -56,9 +69,11 @@ INLINE PointerToBase:: */ template INLINE PointerToBase:: -PointerToBase(PointerToBase &&from) noexcept { - _void_ptr = from._void_ptr; - from._void_ptr = nullptr; +~PointerToBase() { + if (_void_ptr != nullptr) { + unref_delete((To *)_void_ptr); + _void_ptr = nullptr; + } } /** @@ -84,6 +99,31 @@ reassign(PointerToBase &&from) noexcept { } } +/** + * Like above, but casts from a compatible pointer type. + */ +template +template +INLINE void PointerToBase:: +reassign(PointerToBase &&from) noexcept { + // Protect against self-move-assignment. + if (from._void_ptr != this->_void_ptr) { + To *old_ptr = (To *)this->_void_ptr; + + // If there is a compile error on this line, it means you tried to assign + // an incompatible type. + To *new_ptr = (Y *)from._void_ptr; + + this->_void_ptr = new_ptr; + from._void_ptr = nullptr; + + // Now delete the old pointer. + if (old_ptr != nullptr) { + unref_delete(old_ptr); + } + } +} + /** * This is the main work of the PointerTo family. When the pointer is * reassigned, decrement the old reference count and increment the new one. diff --git a/panda/src/express/pointerToBase.h b/panda/src/express/pointerToBase.h index 057a465454..959574aba7 100644 --- a/panda/src/express/pointerToBase.h +++ b/panda/src/express/pointerToBase.h @@ -35,17 +35,25 @@ protected: INLINE PointerToBase(To *ptr); INLINE PointerToBase(const PointerToBase ©); INLINE PointerToBase(PointerToBase &&from) noexcept; + template + INLINE PointerToBase(PointerToBase &&r) noexcept; + INLINE ~PointerToBase(); INLINE void reassign(To *ptr); INLINE void reassign(const PointerToBase ©); INLINE void reassign(PointerToBase &&from) noexcept; + template + INLINE void reassign(PointerToBase &&from) noexcept; INLINE void update_type(To *ptr); // No assignment or retrieval functions are declared in PointerToBase, // because we will have to specialize on const vs. non-const later. + // This is needed to be able to access the privates of other instantiations. + template friend class PointerToBase; + PUBLISHED: ALWAYS_INLINE void clear(); From c6ed4e1836440c459873f9bc784c83b1eaae2e64 Mon Sep 17 00:00:00 2001 From: rdb Date: Sun, 8 Jul 2018 21:39:43 +0200 Subject: [PATCH 028/125] general: don't cast to regular pointer when returning a PointerTo This is inefficient because it induces an unnecessary ref()/unref() pair when we just need to move the pointer out of the function. Thanks to 23128e4695d2e8581551be161f20cf7d53ca87b5, we can now move between related pointer types, making the .p() hack unnecessary. --- panda/src/collide/collisionParabola.cxx | 2 +- panda/src/collide/collisionPolygon.cxx | 4 ++-- panda/src/collide/collisionSegment.cxx | 2 +- panda/src/collide/collisionSolid.cxx | 4 ++-- panda/src/downloader/virtualFileMountHTTP.cxx | 2 +- panda/src/dxgsg9/wdxGraphicsPipe9.cxx | 2 +- panda/src/express/virtualFileMount.cxx | 2 +- panda/src/ffmpeg/ffmpegVideo.cxx | 2 +- panda/src/ffmpeg/ffmpegVideoCursor.cxx | 4 ++-- panda/src/framework/windowFramework.cxx | 2 +- panda/src/gobj/geomLines.cxx | 2 +- panda/src/gobj/geomLinestrips.cxx | 6 +++--- panda/src/gobj/geomLinestripsAdjacency.cxx | 4 ++-- panda/src/gobj/geomPrimitive.cxx | 2 +- panda/src/gobj/geomTriangles.cxx | 6 +++--- panda/src/gobj/geomTrianglesAdjacency.cxx | 4 ++-- panda/src/gobj/geomTrifans.cxx | 4 ++-- panda/src/gobj/geomTristrips.cxx | 4 ++-- panda/src/gobj/internalName_ext.cxx | 2 +- panda/src/gobj/lens.cxx | 2 +- panda/src/gobj/shader.cxx | 3 +-- panda/src/gobj/texture.cxx | 3 +-- panda/src/grutil/cardMaker.cxx | 2 +- panda/src/grutil/fisheyeMaker.cxx | 2 +- panda/src/grutil/movieTexture.cxx | 2 +- panda/src/pgraph/stateMunger.cxx | 2 +- panda/src/pgui/pgFrameStyle.cxx | 8 ++++---- panda/src/speedtree/loaderFileTypeSrt.cxx | 2 +- panda/src/speedtree/loaderFileTypeStf.cxx | 2 +- panda/src/text/textNode.cxx | 6 +++--- panda/src/vision/openCVTexture.cxx | 2 +- pandatool/src/ptloader/loaderFileTypePandatool.cxx | 2 +- pandatool/src/xfile/xFileDataDef.cxx | 2 +- 33 files changed, 49 insertions(+), 51 deletions(-) diff --git a/panda/src/collide/collisionParabola.cxx b/panda/src/collide/collisionParabola.cxx index b439440228..b758cf037a 100644 --- a/panda/src/collide/collisionParabola.cxx +++ b/panda/src/collide/collisionParabola.cxx @@ -157,7 +157,7 @@ compute_internal_bounds() const { LPoint3(0.01, 0, max_z), LPoint3(-0.01, 0, max_z)); // And convert that back into real space. volume->xform(from_parabola); - return volume.p(); + return volume; } /** diff --git a/panda/src/collide/collisionPolygon.cxx b/panda/src/collide/collisionPolygon.cxx index 25dc01d272..24c8230d2f 100644 --- a/panda/src/collide/collisionPolygon.cxx +++ b/panda/src/collide/collisionPolygon.cxx @@ -271,9 +271,9 @@ get_viz(const CullTraverser *trav, const CullTraverserData &data, draw_polygon(viz_geom_node, bounds_viz_geom_node, new_points); if (bounds_only) { - return bounds_viz_geom_node.p(); + return bounds_viz_geom_node; } else { - return viz_geom_node.p(); + return viz_geom_node; } } diff --git a/panda/src/collide/collisionSegment.cxx b/panda/src/collide/collisionSegment.cxx index 802259b338..f0ea03f12a 100644 --- a/panda/src/collide/collisionSegment.cxx +++ b/panda/src/collide/collisionSegment.cxx @@ -131,7 +131,7 @@ compute_internal_bounds() const { LPoint3(0.01, -0.01, 0.01), LPoint3(-0.01, -0.01, 0.01)); volume->xform(from_segment); - return volume.p(); + return volume; } /** diff --git a/panda/src/collide/collisionSolid.cxx b/panda/src/collide/collisionSolid.cxx index 0e83c647de..b862ec7c73 100644 --- a/panda/src/collide/collisionSolid.cxx +++ b/panda/src/collide/collisionSolid.cxx @@ -146,9 +146,9 @@ get_viz(const CullTraverser *, const CullTraverserData &, bool bounds_only) cons } if (bounds_only) { - return _bounds_viz_geom.p(); + return _bounds_viz_geom; } else { - return _viz_geom.p(); + return _viz_geom; } } diff --git a/panda/src/downloader/virtualFileMountHTTP.cxx b/panda/src/downloader/virtualFileMountHTTP.cxx index 25e9dc99ea..09625d53bc 100644 --- a/panda/src/downloader/virtualFileMountHTTP.cxx +++ b/panda/src/downloader/virtualFileMountHTTP.cxx @@ -168,7 +168,7 @@ make_virtual_file(const Filename &local_filename, new VirtualFileHTTP(this, local_filename, implicit_pz_file, open_flags); vfile->set_original_filename(original_filename); - return vfile.p(); + return vfile; } /** diff --git a/panda/src/dxgsg9/wdxGraphicsPipe9.cxx b/panda/src/dxgsg9/wdxGraphicsPipe9.cxx index cbfada1b41..6c85c6652f 100644 --- a/panda/src/dxgsg9/wdxGraphicsPipe9.cxx +++ b/panda/src/dxgsg9/wdxGraphicsPipe9.cxx @@ -846,7 +846,7 @@ make_device(void *scrn) { _device = device; wdxdisplay9_cat.info() << "walla: device" << device << "\n"; - return device.p(); + return device; } pmap g_D3DFORMATmap; diff --git a/panda/src/express/virtualFileMount.cxx b/panda/src/express/virtualFileMount.cxx index 37e3554ac2..0bfc9fc3e3 100644 --- a/panda/src/express/virtualFileMount.cxx +++ b/panda/src/express/virtualFileMount.cxx @@ -58,7 +58,7 @@ make_virtual_file(const Filename &local_filename, make_directory(local); } - return file.p(); + return file; } /** diff --git a/panda/src/ffmpeg/ffmpegVideo.cxx b/panda/src/ffmpeg/ffmpegVideo.cxx index c12892fe47..3cc7105fdd 100644 --- a/panda/src/ffmpeg/ffmpegVideo.cxx +++ b/panda/src/ffmpeg/ffmpegVideo.cxx @@ -60,7 +60,7 @@ open() { ffmpeg_cat.error() << "Could not open " << _filename << "\n"; return nullptr; } else { - return result.p(); + return result; } } diff --git a/panda/src/ffmpeg/ffmpegVideoCursor.cxx b/panda/src/ffmpeg/ffmpegVideoCursor.cxx index 4803e41297..f8c2163b73 100644 --- a/panda/src/ffmpeg/ffmpegVideoCursor.cxx +++ b/panda/src/ffmpeg/ffmpegVideoCursor.cxx @@ -446,7 +446,7 @@ fetch_buffer() { << " at frame " << _current_frame << ", returning NULL\n"; } } - return frame.p(); + return frame; } /** @@ -455,7 +455,7 @@ fetch_buffer() { PT(MovieVideoCursor::Buffer) FfmpegVideoCursor:: make_new_buffer() { PT(FfmpegBuffer) frame = new FfmpegBuffer(size_x() * size_y() * get_num_components(), _video_timebase); - return frame.p(); + return frame; } /** diff --git a/panda/src/framework/windowFramework.cxx b/panda/src/framework/windowFramework.cxx index 1a6c8b1d77..db49ee97e8 100644 --- a/panda/src/framework/windowFramework.cxx +++ b/panda/src/framework/windowFramework.cxx @@ -1334,7 +1334,7 @@ load_image_as_model(const Filename &filename) { card_node->add_geom(geom); - return card_node.p(); + return card_node; } /** diff --git a/panda/src/gobj/geomLines.cxx b/panda/src/gobj/geomLines.cxx index 2d38fc8838..d9b460b14a 100644 --- a/panda/src/gobj/geomLines.cxx +++ b/panda/src/gobj/geomLines.cxx @@ -128,7 +128,7 @@ make_adjacency() const { } adj->set_vertices(std::move(new_vertices)); - return adj.p(); + return adj; } /** diff --git a/panda/src/gobj/geomLinestrips.cxx b/panda/src/gobj/geomLinestrips.cxx index 3e37496bad..8e85ac870a 100644 --- a/panda/src/gobj/geomLinestrips.cxx +++ b/panda/src/gobj/geomLinestrips.cxx @@ -164,7 +164,7 @@ make_adjacency() const { } nassertr(vi == num_vertices, nullptr); - return adj.p(); + return adj; } /** @@ -220,7 +220,7 @@ decompose_impl() const { // Skip unused vertices between tristrips. vi += num_unused; int end = ends[li]; - nassertr(vi + 1 <= end, lines.p()); + nassertr(vi + 1 <= end, lines); int v0 = get_vertex(vi); ++vi; while (vi < end) { @@ -235,7 +235,7 @@ decompose_impl() const { } nassertr(vi == get_num_vertices(), nullptr); - return lines.p(); + return lines; } /** diff --git a/panda/src/gobj/geomLinestripsAdjacency.cxx b/panda/src/gobj/geomLinestripsAdjacency.cxx index 11d14ab319..c9d4ba6891 100644 --- a/panda/src/gobj/geomLinestripsAdjacency.cxx +++ b/panda/src/gobj/geomLinestripsAdjacency.cxx @@ -142,7 +142,7 @@ decompose_impl() const { // Skip unused vertices between tristrips. vi += num_unused; int end = ends[li]; - nassertr(vi + 3 <= end, lines.p()); + nassertr(vi + 3 <= end, lines); int v0 = from.get_vertex(vi++); int v1 = from.get_vertex(vi++); int v2 = from.get_vertex(vi++); @@ -160,7 +160,7 @@ decompose_impl() const { } nassertr(vi == num_vertices, nullptr); - return lines.p(); + return lines; } /** diff --git a/panda/src/gobj/geomPrimitive.cxx b/panda/src/gobj/geomPrimitive.cxx index f52e06663a..da3c10dffd 100644 --- a/panda/src/gobj/geomPrimitive.cxx +++ b/panda/src/gobj/geomPrimitive.cxx @@ -55,7 +55,7 @@ GeomPrimitive() { */ PT(CopyOnWriteObject) GeomPrimitive:: make_cow_copy() { - return make_copy().p(); + return make_copy(); } /** diff --git a/panda/src/gobj/geomTriangles.cxx b/panda/src/gobj/geomTriangles.cxx index 809b9199c0..5171ec6b5f 100644 --- a/panda/src/gobj/geomTriangles.cxx +++ b/panda/src/gobj/geomTriangles.cxx @@ -138,7 +138,7 @@ make_adjacency() const { } adj->set_vertices(std::move(new_vertices)); - return adj.p(); + return adj; } /** @@ -199,7 +199,7 @@ doubleside_impl() const { reversed = (GeomTriangles *)DCAST(GeomTriangles, reversed->rotate()); } - return reversed.p(); + return reversed; } /** @@ -232,7 +232,7 @@ reverse_impl() const { break; } - return reversed.p(); + return reversed; } /** diff --git a/panda/src/gobj/geomTrianglesAdjacency.cxx b/panda/src/gobj/geomTrianglesAdjacency.cxx index 0dffa74329..5278d69bbb 100644 --- a/panda/src/gobj/geomTrianglesAdjacency.cxx +++ b/panda/src/gobj/geomTrianglesAdjacency.cxx @@ -133,7 +133,7 @@ doubleside_impl() const { reversed = (GeomTrianglesAdjacency *)DCAST(GeomTrianglesAdjacency, reversed->rotate()); } - return reversed.p(); + return reversed; } /** @@ -166,7 +166,7 @@ reverse_impl() const { break; } - return reversed.p(); + return reversed; } /** diff --git a/panda/src/gobj/geomTrifans.cxx b/panda/src/gobj/geomTrifans.cxx index 0c5d87f53a..a99481e92e 100644 --- a/panda/src/gobj/geomTrifans.cxx +++ b/panda/src/gobj/geomTrifans.cxx @@ -110,7 +110,7 @@ decompose_impl() const { int li = 0; while (li < (int)ends.size()) { int end = ends[li]; - nassertr(vi + 2 <= end, triangles.p()); + nassertr(vi + 2 <= end, triangles); int v0 = get_vertex(vi); ++vi; int v1 = get_vertex(vi); @@ -129,7 +129,7 @@ decompose_impl() const { nassertr(vi == num_vertices, nullptr); - return triangles.p(); + return triangles; } /** diff --git a/panda/src/gobj/geomTristrips.cxx b/panda/src/gobj/geomTristrips.cxx index 0b88bcf8f1..15b46c409a 100644 --- a/panda/src/gobj/geomTristrips.cxx +++ b/panda/src/gobj/geomTristrips.cxx @@ -219,7 +219,7 @@ make_adjacency() const { } nassertr(vi == num_vertices, nullptr); - return adj.p(); + return adj; } /** @@ -358,7 +358,7 @@ decompose_impl() const { nassertr(vi == num_vertices, nullptr); } - return triangles.p(); + return triangles; } /** diff --git a/panda/src/gobj/internalName_ext.cxx b/panda/src/gobj/internalName_ext.cxx index 4967b330b5..f1cdf0a725 100644 --- a/panda/src/gobj/internalName_ext.cxx +++ b/panda/src/gobj/internalName_ext.cxx @@ -76,7 +76,7 @@ make(PyStringObject *str) { iname->ref(); InternalName::_py_intern_table.insert(std::make_pair((PyObject *)str, iname.p())); - return iname.p(); + return iname; } } diff --git a/panda/src/gobj/lens.cxx b/panda/src/gobj/lens.cxx index 470b64447a..f66f2ba6b9 100644 --- a/panda/src/gobj/lens.cxx +++ b/panda/src/gobj/lens.cxx @@ -630,7 +630,7 @@ make_geometry() { PT(Geom) geom = new Geom(cdata->_geom_data); geom->add_primitive(line); - return geom.p(); + return geom; } /** diff --git a/panda/src/gobj/shader.cxx b/panda/src/gobj/shader.cxx index 31a8d986ed..22a5389b8b 100644 --- a/panda/src/gobj/shader.cxx +++ b/panda/src/gobj/shader.cxx @@ -3417,8 +3417,7 @@ parse_eof() { */ PT(AsyncFuture) Shader:: prepare(PreparedGraphicsObjects *prepared_objects) { - PT(PreparedGraphicsObjects::EnqueuedObject) obj = prepared_objects->enqueue_shader_future(this); - return obj.p(); + return prepared_objects->enqueue_shader_future(this); } /** diff --git a/panda/src/gobj/texture.cxx b/panda/src/gobj/texture.cxx index 5918210fdc..c538391018 100644 --- a/panda/src/gobj/texture.cxx +++ b/panda/src/gobj/texture.cxx @@ -1427,8 +1427,7 @@ peek() { */ PT(AsyncFuture) Texture:: prepare(PreparedGraphicsObjects *prepared_objects) { - PT(PreparedGraphicsObjects::EnqueuedObject) obj = prepared_objects->enqueue_texture_future(this); - return obj.p(); + return prepared_objects->enqueue_texture_future(this); } /** diff --git a/panda/src/grutil/cardMaker.cxx b/panda/src/grutil/cardMaker.cxx index 1b68d1482a..33f6fc88ad 100644 --- a/panda/src/grutil/cardMaker.cxx +++ b/panda/src/grutil/cardMaker.cxx @@ -133,7 +133,7 @@ generate() { gnode->add_geom(geom, state); - return gnode.p(); + return gnode; } /** diff --git a/panda/src/grutil/fisheyeMaker.cxx b/panda/src/grutil/fisheyeMaker.cxx index ad7a8a90ef..5e7d7395ec 100644 --- a/panda/src/grutil/fisheyeMaker.cxx +++ b/panda/src/grutil/fisheyeMaker.cxx @@ -322,7 +322,7 @@ generate() { } } - return geom_node.p(); + return geom_node; } /** diff --git a/panda/src/grutil/movieTexture.cxx b/panda/src/grutil/movieTexture.cxx index 280079948d..36f4913085 100644 --- a/panda/src/grutil/movieTexture.cxx +++ b/panda/src/grutil/movieTexture.cxx @@ -409,7 +409,7 @@ make_copy_impl() const { CDWriter cdata_copy(copy->_cycler, true); copy->do_assign(cdata_copy, cdata_copy_tex, this, cdata, cdata_tex); - return copy.p(); + return copy; } /** diff --git a/panda/src/pgraph/stateMunger.cxx b/panda/src/pgraph/stateMunger.cxx index 8eba900f70..5b52442db0 100644 --- a/panda/src/pgraph/stateMunger.cxx +++ b/panda/src/pgraph/stateMunger.cxx @@ -40,7 +40,7 @@ munge_state(const RenderState *state) { } CPT(RenderState) result = munge_state_impl(state); - munged_states.store(id, result.p()); + munged_states.store(id, result); return result; } diff --git a/panda/src/pgui/pgFrameStyle.cxx b/panda/src/pgui/pgFrameStyle.cxx index b4590bf8f0..a8f53478cb 100644 --- a/panda/src/pgui/pgFrameStyle.cxx +++ b/panda/src/pgui/pgFrameStyle.cxx @@ -257,7 +257,7 @@ generate_flat_geom(const LVecBase4 &frame) { geom->add_primitive(strip); gnode->add_geom(geom, state); - return gnode.p(); + return gnode; } /** @@ -431,7 +431,7 @@ generate_bevel_geom(const LVecBase4 &frame, bool in) { } gnode->add_geom(geom, state); - return gnode.p(); + return gnode; } /** @@ -663,7 +663,7 @@ generate_groove_geom(const LVecBase4 &frame, bool in) { } gnode->add_geom(geom, state); - return gnode.p(); + return gnode; } /** @@ -803,5 +803,5 @@ generate_texture_border_geom(const LVecBase4 &frame) { geom->add_primitive(strip); gnode->add_geom(geom, state); - return gnode.p(); + return gnode; } diff --git a/panda/src/speedtree/loaderFileTypeSrt.cxx b/panda/src/speedtree/loaderFileTypeSrt.cxx index fa1f7b3a48..a0fe4e3022 100644 --- a/panda/src/speedtree/loaderFileTypeSrt.cxx +++ b/panda/src/speedtree/loaderFileTypeSrt.cxx @@ -68,5 +68,5 @@ load_file(const Filename &path, const LoaderOptions &, PT(SpeedTreeNode) st = new SpeedTreeNode(path.get_basename()); st->add_instance(tree, STTransform()); - return st.p(); + return st; } diff --git a/panda/src/speedtree/loaderFileTypeStf.cxx b/panda/src/speedtree/loaderFileTypeStf.cxx index 981d36b59b..9d83bddd3d 100644 --- a/panda/src/speedtree/loaderFileTypeStf.cxx +++ b/panda/src/speedtree/loaderFileTypeStf.cxx @@ -62,5 +62,5 @@ load_file(const Filename &path, const LoaderOptions &options, PT(SpeedTreeNode) st = new SpeedTreeNode(path.get_basename()); st->add_from_stf(path, options); - return st.p(); + return st; } diff --git a/panda/src/text/textNode.cxx b/panda/src/text/textNode.cxx index 19395788c3..92001d7b40 100644 --- a/panda/src/text/textNode.cxx +++ b/panda/src/text/textNode.cxx @@ -755,7 +755,7 @@ make_frame() { frame_node->add_geom(geom2, state); } - return frame_node.p(); + return frame_node; } /** @@ -795,7 +795,7 @@ make_card() { card_node->add_geom(geom); - return card_node.p(); + return card_node; } @@ -896,7 +896,7 @@ make_card_with_border() { card_node->add_geom(geom); - return card_node.p(); + return card_node; } /** diff --git a/panda/src/vision/openCVTexture.cxx b/panda/src/vision/openCVTexture.cxx index 702e0932af..58c233232a 100644 --- a/panda/src/vision/openCVTexture.cxx +++ b/panda/src/vision/openCVTexture.cxx @@ -98,7 +98,7 @@ make_copy_impl() const { Texture::CDWriter cdata_copy_tex(copy->Texture::_cycler, true); copy->do_assign(cdata_copy_tex, this, cdata_tex); - return copy.p(); + return copy; } /** diff --git a/pandatool/src/ptloader/loaderFileTypePandatool.cxx b/pandatool/src/ptloader/loaderFileTypePandatool.cxx index 769eb737d0..9536b3fe65 100644 --- a/pandatool/src/ptloader/loaderFileTypePandatool.cxx +++ b/pandatool/src/ptloader/loaderFileTypePandatool.cxx @@ -196,7 +196,7 @@ load_file(const Filename &path, const LoaderOptions &options, } delete loader; - return result.p(); + return result; } /** diff --git a/pandatool/src/xfile/xFileDataDef.cxx b/pandatool/src/xfile/xFileDataDef.cxx index 2a35528768..5fe983891b 100644 --- a/pandatool/src/xfile/xFileDataDef.cxx +++ b/pandatool/src/xfile/xFileDataDef.cxx @@ -376,7 +376,7 @@ unpack_template_value(const XFileParseDataList &parse_data_list, return nullptr; } - return data_value.p(); + return data_value; } /** From abe20fc4894603058e8e2dc3ffe92aa6c4b1e4e8 Mon Sep 17 00:00:00 2001 From: rdb Date: Sun, 8 Jul 2018 21:49:37 +0200 Subject: [PATCH 029/125] fmod: return NullAudioSound if file does not exist This matches the OpenAL behaviour, and is needed to fix the unit tests on macOS. --- panda/src/audiotraits/fmodAudioManager.cxx | 20 ++++++++++++-------- panda/src/audiotraits/fmodAudioSound.cxx | 17 ++++++----------- panda/src/audiotraits/fmodAudioSound.h | 7 ++++--- 3 files changed, 22 insertions(+), 22 deletions(-) diff --git a/panda/src/audiotraits/fmodAudioManager.cxx b/panda/src/audiotraits/fmodAudioManager.cxx index 1f7ed7cd22..42fd08c536 100644 --- a/panda/src/audiotraits/fmodAudioManager.cxx +++ b/panda/src/audiotraits/fmodAudioManager.cxx @@ -419,15 +419,19 @@ get_sound(const std::string &file_name, bool positional, int) { VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr(); vfs->resolve_filename(path, get_model_path()); - // Build a new AudioSound from the audio data. - PT(AudioSound) audioSound; - PT(FmodAudioSound) fmodAudioSound = new FmodAudioSound(this, path, positional); + // Locate the file on disk. + path.set_binary(); + PT(VirtualFile) file = vfs->get_file(path); + if (file != nullptr) { + // Build a new AudioSound from the audio data. + PT(FmodAudioSound) sound = new FmodAudioSound(this, file, positional); - _all_sounds.insert(fmodAudioSound); - - audioSound = fmodAudioSound; - - return audioSound; + _all_sounds.insert(sound); + return sound; + } else { + audio_error("createSound(" << path << "): File not found."); + return get_null_sound(); + } } /** diff --git a/panda/src/audiotraits/fmodAudioSound.cxx b/panda/src/audiotraits/fmodAudioSound.cxx index 02d8ae51aa..dd060844e9 100644 --- a/panda/src/audiotraits/fmodAudioSound.cxx +++ b/panda/src/audiotraits/fmodAudioSound.cxx @@ -39,9 +39,10 @@ TypeHandle FmodAudioSound::_type_handle; */ FmodAudioSound:: -FmodAudioSound(AudioManager *manager, Filename file_name, bool positional) { +FmodAudioSound(AudioManager *manager, VirtualFile *file, bool positional) { ReMutexHolder holder(FmodAudioManager::_lock); - audio_debug("FmodAudioSound::FmodAudioSound() Creating new sound, filename: " << file_name ); + audio_debug("FmodAudioSound::FmodAudioSound() Creating new sound, filename: " + << file->get_original_filename()); _active = manager->get_active(); _paused = false; @@ -77,20 +78,14 @@ FmodAudioSound(AudioManager *manager, Filename file_name, bool positional) { _manager = fmanager; _channel = 0; - _file_name = file_name; + _file_name = file->get_original_filename(); _file_name.set_binary(); // Get the Speaker Mode [Important for later on.] result = _manager->_system->getSpeakerMode( &_speakermode ); fmod_audio_errcheck("_system->getSpeakerMode()", result); - VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr(); - PT(VirtualFile) file = vfs->get_file(_file_name); - if (file == nullptr) { - // File not found. We will display the appropriate error message below. - result = FMOD_ERR_FILE_NOTFOUND; - - } else { + { bool preload = (fmod_audio_preload_threshold < 0) || (file->get_file_size() < fmod_audio_preload_threshold); int flags = FMOD_SOFTWARE; flags |= positional ? FMOD_3D : FMOD_2D; @@ -149,7 +144,7 @@ FmodAudioSound(AudioManager *manager, Filename file_name, bool positional) { #if defined(HAVE_THREADS) && !defined(SIMPLE_THREADS) // Otherwise, if the Panda threading system is compiled in, we can // assign callbacks to read the file through the VFS. - name_or_data = (const char *)file.p(); + name_or_data = (const char *)file; sound_info.length = (unsigned int)info.get_size(); sound_info.useropen = open_callback; sound_info.userclose = close_callback; diff --git a/panda/src/audiotraits/fmodAudioSound.h b/panda/src/audiotraits/fmodAudioSound.h index 8d0ad4408c..40de00823d 100644 --- a/panda/src/audiotraits/fmodAudioSound.h +++ b/panda/src/audiotraits/fmodAudioSound.h @@ -70,10 +70,11 @@ #include #include -class EXPCL_FMOD_AUDIO FmodAudioSound : public AudioSound { - public: +class VirtualFile; - FmodAudioSound(AudioManager *manager, Filename fn, bool positional ); +class EXPCL_FMOD_AUDIO FmodAudioSound : public AudioSound { +public: + FmodAudioSound(AudioManager *manager, VirtualFile *file, bool positional); ~FmodAudioSound(); // For best compatibility, set the loop_count, start_time, volume, and From 7c8426a79f25321b8d5f2d22aa46b4880c70027c Mon Sep 17 00:00:00 2001 From: rdb Date: Sun, 8 Jul 2018 22:28:52 +0200 Subject: [PATCH 030/125] tests: fix int overflow error with GLSL shader test on some drivers --- tests/display/test_glsl_shader.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/display/test_glsl_shader.py b/tests/display/test_glsl_shader.py index 33bcf969f0..c13e99e92e 100644 --- a/tests/display/test_glsl_shader.py +++ b/tests/display/test_glsl_shader.py @@ -168,7 +168,7 @@ def test_glsl_int(gsg): inputs = dict( zero=0, intmax=0x7fffffff, - intmin=-0x80000000, + intmin=-0x7fffffff, ) preamble = """ uniform int zero; @@ -178,7 +178,7 @@ def test_glsl_int(gsg): code = """ assert(zero == 0); assert(intmax == 0x7fffffff); - assert(intmin == -0x80000000); + assert(intmin == -0x7fffffff); """ run_glsl_test(gsg, code, preamble, inputs) From e673937384ae2303809db43d8fa513527e01e4c2 Mon Sep 17 00:00:00 2001 From: rdb Date: Mon, 9 Jul 2018 16:02:06 +0200 Subject: [PATCH 031/125] parser-inc: add include to unordered_map/set for allocator --- dtool/src/parser-inc/unordered_map | 3 ++- dtool/src/parser-inc/unordered_set | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/dtool/src/parser-inc/unordered_map b/dtool/src/parser-inc/unordered_map index e3c6220d35..035932bd49 100644 --- a/dtool/src/parser-inc/unordered_map +++ b/dtool/src/parser-inc/unordered_map @@ -24,9 +24,10 @@ #include #include #include +#include namespace std { - + template , diff --git a/dtool/src/parser-inc/unordered_set b/dtool/src/parser-inc/unordered_set index 766161d12b..53b6d794c8 100644 --- a/dtool/src/parser-inc/unordered_set +++ b/dtool/src/parser-inc/unordered_set @@ -24,6 +24,7 @@ #include #include #include +#include namespace std { @@ -46,7 +47,7 @@ namespace std { typedef typename allocator_type::const_reference const_reference; typedef size_t size_type; typedef std::ptrdiff_t difference_type; - + class iterator; class const_iterator; class local_iterator; From fbce833aae112d1bc3c99a8d851337de7575d0c8 Mon Sep 17 00:00:00 2001 From: rdb Date: Mon, 9 Jul 2018 16:09:50 +0200 Subject: [PATCH 032/125] pgui: reduce unnecessary locking in PGItem A deadlock has been observed if the lock is held while traversing the scene graph, so the need for locking in cull_callback is now reduced. --- panda/src/pgui/pgItem.I | 13 ++++ panda/src/pgui/pgItem.cxx | 133 ++++++++++++++++++++++---------------- panda/src/pgui/pgItem.h | 8 ++- 3 files changed, 97 insertions(+), 57 deletions(-) diff --git a/panda/src/pgui/pgItem.I b/panda/src/pgui/pgItem.I index f60e4a256c..cfbf10f6b0 100644 --- a/panda/src/pgui/pgItem.I +++ b/panda/src/pgui/pgItem.I @@ -202,6 +202,19 @@ get_suppress_flags() const { return _region->get_suppress_flags(); } +/** + * Returns the Node that is the root of the subgraph that will be drawn when + * the PGItem is in the indicated state. The first time this is called for a + * particular state index, it may create the Node. + */ +INLINE NodePath &PGItem:: +get_state_def(int state) { + nassertr(state >= 0 && state < 1000, get_state_def(0)); // Sanity check. + + LightReMutexHolder holder(_lock); + return do_get_state_def(state); +} + /** * Returns the unique ID assigned to this PGItem. This will be assigned to * the region created with the MouseWatcher, and will thus be used to generate diff --git a/panda/src/pgui/pgItem.cxx b/panda/src/pgui/pgItem.cxx index 582c12985b..a266547ced 100644 --- a/panda/src/pgui/pgItem.cxx +++ b/panda/src/pgui/pgItem.cxx @@ -35,8 +35,6 @@ #include "audioSound.h" #endif -using std::max; -using std::min; using std::string; TypeHandle PGItem::_type_handle; @@ -59,16 +57,15 @@ is_right(const LVector2 &v1, const LVector2 &v2) { PGItem:: PGItem(const string &name) : PandaNode(name), - _lock(name) + _lock(name), + _notify(nullptr), + _has_frame(false), + _frame(0, 0, 0, 0), + _region(new PGMouseWatcherRegion(this)), + _state(0), + _flags(0) { set_cull_callback(); - - _notify = nullptr; - _has_frame = false; - _frame.set(0, 0, 0, 0); - _region = new PGMouseWatcherRegion(this); - _state = 0; - _flags = 0; } /** @@ -96,17 +93,16 @@ PGItem:: PGItem:: PGItem(const PGItem ©) : PandaNode(copy), + _notify(nullptr), _has_frame(copy._has_frame), _frame(copy._frame), _state(copy._state), - _flags(copy._flags) + _flags(copy._flags), + _region(new PGMouseWatcherRegion(this)) #ifdef HAVE_AUDIO , _sounds(copy._sounds) #endif { - _notify = nullptr; - _region = new PGMouseWatcherRegion(this); - // We give our region the same name as the region for the PGItem we're // copying--so that this PGItem will generate the same event names when the // user interacts with it. @@ -190,9 +186,29 @@ draw_mask_changed() { */ bool PGItem:: cull_callback(CullTraverser *trav, CullTraverserData &data) { - LightReMutexHolder holder(_lock); - bool this_node_hidden = data.is_this_node_hidden(trav->get_camera_mask()); - if (!this_node_hidden && has_frame() && get_active()) { + // We try not to hold the lock for longer than necessary. + PT(PandaNode) state_def_root; + bool has_frame; + PGMouseWatcherRegion *region; + { + LightReMutexHolder holder(_lock); + has_frame = _has_frame && ((_flags & F_active) != 0); + region = _region; + + int state = _state; + if (state >= 0 && (size_t)state < _state_defs.size()) { + StateDef &state_def = _state_defs[state]; + if (!state_def._root.is_empty()) { + if (state_def._frame_stale) { + update_frame(state); + } + + state_def_root = state_def._root.node(); + } + } + } + + if (has_frame && !data.is_this_node_hidden(trav->get_camera_mask())) { // The item has a frame, so we want to generate a region for it and update // the MouseWatcher. @@ -202,8 +218,7 @@ cull_callback(CullTraverser *trav, CullTraverserData &data) { PGCullTraverser *pg_trav; DCAST_INTO_R(pg_trav, trav, true); - CPT(TransformState) net_transform = data.get_net_transform(trav); - const LMatrix4 &transform = net_transform->get_mat(); + const LMatrix4 &transform = data.get_net_transform(trav)->get_mat(); // Consider the cull bin this object is in. Since the binning affects // the render order, we want bins that render later to get higher sort @@ -240,19 +255,20 @@ cull_callback(CullTraverser *trav, CullTraverserData &data) { // the existing interface which only provides one. sort = (bin_sort << 16) | ((sort + 0x8000) & 0xffff); - if (activate_region(transform, sort, - DCAST(ClipPlaneAttrib, data._state->get_attrib(ClipPlaneAttrib::get_class_slot())), - DCAST(ScissorAttrib, data._state->get_attrib(ScissorAttrib::get_class_slot())))) { - pg_trav->_top->add_region(get_region()); + const ClipPlaneAttrib *clip = nullptr; + const ScissorAttrib *scissor = nullptr; + data._state->get_attrib(clip); + data._state->get_attrib(scissor); + if (activate_region(transform, sort, clip, scissor)) { + pg_trav->_top->add_region(region); } } } - if (has_state_def(get_state())) { + if (state_def_root != nullptr) { // This item has a current state definition that we should use to render // the item. - NodePath &root = get_state_def(get_state()); - CullTraverserData next_data(data, root.node()); + CullTraverserData next_data(data, state_def_root); trav->traverse(next_data); } @@ -306,7 +322,7 @@ compute_internal_bounds(CPT(BoundingVolume) &internal_bounds, // get_state_def() on each one, to ensure that the frames are updated // correctly before we measure their bounding volumes. for (int i = 0; i < (int)_state_defs.size(); i++) { - NodePath &root = ((PGItem *)this)->get_state_def(i); + NodePath &root = ((PGItem *)this)->do_get_state_def(i); if (!root.is_empty()) { PandaNode *node = root.node(); child_volumes.push_back(node->get_bounds(current_thread)); @@ -388,6 +404,9 @@ bool PGItem:: activate_region(const LMatrix4 &transform, int sort, const ClipPlaneAttrib *cpa, const ScissorAttrib *sa) { + using std::min; + using std::max; + LightReMutexHolder holder(_lock); // Transform all four vertices, and get the new bounding box. This way the // region works (mostly) even if has been rotated. @@ -935,30 +954,6 @@ clear_state_def(int state) { mark_internal_bounds_stale(); } -/** - * Returns the Node that is the root of the subgraph that will be drawn when - * the PGItem is in the indicated state. The first time this is called for a - * particular state index, it may create the Node. - */ -NodePath &PGItem:: -get_state_def(int state) { - LightReMutexHolder holder(_lock); - nassertr(state >= 0 && state < 1000, get_state_def(0)); // Sanity check. - slot_state_def(state); - - if (_state_defs[state]._root.is_empty()) { - // Create a new node. - _state_defs[state]._root = NodePath("state_" + format_string(state)); - _state_defs[state]._frame_stale = true; - } - - if (_state_defs[state]._frame_stale) { - update_frame(state); - } - - return _state_defs[state]._root; -} - /** * Parents an instance of the bottom node of the indicated NodePath to the * indicated state index. @@ -973,7 +968,7 @@ instance_to_state_def(int state, const NodePath &path) { mark_internal_bounds_stale(); - return path.instance_to(get_state_def(state)); + return path.instance_to(do_get_state_def(state)); } /** @@ -998,7 +993,7 @@ set_frame_style(int state, const PGFrameStyle &style) { LightReMutexHolder holder(_lock); // Get the state def node, mainly to ensure that this state is slotted and // listed as having been defined. - NodePath &root = get_state_def(state); + NodePath &root = do_get_state_def(state); nassertv(!root.is_empty()); _state_defs[state]._frame_style = style; @@ -1097,6 +1092,9 @@ play_sound(const string &event) { */ void PGItem:: reduce_region(LVecBase4 &frame, PGItem *obscurer) const { + using std::min; + using std::max; + if (obscurer != nullptr && !obscurer->is_overall_hidden()) { LVecBase4 oframe = get_relative_frame(obscurer); @@ -1124,6 +1122,9 @@ reduce_region(LVecBase4 &frame, PGItem *obscurer) const { */ LVecBase4 PGItem:: get_relative_frame(PGItem *item) const { + using std::min; + using std::max; + NodePath this_np = NodePath::any_path((PGItem *)this); NodePath item_np = this_np.find_path_to(item); if (item_np.is_empty()) { @@ -1174,6 +1175,30 @@ frame_changed() { } } +/** + * Returns the Node that is the root of the subgraph that will be drawn when + * the PGItem is in the indicated state. The first time this is called for a + * particular state index, it may create the Node. + * + * Assumes the lock is already held. + */ +NodePath &PGItem:: +do_get_state_def(int state) { + slot_state_def(state); + + if (_state_defs[state]._root.is_empty()) { + // Create a new node. + _state_defs[state]._root = NodePath("state_" + format_string(state)); + _state_defs[state]._frame_stale = true; + } + + if (_state_defs[state]._frame_stale) { + update_frame(state); + } + + return _state_defs[state]._root; +} + /** * Ensures there is a slot in the array for the given state definition. */ @@ -1200,7 +1225,7 @@ update_frame(int state) { // Now create new frame geometry. if (has_frame()) { - NodePath &root = get_state_def(state); + NodePath &root = do_get_state_def(state); _state_defs[state]._frame = _state_defs[state]._frame_style.generate_into(root, _frame); } diff --git a/panda/src/pgui/pgItem.h b/panda/src/pgui/pgItem.h index fc7f8ff6d4..2c26f91602 100644 --- a/panda/src/pgui/pgItem.h +++ b/panda/src/pgui/pgItem.h @@ -77,11 +77,12 @@ protected: GeomTransformer &transformer, Thread *current_thread); -public: virtual void xform(const LMatrix4 &mat); bool activate_region(const LMatrix4 &transform, int sort, const ClipPlaneAttrib *cpa, const ScissorAttrib *sa); + +public: INLINE PGMouseWatcherRegion *get_region() const; virtual void enter_region(const MouseWatcherParameter ¶m); @@ -130,7 +131,7 @@ PUBLISHED: int get_num_state_defs() const; void clear_state_def(int state); bool has_state_def(int state) const; - NodePath &get_state_def(int state); + INLINE NodePath &get_state_def(int state); MAKE_SEQ(get_state_defs, get_num_state_defs, get_state_def); NodePath instance_to_state_def(int state, const NodePath &path); @@ -187,6 +188,7 @@ protected: virtual void frame_changed(); private: + NodePath &do_get_state_def(int state); void slot_state_def(int state); void update_frame(int state); void mark_frames_stale(); @@ -215,7 +217,7 @@ private: }; int _flags; - PT(PGMouseWatcherRegion) _region; + PT(PGMouseWatcherRegion) const _region; LMatrix4 _frame_inv_xform; From 55146b9f82645873b92d45953fd764c81ee4c638 Mon Sep 17 00:00:00 2001 From: rdb Date: Mon, 9 Jul 2018 17:09:11 +0200 Subject: [PATCH 033/125] dxgsg9: fix compilation error with WeakPointerTo comparison --- panda/src/dxgsg9/dxGeomMunger9.I | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/panda/src/dxgsg9/dxGeomMunger9.I b/panda/src/dxgsg9/dxGeomMunger9.I index 596802b871..cc972bf94b 100644 --- a/panda/src/dxgsg9/dxGeomMunger9.I +++ b/panda/src/dxgsg9/dxGeomMunger9.I @@ -17,14 +17,21 @@ INLINE DXGeomMunger9:: DXGeomMunger9(GraphicsStateGuardian *gsg, const RenderState *state) : StandardMunger(gsg, state, 1, NT_packed_dabc, C_color), - _texture(DCAST(TextureAttrib, state->get_attrib(TextureAttrib::get_class_slot()))), - _tex_gen(DCAST(TexGenAttrib, state->get_attrib(TexGenAttrib::get_class_slot()))) + _texture(nullptr), + _tex_gen(nullptr) { + const TextureAttrib *texture = nullptr; + const TexGenAttrib *tex_gen = nullptr; + state->get_attrib(texture); + state->get_attrib(tex_gen); + _texture = texture; + _tex_gen = tex_gen; + _filtered_texture = nullptr; _reffed_filtered_texture = false; - if (_texture != nullptr) { - _filtered_texture = _texture->filter_to_max(gsg->get_max_texture_stages()); - if (_filtered_texture != _texture) { + if (texture != nullptr) { + _filtered_texture = texture->filter_to_max(gsg->get_max_texture_stages()); + if (_filtered_texture != texture) { _filtered_texture->ref(); _reffed_filtered_texture = true; } From ff3d0052307991c357cddf5ee1bb8a17f02c3a32 Mon Sep 17 00:00:00 2001 From: rdb Date: Wed, 11 Jul 2018 13:32:39 +0200 Subject: [PATCH 034/125] x11display: fix Xlib thread safety problems --- panda/src/x11display/x11GraphicsWindow.cxx | 28 ++++++++++++++++------ 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/panda/src/x11display/x11GraphicsWindow.cxx b/panda/src/x11display/x11GraphicsWindow.cxx index 5eef6b2ea5..d1f49eedc3 100644 --- a/panda/src/x11display/x11GraphicsWindow.cxx +++ b/panda/src/x11display/x11GraphicsWindow.cxx @@ -136,10 +136,11 @@ x11GraphicsWindow(GraphicsEngine *engine, GraphicsPipe *pipe, */ x11GraphicsWindow:: ~x11GraphicsWindow() { - pmap::iterator it; - - for (it = _cursor_filenames.begin(); it != _cursor_filenames.end(); it++) { - XFreeCursor(_display, it->second); + if (!_cursor_filenames.empty()) { + LightReMutexHolder holder(x11GraphicsPipe::_x_mutex); + for (auto item : _cursor_filenames) { + XFreeCursor(_display, item.second); + } } } @@ -157,17 +158,21 @@ get_pointer(int device) const { result = _input_devices[device].get_pointer(); - // We recheck this immediately to get the most up-to-date value. - if (device == 0 && !_dga_mouse_enabled && result._in_window) { + // We recheck this immediately to get the most up-to-date value, but we + // won't bother waiting for the lock if we can't. + if (device == 0 && !_dga_mouse_enabled && result._in_window && + x11GraphicsPipe::_x_mutex.try_lock()) { XEvent event; + LightReMutexHolder holder(x11GraphicsPipe::_x_mutex); if (XQueryPointer(_display, _xwindow, &event.xbutton.root, &event.xbutton.window, &event.xbutton.x_root, &event.xbutton.y_root, &event.xbutton.x, &event.xbutton.y, &event.xbutton.state)) { double time = ClockObject::get_global_clock()->get_real_time(); result._xpos = event.xbutton.x; result._ypos = event.xbutton.y; - ((GraphicsWindowInputDevice &)_input_devices[0]).set_pointer(result._in_window, result._xpos, result._ypos, time); + ((GraphicsWindowInputDevice &)_input_devices[0]).set_pointer_in_window(result._xpos, result._ypos, time); } + x11GraphicsPipe::_x_mutex.release(); } } return result; @@ -197,6 +202,7 @@ move_pointer(int device, int x, int y) { const MouseData &md = _input_devices[0].get_pointer(); if (!md.get_in_window() || md.get_x() != x || md.get_y() != y) { if (!_dga_mouse_enabled) { + LightReMutexHolder holder(x11GraphicsPipe::_x_mutex); XWarpPointer(_display, None, _xwindow, 0, 0, 0, 0, x, y); } _input_devices[0].set_pointer_in_window(x, y); @@ -532,6 +538,8 @@ set_properties_now(WindowProperties &properties) { x11GraphicsPipe *x11_pipe; DCAST_INTO_V(x11_pipe, _pipe); + LightReMutexHolder holder(x11GraphicsPipe::_x_mutex); + // We're either going into or out of fullscreen, or are in fullscreen and // are changing the resolution. bool is_fullscreen = _properties.has_fullscreen() && _properties.get_fullscreen(); @@ -858,6 +866,7 @@ close_window() { _gsg.clear(); } + LightReMutexHolder holder(x11GraphicsPipe::_x_mutex); if (_ic != (XIC)nullptr) { XDestroyIC(_ic); _ic = (XIC)nullptr; @@ -916,6 +925,9 @@ open_window() { _properties.set_size(100, 100); } + // Make sure we are not making X11 calls from other threads. + LightReMutexHolder holder(x11GraphicsPipe::_x_mutex); + if (_properties.get_fullscreen() && x11_pipe->_have_xrandr) { XRRScreenConfiguration* conf = _XRRGetScreenInfo(_display, x11_pipe->get_root()); if (_orig_size_id == (SizeID) -1) { @@ -1059,6 +1071,8 @@ open_window() { * If already_mapped is true, the window has already been mapped (manifested) * on the display. This means we may need to use a different action in some * cases. + * + * Assumes the X11 lock is held. */ void x11GraphicsWindow:: set_wm_properties(const WindowProperties &properties, bool already_mapped) { From 16daf08e42fba21a3e919a0733db76228fd963a5 Mon Sep 17 00:00:00 2001 From: rdb Date: Wed, 11 Jul 2018 13:33:50 +0200 Subject: [PATCH 035/125] glgsg: fix some GCC warning messages --- panda/src/glstuff/glGraphicsStateGuardian_src.cxx | 6 ++++++ panda/src/glstuff/glShaderContext_src.cxx | 4 ++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx index b167f1baa8..8df6b605bb 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx @@ -613,6 +613,8 @@ reset() { get_extension_func("glDebugMessageControlARB"); _supports_debug = true; #endif + } else { + _supports_debug = false; } if (_supports_debug) { @@ -12778,7 +12780,9 @@ upload_texture_image(CLP(TextureContext) *gtc, bool needs_reload, int width = tex->get_expected_mipmap_x_size(n); int height = tex->get_expected_mipmap_y_size(n); +#ifndef OPENGLES_1 int depth = tex->get_expected_mipmap_z_size(n); +#endif #ifdef DO_PSTATS _data_transferred_pcollector.add_level(view_size); @@ -12958,7 +12962,9 @@ upload_texture_image(CLP(TextureContext) *gtc, bool needs_reload, int width = tex->get_expected_mipmap_x_size(n); int height = tex->get_expected_mipmap_y_size(n); +#ifndef OPENGLES_1 int depth = tex->get_expected_mipmap_z_size(n); +#endif #ifdef DO_PSTATS _data_transferred_pcollector.add_level(view_size); diff --git a/panda/src/glstuff/glShaderContext_src.cxx b/panda/src/glstuff/glShaderContext_src.cxx index ac9b28e784..94adf2f6a8 100644 --- a/panda/src/glstuff/glShaderContext_src.cxx +++ b/panda/src/glstuff/glShaderContext_src.cxx @@ -2612,8 +2612,8 @@ update_shader_texture_bindings(ShaderContext *prev) { } size_t num_textures = _shader->_tex_spec.size(); - GLuint *textures; - GLuint *samplers; + GLuint *textures = nullptr; + GLuint *samplers = nullptr; #ifdef OPENGLES static const bool multi_bind = false; #else From 828233a8f2e8423c5b0c9ee177a329abb671b82f Mon Sep 17 00:00:00 2001 From: rdb Date: Thu, 12 Jul 2018 11:39:57 +0200 Subject: [PATCH 036/125] glgsg: support gl-depth-zero-to-one to get same NDC Z range as D3D --- panda/src/glstuff/glGraphicsBuffer_src.cxx | 12 +++- .../glstuff/glGraphicsStateGuardian_src.cxx | 65 ++++++++++++++++++- .../src/glstuff/glGraphicsStateGuardian_src.h | 6 ++ panda/src/glstuff/glmisc_src.cxx | 7 ++ 4 files changed, 87 insertions(+), 3 deletions(-) diff --git a/panda/src/glstuff/glGraphicsBuffer_src.cxx b/panda/src/glstuff/glGraphicsBuffer_src.cxx index f46c8288f1..50491df38d 100644 --- a/panda/src/glstuff/glGraphicsBuffer_src.cxx +++ b/panda/src/glstuff/glGraphicsBuffer_src.cxx @@ -864,14 +864,22 @@ bind_slot(int layer, bool rb_resize, Texture **attach, RenderTexturePlane slot, case RTP_depth_stencil: if (_fb_properties.get_depth_bits() > 24 || _fb_properties.get_float_depth()) { - gl_format = GL_DEPTH32F_STENCIL8; + if (!glgsg->_use_remapped_depth_range) { + gl_format = GL_DEPTH32F_STENCIL8; + } else { + gl_format = GL_DEPTH32F_STENCIL8_NV; + } } else { gl_format = GL_DEPTH24_STENCIL8; } break; case RTP_depth: if (_fb_properties.get_float_depth()) { - gl_format = GL_DEPTH_COMPONENT32F; + if (!glgsg->_use_remapped_depth_range) { + gl_format = GL_DEPTH_COMPONENT32F; + } else { + gl_format = GL_DEPTH_COMPONENT32F_NV; + } } else if (_fb_properties.get_depth_bits() > 24) { gl_format = GL_DEPTH_COMPONENT32; } else if (_fb_properties.get_depth_bits() > 16) { diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx index 8df6b605bb..74080f274f 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx @@ -2997,6 +2997,50 @@ reset() { } #endif + // Set depth range from zero to one if requested. +#ifndef OPENGLES + _use_depth_zero_to_one = false; + _use_remapped_depth_range = false; + + if (gl_depth_zero_to_one) { + if (is_at_least_gl_version(4, 5) || has_extension("GL_ARB_clip_control")) { + PFNGLCLIPCONTROLPROC pglClipControl = + (PFNGLCLIPCONTROLPROC)get_extension_func("glClipControl"); + + if (pglClipControl != nullptr) { + pglClipControl(GL_LOWER_LEFT, GL_ZERO_TO_ONE); + _use_depth_zero_to_one = true; + + if (GLCAT.is_debug()) { + GLCAT.debug() + << "Set zero-to-one depth using glClipControl\n"; + } + } + }/* else if (has_extension("GL_NV_depth_buffer_float")) { + // Alternatively, all GeForce 8+ and even some AMD drivers support this + // extension, which (unlike the core glDepthRange, which clamps its + // input parameters) can compensate for the built-in depth remapping. + _glDepthRangedNV = (PFNGLDEPTHRANGEDNVPROC)get_extension_func("glDepthRangedNV"); + + if (_glDepthRangedNV != nullptr) { + _glDepthRangedNV(-1.0, 1.0); + _use_depth_zero_to_one = true; + _use_remapped_depth_range = true; + + if (GLCAT.is_debug()) { + GLCAT.debug() + << "Set zero-to-one depth using glDepthRangedNV\n"; + } + } + }*/ + + if (!_use_depth_zero_to_one) { + GLCAT.warning() + << "Zero-to-one depth was requested, but driver does not support it.\n"; + } + } +#endif + // Set up all the enableddisabled flags to GL's known initial values: // everything off. _multisample_mode = 0; @@ -3646,6 +3690,19 @@ calc_projection_mat(const Lens *lens) { lens->get_coordinate_system()) * lens->get_projection_mat(_current_stereo_channel); +#ifndef OPENGLES + if (_use_depth_zero_to_one) { + // If we requested that the OpenGL NDC Z goes from zero to one like in + // Direct3D, we need to scale the projection matrix, which assumes -1..1. + static const LMatrix4 rescale_mat + (1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 0.5, 0, + 0, 0, 0.5, 1); + result *= rescale_mat; + } +#endif + if (_scene_setup->get_inverted()) { // If the scene is supposed to be inverted, then invert the projection // matrix. @@ -7452,7 +7509,13 @@ do_issue_depth_offset() { glDepthRangef((GLclampf)min_value, (GLclampf)max_value); #else // Mainline OpenGL uses a double-precision call. - glDepthRange((GLclampd)min_value, (GLclampd)max_value); + if (!_use_remapped_depth_range) { + glDepthRange((GLclampd)min_value, (GLclampd)max_value); + } else { + // If we have a remapped depth range, we should adjust the values to range + // from -1 to 1. We need to use an NV extension to pass unclamped values. + _glDepthRangedNV(min_value * 2.0 - 1.0, max_value * 2.0 - 1.0); + } #endif // OPENGLES report_my_gl_errors(); diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.h b/panda/src/glstuff/glGraphicsStateGuardian_src.h index c0f75a21d5..d00478a58d 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.h +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.h @@ -743,6 +743,12 @@ protected: #endif public: +#ifndef OPENGLES + bool _use_depth_zero_to_one; + bool _use_remapped_depth_range; + PFNGLDEPTHRANGEDNVPROC _glDepthRangedNV; +#endif + bool _supports_point_parameters; PFNGLPOINTPARAMETERFVPROC _glPointParameterfv; bool _supports_point_sprite; diff --git a/panda/src/glstuff/glmisc_src.cxx b/panda/src/glstuff/glmisc_src.cxx index fd2bcf7aee..08e200a4a0 100644 --- a/panda/src/glstuff/glmisc_src.cxx +++ b/panda/src/glstuff/glmisc_src.cxx @@ -313,6 +313,13 @@ ConfigVariableEnum gl_coordinate_system "creating a shader-only application, it may be easier and " "more efficient to set this to default.")); +ConfigVariableBool gl_depth_zero_to_one + ("gl-depth-zero-to-one", false, + PRC_DESC("Normally, OpenGL uses an NDC coordinate space wherein the Z " + "ranges from -1 to 1. This setting can be used to instead use a " + "range from 0 to 1, matching other graphics APIs. This setting " + "requires OpenGL 4.5, or NVIDIA GeForce 8+ hardware.")); + extern ConfigVariableBool gl_parallel_arrays; void CLP(init_classes)() { From e41eeaae23d9bb99a9560b26df8920ef784b6f8f Mon Sep 17 00:00:00 2001 From: rdb Date: Thu, 12 Jul 2018 14:17:02 +0200 Subject: [PATCH 037/125] glgsg: if 32-bit unorm depth is not available, fallback to float This prevents falling back to 24-bit depth if 32-bit depth is requested. --- panda/src/glstuff/glGraphicsBuffer_src.cxx | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/panda/src/glstuff/glGraphicsBuffer_src.cxx b/panda/src/glstuff/glGraphicsBuffer_src.cxx index 50491df38d..66a9e6d407 100644 --- a/panda/src/glstuff/glGraphicsBuffer_src.cxx +++ b/panda/src/glstuff/glGraphicsBuffer_src.cxx @@ -989,6 +989,23 @@ bind_slot(int layer, bool rb_resize, Texture **attach, RenderTexturePlane slot, GLint depth_size = 0; glgsg->_glRenderbufferStorage(GL_RENDERBUFFER_EXT, gl_format, _rb_size_x, _rb_size_y); glgsg->_glGetRenderbufferParameteriv(GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_DEPTH_SIZE_EXT, &depth_size); + +#ifndef OPENGLES + // Are we getting only 24 bits of depth when we requested 32? It may be + // because GL_DEPTH_COMPONENT32 is not a required format, while 32F is. + if (gl_format == GL_DEPTH_COMPONENT32 && depth_size < 32) { + if (!glgsg->_use_remapped_depth_range) { + gl_format = GL_DEPTH_COMPONENT32F; + } else { + gl_format = GL_DEPTH_COMPONENT32F_NV; + } + glgsg->_glRenderbufferStorage(GL_RENDERBUFFER_EXT, gl_format, _rb_size_x, _rb_size_y); + glgsg->_glGetRenderbufferParameteriv(GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_DEPTH_SIZE_EXT, &depth_size); + + _fb_properties.set_float_depth(true); + } +#endif + _fb_properties.set_depth_bits(depth_size); _rb_data_size_bytes += _rb_size_x * _rb_size_y * (depth_size / 8); From c434e08a9c3d6b463124a3d461ebfe9e00e9005e Mon Sep 17 00:00:00 2001 From: rdb Date: Thu, 12 Jul 2018 14:20:13 +0200 Subject: [PATCH 038/125] tests: add various depth buffer rendering tests --- tests/display/test_depth_buffer.py | 150 +++++++++++++++++++++++++++++ 1 file changed, 150 insertions(+) create mode 100644 tests/display/test_depth_buffer.py diff --git a/tests/display/test_depth_buffer.py b/tests/display/test_depth_buffer.py new file mode 100644 index 0000000000..02b0c11b69 --- /dev/null +++ b/tests/display/test_depth_buffer.py @@ -0,0 +1,150 @@ +from panda3d import core +import pytest + + +@pytest.fixture(scope='module', params=[32, 24, 16]) +def depth_region(request, graphics_pipe): + """Creates and returns a DisplayRegion with a depth buffer.""" + + engine = core.GraphicsEngine() + engine.set_threading_model("") + + host_fbprops = core.FrameBufferProperties() + host_fbprops.force_hardware = True + + host = engine.make_output( + graphics_pipe, + 'host', + 0, + host_fbprops, + core.WindowProperties.size(32, 32), + core.GraphicsPipe.BF_refuse_window, + ) + engine.open_windows() + + if host is None: + pytest.skip("GraphicsPipe cannot make offscreen buffers") + + fbprops = core.FrameBufferProperties() + fbprops.force_hardware = True + fbprops.depth_bits = request.param + + if fbprops.depth_bits >= 32: + fbprops.float_depth = True + + buffer = engine.make_output( + graphics_pipe, + 'buffer', + 0, + fbprops, + core.WindowProperties.size(32, 32), + core.GraphicsPipe.BF_refuse_window, + host.gsg, + host + ) + engine.open_windows() + + if buffer is None: + pytest.skip("Cannot make depth buffer") + + if buffer.get_fb_properties().depth_bits != request.param: + pytest.skip("Could not make buffer with desired bit count") + + yield buffer.make_display_region() + + if buffer is not None: + engine.remove_window(buffer) + + +def render_depth_pixel(region, distance, near, far, clear=None, write=True): + """Renders a fragment at the specified distance using the specified render + settings, and returns the resulting depth value.""" + + # Set up the scene with a blank card rendering at specified distance. + scene = core.NodePath("root") + scene.set_attrib(core.DepthTestAttrib.make(core.RenderAttrib.M_always)) + scene.set_depth_write(write) + + camera = scene.attach_new_node(core.Camera("camera")) + camera.node().get_lens(0).set_near_far(near, far) + camera.node().set_cull_bounds(core.OmniBoundingVolume()) + + if distance is not None: + cm = core.CardMaker("card") + cm.set_frame(-1, 1, -1, 1) + card = scene.attach_new_node(cm.generate()) + card.set_pos(0, distance, 0) + card.set_scale(60) + + region.active = True + region.camera = camera + + if clear is not None: + region.set_clear_depth_active(True) + region.set_clear_depth(clear) + + depth_texture = core.Texture("depth") + region.window.add_render_texture(depth_texture, + core.GraphicsOutput.RTM_copy_ram, + core.GraphicsOutput.RTP_depth) + + region.window.engine.render_frame() + region.window.clear_render_textures() + + depth_texture.write("test2.png") + + col = core.LColor() + depth_texture.peek().lookup(col, 0.5, 0.5) + return col[0] + + +def test_depth_clear(depth_region): + assert 1.0 == render_depth_pixel(depth_region, None, near=1, far=10, clear=1.0) + assert 0.0 == render_depth_pixel(depth_region, None, near=1, far=10, clear=0.0) + + +def test_depth_write(depth_region): + assert 1.0 == render_depth_pixel(depth_region, 5.0, near=1, far=10, clear=1.0, write=False) + assert 0.99 > render_depth_pixel(depth_region, 5.0, near=1, far=10, clear=1.0, write=True) + + +def test_depth_far_inf(depth_region): + inf = float("inf") + assert 0.99 > render_depth_pixel(depth_region, 100.0, near=1, far=inf, clear=1.0) + + +def test_depth_clipping(depth_region): + # Get the actual depth resulting from the clear value. + clr = render_depth_pixel(depth_region, None, near=1, far=10, clear=0.5) + + # We try rendering something at various distances to make sure that the + # resulting depth value matches our expectations. + + # Too close; read clear value. + assert clr == render_depth_pixel(depth_region, 0.999, near=1, far=10, clear=0.5) + + # Too far; read clear value. + assert clr == render_depth_pixel(depth_region, 10.01, near=1, far=10, clear=0.5) + + # Just close enough; read a value close to 0.0. + assert 0.01 > render_depth_pixel(depth_region, 1.001, near=1, far=10, clear=0.5) + + # Just far enough; read 1.0. + assert 0.99 < render_depth_pixel(depth_region, 9.999, near=1, far=10, clear=0.5) + + +def test_inverted_depth_clipping(depth_region): + # Get the actual depth resulting from the clear value. + clr = render_depth_pixel(depth_region, None, near=1, far=10, clear=0.5) + + # Too close; read clear value. + assert clr == render_depth_pixel(depth_region, 0.999, near=10, far=1, clear=0.5) + + # Too far; read clear value. + assert clr == render_depth_pixel(depth_region, 10.01, near=10, far=1, clear=0.5) + + # Just close enough; read a value close to 1.0. + assert 0.99 < render_depth_pixel(depth_region, 1.001, near=10, far=1, clear=0.5) + + # Just far enough; read a value close to 0.0. + assert 0.01 > render_depth_pixel(depth_region, 9.999, near=10, far=1, clear=0.5) From 10fe8659c656c5ce33a35897baa5c2cd12ee7f3f Mon Sep 17 00:00:00 2001 From: rdb Date: Thu, 12 Jul 2018 14:22:27 +0200 Subject: [PATCH 039/125] gobj: work around a deadlock in GeomCacheManager::flush() --- panda/src/gobj/geomCacheManager.cxx | 5 +++++ panda/src/gobj/geomMunger.h | 2 ++ 2 files changed, 7 insertions(+) diff --git a/panda/src/gobj/geomCacheManager.cxx b/panda/src/gobj/geomCacheManager.cxx index 7fef373373..4eb06a25b4 100644 --- a/panda/src/gobj/geomCacheManager.cxx +++ b/panda/src/gobj/geomCacheManager.cxx @@ -13,7 +13,9 @@ #include "geomCacheManager.h" #include "geomCacheEntry.h" +#include "geomMunger.h" #include "lightMutexHolder.h" +#include "lightReMutexHolder.h" #include "clockObject.h" GeomCacheManager *GeomCacheManager::_global_ptr = nullptr; @@ -53,6 +55,9 @@ GeomCacheManager:: */ void GeomCacheManager:: flush() { + // Prevent deadlock + LightReMutexHolder registry_holder(GeomMunger::get_registry()->_registry_lock); + LightMutexHolder holder(_lock); evict_old_entries(0, false); } diff --git a/panda/src/gobj/geomMunger.h b/panda/src/gobj/geomMunger.h index 00105108bf..e8aa67bd61 100644 --- a/panda/src/gobj/geomMunger.h +++ b/panda/src/gobj/geomMunger.h @@ -149,6 +149,8 @@ private: static PStatCollector _munge_pcollector; + friend class GeomCacheManager; + public: static TypeHandle get_class_type() { return _type_handle; From 61084a3f4e54555d741302c0f8e0d26309033e47 Mon Sep 17 00:00:00 2001 From: rdb Date: Thu, 12 Jul 2018 14:24:40 +0200 Subject: [PATCH 040/125] pgraph: work around C++11 bug in something or other (see #355) --- panda/src/pgraph/cacheStats.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/panda/src/pgraph/cacheStats.h b/panda/src/pgraph/cacheStats.h index 5658a0472f..daeeb5340d 100644 --- a/panda/src/pgraph/cacheStats.h +++ b/panda/src/pgraph/cacheStats.h @@ -24,7 +24,7 @@ */ class EXPCL_PANDA_PGRAPH CacheStats { public: - constexpr CacheStats() = default; + CacheStats() = default; void init(); void reset(double now); void write(std::ostream &out, const char *name) const; From 799f0b4f7881bc36a4a061c1cacec0beacad4e6d Mon Sep 17 00:00:00 2001 From: rdb Date: Tue, 17 Jul 2018 17:04:50 +0200 Subject: [PATCH 041/125] glgsg: work around driver bug extracting buffer texture data Some drivers would report the wrong internal format. But it's silly that we query the internal format anyway, since buffer textures have a fixed sized internal format. --- panda/src/glstuff/glGraphicsStateGuardian_src.cxx | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx index 74080f274f..90bbaecf40 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx @@ -13442,7 +13442,14 @@ do_extract_texture_data(CLP(TextureContext) *gtc) { GLint internal_format = GL_RGBA; #ifndef OPENGLES - glGetTexLevelParameteriv(page_target, 0, GL_TEXTURE_INTERNAL_FORMAT, &internal_format); + if (target != GL_TEXTURE_BUFFER) { + glGetTexLevelParameteriv(page_target, 0, GL_TEXTURE_INTERNAL_FORMAT, &internal_format); + } else { + // Some drivers give the wrong result for the above call. No problem; we + // already know the internal format of a buffer texture since glTexBuffer + // required passing the exact sized format. + internal_format = gtc->_internal_format; + } #endif // OPENGLES // Make sure we were able to query those parameters properly. From 6cd59807dd63553f149211a617b7f40627ba1028 Mon Sep 17 00:00:00 2001 From: rdb Date: Tue, 17 Jul 2018 19:38:10 +0200 Subject: [PATCH 042/125] Remove useless test_display.cxx file --- makepanda/makepanda.vcproj | 1 - panda/src/display/test_display.cxx | 18 ------------------ 2 files changed, 19 deletions(-) delete mode 100644 panda/src/display/test_display.cxx diff --git a/makepanda/makepanda.vcproj b/makepanda/makepanda.vcproj index b8bdcbf07b..23ed91cdf5 100644 --- a/makepanda/makepanda.vcproj +++ b/makepanda/makepanda.vcproj @@ -1379,7 +1379,6 @@ - diff --git a/panda/src/display/test_display.cxx b/panda/src/display/test_display.cxx deleted file mode 100644 index 6adfdaf269..0000000000 --- a/panda/src/display/test_display.cxx +++ /dev/null @@ -1,18 +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_display.cxx - * @author shochet - * @date 2000-02-02 - */ - -#include "graphicsWindow.h" - -int main() { - return 0; -} From 57578ee58fc4fa89d7b928f5246029b74c5740a3 Mon Sep 17 00:00:00 2001 From: rdb Date: Tue, 17 Jul 2018 22:20:35 +0200 Subject: [PATCH 043/125] direct: add MetaInterval underscore aliases (fixes override bug) These methods are supposed to override the underlying C methods, which do have underscore aliases, so it is important that the Python class defines these underscore aliases as well. --- direct/src/interval/MetaInterval.py | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/direct/src/interval/MetaInterval.py b/direct/src/interval/MetaInterval.py index 259d7f66a3..4f31c9839d 100644 --- a/direct/src/interval/MetaInterval.py +++ b/direct/src/interval/MetaInterval.py @@ -573,7 +573,23 @@ class MetaInterval(CMetaInterval): out = ostream CMetaInterval.timeline(self, out) - + add_sequence = addSequence + add_parallel = addParallel + add_parallel_end_together = addParallelEndTogether + add_track = addTrack + add_interval = addInterval + set_manager = setManager + get_manager = getManager + set_t = setT + resume_until = resumeUntil + clear_to_initial = clearToInitial + clear_intervals = clearIntervals + set_play_rate = setPlayRate + priv_do_event = privDoEvent + priv_post_event = privPostEvent + set_interval_start_time = setIntervalStartTime + get_interval_start_time = getIntervalStartTime + get_duration = getDuration class Sequence(MetaInterval): From 684a58e7e91394213d9649bb0dcef638163b33ca Mon Sep 17 00:00:00 2001 From: rdb Date: Tue, 17 Jul 2018 22:21:44 +0200 Subject: [PATCH 044/125] parser-inc: add timespec --- dtool/src/parser-inc/time.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/dtool/src/parser-inc/time.h b/dtool/src/parser-inc/time.h index 74093ee881..23e49129d2 100644 --- a/dtool/src/parser-inc/time.h +++ b/dtool/src/parser-inc/time.h @@ -1 +1,8 @@ +#pragma once + #include + +struct timespec { + time_t tv_sec; + long tv_nsec; +}; From 71b4b807f8173b683b76936c0f7d7fe8bbd2b556 Mon Sep 17 00:00:00 2001 From: rdb Date: Tue, 17 Jul 2018 22:24:35 +0200 Subject: [PATCH 045/125] collide: add line-into-box test, improve segment/ray into box --- panda/src/collide/collisionBox.cxx | 239 ++++++++++++++++------------- panda/src/collide/collisionBox.h | 7 + 2 files changed, 141 insertions(+), 105 deletions(-) diff --git a/panda/src/collide/collisionBox.cxx b/panda/src/collide/collisionBox.cxx index 46666722e2..494013c75b 100644 --- a/panda/src/collide/collisionBox.cxx +++ b/panda/src/collide/collisionBox.cxx @@ -398,6 +398,49 @@ test_intersection_from_sphere(const CollisionEntry &entry) const { return new_entry; } +/** + * + */ +PT(CollisionEntry) CollisionBox:: +test_intersection_from_line(const CollisionEntry &entry) const { + const CollisionLine *line; + DCAST_INTO_R(line, entry.get_from(), nullptr); + + const LMatrix4 &wrt_mat = entry.get_wrt_mat(); + + LPoint3 from_origin = line->get_origin() * wrt_mat; + LVector3 from_direction = line->get_direction() * wrt_mat; + + double t1, t2; + if (!intersects_line(t1, t2, from_origin, from_direction)) { + // No intersection. + return nullptr; + } + + if (collide_cat.is_debug()) { + collide_cat.debug() + << "intersection detected from " << entry.get_from_node_path() + << " into " << entry.get_into_node_path() << "\n"; + } + PT(CollisionEntry) new_entry = new CollisionEntry(entry); + + LPoint3 point = from_origin + t1 * from_direction; + new_entry->set_surface_point(point); + + if (has_effective_normal() && line->get_respect_effective_normal()) { + new_entry->set_surface_normal(get_effective_normal()); + } else { + LVector3 normal( + IS_NEARLY_EQUAL(point[0], _max[0]) - IS_NEARLY_EQUAL(point[0], _min[0]), + IS_NEARLY_EQUAL(point[1], _max[1]) - IS_NEARLY_EQUAL(point[1], _min[1]), + IS_NEARLY_EQUAL(point[2], _max[2]) - IS_NEARLY_EQUAL(point[2], _min[2]) + ); + normal.normalize(); + new_entry->set_surface_normal(normal); + } + + return new_entry; +} /** * Double dispatch point for ray as a FROM object @@ -411,51 +454,9 @@ test_intersection_from_ray(const CollisionEntry &entry) const { LPoint3 from_origin = ray->get_origin() * wrt_mat; LVector3 from_direction = ray->get_direction() * wrt_mat; - int i, j; - PN_stdfloat t; - PN_stdfloat near_t = 0.0; - bool intersect; - LPlane plane; - LPlane near_plane; - - // Returns the details about the first plane of the box that the ray - // intersects. - for (i = 0, intersect = false, t = 0, j = 0; i < 6 && j < 2; i++) { - plane = get_plane(i); - - if (!plane.intersects_line(t, from_origin, from_direction)) { - // No intersection. The ray is parallel to the plane. - continue; - } - - if (t < 0.0f) { - // The intersection point is before the start of the ray, and so the ray - // is entirely in front of the plane. - continue; - } - LPoint3 plane_point = from_origin + t * from_direction; - LPoint2 p = to_2d(plane_point, i); - - if (!point_is_inside(p, _points[i])){ - continue; - } - intersect = true; - if (j) { - if(t < near_t) { - near_plane = plane; - near_t = t; - } - } - else { - near_plane = plane; - near_t = t; - } - ++j; - } - - - if(!intersect) { - // No intersection with ANY of the box's planes has been detected + double t1, t2; + if (!intersects_line(t1, t2, from_origin, from_direction) || (t1 < 0.0 && t2 < 0.0)) { + // No intersection. return nullptr; } @@ -464,22 +465,32 @@ test_intersection_from_ray(const CollisionEntry &entry) const { << "intersection detected from " << entry.get_from_node_path() << " into " << entry.get_into_node_path() << "\n"; } - PT(CollisionEntry) new_entry = new CollisionEntry(entry); - LPoint3 into_intersection_point = from_origin + near_t * from_direction; + if (t1 < 0.0) { + // The origin is inside the box, so we take the exit as our surface point. + new_entry->set_interior_point(from_origin); + t1 = t2; + } - LVector3 normal = - (has_effective_normal() && ray->get_respect_effective_normal()) - ? get_effective_normal() : near_plane.get_normal(); + LPoint3 point = from_origin + t1 * from_direction; + new_entry->set_surface_point(point); - new_entry->set_surface_normal(normal); - new_entry->set_surface_point(into_intersection_point); + if (has_effective_normal() && ray->get_respect_effective_normal()) { + new_entry->set_surface_normal(get_effective_normal()); + } else { + LVector3 normal( + IS_NEARLY_EQUAL(point[0], _max[0]) - IS_NEARLY_EQUAL(point[0], _min[0]), + IS_NEARLY_EQUAL(point[1], _max[1]) - IS_NEARLY_EQUAL(point[1], _min[1]), + IS_NEARLY_EQUAL(point[2], _max[2]) - IS_NEARLY_EQUAL(point[2], _min[2]) + ); + normal.normalize(); + new_entry->set_surface_normal(normal); + } return new_entry; } - /** * Double dispatch point for segment as a FROM object */ @@ -493,51 +504,10 @@ test_intersection_from_segment(const CollisionEntry &entry) const { LPoint3 from_extent = seg->get_point_b() * wrt_mat; LVector3 from_direction = from_extent - from_origin; - int i, j; - PN_stdfloat t; - PN_stdfloat near_t = 0.0; - bool intersect; - LPlane plane; - LPlane near_plane; - - // Returns the details about the first plane of the box that the segment - // intersects. - for(i = 0, intersect = false, t = 0, j = 0; i < 6 && j < 2; i++) { - plane = get_plane(i); - - if (!plane.intersects_line(t, from_origin, from_direction)) { - // No intersection. The segment is parallel to the plane. - continue; - } - - if (t < 0.0f || t > 1.0f) { - // The intersection point is before the start of the segment, or after - // the end of the segment, so the segment is either entirely in front of - // or behind the plane. - continue; - } - LPoint3 plane_point = from_origin + t * from_direction; - LPoint2 p = to_2d(plane_point, i); - - if (!point_is_inside(p, _points[i])){ - continue; - } - intersect = true; - if(j) { - if(t < near_t) { - near_plane = plane; - near_t = t; - } - } - else { - near_plane = plane; - near_t = t; - } - ++j; - } - - if(!intersect) { - // No intersection with ANY of the box's planes has been detected + double t1, t2; + if (!intersects_line(t1, t2, from_origin, from_direction) || + (t1 < 0.0 && t2 < 0.0) || (t1 > 1.0 && t2 > 1.0)) { + // No intersection. return nullptr; } @@ -546,17 +516,31 @@ test_intersection_from_segment(const CollisionEntry &entry) const { << "intersection detected from " << entry.get_from_node_path() << " into " << entry.get_into_node_path() << "\n"; } - PT(CollisionEntry) new_entry = new CollisionEntry(entry); - LPoint3 into_intersection_point = from_origin + near_t * from_direction; + // In case the segment is entirely inside the cube, we consider the point + // closest to the surface as our entry point. + if (t1 < (1.0 - t2)) { + std::swap(t1, t2); + } - LVector3 normal = - (has_effective_normal() && seg->get_respect_effective_normal()) - ? get_effective_normal() : near_plane.get_normal(); + // Our interior point is the closest point to t2 that is inside the segment. + new_entry->set_interior_point(from_origin + std::min(std::max(t2, 0.0), 1.0) * from_direction); - new_entry->set_surface_normal(normal); - new_entry->set_surface_point(into_intersection_point); + LPoint3 point = from_origin + t1 * from_direction; + new_entry->set_surface_point(point); + + if (has_effective_normal() && seg->get_respect_effective_normal()) { + new_entry->set_surface_normal(get_effective_normal()); + } else { + LVector3 normal( + IS_NEARLY_EQUAL(point[0], _max[0]) - IS_NEARLY_EQUAL(point[0], _min[0]), + IS_NEARLY_EQUAL(point[1], _max[1]) - IS_NEARLY_EQUAL(point[1], _min[1]), + IS_NEARLY_EQUAL(point[2], _max[2]) - IS_NEARLY_EQUAL(point[2], _min[2]) + ); + normal.normalize(); + new_entry->set_surface_normal(normal); + } return new_entry; } @@ -823,6 +807,51 @@ fill_viz_geom() { _bounds_viz_geom->add_geom(geom, get_solid_bounds_viz_state()); } +/** + * Determine the point(s) of intersection of a parametric line with the box. + * The line is infinite in both directions, and passes through "from" and + * from+delta. If the line does not intersect the box, the function returns + * false, and t1 and t2 are undefined. If it does intersect the box, it + * returns true, and t1 and t2 are set to the points along the equation + * from+t*delta that correspond to the two points of intersection. + */ +bool CollisionBox:: +intersects_line(double &t1, double &t2, + const LPoint3 &from, const LVector3 &delta, + PN_stdfloat inflate_size) const { + + LPoint3 bmin = _min - LVector3(inflate_size); + LPoint3 bmax = _max + LVector3(inflate_size); + + double tmin = -DBL_MAX; + double tmax = DBL_MAX; + + for (int i = 0; i < 3; ++i) { + PN_stdfloat d = delta[i]; + if (!IS_NEARLY_ZERO(d)) { + double tmin2 = (bmin[i] - from[i]) / d; + double tmax2 = (bmax[i] - from[i]) / d; + if (tmin2 > tmax2) { + std::swap(tmin2, tmax2); + } + tmin = std::max(tmin, tmin2); + tmax = std::min(tmax, tmax2); + + if (tmin > tmax) { + return false; + } + + } else if (from[i] < bmin[i] || from[i] > bmax[i]) { + // The line is entirely parallel in this dimension. + return false; + } + } + + t1 = tmin; + t2 = tmax; + return true; +} + /** * Clips the polygon by all of the clip planes named in the clip plane * attribute and fills new_points up with the resulting points. diff --git a/panda/src/collide/collisionBox.h b/panda/src/collide/collisionBox.h index 0888d7e4da..0810aa95e2 100644 --- a/panda/src/collide/collisionBox.h +++ b/panda/src/collide/collisionBox.h @@ -75,6 +75,8 @@ protected: virtual PT(BoundingVolume) compute_internal_bounds() const; virtual PT(CollisionEntry) test_intersection_from_sphere(const CollisionEntry &entry) const; + virtual PT(CollisionEntry) + test_intersection_from_line(const CollisionEntry &entry) const; virtual PT(CollisionEntry) test_intersection_from_ray(const CollisionEntry &entry) const; virtual PT(CollisionEntry) @@ -84,6 +86,11 @@ protected: virtual void fill_viz_geom(); +protected: + bool intersects_line(double &t1, double &t2, + const LPoint3 &from, const LVector3 &delta, + PN_stdfloat inflate_size=0) const; + private: LPoint3 _center; LPoint3 _min; From 911a54938625dc22278f6eced827e0ff484b5f05 Mon Sep 17 00:00:00 2001 From: rdb Date: Tue, 17 Jul 2018 22:30:06 +0200 Subject: [PATCH 046/125] collide: add tube-into-tube collision test --- panda/src/collide/collisionTube.cxx | 152 ++++++++++++++++++++++++++-- panda/src/collide/collisionTube.h | 11 +- 2 files changed, 152 insertions(+), 11 deletions(-) diff --git a/panda/src/collide/collisionTube.cxx b/panda/src/collide/collisionTube.cxx index 174935368e..90f82a3630 100644 --- a/panda/src/collide/collisionTube.cxx +++ b/panda/src/collide/collisionTube.cxx @@ -391,6 +391,70 @@ test_intersection_from_segment(const CollisionEntry &entry) const { return new_entry; } +/** + * + */ +PT(CollisionEntry) CollisionTube:: +test_intersection_from_tube(const CollisionEntry &entry) const { + const CollisionTube *tube; + DCAST_INTO_R(tube, entry.get_from(), nullptr); + + LPoint3 into_a = _a; + LVector3 into_direction = _b - into_a; + + const LMatrix4 &wrt_mat = entry.get_wrt_mat(); + + LPoint3 from_a = tube->get_point_a() * wrt_mat; + LPoint3 from_b = tube->get_point_b() * wrt_mat; + LVector3 from_direction = from_b - from_a; + + LVector3 from_radius_v = + LVector3(tube->get_radius(), 0.0f, 0.0f) * wrt_mat; + PN_stdfloat from_radius = length(from_radius_v); + + // Determine the points on each segment with the smallest distance between. + double into_t, from_t; + calc_closest_segment_points(into_t, from_t, + into_a, into_direction, + from_a, from_direction); + LPoint3 into_closest = into_a + into_direction * into_t; + LPoint3 from_closest = from_a + from_direction * from_t; + + // If the distance is greater than the sum of tube radii, the test fails. + LVector3 closest_vec = from_closest - into_closest; + PN_stdfloat distance = closest_vec.length(); + if (distance > _radius + from_radius) { + return nullptr; + } + + if (collide_cat.is_debug()) { + collide_cat.debug() + << "intersection detected from " << entry.get_from_node_path() + << " into " << entry.get_into_node_path() << "\n"; + } + PT(CollisionEntry) new_entry = new CollisionEntry(entry); + + if (distance != 0) { + // This is the most common case, where the line segments don't touch + // exactly. We point the normal along the vector of the closest distance. + LVector3 surface_normal = closest_vec * (1.0 / distance); + + new_entry->set_surface_point(into_closest + surface_normal * _radius); + new_entry->set_interior_point(from_closest - surface_normal * from_radius); + + if (has_effective_normal() && tube->get_respect_effective_normal()) { + new_entry->set_surface_normal(get_effective_normal()); + } else if (distance != 0) { + new_entry->set_surface_normal(surface_normal); + } + } else { + // The rare case of the line segments touching exactly. + set_intersection_point(new_entry, into_closest, 0); + } + + return new_entry; +} + /** * */ @@ -578,6 +642,80 @@ calc_sphere2_vertex(int ri, int si, int num_rings, int num_slices, return LVertex(x, y, z); } +/** + * Given line segments s1 and s2 defined by two points each, computes the + * point on each segment with the closest distance between them. + */ +void CollisionTube:: +calc_closest_segment_points(double &t1, double &t2, + const LPoint3 &from1, const LVector3 &delta1, + const LPoint3 &from2, const LVector3 &delta2) { + // Copyright 2001 softSurfer, 2012 Dan Sunday + // This code may be freely used, distributed and modified for any purpose + // providing that this copyright notice is included with it. + // SoftSurfer makes no warranty for this code, and cannot be held + // liable for any real or imagined damage resulting from its use. + // Users of this code must verify correctness for their application. + LVector3 w = from1 - from2; + PN_stdfloat a = delta1.dot(delta1); // always >= 0 + PN_stdfloat b = delta1.dot(delta2); + PN_stdfloat c = delta2.dot(delta2); // always >= 0 + PN_stdfloat d = delta1.dot(w); + PN_stdfloat e = delta2.dot(w); + PN_stdfloat D = a * c - b * b; // always >= 0 + PN_stdfloat sN, sD = D; + PN_stdfloat tN, tD = D; + + // compute the line parameters of the two closest points + if (IS_NEARLY_ZERO(D)) { // the lines are almost parallel + sN = 0.0; // force using point P0 on segment S1 + sD = 1.0; // to prevent possible division by 0.0 later + tN = e; + tD = c; + } else { + // get the closest points on the infinite lines + sN = (b*e - c*d); + tN = (a*e - b*d); + if (sN < 0.0) { // sc < 0 => the s=0 edge is visible + sN = 0.0; + tN = e; + tD = c; + } else if (sN > sD) { // sc > 1 => the s=1 edge is visible + sN = sD; + tN = e + b; + tD = c; + } + } + + if (tN < 0.0) { // tc < 0 => the t=0 edge is visible + tN = 0.0; + // recompute sc for this edge + if (-d < 0.0) { + sN = 0.0; + } else if (-d > a) { + sN = sD; + } else { + sN = -d; + sD = a; + } + } else if (tN > tD) { // tc > 1 => the t=1 edge is visible + tN = tD; + // recompute sc for this edge + if ((-d + b) < 0.0) { + sN = 0; + } else if ((-d + b) > a) { + sN = sD; + } else { + sN = (-d + b); + sD = a; + } + } + + // finally do the division to get sc and tc + t1 = (IS_NEARLY_ZERO(sN) ? 0.0 : sN / sD); + t2 = (IS_NEARLY_ZERO(tN) ? 0.0 : tN / tD); +} + /** * Determine the point(s) of intersection of a parametric line with the tube. * The line is infinite in both directions, and passes through "from" and @@ -692,7 +830,7 @@ intersects_line(double &t1, double &t2, // The starting point is off the bottom of the tube. Test the line // against the first endcap. double t1a, t2a; - if (!sphere_intersects_line(t1a, t2a, 0.0f, from, delta, inflate_radius)) { + if (!sphere_intersects_line(t1a, t2a, 0.0f, from, delta, radius)) { // If there's no intersection with the endcap, there can't be an // intersection with the cylinder. return false; @@ -703,7 +841,7 @@ intersects_line(double &t1, double &t2, // The starting point is off the top of the tube. Test the line against // the second endcap. double t1b, t2b; - if (!sphere_intersects_line(t1b, t2b, _length, from, delta, inflate_radius)) { + if (!sphere_intersects_line(t1b, t2b, _length, from, delta, radius)) { // If there's no intersection with the endcap, there can't be an // intersection with the cylinder. return false; @@ -715,7 +853,7 @@ intersects_line(double &t1, double &t2, // The ending point is off the bottom of the tube. Test the line against // the first endcap. double t1a, t2a; - if (!sphere_intersects_line(t1a, t2a, 0.0f, from, delta, inflate_radius)) { + if (!sphere_intersects_line(t1a, t2a, 0.0f, from, delta, radius)) { // If there's no intersection with the endcap, there can't be an // intersection with the cylinder. return false; @@ -726,7 +864,7 @@ intersects_line(double &t1, double &t2, // The ending point is off the top of the tube. Test the line against the // second endcap. double t1b, t2b; - if (!sphere_intersects_line(t1b, t2b, _length, from, delta, inflate_radius)) { + if (!sphere_intersects_line(t1b, t2b, _length, from, delta, radius)) { // If there's no intersection with the endcap, there can't be an // intersection with the cylinder. return false; @@ -740,16 +878,14 @@ intersects_line(double &t1, double &t2, /** * After confirming that the line intersects an infinite cylinder, test * whether it intersects one or the other endcaps. The y parameter specifies - * the center of the sphere (and hence the particular endcap. + * the center of the sphere (and hence the particular endcap). */ bool CollisionTube:: sphere_intersects_line(double &t1, double &t2, PN_stdfloat center_y, const LPoint3 &from, const LVector3 &delta, - PN_stdfloat inflate_radius) const { + PN_stdfloat radius) { // See CollisionSphere::intersects_line() for a derivation of the formula // here. - PN_stdfloat radius = _radius + inflate_radius; - double A = dot(delta, delta); nassertr(A != 0.0, false); diff --git a/panda/src/collide/collisionTube.h b/panda/src/collide/collisionTube.h index 1742e24927..70f1832b9b 100644 --- a/panda/src/collide/collisionTube.h +++ b/panda/src/collide/collisionTube.h @@ -82,6 +82,8 @@ protected: virtual PT(CollisionEntry) test_intersection_from_segment(const CollisionEntry &entry) const; virtual PT(CollisionEntry) + test_intersection_from_tube(const CollisionEntry &entry) const; + virtual PT(CollisionEntry) test_intersection_from_parabola(const CollisionEntry &entry) const; virtual void fill_viz_geom(); @@ -93,12 +95,15 @@ private: LVertex calc_sphere2_vertex(int ri, int si, int num_rings, int num_slices, PN_stdfloat length); + static void calc_closest_segment_points(double &t1, double &t2, + const LPoint3 &from1, const LVector3 &delta1, + const LPoint3 &from2, const LVector3 &delta2); bool intersects_line(double &t1, double &t2, const LPoint3 &from, const LVector3 &delta, PN_stdfloat inflate_radius) const; - bool sphere_intersects_line(double &t1, double &t2, PN_stdfloat center_y, - const LPoint3 &from, const LVector3 &delta, - PN_stdfloat inflate_radius) const; + static bool sphere_intersects_line(double &t1, double &t2, PN_stdfloat center_y, + const LPoint3 &from, const LVector3 &delta, + PN_stdfloat radius); bool intersects_parabola(double &t, const LParabola ¶bola, double t1, double t2, const LPoint3 &p1, const LPoint3 &p2) const; From 06539f5c667616a69758add4c4c58ec8bc515a44 Mon Sep 17 00:00:00 2001 From: rdb Date: Tue, 17 Jul 2018 22:32:34 +0200 Subject: [PATCH 047/125] glsl: support passing uint variables to shader --- panda/src/glstuff/glCgShaderContext_src.cxx | 1 + .../glstuff/glGraphicsStateGuardian_src.cxx | 12 ++++ .../src/glstuff/glGraphicsStateGuardian_src.h | 8 +++ panda/src/glstuff/glShaderContext_src.cxx | 61 ++++++++++++++++++- panda/src/gobj/shader.h | 1 + tests/display/test_glsl_shader.py | 5 +- 6 files changed, 83 insertions(+), 5 deletions(-) diff --git a/panda/src/glstuff/glCgShaderContext_src.cxx b/panda/src/glstuff/glCgShaderContext_src.cxx index c7ba6ad3e7..fc1dac82ca 100644 --- a/panda/src/glstuff/glCgShaderContext_src.cxx +++ b/panda/src/glstuff/glCgShaderContext_src.cxx @@ -648,6 +648,7 @@ issue_parameters(int altered) { continue; case Shader::SPT_int: + case Shader::SPT_uint: switch (spec._info._class) { case Shader::SAC_scalar: cgSetParameter1iv(p, (int*)ptr_data->_ptr); diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx index 90bbaecf40..7ca4bd21e8 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx @@ -1699,6 +1699,14 @@ reset() { get_extension_func("glUniform3iv"); _glUniform4iv = (PFNGLUNIFORM4IVPROC) get_extension_func("glUniform4iv"); + _glUniform1uiv = (PFNGLUNIFORM1UIVPROC) + get_extension_func("glUniform1uiv"); + _glUniform2uiv = (PFNGLUNIFORM2UIVPROC) + get_extension_func("glUniform2uiv"); + _glUniform3uiv = (PFNGLUNIFORM3UIVPROC) + get_extension_func("glUniform3uiv"); + _glUniform4uiv = (PFNGLUNIFORM4UIVPROC) + get_extension_func("glUniform4uiv"); _glUniformMatrix3fv = (PFNGLUNIFORMMATRIX3FVPROC) get_extension_func("glUniformMatrix3fv"); _glUniformMatrix4fv = (PFNGLUNIFORMMATRIX4FVPROC) @@ -1777,6 +1785,10 @@ reset() { _glUniform2fv = glUniform2fv; _glUniform3fv = glUniform3fv; _glUniform4fv = glUniform4fv; + _glUniform1iv = glUniform1iv; + _glUniform2iv = glUniform2iv; + _glUniform3iv = glUniform3iv; + _glUniform4iv = glUniform4iv; _glUniformMatrix3fv = glUniformMatrix3fv; _glUniformMatrix4fv = glUniformMatrix4fv; _glValidateProgram = glValidateProgram; diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.h b/panda/src/glstuff/glGraphicsStateGuardian_src.h index d00478a58d..67de9ac54c 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.h +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.h @@ -175,6 +175,10 @@ typedef void (APIENTRYP PFNGLUNIFORM1IVPROC) (GLint location, GLsizei count, con typedef void (APIENTRYP PFNGLUNIFORM2IVPROC) (GLint location, GLsizei count, const GLint *value); typedef void (APIENTRYP PFNGLUNIFORM3IVPROC) (GLint location, GLsizei count, const GLint *value); typedef void (APIENTRYP PFNGLUNIFORM4IVPROC) (GLint location, GLsizei count, const GLint *value); +typedef void (APIENTRYP PFNGLUNIFORM1UIVPROC) (GLint location, GLsizei count, const GLuint *value); +typedef void (APIENTRYP PFNGLUNIFORM2UIVPROC) (GLint location, GLsizei count, const GLuint *value); +typedef void (APIENTRYP PFNGLUNIFORM3UIVPROC) (GLint location, GLsizei count, const GLuint *value); +typedef void (APIENTRYP PFNGLUNIFORM4UIVPROC) (GLint location, GLsizei count, const GLuint *value); typedef void (APIENTRYP PFNGLUNIFORMMATRIX3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); typedef void (APIENTRYP PFNGLUNIFORMMATRIX4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); typedef void (APIENTRYP PFNGLVALIDATEPROGRAMPROC) (GLuint program); @@ -984,6 +988,10 @@ public: PFNGLUNIFORM2IVPROC _glUniform2iv; PFNGLUNIFORM3IVPROC _glUniform3iv; PFNGLUNIFORM4IVPROC _glUniform4iv; + PFNGLUNIFORM1UIVPROC _glUniform1uiv; + PFNGLUNIFORM2UIVPROC _glUniform2uiv; + PFNGLUNIFORM3UIVPROC _glUniform3uiv; + PFNGLUNIFORM4UIVPROC _glUniform4uiv; PFNGLUNIFORMMATRIX3FVPROC _glUniformMatrix3fv; PFNGLUNIFORMMATRIX4FVPROC _glUniformMatrix4fv; PFNGLVALIDATEPROGRAMPROC _glValidateProgram; diff --git a/panda/src/glstuff/glShaderContext_src.cxx b/panda/src/glstuff/glShaderContext_src.cxx index 94adf2f6a8..979c6dada1 100644 --- a/panda/src/glstuff/glShaderContext_src.cxx +++ b/panda/src/glstuff/glShaderContext_src.cxx @@ -1501,21 +1501,29 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) { case GL_INT: case GL_INT_VEC2: case GL_INT_VEC3: - case GL_INT_VEC4: { + case GL_INT_VEC4: + case GL_UNSIGNED_INT: + case GL_UNSIGNED_INT_VEC2: + case GL_UNSIGNED_INT_VEC3: + case GL_UNSIGNED_INT_VEC4: { Shader::ShaderPtrSpec bind; bind._id = arg_id; switch (param_type) { case GL_BOOL: case GL_INT: + case GL_UNSIGNED_INT: case GL_FLOAT: bind._dim[1] = 1; break; case GL_BOOL_VEC2: case GL_INT_VEC2: + case GL_UNSIGNED_INT_VEC2: case GL_FLOAT_VEC2: bind._dim[1] = 2; break; case GL_BOOL_VEC3: case GL_INT_VEC3: + case GL_UNSIGNED_INT_VEC3: case GL_FLOAT_VEC3: bind._dim[1] = 3; break; case GL_BOOL_VEC4: case GL_INT_VEC4: + case GL_UNSIGNED_INT_VEC4: case GL_FLOAT_VEC4: bind._dim[1] = 4; break; case GL_FLOAT_MAT3: bind._dim[1] = 9; break; case GL_FLOAT_MAT4: bind._dim[1] = 16; break; @@ -1525,6 +1533,12 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) { case GL_BOOL_VEC2: case GL_BOOL_VEC3: case GL_BOOL_VEC4: + case GL_UNSIGNED_INT: + case GL_UNSIGNED_INT_VEC2: + case GL_UNSIGNED_INT_VEC3: + case GL_UNSIGNED_INT_VEC4: + bind._type = Shader::SPT_uint; + break; case GL_INT: case GL_INT_VEC2: case GL_INT_VEC3: @@ -1604,6 +1618,10 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) { case GL_INT_VEC2: case GL_INT_VEC3: case GL_INT_VEC4: + case GL_UNSIGNED_INT: + case GL_UNSIGNED_INT_VEC2: + case GL_UNSIGNED_INT_VEC3: + case GL_UNSIGNED_INT_VEC4: case GL_FLOAT: case GL_FLOAT_VEC2: case GL_FLOAT_VEC3: @@ -1633,6 +1651,12 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) { case GL_BOOL_VEC2: case GL_BOOL_VEC3: case GL_BOOL_VEC4: + case GL_UNSIGNED_INT: + case GL_UNSIGNED_INT_VEC2: + case GL_UNSIGNED_INT_VEC3: + case GL_UNSIGNED_INT_VEC4: + bind._type = Shader::SPT_uint; + break; case GL_INT: case GL_INT_VEC2: case GL_INT_VEC3: @@ -2003,6 +2027,8 @@ issue_parameters(int altered) { return; } + nassertd(spec._dim[1] > 0) continue; + GLint p = spec._id._seqno; int array_size = min(spec._dim[0], (int)ptr_data->_size / spec._dim[1]); switch (spec._type) { @@ -2019,6 +2045,14 @@ issue_parameters(int altered) { } break; + case Shader::SPT_uint: + // Convert unsigned int data to float data. + data = (float*) alloca(sizeof(float) * array_size * spec._dim[1]); + for (int i = 0; i < (array_size * spec._dim[1]); ++i) { + data[i] = (float)(((unsigned int*)ptr_data->_ptr)[i]); + } + break; + case Shader::SPT_double: // Downgrade double data to float data. data = (float*) alloca(sizeof(float) * array_size * spec._dim[1]); @@ -2048,7 +2082,8 @@ issue_parameters(int altered) { break; case Shader::SPT_int: - if (ptr_data->_type != Shader::SPT_int) { + if (ptr_data->_type != Shader::SPT_int && + ptr_data->_type != Shader::SPT_uint) { GLCAT.error() << "Cannot pass floating-point data to integer shader input '" << spec._id._name << "'\n"; @@ -2068,6 +2103,28 @@ issue_parameters(int altered) { } break; + case Shader::SPT_uint: + if (ptr_data->_type != Shader::SPT_uint && + ptr_data->_type != Shader::SPT_int) { + GLCAT.error() + << "Cannot pass floating-point data to integer shader input '" << spec._id._name << "'\n"; + + // Deactivate it to make sure the user doesn't get flooded with this + // error. + spec._dep[0] = 0; + spec._dep[1] = 0; + + } else { + switch (spec._dim[1]) { + case 1: _glgsg->_glUniform1uiv(p, array_size, (GLuint *)ptr_data->_ptr); continue; + case 2: _glgsg->_glUniform2uiv(p, array_size, (GLuint *)ptr_data->_ptr); continue; + case 3: _glgsg->_glUniform3uiv(p, array_size, (GLuint *)ptr_data->_ptr); continue; + case 4: _glgsg->_glUniform4uiv(p, array_size, (GLuint *)ptr_data->_ptr); continue; + } + nassertd(false) continue; + } + break; + case Shader::SPT_double: GLCAT.error() << "Passing double-precision shader inputs to GLSL shaders is not currently supported\n"; diff --git a/panda/src/gobj/shader.h b/panda/src/gobj/shader.h index 8e65c005e9..1cc6533044 100644 --- a/panda/src/gobj/shader.h +++ b/panda/src/gobj/shader.h @@ -346,6 +346,7 @@ public: SPT_float, SPT_double, SPT_int, + SPT_uint, SPT_unknown }; diff --git a/tests/display/test_glsl_shader.py b/tests/display/test_glsl_shader.py index c13e99e92e..0c9c9e8e95 100644 --- a/tests/display/test_glsl_shader.py +++ b/tests/display/test_glsl_shader.py @@ -183,7 +183,6 @@ def test_glsl_int(gsg): run_glsl_test(gsg, code, preamble, inputs) -@pytest.mark.xfail def test_glsl_uint(gsg): #TODO: fix passing uints greater than intmax inputs = dict( @@ -191,8 +190,8 @@ def test_glsl_uint(gsg): intmax=0x7fffffff, ) preamble = """ - uniform unsigned int zero; - uniform unsigned int intmax; + uniform uint zero; + uniform uint intmax; """ code = """ assert(zero == 0); From b5194d9ff25033615f9282706ec7fc9266f9925a Mon Sep 17 00:00:00 2001 From: rdb Date: Tue, 17 Jul 2018 22:55:35 +0200 Subject: [PATCH 048/125] glgsg: pad SSBOs to 16 byte boundary (required by some drivers) --- panda/src/glstuff/glGraphicsStateGuardian_src.cxx | 3 ++- panda/src/gobj/shaderBuffer.I | 12 ++++++++---- panda/src/gobj/shaderBuffer.cxx | 2 +- panda/src/gobj/shaderBuffer.h | 2 +- 4 files changed, 12 insertions(+), 7 deletions(-) diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx index 7ca4bd21e8..d6fab2a434 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx @@ -6404,7 +6404,8 @@ prepare_shader_buffer(ShaderBuffer *data) { _glObjectLabel(GL_SHADER_STORAGE_BUFFER, gbc->_index, name.size(), name.data()); } - uint64_t num_bytes = data->get_data_size_bytes(); + // Some drivers require the buffer to be padded to 16 byte boundary. + uint64_t num_bytes = (data->get_data_size_bytes() + 15u) & ~15u; if (_supports_buffer_storage) { _glBufferStorage(GL_SHADER_STORAGE_BUFFER, num_bytes, data->get_initial_data(), 0); } else { diff --git a/panda/src/gobj/shaderBuffer.I b/panda/src/gobj/shaderBuffer.I index 59d62d0171..ccbd160521 100644 --- a/panda/src/gobj/shaderBuffer.I +++ b/panda/src/gobj/shaderBuffer.I @@ -19,8 +19,7 @@ INLINE ShaderBuffer:: ShaderBuffer(const std::string &name, uint64_t size, UsageHint usage_hint) : Namable(name), _data_size_bytes(size), - _usage_hint(usage_hint), - _contexts(nullptr) { + _usage_hint(usage_hint) { } /** @@ -32,8 +31,13 @@ ShaderBuffer(const std::string &name, vector_uchar initial_data, UsageHint usage Namable(name), _data_size_bytes(initial_data.size()), _usage_hint(usage_hint), - _initial_data(initial_data), - _contexts(nullptr) { + _initial_data(std::move(initial_data)) { + + // Make sure it is padded to 16 bytes. Some drivers like that. + if ((_initial_data.size() & 15u) != 0) { + _initial_data.resize((_initial_data.size() + 15u) & ~15u, 0); + _data_size_bytes = _initial_data.size(); + } } /** diff --git a/panda/src/gobj/shaderBuffer.cxx b/panda/src/gobj/shaderBuffer.cxx index 971787f0e6..4e21319b49 100644 --- a/panda/src/gobj/shaderBuffer.cxx +++ b/panda/src/gobj/shaderBuffer.cxx @@ -193,7 +193,7 @@ fillin(DatagramIterator &scan, BamReader *manager) { if (scan.get_bool() && _data_size_bytes > 0) { nassertv_always(_data_size_bytes <= scan.get_remaining_size()); - _initial_data.resize(_data_size_bytes); + _initial_data.resize((_data_size_bytes + 15u) & ~15u); scan.extract_bytes(&_initial_data[0], _data_size_bytes); } else { _initial_data.clear(); diff --git a/panda/src/gobj/shaderBuffer.h b/panda/src/gobj/shaderBuffer.h index 69bdf985d9..bdf0538857 100644 --- a/panda/src/gobj/shaderBuffer.h +++ b/panda/src/gobj/shaderBuffer.h @@ -63,7 +63,7 @@ private: vector_uchar _initial_data; typedef pmap Contexts; - Contexts *_contexts; + Contexts *_contexts = nullptr; public: static void register_with_read_factory(); From 359ce3e9efcaed82b3990f65a32620f1c48bf0e1 Mon Sep 17 00:00:00 2001 From: rdb Date: Tue, 17 Jul 2018 22:59:23 +0200 Subject: [PATCH 049/125] glgsg: fix error with glObjectLabel and SSBO --- panda/src/glstuff/glGraphicsStateGuardian_src.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx index d6fab2a434..7e8a08aacd 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx @@ -6401,7 +6401,7 @@ prepare_shader_buffer(ShaderBuffer *data) { if (_use_object_labels) { string name = data->get_name(); - _glObjectLabel(GL_SHADER_STORAGE_BUFFER, gbc->_index, name.size(), name.data()); + _glObjectLabel(GL_BUFFER, gbc->_index, name.size(), name.data()); } // Some drivers require the buffer to be padded to 16 byte boundary. From eafab53729442671e8cb234526992b52f5bf91e8 Mon Sep 17 00:00:00 2001 From: rdb Date: Tue, 17 Jul 2018 22:59:38 +0200 Subject: [PATCH 050/125] tests: fix depth buffer test failure --- tests/display/test_depth_buffer.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/display/test_depth_buffer.py b/tests/display/test_depth_buffer.py index 02b0c11b69..f4fe924b63 100644 --- a/tests/display/test_depth_buffer.py +++ b/tests/display/test_depth_buffer.py @@ -110,7 +110,7 @@ def test_depth_write(depth_region): def test_depth_far_inf(depth_region): inf = float("inf") - assert 0.99 > render_depth_pixel(depth_region, 100.0, near=1, far=inf, clear=1.0) + assert 0.99 > render_depth_pixel(depth_region, 10.0, near=1, far=inf, clear=1.0) def test_depth_clipping(depth_region): From cf240d95c19ec2a7acc9351f59e1922f06644e41 Mon Sep 17 00:00:00 2001 From: rdb Date: Tue, 17 Jul 2018 22:59:54 +0200 Subject: [PATCH 051/125] gobj: support infinite near distance in PerspectiveLens Useful when rendering with near/far planes flipped around. --- panda/src/gobj/perspectiveLens.cxx | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/panda/src/gobj/perspectiveLens.cxx b/panda/src/gobj/perspectiveLens.cxx index 0fc83ec15b..160ae74aca 100644 --- a/panda/src/gobj/perspectiveLens.cxx +++ b/panda/src/gobj/perspectiveLens.cxx @@ -71,9 +71,14 @@ do_compute_projection_mat(Lens::CData *lens_cdata) { PN_stdfloat fNear = do_get_near(lens_cdata); PN_stdfloat a, b; + // Take the limits if either near or far is infinite. if (cinf(fFar)) { a = 1; b = -2 * fNear; + } else if (cinf(fNear)) { + // This is valid if the near/far planes are inverted. + a = -1; + b = 2 * fFar; } else { PN_stdfloat far_minus_near = fFar-fNear; a = (fFar + fNear); From bbb15631c6bd9969e875ad0f144f6a5b6258393d Mon Sep 17 00:00:00 2001 From: rdb Date: Tue, 17 Jul 2018 23:00:57 +0200 Subject: [PATCH 052/125] mathutil: support infinite near/far in LFrustum I don't know if anyone is using LFrustum, but just in case, it's good to support this corner case. --- panda/src/mathutil/frustum_src.I | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/panda/src/mathutil/frustum_src.I b/panda/src/mathutil/frustum_src.I index f76d5bec53..f884b29f45 100644 --- a/panda/src/mathutil/frustum_src.I +++ b/panda/src/mathutil/frustum_src.I @@ -140,7 +140,6 @@ get_perspective_projection_mat(CoordinateSystem cs) const { cs = get_default_coordinate_system(); } - FLOATTYPE recip_far_minus_near = 1.0f/(_ffar - _fnear); FLOATTYPE recip_r_minus_l = 1.0f/(_r - _l); FLOATTYPE recip_t_minus_b = 1.0f/(_t - _b); FLOATTYPE two_fnear = 2.0f*_fnear; @@ -149,8 +148,20 @@ get_perspective_projection_mat(CoordinateSystem cs) const { FLOATTYPE a = two_fnear * recip_r_minus_l; FLOATTYPE e = two_fnear * recip_t_minus_b; FLOATTYPE b = (_t + _b) * recip_t_minus_b; - FLOATTYPE c = (_ffar + _fnear) * recip_far_minus_near; - FLOATTYPE f = -_ffar * two_fnear * recip_far_minus_near; + FLOATTYPE c, f; + + // Take the limits if either near or far is infinite. + if (cinf(_ffar)) { + c = 1; + f = -2 * _fnear; + } else if (cinf(_fnear)) { + c = -1; + f = 2 * _ffar; + } else { + FLOATTYPE recip_far_minus_near = 1.0f / (_ffar - _fnear); + c = (_ffar + _fnear) * recip_far_minus_near; + f = -_ffar * two_fnear * recip_far_minus_near; + } /* FLOATTYPE a = (2.0f * _fnear) / (_r - _l); From f45fa747d1cdf9e19a25fdaa7b7fedcf23348ef8 Mon Sep 17 00:00:00 2001 From: rdb Date: Tue, 17 Jul 2018 23:01:44 +0200 Subject: [PATCH 053/125] x11display: fix BadWindow if get_pointer called after win close --- panda/src/x11display/x11GraphicsWindow.cxx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/panda/src/x11display/x11GraphicsWindow.cxx b/panda/src/x11display/x11GraphicsWindow.cxx index d1f49eedc3..45c04909a2 100644 --- a/panda/src/x11display/x11GraphicsWindow.cxx +++ b/panda/src/x11display/x11GraphicsWindow.cxx @@ -163,8 +163,8 @@ get_pointer(int device) const { if (device == 0 && !_dga_mouse_enabled && result._in_window && x11GraphicsPipe::_x_mutex.try_lock()) { XEvent event; - LightReMutexHolder holder(x11GraphicsPipe::_x_mutex); - if (XQueryPointer(_display, _xwindow, &event.xbutton.root, + if (_xwindow != None && + XQueryPointer(_display, _xwindow, &event.xbutton.root, &event.xbutton.window, &event.xbutton.x_root, &event.xbutton.y_root, &event.xbutton.x, &event.xbutton.y, &event.xbutton.state)) { double time = ClockObject::get_global_clock()->get_real_time(); From 71e18eb9606fe9da975858c9a877bc62c46a80d0 Mon Sep 17 00:00:00 2001 From: rdb Date: Tue, 17 Jul 2018 23:23:38 +0200 Subject: [PATCH 054/125] tests: add test for setting near distance to infinitiy --- tests/display/test_depth_buffer.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/display/test_depth_buffer.py b/tests/display/test_depth_buffer.py index f4fe924b63..8581fe47ea 100644 --- a/tests/display/test_depth_buffer.py +++ b/tests/display/test_depth_buffer.py @@ -113,6 +113,11 @@ def test_depth_far_inf(depth_region): assert 0.99 > render_depth_pixel(depth_region, 10.0, near=1, far=inf, clear=1.0) +def test_depth_near_inf(depth_region): + inf = float("inf") + assert 0.01 < render_depth_pixel(depth_region, 10.0, near=inf, far=1, clear=0.0) + + def test_depth_clipping(depth_region): # Get the actual depth resulting from the clear value. clr = render_depth_pixel(depth_region, None, near=1, far=10, clear=0.5) From 1a6d329fde5e9961236a6a96ce936b78d4f06ad9 Mon Sep 17 00:00:00 2001 From: rdb Date: Mon, 23 Jul 2018 08:32:58 +0200 Subject: [PATCH 055/125] gobj: support T_unsigned_int_24_8 in TexturePeeker --- panda/src/gobj/texture.I | 18 ++++++++++++++++++ panda/src/gobj/texture.h | 1 + panda/src/gobj/texturePeeker.cxx | 4 ++++ 3 files changed, 23 insertions(+) diff --git a/panda/src/gobj/texture.I b/panda/src/gobj/texture.I index c766c5b82d..4abb480348 100644 --- a/panda/src/gobj/texture.I +++ b/panda/src/gobj/texture.I @@ -2342,6 +2342,24 @@ get_unsigned_int(const unsigned char *&p) { return (double)v.ui / 4294967295.0; } +/** + * This is used by store() to retrieve the next consecutive component value + * from the indicated element of the array, which is taken to be an array of + * unsigned ints with the value packed in the 24 least significant bits. + */ +INLINE double Texture:: +get_unsigned_int_24(const unsigned char *&p) { + union { + uint32_t ui; + uint8_t uc[4]; + } v; + v.uc[0] = (*p++); + v.uc[1] = (*p++); + v.uc[2] = (*p++); + v.uc[3] = (*p++); + return (double)(v.ui & 0xffffff) / (double)0xffffff; +} + /** * This is used by store() to retrieve the next consecutive component value * from the indicated element of the array, which is taken to be an array of diff --git a/panda/src/gobj/texture.h b/panda/src/gobj/texture.h index 852f618c81..7cb5f305fb 100644 --- a/panda/src/gobj/texture.h +++ b/panda/src/gobj/texture.h @@ -858,6 +858,7 @@ private: INLINE static double get_unsigned_byte(const unsigned char *&p); INLINE static double get_unsigned_short(const unsigned char *&p); INLINE static double get_unsigned_int(const unsigned char *&p); + INLINE static double get_unsigned_int_24(const unsigned char *&p); INLINE static double get_float(const unsigned char *&p); INLINE static double get_half_float(const unsigned char *&p); diff --git a/panda/src/gobj/texturePeeker.cxx b/panda/src/gobj/texturePeeker.cxx index ef007d91dd..7bb17ab87a 100644 --- a/panda/src/gobj/texturePeeker.cxx +++ b/panda/src/gobj/texturePeeker.cxx @@ -94,6 +94,10 @@ TexturePeeker(Texture *tex, Texture::CData *cdata) { _get_component = Texture::get_half_float; break; + case Texture::T_unsigned_int_24_8: + _get_component = Texture::get_unsigned_int_24; + break; + default: // Not supported. _image.clear(); From 7fe72c47f352661d423f4629fb3fc0de692cfca7 Mon Sep 17 00:00:00 2001 From: rdb Date: Mon, 23 Jul 2018 09:02:12 +0200 Subject: [PATCH 056/125] glgsg: update copy of glext.h --- panda/src/glstuff/panda_glext.h | 765 ++++++++++++++++++++++++++++++-- 1 file changed, 732 insertions(+), 33 deletions(-) diff --git a/panda/src/glstuff/panda_glext.h b/panda/src/glstuff/panda_glext.h index 3be88b13c5..decfc9fcf4 100644 --- a/panda/src/glstuff/panda_glext.h +++ b/panda/src/glstuff/panda_glext.h @@ -6,7 +6,7 @@ extern "C" { #endif /* -** Copyright (c) 2013-2015 The Khronos Group Inc. +** Copyright (c) 2013-2018 The Khronos Group Inc. ** ** Permission is hereby granted, free of charge, to any person obtaining a ** copy of this software and/or associated documentation files (the @@ -31,9 +31,7 @@ extern "C" { ** This header is generated from the Khronos OpenGL / OpenGL ES XML ** API Registry. The current version of the Registry, generator scripts ** used to make the header, and the header can be found at -** http://www.opengl.org/registry/ -** -** Khronos $Revision: 31717 $ on $Date: 2015-07-20 05:42:11 -0400 (Mon, 20 Jul 2015) $ +** https://github.com/KhronosGroup/OpenGL-Registry */ #if defined(_WIN32) && !defined(APIENTRY) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__) @@ -53,7 +51,7 @@ extern "C" { #define GLAPI extern #endif -#define GL_GLEXT_VERSION 20150720 +#define GL_GLEXT_VERSION 20180525 /* Generated C header for: * API: gl @@ -355,15 +353,17 @@ GLAPI void APIENTRY glMultTransposeMatrixd (const GLdouble *m); #define GL_TEXTURE_FILTER_CONTROL 0x8500 #define GL_DEPTH_TEXTURE_MODE 0x884B #define GL_COMPARE_R_TO_TEXTURE 0x884E -#define GL_FUNC_ADD 0x8006 -#define GL_FUNC_SUBTRACT 0x800A -#define GL_FUNC_REVERSE_SUBTRACT 0x800B -#define GL_MIN 0x8007 -#define GL_MAX 0x8008 +#define GL_BLEND_COLOR 0x8005 +#define GL_BLEND_EQUATION 0x8009 #define GL_CONSTANT_COLOR 0x8001 #define GL_ONE_MINUS_CONSTANT_COLOR 0x8002 #define GL_CONSTANT_ALPHA 0x8003 #define GL_ONE_MINUS_CONSTANT_ALPHA 0x8004 +#define GL_FUNC_ADD 0x8006 +#define GL_FUNC_REVERSE_SUBTRACT 0x800B +#define GL_FUNC_SUBTRACT 0x800A +#define GL_MIN 0x8007 +#define GL_MAX 0x8008 typedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); typedef void (APIENTRYP PFNGLMULTIDRAWARRAYSPROC) (GLenum mode, const GLint *first, const GLsizei *count, GLsizei drawcount); typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTSPROC) (GLenum mode, const GLsizei *count, GLenum type, const void *const*indices, GLsizei drawcount); @@ -2654,7 +2654,7 @@ typedef void (APIENTRYP PFNGLINVALIDATENAMEDFRAMEBUFFERSUBDATAPROC) (GLuint fram typedef void (APIENTRYP PFNGLCLEARNAMEDFRAMEBUFFERIVPROC) (GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLint *value); typedef void (APIENTRYP PFNGLCLEARNAMEDFRAMEBUFFERUIVPROC) (GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLuint *value); typedef void (APIENTRYP PFNGLCLEARNAMEDFRAMEBUFFERFVPROC) (GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLfloat *value); -typedef void (APIENTRYP PFNGLCLEARNAMEDFRAMEBUFFERFIPROC) (GLuint framebuffer, GLenum buffer, const GLfloat depth, GLint stencil); +//typedef void (APIENTRYP PFNGLCLEARNAMEDFRAMEBUFFERFIPROC) (GLuint framebuffer, GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil); typedef void (APIENTRYP PFNGLBLITNAMEDFRAMEBUFFERPROC) (GLuint readFramebuffer, GLuint drawFramebuffer, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); typedef GLenum (APIENTRYP PFNGLCHECKNAMEDFRAMEBUFFERSTATUSPROC) (GLuint framebuffer, GLenum target); typedef void (APIENTRYP PFNGLGETNAMEDFRAMEBUFFERPARAMETERIVPROC) (GLuint framebuffer, GLenum pname, GLint *param); @@ -2777,7 +2777,7 @@ GLAPI void APIENTRY glInvalidateNamedFramebufferSubData (GLuint framebuffer, GLs GLAPI void APIENTRY glClearNamedFramebufferiv (GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLint *value); GLAPI void APIENTRY glClearNamedFramebufferuiv (GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLuint *value); GLAPI void APIENTRY glClearNamedFramebufferfv (GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLfloat *value); -GLAPI void APIENTRY glClearNamedFramebufferfi (GLuint framebuffer, GLenum buffer, const GLfloat depth, GLint stencil); +//GLAPI void APIENTRY glClearNamedFramebufferfi (GLuint framebuffer, GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil); GLAPI void APIENTRY glBlitNamedFramebuffer (GLuint readFramebuffer, GLuint drawFramebuffer, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); GLAPI GLenum APIENTRY glCheckNamedFramebufferStatus (GLuint framebuffer, GLenum target); GLAPI void APIENTRY glGetNamedFramebufferParameteriv (GLuint framebuffer, GLenum pname, GLint *param); @@ -2867,6 +2867,42 @@ GLAPI void APIENTRY glTextureBarrier (void); #endif #endif /* GL_VERSION_4_5 */ +#ifndef GL_VERSION_4_6 +#define GL_VERSION_4_6 1 +#define GL_SHADER_BINARY_FORMAT_SPIR_V 0x9551 +#define GL_SPIR_V_BINARY 0x9552 +#define GL_PARAMETER_BUFFER 0x80EE +#define GL_PARAMETER_BUFFER_BINDING 0x80EF +#define GL_CONTEXT_FLAG_NO_ERROR_BIT 0x00000008 +#define GL_VERTICES_SUBMITTED 0x82EE +#define GL_PRIMITIVES_SUBMITTED 0x82EF +#define GL_VERTEX_SHADER_INVOCATIONS 0x82F0 +#define GL_TESS_CONTROL_SHADER_PATCHES 0x82F1 +#define GL_TESS_EVALUATION_SHADER_INVOCATIONS 0x82F2 +#define GL_GEOMETRY_SHADER_PRIMITIVES_EMITTED 0x82F3 +#define GL_FRAGMENT_SHADER_INVOCATIONS 0x82F4 +#define GL_COMPUTE_SHADER_INVOCATIONS 0x82F5 +#define GL_CLIPPING_INPUT_PRIMITIVES 0x82F6 +#define GL_CLIPPING_OUTPUT_PRIMITIVES 0x82F7 +#define GL_POLYGON_OFFSET_CLAMP 0x8E1B +#define GL_SPIR_V_EXTENSIONS 0x9553 +#define GL_NUM_SPIR_V_EXTENSIONS 0x9554 +#define GL_TEXTURE_MAX_ANISOTROPY 0x84FE +#define GL_MAX_TEXTURE_MAX_ANISOTROPY 0x84FF +#define GL_TRANSFORM_FEEDBACK_OVERFLOW 0x82EC +#define GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW 0x82ED +typedef void (APIENTRYP PFNGLSPECIALIZESHADERPROC) (GLuint shader, const GLchar *pEntryPoint, GLuint numSpecializationConstants, const GLuint *pConstantIndex, const GLuint *pConstantValue); +typedef void (APIENTRYP PFNGLMULTIDRAWARRAYSINDIRECTCOUNTPROC) (GLenum mode, const void *indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride); +typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTSINDIRECTCOUNTPROC) (GLenum mode, GLenum type, const void *indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride); +typedef void (APIENTRYP PFNGLPOLYGONOFFSETCLAMPPROC) (GLfloat factor, GLfloat units, GLfloat clamp); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glSpecializeShader (GLuint shader, const GLchar *pEntryPoint, GLuint numSpecializationConstants, const GLuint *pConstantIndex, const GLuint *pConstantValue); +GLAPI void APIENTRY glMultiDrawArraysIndirectCount (GLenum mode, const void *indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride); +GLAPI void APIENTRY glMultiDrawElementsIndirectCount (GLenum mode, GLenum type, const void *indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride); +GLAPI void APIENTRY glPolygonOffsetClamp (GLfloat factor, GLfloat units, GLfloat clamp); +#endif +#endif /* GL_VERSION_4_6 */ + #ifndef GL_ARB_ES2_compatibility #define GL_ARB_ES2_compatibility 1 #endif /* GL_ARB_ES2_compatibility */ @@ -2875,6 +2911,17 @@ GLAPI void APIENTRY glTextureBarrier (void); #define GL_ARB_ES3_1_compatibility 1 #endif /* GL_ARB_ES3_1_compatibility */ +#ifndef GL_ARB_ES3_2_compatibility +#define GL_ARB_ES3_2_compatibility 1 +#define GL_PRIMITIVE_BOUNDING_BOX_ARB 0x92BE +#define GL_MULTISAMPLE_LINE_WIDTH_RANGE_ARB 0x9381 +#define GL_MULTISAMPLE_LINE_WIDTH_GRANULARITY_ARB 0x9382 +typedef void (APIENTRYP PFNGLPRIMITIVEBOUNDINGBOXARBPROC) (GLfloat minX, GLfloat minY, GLfloat minZ, GLfloat minW, GLfloat maxX, GLfloat maxY, GLfloat maxZ, GLfloat maxW); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glPrimitiveBoundingBoxARB (GLfloat minX, GLfloat minY, GLfloat minZ, GLfloat minW, GLfloat maxX, GLfloat maxY, GLfloat maxZ, GLfloat maxW); +#endif +#endif /* GL_ARB_ES3_2_compatibility */ + #ifndef GL_ARB_ES3_compatibility #define GL_ARB_ES3_compatibility 1 #endif /* GL_ARB_ES3_compatibility */ @@ -3288,6 +3335,10 @@ GLAPI GLboolean APIENTRY glIsProgramARB (GLuint program); #define GL_FRAGMENT_SHADER_DERIVATIVE_HINT_ARB 0x8B8B #endif /* GL_ARB_fragment_shader */ +#ifndef GL_ARB_fragment_shader_interlock +#define GL_ARB_fragment_shader_interlock 1 +#endif /* GL_ARB_fragment_shader_interlock */ + #ifndef GL_ARB_framebuffer_no_attachments #define GL_ARB_framebuffer_no_attachments 1 #endif /* GL_ARB_framebuffer_no_attachments */ @@ -3340,6 +3391,16 @@ GLAPI void APIENTRY glFramebufferTextureFaceARB (GLenum target, GLenum attachmen #define GL_ARB_get_texture_sub_image 1 #endif /* GL_ARB_get_texture_sub_image */ +#ifndef GL_ARB_gl_spirv +#define GL_ARB_gl_spirv 1 +#define GL_SHADER_BINARY_FORMAT_SPIR_V_ARB 0x9551 +#define GL_SPIR_V_BINARY_ARB 0x9552 +typedef void (APIENTRYP PFNGLSPECIALIZESHADERARBPROC) (GLuint shader, const GLchar *pEntryPoint, GLuint numSpecializationConstants, const GLuint *pConstantIndex, const GLuint *pConstantValue); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glSpecializeShaderARB (GLuint shader, const GLchar *pEntryPoint, GLuint numSpecializationConstants, const GLuint *pConstantIndex, const GLuint *pConstantValue); +#endif +#endif /* GL_ARB_gl_spirv */ + #ifndef GL_ARB_gpu_shader5 #define GL_ARB_gpu_shader5 1 #endif /* GL_ARB_gpu_shader5 */ @@ -3348,6 +3409,91 @@ GLAPI void APIENTRY glFramebufferTextureFaceARB (GLenum target, GLenum attachmen #define GL_ARB_gpu_shader_fp64 1 #endif /* GL_ARB_gpu_shader_fp64 */ +#ifndef GL_ARB_gpu_shader_int64 +#define GL_ARB_gpu_shader_int64 1 +#define GL_INT64_ARB 0x140E +#define GL_INT64_VEC2_ARB 0x8FE9 +#define GL_INT64_VEC3_ARB 0x8FEA +#define GL_INT64_VEC4_ARB 0x8FEB +#define GL_UNSIGNED_INT64_VEC2_ARB 0x8FF5 +#define GL_UNSIGNED_INT64_VEC3_ARB 0x8FF6 +#define GL_UNSIGNED_INT64_VEC4_ARB 0x8FF7 +typedef void (APIENTRYP PFNGLUNIFORM1I64ARBPROC) (GLint location, GLint64 x); +typedef void (APIENTRYP PFNGLUNIFORM2I64ARBPROC) (GLint location, GLint64 x, GLint64 y); +typedef void (APIENTRYP PFNGLUNIFORM3I64ARBPROC) (GLint location, GLint64 x, GLint64 y, GLint64 z); +typedef void (APIENTRYP PFNGLUNIFORM4I64ARBPROC) (GLint location, GLint64 x, GLint64 y, GLint64 z, GLint64 w); +typedef void (APIENTRYP PFNGLUNIFORM1I64VARBPROC) (GLint location, GLsizei count, const GLint64 *value); +typedef void (APIENTRYP PFNGLUNIFORM2I64VARBPROC) (GLint location, GLsizei count, const GLint64 *value); +typedef void (APIENTRYP PFNGLUNIFORM3I64VARBPROC) (GLint location, GLsizei count, const GLint64 *value); +typedef void (APIENTRYP PFNGLUNIFORM4I64VARBPROC) (GLint location, GLsizei count, const GLint64 *value); +typedef void (APIENTRYP PFNGLUNIFORM1UI64ARBPROC) (GLint location, GLuint64 x); +typedef void (APIENTRYP PFNGLUNIFORM2UI64ARBPROC) (GLint location, GLuint64 x, GLuint64 y); +typedef void (APIENTRYP PFNGLUNIFORM3UI64ARBPROC) (GLint location, GLuint64 x, GLuint64 y, GLuint64 z); +typedef void (APIENTRYP PFNGLUNIFORM4UI64ARBPROC) (GLint location, GLuint64 x, GLuint64 y, GLuint64 z, GLuint64 w); +typedef void (APIENTRYP PFNGLUNIFORM1UI64VARBPROC) (GLint location, GLsizei count, const GLuint64 *value); +typedef void (APIENTRYP PFNGLUNIFORM2UI64VARBPROC) (GLint location, GLsizei count, const GLuint64 *value); +typedef void (APIENTRYP PFNGLUNIFORM3UI64VARBPROC) (GLint location, GLsizei count, const GLuint64 *value); +typedef void (APIENTRYP PFNGLUNIFORM4UI64VARBPROC) (GLint location, GLsizei count, const GLuint64 *value); +typedef void (APIENTRYP PFNGLGETUNIFORMI64VARBPROC) (GLuint program, GLint location, GLint64 *params); +typedef void (APIENTRYP PFNGLGETUNIFORMUI64VARBPROC) (GLuint program, GLint location, GLuint64 *params); +typedef void (APIENTRYP PFNGLGETNUNIFORMI64VARBPROC) (GLuint program, GLint location, GLsizei bufSize, GLint64 *params); +typedef void (APIENTRYP PFNGLGETNUNIFORMUI64VARBPROC) (GLuint program, GLint location, GLsizei bufSize, GLuint64 *params); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1I64ARBPROC) (GLuint program, GLint location, GLint64 x); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2I64ARBPROC) (GLuint program, GLint location, GLint64 x, GLint64 y); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3I64ARBPROC) (GLuint program, GLint location, GLint64 x, GLint64 y, GLint64 z); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4I64ARBPROC) (GLuint program, GLint location, GLint64 x, GLint64 y, GLint64 z, GLint64 w); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1I64VARBPROC) (GLuint program, GLint location, GLsizei count, const GLint64 *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2I64VARBPROC) (GLuint program, GLint location, GLsizei count, const GLint64 *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3I64VARBPROC) (GLuint program, GLint location, GLsizei count, const GLint64 *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4I64VARBPROC) (GLuint program, GLint location, GLsizei count, const GLint64 *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1UI64ARBPROC) (GLuint program, GLint location, GLuint64 x); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2UI64ARBPROC) (GLuint program, GLint location, GLuint64 x, GLuint64 y); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3UI64ARBPROC) (GLuint program, GLint location, GLuint64 x, GLuint64 y, GLuint64 z); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4UI64ARBPROC) (GLuint program, GLint location, GLuint64 x, GLuint64 y, GLuint64 z, GLuint64 w); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1UI64VARBPROC) (GLuint program, GLint location, GLsizei count, const GLuint64 *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2UI64VARBPROC) (GLuint program, GLint location, GLsizei count, const GLuint64 *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3UI64VARBPROC) (GLuint program, GLint location, GLsizei count, const GLuint64 *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4UI64VARBPROC) (GLuint program, GLint location, GLsizei count, const GLuint64 *value); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glUniform1i64ARB (GLint location, GLint64 x); +GLAPI void APIENTRY glUniform2i64ARB (GLint location, GLint64 x, GLint64 y); +GLAPI void APIENTRY glUniform3i64ARB (GLint location, GLint64 x, GLint64 y, GLint64 z); +GLAPI void APIENTRY glUniform4i64ARB (GLint location, GLint64 x, GLint64 y, GLint64 z, GLint64 w); +GLAPI void APIENTRY glUniform1i64vARB (GLint location, GLsizei count, const GLint64 *value); +GLAPI void APIENTRY glUniform2i64vARB (GLint location, GLsizei count, const GLint64 *value); +GLAPI void APIENTRY glUniform3i64vARB (GLint location, GLsizei count, const GLint64 *value); +GLAPI void APIENTRY glUniform4i64vARB (GLint location, GLsizei count, const GLint64 *value); +GLAPI void APIENTRY glUniform1ui64ARB (GLint location, GLuint64 x); +GLAPI void APIENTRY glUniform2ui64ARB (GLint location, GLuint64 x, GLuint64 y); +GLAPI void APIENTRY glUniform3ui64ARB (GLint location, GLuint64 x, GLuint64 y, GLuint64 z); +GLAPI void APIENTRY glUniform4ui64ARB (GLint location, GLuint64 x, GLuint64 y, GLuint64 z, GLuint64 w); +GLAPI void APIENTRY glUniform1ui64vARB (GLint location, GLsizei count, const GLuint64 *value); +GLAPI void APIENTRY glUniform2ui64vARB (GLint location, GLsizei count, const GLuint64 *value); +GLAPI void APIENTRY glUniform3ui64vARB (GLint location, GLsizei count, const GLuint64 *value); +GLAPI void APIENTRY glUniform4ui64vARB (GLint location, GLsizei count, const GLuint64 *value); +GLAPI void APIENTRY glGetUniformi64vARB (GLuint program, GLint location, GLint64 *params); +GLAPI void APIENTRY glGetUniformui64vARB (GLuint program, GLint location, GLuint64 *params); +GLAPI void APIENTRY glGetnUniformi64vARB (GLuint program, GLint location, GLsizei bufSize, GLint64 *params); +GLAPI void APIENTRY glGetnUniformui64vARB (GLuint program, GLint location, GLsizei bufSize, GLuint64 *params); +GLAPI void APIENTRY glProgramUniform1i64ARB (GLuint program, GLint location, GLint64 x); +GLAPI void APIENTRY glProgramUniform2i64ARB (GLuint program, GLint location, GLint64 x, GLint64 y); +GLAPI void APIENTRY glProgramUniform3i64ARB (GLuint program, GLint location, GLint64 x, GLint64 y, GLint64 z); +GLAPI void APIENTRY glProgramUniform4i64ARB (GLuint program, GLint location, GLint64 x, GLint64 y, GLint64 z, GLint64 w); +GLAPI void APIENTRY glProgramUniform1i64vARB (GLuint program, GLint location, GLsizei count, const GLint64 *value); +GLAPI void APIENTRY glProgramUniform2i64vARB (GLuint program, GLint location, GLsizei count, const GLint64 *value); +GLAPI void APIENTRY glProgramUniform3i64vARB (GLuint program, GLint location, GLsizei count, const GLint64 *value); +GLAPI void APIENTRY glProgramUniform4i64vARB (GLuint program, GLint location, GLsizei count, const GLint64 *value); +GLAPI void APIENTRY glProgramUniform1ui64ARB (GLuint program, GLint location, GLuint64 x); +GLAPI void APIENTRY glProgramUniform2ui64ARB (GLuint program, GLint location, GLuint64 x, GLuint64 y); +GLAPI void APIENTRY glProgramUniform3ui64ARB (GLuint program, GLint location, GLuint64 x, GLuint64 y, GLuint64 z); +GLAPI void APIENTRY glProgramUniform4ui64ARB (GLuint program, GLint location, GLuint64 x, GLuint64 y, GLuint64 z, GLuint64 w); +GLAPI void APIENTRY glProgramUniform1ui64vARB (GLuint program, GLint location, GLsizei count, const GLuint64 *value); +GLAPI void APIENTRY glProgramUniform2ui64vARB (GLuint program, GLint location, GLsizei count, const GLuint64 *value); +GLAPI void APIENTRY glProgramUniform3ui64vARB (GLuint program, GLint location, GLsizei count, const GLuint64 *value); +GLAPI void APIENTRY glProgramUniform4ui64vARB (GLuint program, GLint location, GLsizei count, const GLuint64 *value); +#endif +#endif /* GL_ARB_gpu_shader_int64 */ + #ifndef GL_ARB_half_float_pixel #define GL_ARB_half_float_pixel 1 typedef unsigned short GLhalfARB; @@ -3360,8 +3506,6 @@ typedef unsigned short GLhalfARB; #ifndef GL_ARB_imaging #define GL_ARB_imaging 1 -#define GL_BLEND_COLOR 0x8005 -#define GL_BLEND_EQUATION 0x8009 #define GL_CONVOLUTION_1D 0x8010 #define GL_CONVOLUTION_2D 0x8011 #define GL_SEPARABLE_2D 0x8012 @@ -3498,11 +3642,11 @@ GLAPI void APIENTRY glResetMinmax (GLenum target); #define GL_ARB_indirect_parameters 1 #define GL_PARAMETER_BUFFER_ARB 0x80EE #define GL_PARAMETER_BUFFER_BINDING_ARB 0x80EF -typedef void (APIENTRYP PFNGLMULTIDRAWARRAYSINDIRECTCOUNTARBPROC) (GLenum mode, GLintptr indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride); -typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTSINDIRECTCOUNTARBPROC) (GLenum mode, GLenum type, GLintptr indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride); +typedef void (APIENTRYP PFNGLMULTIDRAWARRAYSINDIRECTCOUNTARBPROC) (GLenum mode, const void *indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride); +typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTSINDIRECTCOUNTARBPROC) (GLenum mode, GLenum type, const void *indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride); #ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glMultiDrawArraysIndirectCountARB (GLenum mode, GLintptr indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride); -GLAPI void APIENTRY glMultiDrawElementsIndirectCountARB (GLenum mode, GLenum type, GLintptr indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride); +GLAPI void APIENTRY glMultiDrawArraysIndirectCountARB (GLenum mode, const void *indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride); +GLAPI void APIENTRY glMultiDrawElementsIndirectCountARB (GLenum mode, GLenum type, const void *indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride); #endif #endif /* GL_ARB_indirect_parameters */ @@ -3727,6 +3871,16 @@ GLAPI void APIENTRY glGetQueryObjectuivARB (GLuint id, GLenum pname, GLuint *par #define GL_ARB_occlusion_query2 1 #endif /* GL_ARB_occlusion_query2 */ +#ifndef GL_ARB_parallel_shader_compile +#define GL_ARB_parallel_shader_compile 1 +#define GL_MAX_SHADER_COMPILER_THREADS_ARB 0x91B0 +#define GL_COMPLETION_STATUS_ARB 0x91B1 +typedef void (APIENTRYP PFNGLMAXSHADERCOMPILERTHREADSARBPROC) (GLuint count); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glMaxShaderCompilerThreadsARB (GLuint count); +#endif +#endif /* GL_ARB_parallel_shader_compile */ + #ifndef GL_ARB_pipeline_statistics_query #define GL_ARB_pipeline_statistics_query 1 #define GL_VERTICES_SUBMITTED_ARB 0x82EE @@ -3769,6 +3923,14 @@ GLAPI void APIENTRY glPointParameterfvARB (GLenum pname, const GLfloat *params); #define GL_COORD_REPLACE_ARB 0x8862 #endif /* GL_ARB_point_sprite */ +#ifndef GL_ARB_polygon_offset_clamp +#define GL_ARB_polygon_offset_clamp 1 +#endif /* GL_ARB_polygon_offset_clamp */ + +#ifndef GL_ARB_post_depth_coverage +#define GL_ARB_post_depth_coverage 1 +#endif /* GL_ARB_post_depth_coverage */ + #ifndef GL_ARB_program_interface_query #define GL_ARB_program_interface_query 1 #endif /* GL_ARB_program_interface_query */ @@ -3842,6 +4004,26 @@ GLAPI void APIENTRY glGetnMinmaxARB (GLenum target, GLboolean reset, GLenum form #define GL_ARB_robustness_isolation 1 #endif /* GL_ARB_robustness_isolation */ +#ifndef GL_ARB_sample_locations +#define GL_ARB_sample_locations 1 +#define GL_SAMPLE_LOCATION_SUBPIXEL_BITS_ARB 0x933D +#define GL_SAMPLE_LOCATION_PIXEL_GRID_WIDTH_ARB 0x933E +#define GL_SAMPLE_LOCATION_PIXEL_GRID_HEIGHT_ARB 0x933F +#define GL_PROGRAMMABLE_SAMPLE_LOCATION_TABLE_SIZE_ARB 0x9340 +#define GL_SAMPLE_LOCATION_ARB 0x8E50 +#define GL_PROGRAMMABLE_SAMPLE_LOCATION_ARB 0x9341 +#define GL_FRAMEBUFFER_PROGRAMMABLE_SAMPLE_LOCATIONS_ARB 0x9342 +#define GL_FRAMEBUFFER_SAMPLE_LOCATION_PIXEL_GRID_ARB 0x9343 +typedef void (APIENTRYP PFNGLFRAMEBUFFERSAMPLELOCATIONSFVARBPROC) (GLenum target, GLuint start, GLsizei count, const GLfloat *v); +typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERSAMPLELOCATIONSFVARBPROC) (GLuint framebuffer, GLuint start, GLsizei count, const GLfloat *v); +typedef void (APIENTRYP PFNGLEVALUATEDEPTHVALUESARBPROC) (void); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glFramebufferSampleLocationsfvARB (GLenum target, GLuint start, GLsizei count, const GLfloat *v); +GLAPI void APIENTRY glNamedFramebufferSampleLocationsfvARB (GLuint framebuffer, GLuint start, GLsizei count, const GLfloat *v); +GLAPI void APIENTRY glEvaluateDepthValuesARB (void); +#endif +#endif /* GL_ARB_sample_locations */ + #ifndef GL_ARB_sample_shading #define GL_ARB_sample_shading 1 #define GL_SAMPLE_SHADING_ARB 0x8C36 @@ -3868,14 +4050,26 @@ GLAPI void APIENTRY glMinSampleShadingARB (GLfloat value); #define GL_ARB_separate_shader_objects 1 #endif /* GL_ARB_separate_shader_objects */ +#ifndef GL_ARB_shader_atomic_counter_ops +#define GL_ARB_shader_atomic_counter_ops 1 +#endif /* GL_ARB_shader_atomic_counter_ops */ + #ifndef GL_ARB_shader_atomic_counters #define GL_ARB_shader_atomic_counters 1 #endif /* GL_ARB_shader_atomic_counters */ +#ifndef GL_ARB_shader_ballot +#define GL_ARB_shader_ballot 1 +#endif /* GL_ARB_shader_ballot */ + #ifndef GL_ARB_shader_bit_encoding #define GL_ARB_shader_bit_encoding 1 #endif /* GL_ARB_shader_bit_encoding */ +#ifndef GL_ARB_shader_clock +#define GL_ARB_shader_clock 1 +#endif /* GL_ARB_shader_clock */ + #ifndef GL_ARB_shader_draw_parameters #define GL_ARB_shader_draw_parameters 1 #endif /* GL_ARB_shader_draw_parameters */ @@ -4040,6 +4234,10 @@ GLAPI void APIENTRY glGetShaderSourceARB (GLhandleARB obj, GLsizei maxLength, GL #define GL_ARB_shader_texture_lod 1 #endif /* GL_ARB_shader_texture_lod */ +#ifndef GL_ARB_shader_viewport_layer_array +#define GL_ARB_shader_viewport_layer_array 1 +#endif /* GL_ARB_shader_viewport_layer_array */ + #ifndef GL_ARB_shading_language_100 #define GL_ARB_shading_language_100 1 #define GL_SHADING_LANGUAGE_VERSION_ARB 0x8B8C @@ -4119,6 +4317,18 @@ GLAPI void APIENTRY glTexPageCommitmentARB (GLenum target, GLint level, GLint xo #endif #endif /* GL_ARB_sparse_texture */ +#ifndef GL_ARB_sparse_texture2 +#define GL_ARB_sparse_texture2 1 +#endif /* GL_ARB_sparse_texture2 */ + +#ifndef GL_ARB_sparse_texture_clamp +#define GL_ARB_sparse_texture_clamp 1 +#endif /* GL_ARB_sparse_texture_clamp */ + +#ifndef GL_ARB_spirv_extensions +#define GL_ARB_spirv_extensions 1 +#endif /* GL_ARB_spirv_extensions */ + #ifndef GL_ARB_stencil_texturing #define GL_ARB_stencil_texturing 1 #endif /* GL_ARB_stencil_texturing */ @@ -4271,6 +4481,16 @@ GLAPI void APIENTRY glGetCompressedTexImageARB (GLenum target, GLint level, void #define GL_DOT3_RGBA_ARB 0x86AF #endif /* GL_ARB_texture_env_dot3 */ +#ifndef GL_ARB_texture_filter_anisotropic +#define GL_ARB_texture_filter_anisotropic 1 +#endif /* GL_ARB_texture_filter_anisotropic */ + +#ifndef GL_ARB_texture_filter_minmax +#define GL_ARB_texture_filter_minmax 1 +#define GL_TEXTURE_REDUCTION_MODE_ARB 0x9366 +#define GL_WEIGHTED_AVERAGE_ARB 0x9367 +#endif /* GL_ARB_texture_filter_minmax */ + #ifndef GL_ARB_texture_float #define GL_ARB_texture_float 1 #define GL_TEXTURE_RED_TYPE_ARB 0x8C10 @@ -4493,6 +4713,9 @@ GLAPI void APIENTRY glVertexBlendARB (GLint count); #ifndef GL_ARB_vertex_buffer_object #define GL_ARB_vertex_buffer_object 1 +#include +typedef ptrdiff_t GLsizeiptrARB; +typedef ptrdiff_t GLintptrARB; #define GL_BUFFER_SIZE_ARB 0x8764 #define GL_BUFFER_USAGE_ARB 0x8765 #define GL_ARRAY_BUFFER_ARB 0x8892 @@ -4528,9 +4751,9 @@ typedef void (APIENTRYP PFNGLBINDBUFFERARBPROC) (GLenum target, GLuint buffer); typedef void (APIENTRYP PFNGLDELETEBUFFERSARBPROC) (GLsizei n, const GLuint *buffers); typedef void (APIENTRYP PFNGLGENBUFFERSARBPROC) (GLsizei n, GLuint *buffers); typedef GLboolean (APIENTRYP PFNGLISBUFFERARBPROC) (GLuint buffer); -typedef void (APIENTRYP PFNGLBUFFERDATAARBPROC) (GLenum target, GLsizeiptr size, const void *data, GLenum usage); -typedef void (APIENTRYP PFNGLBUFFERSUBDATAARBPROC) (GLenum target, GLintptr offset, GLsizeiptr size, const void *data); -typedef void (APIENTRYP PFNGLGETBUFFERSUBDATAARBPROC) (GLenum target, GLintptr offset, GLsizeiptr size, void *data); +typedef void (APIENTRYP PFNGLBUFFERDATAARBPROC) (GLenum target, GLsizeiptrARB size, const void *data, GLenum usage); +typedef void (APIENTRYP PFNGLBUFFERSUBDATAARBPROC) (GLenum target, GLintptrARB offset, GLsizeiptrARB size, const void *data); +typedef void (APIENTRYP PFNGLGETBUFFERSUBDATAARBPROC) (GLenum target, GLintptrARB offset, GLsizeiptrARB size, void *data); typedef void *(APIENTRYP PFNGLMAPBUFFERARBPROC) (GLenum target, GLenum access); typedef GLboolean (APIENTRYP PFNGLUNMAPBUFFERARBPROC) (GLenum target); typedef void (APIENTRYP PFNGLGETBUFFERPARAMETERIVARBPROC) (GLenum target, GLenum pname, GLint *params); @@ -4540,9 +4763,9 @@ GLAPI void APIENTRY glBindBufferARB (GLenum target, GLuint buffer); GLAPI void APIENTRY glDeleteBuffersARB (GLsizei n, const GLuint *buffers); GLAPI void APIENTRY glGenBuffersARB (GLsizei n, GLuint *buffers); GLAPI GLboolean APIENTRY glIsBufferARB (GLuint buffer); -GLAPI void APIENTRY glBufferDataARB (GLenum target, GLsizeiptr size, const void *data, GLenum usage); -GLAPI void APIENTRY glBufferSubDataARB (GLenum target, GLintptr offset, GLsizeiptr size, const void *data); -GLAPI void APIENTRY glGetBufferSubDataARB (GLenum target, GLintptr offset, GLsizeiptr size, void *data); +GLAPI void APIENTRY glBufferDataARB (GLenum target, GLsizeiptrARB size, const void *data, GLenum usage); +GLAPI void APIENTRY glBufferSubDataARB (GLenum target, GLintptrARB offset, GLsizeiptrARB size, const void *data); +GLAPI void APIENTRY glGetBufferSubDataARB (GLenum target, GLintptrARB offset, GLsizeiptrARB size, void *data); GLAPI void *APIENTRY glMapBufferARB (GLenum target, GLenum access); GLAPI GLboolean APIENTRY glUnmapBufferARB (GLenum target); GLAPI void APIENTRY glGetBufferParameterivARB (GLenum target, GLenum pname, GLint *params); @@ -4768,6 +4991,16 @@ GLAPI void APIENTRY glBlendBarrierKHR (void); #define GL_CONTEXT_FLAG_NO_ERROR_BIT_KHR 0x00000008 #endif /* GL_KHR_no_error */ +#ifndef GL_KHR_parallel_shader_compile +#define GL_KHR_parallel_shader_compile 1 +#define GL_MAX_SHADER_COMPILER_THREADS_KHR 0x91B0 +#define GL_COMPLETION_STATUS_KHR 0x91B1 +typedef void (APIENTRYP PFNGLMAXSHADERCOMPILERTHREADSKHRPROC) (GLuint count); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glMaxShaderCompilerThreadsKHR (GLuint count); +#endif +#endif /* GL_KHR_parallel_shader_compile */ + #ifndef GL_KHR_robust_buffer_access_behavior #define GL_KHR_robust_buffer_access_behavior 1 #endif /* GL_KHR_robust_buffer_access_behavior */ @@ -4813,6 +5046,10 @@ GLAPI void APIENTRY glBlendBarrierKHR (void); #define GL_KHR_texture_compression_astc_ldr 1 #endif /* GL_KHR_texture_compression_astc_ldr */ +#ifndef GL_KHR_texture_compression_astc_sliced_3d +#define GL_KHR_texture_compression_astc_sliced_3d 1 +#endif /* GL_KHR_texture_compression_astc_sliced_3d */ + #ifndef GL_OES_byte_coordinates #define GL_OES_byte_coordinates 1 typedef void (APIENTRYP PFNGLMULTITEXCOORD1BOESPROC) (GLenum texture, GLbyte s); @@ -5204,10 +5441,49 @@ GLAPI void APIENTRY glBlendEquationSeparateIndexedAMD (GLuint buf, GLenum modeRG #endif #endif /* GL_AMD_draw_buffers_blend */ +#ifndef GL_AMD_framebuffer_sample_positions +#define GL_AMD_framebuffer_sample_positions 1 +#define GL_SUBSAMPLE_DISTANCE_AMD 0x883F +#define GL_PIXELS_PER_SAMPLE_PATTERN_X_AMD 0x91AE +#define GL_PIXELS_PER_SAMPLE_PATTERN_Y_AMD 0x91AF +#define GL_ALL_PIXELS_AMD 0xFFFFFFFF +typedef void (APIENTRYP PFNGLFRAMEBUFFERSAMPLEPOSITIONSFVAMDPROC) (GLenum target, GLuint numsamples, GLuint pixelindex, const GLfloat *values); +typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERSAMPLEPOSITIONSFVAMDPROC) (GLuint framebuffer, GLuint numsamples, GLuint pixelindex, const GLfloat *values); +typedef void (APIENTRYP PFNGLGETFRAMEBUFFERPARAMETERFVAMDPROC) (GLenum target, GLenum pname, GLuint numsamples, GLuint pixelindex, GLsizei size, GLfloat *values); +typedef void (APIENTRYP PFNGLGETNAMEDFRAMEBUFFERPARAMETERFVAMDPROC) (GLuint framebuffer, GLenum pname, GLuint numsamples, GLuint pixelindex, GLsizei size, GLfloat *values); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glFramebufferSamplePositionsfvAMD (GLenum target, GLuint numsamples, GLuint pixelindex, const GLfloat *values); +GLAPI void APIENTRY glNamedFramebufferSamplePositionsfvAMD (GLuint framebuffer, GLuint numsamples, GLuint pixelindex, const GLfloat *values); +GLAPI void APIENTRY glGetFramebufferParameterfvAMD (GLenum target, GLenum pname, GLuint numsamples, GLuint pixelindex, GLsizei size, GLfloat *values); +GLAPI void APIENTRY glGetNamedFramebufferParameterfvAMD (GLuint framebuffer, GLenum pname, GLuint numsamples, GLuint pixelindex, GLsizei size, GLfloat *values); +#endif +#endif /* GL_AMD_framebuffer_sample_positions */ + #ifndef GL_AMD_gcn_shader #define GL_AMD_gcn_shader 1 #endif /* GL_AMD_gcn_shader */ +#ifndef GL_AMD_gpu_shader_half_float +#define GL_AMD_gpu_shader_half_float 1 +#define GL_FLOAT16_NV 0x8FF8 +#define GL_FLOAT16_VEC2_NV 0x8FF9 +#define GL_FLOAT16_VEC3_NV 0x8FFA +#define GL_FLOAT16_VEC4_NV 0x8FFB +#define GL_FLOAT16_MAT2_AMD 0x91C5 +#define GL_FLOAT16_MAT3_AMD 0x91C6 +#define GL_FLOAT16_MAT4_AMD 0x91C7 +#define GL_FLOAT16_MAT2x3_AMD 0x91C8 +#define GL_FLOAT16_MAT2x4_AMD 0x91C9 +#define GL_FLOAT16_MAT3x2_AMD 0x91CA +#define GL_FLOAT16_MAT3x4_AMD 0x91CB +#define GL_FLOAT16_MAT4x2_AMD 0x91CC +#define GL_FLOAT16_MAT4x3_AMD 0x91CD +#endif /* GL_AMD_gpu_shader_half_float */ + +#ifndef GL_AMD_gpu_shader_int16 +#define GL_AMD_gpu_shader_int16 1 +#endif /* GL_AMD_gpu_shader_int16 */ + #ifndef GL_AMD_gpu_shader_int64 #define GL_AMD_gpu_shader_int64 1 typedef int64_t GLint64EXT; @@ -5235,10 +5511,6 @@ typedef int64_t GLint64EXT; #define GL_UNSIGNED_INT64_VEC2_NV 0x8FF5 #define GL_UNSIGNED_INT64_VEC3_NV 0x8FF6 #define GL_UNSIGNED_INT64_VEC4_NV 0x8FF7 -#define GL_FLOAT16_NV 0x8FF8 -#define GL_FLOAT16_VEC2_NV 0x8FF9 -#define GL_FLOAT16_VEC3_NV 0x8FFA -#define GL_FLOAT16_VEC4_NV 0x8FFB typedef void (APIENTRYP PFNGLUNIFORM1I64NVPROC) (GLint location, GLint64EXT x); typedef void (APIENTRYP PFNGLUNIFORM2I64NVPROC) (GLint location, GLint64EXT x, GLint64EXT y); typedef void (APIENTRYP PFNGLUNIFORM3I64NVPROC) (GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z); @@ -5411,7 +5683,6 @@ GLAPI void APIENTRY glGetPerfMonitorCounterDataAMD (GLuint monitor, GLenum pname #ifndef GL_AMD_sample_positions #define GL_AMD_sample_positions 1 -#define GL_SUBSAMPLE_DISTANCE_AMD 0x883F typedef void (APIENTRYP PFNGLSETMULTISAMPLEFVAMDPROC) (GLenum pname, GLuint index, const GLfloat *val); #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glSetMultisamplefvAMD (GLenum pname, GLuint index, const GLfloat *val); @@ -5426,6 +5697,22 @@ GLAPI void APIENTRY glSetMultisamplefvAMD (GLenum pname, GLuint index, const GLf #define GL_AMD_shader_atomic_counter_ops 1 #endif /* GL_AMD_shader_atomic_counter_ops */ +#ifndef GL_AMD_shader_ballot +#define GL_AMD_shader_ballot 1 +#endif /* GL_AMD_shader_ballot */ + +#ifndef GL_AMD_shader_explicit_vertex_parameter +#define GL_AMD_shader_explicit_vertex_parameter 1 +#endif /* GL_AMD_shader_explicit_vertex_parameter */ + +#ifndef GL_AMD_shader_gpu_shader_half_float_fetch +#define GL_AMD_shader_gpu_shader_half_float_fetch 1 +#endif /* GL_AMD_shader_gpu_shader_half_float_fetch */ + +#ifndef GL_AMD_shader_image_load_store_lod +#define GL_AMD_shader_image_load_store_lod 1 +#endif /* GL_AMD_shader_image_load_store_lod */ + #ifndef GL_AMD_shader_stencil_export #define GL_AMD_shader_stencil_export 1 #endif /* GL_AMD_shader_stencil_export */ @@ -5465,6 +5752,10 @@ GLAPI void APIENTRY glStencilOpValueAMD (GLenum face, GLuint value); #endif #endif /* GL_AMD_stencil_operation_extended */ +#ifndef GL_AMD_texture_gather_bias_lod +#define GL_AMD_texture_gather_bias_lod 1 +#endif /* GL_AMD_texture_gather_bias_lod */ + #ifndef GL_AMD_texture_texture4 #define GL_AMD_texture_texture4 1 #endif /* GL_AMD_texture_texture4 */ @@ -6165,6 +6456,17 @@ GLAPI void APIENTRY glVertexBlendEnvfATI (GLenum pname, GLfloat param); #define GL_422_REV_AVERAGE_EXT 0x80CF #endif /* GL_EXT_422_pixels */ +#ifndef GL_EXT_EGL_image_storage +#define GL_EXT_EGL_image_storage 1 +typedef void *GLeglImageOES; +typedef void (APIENTRYP PFNGLEGLIMAGETARGETTEXSTORAGEEXTPROC) (GLenum target, GLeglImageOES image, const GLint* attrib_list); +typedef void (APIENTRYP PFNGLEGLIMAGETARGETTEXTURESTORAGEEXTPROC) (GLuint texture, GLeglImageOES image, const GLint* attrib_list); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glEGLImageTargetTexStorageEXT (GLenum target, GLeglImageOES image, const GLint* attrib_list); +GLAPI void APIENTRY glEGLImageTargetTextureStorageEXT (GLuint texture, GLeglImageOES image, const GLint* attrib_list); +#endif +#endif /* GL_EXT_EGL_image_storage */ + #ifndef GL_EXT_abgr #define GL_EXT_abgr 1 #define GL_ABGR_EXT 0x8000 @@ -7016,6 +7318,17 @@ GLAPI void APIENTRY glDrawRangeElementsEXT (GLenum mode, GLuint start, GLuint en #endif #endif /* GL_EXT_draw_range_elements */ +#ifndef GL_EXT_external_buffer +#define GL_EXT_external_buffer 1 +typedef void *GLeglClientBufferEXT; +typedef void (APIENTRYP PFNGLBUFFERSTORAGEEXTERNALEXTPROC) (GLenum target, GLintptr offset, GLsizeiptr size, GLeglClientBufferEXT clientBuffer, GLbitfield flags); +typedef void (APIENTRYP PFNGLNAMEDBUFFERSTORAGEEXTERNALEXTPROC) (GLuint buffer, GLintptr offset, GLsizeiptr size, GLeglClientBufferEXT clientBuffer, GLbitfield flags); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glBufferStorageExternalEXT (GLenum target, GLintptr offset, GLsizeiptr size, GLeglClientBufferEXT clientBuffer, GLbitfield flags); +GLAPI void APIENTRY glNamedBufferStorageExternalEXT (GLuint buffer, GLintptr offset, GLsizeiptr size, GLeglClientBufferEXT clientBuffer, GLbitfield flags); +#endif +#endif /* GL_EXT_external_buffer */ + #ifndef GL_EXT_fog_coord #define GL_EXT_fog_coord 1 #define GL_FOG_COORDINATE_SOURCE_EXT 0x8450 @@ -7359,6 +7672,89 @@ GLAPI void APIENTRY glTextureMaterialEXT (GLenum face, GLenum mode); #endif #endif /* GL_EXT_light_texture */ +#ifndef GL_EXT_memory_object +#define GL_EXT_memory_object 1 +#define GL_TEXTURE_TILING_EXT 0x9580 +#define GL_DEDICATED_MEMORY_OBJECT_EXT 0x9581 +#define GL_PROTECTED_MEMORY_OBJECT_EXT 0x959B +#define GL_NUM_TILING_TYPES_EXT 0x9582 +#define GL_TILING_TYPES_EXT 0x9583 +#define GL_OPTIMAL_TILING_EXT 0x9584 +#define GL_LINEAR_TILING_EXT 0x9585 +#define GL_NUM_DEVICE_UUIDS_EXT 0x9596 +#define GL_DEVICE_UUID_EXT 0x9597 +#define GL_DRIVER_UUID_EXT 0x9598 +#define GL_UUID_SIZE_EXT 16 +typedef void (APIENTRYP PFNGLGETUNSIGNEDBYTEVEXTPROC) (GLenum pname, GLubyte *data); +typedef void (APIENTRYP PFNGLGETUNSIGNEDBYTEI_VEXTPROC) (GLenum target, GLuint index, GLubyte *data); +typedef void (APIENTRYP PFNGLDELETEMEMORYOBJECTSEXTPROC) (GLsizei n, const GLuint *memoryObjects); +typedef GLboolean (APIENTRYP PFNGLISMEMORYOBJECTEXTPROC) (GLuint memoryObject); +typedef void (APIENTRYP PFNGLCREATEMEMORYOBJECTSEXTPROC) (GLsizei n, GLuint *memoryObjects); +typedef void (APIENTRYP PFNGLMEMORYOBJECTPARAMETERIVEXTPROC) (GLuint memoryObject, GLenum pname, const GLint *params); +typedef void (APIENTRYP PFNGLGETMEMORYOBJECTPARAMETERIVEXTPROC) (GLuint memoryObject, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLTEXSTORAGEMEM2DEXTPROC) (GLenum target, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height, GLuint memory, GLuint64 offset); +typedef void (APIENTRYP PFNGLTEXSTORAGEMEM2DMULTISAMPLEEXTPROC) (GLenum target, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations, GLuint memory, GLuint64 offset); +typedef void (APIENTRYP PFNGLTEXSTORAGEMEM3DEXTPROC) (GLenum target, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLuint memory, GLuint64 offset); +typedef void (APIENTRYP PFNGLTEXSTORAGEMEM3DMULTISAMPLEEXTPROC) (GLenum target, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations, GLuint memory, GLuint64 offset); +typedef void (APIENTRYP PFNGLBUFFERSTORAGEMEMEXTPROC) (GLenum target, GLsizeiptr size, GLuint memory, GLuint64 offset); +typedef void (APIENTRYP PFNGLTEXTURESTORAGEMEM2DEXTPROC) (GLuint texture, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height, GLuint memory, GLuint64 offset); +typedef void (APIENTRYP PFNGLTEXTURESTORAGEMEM2DMULTISAMPLEEXTPROC) (GLuint texture, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations, GLuint memory, GLuint64 offset); +typedef void (APIENTRYP PFNGLTEXTURESTORAGEMEM3DEXTPROC) (GLuint texture, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLuint memory, GLuint64 offset); +typedef void (APIENTRYP PFNGLTEXTURESTORAGEMEM3DMULTISAMPLEEXTPROC) (GLuint texture, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations, GLuint memory, GLuint64 offset); +typedef void (APIENTRYP PFNGLNAMEDBUFFERSTORAGEMEMEXTPROC) (GLuint buffer, GLsizeiptr size, GLuint memory, GLuint64 offset); +typedef void (APIENTRYP PFNGLTEXSTORAGEMEM1DEXTPROC) (GLenum target, GLsizei levels, GLenum internalFormat, GLsizei width, GLuint memory, GLuint64 offset); +typedef void (APIENTRYP PFNGLTEXTURESTORAGEMEM1DEXTPROC) (GLuint texture, GLsizei levels, GLenum internalFormat, GLsizei width, GLuint memory, GLuint64 offset); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glGetUnsignedBytevEXT (GLenum pname, GLubyte *data); +GLAPI void APIENTRY glGetUnsignedBytei_vEXT (GLenum target, GLuint index, GLubyte *data); +GLAPI void APIENTRY glDeleteMemoryObjectsEXT (GLsizei n, const GLuint *memoryObjects); +GLAPI GLboolean APIENTRY glIsMemoryObjectEXT (GLuint memoryObject); +GLAPI void APIENTRY glCreateMemoryObjectsEXT (GLsizei n, GLuint *memoryObjects); +GLAPI void APIENTRY glMemoryObjectParameterivEXT (GLuint memoryObject, GLenum pname, const GLint *params); +GLAPI void APIENTRY glGetMemoryObjectParameterivEXT (GLuint memoryObject, GLenum pname, GLint *params); +GLAPI void APIENTRY glTexStorageMem2DEXT (GLenum target, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height, GLuint memory, GLuint64 offset); +GLAPI void APIENTRY glTexStorageMem2DMultisampleEXT (GLenum target, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations, GLuint memory, GLuint64 offset); +GLAPI void APIENTRY glTexStorageMem3DEXT (GLenum target, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLuint memory, GLuint64 offset); +GLAPI void APIENTRY glTexStorageMem3DMultisampleEXT (GLenum target, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations, GLuint memory, GLuint64 offset); +GLAPI void APIENTRY glBufferStorageMemEXT (GLenum target, GLsizeiptr size, GLuint memory, GLuint64 offset); +GLAPI void APIENTRY glTextureStorageMem2DEXT (GLuint texture, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height, GLuint memory, GLuint64 offset); +GLAPI void APIENTRY glTextureStorageMem2DMultisampleEXT (GLuint texture, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations, GLuint memory, GLuint64 offset); +GLAPI void APIENTRY glTextureStorageMem3DEXT (GLuint texture, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLuint memory, GLuint64 offset); +GLAPI void APIENTRY glTextureStorageMem3DMultisampleEXT (GLuint texture, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations, GLuint memory, GLuint64 offset); +GLAPI void APIENTRY glNamedBufferStorageMemEXT (GLuint buffer, GLsizeiptr size, GLuint memory, GLuint64 offset); +GLAPI void APIENTRY glTexStorageMem1DEXT (GLenum target, GLsizei levels, GLenum internalFormat, GLsizei width, GLuint memory, GLuint64 offset); +GLAPI void APIENTRY glTextureStorageMem1DEXT (GLuint texture, GLsizei levels, GLenum internalFormat, GLsizei width, GLuint memory, GLuint64 offset); +#endif +#endif /* GL_EXT_memory_object */ + +#ifndef GL_EXT_memory_object_fd +#define GL_EXT_memory_object_fd 1 +#define GL_HANDLE_TYPE_OPAQUE_FD_EXT 0x9586 +typedef void (APIENTRYP PFNGLIMPORTMEMORYFDEXTPROC) (GLuint memory, GLuint64 size, GLenum handleType, GLint fd); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glImportMemoryFdEXT (GLuint memory, GLuint64 size, GLenum handleType, GLint fd); +#endif +#endif /* GL_EXT_memory_object_fd */ + +#ifndef GL_EXT_memory_object_win32 +#define GL_EXT_memory_object_win32 1 +#define GL_HANDLE_TYPE_OPAQUE_WIN32_EXT 0x9587 +#define GL_HANDLE_TYPE_OPAQUE_WIN32_KMT_EXT 0x9588 +#define GL_DEVICE_LUID_EXT 0x9599 +#define GL_DEVICE_NODE_MASK_EXT 0x959A +#define GL_LUID_SIZE_EXT 8 +#define GL_HANDLE_TYPE_D3D12_TILEPOOL_EXT 0x9589 +#define GL_HANDLE_TYPE_D3D12_RESOURCE_EXT 0x958A +#define GL_HANDLE_TYPE_D3D11_IMAGE_EXT 0x958B +#define GL_HANDLE_TYPE_D3D11_IMAGE_KMT_EXT 0x958C +typedef void (APIENTRYP PFNGLIMPORTMEMORYWIN32HANDLEEXTPROC) (GLuint memory, GLuint64 size, GLenum handleType, void *handle); +typedef void (APIENTRYP PFNGLIMPORTMEMORYWIN32NAMEEXTPROC) (GLuint memory, GLuint64 size, GLenum handleType, const void *name); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glImportMemoryWin32HandleEXT (GLuint memory, GLuint64 size, GLenum handleType, void *handle); +GLAPI void APIENTRY glImportMemoryWin32NameEXT (GLuint memory, GLuint64 size, GLenum handleType, const void *name); +#endif +#endif /* GL_EXT_memory_object_win32 */ + #ifndef GL_EXT_misc_attribute #define GL_EXT_misc_attribute 1 #endif /* GL_EXT_misc_attribute */ @@ -7600,6 +7996,55 @@ GLAPI void APIENTRY glSecondaryColorPointerEXT (GLint size, GLenum type, GLsizei #endif #endif /* GL_EXT_secondary_color */ +#ifndef GL_EXT_semaphore +#define GL_EXT_semaphore 1 +#define GL_LAYOUT_GENERAL_EXT 0x958D +#define GL_LAYOUT_COLOR_ATTACHMENT_EXT 0x958E +#define GL_LAYOUT_DEPTH_STENCIL_ATTACHMENT_EXT 0x958F +#define GL_LAYOUT_DEPTH_STENCIL_READ_ONLY_EXT 0x9590 +#define GL_LAYOUT_SHADER_READ_ONLY_EXT 0x9591 +#define GL_LAYOUT_TRANSFER_SRC_EXT 0x9592 +#define GL_LAYOUT_TRANSFER_DST_EXT 0x9593 +#define GL_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_EXT 0x9530 +#define GL_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_EXT 0x9531 +typedef void (APIENTRYP PFNGLGENSEMAPHORESEXTPROC) (GLsizei n, GLuint *semaphores); +typedef void (APIENTRYP PFNGLDELETESEMAPHORESEXTPROC) (GLsizei n, const GLuint *semaphores); +typedef GLboolean (APIENTRYP PFNGLISSEMAPHOREEXTPROC) (GLuint semaphore); +typedef void (APIENTRYP PFNGLSEMAPHOREPARAMETERUI64VEXTPROC) (GLuint semaphore, GLenum pname, const GLuint64 *params); +typedef void (APIENTRYP PFNGLGETSEMAPHOREPARAMETERUI64VEXTPROC) (GLuint semaphore, GLenum pname, GLuint64 *params); +typedef void (APIENTRYP PFNGLWAITSEMAPHOREEXTPROC) (GLuint semaphore, GLuint numBufferBarriers, const GLuint *buffers, GLuint numTextureBarriers, const GLuint *textures, const GLenum *srcLayouts); +typedef void (APIENTRYP PFNGLSIGNALSEMAPHOREEXTPROC) (GLuint semaphore, GLuint numBufferBarriers, const GLuint *buffers, GLuint numTextureBarriers, const GLuint *textures, const GLenum *dstLayouts); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glGenSemaphoresEXT (GLsizei n, GLuint *semaphores); +GLAPI void APIENTRY glDeleteSemaphoresEXT (GLsizei n, const GLuint *semaphores); +GLAPI GLboolean APIENTRY glIsSemaphoreEXT (GLuint semaphore); +GLAPI void APIENTRY glSemaphoreParameterui64vEXT (GLuint semaphore, GLenum pname, const GLuint64 *params); +GLAPI void APIENTRY glGetSemaphoreParameterui64vEXT (GLuint semaphore, GLenum pname, GLuint64 *params); +GLAPI void APIENTRY glWaitSemaphoreEXT (GLuint semaphore, GLuint numBufferBarriers, const GLuint *buffers, GLuint numTextureBarriers, const GLuint *textures, const GLenum *srcLayouts); +GLAPI void APIENTRY glSignalSemaphoreEXT (GLuint semaphore, GLuint numBufferBarriers, const GLuint *buffers, GLuint numTextureBarriers, const GLuint *textures, const GLenum *dstLayouts); +#endif +#endif /* GL_EXT_semaphore */ + +#ifndef GL_EXT_semaphore_fd +#define GL_EXT_semaphore_fd 1 +typedef void (APIENTRYP PFNGLIMPORTSEMAPHOREFDEXTPROC) (GLuint semaphore, GLenum handleType, GLint fd); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glImportSemaphoreFdEXT (GLuint semaphore, GLenum handleType, GLint fd); +#endif +#endif /* GL_EXT_semaphore_fd */ + +#ifndef GL_EXT_semaphore_win32 +#define GL_EXT_semaphore_win32 1 +#define GL_HANDLE_TYPE_D3D12_FENCE_EXT 0x9594 +#define GL_D3D12_FENCE_VALUE_EXT 0x9595 +typedef void (APIENTRYP PFNGLIMPORTSEMAPHOREWIN32HANDLEEXTPROC) (GLuint semaphore, GLenum handleType, void *handle); +typedef void (APIENTRYP PFNGLIMPORTSEMAPHOREWIN32NAMEEXTPROC) (GLuint semaphore, GLenum handleType, const void *name); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glImportSemaphoreWin32HandleEXT (GLuint semaphore, GLenum handleType, void *handle); +GLAPI void APIENTRY glImportSemaphoreWin32NameEXT (GLuint semaphore, GLenum handleType, const void *name); +#endif +#endif /* GL_EXT_semaphore_win32 */ + #ifndef GL_EXT_separate_shader_objects #define GL_EXT_separate_shader_objects 1 #define GL_ACTIVE_PROGRAM_EXT 0x8B8D @@ -7620,6 +8065,19 @@ GLAPI GLuint APIENTRY glCreateShaderProgramEXT (GLenum type, const GLchar *strin #define GL_SEPARATE_SPECULAR_COLOR_EXT 0x81FA #endif /* GL_EXT_separate_specular_color */ +#ifndef GL_EXT_shader_framebuffer_fetch +#define GL_EXT_shader_framebuffer_fetch 1 +#define GL_FRAGMENT_SHADER_DISCARDS_SAMPLES_EXT 0x8A52 +#endif /* GL_EXT_shader_framebuffer_fetch */ + +#ifndef GL_EXT_shader_framebuffer_fetch_non_coherent +#define GL_EXT_shader_framebuffer_fetch_non_coherent 1 +typedef void (APIENTRYP PFNGLFRAMEBUFFERFETCHBARRIEREXTPROC) (void); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glFramebufferFetchBarrierEXT (void); +#endif +#endif /* GL_EXT_shader_framebuffer_fetch_non_coherent */ + #ifndef GL_EXT_shader_image_load_formatted #define GL_EXT_shader_image_load_formatted 1 #endif /* GL_EXT_shader_image_load_formatted */ @@ -7920,6 +8378,8 @@ GLAPI void APIENTRY glTexBufferEXT (GLenum target, GLenum internalformat, GLuint #ifndef GL_EXT_texture_filter_minmax #define GL_EXT_texture_filter_minmax 1 +#define GL_TEXTURE_REDUCTION_MODE_EXT 0x9366 +#define GL_WEIGHTED_AVERAGE_EXT 0x9367 #endif /* GL_EXT_texture_filter_minmax */ #ifndef GL_EXT_texture_integer @@ -8466,6 +8926,30 @@ GLAPI void APIENTRY glVertexWeightPointerEXT (GLint size, GLenum type, GLsizei s #endif #endif /* GL_EXT_vertex_weighting */ +#ifndef GL_EXT_win32_keyed_mutex +#define GL_EXT_win32_keyed_mutex 1 +typedef GLboolean (APIENTRYP PFNGLACQUIREKEYEDMUTEXWIN32EXTPROC) (GLuint memory, GLuint64 key, GLuint timeout); +typedef GLboolean (APIENTRYP PFNGLRELEASEKEYEDMUTEXWIN32EXTPROC) (GLuint memory, GLuint64 key); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI GLboolean APIENTRY glAcquireKeyedMutexWin32EXT (GLuint memory, GLuint64 key, GLuint timeout); +GLAPI GLboolean APIENTRY glReleaseKeyedMutexWin32EXT (GLuint memory, GLuint64 key); +#endif +#endif /* GL_EXT_win32_keyed_mutex */ + +#ifndef GL_EXT_window_rectangles +#define GL_EXT_window_rectangles 1 +#define GL_INCLUSIVE_EXT 0x8F10 +#define GL_EXCLUSIVE_EXT 0x8F11 +#define GL_WINDOW_RECTANGLE_EXT 0x8F12 +#define GL_WINDOW_RECTANGLE_MODE_EXT 0x8F13 +#define GL_MAX_WINDOW_RECTANGLES_EXT 0x8F14 +#define GL_NUM_WINDOW_RECTANGLES_EXT 0x8F15 +typedef void (APIENTRYP PFNGLWINDOWRECTANGLESEXTPROC) (GLenum mode, GLsizei count, const GLint *box); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glWindowRectanglesEXT (GLenum mode, GLsizei count, const GLint *box); +#endif +#endif /* GL_EXT_window_rectangles */ + #ifndef GL_EXT_x11_sync_object #define GL_EXT_x11_sync_object 1 #define GL_SYNC_X11_FENCE_EXT 0x90E1 @@ -8643,10 +9127,28 @@ GLAPI void APIENTRY glBlendFuncSeparateINGR (GLenum sfactorRGB, GLenum dfactorRG #define GL_INTERLACE_READ_INGR 0x8568 #endif /* GL_INGR_interlace_read */ +#ifndef GL_INTEL_blackhole_render +#define GL_INTEL_blackhole_render 1 +#define GL_BLACKHOLE_RENDER_INTEL 0x83FC +#endif /* GL_INTEL_blackhole_render */ + +#ifndef GL_INTEL_conservative_rasterization +#define GL_INTEL_conservative_rasterization 1 +#define GL_CONSERVATIVE_RASTERIZATION_INTEL 0x83FE +#endif /* GL_INTEL_conservative_rasterization */ + #ifndef GL_INTEL_fragment_shader_ordering #define GL_INTEL_fragment_shader_ordering 1 #endif /* GL_INTEL_fragment_shader_ordering */ +#ifndef GL_INTEL_framebuffer_CMAA +#define GL_INTEL_framebuffer_CMAA 1 +typedef void (APIENTRYP PFNGLAPPLYFRAMEBUFFERATTACHMENTCMAAINTELPROC) (void); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glApplyFramebufferAttachmentCMAAINTEL (void); +#endif +#endif /* GL_INTEL_framebuffer_CMAA */ + #ifndef GL_INTEL_map_texture #define GL_INTEL_map_texture 1 #define GL_TEXTURE_MEMORY_LAYOUT_INTEL 0x83FF @@ -8711,7 +9213,7 @@ typedef void (APIENTRYP PFNGLENDPERFQUERYINTELPROC) (GLuint queryHandle); typedef void (APIENTRYP PFNGLGETFIRSTPERFQUERYIDINTELPROC) (GLuint *queryId); typedef void (APIENTRYP PFNGLGETNEXTPERFQUERYIDINTELPROC) (GLuint queryId, GLuint *nextQueryId); typedef void (APIENTRYP PFNGLGETPERFCOUNTERINFOINTELPROC) (GLuint queryId, GLuint counterId, GLuint counterNameLength, GLchar *counterName, GLuint counterDescLength, GLchar *counterDesc, GLuint *counterOffset, GLuint *counterDataSize, GLuint *counterTypeEnum, GLuint *counterDataTypeEnum, GLuint64 *rawCounterMaxValue); -typedef void (APIENTRYP PFNGLGETPERFQUERYDATAINTELPROC) (GLuint queryHandle, GLuint flags, GLsizei dataSize, GLvoid *data, GLuint *bytesWritten); +typedef void (APIENTRYP PFNGLGETPERFQUERYDATAINTELPROC) (GLuint queryHandle, GLuint flags, GLsizei dataSize, void *data, GLuint *bytesWritten); typedef void (APIENTRYP PFNGLGETPERFQUERYIDBYNAMEINTELPROC) (GLchar *queryName, GLuint *queryId); typedef void (APIENTRYP PFNGLGETPERFQUERYINFOINTELPROC) (GLuint queryId, GLuint queryNameLength, GLchar *queryName, GLuint *dataSize, GLuint *noCounters, GLuint *noInstances, GLuint *capsMask); #ifdef GL_GLEXT_PROTOTYPES @@ -8722,7 +9224,7 @@ GLAPI void APIENTRY glEndPerfQueryINTEL (GLuint queryHandle); GLAPI void APIENTRY glGetFirstPerfQueryIdINTEL (GLuint *queryId); GLAPI void APIENTRY glGetNextPerfQueryIdINTEL (GLuint queryId, GLuint *nextQueryId); GLAPI void APIENTRY glGetPerfCounterInfoINTEL (GLuint queryId, GLuint counterId, GLuint counterNameLength, GLchar *counterName, GLuint counterDescLength, GLchar *counterDesc, GLuint *counterOffset, GLuint *counterDataSize, GLuint *counterTypeEnum, GLuint *counterDataTypeEnum, GLuint64 *rawCounterMaxValue); -GLAPI void APIENTRY glGetPerfQueryDataINTEL (GLuint queryHandle, GLuint flags, GLsizei dataSize, GLvoid *data, GLuint *bytesWritten); +GLAPI void APIENTRY glGetPerfQueryDataINTEL (GLuint queryHandle, GLuint flags, GLsizei dataSize, void *data, GLuint *bytesWritten); GLAPI void APIENTRY glGetPerfQueryIdByNameINTEL (GLchar *queryName, GLuint *queryId); GLAPI void APIENTRY glGetPerfQueryInfoINTEL (GLuint queryId, GLuint queryNameLength, GLchar *queryName, GLuint *dataSize, GLuint *noCounters, GLuint *noInstances, GLuint *capsMask); #endif @@ -8743,6 +9245,11 @@ GLAPI void APIENTRY glGetPerfQueryInfoINTEL (GLuint queryId, GLuint queryNameLen #define GL_PACK_INVERT_MESA 0x8758 #endif /* GL_MESA_pack_invert */ +#ifndef GL_MESA_program_binary_formats +#define GL_MESA_program_binary_formats 1 +#define GL_PROGRAM_BINARY_FORMAT_MESA 0x875F +#endif /* GL_MESA_program_binary_formats */ + #ifndef GL_MESA_resize_buffers #define GL_MESA_resize_buffers 1 typedef void (APIENTRYP PFNGLRESIZEBUFFERSMESAPROC) (void); @@ -8751,6 +9258,17 @@ GLAPI void APIENTRY glResizeBuffersMESA (void); #endif #endif /* GL_MESA_resize_buffers */ +#ifndef GL_MESA_shader_integer_functions +#define GL_MESA_shader_integer_functions 1 +#endif /* GL_MESA_shader_integer_functions */ + +#ifndef GL_MESA_tile_raster_order +#define GL_MESA_tile_raster_order 1 +#define GL_TILE_RASTER_ORDER_FIXED_MESA 0x8BB8 +#define GL_TILE_RASTER_ORDER_INCREASING_X_MESA 0x8BB9 +#define GL_TILE_RASTER_ORDER_INCREASING_Y_MESA 0x8BBA +#endif /* GL_MESA_tile_raster_order */ + #ifndef GL_MESA_window_pos #define GL_MESA_window_pos 1 typedef void (APIENTRYP PFNGLWINDOWPOS2DMESAPROC) (GLdouble x, GLdouble y); @@ -8812,6 +9330,10 @@ GLAPI void APIENTRY glWindowPos4svMESA (const GLshort *v); #define GL_YCBCR_MESA 0x8757 #endif /* GL_MESA_ycbcr_texture */ +#ifndef GL_NVX_blend_equation_advanced_multi_draw_buffers +#define GL_NVX_blend_equation_advanced_multi_draw_buffers 1 +#endif /* GL_NVX_blend_equation_advanced_multi_draw_buffers */ + #ifndef GL_NVX_conditional_render #define GL_NVX_conditional_render 1 typedef void (APIENTRYP PFNGLBEGINCONDITIONALRENDERNVXPROC) (GLuint id); @@ -8831,6 +9353,32 @@ GLAPI void APIENTRY glEndConditionalRenderNVX (void); #define GL_GPU_MEMORY_INFO_EVICTED_MEMORY_NVX 0x904B #endif /* GL_NVX_gpu_memory_info */ +#ifndef GL_NVX_linked_gpu_multicast +#define GL_NVX_linked_gpu_multicast 1 +#define GL_LGPU_SEPARATE_STORAGE_BIT_NVX 0x0800 +#define GL_MAX_LGPU_GPUS_NVX 0x92BA +typedef void (APIENTRYP PFNGLLGPUNAMEDBUFFERSUBDATANVXPROC) (GLbitfield gpuMask, GLuint buffer, GLintptr offset, GLsizeiptr size, const void *data); +typedef void (APIENTRYP PFNGLLGPUCOPYIMAGESUBDATANVXPROC) (GLuint sourceGpu, GLbitfield destinationGpuMask, GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srxY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei width, GLsizei height, GLsizei depth); +typedef void (APIENTRYP PFNGLLGPUINTERLOCKNVXPROC) (void); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glLGPUNamedBufferSubDataNVX (GLbitfield gpuMask, GLuint buffer, GLintptr offset, GLsizeiptr size, const void *data); +GLAPI void APIENTRY glLGPUCopyImageSubDataNVX (GLuint sourceGpu, GLbitfield destinationGpuMask, GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srxY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei width, GLsizei height, GLsizei depth); +GLAPI void APIENTRY glLGPUInterlockNVX (void); +#endif +#endif /* GL_NVX_linked_gpu_multicast */ + +#ifndef GL_NV_alpha_to_coverage_dither_control +#define GL_NV_alpha_to_coverage_dither_control 1 +#define GL_ALPHA_TO_COVERAGE_DITHER_DEFAULT_NV 0x934D +#define GL_ALPHA_TO_COVERAGE_DITHER_ENABLE_NV 0x934E +#define GL_ALPHA_TO_COVERAGE_DITHER_DISABLE_NV 0x934F +#define GL_ALPHA_TO_COVERAGE_DITHER_MODE_NV 0x92BF +typedef void (APIENTRYP PFNGLALPHATOCOVERAGEDITHERCONTROLNVPROC) (GLenum mode); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glAlphaToCoverageDitherControlNV (GLenum mode); +#endif +#endif /* GL_NV_alpha_to_coverage_dither_control */ + #ifndef GL_NV_bindless_multi_draw_indirect #define GL_NV_bindless_multi_draw_indirect 1 typedef void (APIENTRYP PFNGLMULTIDRAWARRAYSINDIRECTBINDLESSNVPROC) (GLenum mode, const void *indirect, GLsizei drawCount, GLsizei stride, GLint vertexBufferCount); @@ -8947,10 +9495,25 @@ GLAPI void APIENTRY glBlendBarrierNV (void); #define GL_BLEND_ADVANCED_COHERENT_NV 0x9285 #endif /* GL_NV_blend_equation_advanced_coherent */ +#ifndef GL_NV_blend_minmax_factor +#define GL_NV_blend_minmax_factor 1 +#endif /* GL_NV_blend_minmax_factor */ + #ifndef GL_NV_blend_square #define GL_NV_blend_square 1 #endif /* GL_NV_blend_square */ +#ifndef GL_NV_clip_space_w_scaling +#define GL_NV_clip_space_w_scaling 1 +#define GL_VIEWPORT_POSITION_W_SCALE_NV 0x937C +#define GL_VIEWPORT_POSITION_W_SCALE_X_COEFF_NV 0x937D +#define GL_VIEWPORT_POSITION_W_SCALE_Y_COEFF_NV 0x937E +typedef void (APIENTRYP PFNGLVIEWPORTPOSITIONWSCALENVPROC) (GLuint index, GLfloat xcoeff, GLfloat ycoeff); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glViewportPositionWScaleNV (GLuint index, GLfloat xcoeff, GLfloat ycoeff); +#endif +#endif /* GL_NV_clip_space_w_scaling */ + #ifndef GL_NV_command_list #define GL_NV_command_list 1 #define GL_TERMINATE_SEQUENCE_COMMAND_NV 0x0000 @@ -9053,6 +9616,26 @@ GLAPI void APIENTRY glConservativeRasterParameterfNV (GLenum pname, GLfloat valu #endif #endif /* GL_NV_conservative_raster_dilate */ +#ifndef GL_NV_conservative_raster_pre_snap +#define GL_NV_conservative_raster_pre_snap 1 +#define GL_CONSERVATIVE_RASTER_MODE_PRE_SNAP_NV 0x9550 +#endif /* GL_NV_conservative_raster_pre_snap */ + +#ifndef GL_NV_conservative_raster_pre_snap_triangles +#define GL_NV_conservative_raster_pre_snap_triangles 1 +#define GL_CONSERVATIVE_RASTER_MODE_NV 0x954D +#define GL_CONSERVATIVE_RASTER_MODE_POST_SNAP_NV 0x954E +#define GL_CONSERVATIVE_RASTER_MODE_PRE_SNAP_TRIANGLES_NV 0x954F +typedef void (APIENTRYP PFNGLCONSERVATIVERASTERPARAMETERINVPROC) (GLenum pname, GLint param); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glConservativeRasterParameteriNV (GLenum pname, GLint param); +#endif +#endif /* GL_NV_conservative_raster_pre_snap_triangles */ + +#ifndef GL_NV_conservative_raster_underestimation +#define GL_NV_conservative_raster_underestimation 1 +#endif /* GL_NV_conservative_raster_underestimation */ + #ifndef GL_NV_copy_depth_to_color #define GL_NV_copy_depth_to_color 1 #define GL_DEPTH_STENCIL_TO_RGBA_NV 0x886E @@ -9102,6 +9685,23 @@ GLAPI void APIENTRY glDrawTextureNV (GLuint texture, GLuint sampler, GLfloat x0, #endif #endif /* GL_NV_draw_texture */ +#ifndef GL_NV_draw_vulkan_image +#define GL_NV_draw_vulkan_image 1 +typedef void (APIENTRY *GLVULKANPROCNV)(void); +typedef void (APIENTRYP PFNGLDRAWVKIMAGENVPROC) (GLuint64 vkImage, GLuint sampler, GLfloat x0, GLfloat y0, GLfloat x1, GLfloat y1, GLfloat z, GLfloat s0, GLfloat t0, GLfloat s1, GLfloat t1); +typedef GLVULKANPROCNV (APIENTRYP PFNGLGETVKPROCADDRNVPROC) (const GLchar *name); +typedef void (APIENTRYP PFNGLWAITVKSEMAPHORENVPROC) (GLuint64 vkSemaphore); +typedef void (APIENTRYP PFNGLSIGNALVKSEMAPHORENVPROC) (GLuint64 vkSemaphore); +typedef void (APIENTRYP PFNGLSIGNALVKFENCENVPROC) (GLuint64 vkFence); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glDrawVkImageNV (GLuint64 vkImage, GLuint sampler, GLfloat x0, GLfloat y0, GLfloat x1, GLfloat y1, GLfloat z, GLfloat s0, GLfloat t0, GLfloat s1, GLfloat t1); +GLAPI GLVULKANPROCNV APIENTRY glGetVkProcAddrNV (const GLchar *name); +GLAPI void APIENTRY glWaitVkSemaphoreNV (GLuint64 vkSemaphore); +GLAPI void APIENTRY glSignalVkSemaphoreNV (GLuint64 vkSemaphore); +GLAPI void APIENTRY glSignalVkFenceNV (GLuint64 vkFence); +#endif +#endif /* GL_NV_draw_vulkan_image */ + #ifndef GL_NV_evaluators #define GL_NV_evaluators 1 #define GL_EVAL_2D_NV 0x86C0 @@ -9336,6 +9936,41 @@ GLAPI void APIENTRY glFramebufferTextureFaceEXT (GLenum target, GLenum attachmen #define GL_NV_geometry_shader_passthrough 1 #endif /* GL_NV_geometry_shader_passthrough */ +#ifndef GL_NV_gpu_multicast +#define GL_NV_gpu_multicast 1 +#define GL_PER_GPU_STORAGE_BIT_NV 0x0800 +#define GL_MULTICAST_GPUS_NV 0x92BA +#define GL_RENDER_GPU_MASK_NV 0x9558 +#define GL_PER_GPU_STORAGE_NV 0x9548 +#define GL_MULTICAST_PROGRAMMABLE_SAMPLE_LOCATION_NV 0x9549 +typedef void (APIENTRYP PFNGLRENDERGPUMASKNVPROC) (GLbitfield mask); +typedef void (APIENTRYP PFNGLMULTICASTBUFFERSUBDATANVPROC) (GLbitfield gpuMask, GLuint buffer, GLintptr offset, GLsizeiptr size, const void *data); +typedef void (APIENTRYP PFNGLMULTICASTCOPYBUFFERSUBDATANVPROC) (GLuint readGpu, GLbitfield writeGpuMask, GLuint readBuffer, GLuint writeBuffer, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); +typedef void (APIENTRYP PFNGLMULTICASTCOPYIMAGESUBDATANVPROC) (GLuint srcGpu, GLbitfield dstGpuMask, GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth); +typedef void (APIENTRYP PFNGLMULTICASTBLITFRAMEBUFFERNVPROC) (GLuint srcGpu, GLuint dstGpu, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); +typedef void (APIENTRYP PFNGLMULTICASTFRAMEBUFFERSAMPLELOCATIONSFVNVPROC) (GLuint gpu, GLuint framebuffer, GLuint start, GLsizei count, const GLfloat *v); +typedef void (APIENTRYP PFNGLMULTICASTBARRIERNVPROC) (void); +typedef void (APIENTRYP PFNGLMULTICASTWAITSYNCNVPROC) (GLuint signalGpu, GLbitfield waitGpuMask); +typedef void (APIENTRYP PFNGLMULTICASTGETQUERYOBJECTIVNVPROC) (GLuint gpu, GLuint id, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLMULTICASTGETQUERYOBJECTUIVNVPROC) (GLuint gpu, GLuint id, GLenum pname, GLuint *params); +typedef void (APIENTRYP PFNGLMULTICASTGETQUERYOBJECTI64VNVPROC) (GLuint gpu, GLuint id, GLenum pname, GLint64 *params); +typedef void (APIENTRYP PFNGLMULTICASTGETQUERYOBJECTUI64VNVPROC) (GLuint gpu, GLuint id, GLenum pname, GLuint64 *params); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glRenderGpuMaskNV (GLbitfield mask); +GLAPI void APIENTRY glMulticastBufferSubDataNV (GLbitfield gpuMask, GLuint buffer, GLintptr offset, GLsizeiptr size, const void *data); +GLAPI void APIENTRY glMulticastCopyBufferSubDataNV (GLuint readGpu, GLbitfield writeGpuMask, GLuint readBuffer, GLuint writeBuffer, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); +GLAPI void APIENTRY glMulticastCopyImageSubDataNV (GLuint srcGpu, GLbitfield dstGpuMask, GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth); +GLAPI void APIENTRY glMulticastBlitFramebufferNV (GLuint srcGpu, GLuint dstGpu, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); +GLAPI void APIENTRY glMulticastFramebufferSampleLocationsfvNV (GLuint gpu, GLuint framebuffer, GLuint start, GLsizei count, const GLfloat *v); +GLAPI void APIENTRY glMulticastBarrierNV (void); +GLAPI void APIENTRY glMulticastWaitSyncNV (GLuint signalGpu, GLbitfield waitGpuMask); +GLAPI void APIENTRY glMulticastGetQueryObjectivNV (GLuint gpu, GLuint id, GLenum pname, GLint *params); +GLAPI void APIENTRY glMulticastGetQueryObjectuivNV (GLuint gpu, GLuint id, GLenum pname, GLuint *params); +GLAPI void APIENTRY glMulticastGetQueryObjecti64vNV (GLuint gpu, GLuint id, GLenum pname, GLint64 *params); +GLAPI void APIENTRY glMulticastGetQueryObjectui64vNV (GLuint gpu, GLuint id, GLenum pname, GLuint64 *params); +#endif +#endif /* GL_NV_gpu_multicast */ + #ifndef GL_NV_gpu_program4 #define GL_NV_gpu_program4 1 #define GL_MIN_PROGRAM_TEXEL_OFFSET_NV 0x8904 @@ -9953,6 +10588,32 @@ GLAPI void APIENTRY glPrimitiveRestartIndexNV (GLuint index); #endif #endif /* GL_NV_primitive_restart */ +#ifndef GL_NV_query_resource +#define GL_NV_query_resource 1 +#define GL_QUERY_RESOURCE_TYPE_VIDMEM_ALLOC_NV 0x9540 +#define GL_QUERY_RESOURCE_MEMTYPE_VIDMEM_NV 0x9542 +#define GL_QUERY_RESOURCE_SYS_RESERVED_NV 0x9544 +#define GL_QUERY_RESOURCE_TEXTURE_NV 0x9545 +#define GL_QUERY_RESOURCE_RENDERBUFFER_NV 0x9546 +#define GL_QUERY_RESOURCE_BUFFEROBJECT_NV 0x9547 +typedef GLint (APIENTRYP PFNGLQUERYRESOURCENVPROC) (GLenum queryType, GLint tagId, GLuint bufSize, GLint *buffer); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI GLint APIENTRY glQueryResourceNV (GLenum queryType, GLint tagId, GLuint bufSize, GLint *buffer); +#endif +#endif /* GL_NV_query_resource */ + +#ifndef GL_NV_query_resource_tag +#define GL_NV_query_resource_tag 1 +typedef void (APIENTRYP PFNGLGENQUERYRESOURCETAGNVPROC) (GLsizei n, GLint *tagIds); +typedef void (APIENTRYP PFNGLDELETEQUERYRESOURCETAGNVPROC) (GLsizei n, const GLint *tagIds); +typedef void (APIENTRYP PFNGLQUERYRESOURCETAGNVPROC) (GLint tagId, const GLchar *tagString); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glGenQueryResourceTagNV (GLsizei n, GLint *tagIds); +GLAPI void APIENTRY glDeleteQueryResourceTagNV (GLsizei n, const GLint *tagIds); +GLAPI void APIENTRY glQueryResourceTagNV (GLint tagId, const GLchar *tagString); +#endif +#endif /* GL_NV_query_resource_tag */ + #ifndef GL_NV_register_combiners #define GL_NV_register_combiners 1 #define GL_REGISTER_COMBINERS_NV 0x8522 @@ -10045,6 +10706,11 @@ GLAPI void APIENTRY glGetCombinerStageParameterfvNV (GLenum stage, GLenum pname, #endif #endif /* GL_NV_register_combiners2 */ +#ifndef GL_NV_robustness_video_memory_purge +#define GL_NV_robustness_video_memory_purge 1 +#define GL_PURGED_CONTEXT_RESET_NV 0x92BB +#endif /* GL_NV_robustness_video_memory_purge */ + #ifndef GL_NV_sample_locations #define GL_NV_sample_locations 1 #define GL_SAMPLE_LOCATION_SUBPIXEL_BITS_NV 0x933D @@ -10077,6 +10743,10 @@ GLAPI void APIENTRY glResolveDepthValuesNV (void); #define GL_NV_shader_atomic_float 1 #endif /* GL_NV_shader_atomic_float */ +#ifndef GL_NV_shader_atomic_float64 +#define GL_NV_shader_atomic_float64 1 +#endif /* GL_NV_shader_atomic_float64 */ + #ifndef GL_NV_shader_atomic_fp16_vector #define GL_NV_shader_atomic_fp16_vector 1 #endif /* GL_NV_shader_atomic_fp16_vector */ @@ -10140,6 +10810,10 @@ GLAPI void APIENTRY glProgramUniformui64vNV (GLuint program, GLint location, GLs #define GL_NV_shader_thread_shuffle 1 #endif /* GL_NV_shader_thread_shuffle */ +#ifndef GL_NV_stereo_view_rendering +#define GL_NV_stereo_view_rendering 1 +#endif /* GL_NV_stereo_view_rendering */ + #ifndef GL_NV_tessellation_program5 #define GL_NV_tessellation_program5 1 #define GL_MAX_PROGRAM_PATCH_ATTRIBS_NV 0x86D8 @@ -10216,6 +10890,10 @@ GLAPI void APIENTRY glTextureImage3DMultisampleCoverageNV (GLuint texture, GLenu #define GL_MAX_RECTANGLE_TEXTURE_SIZE_NV 0x84F8 #endif /* GL_NV_texture_rectangle */ +#ifndef GL_NV_texture_rectangle_compressed +#define GL_NV_texture_rectangle_compressed 1 +#endif /* GL_NV_texture_rectangle_compressed */ + #ifndef GL_NV_texture_shader #define GL_NV_texture_shader 1 #define GL_OFFSET_TEXTURE_RECTANGLE_NV 0x864C @@ -10879,7 +11557,7 @@ GLAPI void APIENTRY glGetVertexAttribIuivEXT (GLuint index, GLenum pname, GLuint #define GL_VIDEO_CAPTURE_FIELD_LOWER_HEIGHT_NV 0x903B #define GL_VIDEO_CAPTURE_SURFACE_ORIGIN_NV 0x903C typedef void (APIENTRYP PFNGLBEGINVIDEOCAPTURENVPROC) (GLuint video_capture_slot); -typedef void (APIENTRYP PFNGLBINDVIDEOCAPTURESTREAMBUFFERNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum frame_region, GLintptr offset); +typedef void (APIENTRYP PFNGLBINDVIDEOCAPTURESTREAMBUFFERNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum frame_region, GLintptrARB offset); typedef void (APIENTRYP PFNGLBINDVIDEOCAPTURESTREAMTEXTURENVPROC) (GLuint video_capture_slot, GLuint stream, GLenum frame_region, GLenum target, GLuint texture); typedef void (APIENTRYP PFNGLENDVIDEOCAPTURENVPROC) (GLuint video_capture_slot); typedef void (APIENTRYP PFNGLGETVIDEOCAPTUREIVNVPROC) (GLuint video_capture_slot, GLenum pname, GLint *params); @@ -10892,7 +11570,7 @@ typedef void (APIENTRYP PFNGLVIDEOCAPTURESTREAMPARAMETERFVNVPROC) (GLuint video_ typedef void (APIENTRYP PFNGLVIDEOCAPTURESTREAMPARAMETERDVNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum pname, const GLdouble *params); #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glBeginVideoCaptureNV (GLuint video_capture_slot); -GLAPI void APIENTRY glBindVideoCaptureStreamBufferNV (GLuint video_capture_slot, GLuint stream, GLenum frame_region, GLintptr offset); +GLAPI void APIENTRY glBindVideoCaptureStreamBufferNV (GLuint video_capture_slot, GLuint stream, GLenum frame_region, GLintptrARB offset); GLAPI void APIENTRY glBindVideoCaptureStreamTextureNV (GLuint video_capture_slot, GLuint stream, GLenum frame_region, GLenum target, GLuint texture); GLAPI void APIENTRY glEndVideoCaptureNV (GLuint video_capture_slot); GLAPI void APIENTRY glGetVideoCaptureivNV (GLuint video_capture_slot, GLenum pname, GLint *params); @@ -10910,6 +11588,26 @@ GLAPI void APIENTRY glVideoCaptureStreamParameterdvNV (GLuint video_capture_slot #define GL_NV_viewport_array2 1 #endif /* GL_NV_viewport_array2 */ +#ifndef GL_NV_viewport_swizzle +#define GL_NV_viewport_swizzle 1 +#define GL_VIEWPORT_SWIZZLE_POSITIVE_X_NV 0x9350 +#define GL_VIEWPORT_SWIZZLE_NEGATIVE_X_NV 0x9351 +#define GL_VIEWPORT_SWIZZLE_POSITIVE_Y_NV 0x9352 +#define GL_VIEWPORT_SWIZZLE_NEGATIVE_Y_NV 0x9353 +#define GL_VIEWPORT_SWIZZLE_POSITIVE_Z_NV 0x9354 +#define GL_VIEWPORT_SWIZZLE_NEGATIVE_Z_NV 0x9355 +#define GL_VIEWPORT_SWIZZLE_POSITIVE_W_NV 0x9356 +#define GL_VIEWPORT_SWIZZLE_NEGATIVE_W_NV 0x9357 +#define GL_VIEWPORT_SWIZZLE_X_NV 0x9358 +#define GL_VIEWPORT_SWIZZLE_Y_NV 0x9359 +#define GL_VIEWPORT_SWIZZLE_Z_NV 0x935A +#define GL_VIEWPORT_SWIZZLE_W_NV 0x935B +typedef void (APIENTRYP PFNGLVIEWPORTSWIZZLENVPROC) (GLuint index, GLenum swizzlex, GLenum swizzley, GLenum swizzlez, GLenum swizzlew); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glViewportSwizzleNV (GLuint index, GLenum swizzlex, GLenum swizzley, GLenum swizzlez, GLenum swizzlew); +#endif +#endif /* GL_NV_viewport_swizzle */ + #ifndef GL_OML_interlace #define GL_OML_interlace 1 #define GL_INTERLACE_OML 0x8980 @@ -10937,6 +11635,7 @@ GLAPI void APIENTRY glVideoCaptureStreamParameterdvNV (GLuint video_capture_slot #define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_NUM_VIEWS_OVR 0x9630 #define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_BASE_VIEW_INDEX_OVR 0x9632 #define GL_MAX_VIEWS_OVR 0x9631 +#define GL_FRAMEBUFFER_INCOMPLETE_VIEW_TARGETS_OVR 0x9633 typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTUREMULTIVIEWOVRPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint baseViewIndex, GLsizei numViews); #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glFramebufferTextureMultiviewOVR (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint baseViewIndex, GLsizei numViews); From ecfeae8a276cab954e37661269a27f814558a1ec Mon Sep 17 00:00:00 2001 From: rdb Date: Thu, 26 Jul 2018 13:50:54 +0200 Subject: [PATCH 057/125] shader: support double-precision vertex columns in GLSL --- panda/src/glstuff/glCgShaderContext_src.cxx | 22 +++++--- panda/src/glstuff/glShaderContext_src.cxx | 60 ++++++++++++++------- panda/src/gobj/shader.cxx | 27 ++++++++-- panda/src/gobj/shader.h | 20 +++---- 4 files changed, 86 insertions(+), 43 deletions(-) diff --git a/panda/src/glstuff/glCgShaderContext_src.cxx b/panda/src/glstuff/glCgShaderContext_src.cxx index fc1dac82ca..3a9b2fea6a 100644 --- a/panda/src/glstuff/glCgShaderContext_src.cxx +++ b/panda/src/glstuff/glCgShaderContext_src.cxx @@ -885,17 +885,21 @@ update_shader_vertex_arrays(ShaderContext *prev, bool force) { _glgsg->enable_vertex_attrib_array(p); - if (bind._integer) { - _glgsg->_glVertexAttribIPointer(p, num_values, type, - stride, client_pointer); - } else if (numeric_type == GeomEnums::NT_packed_dabc) { + if (numeric_type == GeomEnums::NT_packed_dabc) { // GL_BGRA is a special accepted value available since OpenGL 3.2. // It requires us to pass GL_TRUE for normalized. _glgsg->_glVertexAttribPointer(p, GL_BGRA, GL_UNSIGNED_BYTE, GL_TRUE, stride, client_pointer); - } else { + } else if (bind._numeric_type == Shader::SPT_float || + numeric_type == GeomEnums::NT_float32) { _glgsg->_glVertexAttribPointer(p, num_values, type, normalized, stride, client_pointer); + } else if (bind._numeric_type == Shader::SPT_double) { + _glgsg->_glVertexAttribLPointer(p, num_values, type, + stride, client_pointer); + } else { + _glgsg->_glVertexAttribIPointer(p, num_values, type, + stride, client_pointer); } if (divisor > 0) { @@ -952,10 +956,12 @@ update_shader_vertex_arrays(ShaderContext *prev, bool force) { // So, we work around this by just binding something silly to 0. // This breaks flat colors, but it's better than invisible objects? _glgsg->enable_vertex_attrib_array(0); - if (bind._integer) { - _glgsg->_glVertexAttribIPointer(0, 4, GL_INT, 0, 0); - } else { + if (bind._numeric_type == Shader::SPT_float) { _glgsg->_glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0); + } else if (bind._numeric_type == Shader::SPT_double) { + _glgsg->_glVertexAttribLPointer(0, 4, GL_DOUBLE, 0, 0); + } else { + _glgsg->_glVertexAttribIPointer(0, 4, GL_INT, 0, 0); } } else if (p >= 0) { diff --git a/panda/src/glstuff/glShaderContext_src.cxx b/panda/src/glstuff/glShaderContext_src.cxx index 979c6dada1..a96a07a2e8 100644 --- a/panda/src/glstuff/glShaderContext_src.cxx +++ b/panda/src/glstuff/glShaderContext_src.cxx @@ -426,18 +426,34 @@ reflect_attribute(int i, char *name_buffer, GLsizei name_buflen) { bind._elements = 1; // Check if this is an integer input- if so, we have to bind it differently. - bind._integer = (param_type == GL_BOOL || - param_type == GL_BOOL_VEC2 || - param_type == GL_BOOL_VEC3 || - param_type == GL_BOOL_VEC4 || - param_type == GL_INT || - param_type == GL_INT_VEC2 || - param_type == GL_INT_VEC3 || - param_type == GL_INT_VEC4 || - param_type == GL_UNSIGNED_INT_VEC2 || - param_type == GL_UNSIGNED_INT_VEC3 || - param_type == GL_UNSIGNED_INT_VEC4 || - param_type == GL_UNSIGNED_INT); + switch (param_type) { + case GL_INT: + case GL_INT_VEC2: + case GL_INT_VEC3: + case GL_INT_VEC4: + bind._numeric_type = Shader::SPT_int; + break; + case GL_BOOL: + case GL_BOOL_VEC2: + case GL_BOOL_VEC3: + case GL_BOOL_VEC4: + case GL_UNSIGNED_INT: + case GL_UNSIGNED_INT_VEC2: + case GL_UNSIGNED_INT_VEC3: + case GL_UNSIGNED_INT_VEC4: + bind._numeric_type = Shader::SPT_uint; + break; +#ifndef OPENGLES + case GL_DOUBLE: + case GL_DOUBLE_VEC2: + case GL_DOUBLE_VEC3: + case GL_DOUBLE_VEC4: + bind._numeric_type = Shader::SPT_double; + break; +#endif + default: + bind._numeric_type = Shader::SPT_float; + } // Check if it has a p3d_ prefix - if so, assign special meaning. if (strncmp(name_buffer, "p3d_", 4) == 0) { @@ -2264,7 +2280,7 @@ disable_shader_vertex_arrays() { return; } - for (int i=0; i<(int)_shader->_var_spec.size(); i++) { + for (size_t i = 0; i < _shader->_var_spec.size(); ++i) { const Shader::ShaderVarSpec &bind = _shader->_var_spec[i]; GLint p = bind._id._seqno; @@ -2389,21 +2405,25 @@ update_shader_vertex_arrays(ShaderContext *prev, bool force) { } client_pointer += start; + GLenum type = _glgsg->get_numeric_type(numeric_type); for (int i = 0; i < num_elements; ++i) { _glgsg->enable_vertex_attrib_array(p); - if (bind._integer) { - _glgsg->_glVertexAttribIPointer(p, num_values, _glgsg->get_numeric_type(numeric_type), - stride, client_pointer); - } else if (numeric_type == GeomEnums::NT_packed_dabc) { + if (numeric_type == GeomEnums::NT_packed_dabc) { // GL_BGRA is a special accepted value available since OpenGL 3.2. // It requires us to pass GL_TRUE for normalized. _glgsg->_glVertexAttribPointer(p, GL_BGRA, GL_UNSIGNED_BYTE, GL_TRUE, stride, client_pointer); - } else { - _glgsg->_glVertexAttribPointer(p, num_values, - _glgsg->get_numeric_type(numeric_type), + } else if (bind._numeric_type == Shader::SPT_float || + numeric_type == GeomEnums::NT_float32) { + _glgsg->_glVertexAttribPointer(p, num_values, type, normalized, stride, client_pointer); + } else if (bind._numeric_type == Shader::SPT_double) { + _glgsg->_glVertexAttribLPointer(p, num_values, type, + stride, client_pointer); + } else { + _glgsg->_glVertexAttribIPointer(p, num_values, type, + stride, client_pointer); } if (divisor > 0) { diff --git a/panda/src/gobj/shader.cxx b/panda/src/gobj/shader.cxx index 22a5389b8b..220bd56ed2 100644 --- a/panda/src/gobj/shader.cxx +++ b/panda/src/gobj/shader.cxx @@ -619,12 +619,29 @@ cg_recurse_parameters(CGparameter parameter, const ShaderType &type, p._type = arg_type; p._direction = arg_dir; p._varying = (vbl == CG_VARYING); - p._integer = (base_type == CG_UINT || base_type == CG_INT || - base_type == CG_ULONG || base_type == CG_LONG || - base_type == CG_USHORT || base_type == CG_SHORT || - base_type == CG_UCHAR || base_type == CG_CHAR); p._cat = shader_cat.get_safe_ptr(); + //NB. Cg does have a CG_DOUBLE type, but at least for the ARB + // profiles and GLSL profiles it just maps to float. + switch (base_type) { + case CG_UINT: + case CG_ULONG: + case CG_USHORT: + case CG_UCHAR: + case CG_BOOL: + p._numeric_type = SPT_uint; + break; + case CG_INT: + case CG_LONG: + case CG_SHORT: + case CG_CHAR: + p._numeric_type = SPT_int; + break; + default: + p._numeric_type = SPT_float; + break; + } + success &= compile_parameter(p, arg_dim); break; } @@ -681,7 +698,7 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) { ShaderVarSpec bind; bind._id = p._id; bind._append_uv = -1; - bind._integer = p._integer; + bind._numeric_type = p._numeric_type; if (pieces.size() == 2) { if (pieces[1] == "position") { diff --git a/panda/src/gobj/shader.h b/panda/src/gobj/shader.h index 1cc6533044..99b8d45e53 100644 --- a/panda/src/gobj/shader.h +++ b/panda/src/gobj/shader.h @@ -331,6 +331,14 @@ public: int _seqno; }; + enum ShaderPtrType { + SPT_float, + SPT_double, + SPT_int, + SPT_uint, + SPT_unknown + }; + struct ShaderArgInfo { ShaderArgId _id; ShaderArgClass _class; @@ -338,18 +346,10 @@ public: ShaderArgType _type; ShaderArgDir _direction; bool _varying; - bool _integer; + ShaderPtrType _numeric_type; NotifyCategory *_cat; }; - enum ShaderPtrType { - SPT_float, - SPT_double, - SPT_int, - SPT_uint, - SPT_unknown - }; - // Container structure for data of parameters ShaderPtrSpec. struct ShaderPtrData { private: @@ -425,7 +425,7 @@ public: PT(InternalName) _name; int _append_uv; int _elements; - bool _integer; + ShaderPtrType _numeric_type; }; struct ShaderPtrSpec { From c634c455fd737a0a55b0c1371f8ee73c1dae5e3e Mon Sep 17 00:00:00 2001 From: rdb Date: Thu, 26 Jul 2018 19:33:42 +0200 Subject: [PATCH 058/125] framework: add zero-argument version of open_framework() --- panda/src/framework/pandaFramework.cxx | 10 +++++++++- panda/src/framework/pandaFramework.h | 1 + 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/panda/src/framework/pandaFramework.cxx b/panda/src/framework/pandaFramework.cxx index 4dfbaee572..706ff4995d 100644 --- a/panda/src/framework/pandaFramework.cxx +++ b/panda/src/framework/pandaFramework.cxx @@ -82,7 +82,7 @@ PandaFramework:: * control parameters. */ void PandaFramework:: -open_framework(int &argc, char **&argv) { +open_framework() { if (_is_open) { return; } @@ -162,6 +162,14 @@ open_framework(int &argc, char **&argv) { _event_handler.add_hook("window-event", event_window_event, this); } +/** + * @deprecated See the version of open_framework() without arguments. + */ +void PandaFramework:: +open_framework(int &argc, char **&argv) { + open_framework(); +} + /** * Should be called at the end of an application to close Panda. This is * optional, as the destructor will do the same thing. diff --git a/panda/src/framework/pandaFramework.h b/panda/src/framework/pandaFramework.h index ef570a6c96..3c901d8e27 100644 --- a/panda/src/framework/pandaFramework.h +++ b/panda/src/framework/pandaFramework.h @@ -40,6 +40,7 @@ public: PandaFramework(); virtual ~PandaFramework(); + void open_framework(); void open_framework(int &argc, char **&argv); void close_framework(); From d081b4d4204ab022c94c9e250625a11d9e28682f Mon Sep 17 00:00:00 2001 From: rdb Date: Thu, 26 Jul 2018 19:34:23 +0200 Subject: [PATCH 059/125] mathutil: override plane.normalize() to be meaningful for planes Now it only divides by the length of the normal, rather than also adding in the square of the w component. --- panda/src/mathutil/plane_src.I | 31 +++++++++++++++++++++++++++++++ panda/src/mathutil/plane_src.h | 3 +++ 2 files changed, 34 insertions(+) diff --git a/panda/src/mathutil/plane_src.I b/panda/src/mathutil/plane_src.I index f357b34e60..7ea0acc828 100644 --- a/panda/src/mathutil/plane_src.I +++ b/panda/src/mathutil/plane_src.I @@ -137,6 +137,37 @@ dist_to_plane(const FLOATNAME(LPoint3) &point) const { return (_v(0) * point[0] + _v(1) * point[1] + _v(2) * point[2] + _v(3)); } +/** + * Normalizes the plane in place. Returns true if the plane was normalized, + * false if the plane had a zero-length normal vector. + */ +INLINE_MATHUTIL bool FLOATNAME(LPlane):: +normalize() { + FLOATTYPE l2 = get_normal().length_squared(); + if (l2 == (FLOATTYPE)0.0f) { + return false; + + } else if (!IS_THRESHOLD_EQUAL(l2, 1.0f, NEARLY_ZERO(FLOATTYPE) * NEARLY_ZERO(FLOATTYPE))) { + (*this) /= csqrt(l2); + } + + return true; +} + +/** + * Normalizes the plane and returns the normalized plane as a copy. If the + * plane's normal was a zero-length vector, the same plane is returned. + */ +INLINE_MATHUTIL FLOATNAME(LPlane) FLOATNAME(LPlane):: +normalized() const { + FLOATTYPE l2 = get_normal().length_squared(); + if (l2 != (FLOATTYPE)0.0f) { + return (*this) / csqrt(l2); + } else { + return (*this); + } +} + /** * Returns the point within the plane nearest to the indicated point in space. */ diff --git a/panda/src/mathutil/plane_src.h b/panda/src/mathutil/plane_src.h index c3301aa641..c1dffc4d5d 100644 --- a/panda/src/mathutil/plane_src.h +++ b/panda/src/mathutil/plane_src.h @@ -39,6 +39,9 @@ PUBLISHED: FLOATNAME(LPoint3) get_point() const; INLINE_MATHUTIL FLOATTYPE dist_to_plane(const FLOATNAME(LPoint3) &point) const; + + INLINE_MATHUTIL bool normalize(); + INLINE_MATHUTIL FLOATNAME(LPlane) normalized() const; INLINE_MATHUTIL FLOATNAME(LPoint3) project(const FLOATNAME(LPoint3) &point) const; INLINE_MATHUTIL void flip(); From 0f4168a3047c253ef1e0b7e55d7d3e1f9bc84203 Mon Sep 17 00:00:00 2001 From: rdb Date: Thu, 26 Jul 2018 19:35:57 +0200 Subject: [PATCH 060/125] text: use 64-bit coords in TextAssembler if vertices-float64 set --- panda/src/text/textAssembler.cxx | 114 +++++++++++++++---------------- 1 file changed, 57 insertions(+), 57 deletions(-) diff --git a/panda/src/text/textAssembler.cxx b/panda/src/text/textAssembler.cxx index bb3a789504..3925715c6d 100644 --- a/panda/src/text/textAssembler.cxx +++ b/panda/src/text/textAssembler.cxx @@ -1137,52 +1137,30 @@ generate_quads(GeomNode *geom_node, const QuadMap &quad_map) { GeomTextGlyph::Glyphs glyphs; glyphs.reserve(quads.size()); - static CPT(GeomVertexFormat) format; - if (format.is_null()) { - // The optimized code below assumes 32-bit floats, so let's make sure we - // got the right format by creating it ourselves. - format = GeomVertexFormat::register_format(new GeomVertexArrayFormat( - InternalName::get_vertex(), 3, GeomEnums::NT_float32, GeomEnums::C_point, - InternalName::get_texcoord(), 2, GeomEnums::NT_float32, GeomEnums::C_texcoord)); - } - + const GeomVertexFormat *format = GeomVertexFormat::get_v3t2(); PT(GeomVertexData) vdata = new GeomVertexData("text", format, Geom::UH_static); - PT(GeomTriangles) tris = new GeomTriangles(Geom::UH_static); - if (quads.size() > 10922) { - tris->set_index_type(GeomEnums::NT_uint32); - } else { - tris->set_index_type(GeomEnums::NT_uint16); - } - - int i = 0; + Thread *current_thread = Thread::get_current_thread(); // This is quite a critical loop and GeomVertexWriter quickly becomes the // bottleneck. So, I've written this out the hard way instead. Two - // versions of the loop: one for 32-bit indices, one for 16-bit. + // versions of the loop: one for 32-bit floats, the other for 64-bit. { PT(GeomVertexArrayDataHandle) vtx_handle = vdata->modify_array_handle(0); vtx_handle->unclean_set_num_rows(quads.size() * 4); - Thread *current_thread = Thread::get_current_thread(); unsigned char *write_ptr = vtx_handle->get_write_pointer(); - size_t stride = format->get_array(0)->get_stride() / sizeof(PN_float32); - PN_float32 *vtx_ptr = (PN_float32 *) - (write_ptr + format->get_column(InternalName::get_vertex())->get_start()); - PN_float32 *tex_ptr = (PN_float32 *) - (write_ptr + format->get_column(InternalName::get_texcoord())->get_start()); + if (format->get_vertex_column()->get_numeric_type() == GeomEnums::NT_float32) { + // 32-bit vertex case. + size_t stride = format->get_array(0)->get_stride() / sizeof(PN_float32); - if (tris->get_index_type() == GeomEnums::NT_uint32) { - // 32-bit index case. - PT(GeomVertexArrayDataHandle) idx_handle = tris->modify_vertices_handle(current_thread); - idx_handle->unclean_set_num_rows(quads.size() * 6); - uint32_t *idx_ptr = (uint32_t *)idx_handle->get_write_pointer(); - - QuadDefs::const_iterator qi; - for (qi = quads.begin(); qi != quads.end(); ++qi) { - const QuadDef &quad = (*qi); + PN_float32 *vtx_ptr = (PN_float32 *) + (write_ptr + format->get_column(InternalName::get_vertex())->get_start()); + PN_float32 *tex_ptr = (PN_float32 *) + (write_ptr + format->get_column(InternalName::get_texcoord())->get_start()); + for (const QuadDef &quad : quads) { vtx_ptr[0] = quad._dimensions[0] + quad._slanth; vtx_ptr[1] = 0; vtx_ptr[2] = quad._dimensions[3]; @@ -1219,26 +1197,18 @@ generate_quads(GeomNode *geom_node, const QuadMap &quad_map) { tex_ptr[1] = quad._uvs[1]; tex_ptr += stride; - *(idx_ptr++) = i + 0; - *(idx_ptr++) = i + 1; - *(idx_ptr++) = i + 2; - *(idx_ptr++) = i + 2; - *(idx_ptr++) = i + 1; - *(idx_ptr++) = i + 3; - i += 4; - glyphs.push_back(move(quad._glyph)); } } else { - // 16-bit index case. - PT(GeomVertexArrayDataHandle) idx_handle = tris->modify_vertices_handle(current_thread); - idx_handle->unclean_set_num_rows(quads.size() * 6); - uint16_t *idx_ptr = (uint16_t *)idx_handle->get_write_pointer(); + // 64-bit vertex case. + size_t stride = format->get_array(0)->get_stride() / sizeof(PN_float64); - QuadDefs::const_iterator qi; - for (qi = quads.begin(); qi != quads.end(); ++qi) { - const QuadDef &quad = (*qi); + PN_float64 *vtx_ptr = (PN_float64 *) + (write_ptr + format->get_column(InternalName::get_vertex())->get_start()); + PN_float64 *tex_ptr = (PN_float64 *) + (write_ptr + format->get_column(InternalName::get_texcoord())->get_start()); + for (const QuadDef &quad : quads) { vtx_ptr[0] = quad._dimensions[0] + quad._slanth; vtx_ptr[1] = 0; vtx_ptr[2] = quad._dimensions[3]; @@ -1275,21 +1245,51 @@ generate_quads(GeomNode *geom_node, const QuadMap &quad_map) { tex_ptr[1] = quad._uvs[1]; tex_ptr += stride; - *(idx_ptr++) = i + 0; - *(idx_ptr++) = i + 1; - *(idx_ptr++) = i + 2; - *(idx_ptr++) = i + 2; - *(idx_ptr++) = i + 1; - *(idx_ptr++) = i + 3; - i += 4; - glyphs.push_back(move(quad._glyph)); } } } + // Now write the indices. Two cases: 32-bit indices and 16-bit indices. + int vtx_count = quads.size() * 4; + PT(GeomTriangles) tris = new GeomTriangles(Geom::UH_static); + if (vtx_count > 65535) { + tris->set_index_type(GeomEnums::NT_uint32); + } else { + tris->set_index_type(GeomEnums::NT_uint16); + } + { + PT(GeomVertexArrayDataHandle) idx_handle = tris->modify_vertices_handle(current_thread); + idx_handle->unclean_set_num_rows(quads.size() * 6); + if (tris->get_index_type() == GeomEnums::NT_uint16) { + // 16-bit index case. + uint16_t *idx_ptr = (uint16_t *)idx_handle->get_write_pointer(); + + for (int i = 0; i < vtx_count; i += 4) { + *(idx_ptr++) = i + 0; + *(idx_ptr++) = i + 1; + *(idx_ptr++) = i + 2; + *(idx_ptr++) = i + 2; + *(idx_ptr++) = i + 1; + *(idx_ptr++) = i + 3; + } + } else { + // 32-bit index case. + uint32_t *idx_ptr = (uint32_t *)idx_handle->get_write_pointer(); + + for (int i = 0; i < vtx_count; i += 4) { + *(idx_ptr++) = i + 0; + *(idx_ptr++) = i + 1; + *(idx_ptr++) = i + 2; + *(idx_ptr++) = i + 2; + *(idx_ptr++) = i + 1; + *(idx_ptr++) = i + 3; + } + } + } + // We can compute this value much faster than GeomPrimitive can. - tris->set_minmax(0, i - 1, nullptr, nullptr); + tris->set_minmax(0, vtx_count - 1, nullptr, nullptr); PT(GeomTextGlyph) geom = new GeomTextGlyph(vdata); geom->_glyphs.swap(glyphs); From 02b32a5814f0bed820677d2383cc4b4d249d929c Mon Sep 17 00:00:00 2001 From: rdb Date: Thu, 26 Jul 2018 20:05:35 +0200 Subject: [PATCH 061/125] glgsg: support vertices-float64 in core profile shaders Requires OpenGL 4.1 or GL_ARB_vertex_attrib_64bit extension. --- .../glstuff/glGraphicsStateGuardian_src.cxx | 58 +++++++++++++++++-- .../src/glstuff/glGraphicsStateGuardian_src.h | 2 +- 2 files changed, 54 insertions(+), 6 deletions(-) diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx index 7e8a08aacd..25a57a9a17 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx @@ -92,10 +92,6 @@ PStatCollector CLP(GraphicsStateGuardian)::_texture_update_pcollector("Draw:Upda PStatCollector CLP(GraphicsStateGuardian)::_fbo_bind_pcollector("Draw:Bind FBO"); PStatCollector CLP(GraphicsStateGuardian)::_check_error_pcollector("Draw:Check errors"); -#ifndef OPENGLES_1 -PT(Shader) CLP(GraphicsStateGuardian)::_default_shader = nullptr; -#endif - // The following noop functions are assigned to the corresponding glext // function pointers in the class, in case the functions are not defined by // the GL, just so it will always be safe to call the extension functions. @@ -188,6 +184,48 @@ static const string default_vshader = " color = p3d_Color * p3d_ColorScale;\n" "}\n"; +#ifndef OPENGLES +// This version of the shader is used if vertices-float64 is enabled. +static const string default_vshader_fp64 = +#ifdef __APPLE__ + "#version 150\n" +#else + "#version 130\n" +#endif + "#extension GL_ARB_vertex_attrib_64bit : require\n" + "#extension GL_ARB_gpu_shader_fp64 : require\n" + "in dvec3 p3d_Vertex;\n" + "in vec4 p3d_Color;\n" + "in dvec2 p3d_MultiTexCoord0;\n" + "out vec2 texcoord;\n" + "out vec4 color;\n" + "uniform mat4 p3d_ModelViewMatrix;\n" + "uniform mat4 p3d_ProjectionMatrix;\n" + "uniform vec4 p3d_ColorScale;\n" + "void main(void) {\n" // Apply proj & modelview in two steps, more precise + " gl_Position = vec4(dmat4(p3d_ProjectionMatrix) * (dmat4(p3d_ModelViewMatrix) * dvec4(p3d_Vertex, 1)));\n" + " texcoord = vec2(p3d_MultiTexCoord0);\n" + " color = p3d_Color * p3d_ColorScale;\n" + "}\n"; + +// Same as above, but for OpenGL 4.1. +static const string default_vshader_fp64_gl41 = + "#version 410\n" + "in dvec3 p3d_Vertex;\n" + "in vec4 p3d_Color;\n" + "in dvec2 p3d_MultiTexCoord0;\n" + "out vec2 texcoord;\n" + "out vec4 color;\n" + "uniform mat4 p3d_ModelViewMatrix;\n" + "uniform mat4 p3d_ProjectionMatrix;\n" + "uniform vec4 p3d_ColorScale;\n" + "void main(void) {\n" // Apply proj & modelview in two steps, more precise + " gl_Position = vec4(dmat4(p3d_ProjectionMatrix) * (dmat4(p3d_ModelViewMatrix) * dvec4(p3d_Vertex, 1)));\n" + " texcoord = vec2(p3d_MultiTexCoord0);\n" + " color = p3d_Color * p3d_ColorScale;\n" + "}\n"; +#endif + static const string default_fshader = #ifndef OPENGLES #ifdef __APPLE__ // Apple's GL 3.2 contexts require at least GLSL 1.50. @@ -1839,7 +1877,17 @@ reset() { // shader just outputs a red color, indicating that something went wrong. #ifndef OPENGLES_1 if (_default_shader == nullptr && !has_fixed_function_pipeline()) { - _default_shader = Shader::make(Shader::SL_GLSL, default_vshader, default_fshader); +#ifndef OPENGLES + bool use_float64 = vertices_float64; + if (use_float64 && is_at_least_gl_version(4, 1)) { + _default_shader = Shader::make(Shader::SL_GLSL, default_vshader_fp64_gl41, default_fshader); + } else if (use_float64 && has_extension("GL_ARB_vertex_attrib_64bit")) { + _default_shader = Shader::make(Shader::SL_GLSL, default_vshader_fp64, default_fshader); + } else +#endif + { + _default_shader = Shader::make(Shader::SL_GLSL, default_vshader, default_fshader); + } } #endif diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.h b/panda/src/glstuff/glGraphicsStateGuardian_src.h index 67de9ac54c..a8cd3a2e3b 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.h +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.h @@ -674,7 +674,7 @@ protected: PT(Shader) _texture_binding_shader; ShaderContext *_texture_binding_shader_context; - static PT(Shader) _default_shader; + PT(Shader) _default_shader; #ifndef OPENGLES bool _shader_point_size; From 0cb763a10af44220e3ff651e5d066d54368bc978 Mon Sep 17 00:00:00 2001 From: rdb Date: Thu, 26 Jul 2018 21:56:22 +0200 Subject: [PATCH 062/125] ShaderGenerator: always use generic attr on Linux 48808fe269eac07b725dead80e2b18c838b53abb disabled this on Linux, but I believe this was an accidental change. --- panda/src/pgraphnodes/shaderGenerator.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/panda/src/pgraphnodes/shaderGenerator.cxx b/panda/src/pgraphnodes/shaderGenerator.cxx index 22d0b32259..71379ddbac 100644 --- a/panda/src/pgraphnodes/shaderGenerator.cxx +++ b/panda/src/pgraphnodes/shaderGenerator.cxx @@ -77,7 +77,7 @@ ShaderGenerator(const GraphicsStateGuardianBase *gsg) { #ifdef _WIN32 _use_generic_attr = !gsg->get_supports_hlsl(); #else - _use_generic_attr = false; + _use_generic_attr = true; #endif // Do we want to use the ARB_shadow extension? This also allows us to use From f12bc29d6d4b28124a6db9c8ba08e963277ed5b6 Mon Sep 17 00:00:00 2001 From: rdb Date: Thu, 26 Jul 2018 22:57:09 +0200 Subject: [PATCH 063/125] tests: do not attempt to run GLSL tests without buffer tex support --- tests/display/test_glsl_shader.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/display/test_glsl_shader.py b/tests/display/test_glsl_shader.py index 0c9c9e8e95..91816353f6 100644 --- a/tests/display/test_glsl_shader.py +++ b/tests/display/test_glsl_shader.py @@ -45,6 +45,9 @@ def run_glsl_test(gsg, body, preamble="", inputs={}, version=430): if not gsg.supports_compute_shaders or not gsg.supports_glsl: pytest.skip("compute shaders not supported") + if not gsg.supports_buffer_texture: + pytest.skip("buffer textures not supported") + __tracebackhide__ = True preamble = preamble.strip() From 2d7e80a89e9c8a245778fe19d537ecfc9819d248 Mon Sep 17 00:00:00 2001 From: rdb Date: Mon, 30 Jul 2018 11:04:20 +0200 Subject: [PATCH 064/125] express: add full range of WeakPointerTo ctors and assign ops Matches PointerTo constructors/assignment operators, supporting conversion between related pointer types. Fixes #367 --- panda/src/express/pointerToVoid.I | 7 - panda/src/express/pointerToVoid.h | 4 +- panda/src/express/weakPointerTo.I | 258 ++++++++++++++++++++++++++ panda/src/express/weakPointerTo.h | 60 +++++- panda/src/express/weakPointerToBase.I | 58 ++++-- panda/src/express/weakPointerToBase.h | 8 +- panda/src/express/weakPointerToVoid.I | 7 - panda/src/express/weakPointerToVoid.h | 4 +- 8 files changed, 373 insertions(+), 33 deletions(-) diff --git a/panda/src/express/pointerToVoid.I b/panda/src/express/pointerToVoid.I index c6f981a7fb..8704ce4ce6 100644 --- a/panda/src/express/pointerToVoid.I +++ b/panda/src/express/pointerToVoid.I @@ -11,13 +11,6 @@ * @date 2004-09-27 */ -/** - * - */ -constexpr PointerToVoid:: -PointerToVoid() noexcept : _void_ptr(nullptr) { -} - /** * */ diff --git a/panda/src/express/pointerToVoid.h b/panda/src/express/pointerToVoid.h index 1f5fadd492..e185911eab 100644 --- a/panda/src/express/pointerToVoid.h +++ b/panda/src/express/pointerToVoid.h @@ -32,7 +32,7 @@ */ class EXPCL_PANDA_EXPRESS PointerToVoid : public MemoryBase { protected: - constexpr PointerToVoid() noexcept; + constexpr PointerToVoid() noexcept = default; //INLINE ~PointerToVoid(); private: @@ -63,7 +63,7 @@ protected: // a PointerTo any class that inherits virtually from ReferenceCount. (You // can't downcast past a virtual inheritance level, but you can always // cross-cast from a void pointer.) - AtomicAdjust::Pointer _void_ptr; + AtomicAdjust::Pointer _void_ptr = nullptr; }; #include "pointerToVoid.I" diff --git a/panda/src/express/weakPointerTo.I b/panda/src/express/weakPointerTo.I index c6e570979f..354846807a 100644 --- a/panda/src/express/weakPointerTo.I +++ b/panda/src/express/weakPointerTo.I @@ -39,6 +39,49 @@ WeakPointerTo(const WeakPointerTo ©) : { } +/** + * + */ +template +INLINE WeakPointerTo:: +WeakPointerTo(WeakPointerTo &&from) noexcept : + WeakPointerToBase(std::move(from)) +{ +} + +/** + * + */ +template +template +ALWAYS_INLINE WeakPointerTo:: +WeakPointerTo(const WeakPointerTo &r) noexcept : + WeakPointerToBase(r) +{ +} + +/** + * + */ +template +template +ALWAYS_INLINE WeakPointerTo:: +WeakPointerTo(const PointerTo &r) noexcept : + WeakPointerToBase(r) +{ +} + +/** + * + */ +template +template +ALWAYS_INLINE WeakPointerTo:: +WeakPointerTo(WeakPointerTo &&r) noexcept : + WeakPointerToBase(std::move(r)) +{ +} + /** * */ @@ -152,6 +195,49 @@ operator = (const WeakPointerTo ©) { return *this; } +/** + * + */ +template +INLINE WeakPointerTo &WeakPointerTo:: +operator = (WeakPointerTo &&from) noexcept { + this->reassign(std::move(from)); + return *this; +} + +/** + * + */ +template +template +ALWAYS_INLINE WeakPointerTo &WeakPointerTo:: +operator = (const WeakPointerTo &r) noexcept { + this->reassign(r); + return *this; +} + +/** + * + */ +template +template +ALWAYS_INLINE WeakPointerTo &WeakPointerTo:: +operator = (const PointerTo &r) noexcept { + this->reassign(r); + return *this; +} + +/** + * + */ +template +template +ALWAYS_INLINE WeakPointerTo &WeakPointerTo:: +operator = (WeakPointerTo &&r) noexcept { + this->reassign(std::move(r)); + return *this; +} + /** * */ @@ -202,6 +288,92 @@ WeakConstPointerTo(const WeakConstPointerTo ©) : { } +/** + * + */ +template +INLINE WeakConstPointerTo:: +WeakConstPointerTo(WeakPointerTo &&from) noexcept : + WeakPointerToBase(std::move(from)) +{ +} + +/** + * + */ +template +INLINE WeakConstPointerTo:: +WeakConstPointerTo(WeakConstPointerTo &&from) noexcept : + WeakPointerToBase(std::move(from)) +{ +} + +/** + * + */ +template +template +ALWAYS_INLINE WeakConstPointerTo:: +WeakConstPointerTo(const WeakPointerTo &r) noexcept : + WeakPointerToBase(r) +{ +} + +/** + * + */ +template +template +ALWAYS_INLINE WeakConstPointerTo:: +WeakConstPointerTo(const WeakConstPointerTo &r) noexcept : + WeakPointerToBase(r) +{ +} + +/** + * + */ +template +template +ALWAYS_INLINE WeakConstPointerTo:: +WeakConstPointerTo(const PointerTo &r) noexcept : + WeakPointerToBase(r) +{ +} + +/** + * + */ +template +template +ALWAYS_INLINE WeakConstPointerTo:: +WeakConstPointerTo(const ConstPointerTo &r) noexcept : + WeakPointerToBase(r) +{ +} + +/** + * + */ +template +template +ALWAYS_INLINE WeakConstPointerTo:: +WeakConstPointerTo(WeakPointerTo &&r) noexcept : + WeakPointerToBase(std::move(r)) +{ +} + +/** + * + */ +template +template +ALWAYS_INLINE WeakConstPointerTo:: +WeakConstPointerTo(WeakConstPointerTo &&r) noexcept : + WeakPointerToBase(std::move(r)) +{ +} + /** * */ @@ -332,3 +504,89 @@ operator = (const WeakConstPointerTo ©) { ((WeakConstPointerTo *)this)->reassign(*(const PointerToBase *)©); return *this; } + +/** + * + */ +template +INLINE WeakConstPointerTo &WeakConstPointerTo:: +operator = (WeakPointerTo &&from) noexcept { + this->reassign(std::move(from)); + return *this; +} + +/** + * + */ +template +INLINE WeakConstPointerTo &WeakConstPointerTo:: +operator = (WeakConstPointerTo &&from) noexcept { + this->reassign(std::move(from)); + return *this; +} + +/** + * + */ +template +template +ALWAYS_INLINE WeakConstPointerTo &WeakConstPointerTo:: +operator = (const WeakPointerTo &r) noexcept { + this->reassign(r); + return *this; +} + +/** + * + */ +template +template +ALWAYS_INLINE WeakConstPointerTo &WeakConstPointerTo:: +operator = (const WeakConstPointerTo &r) noexcept { + this->reassign(r); + return *this; +} + +/** + * + */ +template +template +ALWAYS_INLINE WeakConstPointerTo &WeakConstPointerTo:: +operator = (const PointerTo &r) noexcept { + this->reassign(r); + return *this; +} + +/** + * + */ +template +template +ALWAYS_INLINE WeakConstPointerTo &WeakConstPointerTo:: +operator = (const ConstPointerTo &r) noexcept { + this->reassign(r); + return *this; +} + +/** + * + */ +template +template +ALWAYS_INLINE WeakConstPointerTo &WeakConstPointerTo:: +operator = (WeakPointerTo &&r) noexcept { + this->reassign(std::move(r)); + return *this; +} + +/** + * + */ +template +template +ALWAYS_INLINE WeakConstPointerTo &WeakConstPointerTo:: +operator = (WeakConstPointerTo &&r) noexcept { + this->reassign(std::move(r)); + return *this; +} diff --git a/panda/src/express/weakPointerTo.h b/panda/src/express/weakPointerTo.h index 2e8c6029a5..ee50b0ebc3 100644 --- a/panda/src/express/weakPointerTo.h +++ b/panda/src/express/weakPointerTo.h @@ -30,11 +30,21 @@ class WeakPointerTo : public WeakPointerToBase { public: typedef typename WeakPointerToBase::To To; PUBLISHED: - INLINE WeakPointerTo(To *ptr = nullptr); + constexpr WeakPointerTo() noexcept = default; + INLINE WeakPointerTo(To *ptr); INLINE WeakPointerTo(const PointerTo ©); INLINE WeakPointerTo(const WeakPointerTo ©); public: + INLINE WeakPointerTo(WeakPointerTo &&from) noexcept; + + template + ALWAYS_INLINE WeakPointerTo(const WeakPointerTo &r) noexcept; + template + ALWAYS_INLINE WeakPointerTo(const PointerTo &r) noexcept; + template + ALWAYS_INLINE WeakPointerTo(WeakPointerTo &&r) noexcept; + INLINE To &operator *() const; INLINE To *operator -> () const; // MSVC.NET 2005 insists that we use T *, and not To *, here. @@ -49,6 +59,17 @@ PUBLISHED: INLINE WeakPointerTo &operator = (const PointerTo ©); INLINE WeakPointerTo &operator = (const WeakPointerTo ©); +public: + INLINE WeakPointerTo &operator = (WeakPointerTo &&from) noexcept; + + template + ALWAYS_INLINE WeakPointerTo &operator = (const WeakPointerTo &r) noexcept; + template + ALWAYS_INLINE WeakPointerTo &operator = (const PointerTo &r) noexcept; + template + ALWAYS_INLINE WeakPointerTo &operator = (WeakPointerTo &&r) noexcept; + +PUBLISHED: // This function normally wouldn't need to be redefined here, but we do so // anyway just to help out interrogate (which doesn't seem to want to // automatically export the WeakPointerToBase class). When this works again @@ -66,13 +87,30 @@ class WeakConstPointerTo : public WeakPointerToBase { public: typedef typename WeakPointerToBase::To To; PUBLISHED: - INLINE WeakConstPointerTo(const To *ptr = nullptr); + constexpr WeakConstPointerTo() noexcept = default; + INLINE WeakConstPointerTo(const To *ptr); INLINE WeakConstPointerTo(const PointerTo ©); INLINE WeakConstPointerTo(const ConstPointerTo ©); INLINE WeakConstPointerTo(const WeakPointerTo ©); INLINE WeakConstPointerTo(const WeakConstPointerTo ©); public: + INLINE WeakConstPointerTo(WeakPointerTo &&from) noexcept; + INLINE WeakConstPointerTo(WeakConstPointerTo &&from) noexcept; + + template + ALWAYS_INLINE WeakConstPointerTo(const WeakPointerTo &r) noexcept; + template + ALWAYS_INLINE WeakConstPointerTo(const WeakConstPointerTo &r) noexcept; + template + ALWAYS_INLINE WeakConstPointerTo(const PointerTo &r) noexcept; + template + ALWAYS_INLINE WeakConstPointerTo(const ConstPointerTo &r) noexcept; + template + ALWAYS_INLINE WeakConstPointerTo(WeakPointerTo &&r) noexcept; + template + ALWAYS_INLINE WeakConstPointerTo(WeakConstPointerTo &&r) noexcept; + INLINE const To &operator *() const; INLINE const To *operator -> () const; INLINE explicit operator const T *() const; @@ -88,6 +126,24 @@ PUBLISHED: INLINE WeakConstPointerTo &operator = (const WeakPointerTo ©); INLINE WeakConstPointerTo &operator = (const WeakConstPointerTo ©); +public: + INLINE WeakConstPointerTo &operator = (WeakPointerTo &&from) noexcept; + INLINE WeakConstPointerTo &operator = (WeakConstPointerTo &&from) noexcept; + + template + ALWAYS_INLINE WeakConstPointerTo &operator = (const WeakPointerTo &r) noexcept; + template + ALWAYS_INLINE WeakConstPointerTo &operator = (const WeakConstPointerTo &r) noexcept; + template + ALWAYS_INLINE WeakConstPointerTo &operator = (const PointerTo &r) noexcept; + template + ALWAYS_INLINE WeakConstPointerTo &operator = (const ConstPointerTo &r) noexcept; + template + ALWAYS_INLINE WeakConstPointerTo &operator = (WeakPointerTo &&r) noexcept; + template + ALWAYS_INLINE WeakConstPointerTo &operator = (WeakConstPointerTo &&r) noexcept; + +PUBLISHED: // These functions normally wouldn't need to be redefined here, but we do so // anyway just to help out interrogate (which doesn't seem to want to // automatically export the WeakPointerToBase class). When this works again diff --git a/panda/src/express/weakPointerToBase.I b/panda/src/express/weakPointerToBase.I index 2e537c9639..5410903fdd 100644 --- a/panda/src/express/weakPointerToBase.I +++ b/panda/src/express/weakPointerToBase.I @@ -64,20 +64,27 @@ WeakPointerToBase(const WeakPointerToBase ©) { template INLINE WeakPointerToBase:: WeakPointerToBase(WeakPointerToBase &&from) noexcept { - // Protect against self-move-assignment. - if (from._void_ptr != this->_void_ptr) { - WeakReferenceList *old_ref = (To *)this->_weak_ref; + this->_void_ptr = from._void_ptr; + this->_weak_ref = from._weak_ref; + from._void_ptr = nullptr; + from._weak_ref = nullptr; +} - this->_void_ptr = from._void_ptr; - this->_weak_ref = from._weak_ref; - from._void_ptr = nullptr; - from._weak_ref = nullptr; +/** + * + */ +template +template +INLINE WeakPointerToBase:: +WeakPointerToBase(WeakPointerToBase &&r) noexcept { + // If this next line gives an error, you are trying to convert a WeakPointerTo + // from an incompatible type of another WeakPointerTo. + To *ptr = (Y *)r._void_ptr; - // Now delete the old pointer. - if (old_ref != nullptr && !old_ref->unref()) { - delete old_ref; - } - } + this->_void_ptr = ptr; + this->_weak_ref = r._weak_ref; + r._void_ptr = nullptr; + r._weak_ref = nullptr; } /** @@ -180,6 +187,33 @@ reassign(WeakPointerToBase &&from) noexcept { } } +/** + * Like above, but casts from a compatible pointer type. + */ +template +template +INLINE void WeakPointerToBase:: +reassign(WeakPointerToBase &&from) noexcept { + // Protect against self-move-assignment. + if (from._void_ptr != this->_void_ptr) { + WeakReferenceList *old_ref = (WeakReferenceList *)this->_weak_ref; + + // If there is a compile error on this line, it means you tried to assign + // an incompatible type. + To *new_ptr = (Y *)from._void_ptr; + + this->_void_ptr = new_ptr; + this->_weak_ref = from._weak_ref; + from._void_ptr = nullptr; + from._weak_ref = nullptr; + + // Now delete the old pointer. + if (old_ref != nullptr && !old_ref->unref()) { + delete old_ref; + } + } +} + /** * Ensures that the MemoryUsage record for the pointer has the right type of * object, if we know the type ourselves. diff --git a/panda/src/express/weakPointerToBase.h b/panda/src/express/weakPointerToBase.h index a34b39bdb5..94efd051eb 100644 --- a/panda/src/express/weakPointerToBase.h +++ b/panda/src/express/weakPointerToBase.h @@ -28,16 +28,22 @@ public: typedef T To; protected: - INLINE WeakPointerToBase(To *ptr); + constexpr WeakPointerToBase() noexcept = default; + INLINE explicit WeakPointerToBase(To *ptr); INLINE WeakPointerToBase(const PointerToBase ©); INLINE WeakPointerToBase(const WeakPointerToBase ©); INLINE WeakPointerToBase(WeakPointerToBase &&from) noexcept; + template + INLINE WeakPointerToBase(WeakPointerToBase &&r) noexcept; + INLINE ~WeakPointerToBase(); void reassign(To *ptr); INLINE void reassign(const PointerToBase ©); INLINE void reassign(const WeakPointerToBase ©); INLINE void reassign(WeakPointerToBase &&from) noexcept; + template + INLINE void reassign(WeakPointerToBase &&from) noexcept; INLINE void update_type(To *ptr); diff --git a/panda/src/express/weakPointerToVoid.I b/panda/src/express/weakPointerToVoid.I index 120836510d..187a659fc1 100644 --- a/panda/src/express/weakPointerToVoid.I +++ b/panda/src/express/weakPointerToVoid.I @@ -11,13 +11,6 @@ * @date 2004-09-27 */ -/** - * - */ -INLINE WeakPointerToVoid:: -WeakPointerToVoid() : _weak_ref(nullptr) { -} - /** * Sets a callback that will be made when the pointer is deleted. Does * nothing if this is a null pointer. diff --git a/panda/src/express/weakPointerToVoid.h b/panda/src/express/weakPointerToVoid.h index 56ace2dcb2..3eadfffc4d 100644 --- a/panda/src/express/weakPointerToVoid.h +++ b/panda/src/express/weakPointerToVoid.h @@ -25,7 +25,7 @@ */ class EXPCL_PANDA_EXPRESS WeakPointerToVoid : public PointerToVoid { protected: - INLINE WeakPointerToVoid(); + constexpr WeakPointerToVoid() noexcept = default; public: INLINE void add_callback(WeakPointerCallback *callback) const; @@ -36,7 +36,7 @@ PUBLISHED: INLINE bool is_valid_pointer() const; protected: - mutable WeakReferenceList *_weak_ref; + mutable WeakReferenceList *_weak_ref = nullptr; }; #include "weakPointerToVoid.I" From ad3ab3ad211650fe0cf7c304a4032c87326a0d10 Mon Sep 17 00:00:00 2001 From: rdb Date: Mon, 30 Jul 2018 17:27:09 +0200 Subject: [PATCH 065/125] Define stable ordering for WeakPointerTo for use as map/set key Currently, the WeakPointerTo comparison operators compare the raw pointers, but this is not useful as it may cause a false equality if one weak pointer in the comparison is expired and points to memory that has since been reused. Instead, we can define a comparison based on the control block pointer, which exists since the new weak pointer implementation in 0bb81a43c9e4fffb37cc2234c1b0fbae42020ceb. This is implemented in the owner_before method, matching C++11 std::weak_ptr semantics. I would now recommend deprecating most comparison operators of WeakPointerTo or redefining them to make more sense, ie. comparing equal if they (once) referred to the same object and not if they simply point to the same memory address. This has not yet been done, though code that uses the comparison operators has been fixed in this commit. Overloads of std::owner_less have been provided for creating a map or set with Weak(Const)PointerTo keys. --- dtool/src/dtoolbase/dtoolbase_cc.h | 2 + panda/src/chan/partBundle.h | 2 +- panda/src/char/characterJointEffect.I | 6 +- panda/src/dxgsg9/dxGeomMunger9.cxx | 14 ++-- panda/src/express/pointerTo.h | 20 ++++++ panda/src/express/pointerToBase.h | 1 + panda/src/express/weakPointerTo.h | 19 ++++++ panda/src/express/weakPointerToBase.I | 94 +++++++++++++++++++------- panda/src/express/weakPointerToBase.h | 5 ++ panda/src/glstuff/glGeomMunger_src.cxx | 28 +++++--- panda/src/pgraph/nodePath.cxx | 14 ++-- panda/src/pgraph/weakNodePath.I | 21 +++--- 12 files changed, 167 insertions(+), 59 deletions(-) diff --git a/dtool/src/dtoolbase/dtoolbase_cc.h b/dtool/src/dtoolbase/dtoolbase_cc.h index b4ce1d597c..3af3c9c250 100644 --- a/dtool/src/dtoolbase/dtoolbase_cc.h +++ b/dtool/src/dtoolbase/dtoolbase_cc.h @@ -111,6 +111,8 @@ namespace std { template typename remove_reference::type &&move(T &&t) { return static_cast::type&&>(t); } + + template struct owner_less; }; #endif diff --git a/panda/src/chan/partBundle.h b/panda/src/chan/partBundle.h index 7a611a80de..f8fda4bd47 100644 --- a/panda/src/chan/partBundle.h +++ b/panda/src/chan/partBundle.h @@ -172,7 +172,7 @@ private: typedef pvector Nodes; Nodes _nodes; - typedef pmap AppliedTransforms; + typedef pmap > AppliedTransforms; AppliedTransforms _applied_transforms; double _update_delay; diff --git a/panda/src/char/characterJointEffect.I b/panda/src/char/characterJointEffect.I index e4d596dafe..34e2502afa 100644 --- a/panda/src/char/characterJointEffect.I +++ b/panda/src/char/characterJointEffect.I @@ -35,5 +35,9 @@ get_character() const { */ INLINE bool CharacterJointEffect:: matches_character(Character *character) const { - return _character == character; + // This works because while the Character is destructing, the ref count will + // be 0 but was_deleted() will still return false. We cannot construct a + // PointerTo to the character (via lock() or otherwise) when the reference + // count is 0 since that will cause double deletion. + return _character.get_orig() == character && !_character.was_deleted(); } diff --git a/panda/src/dxgsg9/dxGeomMunger9.cxx b/panda/src/dxgsg9/dxGeomMunger9.cxx index 8aa539c11f..638b121f27 100644 --- a/panda/src/dxgsg9/dxGeomMunger9.cxx +++ b/panda/src/dxgsg9/dxGeomMunger9.cxx @@ -300,8 +300,11 @@ compare_to_impl(const GeomMunger *other) const { if (_filtered_texture != om->_filtered_texture) { return _filtered_texture < om->_filtered_texture ? -1 : 1; } - if (_tex_gen != om->_tex_gen) { - return _tex_gen < om->_tex_gen ? -1 : 1; + if (_tex_gen.owner_before(om->_tex_gen)) { + return -1; + } + if (om->_tex_gen.owner_before(_tex_gen)) { + return 1; } return StandardMunger::compare_to_impl(other); @@ -321,8 +324,11 @@ geom_compare_to_impl(const GeomMunger *other) const { if (_filtered_texture != om->_filtered_texture) { return _filtered_texture < om->_filtered_texture ? -1 : 1; } - if (_tex_gen != om->_tex_gen) { - return _tex_gen < om->_tex_gen ? -1 : 1; + if (_tex_gen.owner_before(om->_tex_gen)) { + return -1; + } + if (om->_tex_gen.owner_before(_tex_gen)) { + return 1; } return StandardMunger::geom_compare_to_impl(other); diff --git a/panda/src/express/pointerTo.h b/panda/src/express/pointerTo.h index e9250a2f8a..cb790ebd81 100644 --- a/panda/src/express/pointerTo.h +++ b/panda/src/express/pointerTo.h @@ -215,6 +215,26 @@ void swap(ConstPointerTo &one, ConstPointerTo &two) noexcept { } +// Define owner_less specializations, for completeness' sake. +namespace std { + template + struct owner_less > { + bool operator () (const PointerTo &lhs, + const PointerTo &rhs) const noexcept { + return lhs < rhs; + } + }; + + template + struct owner_less > { + bool operator () (const ConstPointerTo &lhs, + const ConstPointerTo &rhs) const noexcept { + return lhs < rhs; + } + }; +} + + // Finally, we'll define a couple of handy abbreviations to save on all that // wasted typing time. diff --git a/panda/src/express/pointerToBase.h b/panda/src/express/pointerToBase.h index 959574aba7..832717e14e 100644 --- a/panda/src/express/pointerToBase.h +++ b/panda/src/express/pointerToBase.h @@ -53,6 +53,7 @@ protected: // This is needed to be able to access the privates of other instantiations. template friend class PointerToBase; + template friend class WeakPointerToBase; PUBLISHED: ALWAYS_INLINE void clear(); diff --git a/panda/src/express/weakPointerTo.h b/panda/src/express/weakPointerTo.h index ee50b0ebc3..bd302e0ec9 100644 --- a/panda/src/express/weakPointerTo.h +++ b/panda/src/express/weakPointerTo.h @@ -152,6 +152,25 @@ PUBLISHED: INLINE void clear() { WeakPointerToBase::clear(); } }; +// Provide specializations of std::owner_less, for using a WPT as a map key. +namespace std { + template + struct owner_less > { + bool operator () (const WeakPointerTo &lhs, + const WeakPointerTo &rhs) const noexcept { + return lhs.owner_before(rhs); + } + }; + + template + struct owner_less > { + bool operator () (const WeakConstPointerTo &lhs, + const WeakConstPointerTo &rhs) const noexcept { + return lhs.owner_before(rhs); + } + }; +} + #define WPT(type) WeakPointerTo< type > #define WCPT(type) WeakConstPointerTo< type > diff --git a/panda/src/express/weakPointerToBase.I b/panda/src/express/weakPointerToBase.I index 5410903fdd..c57ea31719 100644 --- a/panda/src/express/weakPointerToBase.I +++ b/panda/src/express/weakPointerToBase.I @@ -12,7 +12,8 @@ */ /** - * + * Constructs a weak pointer from a plain pointer (or nullptr). It is the + * caller's responsibility to ensure that it points to a valid object. */ template INLINE WeakPointerToBase:: @@ -27,7 +28,7 @@ WeakPointerToBase(To *ptr) { } /** - * + * Constructs a weak pointer from a reference-counting pointer. */ template INLINE WeakPointerToBase:: @@ -42,24 +43,25 @@ WeakPointerToBase(const PointerToBase ©) { } /** - * + * Copies a weak pointer. This is always safe, even for expired pointers. */ template INLINE WeakPointerToBase:: WeakPointerToBase(const WeakPointerToBase ©) { _void_ptr = copy._void_ptr; - // Don't bother increasing the weak reference count if the object was - // already deleted. + // While it is tempting to stop maintaining the control block pointer after + // the object has been deleted, we still need it in order to define a + // consistent ordering in owner_before. WeakReferenceList *weak_ref = copy._weak_ref; - if (weak_ref != nullptr && !weak_ref->was_deleted()) { + if (weak_ref != nullptr/* && !weak_ref->was_deleted()*/) { _weak_ref = copy._weak_ref; _weak_ref->ref(); } } /** - * + * Moves a weak pointer. This is always safe, even for expired pointers. */ template INLINE WeakPointerToBase:: @@ -71,7 +73,7 @@ WeakPointerToBase(WeakPointerToBase &&from) noexcept { } /** - * + * Moves a weak pointer from a cast-convertible weak pointer type. */ template template @@ -148,10 +150,11 @@ reassign(const WeakPointerToBase ©) { WeakReferenceList *old_ref = (WeakReferenceList *)_weak_ref; _void_ptr = new_ptr; - // Don't bother increasing the weak reference count if the object was - // already deleted. + // While it is tempting to stop maintaining the control block pointer + // after the object has been deleted, we still need it in order to define + // a consistent ordering in owner_before. WeakReferenceList *weak_ref = copy._weak_ref; - if (weak_ref != nullptr && !weak_ref->was_deleted()) { + if (weak_ref != nullptr/* && !weak_ref->was_deleted()*/) { weak_ref->ref(); _weak_ref = weak_ref; } else { @@ -371,7 +374,11 @@ operator >= (std::nullptr_t) const { } /** - * + * Returns true if both pointers have the same raw pointer value. For this to + * be meaningful, neither pointer may have expired, since if one has expired + * while the other was allocated at the expired pointer's memory address, this + * comparison will be true even though they didn't refer to the same object. + * @see owner_before */ template INLINE bool WeakPointerToBase:: @@ -380,7 +387,7 @@ operator == (const WeakPointerToBase &other) const { } /** - * + * @see operator == */ template INLINE bool WeakPointerToBase:: @@ -389,7 +396,8 @@ operator != (const WeakPointerToBase &other) const { } /** - * + * Defines an ordering between WeakPointerTo based on their raw pointer value. + * @deprecated Do not use this. Use owner_before or std::owner_less instead. */ template INLINE bool WeakPointerToBase:: @@ -398,7 +406,8 @@ operator > (const WeakPointerToBase &other) const { } /** - * + * Defines an ordering between WeakPointerTo based on their raw pointer value. + * @deprecated Do not use this. Use owner_before or std::owner_less instead. */ template INLINE bool WeakPointerToBase:: @@ -407,7 +416,8 @@ operator <= (const WeakPointerToBase &other) const { } /** - * + * Defines an ordering between WeakPointerTo based on their raw pointer value. + * @deprecated Do not use this. Use owner_before or std::owner_less instead. */ template INLINE bool WeakPointerToBase:: @@ -416,7 +426,7 @@ operator >= (const WeakPointerToBase &other) const { } /** - * + * Returns true if both pointers point to the same object. */ template INLINE bool WeakPointerToBase:: @@ -425,7 +435,7 @@ operator == (const PointerToBase &other) const { } /** - * + * Returns false if both pointers point to the same object. */ template INLINE bool WeakPointerToBase:: @@ -479,7 +489,8 @@ operator < (std::nullptr_t) const { } /** - * + * Defines an ordering between WeakPointerTo based on their raw pointer value. + * @deprecated Do not use this. Use owner_before or std::owner_less instead. */ template INLINE bool WeakPointerToBase:: @@ -498,6 +509,35 @@ operator < (const PointerToBase &other) const { #endif // CPPPARSER +/** + * Defines an ordering that is guaranteed to remain consistent even after the + * weak pointers have expired. This may result in two pointers with the same + * get_orig() value comparing unequal if one of them is a new object that was + * allocated at the same memory address as the older, expired pointer. + */ +template +template +INLINE bool WeakPointerToBase:: +owner_before(const WeakPointerToBase &other) const noexcept { + return _weak_ref < other._weak_ref; +} + +/** + * Defines an ordering that is guaranteed to remain consistent even after this + * weak pointer has expired. This may result in two pointers with the same + * get_orig() value comparing unequal if one of them is a new object that was + * allocated at the same memory address as the older, expired pointer. + */ +template +template +INLINE bool WeakPointerToBase:: +owner_before(const PointerToBase &other) const noexcept { + // Unfortunately, this may needlessly cause a control block to be allocated, + // but I do not see a more efficient solution. + return (other._void_ptr != nullptr) && + (_void_ptr == nullptr || _weak_ref < ((const Y *)other._void_ptr)->get_weak_list()); +} + /** * A convenient way to set the PointerTo object to NULL. (Assignment to a NULL * pointer also works, of course.) @@ -539,9 +579,17 @@ template INLINE void WeakPointerToBase:: output(std::ostream &out) const { out << _void_ptr; - if (was_deleted()) { - out << ":deleted"; - } else if (_void_ptr != nullptr) { - out << ":" << ((To *)_void_ptr)->get_ref_count(); + + WeakReferenceList *weak_ref = this->_weak_ref; + if (weak_ref != nullptr) { + weak_ref->_lock.lock(); + if (!weak_ref->was_deleted()) { + out << ":" << ((To *)_void_ptr)->get_ref_count(); + } else { + out << ":deleted"; + } + weak_ref->_lock.unlock(); + } else { + out << ":invalid"; } } diff --git a/panda/src/express/weakPointerToBase.h b/panda/src/express/weakPointerToBase.h index 94efd051eb..60be402c4c 100644 --- a/panda/src/express/weakPointerToBase.h +++ b/panda/src/express/weakPointerToBase.h @@ -89,6 +89,11 @@ public: INLINE bool operator < (const PointerToBase &other) const; #endif // CPPPARSER + template + INLINE bool owner_before(const WeakPointerToBase &other) const noexcept; + template + INLINE bool owner_before(const PointerToBase &other) const noexcept; + PUBLISHED: INLINE void clear(); INLINE void refresh() const; diff --git a/panda/src/glstuff/glGeomMunger_src.cxx b/panda/src/glstuff/glGeomMunger_src.cxx index 27f226a6cc..923b8e5b76 100644 --- a/panda/src/glstuff/glGeomMunger_src.cxx +++ b/panda/src/glstuff/glGeomMunger_src.cxx @@ -426,11 +426,17 @@ premunge_format_impl(const GeomVertexFormat *orig) { int CLP(GeomMunger):: compare_to_impl(const GeomMunger *other) const { const CLP(GeomMunger) *om = (CLP(GeomMunger) *)other; - if (_texture != om->_texture) { - return _texture < om->_texture ? -1 : 1; + if (_texture.owner_before(om->_texture)) { + return -1; } - if (_tex_gen != om->_tex_gen) { - return _tex_gen < om->_tex_gen ? -1 : 1; + if (om->_texture.owner_before(_texture)) { + return 1; + } + if (_tex_gen.owner_before(om->_tex_gen)) { + return -1; + } + if (om->_tex_gen.owner_before(_tex_gen)) { + return 1; } if (_flags != om->_flags) { return _flags < om->_flags ? -1 : 1; @@ -447,11 +453,17 @@ compare_to_impl(const GeomMunger *other) const { int CLP(GeomMunger):: geom_compare_to_impl(const GeomMunger *other) const { const CLP(GeomMunger) *om = (CLP(GeomMunger) *)other; - if (_texture != om->_texture) { - return _texture < om->_texture ? -1 : 1; + if (_texture.owner_before(om->_texture)) { + return -1; } - if (_tex_gen != om->_tex_gen) { - return _tex_gen < om->_tex_gen ? -1 : 1; + if (om->_texture.owner_before(_texture)) { + return 1; + } + if (_tex_gen.owner_before(om->_tex_gen)) { + return -1; + } + if (om->_tex_gen.owner_before(_tex_gen)) { + return 1; } if (_flags != om->_flags) { return _flags < om->_flags ? -1 : 1; diff --git a/panda/src/pgraph/nodePath.cxx b/panda/src/pgraph/nodePath.cxx index 9123a951b5..a21df38d19 100644 --- a/panda/src/pgraph/nodePath.cxx +++ b/panda/src/pgraph/nodePath.cxx @@ -5177,7 +5177,7 @@ get_stashed_ancestor(Thread *current_thread) const { */ bool NodePath:: operator == (const WeakNodePath &other) const { - return _head == other._head; + return (other == *this); } /** @@ -5185,7 +5185,7 @@ operator == (const WeakNodePath &other) const { */ bool NodePath:: operator != (const WeakNodePath &other) const { - return _head != other._head; + return (other != *this); } /** @@ -5196,7 +5196,7 @@ operator != (const WeakNodePath &other) const { */ bool NodePath:: operator < (const WeakNodePath &other) const { - return _head < other._head; + return other.compare_to(*this) > 0; } /** @@ -5211,13 +5211,7 @@ operator < (const WeakNodePath &other) const { */ int NodePath:: compare_to(const WeakNodePath &other) const { - // Nowadays, the NodePathComponents at the head are pointerwise equivalent - // if and only if the NodePaths are equivalent. So we only have to compare - // pointers. - if (_head != other._head) { - return _head < other._head ? -1 : 1; - } - return 0; + return -other.compare_to(*this); } /** diff --git a/panda/src/pgraph/weakNodePath.I b/panda/src/pgraph/weakNodePath.I index c2d4b0a523..3096f99c41 100644 --- a/panda/src/pgraph/weakNodePath.I +++ b/panda/src/pgraph/weakNodePath.I @@ -124,7 +124,7 @@ node() const { */ INLINE bool WeakNodePath:: operator == (const NodePath &other) const { - return _head == other._head; + return _head.get_orig() == other._head && !_head.was_deleted(); } /** @@ -132,7 +132,7 @@ operator == (const NodePath &other) const { */ INLINE bool WeakNodePath:: operator != (const NodePath &other) const { - return _head != other._head; + return !operator == (other); } /** @@ -143,7 +143,7 @@ operator != (const NodePath &other) const { */ INLINE bool WeakNodePath:: operator < (const NodePath &other) const { - return _head < other._head; + return _head.owner_before(other._head); } /** @@ -158,8 +158,8 @@ operator < (const NodePath &other) const { */ INLINE int WeakNodePath:: compare_to(const NodePath &other) const { - if (_head != other._head) { - return _head < other._head ? -1 : 1; + if (operator != (other)) { + return _head.owner_before(other._head) ? -1 : 1; } return 0; } @@ -170,7 +170,7 @@ compare_to(const NodePath &other) const { */ INLINE bool WeakNodePath:: operator == (const WeakNodePath &other) const { - return _head == other._head; + return !_head.owner_before(other._head) && !other._head.owner_before(_head); } /** @@ -178,7 +178,7 @@ operator == (const WeakNodePath &other) const { */ INLINE bool WeakNodePath:: operator != (const WeakNodePath &other) const { - return _head != other._head; + return _head.owner_before(other._head) || other._head.owner_before(_head); } /** @@ -189,7 +189,7 @@ operator != (const WeakNodePath &other) const { */ INLINE bool WeakNodePath:: operator < (const WeakNodePath &other) const { - return _head < other._head; + return _head.owner_before(other._head); } /** @@ -204,10 +204,7 @@ operator < (const WeakNodePath &other) const { */ INLINE int WeakNodePath:: compare_to(const WeakNodePath &other) const { - if (_head != other._head) { - return _head < other._head ? -1 : 1; - } - return 0; + return other._head.owner_before(_head) - _head.owner_before(other._head); } /** From 243ee75e47563def6620c3cfebf6dcc12f4c9b31 Mon Sep 17 00:00:00 2001 From: rdb Date: Mon, 30 Jul 2018 22:24:55 +0200 Subject: [PATCH 066/125] express: refactor WeakPointerTo::lock() a little bit --- panda/src/express/weakPointerTo.I | 40 ++++----------------------- panda/src/express/weakPointerToBase.I | 28 +++++++++++++++++++ panda/src/express/weakPointerToBase.h | 2 ++ panda/src/express/weakPointerToVoid.I | 8 ++++-- 4 files changed, 42 insertions(+), 36 deletions(-) diff --git a/panda/src/express/weakPointerTo.I b/panda/src/express/weakPointerTo.I index 354846807a..8d60057c31 100644 --- a/panda/src/express/weakPointerTo.I +++ b/panda/src/express/weakPointerTo.I @@ -125,23 +125,9 @@ operator T * () const { template INLINE PointerTo WeakPointerTo:: lock() const { - WeakReferenceList *weak_ref = this->_weak_ref; - if (weak_ref != nullptr) { - PointerTo ptr; - weak_ref->_lock.lock(); - if (!weak_ref->was_deleted()) { - // We also need to check that the reference count is not zero (which can - // happen if the object is currently being destructed), since that could - // cause double deletion. - To *plain_ptr = (To *)WeakPointerToBase::_void_ptr; - if (plain_ptr != nullptr && plain_ptr->ref_if_nonzero()) { - ptr.cheat() = plain_ptr; - } - } - weak_ref->_lock.unlock(); - return ptr; - } - return nullptr; + PointerTo ptr; + this->lock_into(ptr); + return ptr; } /** @@ -415,23 +401,9 @@ operator const T * () const { template INLINE ConstPointerTo WeakConstPointerTo:: lock() const { - WeakReferenceList *weak_ref = this->_weak_ref; - if (weak_ref != nullptr) { - ConstPointerTo ptr; - weak_ref->_lock.lock(); - if (!weak_ref->was_deleted()) { - // We also need to check that the reference count is not zero (which can - // happen if the object is currently being destructed), since that could - // cause double deletion. - const To *plain_ptr = (const To *)WeakPointerToBase::_void_ptr; - if (plain_ptr != nullptr && plain_ptr->ref_if_nonzero()) { - ptr.cheat() = plain_ptr; - } - } - weak_ref->_lock.unlock(); - return ptr; - } - return nullptr; + ConstPointerTo ptr; + this->lock_into(ptr); + return ptr; } /** diff --git a/panda/src/express/weakPointerToBase.I b/panda/src/express/weakPointerToBase.I index c57ea31719..8c6de65523 100644 --- a/panda/src/express/weakPointerToBase.I +++ b/panda/src/express/weakPointerToBase.I @@ -238,6 +238,34 @@ update_type(To *ptr) { #endif // DO_MEMORY_USAGE } +/** + * A thread-safe way to access the underlying pointer; will only write to the + * given pointer if the underlying pointer has not yet been deleted and is not + * null. Note that it may leave the pointer unassigned even if was_deleted() + * still returns true, which can occur if the object has reached reference + * count 0 and is about to be destroyed. + */ +template +INLINE void WeakPointerToBase:: +lock_into(PointerToBase &locked) const { + WeakReferenceList *weak_ref = this->_weak_ref; + if (weak_ref != nullptr) { + weak_ref->_lock.lock(); + if (!weak_ref->was_deleted()) { + // We also need to check that the reference count is not zero (which can + // happen if the object is currently being destructed), since that could + // cause double deletion. + To *plain_ptr = (To *)WeakPointerToBase::_void_ptr; + if (plain_ptr != nullptr && plain_ptr->ref_if_nonzero()) { + // It is valid and we successfully grabbed a reference. Assign it, + // noting we have already incremented the reference count. + locked._void_ptr = plain_ptr; + } + } + weak_ref->_lock.unlock(); + } +} + #ifndef CPPPARSER /** * diff --git a/panda/src/express/weakPointerToBase.h b/panda/src/express/weakPointerToBase.h index 60be402c4c..474514b055 100644 --- a/panda/src/express/weakPointerToBase.h +++ b/panda/src/express/weakPointerToBase.h @@ -47,6 +47,8 @@ protected: INLINE void update_type(To *ptr); + INLINE void lock_into(PointerToBase &locked) const; + // No assignment or retrieval functions are declared in WeakPointerToBase, // because we will have to specialize on const vs. non-const later. diff --git a/panda/src/express/weakPointerToVoid.I b/panda/src/express/weakPointerToVoid.I index 187a659fc1..83253c7921 100644 --- a/panda/src/express/weakPointerToVoid.I +++ b/panda/src/express/weakPointerToVoid.I @@ -40,7 +40,11 @@ remove_callback(WeakPointerCallback *callback) const { /** * Returns true if the object we are pointing to has been deleted, false - * otherwise. + * otherwise. If this returns true, it means that the pointer can not yet be + * reused, but it does not guarantee that it can be safely accessed. See the + * lock() method for a safe way to access the underlying pointer. + * + * This will always return true for a null pointer, unlike is_valid_pointer(). */ INLINE bool WeakPointerToVoid:: was_deleted() const { @@ -49,7 +53,7 @@ was_deleted() const { /** * Returns true if the pointer is not null and the object has not been - * deleted. + * deleted. See was_deleted() for caveats. */ INLINE bool WeakPointerToVoid:: is_valid_pointer() const { From 91b01e562128c4a18e20edbafd8fe97da04dc0a0 Mon Sep 17 00:00:00 2001 From: rdb Date: Mon, 30 Jul 2018 22:37:02 +0200 Subject: [PATCH 067/125] collide: add tube-into-box collision test --- panda/src/collide/collisionBox.cxx | 145 +++++++++++++++++++++++++++++ panda/src/collide/collisionBox.h | 2 + panda/src/collide/collisionTube.h | 2 + 3 files changed, 149 insertions(+) diff --git a/panda/src/collide/collisionBox.cxx b/panda/src/collide/collisionBox.cxx index 494013c75b..119284f905 100644 --- a/panda/src/collide/collisionBox.cxx +++ b/panda/src/collide/collisionBox.cxx @@ -545,6 +545,151 @@ test_intersection_from_segment(const CollisionEntry &entry) const { return new_entry; } +/** + * Double dispatch point for tube as a FROM object + */ +PT(CollisionEntry) CollisionBox:: +test_intersection_from_tube(const CollisionEntry &entry) const { + const CollisionTube *tube; + DCAST_INTO_R(tube, entry.get_from(), nullptr); + + const LMatrix4 &wrt_mat = entry.get_wrt_mat(); + + LPoint3 from_a = tube->get_point_a() * wrt_mat; + LPoint3 from_b = tube->get_point_b() * wrt_mat; + LVector3 from_direction = from_b - from_a; + PN_stdfloat radius_sq = wrt_mat.xform_vec(LVector3(0, 0, tube->get_radius())).length_squared(); + PN_stdfloat radius = csqrt(radius_sq); + + LPoint3 box_min = get_min(); + LPoint3 box_max = get_max(); + LVector3 dimensions = box_max - box_min; + + // The method below is inspired by Christer Ericson's book Real-Time + // Collision Detection. Instead of testing a capsule against a box, we test + // a segment against an box that is oversized by the capsule radius. + + // First, we test if the line segment intersects a box with its faces + // expanded outwards by the capsule radius. If not, there is no collision. + double t1, t2; + if (!intersects_line(t1, t2, from_a, from_direction, radius)) { + return nullptr; + } + + if (t2 < 0.0 || t1 > 1.0) { + return nullptr; + } + + t1 = std::min(1.0, std::max(0.0, (t1 + t2) * 0.5)); + LPoint3 point = from_a + from_direction * t1; + + // We now have a point of intersection between the line segment and the + // oversized box. Check on how many axes it lies outside the box. If it is + // less than two, we know that it does not lie in one of the rounded regions + // of the oversized rounded box, and it is a guaranteed hit. Otherwise, we + // will need to test against the edge regions. + if ((point[0] < box_min[0] || point[0] > box_max[0]) + + (point[1] < box_min[1] || point[1] > box_max[1]) + + (point[2] < box_min[2] || point[2] > box_max[2]) > 1) { + // Test the capsule against each edge of the box. + static const struct { + LPoint3 point; + int axis; + } edges[] = { + {{0, 0, 0}, 0}, + {{0, 1, 0}, 0}, + {{0, 0, 1}, 0}, + {{0, 1, 1}, 0}, + {{0, 0, 0}, 1}, + {{0, 0, 1}, 1}, + {{1, 0, 0}, 1}, + {{1, 0, 1}, 1}, + {{0, 0, 0}, 2}, + {{0, 1, 0}, 2}, + {{1, 0, 0}, 2}, + {{1, 1, 0}, 2}, + }; + + PN_stdfloat best_dist_sq = FLT_MAX; + + for (int i = 0; i < 12; ++i) { + LPoint3 vertex = edges[i].point; + vertex.componentwise_mult(dimensions); + vertex += box_min; + LVector3 delta(0); + delta[edges[i].axis] = dimensions[edges[i].axis]; + double u1, u2; + CollisionTube::calc_closest_segment_points(u1, u2, from_a, from_direction, vertex, delta); + PN_stdfloat dist_sq = ((from_a + from_direction * u1) - (vertex + delta * u2)).length_squared(); + if (dist_sq < best_dist_sq) { + best_dist_sq = dist_sq; + } + } + + if (best_dist_sq > radius_sq) { + // It is not actually touching any edge. + return nullptr; + } + } + + if (collide_cat.is_debug()) { + collide_cat.debug() + << "intersection detected from " << entry.get_from_node_path() + << " into " << entry.get_into_node_path() << "\n"; + } + PT(CollisionEntry) new_entry = new CollisionEntry(entry); + + // Which is the longest axis? + LVector3 diff = point - _center; + diff[0] /= dimensions[0]; + diff[1] /= dimensions[1]; + diff[2] /= dimensions[2]; + int axis = 0; + if (cabs(diff[0]) > cabs(diff[1])) { + if (cabs(diff[0]) > cabs(diff[2])) { + axis = 0; + } else { + axis = 2; + } + } else { + if (cabs(diff[1]) > cabs(diff[2])) { + axis = 1; + } else { + axis = 2; + } + } + LVector3 normal(0); + normal[axis] = std::copysign(1, diff[axis]); + + LPoint3 clamped = point.fmax(box_min).fmin(box_max); + LPoint3 surface_point = clamped; + surface_point[axis] = (diff[axis] >= 0.0f) ? box_max[axis] : box_min[axis]; + + // Is the point inside the box? + LVector3 interior_vec; + if (clamped != point) { + // No, it is outside. The interior point is in the direction of the + // surface point. + interior_vec = point - surface_point; + if (!interior_vec.normalize()) { + interior_vec = normal; + } + } else { + // It is inside. I think any point will work for this. + interior_vec = normal; + } + new_entry->set_interior_point(point - interior_vec * radius); + new_entry->set_surface_point(surface_point); + + if (has_effective_normal() && tube->get_respect_effective_normal()) { + new_entry->set_surface_normal(get_effective_normal()); + } else { + new_entry->set_surface_normal(normal); + } + + return new_entry; +} + /** * Double dispatch point for box as a FROM object */ diff --git a/panda/src/collide/collisionBox.h b/panda/src/collide/collisionBox.h index 0810aa95e2..cf9e8bc15b 100644 --- a/panda/src/collide/collisionBox.h +++ b/panda/src/collide/collisionBox.h @@ -81,6 +81,8 @@ protected: test_intersection_from_ray(const CollisionEntry &entry) const; virtual PT(CollisionEntry) test_intersection_from_segment(const CollisionEntry &entry) const; + virtual PT(CollisionEntry) + test_intersection_from_tube(const CollisionEntry &entry) const; virtual PT(CollisionEntry) test_intersection_from_box(const CollisionEntry &entry) const; diff --git a/panda/src/collide/collisionTube.h b/panda/src/collide/collisionTube.h index 70f1832b9b..3d91ce2506 100644 --- a/panda/src/collide/collisionTube.h +++ b/panda/src/collide/collisionTube.h @@ -151,6 +151,8 @@ public: private: static TypeHandle _type_handle; + + friend class CollisionBox; }; #include "collisionTube.I" From 247575df62f1c3b0bbda84abf503c8646cbe15ef Mon Sep 17 00:00:00 2001 From: Mitchell Stokes Date: Mon, 30 Jul 2018 21:02:55 -0700 Subject: [PATCH 068/125] CoordinateSystem: Document enumerators --- panda/src/linmath/coordinateSystem.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/panda/src/linmath/coordinateSystem.h b/panda/src/linmath/coordinateSystem.h index 313645a35e..b365297f84 100644 --- a/panda/src/linmath/coordinateSystem.h +++ b/panda/src/linmath/coordinateSystem.h @@ -26,10 +26,10 @@ enum CoordinateSystem { // turn is loaded from the config variable "coordinate-system". CS_default, - CS_zup_right, - CS_yup_right, - CS_zup_left, - CS_yup_left, + CS_zup_right, // Z-Up, Right-handed + CS_yup_right, // Y-Up, Right-handed + CS_zup_left, // Z-Up, Left-handed + CS_yup_left, // Y-Up, Left-handed // CS_invalid is not a coordinate system at all. It can be used in user- // input processing code to indicate a contradictory coordinate system From 079a7495f279080b6745ea4fceb5a313aca3d4b8 Mon Sep 17 00:00:00 2001 From: rdb Date: Tue, 31 Jul 2018 10:47:16 +0200 Subject: [PATCH 069/125] Fix macOS build by providing missing std::copysign --- dtool/src/dtoolbase/dtoolbase_cc.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dtool/src/dtoolbase/dtoolbase_cc.h b/dtool/src/dtoolbase/dtoolbase_cc.h index 3af3c9c250..ff52c6291a 100644 --- a/dtool/src/dtoolbase/dtoolbase_cc.h +++ b/dtool/src/dtoolbase/dtoolbase_cc.h @@ -97,10 +97,12 @@ typedef std::ios::seekdir ios_seekdir; // in some important missing functions. #if defined(__GLIBCXX__) && __GLIBCXX__ <= 20070719 #include +#include namespace std { using std::tr1::tuple; using std::tr1::tie; + using std::tr1::copysign; typedef decltype(nullptr) nullptr_t; From 4e42c4c94173e09d8638e50b230966653afc766f Mon Sep 17 00:00:00 2001 From: rdb Date: Tue, 31 Jul 2018 11:08:14 +0200 Subject: [PATCH 070/125] nativenet: fix interrogate error recognizing sockaddr types --- panda/src/nativenet/socket_portable.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/panda/src/nativenet/socket_portable.h b/panda/src/nativenet/socket_portable.h index d4bdd1fa98..a4a249f92e 100644 --- a/panda/src/nativenet/socket_portable.h +++ b/panda/src/nativenet/socket_portable.h @@ -12,7 +12,9 @@ const int BASIC_ERROR = -1; // Interrogate doesn't need to parse any of this. typedef unsigned long SOCKET; -typedef unsigned short sa_family_t; + +#include +#include /************************************************************************ * HP SOCKET LIBRARY STUFF From fe1bfef5c01281dd42b7e2fd7d99f46233ae6d61 Mon Sep 17 00:00:00 2001 From: rdb Date: Tue, 31 Jul 2018 14:02:58 +0200 Subject: [PATCH 071/125] express: fix a few compile errors with certain WeakPointerTo uses Fixes #367 --- panda/src/express/weakPointerToBase.I | 48 +++++++++++++++++++++++++++ panda/src/express/weakPointerToBase.h | 7 ++++ 2 files changed, 55 insertions(+) diff --git a/panda/src/express/weakPointerToBase.I b/panda/src/express/weakPointerToBase.I index 8c6de65523..5673114764 100644 --- a/panda/src/express/weakPointerToBase.I +++ b/panda/src/express/weakPointerToBase.I @@ -72,6 +72,26 @@ WeakPointerToBase(WeakPointerToBase &&from) noexcept { from._weak_ref = nullptr; } +/** + * Copies a weak pointer from a cast-convertible weak pointer type. + */ +template +template +INLINE WeakPointerToBase:: +WeakPointerToBase(const WeakPointerToBase &r) { + // If this next line gives an error, you are trying to convert a WeakPointerTo + // from an incompatible type of another WeakPointerTo. + To *ptr = (Y *)r._void_ptr; + + this->_void_ptr = ptr; + + WeakReferenceList *weak_ref = r._weak_ref; + if (weak_ref != nullptr) { + _weak_ref = weak_ref; + weak_ref->ref(); + } +} + /** * Moves a weak pointer from a cast-convertible weak pointer type. */ @@ -190,6 +210,34 @@ reassign(WeakPointerToBase &&from) noexcept { } } +/** + * Like above, but casts from a compatible pointer type. + */ +template +template +INLINE void WeakPointerToBase:: +reassign(const WeakPointerToBase ©) { + // If there is a compile error on this line, it means you tried to assign + // an incompatible type. + To *new_ptr = (Y *)copy._void_ptr; + + if (new_ptr != (To *)_void_ptr) { + WeakReferenceList *old_ref = (WeakReferenceList *)_weak_ref; + WeakReferenceList *new_ref = copy._weak_ref; + _void_ptr = new_ptr; + _weak_ref = new_ref; + + if (new_ref != nullptr) { + new_ref->ref(); + } + + // Now remove the old reference. + if (old_ref != nullptr && !old_ref->unref()) { + delete old_ref; + } + } +} + /** * Like above, but casts from a compatible pointer type. */ diff --git a/panda/src/express/weakPointerToBase.h b/panda/src/express/weakPointerToBase.h index 474514b055..291cd587e4 100644 --- a/panda/src/express/weakPointerToBase.h +++ b/panda/src/express/weakPointerToBase.h @@ -34,6 +34,8 @@ protected: INLINE WeakPointerToBase(const WeakPointerToBase ©); INLINE WeakPointerToBase(WeakPointerToBase &&from) noexcept; template + INLINE WeakPointerToBase(const WeakPointerToBase &r); + template INLINE WeakPointerToBase(WeakPointerToBase &&r) noexcept; INLINE ~WeakPointerToBase(); @@ -43,6 +45,8 @@ protected: INLINE void reassign(const WeakPointerToBase ©); INLINE void reassign(WeakPointerToBase &&from) noexcept; template + INLINE void reassign(const WeakPointerToBase ©); + template INLINE void reassign(WeakPointerToBase &&from) noexcept; INLINE void update_type(To *ptr); @@ -96,6 +100,9 @@ public: template INLINE bool owner_before(const PointerToBase &other) const noexcept; + // This is needed to be able to access the privates of other instantiations. + template friend class WeakPointerToBase; + PUBLISHED: INLINE void clear(); INLINE void refresh() const; From 30721ba33bbd4f90c40e61825f47571ac6ff3893 Mon Sep 17 00:00:00 2001 From: rdb Date: Tue, 31 Jul 2018 14:05:08 +0200 Subject: [PATCH 072/125] cppparser: fix issues when parsing templated constructor definition --- dtool/src/cppparser/cppBison.cxx.prebuilt | 2759 +++++++++++---------- dtool/src/cppparser/cppBison.h.prebuilt | 4 +- dtool/src/cppparser/cppBison.yxx | 32 +- 3 files changed, 1420 insertions(+), 1375 deletions(-) diff --git a/dtool/src/cppparser/cppBison.cxx.prebuilt b/dtool/src/cppparser/cppBison.cxx.prebuilt index 4bff774461..be3f2b4e95 100644 --- a/dtool/src/cppparser/cppBison.cxx.prebuilt +++ b/dtool/src/cppparser/cppBison.cxx.prebuilt @@ -1,8 +1,8 @@ -/* A Bison parser, made by GNU Bison 3.0.4. */ +/* A Bison parser, made by GNU Bison 3.0.5. */ /* Bison implementation for Yacc-like parsers in C - Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc. + Copyright (C) 1984, 1989-1990, 2000-2015, 2018 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -44,7 +44,7 @@ #define YYBISON 1 /* Bison version. */ -#define YYBISON_VERSION "3.0.4" +#define YYBISON_VERSION "3.0.5" /* Skeleton name. */ #define YYSKELETON_NAME "yacc.c" @@ -104,15 +104,15 @@ using std::string; // Defining the interface to the parser. //////////////////////////////////////////////////////////////////// -CPPScope *current_scope = NULL; -CPPScope *global_scope = NULL; -CPPPreprocessor *current_lexer = NULL; +CPPScope *current_scope = nullptr; +CPPScope *global_scope = nullptr; +CPPPreprocessor *current_lexer = nullptr; -static CPPStructType *current_struct = NULL; -static CPPEnumType *current_enum = NULL; +static CPPStructType *current_struct = nullptr; +static CPPEnumType *current_enum = nullptr; static int current_storage_class = 0; -static CPPType *current_type = NULL; -static CPPExpression *current_expr = NULL; +static CPPType *current_type = nullptr; +static CPPExpression *current_expr = nullptr; static int publish_nest_level = 0; static CPPVisibility publish_previous; static YYLTYPE publish_loc; @@ -186,7 +186,7 @@ parse_const_expr(CPPPreprocessor *pp, CPPScope *new_current_scope, current_scope = new_current_scope; global_scope = new_global_scope; - current_expr = (CPPExpression *)NULL; + current_expr = nullptr; current_lexer = pp; yyparse(); @@ -210,7 +210,7 @@ parse_type(CPPPreprocessor *pp, CPPScope *new_current_scope, current_scope = new_current_scope; global_scope = new_global_scope; - current_type = (CPPType *)NULL; + current_type = nullptr; current_lexer = pp; yyparse(); @@ -227,7 +227,7 @@ parse_type(CPPPreprocessor *pp, CPPScope *new_current_scope, static void push_scope(CPPScope *new_scope) { last_scopes.push_back(current_scope); - if (new_scope != NULL) { + if (new_scope != nullptr) { current_scope = new_scope; } } @@ -266,7 +266,7 @@ pop_struct() { } -#line 268 "built/tmp/cppBison.yxx.c" /* yacc.c:339 */ +#line 270 "built/tmp/cppBison.yxx.c" /* yacc.c:339 */ # ifndef YY_NULLPTR # if defined __cplusplus && 201103L <= __cplusplus @@ -617,7 +617,7 @@ int cppyyparse (void); /* Copy the second part of user declarations. */ -#line 619 "built/tmp/cppBison.yxx.c" /* yacc.c:358 */ +#line 621 "built/tmp/cppBison.yxx.c" /* yacc.c:358 */ #ifdef short # undef short @@ -931,83 +931,83 @@ static const yytype_uint8 yytranslate[] = /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ static const yytype_uint16 yyrline[] = { - 0, 450, 450, 451, 455, 462, 463, 464, 468, 469, - 473, 477, 481, 494, 493, 505, 506, 507, 508, 509, - 510, 511, 524, 533, 537, 545, 549, 553, 574, 601, - 622, 651, 687, 730, 742, 763, 799, 833, 855, 891, - 913, 924, 938, 937, 952, 956, 961, 965, 976, 980, - 984, 988, 992, 996, 1000, 1004, 1008, 1012, 1016, 1020, - 1025, 1029, 1036, 1037, 1041, 1042, 1043, 1048, 1047, 1063, - 1073, 1072, 1089, 1097, 1105, 1116, 1132, 1131, 1146, 1161, - 1170, 1185, 1184, 1209, 1208, 1236, 1235, 1266, 1265, 1284, - 1283, 1304, 1303, 1335, 1334, 1360, 1373, 1377, 1381, 1385, - 1398, 1402, 1406, 1410, 1414, 1419, 1424, 1428, 1432, 1436, - 1443, 1447, 1451, 1455, 1459, 1463, 1467, 1471, 1475, 1479, - 1483, 1487, 1491, 1495, 1499, 1503, 1507, 1511, 1515, 1519, - 1523, 1527, 1531, 1535, 1539, 1543, 1547, 1551, 1555, 1559, - 1563, 1567, 1571, 1575, 1579, 1583, 1587, 1591, 1595, 1602, - 1603, 1604, 1608, 1610, 1609, 1617, 1618, 1622, 1623, 1627, - 1633, 1642, 1643, 1647, 1651, 1655, 1659, 1665, 1671, 1677, - 1684, 1689, 1698, 1702, 1707, 1715, 1727, 1731, 1745, 1760, - 1765, 1770, 1775, 1780, 1785, 1790, 1795, 1801, 1800, 1831, - 1841, 1851, 1855, 1859, 1868, 1872, 1880, 1884, 1889, 1893, - 1898, 1906, 1911, 1919, 1923, 1928, 1932, 1937, 1945, 1950, - 1958, 1962, 1969, 1973, 1980, 1984, 1988, 1992, 1996, 2003, - 2007, 2011, 2015, 2019, 2023, 2030, 2031, 2032, 2036, 2039, - 2040, 2041, 2045, 2050, 2056, 2062, 2067, 2073, 2079, 2083, - 2094, 2098, 2108, 2112, 2116, 2121, 2126, 2131, 2136, 2141, - 2146, 2154, 2158, 2162, 2167, 2172, 2177, 2182, 2187, 2192, - 2197, 2203, 2211, 2216, 2221, 2226, 2231, 2236, 2241, 2246, - 2251, 2256, 2262, 2270, 2274, 2279, 2284, 2289, 2294, 2299, - 2304, 2309, 2314, 2322, 2326, 2331, 2336, 2341, 2346, 2351, - 2356, 2361, 2366, 2371, 2377, 2384, 2391, 2401, 2405, 2413, - 2417, 2421, 2425, 2429, 2445, 2461, 2470, 2474, 2484, 2491, - 2502, 2506, 2514, 2518, 2522, 2526, 2530, 2546, 2562, 2580, - 2589, 2593, 2603, 2610, 2614, 2622, 2626, 2642, 2658, 2667, - 2677, 2684, 2688, 2696, 2700, 2705, 2709, 2717, 2718, 2719, - 2720, 2725, 2724, 2749, 2748, 2778, 2779, 2786, 2787, 2791, - 2792, 2796, 2800, 2804, 2808, 2812, 2816, 2820, 2824, 2828, - 2832, 2839, 2847, 2851, 2855, 2860, 2868, 2872, 2879, 2880, - 2885, 2892, 2893, 2898, 2906, 2910, 2914, 2921, 2925, 2929, - 2937, 2936, 2959, 2958, 2981, 2982, 2986, 2992, 2999, 3008, - 3009, 3010, 3014, 3018, 3022, 3026, 3030, 3034, 3039, 3044, - 3049, 3054, 3058, 3063, 3072, 3077, 3085, 3089, 3093, 3101, - 3111, 3111, 3121, 3122, 3126, 3127, 3128, 3129, 3130, 3131, - 3132, 3133, 3134, 3135, 3136, 3137, 3137, 3137, 3138, 3138, - 3138, 3138, 3139, 3139, 3139, 3139, 3139, 3140, 3140, 3140, - 3141, 3141, 3141, 3141, 3141, 3142, 3142, 3142, 3142, 3142, - 3143, 3143, 3144, 3144, 3144, 3144, 3144, 3145, 3145, 3145, - 3145, 3145, 3146, 3146, 3146, 3146, 3147, 3147, 3147, 3147, - 3147, 3148, 3148, 3148, 3148, 3148, 3149, 3149, 3149, 3149, - 3149, 3149, 3150, 3150, 3150, 3150, 3150, 3151, 3151, 3151, - 3151, 3152, 3152, 3152, 3152, 3153, 3153, 3153, 3153, 3153, - 3154, 3154, 3154, 3154, 3155, 3155, 3155, 3155, 3155, 3156, - 3156, 3156, 3156, 3157, 3157, 3157, 3157, 3157, 3158, 3158, - 3161, 3161, 3161, 3161, 3161, 3161, 3161, 3161, 3161, 3161, - 3161, 3162, 3162, 3162, 3162, 3162, 3162, 3162, 3162, 3162, - 3162, 3163, 3163, 3167, 3171, 3178, 3182, 3189, 3193, 3200, - 3204, 3208, 3212, 3216, 3220, 3224, 3228, 3240, 3244, 3248, - 3252, 3256, 3260, 3264, 3268, 3272, 3276, 3280, 3284, 3288, - 3292, 3296, 3300, 3304, 3308, 3312, 3316, 3320, 3324, 3328, - 3332, 3336, 3340, 3344, 3348, 3352, 3356, 3360, 3368, 3372, - 3376, 3380, 3384, 3388, 3392, 3402, 3412, 3418, 3424, 3430, - 3436, 3442, 3448, 3455, 3462, 3469, 3476, 3482, 3488, 3492, - 3504, 3508, 3512, 3516, 3520, 3531, 3542, 3546, 3550, 3554, - 3558, 3562, 3566, 3570, 3574, 3578, 3582, 3586, 3590, 3594, - 3598, 3602, 3606, 3610, 3614, 3618, 3622, 3626, 3630, 3634, - 3638, 3642, 3646, 3650, 3654, 3658, 3662, 3669, 3673, 3677, - 3681, 3685, 3689, 3693, 3697, 3701, 3707, 3713, 3717, 3723, - 3730, 3734, 3738, 3742, 3746, 3750, 3754, 3758, 3762, 3766, - 3770, 3774, 3778, 3782, 3786, 3790, 3794, 3808, 3812, 3816, - 3820, 3824, 3828, 3832, 3836, 3848, 3852, 3856, 3860, 3864, - 3875, 3886, 3890, 3894, 3898, 3902, 3906, 3910, 3914, 3918, - 3922, 3926, 3930, 3934, 3938, 3942, 3946, 3950, 3954, 3958, - 3962, 3966, 3970, 3974, 3978, 3982, 3986, 3990, 3994, 3998, - 4002, 4009, 4013, 4017, 4021, 4025, 4029, 4033, 4037, 4041, - 4047, 4053, 4061, 4065, 4069, 4073, 4080, 4090, 4096, 4102, - 4112, 4124, 4132, 4136, 4166, 4170, 4174, 4178, 4182, 4186, - 4192, 4196, 4200, 4204, 4208, 4219, 4223, 4227, 4231, 4239, - 4243, 4247, 4253, 4264 + 0, 452, 452, 453, 457, 464, 465, 466, 470, 471, + 475, 479, 483, 496, 495, 507, 508, 509, 510, 511, + 512, 513, 526, 535, 539, 547, 551, 555, 576, 603, + 624, 653, 689, 732, 744, 765, 801, 835, 857, 893, + 915, 926, 940, 939, 954, 958, 963, 967, 978, 982, + 986, 990, 994, 998, 1002, 1006, 1010, 1014, 1018, 1022, + 1027, 1031, 1038, 1039, 1043, 1044, 1045, 1050, 1049, 1065, + 1075, 1074, 1091, 1099, 1107, 1118, 1134, 1133, 1148, 1163, + 1172, 1187, 1186, 1224, 1223, 1260, 1259, 1290, 1289, 1308, + 1307, 1328, 1327, 1359, 1358, 1384, 1397, 1401, 1405, 1409, + 1422, 1426, 1430, 1434, 1438, 1443, 1448, 1452, 1456, 1460, + 1467, 1471, 1475, 1479, 1483, 1487, 1491, 1495, 1499, 1503, + 1507, 1511, 1515, 1519, 1523, 1527, 1531, 1535, 1539, 1543, + 1547, 1551, 1555, 1559, 1563, 1567, 1571, 1575, 1579, 1583, + 1587, 1591, 1595, 1599, 1603, 1607, 1611, 1615, 1619, 1626, + 1627, 1628, 1632, 1634, 1633, 1641, 1642, 1646, 1647, 1651, + 1657, 1666, 1667, 1671, 1675, 1679, 1683, 1689, 1695, 1701, + 1708, 1713, 1722, 1726, 1731, 1739, 1751, 1755, 1769, 1784, + 1789, 1794, 1799, 1804, 1809, 1814, 1819, 1825, 1824, 1855, + 1865, 1875, 1879, 1883, 1892, 1896, 1904, 1908, 1913, 1917, + 1922, 1930, 1935, 1943, 1947, 1952, 1956, 1961, 1969, 1974, + 1982, 1986, 1993, 1997, 2004, 2008, 2012, 2016, 2020, 2027, + 2031, 2035, 2039, 2043, 2047, 2054, 2055, 2056, 2060, 2063, + 2064, 2065, 2069, 2074, 2080, 2086, 2091, 2097, 2103, 2107, + 2118, 2122, 2132, 2136, 2140, 2145, 2150, 2155, 2160, 2165, + 2170, 2178, 2182, 2186, 2191, 2196, 2201, 2206, 2211, 2216, + 2221, 2227, 2235, 2240, 2245, 2250, 2255, 2260, 2265, 2270, + 2275, 2280, 2286, 2294, 2298, 2303, 2308, 2313, 2318, 2323, + 2328, 2333, 2338, 2346, 2350, 2355, 2360, 2365, 2370, 2375, + 2380, 2385, 2390, 2395, 2401, 2408, 2415, 2425, 2429, 2437, + 2441, 2445, 2449, 2453, 2469, 2485, 2494, 2498, 2508, 2515, + 2526, 2530, 2538, 2542, 2546, 2550, 2554, 2570, 2586, 2604, + 2613, 2617, 2627, 2634, 2638, 2646, 2650, 2666, 2682, 2691, + 2701, 2708, 2712, 2720, 2724, 2729, 2733, 2741, 2742, 2743, + 2744, 2749, 2748, 2773, 2772, 2802, 2803, 2810, 2811, 2815, + 2816, 2820, 2824, 2828, 2832, 2836, 2840, 2844, 2848, 2852, + 2856, 2863, 2871, 2875, 2879, 2884, 2892, 2896, 2903, 2904, + 2909, 2916, 2917, 2922, 2930, 2934, 2938, 2945, 2949, 2953, + 2961, 2960, 2983, 2982, 3005, 3006, 3010, 3016, 3023, 3032, + 3033, 3034, 3038, 3042, 3046, 3050, 3054, 3058, 3063, 3068, + 3073, 3078, 3082, 3087, 3096, 3101, 3109, 3113, 3117, 3125, + 3135, 3135, 3145, 3146, 3150, 3151, 3152, 3153, 3154, 3155, + 3156, 3157, 3158, 3159, 3160, 3161, 3161, 3161, 3162, 3162, + 3162, 3162, 3163, 3163, 3163, 3163, 3163, 3164, 3164, 3164, + 3165, 3165, 3165, 3165, 3165, 3166, 3166, 3166, 3166, 3166, + 3167, 3167, 3168, 3168, 3168, 3168, 3168, 3169, 3169, 3169, + 3169, 3169, 3170, 3170, 3170, 3170, 3171, 3171, 3171, 3171, + 3171, 3172, 3172, 3172, 3172, 3172, 3173, 3173, 3173, 3173, + 3173, 3173, 3174, 3174, 3174, 3174, 3174, 3175, 3175, 3175, + 3175, 3176, 3176, 3176, 3176, 3177, 3177, 3177, 3177, 3177, + 3178, 3178, 3178, 3178, 3179, 3179, 3179, 3179, 3179, 3180, + 3180, 3180, 3180, 3181, 3181, 3181, 3181, 3181, 3182, 3182, + 3185, 3185, 3185, 3185, 3185, 3185, 3185, 3185, 3185, 3185, + 3185, 3186, 3186, 3186, 3186, 3186, 3186, 3186, 3186, 3186, + 3186, 3187, 3187, 3191, 3195, 3202, 3206, 3213, 3217, 3224, + 3228, 3232, 3236, 3240, 3244, 3248, 3252, 3264, 3268, 3272, + 3276, 3280, 3284, 3288, 3292, 3296, 3300, 3304, 3308, 3312, + 3316, 3320, 3324, 3328, 3332, 3336, 3340, 3344, 3348, 3352, + 3356, 3360, 3364, 3368, 3372, 3376, 3380, 3384, 3392, 3396, + 3400, 3404, 3408, 3412, 3416, 3426, 3436, 3442, 3448, 3454, + 3460, 3466, 3472, 3479, 3486, 3493, 3500, 3506, 3512, 3516, + 3528, 3532, 3536, 3540, 3544, 3555, 3566, 3570, 3574, 3578, + 3582, 3586, 3590, 3594, 3598, 3602, 3606, 3610, 3614, 3618, + 3622, 3626, 3630, 3634, 3638, 3642, 3646, 3650, 3654, 3658, + 3662, 3666, 3670, 3674, 3678, 3682, 3686, 3693, 3697, 3701, + 3705, 3709, 3713, 3717, 3721, 3725, 3731, 3737, 3741, 3747, + 3754, 3758, 3762, 3766, 3770, 3774, 3778, 3782, 3786, 3790, + 3794, 3798, 3802, 3806, 3810, 3814, 3818, 3832, 3836, 3840, + 3844, 3848, 3852, 3856, 3860, 3872, 3876, 3880, 3884, 3888, + 3899, 3910, 3914, 3918, 3922, 3926, 3930, 3934, 3938, 3942, + 3946, 3950, 3954, 3958, 3962, 3966, 3970, 3974, 3978, 3982, + 3986, 3990, 3994, 3998, 4002, 4006, 4010, 4014, 4018, 4022, + 4026, 4033, 4037, 4041, 4045, 4049, 4053, 4057, 4061, 4065, + 4071, 4077, 4085, 4089, 4093, 4097, 4104, 4114, 4120, 4126, + 4136, 4148, 4156, 4160, 4190, 4194, 4198, 4202, 4206, 4210, + 4216, 4220, 4224, 4228, 4232, 4243, 4247, 4251, 4255, 4263, + 4267, 4271, 4277, 4288 }; #endif @@ -3673,6 +3673,7 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, case N: \ yyformat = S; \ break + default: /* Avoid compiler warnings. */ YYCASE_(0, YY_("syntax error")); YYCASE_(1, YY_("syntax error, unexpected %s")); YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s")); @@ -4014,70 +4015,71 @@ yyreduce: GCC warning that YYVAL may be used uninitialized. */ yyval = yyvsp[1-yylen]; - /* Default location. */ + /* Default location. */ YYLLOC_DEFAULT (yyloc, (yylsp - yylen), yylen); + yyerror_range[1] = yyloc; YY_REDUCE_PRINT (yyn); switch (yyn) { case 3: -#line 452 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 454 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { current_expr = (yyvsp[0].u.expr); } -#line 4026 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 4030 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 4: -#line 456 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 458 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { current_type = (yyvsp[0].u.type); } -#line 4034 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 4038 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 10: -#line 474 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 476 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { delete (yyvsp[-1].u.expr); } -#line 4042 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 4046 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 11: -#line 478 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 480 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { delete (yyvsp[-2].u.expr); } -#line 4050 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 4054 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 12: -#line 482 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 484 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { delete (yyvsp[-1].u.expr); } -#line 4058 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 4062 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 13: -#line 494 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 496 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { push_storage_class((current_storage_class & ~CPPInstance::SC_c_binding) | ((yyvsp[-1].u.integer) & CPPInstance::SC_c_binding)); } -#line 4067 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 4071 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 14: -#line 499 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 501 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { pop_storage_class(); } -#line 4075 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 4079 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 21: -#line 512 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 514 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { if (publish_nest_level != 0) { yyerror("Unclosed __begin_publish", publish_loc); @@ -4090,11 +4092,11 @@ yyreduce: publish_nest_level++; current_scope->set_current_vis(V_published); } -#line 4092 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 4096 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 22: -#line 525 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 527 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { if (publish_nest_level != 1) { yyerror("Unmatched __end_publish", (yylsp[0])); @@ -4103,19 +4105,19 @@ yyreduce: } publish_nest_level = 0; } -#line 4105 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 4109 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 23: -#line 534 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 536 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { current_scope->set_current_vis(V_published); } -#line 4113 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 4117 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 24: -#line 538 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 540 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { if (publish_nest_level > 0) { current_scope->set_current_vis(V_published); @@ -4123,27 +4125,27 @@ yyreduce: current_scope->set_current_vis(V_public); } } -#line 4125 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 4129 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 25: -#line 546 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 548 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { current_scope->set_current_vis(V_protected); } -#line 4133 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 4137 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 26: -#line 550 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 552 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { current_scope->set_current_vis(V_private); } -#line 4141 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 4145 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 27: -#line 554 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 556 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { CPPDeclaration *getter = (yyvsp[-3].u.identifier)->find_symbol(current_scope, global_scope, current_lexer); if (getter == nullptr || getter->get_subtype() != CPPDeclaration::ST_function_group) { @@ -4164,11 +4166,11 @@ yyreduce: current_scope->add_declaration(make_property, global_scope, current_lexer, (yylsp[-7])); } } -#line 4166 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 4170 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 28: -#line 575 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 577 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { CPPDeclaration *getter = (yyvsp[-6].u.identifier)->find_symbol(current_scope, global_scope, current_lexer); if (getter == nullptr || getter->get_subtype() != CPPDeclaration::ST_function_group) { @@ -4195,11 +4197,11 @@ yyreduce: current_scope->add_declaration(make_property, global_scope, current_lexer, (yylsp[-10])); } } -#line 4197 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 4201 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 29: -#line 602 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 604 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { CPPDeclaration *length_getter = (yyvsp[-4].u.identifier)->find_symbol(current_scope, global_scope, current_lexer); if (length_getter == nullptr || length_getter->get_subtype() != CPPDeclaration::ST_function_group) { @@ -4220,11 +4222,11 @@ yyreduce: current_scope->add_declaration(make_property, global_scope, current_lexer, (yylsp[-8])); } } -#line 4222 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 4226 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 30: -#line 623 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 625 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { CPPDeclaration *length_getter = (yyvsp[-6].u.identifier)->find_symbol(current_scope, global_scope, current_lexer); if (length_getter == nullptr || length_getter->get_subtype() != CPPDeclaration::ST_function_group) { @@ -4253,16 +4255,16 @@ yyreduce: current_scope->add_declaration(make_property, global_scope, current_lexer, (yylsp[-10])); } } -#line 4255 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 4259 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 31: -#line 652 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 654 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { CPPDeclaration *length_getter = (yyvsp[-8].u.identifier)->find_symbol(current_scope, global_scope, current_lexer); if (length_getter == nullptr || length_getter->get_subtype() != CPPDeclaration::ST_function_group) { yyerror("reference to non-existent or invalid length method: " + (yyvsp[-8].u.identifier)->get_fully_scoped_name(), (yylsp[-8])); - length_getter = NULL; + length_getter = nullptr; } CPPDeclaration *getter = (yyvsp[-6].u.identifier)->find_symbol(current_scope, global_scope, current_lexer); @@ -4293,16 +4295,16 @@ yyreduce: current_scope->add_declaration(make_property, global_scope, current_lexer, (yylsp[-12])); } } -#line 4295 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 4299 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 32: -#line 688 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 690 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { CPPDeclaration *length_getter = (yyvsp[-10].u.identifier)->find_symbol(current_scope, global_scope, current_lexer); if (length_getter == nullptr || length_getter->get_subtype() != CPPDeclaration::ST_function_group) { yyerror("reference to non-existent or invalid length method: " + (yyvsp[-10].u.identifier)->get_fully_scoped_name(), (yylsp[-10])); - length_getter = NULL; + length_getter = nullptr; } CPPDeclaration *getter = (yyvsp[-8].u.identifier)->find_symbol(current_scope, global_scope, current_lexer); @@ -4340,11 +4342,11 @@ yyreduce: current_scope->add_declaration(make_property, global_scope, current_lexer, (yylsp[-14])); } } -#line 4342 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 4346 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 33: -#line 731 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 733 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { CPPDeclaration *getter = (yyvsp[-2].u.identifier)->find_symbol(current_scope, global_scope, current_lexer); if (getter == nullptr || getter->get_subtype() != CPPDeclaration::ST_function_group) { @@ -4356,11 +4358,11 @@ yyreduce: current_scope->add_declaration(make_property, global_scope, current_lexer, (yylsp[-6])); } } -#line 4358 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 4362 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 34: -#line 743 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 745 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { CPPDeclaration *getter = (yyvsp[-2].u.identifier)->find_symbol(current_scope, global_scope, current_lexer); if (getter == nullptr || getter->get_subtype() != CPPDeclaration::ST_function_group) { @@ -4381,11 +4383,11 @@ yyreduce: current_scope->add_declaration(make_property, global_scope, current_lexer, (yylsp[-8])); } } -#line 4383 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 4387 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 35: -#line 764 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 766 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { CPPDeclaration *getter = (yyvsp[-5].u.identifier)->find_symbol(current_scope, global_scope, current_lexer); if (getter == nullptr || getter->get_subtype() != CPPDeclaration::ST_function_group) { @@ -4421,11 +4423,11 @@ yyreduce: current_scope->add_declaration(make_property, global_scope, current_lexer, (yylsp[-11])); } } -#line 4423 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 4427 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 36: -#line 800 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 802 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { CPPDeclaration *length_getter = (yyvsp[-4].u.identifier)->find_symbol(current_scope, global_scope, current_lexer); if (length_getter == nullptr || length_getter->get_subtype() != CPPDeclaration::ST_function_group) { @@ -4459,11 +4461,11 @@ yyreduce: } } } -#line 4461 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 4465 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 37: -#line 834 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 836 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { CPPDeclaration *getter = (yyvsp[-2].u.identifier)->find_symbol(current_scope, global_scope, current_lexer); if (getter == nullptr || getter->get_subtype() != CPPDeclaration::ST_function_group) { @@ -4485,11 +4487,11 @@ yyreduce: current_scope->add_declaration(make_property, global_scope, current_lexer, (yylsp[-8])); } } -#line 4487 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 4491 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 38: -#line 856 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 858 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { CPPDeclaration *getter = (yyvsp[-6].u.identifier)->find_symbol(current_scope, global_scope, current_lexer); if (getter == nullptr || getter->get_subtype() != CPPDeclaration::ST_function_group) { @@ -4525,25 +4527,25 @@ yyreduce: current_scope->add_declaration(make_property, global_scope, current_lexer, (yylsp[-12])); } } -#line 4527 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 4531 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 39: -#line 892 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 894 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { CPPDeclaration *length_getter = (yyvsp[-4].u.identifier)->find_symbol(current_scope, global_scope, current_lexer); - if (length_getter == (CPPDeclaration *)NULL || length_getter->get_subtype() != CPPDeclaration::ST_function_group) { + if (length_getter == nullptr || length_getter->get_subtype() != CPPDeclaration::ST_function_group) { yyerror("reference to non-existent or invalid length method: " + (yyvsp[-4].u.identifier)->get_fully_scoped_name(), (yylsp[-4])); - length_getter = NULL; + length_getter = nullptr; } CPPDeclaration *element_getter = (yyvsp[-2].u.identifier)->find_symbol(current_scope, global_scope, current_lexer); - if (element_getter == (CPPDeclaration *)NULL || element_getter->get_subtype() != CPPDeclaration::ST_function_group) { + if (element_getter == nullptr || element_getter->get_subtype() != CPPDeclaration::ST_function_group) { yyerror("reference to non-existent or invalid element method: " + (yyvsp[-2].u.identifier)->get_fully_scoped_name(), (yylsp[-4])); - element_getter = NULL; + element_getter = nullptr; } - if (length_getter != (CPPDeclaration *)NULL && element_getter != (CPPDeclaration *)NULL) { + if (length_getter != nullptr && element_getter != nullptr) { CPPMakeSeq *make_seq = new CPPMakeSeq((yyvsp[-6].u.identifier), length_getter->as_function_group(), element_getter->as_function_group(), @@ -4551,11 +4553,11 @@ yyreduce: current_scope->add_declaration(make_seq, global_scope, current_lexer, (yylsp[-8])); } } -#line 4553 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 4557 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 40: -#line 914 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 916 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { CPPExpression::Result result = (yyvsp[-4].u.expr)->evaluate(); if (result._type == CPPExpression::RT_error) { @@ -4566,11 +4568,11 @@ yyreduce: yywarning("static_assert failed: " + str.str(), (yylsp[-4])); } } -#line 4568 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 4572 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 41: -#line 925 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 927 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { // This alternative version of static_assert was introduced in C++17. CPPExpression::Result result = (yyvsp[-2].u.expr)->evaluate(); @@ -4580,55 +4582,55 @@ yyreduce: yywarning("static_assert failed", (yylsp[-2])); } } -#line 4582 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 4586 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 42: -#line 938 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 940 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { CPPScope *new_scope = new CPPScope(current_scope, CPPNameComponent("temp"), V_public); push_scope(new_scope); } -#line 4592 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 4596 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 43: -#line 944 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 946 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { delete current_scope; pop_scope(); } -#line 4601 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 4605 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 44: -#line 953 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 955 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.integer) = 0; } -#line 4609 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 4613 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 45: -#line 957 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 959 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { // This isn't really a storage class, but it helps with parsing. (yyval.u.integer) = (yyvsp[0].u.integer) | (int)CPPInstance::SC_const; } -#line 4618 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 4622 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 46: -#line 962 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 964 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.integer) = (yyvsp[0].u.integer) | (int)CPPInstance::SC_extern; } -#line 4626 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 4630 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 47: -#line 966 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 968 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.integer) = (yyvsp[0].u.integer) | (int)CPPInstance::SC_extern; if ((yyvsp[-1].str) == "C") { @@ -4639,124 +4641,124 @@ yyreduce: yywarning("Ignoring unknown linkage type \"" + (yyvsp[-1].str) + "\"", (yylsp[-1])); } } -#line 4641 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 4645 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 48: -#line 977 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 979 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.integer) = (yyvsp[0].u.integer) | (int)CPPInstance::SC_static; } -#line 4649 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 4653 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 49: -#line 981 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 983 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.integer) = (yyvsp[0].u.integer) | (int)CPPInstance::SC_inline; } -#line 4657 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 4661 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 50: -#line 985 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 987 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.integer) = (yyvsp[0].u.integer) | (int)CPPInstance::SC_virtual; } -#line 4665 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 4669 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 51: -#line 989 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 991 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.integer) = (yyvsp[0].u.integer) | (int)CPPInstance::SC_explicit; } -#line 4673 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 4677 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 52: -#line 993 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 995 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.integer) = (yyvsp[0].u.integer) | (int)CPPInstance::SC_register; } -#line 4681 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 4685 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 53: -#line 997 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 999 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.integer) = (yyvsp[0].u.integer) | (int)CPPInstance::SC_volatile; } -#line 4689 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 4693 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 54: -#line 1001 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1003 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.integer) = (yyvsp[0].u.integer) | (int)CPPInstance::SC_mutable; } -#line 4697 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 4701 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 55: -#line 1005 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1007 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.integer) = (yyvsp[0].u.integer) | (int)CPPInstance::SC_constexpr; } -#line 4705 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 4709 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 56: -#line 1009 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1011 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.integer) = (yyvsp[0].u.integer) | (int)CPPInstance::SC_blocking; } -#line 4713 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 4717 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 57: -#line 1013 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1015 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.integer) = (yyvsp[0].u.integer) | (int)CPPInstance::SC_extension; } -#line 4721 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 4725 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 58: -#line 1017 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1019 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.integer) = (yyvsp[0].u.integer) | (int)CPPInstance::SC_thread_local; } -#line 4729 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 4733 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 59: -#line 1021 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1023 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { // Ignore attribute specifiers for now. (yyval.u.integer) = (yyvsp[0].u.integer); } -#line 4738 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 4742 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 60: -#line 1026 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1028 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.integer) = (yyvsp[0].u.integer); } -#line 4746 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 4750 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 61: -#line 1030 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1032 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.integer) = (yyvsp[0].u.integer); } -#line 4754 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 4758 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 67: -#line 1048 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1050 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { // We don't need to push/pop type, because we can't nest // type_like_declaration. @@ -4767,19 +4769,19 @@ yyreduce: } push_storage_class((yyvsp[-1].u.integer)); } -#line 4769 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 4773 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 68: -#line 1059 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1061 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { pop_storage_class(); } -#line 4777 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 4781 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 69: -#line 1064 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1066 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { // We don't really care about the storage class here. In fact, it's // not actually legal to define a class or struct using a particular @@ -4788,48 +4790,48 @@ yyreduce: current_scope->add_declaration((yyvsp[-1].u.decl), global_scope, current_lexer, (yylsp[-1])); } -#line 4790 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 4794 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 70: -#line 1073 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1075 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { - if ((yyvsp[0].u.instance) != (CPPInstance *)NULL) { + if ((yyvsp[0].u.instance) != nullptr) { // Push the scope so that the initializers can make use of things defined // in the class body. push_scope((yyvsp[0].u.instance)->get_scope(current_scope, global_scope)); (yyvsp[0].u.instance)->_storage_class |= (current_storage_class | (yyvsp[-1].u.integer)); } } -#line 4803 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 4807 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 71: -#line 1082 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1084 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { - if ((yyvsp[-2].u.instance) != (CPPInstance *)NULL) { + if ((yyvsp[-2].u.instance) != nullptr) { pop_scope(); current_scope->add_declaration((yyvsp[-2].u.instance), global_scope, current_lexer, (yylsp[-2])); (yyvsp[-2].u.instance)->set_initializer((yyvsp[0].u.expr)); } } -#line 4815 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 4819 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 72: -#line 1090 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1092 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { - if ((yyvsp[-1].u.instance) != (CPPInstance *)NULL) { + if ((yyvsp[-1].u.instance) != nullptr) { (yyvsp[-1].u.instance)->_storage_class |= (current_storage_class | (yyvsp[-2].u.integer)); current_scope->add_declaration((yyvsp[-1].u.instance), global_scope, current_lexer, (yylsp[-1])); (yyvsp[-1].u.instance)->set_initializer((yyvsp[0].u.expr)); } } -#line 4827 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 4831 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 74: -#line 1106 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1108 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { if (current_storage_class & CPPInstance::SC_const) { (yyvsp[-1].u.inst_ident)->add_modifier(IIT_const); @@ -4840,11 +4842,11 @@ yyreduce: inst->set_initializer((yyvsp[0].u.expr)); current_scope->add_declaration(inst, global_scope, current_lexer, (yylsp[-1])); } -#line 4842 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 4846 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 75: -#line 1117 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1119 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { if (current_storage_class & CPPInstance::SC_const) { (yyvsp[-3].u.inst_ident)->add_modifier(IIT_const); @@ -4855,11 +4857,11 @@ yyreduce: inst->set_initializer((yyvsp[-2].u.expr)); current_scope->add_declaration(inst, global_scope, current_lexer, (yylsp[-3])); } -#line 4857 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 4861 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 76: -#line 1132 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1134 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { // We don't need to push/pop type, because we can't nest // multiple_var_declarations. @@ -4870,23 +4872,23 @@ yyreduce: } push_storage_class((yyvsp[-1].u.integer)); } -#line 4872 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 4876 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 77: -#line 1143 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1145 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { pop_storage_class(); } -#line 4880 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 4884 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 78: -#line 1147 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1149 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { - if ((yyvsp[-1].u.instance) != (CPPDeclaration *)NULL) { + if ((yyvsp[-1].u.instance) != nullptr) { CPPInstance *inst = (yyvsp[-1].u.instance)->as_instance(); - if (inst != (CPPInstance *)NULL) { + if (inst != nullptr) { inst->_storage_class |= (current_storage_class | (yyvsp[-2].u.integer)); current_scope->add_declaration(inst, global_scope, current_lexer, (yylsp[-1])); CPPTypedefType *typedef_type = new CPPTypedefType(inst->_type, inst->_ident, current_scope); @@ -4894,11 +4896,11 @@ yyreduce: } } } -#line 4896 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 4900 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 79: -#line 1162 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1164 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { if (current_storage_class & CPPInstance::SC_const) { (yyvsp[-1].u.inst_ident)->add_modifier(IIT_const); @@ -4907,11 +4909,11 @@ yyreduce: CPPTypedefType *typedef_type = new CPPTypedefType(target_type, (yyvsp[-1].u.inst_ident), current_scope, (yylsp[-1]).file); current_scope->add_declaration(CPPType::new_type(typedef_type), global_scope, current_lexer, (yylsp[-1])); } -#line 4909 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 4913 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 80: -#line 1171 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1173 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { if (current_storage_class & CPPInstance::SC_const) { (yyvsp[-3].u.inst_ident)->add_modifier(IIT_const); @@ -4920,24 +4922,37 @@ yyreduce: CPPTypedefType *typedef_type = new CPPTypedefType(target_type, (yyvsp[-3].u.inst_ident), current_scope, (yylsp[-3]).file); current_scope->add_declaration(CPPType::new_type(typedef_type), global_scope, current_lexer, (yylsp[-3])); } -#line 4922 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 4926 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 81: -#line 1185 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1187 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { - push_scope((yyvsp[-1].u.identifier)->get_scope(current_scope, global_scope)); + // Create a scope for this function. + CPPScope *scope = new CPPScope((yyvsp[-1].u.identifier)->get_scope(current_scope, global_scope), + (yyvsp[-1].u.identifier)->_names.back(), V_private); + + // It still needs to be able to pick up any template arguments, if this is + // a definition for a method template. Add a fake "using" declaration to + // accomplish this. + scope->_using.insert(current_scope); + + push_scope(scope); } -#line 4930 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 4943 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 82: -#line 1189 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1200 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { + CPPScope *scope = (yyvsp[-5].u.identifier)->get_scope(current_scope, global_scope); CPPType *type; - if ((yyvsp[-5].u.identifier)->get_simple_name() == current_scope->get_simple_name() || - (yyvsp[-5].u.identifier)->get_simple_name() == string("~") + current_scope->get_simple_name()) { - // This is a constructor, and has no return. + std::string simple_name = (yyvsp[-5].u.identifier)->get_simple_name(); + if (!simple_name.empty() && simple_name[0] == '~') { + // A destructor has no return type. + type = new CPPSimpleType(CPPSimpleType::T_void); + } else if (scope != nullptr && simple_name == scope->get_simple_name()) { + // Neither does a constructor. type = new CPPSimpleType(CPPSimpleType::T_void); } else { // This isn't a constructor, so it has an implicit return type of @@ -4952,19 +4967,28 @@ yyreduce: (yyval.u.instance) = new CPPInstance(type, ii, 0, (yylsp[-5]).file); } -#line 4954 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 4971 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 83: -#line 1209 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1224 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { - push_scope((yyvsp[-1].u.identifier)->get_scope(current_scope, global_scope)); + // Create a scope for this function. + CPPScope *scope = new CPPScope((yyvsp[-1].u.identifier)->get_scope(current_scope, global_scope), + (yyvsp[-1].u.identifier)->_names.back(), V_private); + + // It still needs to be able to pick up any template arguments, if this is + // a definition for a method template. Add a fake "using" declaration to + // accomplish this. + scope->_using.insert(current_scope); + + push_scope(scope); } -#line 4962 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 4988 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 84: -#line 1213 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1237 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { pop_scope(); CPPType *type; @@ -4982,19 +5006,19 @@ yyreduce: (yyval.u.instance) = new CPPInstance(type, ii, 0, (yylsp[-5]).file); } -#line 4984 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 5010 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 85: -#line 1236 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1260 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { push_scope((yyvsp[-1].u.identifier)->get_scope(current_scope, global_scope)); } -#line 4992 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 5018 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 86: -#line 1240 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1264 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { pop_scope(); if ((yyvsp[-5].u.identifier)->is_scoped()) { @@ -5013,75 +5037,75 @@ yyreduce: (yyval.u.instance) = new CPPInstance(type, ii, 0, (yylsp[-5]).file); } } -#line 5015 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 5041 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 87: -#line 1266 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1290 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { push_scope((yyvsp[-2].u.inst_ident)->get_scope(current_scope, global_scope)); } -#line 5023 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 5049 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 88: -#line 1270 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1294 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { pop_scope(); CPPType *type = (yyvsp[-10].u.identifier)->find_type(current_scope, global_scope, false, current_lexer); - if (type == NULL) { + if (type == nullptr) { yyerror(string("internal error resolving type ") + (yyvsp[-10].u.identifier)->get_fully_scoped_name(), (yylsp[-10])); } - assert(type != NULL); + assert(type != nullptr); CPPInstanceIdentifier *ii = (yyvsp[-7].u.inst_ident); ii->add_modifier(IIT_pointer); ii->add_func_modifier((yyvsp[-3].u.param_list), (yyvsp[-1].u.integer)); (yyval.u.instance) = new CPPInstance(type, ii, 0, (yylsp[-10]).file); } -#line 5041 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 5067 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 89: -#line 1284 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1308 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { push_scope((yyvsp[-2].u.inst_ident)->get_scope(current_scope, global_scope)); } -#line 5049 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 5075 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 90: -#line 1288 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1312 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { pop_scope(); CPPType *type = (yyvsp[-11].u.identifier)->find_type(current_scope, global_scope, false, current_lexer); - if (type == NULL) { + if (type == nullptr) { yyerror(string("internal error resolving type ") + (yyvsp[-11].u.identifier)->get_fully_scoped_name(), (yylsp[-11])); } - assert(type != NULL); + assert(type != nullptr); CPPInstanceIdentifier *ii = (yyvsp[-7].u.inst_ident); ii->add_scoped_pointer_modifier((yyvsp[-9].u.identifier)); ii->add_func_modifier((yyvsp[-3].u.param_list), (yyvsp[-1].u.integer)); (yyval.u.instance) = new CPPInstance(type, ii, 0, (yylsp[-11]).file); } -#line 5067 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 5093 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 91: -#line 1304 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1328 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { - if ((yyvsp[-3].u.identifier) != NULL) { + if ((yyvsp[-3].u.identifier) != nullptr) { push_scope((yyvsp[-3].u.identifier)->get_scope(current_scope, global_scope)); } } -#line 5077 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 5103 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 92: -#line 1310 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1334 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { - if ((yyvsp[-7].u.identifier) != NULL) { + if ((yyvsp[-7].u.identifier) != nullptr) { pop_scope(); } @@ -5096,7 +5120,7 @@ yyreduce: // the method's return type to determine the full type description. string name = "operator typecast " + (yyvsp[-6].u.type)->get_simple_name(); CPPIdentifier *ident = (yyvsp[-7].u.identifier); - if (ident == NULL) { + if (ident == nullptr) { ident = new CPPIdentifier(name, (yylsp[-6])); } else { ident->add_name(name); @@ -5104,28 +5128,28 @@ yyreduce: (yyval.u.instance) = CPPInstance::make_typecast_function (new CPPInstance((yyvsp[-6].u.type), (yyvsp[-5].u.inst_ident), 0, (yylsp[-5]).file), ident, (yyvsp[-2].u.param_list), (yyvsp[0].u.integer)); } -#line 5106 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 5132 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 93: -#line 1335 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1359 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { - if ((yyvsp[-4].u.identifier) != NULL) { + if ((yyvsp[-4].u.identifier) != nullptr) { push_scope((yyvsp[-4].u.identifier)->get_scope(current_scope, global_scope)); } } -#line 5116 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 5142 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 94: -#line 1341 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1365 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { - if ((yyvsp[-8].u.identifier) != NULL) { + if ((yyvsp[-8].u.identifier) != nullptr) { pop_scope(); } CPPIdentifier *ident = (yyvsp[-8].u.identifier); - if (ident == NULL) { + if (ident == nullptr) { ident = new CPPIdentifier("operator typecast", (yylsp[-5])); } else { ident->add_name("operator typecast"); @@ -5134,626 +5158,626 @@ yyreduce: (yyval.u.instance) = CPPInstance::make_typecast_function (new CPPInstance((yyvsp[-6].u.type), (yyvsp[-5].u.inst_ident), 0, (yylsp[-5]).file), ident, (yyvsp[-2].u.param_list), (yyvsp[0].u.integer)); } -#line 5136 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 5162 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 95: -#line 1361 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1385 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { CPPDeclaration *decl = (yyvsp[0].u.identifier)->find_symbol(current_scope, global_scope, current_lexer); - if (decl != (CPPDeclaration *)NULL) { + if (decl != nullptr) { (yyval.u.instance) = decl->as_instance(); } else { - (yyval.u.instance) = (CPPInstance *)NULL; + (yyval.u.instance) = nullptr; } } -#line 5150 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 5176 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 96: -#line 1374 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1398 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.integer) = 0; } -#line 5158 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 5184 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 97: -#line 1378 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1402 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.integer) = (yyvsp[-1].u.integer) | (int)CPPFunctionType::F_const_method; } -#line 5166 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 5192 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 98: -#line 1382 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1406 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.integer) = (yyvsp[-1].u.integer) | (int)CPPFunctionType::F_volatile_method; } -#line 5174 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 5200 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 99: -#line 1386 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1410 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.integer) = (yyvsp[-1].u.integer) | (int)CPPFunctionType::F_noexcept; } -#line 5182 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 5208 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 100: -#line 1399 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1423 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.integer) = (yyvsp[-1].u.integer) | (int)CPPFunctionType::F_final; } -#line 5190 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 5216 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 101: -#line 1403 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1427 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.integer) = (yyvsp[-1].u.integer) | (int)CPPFunctionType::F_override; } -#line 5198 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 5224 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 102: -#line 1407 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1431 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.integer) = (yyvsp[-1].u.integer) | (int)CPPFunctionType::F_lvalue_method; } -#line 5206 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 5232 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 103: -#line 1411 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1435 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.integer) = (yyvsp[-1].u.integer) | (int)CPPFunctionType::F_rvalue_method; } -#line 5214 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 5240 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 104: -#line 1415 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1439 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { // Used for lambdas, currently ignored. (yyval.u.integer) = (yyvsp[-1].u.integer); } -#line 5223 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 5249 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 105: -#line 1420 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1444 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { // Used for lambdas in C++17, currently ignored. (yyval.u.integer) = (yyvsp[-1].u.integer); } -#line 5232 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 5258 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 106: -#line 1425 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1449 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.integer) = (yyvsp[-3].u.integer); } -#line 5240 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 5266 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 107: -#line 1429 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1453 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.integer) = (yyvsp[-4].u.integer); } -#line 5248 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 5274 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 108: -#line 1433 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1457 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.integer) = (yyvsp[-5].u.integer); } -#line 5256 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 5282 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 109: -#line 1437 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1461 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.integer) = (yyvsp[-3].u.integer); } -#line 5264 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 5290 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 110: -#line 1444 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1468 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.str) = "!"; } -#line 5272 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 5298 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 111: -#line 1448 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1472 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.str) = "~"; } -#line 5280 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 5306 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 112: -#line 1452 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1476 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.str) = "*"; } -#line 5288 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 5314 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 113: -#line 1456 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1480 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.str) = "/"; } -#line 5296 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 5322 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 114: -#line 1460 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1484 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.str) = "%"; } -#line 5304 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 5330 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 115: -#line 1464 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1488 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.str) = "+"; } -#line 5312 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 5338 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 116: -#line 1468 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1492 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.str) = "-"; } -#line 5320 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 5346 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 117: -#line 1472 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1496 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.str) = "|"; } -#line 5328 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 5354 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 118: -#line 1476 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1500 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.str) = "&"; } -#line 5336 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 5362 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 119: -#line 1480 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1504 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.str) = "^"; } -#line 5344 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 5370 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 120: -#line 1484 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1508 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.str) = "||"; } -#line 5352 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 5378 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 121: -#line 1488 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1512 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.str) = "&&"; } -#line 5360 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 5386 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 122: -#line 1492 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1516 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.str) = "=="; } -#line 5368 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 5394 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 123: -#line 1496 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1520 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.str) = "!="; } -#line 5376 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 5402 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 124: -#line 1500 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1524 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.str) = "<="; } -#line 5384 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 5410 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 125: -#line 1504 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1528 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.str) = ">="; } -#line 5392 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 5418 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 126: -#line 1508 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1532 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.str) = "<"; } -#line 5400 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 5426 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 127: -#line 1512 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1536 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.str) = ">"; } -#line 5408 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 5434 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 128: -#line 1516 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1540 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.str) = "<<"; } -#line 5416 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 5442 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 129: -#line 1520 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1544 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.str) = ">>"; } -#line 5424 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 5450 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 130: -#line 1524 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1548 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.str) = "="; } -#line 5432 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 5458 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 131: -#line 1528 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1552 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.str) = ","; } -#line 5440 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 5466 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 132: -#line 1532 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1556 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.str) = "++"; } -#line 5448 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 5474 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 133: -#line 1536 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1560 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.str) = "--"; } -#line 5456 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 5482 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 134: -#line 1540 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1564 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.str) = "*="; } -#line 5464 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 5490 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 135: -#line 1544 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1568 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.str) = "/="; } -#line 5472 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 5498 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 136: -#line 1548 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1572 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.str) = "%="; } -#line 5480 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 5506 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 137: -#line 1552 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1576 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.str) = "+="; } -#line 5488 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 5514 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 138: -#line 1556 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1580 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.str) = "-="; } -#line 5496 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 5522 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 139: -#line 1560 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1584 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.str) = "|="; } -#line 5504 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 5530 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 140: -#line 1564 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1588 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.str) = "&="; } -#line 5512 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 5538 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 141: -#line 1568 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1592 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.str) = "^="; } -#line 5520 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 5546 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 142: -#line 1572 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1596 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.str) = "<<="; } -#line 5528 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 5554 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 143: -#line 1576 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1600 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.str) = ">>="; } -#line 5536 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 5562 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 144: -#line 1580 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1604 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.str) = "->"; } -#line 5544 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 5570 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 145: -#line 1584 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1608 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.str) = "[]"; } -#line 5552 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 5578 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 146: -#line 1588 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1612 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.str) = "()"; } -#line 5560 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 5586 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 147: -#line 1592 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1616 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.str) = "new"; } -#line 5568 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 5594 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 148: -#line 1596 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1620 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.str) = "delete"; } -#line 5576 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 5602 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 153: -#line 1610 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1634 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { push_scope(new CPPTemplateScope(current_scope)); } -#line 5584 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 5610 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 154: -#line 1614 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1638 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { pop_scope(); } -#line 5592 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 5618 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 159: -#line 1628 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1652 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { CPPTemplateScope *ts = current_scope->as_template_scope(); - assert(ts != NULL); + assert(ts != nullptr); ts->add_template_parameter((yyvsp[0].u.decl)); } -#line 5602 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 5628 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 160: -#line 1634 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1658 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { CPPTemplateScope *ts = current_scope->as_template_scope(); - assert(ts != NULL); + assert(ts != nullptr); ts->add_template_parameter((yyvsp[0].u.decl)); } -#line 5612 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 5638 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 163: -#line 1648 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1672 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { - (yyval.u.decl) = CPPType::new_type(new CPPClassTemplateParameter((CPPIdentifier *)NULL)); + (yyval.u.decl) = CPPType::new_type(new CPPClassTemplateParameter(nullptr)); } -#line 5620 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 5646 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 164: -#line 1652 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1676 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.decl) = CPPType::new_type(new CPPClassTemplateParameter((yyvsp[0].u.identifier))); } -#line 5628 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 5654 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 165: -#line 1656 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1680 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.decl) = CPPType::new_type(new CPPClassTemplateParameter((yyvsp[-2].u.identifier), (yyvsp[0].u.type))); } -#line 5636 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 5662 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 166: -#line 1660 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1684 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { - CPPClassTemplateParameter *ctp = new CPPClassTemplateParameter((CPPIdentifier *)NULL); + CPPClassTemplateParameter *ctp = new CPPClassTemplateParameter(nullptr); ctp->_packed = true; (yyval.u.decl) = CPPType::new_type(ctp); } -#line 5646 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 5672 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 167: -#line 1666 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1690 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { CPPClassTemplateParameter *ctp = new CPPClassTemplateParameter((yyvsp[0].u.identifier)); ctp->_packed = true; (yyval.u.decl) = CPPType::new_type(ctp); } -#line 5656 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 5682 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 168: -#line 1672 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1696 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { CPPInstance *inst = new CPPInstance((yyvsp[-2].u.type), (yyvsp[-1].u.inst_ident), 0, (yylsp[-1]).file); inst->set_initializer((yyvsp[0].u.expr)); (yyval.u.decl) = inst; } -#line 5666 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 5692 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 169: -#line 1678 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1702 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyvsp[-1].u.inst_ident)->add_modifier(IIT_const); CPPInstance *inst = new CPPInstance((yyvsp[-2].u.type), (yyvsp[-1].u.inst_ident), 0, (yylsp[-1]).file); inst->set_initializer((yyvsp[0].u.expr)); (yyval.u.decl) = inst; } -#line 5677 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 5703 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 170: -#line 1685 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1709 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { CPPInstance *inst = new CPPInstance((yyvsp[-1].u.type), (yyvsp[0].u.inst_ident), 0, (yylsp[0]).file); (yyval.u.decl) = inst; } -#line 5686 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 5712 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 171: -#line 1690 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1714 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyvsp[0].u.inst_ident)->add_modifier(IIT_const); CPPInstance *inst = new CPPInstance((yyvsp[-1].u.type), (yyvsp[0].u.inst_ident), 0, (yylsp[0]).file); (yyval.u.decl) = inst; } -#line 5696 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 5722 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 172: -#line 1699 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1723 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.type) = CPPType::new_type((yyvsp[0].u.simple_type)); } -#line 5704 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 5730 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 173: -#line 1703 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1727 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { yywarning("Not a type: " + (yyvsp[0].u.identifier)->get_fully_scoped_name(), (yylsp[0])); (yyval.u.type) = CPPType::new_type(new CPPSimpleType(CPPSimpleType::T_unknown)); } -#line 5713 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 5739 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 174: -#line 1708 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1732 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.type) = (yyvsp[0].u.identifier)->find_type(current_scope, global_scope, false, current_lexer); - if ((yyval.u.type) == NULL) { + if ((yyval.u.type) == nullptr) { yyerror(string("internal error resolving type ") + (yyvsp[0].u.identifier)->get_fully_scoped_name(), (yylsp[0])); } - assert((yyval.u.type) != NULL); + assert((yyval.u.type) != nullptr); } -#line 5725 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 5751 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 175: -#line 1716 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1740 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.type) = (yyvsp[0].u.identifier)->find_type(current_scope, global_scope, false, current_lexer); - if ((yyval.u.type) == NULL) { + if ((yyval.u.type) == nullptr) { yyerror(string("internal error resolving type ") + (yyvsp[0].u.identifier)->get_fully_scoped_name(), (yylsp[0])); } - assert((yyval.u.type) != NULL); + assert((yyval.u.type) != nullptr); } -#line 5737 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 5763 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 176: -#line 1728 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1752 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.inst_ident) = new CPPInstanceIdentifier((yyvsp[0].u.identifier)); } -#line 5745 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 5771 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 177: -#line 1732 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1756 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { // For an operator function. We implement this simply by building a // ficticious name for the function; in other respects it's just // like a regular function. CPPIdentifier *ident = (yyvsp[-1].u.identifier); - if (ident == NULL) { + if (ident == nullptr) { ident = new CPPIdentifier("operator "+(yyvsp[0].str), (yylsp[0])); } else { ident->_names.push_back("operator "+(yyvsp[0].str)); @@ -5761,18 +5785,18 @@ yyreduce: (yyval.u.inst_ident) = new CPPInstanceIdentifier(ident); } -#line 5763 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 5789 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 178: -#line 1746 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1770 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { // A C++11 literal operator. if (!(yyvsp[-1].str).empty()) { yyerror("expected empty string", (yylsp[-1])); } CPPIdentifier *ident = (yyvsp[-2].u.identifier); - if (ident == NULL) { + if (ident == nullptr) { ident = new CPPIdentifier("operator \"\" "+(yyvsp[0].u.identifier)->get_simple_name(), (yylsp[0])); } else { ident->_names.push_back("operator \"\" "+(yyvsp[0].u.identifier)->get_simple_name()); @@ -5780,83 +5804,83 @@ yyreduce: (yyval.u.inst_ident) = new CPPInstanceIdentifier(ident); } -#line 5782 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 5808 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 179: -#line 1761 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1785 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.inst_ident) = (yyvsp[0].u.inst_ident); (yyval.u.inst_ident)->add_modifier(IIT_const); } -#line 5791 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 5817 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 180: -#line 1766 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1790 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.inst_ident) = (yyvsp[0].u.inst_ident); (yyval.u.inst_ident)->add_modifier(IIT_volatile); } -#line 5800 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 5826 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 181: -#line 1771 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1795 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.inst_ident) = (yyvsp[0].u.inst_ident); (yyval.u.inst_ident)->add_modifier(IIT_pointer); } -#line 5809 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 5835 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 182: -#line 1776 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1800 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.inst_ident) = (yyvsp[0].u.inst_ident); (yyval.u.inst_ident)->add_modifier(IIT_reference); } -#line 5818 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 5844 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 183: -#line 1781 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1805 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.inst_ident) = (yyvsp[0].u.inst_ident); (yyval.u.inst_ident)->add_modifier(IIT_rvalue_reference); } -#line 5827 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 5853 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 184: -#line 1786 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1810 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.inst_ident) = (yyvsp[0].u.inst_ident); (yyval.u.inst_ident)->add_scoped_pointer_modifier((yyvsp[-2].u.identifier)); } -#line 5836 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 5862 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 185: -#line 1791 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1815 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.inst_ident) = (yyvsp[-3].u.inst_ident); (yyval.u.inst_ident)->add_array_modifier((yyvsp[-1].u.expr)); } -#line 5845 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 5871 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 186: -#line 1796 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1820 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.inst_ident) = (yyvsp[-1].u.inst_ident); (yyval.u.inst_ident)->add_modifier(IIT_paren); } -#line 5854 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 5880 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 187: -#line 1801 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1825 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { // Create a scope for this function (in case it is a function) CPPScope *scope = new CPPScope((yyvsp[-1].u.inst_ident)->get_scope(current_scope, global_scope), @@ -5869,11 +5893,11 @@ yyreduce: push_scope(scope); } -#line 5871 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 5897 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 188: -#line 1814 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1838 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { pop_scope(); (yyval.u.inst_ident) = (yyvsp[-5].u.inst_ident); @@ -5887,1410 +5911,1410 @@ yyreduce: (yyval.u.inst_ident)->add_func_modifier((yyvsp[-2].u.param_list), (yyvsp[0].u.integer)); } } -#line 5889 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 5915 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 189: -#line 1832 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1856 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { // This is handled a bit awkwardly right now. Ideally it'd be wrapped // up in the instance_identifier rule, but then more needs to happen in // order to avoid shift/reduce conflicts. - if ((yyvsp[0].u.type) != NULL) { + if ((yyvsp[0].u.type) != nullptr) { (yyvsp[-1].u.inst_ident)->add_trailing_return_type((yyvsp[0].u.type)); } (yyval.u.inst_ident) = (yyvsp[-1].u.inst_ident); } -#line 5903 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 5929 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 190: -#line 1842 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1866 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { // Bitfield definition. (yyvsp[-2].u.inst_ident)->_bit_width = (yyvsp[0].u.integer); (yyval.u.inst_ident) = (yyvsp[-2].u.inst_ident); } -#line 5913 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 5939 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 191: -#line 1852 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1876 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { - (yyval.u.type) = NULL; + (yyval.u.type) = nullptr; } -#line 5921 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 5947 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 192: -#line 1856 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1880 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.type) = (yyvsp[0].u.inst_ident)->unroll_type((yyvsp[-1].u.type)); } -#line 5929 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 5955 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 193: -#line 1860 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1884 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyvsp[0].u.inst_ident)->add_modifier(IIT_const); (yyval.u.type) = (yyvsp[0].u.inst_ident)->unroll_type((yyvsp[-1].u.type)); } -#line 5938 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 5964 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 194: -#line 1869 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1893 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { - (yyval.u.identifier) = NULL; + (yyval.u.identifier) = nullptr; } -#line 5946 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 5972 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 195: -#line 1873 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1897 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.identifier) = (yyvsp[0].u.identifier); } -#line 5954 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 5980 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 196: -#line 1881 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1905 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.param_list) = new CPPParameterList; } -#line 5962 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 5988 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 197: -#line 1885 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1909 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.param_list) = new CPPParameterList; (yyval.u.param_list)->_includes_ellipsis = true; } -#line 5971 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 5997 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 198: -#line 1890 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1914 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.param_list) = (yyvsp[0].u.param_list); } -#line 5979 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 6005 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 199: -#line 1894 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1918 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.param_list) = (yyvsp[-2].u.param_list); (yyval.u.param_list)->_includes_ellipsis = true; } -#line 5988 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 6014 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 200: -#line 1899 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1923 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.param_list) = (yyvsp[-1].u.param_list); (yyval.u.param_list)->_includes_ellipsis = true; } -#line 5997 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 6023 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 201: -#line 1907 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1931 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.param_list) = new CPPParameterList; (yyval.u.param_list)->_parameters.push_back((yyvsp[0].u.instance)); } -#line 6006 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 6032 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 202: -#line 1912 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1936 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.param_list) = (yyvsp[-2].u.param_list); (yyval.u.param_list)->_parameters.push_back((yyvsp[0].u.instance)); } -#line 6015 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 6041 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 203: -#line 1920 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1944 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.param_list) = new CPPParameterList; } -#line 6023 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 6049 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 204: -#line 1924 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1948 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.param_list) = new CPPParameterList; (yyval.u.param_list)->_includes_ellipsis = true; } -#line 6032 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 6058 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 205: -#line 1929 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1953 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.param_list) = (yyvsp[0].u.param_list); } -#line 6040 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 6066 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 206: -#line 1933 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1957 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.param_list) = (yyvsp[-2].u.param_list); (yyval.u.param_list)->_includes_ellipsis = true; } -#line 6049 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 6075 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 207: -#line 1938 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1962 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.param_list) = (yyvsp[-1].u.param_list); (yyval.u.param_list)->_includes_ellipsis = true; } -#line 6058 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 6084 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 208: -#line 1946 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1970 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.param_list) = new CPPParameterList; (yyval.u.param_list)->_parameters.push_back((yyvsp[0].u.instance)); } -#line 6067 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 6093 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 209: -#line 1951 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1975 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.param_list) = (yyvsp[-2].u.param_list); (yyval.u.param_list)->_parameters.push_back((yyvsp[0].u.instance)); } -#line 6076 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 6102 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 210: -#line 1959 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1983 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { - (yyval.u.expr) = (CPPExpression *)NULL; + (yyval.u.expr) = nullptr; } -#line 6084 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 6110 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 211: -#line 1963 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1987 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = (yyvsp[0].u.expr); } -#line 6092 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 6118 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 212: -#line 1970 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1994 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { - (yyval.u.expr) = (CPPExpression *)NULL; + (yyval.u.expr) = nullptr; } -#line 6100 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 6126 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 213: -#line 1974 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 1998 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = (yyvsp[0].u.expr); } -#line 6108 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 6134 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 214: -#line 1981 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2005 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { - (yyval.u.expr) = (CPPExpression *)NULL; + (yyval.u.expr) = nullptr; } -#line 6116 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 6142 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 215: -#line 1985 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2009 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { - (yyval.u.expr) = (CPPExpression *)NULL; + (yyval.u.expr) = nullptr; } -#line 6124 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 6150 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 216: -#line 1989 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2013 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { - (yyval.u.expr) = (CPPExpression *)NULL; + (yyval.u.expr) = nullptr; } -#line 6132 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 6158 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 217: -#line 1993 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2017 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression(CPPExpression::get_default()); } -#line 6140 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 6166 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 218: -#line 1997 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2021 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression(CPPExpression::get_delete()); } -#line 6148 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 6174 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 219: -#line 2004 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2028 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { - (yyval.u.expr) = (CPPExpression *)NULL; + (yyval.u.expr) = nullptr; } -#line 6156 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 6182 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 220: -#line 2008 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2032 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { - (yyval.u.expr) = (CPPExpression *)NULL; + (yyval.u.expr) = nullptr; } -#line 6164 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 6190 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 221: -#line 2012 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2036 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = (yyvsp[-1].u.expr); } -#line 6172 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 6198 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 222: -#line 2016 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2040 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression(CPPExpression::get_default()); } -#line 6180 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 6206 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 223: -#line 2020 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2044 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression(CPPExpression::get_delete()); } -#line 6188 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 6214 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 224: -#line 2024 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2048 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { - (yyval.u.expr) = (CPPExpression *)NULL; + (yyval.u.expr) = nullptr; } -#line 6196 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 6222 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 228: -#line 2037 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2061 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { } -#line 6203 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 6229 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 232: -#line 2046 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2070 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.instance) = new CPPInstance((yyvsp[-2].u.type), (yyvsp[-1].u.inst_ident), 0, (yylsp[-1]).file); (yyval.u.instance)->set_initializer((yyvsp[0].u.expr)); } -#line 6212 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 6238 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 233: -#line 2051 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2075 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyvsp[-1].u.inst_ident)->add_modifier(IIT_const); (yyval.u.instance) = new CPPInstance((yyvsp[-2].u.type), (yyvsp[-1].u.inst_ident), 0, (yylsp[-1]).file); (yyval.u.instance)->set_initializer((yyvsp[0].u.expr)); } -#line 6222 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 6248 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 234: -#line 2057 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2081 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyvsp[-1].u.inst_ident)->add_modifier(IIT_const); (yyval.u.instance) = new CPPInstance((yyvsp[-2].u.type), (yyvsp[-1].u.inst_ident), 0, (yylsp[-2]).file); (yyval.u.instance)->set_initializer((yyvsp[0].u.expr)); } -#line 6232 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 6258 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 235: -#line 2063 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2087 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.instance) = new CPPInstance((yyvsp[-2].u.type), (yyvsp[-1].u.inst_ident), 0, (yylsp[-1]).file); (yyval.u.instance)->set_initializer((yyvsp[0].u.expr)); } -#line 6241 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 6267 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 236: -#line 2068 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2092 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyvsp[-1].u.inst_ident)->add_modifier(IIT_const); (yyval.u.instance) = new CPPInstance((yyvsp[-2].u.type), (yyvsp[-1].u.inst_ident), 0, (yylsp[-1]).file); (yyval.u.instance)->set_initializer((yyvsp[0].u.expr)); } -#line 6251 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 6277 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 237: -#line 2074 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2098 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyvsp[-1].u.inst_ident)->add_modifier(IIT_const); (yyval.u.instance) = new CPPInstance((yyvsp[-2].u.type), (yyvsp[-1].u.inst_ident), 0, (yylsp[-2]).file); (yyval.u.instance)->set_initializer((yyvsp[0].u.expr)); } -#line 6261 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 6287 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 238: -#line 2080 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2104 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.instance) = (yyvsp[0].u.instance); } -#line 6269 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 6295 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 239: -#line 2084 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2108 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.instance) = (yyvsp[0].u.instance); } -#line 6277 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 6303 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 240: -#line 2095 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2119 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.instance) = (yyvsp[0].u.instance); } -#line 6285 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 6311 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 241: -#line 2099 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2123 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { CPPType *type = CPPType::new_type(new CPPSimpleType(CPPSimpleType::T_parameter)); (yyval.u.instance) = new CPPInstance(type, "expr"); (yyval.u.instance)->set_initializer((yyvsp[0].u.expr)); } -#line 6296 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 6322 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 242: -#line 2109 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2133 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { - (yyval.u.inst_ident) = new CPPInstanceIdentifier((CPPIdentifier *)NULL); + (yyval.u.inst_ident) = new CPPInstanceIdentifier(nullptr); } -#line 6304 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 6330 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 243: -#line 2113 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2137 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.inst_ident) = new CPPInstanceIdentifier((yyvsp[0].u.identifier)); } -#line 6312 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 6338 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 244: -#line 2117 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2141 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.inst_ident) = (yyvsp[0].u.inst_ident); (yyval.u.inst_ident)->add_modifier(IIT_const); } -#line 6321 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 6347 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 245: -#line 2122 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2146 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.inst_ident) = (yyvsp[0].u.inst_ident); (yyval.u.inst_ident)->add_modifier(IIT_volatile); } -#line 6330 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 6356 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 246: -#line 2127 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2151 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.inst_ident) = (yyvsp[0].u.inst_ident); (yyval.u.inst_ident)->add_modifier(IIT_pointer); } -#line 6339 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 6365 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 247: -#line 2132 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2156 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.inst_ident) = (yyvsp[0].u.inst_ident); (yyval.u.inst_ident)->add_modifier(IIT_reference); } -#line 6348 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 6374 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 248: -#line 2137 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2161 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.inst_ident) = (yyvsp[0].u.inst_ident); (yyval.u.inst_ident)->add_modifier(IIT_rvalue_reference); } -#line 6357 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 6383 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 249: -#line 2142 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2166 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.inst_ident) = (yyvsp[0].u.inst_ident); (yyval.u.inst_ident)->add_scoped_pointer_modifier((yyvsp[-2].u.identifier)); } -#line 6366 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 6392 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 250: -#line 2147 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2171 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.inst_ident) = (yyvsp[-3].u.inst_ident); (yyval.u.inst_ident)->add_array_modifier((yyvsp[-1].u.expr)); } -#line 6375 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 6401 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 251: -#line 2155 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2179 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { - (yyval.u.inst_ident) = new CPPInstanceIdentifier((CPPIdentifier *)NULL); + (yyval.u.inst_ident) = new CPPInstanceIdentifier(nullptr); } -#line 6383 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 6409 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 252: -#line 2159 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2183 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.inst_ident) = new CPPInstanceIdentifier((yyvsp[0].u.identifier)); } -#line 6391 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 6417 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 253: -#line 2163 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2187 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.inst_ident) = (yyvsp[0].u.inst_ident); (yyval.u.inst_ident)->add_modifier(IIT_const); } -#line 6400 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 6426 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 254: -#line 2168 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2192 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.inst_ident) = (yyvsp[0].u.inst_ident); (yyval.u.inst_ident)->add_modifier(IIT_volatile); } -#line 6409 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 6435 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 255: -#line 2173 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2197 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.inst_ident) = (yyvsp[0].u.inst_ident); (yyval.u.inst_ident)->add_modifier(IIT_pointer); } -#line 6418 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 6444 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 256: -#line 2178 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2202 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.inst_ident) = (yyvsp[0].u.inst_ident); (yyval.u.inst_ident)->add_modifier(IIT_reference); } -#line 6427 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 6453 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 257: -#line 2183 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2207 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.inst_ident) = (yyvsp[0].u.inst_ident); (yyval.u.inst_ident)->add_modifier(IIT_rvalue_reference); } -#line 6436 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 6462 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 258: -#line 2188 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2212 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.inst_ident) = (yyvsp[0].u.inst_ident); (yyval.u.inst_ident)->add_scoped_pointer_modifier((yyvsp[-2].u.identifier)); } -#line 6445 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 6471 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 259: -#line 2193 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2217 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.inst_ident) = (yyvsp[-3].u.inst_ident); (yyval.u.inst_ident)->add_array_modifier((yyvsp[-1].u.expr)); } -#line 6454 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 6480 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 260: -#line 2198 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2222 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.inst_ident) = (yyvsp[-5].u.inst_ident); (yyval.u.inst_ident)->add_modifier(IIT_paren); (yyval.u.inst_ident)->add_func_modifier((yyvsp[-2].u.param_list), (yyvsp[0].u.integer)); } -#line 6464 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 6490 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 261: -#line 2204 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2228 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.inst_ident) = (yyvsp[-1].u.inst_ident); (yyval.u.inst_ident)->add_modifier(IIT_paren); } -#line 6473 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 6499 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 262: -#line 2212 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2236 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { - (yyval.u.inst_ident) = new CPPInstanceIdentifier((CPPIdentifier *)NULL); + (yyval.u.inst_ident) = new CPPInstanceIdentifier(nullptr); (yyval.u.inst_ident)->_packed = true; } -#line 6482 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 6508 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 263: -#line 2217 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2241 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.inst_ident) = new CPPInstanceIdentifier((yyvsp[0].u.identifier)); (yyval.u.inst_ident)->_packed = true; } -#line 6491 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 6517 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 264: -#line 2222 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2246 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.inst_ident) = (yyvsp[0].u.inst_ident); (yyval.u.inst_ident)->add_modifier(IIT_const); } -#line 6500 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 6526 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 265: -#line 2227 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2251 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.inst_ident) = (yyvsp[0].u.inst_ident); (yyval.u.inst_ident)->add_modifier(IIT_volatile); } -#line 6509 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 6535 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 266: -#line 2232 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2256 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.inst_ident) = (yyvsp[0].u.inst_ident); (yyval.u.inst_ident)->add_modifier(IIT_pointer); } -#line 6518 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 6544 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 267: -#line 2237 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2261 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.inst_ident) = (yyvsp[0].u.inst_ident); (yyval.u.inst_ident)->add_modifier(IIT_reference); } -#line 6527 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 6553 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 268: -#line 2242 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2266 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.inst_ident) = (yyvsp[0].u.inst_ident); (yyval.u.inst_ident)->add_modifier(IIT_rvalue_reference); } -#line 6536 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 6562 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 269: -#line 2247 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2271 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.inst_ident) = (yyvsp[0].u.inst_ident); (yyval.u.inst_ident)->add_scoped_pointer_modifier((yyvsp[-2].u.identifier)); } -#line 6545 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 6571 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 270: -#line 2252 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2276 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.inst_ident) = (yyvsp[-3].u.inst_ident); (yyval.u.inst_ident)->add_array_modifier((yyvsp[-1].u.expr)); } -#line 6554 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 6580 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 271: -#line 2257 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2281 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.inst_ident) = (yyvsp[-5].u.inst_ident); (yyval.u.inst_ident)->add_modifier(IIT_paren); (yyval.u.inst_ident)->add_func_modifier((yyvsp[-2].u.param_list), (yyvsp[0].u.integer)); } -#line 6564 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 6590 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 272: -#line 2263 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2287 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.inst_ident) = (yyvsp[-1].u.inst_ident); (yyval.u.inst_ident)->add_modifier(IIT_paren); } -#line 6573 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 6599 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 273: -#line 2271 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2295 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { - (yyval.u.inst_ident) = new CPPInstanceIdentifier((CPPIdentifier *)NULL); + (yyval.u.inst_ident) = new CPPInstanceIdentifier(nullptr); } -#line 6581 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 6607 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 274: -#line 2275 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2299 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { - (yyval.u.inst_ident) = new CPPInstanceIdentifier((CPPIdentifier *)NULL); + (yyval.u.inst_ident) = new CPPInstanceIdentifier(nullptr); (yyval.u.inst_ident)->_packed = true; } -#line 6590 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 6616 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 275: -#line 2280 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2304 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.inst_ident) = new CPPInstanceIdentifier((yyvsp[0].u.identifier)); (yyval.u.inst_ident)->_packed = true; } -#line 6599 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 6625 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 276: -#line 2285 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2309 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.inst_ident) = (yyvsp[0].u.inst_ident); (yyval.u.inst_ident)->add_modifier(IIT_const); } -#line 6608 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 6634 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 277: -#line 2290 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2314 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.inst_ident) = (yyvsp[0].u.inst_ident); (yyval.u.inst_ident)->add_modifier(IIT_volatile); } -#line 6617 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 6643 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 278: -#line 2295 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2319 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.inst_ident) = (yyvsp[0].u.inst_ident); (yyval.u.inst_ident)->add_modifier(IIT_pointer); } -#line 6626 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 6652 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 279: -#line 2300 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2324 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.inst_ident) = (yyvsp[0].u.inst_ident); (yyval.u.inst_ident)->add_modifier(IIT_reference); } -#line 6635 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 6661 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 280: -#line 2305 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2329 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.inst_ident) = (yyvsp[0].u.inst_ident); (yyval.u.inst_ident)->add_modifier(IIT_rvalue_reference); } -#line 6644 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 6670 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 281: -#line 2310 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2334 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.inst_ident) = (yyvsp[0].u.inst_ident); (yyval.u.inst_ident)->add_scoped_pointer_modifier((yyvsp[-2].u.identifier)); } -#line 6653 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 6679 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 282: -#line 2315 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2339 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.inst_ident) = (yyvsp[-3].u.inst_ident); (yyval.u.inst_ident)->add_array_modifier((yyvsp[-1].u.expr)); } -#line 6662 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 6688 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 283: -#line 2323 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2347 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { - (yyval.u.inst_ident) = new CPPInstanceIdentifier((CPPIdentifier *)NULL); + (yyval.u.inst_ident) = new CPPInstanceIdentifier(nullptr); } -#line 6670 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 6696 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 284: -#line 2327 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2351 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { - (yyval.u.inst_ident) = new CPPInstanceIdentifier((CPPIdentifier *)NULL); + (yyval.u.inst_ident) = new CPPInstanceIdentifier(nullptr); (yyval.u.inst_ident)->_packed = true; } -#line 6679 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 6705 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 285: -#line 2332 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2356 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.inst_ident) = new CPPInstanceIdentifier((yyvsp[0].u.identifier)); (yyval.u.inst_ident)->_packed = true; } -#line 6688 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 6714 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 286: -#line 2337 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2361 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.inst_ident) = (yyvsp[0].u.inst_ident); (yyval.u.inst_ident)->add_modifier(IIT_const); } -#line 6697 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 6723 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 287: -#line 2342 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2366 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.inst_ident) = (yyvsp[0].u.inst_ident); (yyval.u.inst_ident)->add_modifier(IIT_volatile); } -#line 6706 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 6732 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 288: -#line 2347 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2371 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.inst_ident) = (yyvsp[0].u.inst_ident); (yyval.u.inst_ident)->add_modifier(IIT_pointer); } -#line 6715 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 6741 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 289: -#line 2352 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2376 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.inst_ident) = (yyvsp[0].u.inst_ident); (yyval.u.inst_ident)->add_modifier(IIT_reference); } -#line 6724 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 6750 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 290: -#line 2357 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2381 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.inst_ident) = (yyvsp[0].u.inst_ident); (yyval.u.inst_ident)->add_modifier(IIT_rvalue_reference); } -#line 6733 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 6759 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 291: -#line 2362 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2386 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.inst_ident) = (yyvsp[0].u.inst_ident); (yyval.u.inst_ident)->add_scoped_pointer_modifier((yyvsp[-2].u.identifier)); } -#line 6742 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 6768 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 292: -#line 2367 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2391 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.inst_ident) = (yyvsp[-3].u.inst_ident); (yyval.u.inst_ident)->add_array_modifier((yyvsp[-1].u.expr)); } -#line 6751 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 6777 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 293: -#line 2372 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2396 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { - (yyval.u.inst_ident) = new CPPInstanceIdentifier((CPPIdentifier *)NULL); + (yyval.u.inst_ident) = new CPPInstanceIdentifier(nullptr); (yyval.u.inst_ident)->add_modifier(IIT_paren); (yyval.u.inst_ident)->add_func_modifier((yyvsp[-3].u.param_list), (yyvsp[-1].u.integer), (yyvsp[0].u.type)); } -#line 6761 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 6787 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 294: -#line 2378 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2402 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.inst_ident) = (yyvsp[-6].u.inst_ident); (yyval.u.inst_ident)->add_modifier(IIT_pointer); (yyval.u.inst_ident)->add_modifier(IIT_paren); (yyval.u.inst_ident)->add_func_modifier((yyvsp[-3].u.param_list), (yyvsp[-1].u.integer), (yyvsp[0].u.type)); } -#line 6772 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 6798 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 295: -#line 2385 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2409 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.inst_ident) = (yyvsp[-6].u.inst_ident); (yyval.u.inst_ident)->add_modifier(IIT_reference); (yyval.u.inst_ident)->add_modifier(IIT_paren); (yyval.u.inst_ident)->add_func_modifier((yyvsp[-3].u.param_list), (yyvsp[-1].u.integer), (yyvsp[0].u.type)); } -#line 6783 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 6809 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 296: -#line 2392 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2416 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.inst_ident) = (yyvsp[-6].u.inst_ident); (yyval.u.inst_ident)->add_modifier(IIT_rvalue_reference); (yyval.u.inst_ident)->add_modifier(IIT_paren); (yyval.u.inst_ident)->add_func_modifier((yyvsp[-3].u.param_list), (yyvsp[-1].u.integer), (yyvsp[0].u.type)); } -#line 6794 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 6820 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 297: -#line 2402 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2426 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.type) = CPPType::new_type((yyvsp[0].u.simple_type)); } -#line 6802 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 6828 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 298: -#line 2406 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2430 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.type) = (yyvsp[0].u.identifier)->find_type(current_scope, global_scope, false, current_lexer); - if ((yyval.u.type) == NULL) { + if ((yyval.u.type) == nullptr) { yyerror(string("internal error resolving type ") + (yyvsp[0].u.identifier)->get_fully_scoped_name(), (yylsp[0])); } - assert((yyval.u.type) != NULL); + assert((yyval.u.type) != nullptr); } -#line 6814 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 6840 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 299: -#line 2414 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2438 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.type) = CPPType::new_type(new CPPTBDType((yyvsp[0].u.identifier))); } -#line 6822 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 6848 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 300: -#line 2418 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2442 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.type) = CPPType::new_type((yyvsp[0].u.struct_type)); } -#line 6830 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 6856 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 301: -#line 2422 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2446 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.type) = CPPType::new_type((yyvsp[0].u.struct_type)); } -#line 6838 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 6864 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 302: -#line 2426 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2450 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.type) = CPPType::new_type((yyvsp[0].u.enum_type)); } -#line 6846 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 6872 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 303: -#line 2430 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2454 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { CPPType *type = (yyvsp[0].u.identifier)->find_type(current_scope, global_scope, false, current_lexer); - if (type != NULL) { + if (type != nullptr) { (yyval.u.type) = type; } else { CPPExtensionType *et = CPPType::new_type(new CPPExtensionType((yyvsp[-2].u.extension_enum), (yyvsp[0].u.identifier), current_scope, (yylsp[-2]).file)) ->as_extension_type(); CPPScope *scope = (yyvsp[0].u.identifier)->get_scope(current_scope, global_scope); - if (scope != NULL) { + if (scope != nullptr) { scope->define_extension_type(et); } (yyval.u.type) = et; } } -#line 6866 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 6892 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 304: -#line 2446 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2470 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { CPPType *type = (yyvsp[-2].u.identifier)->find_type(current_scope, global_scope, false, current_lexer); - if (type != NULL) { + if (type != nullptr) { (yyval.u.type) = type; } else { CPPExtensionType *et = CPPType::new_type(new CPPExtensionType((yyvsp[-3].u.extension_enum), (yyvsp[-2].u.identifier), current_scope, (yylsp[-3]).file)) ->as_extension_type(); CPPScope *scope = (yyvsp[-2].u.identifier)->get_scope(current_scope, global_scope); - if (scope != NULL) { + if (scope != nullptr) { scope->define_extension_type(et); } (yyval.u.type) = et; } } -#line 6886 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 6912 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 305: -#line 2462 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2486 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.type) = (yyvsp[-1].u.expr)->determine_type(); - if ((yyval.u.type) == (CPPType *)NULL) { + if ((yyval.u.type) == nullptr) { stringstream str; str << *(yyvsp[-1].u.expr); yyerror("could not determine type of " + str.str(), (yylsp[-1])); } } -#line 6899 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 6925 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 306: -#line 2471 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2495 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.type) = CPPType::new_type(new CPPSimpleType(CPPSimpleType::T_auto)); } -#line 6907 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 6933 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 307: -#line 2475 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2499 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { CPPEnumType *enum_type = (yyvsp[-1].u.type)->as_enum_type(); - if (enum_type == NULL) { + if (enum_type == nullptr) { yyerror("an enumeration type is required", (yylsp[-1])); (yyval.u.type) = (yyvsp[-1].u.type); } else { (yyval.u.type) = enum_type->get_underlying_type(); } } -#line 6921 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 6947 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 308: -#line 2485 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2509 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.type) = CPPType::new_type(new CPPSimpleType(CPPSimpleType::T_auto)); } -#line 6929 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 6955 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 309: -#line 2492 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2516 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.type) = (yyvsp[0].u.identifier)->find_type(current_scope, global_scope, false, current_lexer); - if ((yyval.u.type) == NULL) { + if ((yyval.u.type) == nullptr) { yyerror(string("internal error resolving type ") + (yyvsp[0].u.identifier)->get_fully_scoped_name(), (yylsp[0])); } - assert((yyval.u.type) != NULL); + assert((yyval.u.type) != nullptr); } -#line 6941 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 6967 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 310: -#line 2503 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2527 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.decl) = CPPType::new_type((yyvsp[0].u.simple_type)); } -#line 6949 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 6975 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 311: -#line 2507 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2531 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.decl) = (yyvsp[0].u.identifier)->find_type(current_scope, global_scope, false, current_lexer); - if ((yyval.u.decl) == NULL) { + if ((yyval.u.decl) == nullptr) { yyerror(string("internal error resolving type ") + (yyvsp[0].u.identifier)->get_fully_scoped_name(), (yylsp[0])); } - assert((yyval.u.decl) != NULL); + assert((yyval.u.decl) != nullptr); } -#line 6961 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 6987 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 312: -#line 2515 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2539 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.decl) = CPPType::new_type(new CPPTBDType((yyvsp[0].u.identifier))); } -#line 6969 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 6995 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 313: -#line 2519 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2543 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.decl) = CPPType::new_type((yyvsp[0].u.struct_type)); } -#line 6977 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 7003 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 314: -#line 2523 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2547 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.decl) = new CPPTypeDeclaration(CPPType::new_type((yyvsp[0].u.struct_type))); } -#line 6985 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 7011 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 315: -#line 2527 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2551 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.decl) = new CPPTypeDeclaration(CPPType::new_type((yyvsp[0].u.enum_type))); } -#line 6993 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 7019 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 316: -#line 2531 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2555 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { CPPType *type = (yyvsp[0].u.identifier)->find_type(current_scope, global_scope, false, current_lexer); - if (type != NULL) { + if (type != nullptr) { (yyval.u.decl) = type; } else { CPPExtensionType *et = CPPType::new_type(new CPPExtensionType((yyvsp[-2].u.extension_enum), (yyvsp[0].u.identifier), current_scope, (yylsp[-2]).file)) ->as_extension_type(); CPPScope *scope = (yyvsp[0].u.identifier)->get_scope(current_scope, global_scope); - if (scope != NULL) { + if (scope != nullptr) { scope->define_extension_type(et); } (yyval.u.decl) = et; } } -#line 7013 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 7039 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 317: -#line 2547 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2571 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { CPPType *type = (yyvsp[-2].u.identifier)->find_type(current_scope, global_scope, false, current_lexer); - if (type != NULL) { + if (type != nullptr) { (yyval.u.decl) = type; } else { CPPExtensionType *et = CPPType::new_type(new CPPExtensionType((yyvsp[-3].u.extension_enum), (yyvsp[-2].u.identifier), current_scope, (yylsp[-3]).file)) ->as_extension_type(); CPPScope *scope = (yyvsp[-2].u.identifier)->get_scope(current_scope, global_scope); - if (scope != NULL) { + if (scope != nullptr) { scope->define_extension_type(et); } (yyval.u.decl) = et; } } -#line 7033 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 7059 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 318: -#line 2563 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2587 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { yywarning(string("C++ does not permit forward declaration of untyped enum ") + (yyvsp[0].u.identifier)->get_fully_scoped_name(), (yylsp[-1])); CPPType *type = (yyvsp[0].u.identifier)->find_type(current_scope, global_scope, false, current_lexer); - if (type != NULL) { + if (type != nullptr) { (yyval.u.decl) = type; } else { CPPExtensionType *et = CPPType::new_type(new CPPExtensionType((yyvsp[-1].u.extension_enum), (yyvsp[0].u.identifier), current_scope, (yylsp[-1]).file)) ->as_extension_type(); CPPScope *scope = (yyvsp[0].u.identifier)->get_scope(current_scope, global_scope); - if (scope != NULL) { + if (scope != nullptr) { scope->define_extension_type(et); } (yyval.u.decl) = et; } } -#line 7055 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 7081 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 319: -#line 2581 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2605 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.decl) = (yyvsp[-1].u.expr)->determine_type(); - if ((yyval.u.decl) == (CPPType *)NULL) { + if ((yyval.u.decl) == nullptr) { stringstream str; str << *(yyvsp[-1].u.expr); yyerror("could not determine type of " + str.str(), (yylsp[-1])); } } -#line 7068 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 7094 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 320: -#line 2590 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2614 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.decl) = CPPType::new_type(new CPPSimpleType(CPPSimpleType::T_auto)); } -#line 7076 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 7102 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 321: -#line 2594 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2618 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { CPPEnumType *enum_type = (yyvsp[-1].u.type)->as_enum_type(); - if (enum_type == NULL) { + if (enum_type == nullptr) { yyerror("an enumeration type is required", (yylsp[-1])); (yyval.u.decl) = (yyvsp[-1].u.type); } else { (yyval.u.decl) = enum_type->get_underlying_type(); } } -#line 7090 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 7116 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 322: -#line 2604 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2628 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.decl) = CPPType::new_type(new CPPSimpleType(CPPSimpleType::T_auto)); } -#line 7098 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 7124 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 323: -#line 2611 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2635 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.type) = CPPType::new_type((yyvsp[0].u.simple_type)); } -#line 7106 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 7132 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 324: -#line 2615 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2639 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.type) = (yyvsp[0].u.identifier)->find_type(current_scope, global_scope, false, current_lexer); - if ((yyval.u.type) == NULL) { + if ((yyval.u.type) == nullptr) { yyerror(string("internal error resolving type ") + (yyvsp[0].u.identifier)->get_fully_scoped_name(), (yylsp[0])); } - assert((yyval.u.type) != NULL); + assert((yyval.u.type) != nullptr); } -#line 7118 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 7144 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 325: -#line 2623 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2647 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.type) = CPPType::new_type(new CPPTBDType((yyvsp[0].u.identifier))); } -#line 7126 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 7152 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 326: -#line 2627 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2651 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { CPPType *type = (yyvsp[0].u.identifier)->find_type(current_scope, global_scope, false, current_lexer); - if (type != NULL) { + if (type != nullptr) { (yyval.u.type) = type; } else { CPPExtensionType *et = CPPType::new_type(new CPPExtensionType((yyvsp[-2].u.extension_enum), (yyvsp[0].u.identifier), current_scope, (yylsp[-2]).file)) ->as_extension_type(); CPPScope *scope = (yyvsp[0].u.identifier)->get_scope(current_scope, global_scope); - if (scope != NULL) { + if (scope != nullptr) { scope->define_extension_type(et); } (yyval.u.type) = et; } } -#line 7146 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 7172 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 327: -#line 2643 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2667 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { CPPType *type = (yyvsp[0].u.identifier)->find_type(current_scope, global_scope, false, current_lexer); - if (type != NULL) { + if (type != nullptr) { (yyval.u.type) = type; } else { CPPExtensionType *et = CPPType::new_type(new CPPExtensionType((yyvsp[-1].u.extension_enum), (yyvsp[0].u.identifier), current_scope, (yylsp[-1]).file)) ->as_extension_type(); CPPScope *scope = (yyvsp[0].u.identifier)->get_scope(current_scope, global_scope); - if (scope != NULL) { + if (scope != nullptr) { scope->define_extension_type(et); } (yyval.u.type) = et; } } -#line 7166 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 7192 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 328: -#line 2659 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2683 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.type) = (yyvsp[-1].u.expr)->determine_type(); - if ((yyval.u.type) == (CPPType *)NULL) { + if ((yyval.u.type) == nullptr) { stringstream str; str << *(yyvsp[-1].u.expr); yyerror("could not determine type of " + str.str(), (yylsp[-1])); } } -#line 7179 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 7205 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 329: -#line 2668 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2692 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { CPPEnumType *enum_type = (yyvsp[-1].u.type)->as_enum_type(); - if (enum_type == NULL) { + if (enum_type == nullptr) { yyerror("an enumeration type is required", (yylsp[-1])); (yyval.u.type) = (yyvsp[-1].u.type); } else { (yyval.u.type) = enum_type->get_underlying_type(); } } -#line 7193 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 7219 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 330: -#line 2678 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2702 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.type) = CPPType::new_type(new CPPSimpleType(CPPSimpleType::T_auto)); } -#line 7201 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 7227 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 331: -#line 2685 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2709 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.decl) = (yyvsp[0].u.decl); } -#line 7209 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 7235 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 332: -#line 2689 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2713 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { yyerror(string("unknown type '") + (yyvsp[0].u.identifier)->get_fully_scoped_name() + "'", (yylsp[0])); (yyval.u.decl) = CPPType::new_type(new CPPSimpleType(CPPSimpleType::T_unknown)); } -#line 7219 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 7245 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 333: -#line 2697 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2721 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.type) = (yyvsp[0].u.inst_ident)->unroll_type((yyvsp[-1].u.type)); } -#line 7227 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 7253 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 334: -#line 2701 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2725 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyvsp[0].u.inst_ident)->add_modifier(IIT_const); (yyval.u.type) = (yyvsp[0].u.inst_ident)->unroll_type((yyvsp[-1].u.type)); } -#line 7236 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 7262 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 335: -#line 2706 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2730 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.type) = (yyvsp[0].u.inst_ident)->unroll_type((yyvsp[-1].u.type)); } -#line 7244 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 7270 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 336: -#line 2710 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2734 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyvsp[0].u.inst_ident)->add_modifier(IIT_const); (yyval.u.type) = (yyvsp[0].u.inst_ident)->unroll_type((yyvsp[-1].u.type)); } -#line 7253 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 7279 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 341: -#line 2725 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2749 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { CPPVisibility starting_vis = ((yyvsp[-2].u.extension_enum) == CPPExtensionType::T_class) ? V_private : V_public; CPPScope *new_scope = new CPPScope(current_scope, CPPNameComponent("anon"), starting_vis); - CPPStructType *st = new CPPStructType((yyvsp[-2].u.extension_enum), NULL, current_scope, + CPPStructType *st = new CPPStructType((yyvsp[-2].u.extension_enum), nullptr, current_scope, new_scope, (yylsp[-2]).file); new_scope->set_struct_type(st); push_scope(new_scope); push_struct(st); } -#line 7271 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 7297 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 342: -#line 2739 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2763 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.struct_type) = current_struct; current_struct->_incomplete = false; pop_struct(); pop_scope(); } -#line 7282 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 7308 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 343: -#line 2749 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2773 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { CPPVisibility starting_vis = ((yyvsp[-2].u.extension_enum) == CPPExtensionType::T_class) ? V_private : V_public; CPPScope *scope = (yyvsp[0].u.identifier)->get_scope(current_scope, global_scope, current_lexer); - if (scope == NULL) { + if (scope == nullptr) { scope = current_scope; } CPPScope *new_scope = new CPPScope(scope, (yyvsp[0].u.identifier)->_names.back(), @@ -7304,260 +7328,260 @@ yyreduce: push_scope(new_scope); push_struct(st); } -#line 7306 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 7332 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 344: -#line 2769 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2793 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.struct_type) = current_struct; current_struct->_incomplete = false; pop_struct(); pop_scope(); } -#line 7317 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 7343 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 346: -#line 2780 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2804 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { current_struct->_final = true; } -#line 7325 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 7351 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 351: -#line 2797 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2821 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { current_struct->append_derivation((yyvsp[0].u.type), V_unknown, false); } -#line 7333 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 7359 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 352: -#line 2801 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2825 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { current_struct->append_derivation((yyvsp[0].u.type), V_public, false); } -#line 7341 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 7367 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 353: -#line 2805 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2829 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { current_struct->append_derivation((yyvsp[0].u.type), V_protected, false); } -#line 7349 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 7375 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 354: -#line 2809 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2833 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { current_struct->append_derivation((yyvsp[0].u.type), V_private, false); } -#line 7357 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 7383 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 355: -#line 2813 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2837 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { current_struct->append_derivation((yyvsp[0].u.type), V_public, true); } -#line 7365 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 7391 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 356: -#line 2817 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2841 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { current_struct->append_derivation((yyvsp[0].u.type), V_protected, true); } -#line 7373 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 7399 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 357: -#line 2821 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2845 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { current_struct->append_derivation((yyvsp[0].u.type), V_private, true); } -#line 7381 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 7407 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 358: -#line 2825 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2849 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { current_struct->append_derivation((yyvsp[0].u.type), V_public, true); } -#line 7389 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 7415 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 359: -#line 2829 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2853 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { current_struct->append_derivation((yyvsp[0].u.type), V_protected, true); } -#line 7397 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 7423 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 360: -#line 2833 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2857 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { current_struct->append_derivation((yyvsp[0].u.type), V_private, true); } -#line 7405 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 7431 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 361: -#line 2840 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2864 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.enum_type) = current_enum; - current_enum = NULL; + current_enum = nullptr; } -#line 7414 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 7440 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 362: -#line 2848 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2872 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { - current_enum = new CPPEnumType((yyvsp[-2].u.extension_enum), NULL, (yyvsp[0].u.type), current_scope, NULL, (yylsp[-2]).file); + current_enum = new CPPEnumType((yyvsp[-2].u.extension_enum), nullptr, (yyvsp[0].u.type), current_scope, nullptr, (yylsp[-2]).file); } -#line 7422 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 7448 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 363: -#line 2852 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2876 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { - current_enum = new CPPEnumType((yyvsp[0].u.extension_enum), NULL, current_scope, NULL, (yylsp[0]).file); + current_enum = new CPPEnumType((yyvsp[0].u.extension_enum), nullptr, current_scope, nullptr, (yylsp[0]).file); } -#line 7430 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 7456 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 364: -#line 2856 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2880 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { CPPScope *new_scope = new CPPScope(current_scope, (yyvsp[-2].u.identifier)->_names.back(), V_public); current_enum = new CPPEnumType((yyvsp[-3].u.extension_enum), (yyvsp[-2].u.identifier), (yyvsp[0].u.type), current_scope, new_scope, (yylsp[-3]).file); } -#line 7439 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 7465 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 365: -#line 2861 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2885 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { CPPScope *new_scope = new CPPScope(current_scope, (yyvsp[0].u.identifier)->_names.back(), V_public); current_enum = new CPPEnumType((yyvsp[-1].u.extension_enum), (yyvsp[0].u.identifier), current_scope, new_scope, (yylsp[-1]).file); } -#line 7448 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 7474 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 366: -#line 2869 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2893 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.type) = CPPType::new_type((yyvsp[0].u.simple_type)); } -#line 7456 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 7482 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 367: -#line 2873 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2897 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.type) = (yyvsp[0].u.identifier)->find_type(current_scope, global_scope, false, current_lexer); } -#line 7464 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 7490 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 369: -#line 2881 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2905 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { - assert(current_enum != NULL); - current_enum->add_element((yyvsp[-1].u.identifier)->get_simple_name(), NULL, current_lexer, (yylsp[-1])); + assert(current_enum != nullptr); + current_enum->add_element((yyvsp[-1].u.identifier)->get_simple_name(), nullptr, current_lexer, (yylsp[-1])); } -#line 7473 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 7499 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 370: -#line 2886 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2910 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { - assert(current_enum != NULL); + assert(current_enum != nullptr); current_enum->add_element((yyvsp[-3].u.identifier)->get_simple_name(), (yyvsp[-1].u.expr), current_lexer, (yylsp[-3])); } -#line 7482 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 7508 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 372: -#line 2894 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2918 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { - assert(current_enum != NULL); - current_enum->add_element((yyvsp[0].u.identifier)->get_simple_name(), NULL, current_lexer, (yylsp[0])); + assert(current_enum != nullptr); + current_enum->add_element((yyvsp[0].u.identifier)->get_simple_name(), nullptr, current_lexer, (yylsp[0])); } -#line 7491 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 7517 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 373: -#line 2899 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2923 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { - assert(current_enum != NULL); + assert(current_enum != nullptr); current_enum->add_element((yyvsp[-2].u.identifier)->get_simple_name(), (yyvsp[0].u.expr), current_lexer, (yylsp[-2])); } -#line 7500 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 7526 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 374: -#line 2907 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2931 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.extension_enum) = CPPExtensionType::T_enum; } -#line 7508 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 7534 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 375: -#line 2911 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2935 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.extension_enum) = CPPExtensionType::T_enum_class; } -#line 7516 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 7542 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 376: -#line 2915 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2939 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.extension_enum) = CPPExtensionType::T_enum_struct; } -#line 7524 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 7550 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 377: -#line 2922 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2946 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.extension_enum) = CPPExtensionType::T_class; } -#line 7532 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 7558 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 378: -#line 2926 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2950 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.extension_enum) = CPPExtensionType::T_struct; } -#line 7540 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 7566 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 379: -#line 2930 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2954 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.extension_enum) = CPPExtensionType::T_union; } -#line 7548 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 7574 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 380: -#line 2937 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2961 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { CPPScope *scope = (yyvsp[-1].u.identifier)->find_scope(current_scope, global_scope, current_lexer); - if (scope == NULL) { + if (scope == nullptr) { // This must be a new namespace declaration. CPPScope *parent_scope = (yyvsp[-1].u.identifier)->get_scope(current_scope, global_scope, current_lexer); - if (parent_scope == NULL) { + if (parent_scope == nullptr) { parent_scope = current_scope; } scope = new CPPScope(parent_scope, (yyvsp[-1].u.identifier)->_names.back(), V_public); @@ -7568,26 +7592,26 @@ yyreduce: current_scope->define_namespace(nspace); push_scope(scope); } -#line 7570 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 7596 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 381: -#line 2955 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2979 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { pop_scope(); } -#line 7578 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 7604 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 382: -#line 2959 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 2983 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { CPPScope *scope = (yyvsp[-1].u.identifier)->find_scope(current_scope, global_scope, current_lexer); - if (scope == NULL) { + if (scope == nullptr) { // This must be a new namespace declaration. CPPScope *parent_scope = (yyvsp[-1].u.identifier)->get_scope(current_scope, global_scope, current_lexer); - if (parent_scope == NULL) { + if (parent_scope == nullptr) { parent_scope = current_scope; } scope = new CPPScope(parent_scope, (yyvsp[-1].u.identifier)->_names.back(), V_public); @@ -7599,143 +7623,143 @@ yyreduce: current_scope->define_namespace(nspace); push_scope(scope); } -#line 7601 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 7627 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 383: -#line 2978 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3002 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { pop_scope(); } -#line 7609 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 7635 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 386: -#line 2987 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3011 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { CPPUsing *using_decl = new CPPUsing((yyvsp[-1].u.identifier), false, (yylsp[-2]).file); current_scope->add_declaration(using_decl, global_scope, current_lexer, (yylsp[-2])); current_scope->add_using(using_decl, global_scope, current_lexer); } -#line 7619 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 7645 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 387: -#line 2993 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3017 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { // This is really just an alternative way to declare a typedef. CPPTypedefType *typedef_type = new CPPTypedefType((yyvsp[-1].u.type), (yyvsp[-3].u.identifier), current_scope); typedef_type->_using = true; current_scope->add_declaration(CPPType::new_type(typedef_type), global_scope, current_lexer, (yylsp[-4])); } -#line 7630 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 7656 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 388: -#line 3000 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3024 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { CPPUsing *using_decl = new CPPUsing((yyvsp[-1].u.identifier), true, (yylsp[-3]).file); current_scope->add_declaration(using_decl, global_scope, current_lexer, (yylsp[-3])); current_scope->add_using(using_decl, global_scope, current_lexer); } -#line 7640 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 7666 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 392: -#line 3015 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3039 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.simple_type) = new CPPSimpleType(CPPSimpleType::T_bool); } -#line 7648 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 7674 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 393: -#line 3019 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3043 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.simple_type) = new CPPSimpleType(CPPSimpleType::T_char); } -#line 7656 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 7682 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 394: -#line 3023 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3047 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.simple_type) = new CPPSimpleType(CPPSimpleType::T_wchar_t); } -#line 7664 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 7690 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 395: -#line 3027 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3051 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.simple_type) = new CPPSimpleType(CPPSimpleType::T_char16_t); } -#line 7672 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 7698 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 396: -#line 3031 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3055 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.simple_type) = new CPPSimpleType(CPPSimpleType::T_char32_t); } -#line 7680 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 7706 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 397: -#line 3035 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3059 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.simple_type) = new CPPSimpleType(CPPSimpleType::T_int, CPPSimpleType::F_short); } -#line 7689 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 7715 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 398: -#line 3040 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3064 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.simple_type) = new CPPSimpleType(CPPSimpleType::T_int, CPPSimpleType::F_long); } -#line 7698 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 7724 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 399: -#line 3045 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3069 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.simple_type) = new CPPSimpleType(CPPSimpleType::T_int, CPPSimpleType::F_unsigned); } -#line 7707 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 7733 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 400: -#line 3050 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3074 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.simple_type) = new CPPSimpleType(CPPSimpleType::T_int, CPPSimpleType::F_signed); } -#line 7716 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 7742 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 401: -#line 3055 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3079 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.simple_type) = new CPPSimpleType(CPPSimpleType::T_int); } -#line 7724 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 7750 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 402: -#line 3059 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3083 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.simple_type) = (yyvsp[0].u.simple_type); (yyval.u.simple_type)->_flags |= CPPSimpleType::F_short; } -#line 7733 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 7759 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 403: -#line 3064 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3088 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.simple_type) = (yyvsp[0].u.simple_type); if ((yyval.u.simple_type)->_flags & CPPSimpleType::F_long) { @@ -7744,192 +7768,192 @@ yyreduce: (yyval.u.simple_type)->_flags |= CPPSimpleType::F_long; } } -#line 7746 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 7772 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 404: -#line 3073 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3097 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.simple_type) = (yyvsp[0].u.simple_type); (yyval.u.simple_type)->_flags |= CPPSimpleType::F_unsigned; } -#line 7755 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 7781 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 405: -#line 3078 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3102 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.simple_type) = (yyvsp[0].u.simple_type); (yyval.u.simple_type)->_flags |= CPPSimpleType::F_signed; } -#line 7764 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 7790 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 406: -#line 3086 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3110 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.simple_type) = new CPPSimpleType(CPPSimpleType::T_float); } -#line 7772 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 7798 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 407: -#line 3090 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3114 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.simple_type) = new CPPSimpleType(CPPSimpleType::T_double); } -#line 7780 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 7806 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 408: -#line 3094 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3118 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.simple_type) = new CPPSimpleType(CPPSimpleType::T_double, CPPSimpleType::F_long); } -#line 7789 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 7815 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 409: -#line 3102 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3126 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.simple_type) = new CPPSimpleType(CPPSimpleType::T_void); } -#line 7797 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 7823 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 410: -#line 3111 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3135 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { current_lexer->_resolve_identifiers = false; } -#line 7805 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 7831 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 411: -#line 3115 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3139 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { current_lexer->_resolve_identifiers = true; } -#line 7813 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 7839 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 519: -#line 3159 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3183 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { } -#line 7820 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 7846 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 543: -#line 3168 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3192 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { - (yyval.u.expr) = (CPPExpression *)NULL; + (yyval.u.expr) = nullptr; } -#line 7828 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 7854 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 544: -#line 3172 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3196 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = (yyvsp[0].u.expr); } -#line 7836 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 7862 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 545: -#line 3179 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3203 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { - (yyval.u.expr) = (CPPExpression *)NULL; + (yyval.u.expr) = nullptr; } -#line 7844 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 7870 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 546: -#line 3183 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3207 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = (yyvsp[0].u.expr); } -#line 7852 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 7878 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 547: -#line 3190 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3214 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = (yyvsp[0].u.expr); } -#line 7860 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 7886 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 548: -#line 3194 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3218 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression(',', (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 7868 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 7894 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 549: -#line 3201 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3225 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = (yyvsp[0].u.expr); } -#line 7876 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 7902 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 550: -#line 3205 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3229 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression(CPPExpression::typecast_op((yyvsp[-2].u.type), (yyvsp[0].u.expr))); } -#line 7884 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 7910 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 551: -#line 3209 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3233 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression(CPPExpression::typecast_op((yyvsp[-4].u.type), (yyvsp[-1].u.expr), CPPExpression::T_static_cast)); } -#line 7892 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 7918 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 552: -#line 3213 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3237 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression(CPPExpression::typecast_op((yyvsp[-4].u.type), (yyvsp[-1].u.expr), CPPExpression::T_dynamic_cast)); } -#line 7900 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 7926 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 553: -#line 3217 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3241 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression(CPPExpression::typecast_op((yyvsp[-4].u.type), (yyvsp[-1].u.expr), CPPExpression::T_const_cast)); } -#line 7908 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 7934 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 554: -#line 3221 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3245 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression(CPPExpression::typecast_op((yyvsp[-4].u.type), (yyvsp[-1].u.expr), CPPExpression::T_reinterpret_cast)); } -#line 7916 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 7942 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 555: -#line 3225 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3249 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression(CPPExpression::sizeof_func((yyvsp[-1].u.type))); } -#line 7924 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 7950 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 556: -#line 3229 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3253 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { CPPDeclaration *arg = (yyvsp[-1].u.identifier)->find_symbol(current_scope, global_scope, current_lexer); - if (arg == (CPPDeclaration *)NULL) { + if (arg == nullptr) { yyerror("undefined sizeof argument: " + (yyvsp[-1].u.identifier)->get_fully_scoped_name(), (yylsp[-1])); } else if (arg->get_subtype() == CPPDeclaration::ST_instance) { CPPInstance *inst = arg->as_instance(); @@ -7938,470 +7962,470 @@ yyreduce: (yyval.u.expr) = new CPPExpression(CPPExpression::sizeof_func(arg->as_type())); } } -#line 7940 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 7966 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 557: -#line 3241 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3265 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression(CPPExpression::sizeof_ellipsis_func((yyvsp[-1].u.identifier))); } -#line 7948 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 7974 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 558: -#line 3245 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3269 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression(CPPExpression::alignof_func((yyvsp[-1].u.type))); } -#line 7956 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 7982 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 559: -#line 3249 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3273 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression(UNARY_NOT, (yyvsp[0].u.expr)); } -#line 7964 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 7990 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 560: -#line 3253 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3277 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression(UNARY_NEGATE, (yyvsp[0].u.expr)); } -#line 7972 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 7998 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 561: -#line 3257 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3281 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression(UNARY_MINUS, (yyvsp[0].u.expr)); } -#line 7980 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 8006 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 562: -#line 3261 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3285 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression(UNARY_PLUS, (yyvsp[0].u.expr)); } -#line 7988 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 8014 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 563: -#line 3265 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3289 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression(UNARY_STAR, (yyvsp[0].u.expr)); } -#line 7996 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 8022 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 564: -#line 3269 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3293 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression(UNARY_REF, (yyvsp[0].u.expr)); } -#line 8004 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 8030 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 565: -#line 3273 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3297 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression('*', (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 8012 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 8038 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 566: -#line 3277 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3301 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression('/', (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 8020 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 8046 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 567: -#line 3281 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3305 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression('%', (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 8028 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 8054 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 568: -#line 3285 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3309 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression('+', (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 8036 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 8062 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 569: -#line 3289 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3313 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression('-', (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 8044 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 8070 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 570: -#line 3293 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3317 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression('|', (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 8052 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 8078 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 571: -#line 3297 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3321 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression('^', (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 8060 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 8086 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 572: -#line 3301 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3325 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression('&', (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 8068 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 8094 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 573: -#line 3305 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3329 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression(OROR, (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 8076 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 8102 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 574: -#line 3309 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3333 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression(ANDAND, (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 8084 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 8110 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 575: -#line 3313 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3337 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression(EQCOMPARE, (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 8092 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 8118 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 576: -#line 3317 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3341 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression(NECOMPARE, (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 8100 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 8126 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 577: -#line 3321 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3345 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression(LECOMPARE, (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 8108 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 8134 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 578: -#line 3325 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3349 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression(GECOMPARE, (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 8116 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 8142 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 579: -#line 3329 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3353 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression(LSHIFT, (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 8124 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 8150 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 580: -#line 3333 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3357 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression(RSHIFT, (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 8132 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 8158 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 581: -#line 3337 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3361 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression('?', (yyvsp[-4].u.expr), (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 8140 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 8166 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 582: -#line 3341 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3365 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression('[', (yyvsp[-3].u.expr), (yyvsp[-1].u.expr)); } -#line 8148 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 8174 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 583: -#line 3345 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3369 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression('f', (yyvsp[-3].u.expr), (yyvsp[-1].u.expr)); } -#line 8156 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 8182 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 584: -#line 3349 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3373 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression('f', (yyvsp[-2].u.expr)); } -#line 8164 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 8190 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 585: -#line 3353 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3377 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression('.', (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 8172 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 8198 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 586: -#line 3357 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3381 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression(POINTSAT, (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 8180 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 8206 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 587: -#line 3361 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3385 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = (yyvsp[-1].u.expr); } -#line 8188 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 8214 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 588: -#line 3369 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3393 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = (yyvsp[0].u.expr); } -#line 8196 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 8222 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 589: -#line 3373 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3397 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression(CPPExpression::typecast_op((yyvsp[-2].u.type), (yyvsp[0].u.expr))); } -#line 8204 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 8230 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 590: -#line 3377 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3401 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression(CPPExpression::typecast_op((yyvsp[-4].u.type), (yyvsp[-1].u.expr), CPPExpression::T_static_cast)); } -#line 8212 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 8238 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 591: -#line 3381 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3405 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression(CPPExpression::typecast_op((yyvsp[-4].u.type), (yyvsp[-1].u.expr), CPPExpression::T_dynamic_cast)); } -#line 8220 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 8246 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 592: -#line 3385 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3409 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression(CPPExpression::typecast_op((yyvsp[-4].u.type), (yyvsp[-1].u.expr), CPPExpression::T_const_cast)); } -#line 8228 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 8254 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 593: -#line 3389 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3413 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression(CPPExpression::typecast_op((yyvsp[-4].u.type), (yyvsp[-1].u.expr), CPPExpression::T_reinterpret_cast)); } -#line 8236 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 8262 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 594: -#line 3393 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3417 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { // A constructor call. CPPType *type = (yyvsp[-3].u.identifier)->find_type(current_scope, global_scope, false, current_lexer); - if (type == NULL) { + if (type == nullptr) { yyerror(string("internal error resolving type ") + (yyvsp[-3].u.identifier)->get_fully_scoped_name(), (yylsp[-3])); } - assert(type != NULL); + assert(type != nullptr); (yyval.u.expr) = new CPPExpression(CPPExpression::construct_op(type, (yyvsp[-1].u.expr))); } -#line 8250 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 8276 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 595: -#line 3403 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3427 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { // Aggregate initialization. CPPType *type = (yyvsp[-3].u.identifier)->find_type(current_scope, global_scope, false, current_lexer); - if (type == NULL) { + if (type == nullptr) { yyerror(string("internal error resolving type ") + (yyvsp[-3].u.identifier)->get_fully_scoped_name(), (yylsp[-3])); } - assert(type != NULL); + assert(type != nullptr); (yyval.u.expr) = new CPPExpression(CPPExpression::aggregate_init_op(type, (yyvsp[-1].u.expr))); } -#line 8264 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 8290 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 596: -#line 3413 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3437 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { CPPType *type = CPPType::new_type(new CPPSimpleType(CPPSimpleType::T_int)); (yyval.u.expr) = new CPPExpression(CPPExpression::construct_op(type, (yyvsp[-1].u.expr))); } -#line 8274 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 8300 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 597: -#line 3419 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3443 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { CPPType *type = CPPType::new_type(new CPPSimpleType(CPPSimpleType::T_char)); (yyval.u.expr) = new CPPExpression(CPPExpression::construct_op(type, (yyvsp[-1].u.expr))); } -#line 8284 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 8310 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 598: -#line 3425 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3449 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { CPPType *type = CPPType::new_type(new CPPSimpleType(CPPSimpleType::T_wchar_t)); (yyval.u.expr) = new CPPExpression(CPPExpression::construct_op(type, (yyvsp[-1].u.expr))); } -#line 8294 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 8320 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 599: -#line 3431 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3455 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { CPPType *type = CPPType::new_type(new CPPSimpleType(CPPSimpleType::T_char16_t)); (yyval.u.expr) = new CPPExpression(CPPExpression::construct_op(type, (yyvsp[-1].u.expr))); } -#line 8304 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 8330 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 600: -#line 3437 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3461 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { CPPType *type = CPPType::new_type(new CPPSimpleType(CPPSimpleType::T_char32_t)); (yyval.u.expr) = new CPPExpression(CPPExpression::construct_op(type, (yyvsp[-1].u.expr))); } -#line 8314 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 8340 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 601: -#line 3443 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3467 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { CPPType *type = CPPType::new_type(new CPPSimpleType(CPPSimpleType::T_bool)); (yyval.u.expr) = new CPPExpression(CPPExpression::construct_op(type, (yyvsp[-1].u.expr))); } -#line 8324 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 8350 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 602: -#line 3449 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3473 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { CPPType *type = CPPType::new_type(new CPPSimpleType(CPPSimpleType::T_int, CPPSimpleType::F_short)); (yyval.u.expr) = new CPPExpression(CPPExpression::construct_op(type, (yyvsp[-1].u.expr))); } -#line 8335 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 8361 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 603: -#line 3456 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3480 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { CPPType *type = CPPType::new_type(new CPPSimpleType(CPPSimpleType::T_int, CPPSimpleType::F_long)); (yyval.u.expr) = new CPPExpression(CPPExpression::construct_op(type, (yyvsp[-1].u.expr))); } -#line 8346 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 8372 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 604: -#line 3463 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3487 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { CPPType *type = CPPType::new_type(new CPPSimpleType(CPPSimpleType::T_int, CPPSimpleType::F_unsigned)); (yyval.u.expr) = new CPPExpression(CPPExpression::construct_op(type, (yyvsp[-1].u.expr))); } -#line 8357 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 8383 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 605: -#line 3470 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3494 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { CPPType *type = CPPType::new_type(new CPPSimpleType(CPPSimpleType::T_int, CPPSimpleType::F_signed)); (yyval.u.expr) = new CPPExpression(CPPExpression::construct_op(type, (yyvsp[-1].u.expr))); } -#line 8368 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 8394 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 606: -#line 3477 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3501 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { CPPType *type = CPPType::new_type(new CPPSimpleType(CPPSimpleType::T_float)); (yyval.u.expr) = new CPPExpression(CPPExpression::construct_op(type, (yyvsp[-1].u.expr))); } -#line 8378 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 8404 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 607: -#line 3483 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3507 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { CPPType *type = CPPType::new_type(new CPPSimpleType(CPPSimpleType::T_double)); (yyval.u.expr) = new CPPExpression(CPPExpression::construct_op(type, (yyvsp[-1].u.expr))); } -#line 8388 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 8414 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 608: -#line 3489 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3513 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression(CPPExpression::sizeof_func((yyvsp[-1].u.type))); } -#line 8396 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 8422 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 609: -#line 3493 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3517 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { CPPDeclaration *arg = (yyvsp[-1].u.identifier)->find_symbol(current_scope, global_scope, current_lexer); - if (arg == (CPPDeclaration *)NULL) { + if (arg == nullptr) { yyerror("undefined sizeof argument: " + (yyvsp[-1].u.identifier)->get_fully_scoped_name(), (yylsp[-1])); } else if (arg->get_subtype() == CPPDeclaration::ST_instance) { CPPInstance *inst = arg->as_instance(); @@ -8410,43 +8434,43 @@ yyreduce: (yyval.u.expr) = new CPPExpression(CPPExpression::sizeof_func(arg->as_type())); } } -#line 8412 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 8438 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 610: -#line 3505 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3529 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression(CPPExpression::sizeof_ellipsis_func((yyvsp[-1].u.identifier))); } -#line 8420 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 8446 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 611: -#line 3509 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3533 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression(CPPExpression::alignof_func((yyvsp[-1].u.type))); } -#line 8428 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 8454 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 612: -#line 3513 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3537 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression(CPPExpression::new_op((yyvsp[0].u.type))); } -#line 8436 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 8462 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 613: -#line 3517 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3541 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression(CPPExpression::new_op((yyvsp[-3].u.type), (yyvsp[-1].u.expr))); } -#line 8444 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 8470 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 614: -#line 3521 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3545 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { CPPIdentifier ident(""); ident.add_name("std"); @@ -8457,11 +8481,11 @@ yyreduce: } (yyval.u.expr) = new CPPExpression(CPPExpression::typeid_op((yyvsp[-1].u.type), std_type_info)); } -#line 8459 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 8485 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 615: -#line 3532 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3556 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { CPPIdentifier ident(""); ident.add_name("std"); @@ -8472,567 +8496,567 @@ yyreduce: } (yyval.u.expr) = new CPPExpression(CPPExpression::typeid_op((yyvsp[-1].u.expr), std_type_info)); } -#line 8474 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 8500 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 616: -#line 3543 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3567 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression(UNARY_NOT, (yyvsp[0].u.expr)); } -#line 8482 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 8508 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 617: -#line 3547 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3571 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression(UNARY_NEGATE, (yyvsp[0].u.expr)); } -#line 8490 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 8516 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 618: -#line 3551 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3575 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression(UNARY_MINUS, (yyvsp[0].u.expr)); } -#line 8498 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 8524 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 619: -#line 3555 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3579 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression(UNARY_PLUS, (yyvsp[0].u.expr)); } -#line 8506 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 8532 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 620: -#line 3559 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3583 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression(UNARY_STAR, (yyvsp[0].u.expr)); } -#line 8514 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 8540 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 621: -#line 3563 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3587 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression(UNARY_REF, (yyvsp[0].u.expr)); } -#line 8522 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 8548 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 622: -#line 3567 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3591 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression('*', (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 8530 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 8556 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 623: -#line 3571 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3595 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression('/', (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 8538 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 8564 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 624: -#line 3575 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3599 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression('%', (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 8546 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 8572 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 625: -#line 3579 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3603 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression('+', (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 8554 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 8580 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 626: -#line 3583 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3607 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression('-', (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 8562 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 8588 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 627: -#line 3587 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3611 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression('|', (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 8570 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 8596 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 628: -#line 3591 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3615 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression('^', (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 8578 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 8604 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 629: -#line 3595 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3619 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression('&', (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 8586 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 8612 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 630: -#line 3599 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3623 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression(OROR, (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 8594 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 8620 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 631: -#line 3603 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3627 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression(ANDAND, (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 8602 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 8628 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 632: -#line 3607 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3631 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression(EQCOMPARE, (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 8610 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 8636 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 633: -#line 3611 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3635 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression(NECOMPARE, (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 8618 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 8644 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 634: -#line 3615 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3639 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression(LECOMPARE, (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 8626 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 8652 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 635: -#line 3619 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3643 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression(GECOMPARE, (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 8634 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 8660 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 636: -#line 3623 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3647 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression('<', (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 8642 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 8668 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 637: -#line 3627 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3651 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression('>', (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 8650 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 8676 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 638: -#line 3631 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3655 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression(LSHIFT, (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 8658 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 8684 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 639: -#line 3635 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3659 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression(RSHIFT, (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 8666 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 8692 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 640: -#line 3639 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3663 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression('?', (yyvsp[-4].u.expr), (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 8674 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 8700 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 641: -#line 3643 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3667 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression('[', (yyvsp[-3].u.expr), (yyvsp[-1].u.expr)); } -#line 8682 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 8708 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 642: -#line 3647 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3671 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression('f', (yyvsp[-3].u.expr), (yyvsp[-1].u.expr)); } -#line 8690 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 8716 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 643: -#line 3651 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3675 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression('f', (yyvsp[-2].u.expr)); } -#line 8698 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 8724 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 644: -#line 3655 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3679 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression('.', (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 8706 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 8732 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 645: -#line 3659 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3683 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression(POINTSAT, (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 8714 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 8740 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 646: -#line 3663 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3687 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = (yyvsp[-1].u.expr); } -#line 8722 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 8748 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 647: -#line 3670 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3694 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression((yyvsp[0].u.integer)); } -#line 8730 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 8756 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 648: -#line 3674 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3698 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression(true); } -#line 8738 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 8764 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 649: -#line 3678 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3702 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression(false); } -#line 8746 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 8772 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 650: -#line 3682 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3706 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression((yyvsp[0].u.integer)); } -#line 8754 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 8780 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 651: -#line 3686 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3710 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression((yyvsp[0].u.real)); } -#line 8762 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 8788 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 652: -#line 3690 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3714 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = (yyvsp[0].u.expr); } -#line 8770 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 8796 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 653: -#line 3694 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3718 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = (yyvsp[0].u.expr); } -#line 8778 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 8804 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 654: -#line 3698 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3722 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression((yyvsp[0].u.identifier), current_scope, global_scope, current_lexer); } -#line 8786 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 8812 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 655: -#line 3702 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3726 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { // A variable named "final". C++11 explicitly permits this. CPPIdentifier *ident = new CPPIdentifier("final", (yylsp[0])); (yyval.u.expr) = new CPPExpression(ident, current_scope, global_scope, current_lexer); } -#line 8796 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 8822 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 656: -#line 3708 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3732 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { // A variable named "override". C++11 explicitly permits this. CPPIdentifier *ident = new CPPIdentifier("override", (yylsp[0])); (yyval.u.expr) = new CPPExpression(ident, current_scope, global_scope, current_lexer); } -#line 8806 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 8832 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 657: -#line 3714 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3738 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression(CPPExpression::get_nullptr()); } -#line 8814 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 8840 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 658: -#line 3718 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3742 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyvsp[-6].u.closure_type)->_flags = (yyvsp[-4].u.integer); (yyvsp[-6].u.closure_type)->_return_type = (yyvsp[-3].u.type); (yyval.u.expr) = new CPPExpression(CPPExpression::lambda((yyvsp[-6].u.closure_type))); } -#line 8824 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 8850 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 659: -#line 3724 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3748 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyvsp[-9].u.closure_type)->_parameters = (yyvsp[-6].u.param_list); (yyvsp[-9].u.closure_type)->_flags = (yyvsp[-4].u.integer); (yyvsp[-9].u.closure_type)->_return_type = (yyvsp[-3].u.type); (yyval.u.expr) = new CPPExpression(CPPExpression::lambda((yyvsp[-9].u.closure_type))); } -#line 8835 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 8861 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 660: -#line 3731 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3755 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression(CPPExpression::type_trait(KW_HAS_VIRTUAL_DESTRUCTOR, (yyvsp[-1].u.type))); } -#line 8843 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 8869 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 661: -#line 3735 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3759 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression(CPPExpression::type_trait(KW_IS_ABSTRACT, (yyvsp[-1].u.type))); } -#line 8851 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 8877 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 662: -#line 3739 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3763 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression(CPPExpression::type_trait(KW_IS_CLASS, (yyvsp[-3].u.type), (yyvsp[-1].u.type))); } -#line 8859 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 8885 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 663: -#line 3743 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3767 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression(CPPExpression::type_trait(KW_IS_CLASS, (yyvsp[-1].u.type))); } -#line 8867 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 8893 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 664: -#line 3747 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3771 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression(CPPExpression::type_trait(KW_IS_CONSTRUCTIBLE, (yyvsp[-1].u.type))); } -#line 8875 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 8901 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 665: -#line 3751 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3775 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression(CPPExpression::type_trait(KW_IS_CONSTRUCTIBLE, (yyvsp[-3].u.type), (yyvsp[-1].u.type))); } -#line 8883 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 8909 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 666: -#line 3755 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3779 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression(CPPExpression::type_trait(KW_IS_CONVERTIBLE_TO, (yyvsp[-3].u.type), (yyvsp[-1].u.type))); } -#line 8891 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 8917 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 667: -#line 3759 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3783 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression(CPPExpression::type_trait(KW_IS_DESTRUCTIBLE, (yyvsp[-1].u.type))); } -#line 8899 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 8925 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 668: -#line 3763 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3787 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression(CPPExpression::type_trait(KW_IS_EMPTY, (yyvsp[-1].u.type))); } -#line 8907 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 8933 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 669: -#line 3767 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3791 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression(CPPExpression::type_trait(KW_IS_ENUM, (yyvsp[-1].u.type))); } -#line 8915 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 8941 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 670: -#line 3771 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3795 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression(CPPExpression::type_trait(KW_IS_FINAL, (yyvsp[-1].u.type))); } -#line 8923 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 8949 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 671: -#line 3775 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3799 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression(CPPExpression::type_trait(KW_IS_FUNDAMENTAL, (yyvsp[-1].u.type))); } -#line 8931 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 8957 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 672: -#line 3779 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3803 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression(CPPExpression::type_trait(KW_IS_POD, (yyvsp[-1].u.type))); } -#line 8939 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 8965 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 673: -#line 3783 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3807 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression(CPPExpression::type_trait(KW_IS_POLYMORPHIC, (yyvsp[-1].u.type))); } -#line 8947 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 8973 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 674: -#line 3787 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3811 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression(CPPExpression::type_trait(KW_IS_STANDARD_LAYOUT, (yyvsp[-1].u.type))); } -#line 8955 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 8981 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 675: -#line 3791 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3815 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression(CPPExpression::type_trait(KW_IS_TRIVIAL, (yyvsp[-1].u.type))); } -#line 8963 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 8989 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 676: -#line 3795 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3819 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression(CPPExpression::type_trait(KW_IS_UNION, (yyvsp[-1].u.type))); } -#line 8971 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 8997 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 677: -#line 3809 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3833 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = (yyvsp[0].u.expr); } -#line 8979 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 9005 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 678: -#line 3813 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3837 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression(CPPExpression::typecast_op((yyvsp[-2].u.type), (yyvsp[0].u.expr))); } -#line 8987 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 9013 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 679: -#line 3817 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3841 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression(CPPExpression::typecast_op((yyvsp[-4].u.type), (yyvsp[-1].u.expr), CPPExpression::T_static_cast)); } -#line 8995 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 9021 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 680: -#line 3821 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3845 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression(CPPExpression::typecast_op((yyvsp[-4].u.type), (yyvsp[-1].u.expr), CPPExpression::T_dynamic_cast)); } -#line 9003 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 9029 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 681: -#line 3825 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3849 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression(CPPExpression::typecast_op((yyvsp[-4].u.type), (yyvsp[-1].u.expr), CPPExpression::T_const_cast)); } -#line 9011 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 9037 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 682: -#line 3829 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3853 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression(CPPExpression::typecast_op((yyvsp[-4].u.type), (yyvsp[-1].u.expr), CPPExpression::T_reinterpret_cast)); } -#line 9019 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 9045 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 683: -#line 3833 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3857 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression(CPPExpression::sizeof_func((yyvsp[-1].u.type))); } -#line 9027 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 9053 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 684: -#line 3837 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3861 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { CPPDeclaration *arg = (yyvsp[-1].u.identifier)->find_symbol(current_scope, global_scope, current_lexer); - if (arg == (CPPDeclaration *)NULL) { + if (arg == nullptr) { yyerror("undefined sizeof argument: " + (yyvsp[-1].u.identifier)->get_fully_scoped_name(), (yylsp[-1])); } else if (arg->get_subtype() == CPPDeclaration::ST_instance) { CPPInstance *inst = arg->as_instance(); @@ -9041,43 +9065,43 @@ yyreduce: (yyval.u.expr) = new CPPExpression(CPPExpression::sizeof_func(arg->as_type())); } } -#line 9043 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 9069 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 685: -#line 3849 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3873 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression(CPPExpression::sizeof_ellipsis_func((yyvsp[-1].u.identifier))); } -#line 9051 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 9077 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 686: -#line 3853 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3877 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression(CPPExpression::alignof_func((yyvsp[-1].u.type))); } -#line 9059 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 9085 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 687: -#line 3857 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3881 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression(CPPExpression::new_op((yyvsp[0].u.type))); } -#line 9067 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 9093 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 688: -#line 3861 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3885 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression(CPPExpression::new_op((yyvsp[-3].u.type), (yyvsp[-1].u.expr))); } -#line 9075 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 9101 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 689: -#line 3865 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3889 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { CPPIdentifier ident(""); ident.add_name("std"); @@ -9088,11 +9112,11 @@ yyreduce: } (yyval.u.expr) = new CPPExpression(CPPExpression::typeid_op((yyvsp[-1].u.type), std_type_info)); } -#line 9090 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 9116 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 690: -#line 3876 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3900 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { CPPIdentifier ident(""); ident.add_name("std"); @@ -9103,409 +9127,409 @@ yyreduce: } (yyval.u.expr) = new CPPExpression(CPPExpression::typeid_op((yyvsp[-1].u.expr), std_type_info)); } -#line 9105 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 9131 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 691: -#line 3887 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3911 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression(UNARY_NOT, (yyvsp[0].u.expr)); } -#line 9113 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 9139 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 692: -#line 3891 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3915 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression(UNARY_NEGATE, (yyvsp[0].u.expr)); } -#line 9121 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 9147 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 693: -#line 3895 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3919 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression(UNARY_MINUS, (yyvsp[0].u.expr)); } -#line 9129 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 9155 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 694: -#line 3899 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3923 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression(UNARY_PLUS, (yyvsp[0].u.expr)); } -#line 9137 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 9163 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 695: -#line 3903 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3927 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression(UNARY_REF, (yyvsp[0].u.expr)); } -#line 9145 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 9171 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 696: -#line 3907 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3931 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression('*', (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 9153 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 9179 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 697: -#line 3911 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3935 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression('/', (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 9161 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 9187 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 698: -#line 3915 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3939 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression('%', (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 9169 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 9195 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 699: -#line 3919 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3943 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression('+', (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 9177 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 9203 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 700: -#line 3923 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3947 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression('-', (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 9185 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 9211 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 701: -#line 3927 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3951 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression('|', (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 9193 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 9219 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 702: -#line 3931 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3955 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression('^', (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 9201 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 9227 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 703: -#line 3935 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3959 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression('&', (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 9209 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 9235 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 704: -#line 3939 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3963 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression(OROR, (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 9217 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 9243 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 705: -#line 3943 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3967 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression(ANDAND, (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 9225 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 9251 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 706: -#line 3947 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3971 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression(EQCOMPARE, (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 9233 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 9259 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 707: -#line 3951 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3975 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression(NECOMPARE, (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 9241 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 9267 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 708: -#line 3955 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3979 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression(LECOMPARE, (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 9249 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 9275 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 709: -#line 3959 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3983 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression(GECOMPARE, (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 9257 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 9283 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 710: -#line 3963 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3987 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression('<', (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 9265 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 9291 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 711: -#line 3967 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3991 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression('>', (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 9273 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 9299 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 712: -#line 3971 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3995 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression(LSHIFT, (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 9281 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 9307 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 713: -#line 3975 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 3999 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression(RSHIFT, (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 9289 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 9315 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 714: -#line 3979 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 4003 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression('?', (yyvsp[-4].u.expr), (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 9297 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 9323 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 715: -#line 3983 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 4007 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression('[', (yyvsp[-3].u.expr), (yyvsp[-1].u.expr)); } -#line 9305 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 9331 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 716: -#line 3987 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 4011 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression('f', (yyvsp[-3].u.expr), (yyvsp[-1].u.expr)); } -#line 9313 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 9339 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 717: -#line 3991 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 4015 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression('f', (yyvsp[-2].u.expr)); } -#line 9321 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 9347 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 718: -#line 3995 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 4019 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression('.', (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 9329 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 9355 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 719: -#line 3999 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 4023 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression(POINTSAT, (yyvsp[-2].u.expr), (yyvsp[0].u.expr)); } -#line 9337 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 9363 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 720: -#line 4003 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 4027 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = (yyvsp[-1].u.expr); } -#line 9345 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 9371 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 721: -#line 4010 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 4034 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression((yyvsp[0].u.integer)); } -#line 9353 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 9379 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 722: -#line 4014 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 4038 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression(true); } -#line 9361 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 9387 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 723: -#line 4018 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 4042 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression(false); } -#line 9369 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 9395 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 724: -#line 4022 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 4046 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression((yyvsp[0].u.integer)); } -#line 9377 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 9403 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 725: -#line 4026 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 4050 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression((yyvsp[0].u.real)); } -#line 9385 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 9411 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 726: -#line 4030 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 4054 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = (yyvsp[0].u.expr); } -#line 9393 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 9419 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 727: -#line 4034 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 4058 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = (yyvsp[0].u.expr); } -#line 9401 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 9427 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 728: -#line 4038 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 4062 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression((yyvsp[0].u.identifier), current_scope, global_scope, current_lexer); } -#line 9409 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 9435 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 729: -#line 4042 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 4066 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { // A variable named "final". C++11 explicitly permits this. CPPIdentifier *ident = new CPPIdentifier("final", (yylsp[0])); (yyval.u.expr) = new CPPExpression(ident, current_scope, global_scope, current_lexer); } -#line 9419 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 9445 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 730: -#line 4048 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 4072 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { // A variable named "override". C++11 explicitly permits this. CPPIdentifier *ident = new CPPIdentifier("override", (yylsp[0])); (yyval.u.expr) = new CPPExpression(ident, current_scope, global_scope, current_lexer); } -#line 9429 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 9455 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 731: -#line 4054 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 4078 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression(CPPExpression::get_nullptr()); } -#line 9437 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 9463 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 732: -#line 4062 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 4086 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.closure_type) = new CPPClosureType(); } -#line 9445 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 9471 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 733: -#line 4066 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 4090 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.closure_type) = new CPPClosureType(CPPClosureType::CT_by_value); } -#line 9453 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 9479 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 734: -#line 4070 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 4094 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.closure_type) = new CPPClosureType(CPPClosureType::CT_by_reference); } -#line 9461 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 9487 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 735: -#line 4074 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 4098 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.closure_type) = new CPPClosureType(); (yyvsp[-1].u.capture)->_initializer = (yyvsp[0].u.expr); (yyval.u.closure_type)->_captures.push_back(*(yyvsp[-1].u.capture)); delete (yyvsp[-1].u.capture); } -#line 9472 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 9498 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 736: -#line 4081 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 4105 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.closure_type) = (yyvsp[-3].u.closure_type); (yyvsp[-1].u.capture)->_initializer = (yyvsp[0].u.expr); (yyval.u.closure_type)->_captures.push_back(*(yyvsp[-1].u.capture)); delete (yyvsp[-1].u.capture); } -#line 9483 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 9509 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 737: -#line 4091 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 4115 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.capture) = new CPPClosureType::Capture; (yyval.u.capture)->_name = (yyvsp[0].u.identifier)->get_simple_name(); (yyval.u.capture)->_type = CPPClosureType::CT_by_reference; } -#line 9493 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 9519 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 738: -#line 4097 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 4121 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.capture) = new CPPClosureType::Capture; (yyval.u.capture)->_name = (yyvsp[-1].u.identifier)->get_simple_name(); (yyval.u.capture)->_type = CPPClosureType::CT_by_reference; } -#line 9503 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 9529 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 739: -#line 4103 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 4127 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.capture) = new CPPClosureType::Capture; (yyval.u.capture)->_name = (yyvsp[0].u.identifier)->get_simple_name(); @@ -9515,11 +9539,11 @@ yyreduce: (yyval.u.capture)->_type = CPPClosureType::CT_by_value; } } -#line 9517 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 9543 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 740: -#line 4113 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 4137 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.capture) = new CPPClosureType::Capture; (yyval.u.capture)->_name = (yyvsp[0].u.identifier)->get_simple_name(); @@ -9528,189 +9552,189 @@ yyreduce: yywarning("only capture name 'this' may be preceded by an asterisk", (yylsp[0])); } } -#line 9530 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 9556 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 741: -#line 4125 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 4149 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { CPPType *type = (yyvsp[0].u.identifier)->find_type(current_scope, global_scope, true); - if (type == NULL) { + if (type == nullptr) { type = CPPType::new_type(new CPPTBDType((yyvsp[0].u.identifier))); } (yyval.u.type) = type; } -#line 9542 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 9568 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 742: -#line 4133 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 4157 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.type) = CPPType::new_type(new CPPTBDType((yyvsp[0].u.identifier))); } -#line 9550 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 9576 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 743: -#line 4137 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 4161 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { CPPClassTemplateParameter *ctp = new CPPClassTemplateParameter((yyvsp[-1].u.identifier)); ctp->_packed = true; (yyval.u.type) = CPPType::new_type(ctp); } -#line 9560 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 9586 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 744: -#line 4167 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 4191 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.identifier) = (yyvsp[0].u.identifier); } -#line 9568 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 9594 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 745: -#line 4171 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 4195 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.identifier) = (yyvsp[0].u.identifier); } -#line 9576 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 9602 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 746: -#line 4175 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 4199 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.identifier) = (yyvsp[0].u.identifier); } -#line 9584 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 9610 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 747: -#line 4179 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 4203 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.identifier) = new CPPIdentifier("final", (yylsp[0])); } -#line 9592 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 9618 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 748: -#line 4183 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 4207 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.identifier) = new CPPIdentifier("override", (yylsp[0])); } -#line 9600 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 9626 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 749: -#line 4187 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 4211 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { // This is not a keyword in Python, so it is useful to be able to use this // in MAKE_PROPERTY definitions, etc. (yyval.u.identifier) = new CPPIdentifier("signed", (yylsp[0])); } -#line 9610 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 9636 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 750: -#line 4193 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 4217 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.identifier) = new CPPIdentifier("float", (yylsp[0])); } -#line 9618 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 9644 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 751: -#line 4197 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 4221 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.identifier) = new CPPIdentifier("public", (yylsp[0])); } -#line 9626 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 9652 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 752: -#line 4201 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 4225 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.identifier) = new CPPIdentifier("private", (yylsp[0])); } -#line 9634 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 9660 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 753: -#line 4205 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 4229 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.identifier) = new CPPIdentifier("static", (yylsp[0])); } -#line 9642 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 9668 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 754: -#line 4209 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 4233 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.identifier) = new CPPIdentifier("default", (yylsp[0])); } -#line 9650 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 9676 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 755: -#line 4220 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 4244 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.identifier) = (yyvsp[0].u.identifier); } -#line 9658 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 9684 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 756: -#line 4224 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 4248 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.identifier) = (yyvsp[0].u.identifier); } -#line 9666 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 9692 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 757: -#line 4228 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 4252 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.identifier) = (yyvsp[0].u.identifier); } -#line 9674 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 9700 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 758: -#line 4232 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 4256 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.identifier) = new CPPIdentifier("override", (yylsp[0])); } -#line 9682 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 9708 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 759: -#line 4240 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 4264 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = new CPPExpression((yyvsp[0].str)); } -#line 9690 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 9716 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 760: -#line 4244 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 4268 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { (yyval.u.expr) = (yyvsp[0].u.expr); } -#line 9698 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 9724 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 761: -#line 4248 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 4272 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { // The right string takes on the literal type of the left. (yyval.u.expr) = (yyvsp[-1].u.expr); (yyval.u.expr)->_str += (yyvsp[0].str); } -#line 9708 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 9734 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; case 762: -#line 4254 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1646 */ +#line 4278 "dtool/src/cppparser/cppBison.yxx" /* yacc.c:1648 */ { // We have to check that the two literal types match up. (yyval.u.expr) = (yyvsp[-1].u.expr); @@ -9719,11 +9743,11 @@ yyreduce: } (yyval.u.expr)->_str += (yyvsp[0].u.expr)->_str; } -#line 9721 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 9747 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ break; -#line 9725 "built/tmp/cppBison.yxx.c" /* yacc.c:1646 */ +#line 9751 "built/tmp/cppBison.yxx.c" /* yacc.c:1648 */ default: break; } /* User semantic actions sometimes alter yychar, and that requires @@ -9846,7 +9870,6 @@ yyerrorlab: if (/*CONSTCOND*/ 0) goto yyerrorlab; - yyerror_range[1] = yylsp[1-yylen]; /* Do not reclaim the symbols of the rule whose action triggered this YYERROR. */ YYPOPSTACK (yylen); diff --git a/dtool/src/cppparser/cppBison.h.prebuilt b/dtool/src/cppparser/cppBison.h.prebuilt index a2ec1fca8c..c33ce691eb 100644 --- a/dtool/src/cppparser/cppBison.h.prebuilt +++ b/dtool/src/cppparser/cppBison.h.prebuilt @@ -1,8 +1,8 @@ -/* A Bison parser, made by GNU Bison 3.0.4. */ +/* A Bison parser, made by GNU Bison 3.0.5. */ /* Bison interface for Yacc-like parsers in C - Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc. + Copyright (C) 1984, 1989-1990, 2000-2015, 2018 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/dtool/src/cppparser/cppBison.yxx b/dtool/src/cppparser/cppBison.yxx index 5c2721eea7..5a82fa5d9f 100644 --- a/dtool/src/cppparser/cppBison.yxx +++ b/dtool/src/cppparser/cppBison.yxx @@ -1185,14 +1185,27 @@ constructor_prototype: /* Functions with implicit return types, and constructors */ IDENTIFIER '(' { - push_scope($1->get_scope(current_scope, global_scope)); + // Create a scope for this function. + CPPScope *scope = new CPPScope($1->get_scope(current_scope, global_scope), + $1->_names.back(), V_private); + + // It still needs to be able to pick up any template arguments, if this is + // a definition for a method template. Add a fake "using" declaration to + // accomplish this. + scope->_using.insert(current_scope); + + push_scope(scope); } function_parameter_list ')' function_post { + CPPScope *scope = $1->get_scope(current_scope, global_scope); CPPType *type; - if ($1->get_simple_name() == current_scope->get_simple_name() || - $1->get_simple_name() == string("~") + current_scope->get_simple_name()) { - // This is a constructor, and has no return. + std::string simple_name = $1->get_simple_name(); + if (!simple_name.empty() && simple_name[0] == '~') { + // A destructor has no return type. + type = new CPPSimpleType(CPPSimpleType::T_void); + } else if (scope != nullptr && simple_name == scope->get_simple_name()) { + // Neither does a constructor. type = new CPPSimpleType(CPPSimpleType::T_void); } else { // This isn't a constructor, so it has an implicit return type of @@ -1209,7 +1222,16 @@ constructor_prototype: } | TYPENAME_IDENTIFIER '(' { - push_scope($1->get_scope(current_scope, global_scope)); + // Create a scope for this function. + CPPScope *scope = new CPPScope($1->get_scope(current_scope, global_scope), + $1->_names.back(), V_private); + + // It still needs to be able to pick up any template arguments, if this is + // a definition for a method template. Add a fake "using" declaration to + // accomplish this. + scope->_using.insert(current_scope); + + push_scope(scope); } function_parameter_list ')' function_post { From 0cd69c8748340a4bdeeb63d7852244a01d2552eb Mon Sep 17 00:00:00 2001 From: rdb Date: Tue, 31 Jul 2018 14:56:04 +0200 Subject: [PATCH 073/125] gobj: fix TexturePool ambiguity when loading tex with other settings Previously, if you called load_texture a second time with different parameters (such as an alpha filename), you would still get the old texture. --- panda/src/gobj/texturePool.I | 20 +++ panda/src/gobj/texturePool.cxx | 239 ++++++++++++++++++--------------- panda/src/gobj/texturePool.h | 13 +- 3 files changed, 160 insertions(+), 112 deletions(-) diff --git a/panda/src/gobj/texturePool.I b/panda/src/gobj/texturePool.I index 6ff48f14d3..1c25485f51 100644 --- a/panda/src/gobj/texturePool.I +++ b/panda/src/gobj/texturePool.I @@ -275,3 +275,23 @@ PT(Texture) TexturePool:: make_texture(const std::string &extension) { return get_global_ptr()->ns_make_texture(extension); } + +/** + * Defines relative ordering between LookupKey instances. + */ +INLINE bool TexturePool::LookupKey:: +operator < (const LookupKey &other) const { + if (_fullpath != other._fullpath) { + return _fullpath < other._fullpath; + } + if (_alpha_fullpath != other._alpha_fullpath) { + return _alpha_fullpath < other._alpha_fullpath; + } + if (_primary_file_num_channels != other._primary_file_num_channels) { + return _primary_file_num_channels < other._primary_file_num_channels; + } + if (_alpha_file_channel != other._alpha_file_channel) { + return _alpha_file_channel < other._alpha_file_channel; + } + return _texture_type < other._texture_type; +} diff --git a/panda/src/gobj/texturePool.cxx b/panda/src/gobj/texturePool.cxx index d62b68b377..c09df1d9e3 100644 --- a/panda/src/gobj/texturePool.cxx +++ b/panda/src/gobj/texturePool.cxx @@ -177,16 +177,23 @@ bool TexturePool:: ns_has_texture(const Filename &orig_filename) { MutexHolder holder(_lock); - Filename filename; - resolve_filename(filename, orig_filename, false, LoaderOptions()); + LookupKey key; + resolve_filename(key._fullpath, orig_filename, false, LoaderOptions()); Textures::const_iterator ti; - ti = _textures.find(filename); + ti = _textures.find(key); if (ti != _textures.end()) { // This texture was previously loaded. return true; } + // It might still have been loaded with non-standard settings. + for (ti = _textures.begin(); ti != _textures.end(); ++ti) { + if (ti->first._fullpath == key._fullpath) { + return true; + } + } + return false; } @@ -196,13 +203,14 @@ ns_has_texture(const Filename &orig_filename) { Texture *TexturePool:: ns_load_texture(const Filename &orig_filename, int primary_file_num_channels, bool read_mipmaps, const LoaderOptions &options) { - Filename filename; - + LookupKey key; + key._primary_file_num_channels = primary_file_num_channels; { MutexHolder holder(_lock); - resolve_filename(filename, orig_filename, read_mipmaps, options); + resolve_filename(key._fullpath, orig_filename, read_mipmaps, options); + Textures::const_iterator ti; - ti = _textures.find(filename); + ti = _textures.find(key); if (ti != _textures.end()) { // This texture was previously loaded. Texture *tex = (*ti).second; @@ -222,54 +230,54 @@ ns_load_texture(const Filename &orig_filename, int primary_file_num_channels, BamCache *cache = BamCache::get_global_ptr(); bool compressed_cache_record = false; - try_load_cache(tex, cache, filename, record, compressed_cache_record, + try_load_cache(tex, cache, key._fullpath, record, compressed_cache_record, options); if (tex == nullptr) { // The texture was neither in the pool, nor found in the on-disk cache; it // needs to be loaded from its source image(s). gobj_cat.info() - << "Loading texture " << filename << "\n"; + << "Loading texture " << key._fullpath << "\n"; - string ext = downcase(filename.get_extension()); + string ext = downcase(key._fullpath.get_extension()); if (ext == "txo" || ext == "bam") { // Assume this is a txo file, which might conceivably contain a movie // file or some other subclass of Texture. In that case, use // make_from_txo() to load it instead of read(). VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr(); - filename.set_binary(); - PT(VirtualFile) file = vfs->get_file(filename); + key._fullpath.set_binary(); + PT(VirtualFile) file = vfs->get_file(key._fullpath); if (file == nullptr) { // No such file. gobj_cat.error() - << "Could not find " << filename << "\n"; + << "Could not find " << key._fullpath << "\n"; return nullptr; } if (gobj_cat.is_debug()) { gobj_cat.debug() - << "Reading texture object " << filename << "\n"; + << "Reading texture object " << key._fullpath << "\n"; } istream *in = file->open_read_file(true); - tex = Texture::make_from_txo(*in, filename); + tex = Texture::make_from_txo(*in, key._fullpath); vfs->close_read_file(in); if (tex == nullptr) { return nullptr; } - tex->set_fullpath(filename); + tex->set_fullpath(key._fullpath); tex->clear_alpha_fullpath(); tex->set_keep_ram_image(false); } else { // Read it the conventional way. tex = ns_make_texture(ext); - if (!tex->read(filename, Filename(), primary_file_num_channels, 0, + if (!tex->read(key._fullpath, Filename(), primary_file_num_channels, 0, 0, 0, false, read_mipmaps, record, options)) { // This texture was not found or could not be read. - report_texture_unreadable(filename); + report_texture_unreadable(key._fullpath); return nullptr; } } @@ -304,8 +312,8 @@ ns_load_texture(const Filename &orig_filename, int primary_file_num_channels, // Set the original filename, before we searched along the path. nassertr(tex != nullptr, nullptr); tex->set_filename(orig_filename); - tex->set_fullpath(filename); - tex->_texture_pool_key = filename; + tex->set_fullpath(key._fullpath); + tex->_texture_pool_key = key._fullpath; { MutexHolder holder(_lock); @@ -313,7 +321,7 @@ ns_load_texture(const Filename &orig_filename, int primary_file_num_channels, // Now look again--someone may have just loaded this texture in another // thread. Textures::const_iterator ti; - ti = _textures.find(filename); + ti = _textures.find(key); if (ti != _textures.end()) { // This texture was previously loaded. Texture *tex = (*ti).second; @@ -321,7 +329,7 @@ ns_load_texture(const Filename &orig_filename, int primary_file_num_channels, return tex; } - _textures[filename] = tex; + _textures[std::move(key)] = tex; } if (store_record && tex->is_cacheable()) { @@ -357,16 +365,16 @@ ns_load_texture(const Filename &orig_filename, read_mipmaps, options); } - Filename filename; - Filename alpha_filename; - + LookupKey key; + key._primary_file_num_channels = primary_file_num_channels; + key._alpha_file_channel = alpha_file_channel; { MutexHolder holder(_lock); - resolve_filename(filename, orig_filename, read_mipmaps, options); - resolve_filename(alpha_filename, orig_alpha_filename, read_mipmaps, options); + resolve_filename(key._fullpath, orig_filename, read_mipmaps, options); + resolve_filename(key._alpha_fullpath, orig_alpha_filename, read_mipmaps, options); Textures::const_iterator ti; - ti = _textures.find(filename); + ti = _textures.find(key); if (ti != _textures.end()) { // This texture was previously loaded. Texture *tex = (*ti).second; @@ -380,26 +388,26 @@ ns_load_texture(const Filename &orig_filename, bool store_record = false; // Can one of our texture filters supply the texture? - tex = pre_load(orig_filename, alpha_filename, primary_file_num_channels, + tex = pre_load(orig_filename, orig_alpha_filename, primary_file_num_channels, alpha_file_channel, read_mipmaps, options); BamCache *cache = BamCache::get_global_ptr(); bool compressed_cache_record = false; - try_load_cache(tex, cache, filename, record, compressed_cache_record, + try_load_cache(tex, cache, key._fullpath, record, compressed_cache_record, options); if (tex == nullptr) { // The texture was neither in the pool, nor found in the on-disk cache; it // needs to be loaded from its source image(s). gobj_cat.info() - << "Loading texture " << filename << " and alpha component " - << alpha_filename << std::endl; - tex = ns_make_texture(filename.get_extension()); - if (!tex->read(filename, alpha_filename, primary_file_num_channels, + << "Loading texture " << key._fullpath << " and alpha component " + << key._alpha_fullpath << std::endl; + tex = ns_make_texture(key._fullpath.get_extension()); + if (!tex->read(key._fullpath, key._alpha_fullpath, primary_file_num_channels, alpha_file_channel, 0, 0, false, read_mipmaps, nullptr, options)) { // This texture was not found or could not be read. - report_texture_unreadable(filename); + report_texture_unreadable(key._fullpath); return nullptr; } @@ -433,17 +441,17 @@ ns_load_texture(const Filename &orig_filename, // Set the original filenames, before we searched along the path. nassertr(tex != nullptr, nullptr); tex->set_filename(orig_filename); - tex->set_fullpath(filename); + tex->set_fullpath(key._fullpath); tex->set_alpha_filename(orig_alpha_filename); - tex->set_alpha_fullpath(alpha_filename); - tex->_texture_pool_key = filename; + tex->set_alpha_fullpath(key._alpha_fullpath); + tex->_texture_pool_key = key._fullpath; { MutexHolder holder(_lock); // Now look again. Textures::const_iterator ti; - ti = _textures.find(filename); + ti = _textures.find(key); if (ti != _textures.end()) { // This texture was previously loaded. Texture *tex = (*ti).second; @@ -451,7 +459,7 @@ ns_load_texture(const Filename &orig_filename, return tex; } - _textures[filename] = tex; + _textures[std::move(key)] = tex; } if (store_record && tex->is_cacheable()) { @@ -482,18 +490,19 @@ ns_load_3d_texture(const Filename &filename_pattern, Filename orig_filename(filename_pattern); orig_filename.set_pattern(true); - Filename filename; + LookupKey key; + key._texture_type = Texture::TT_3d_texture; { MutexHolder holder(_lock); - resolve_filename(filename, orig_filename, read_mipmaps, options); + resolve_filename(key._fullpath, orig_filename, read_mipmaps, options); Textures::const_iterator ti; - ti = _textures.find(filename); + ti = _textures.find(key); if (ti != _textures.end()) { - if ((*ti).second->get_texture_type() == Texture::TT_3d_texture) { - // This texture was previously loaded, as a 3d texture - return (*ti).second; - } + // This texture was previously loaded. + Texture *tex = (*ti).second; + nassertr(!tex->get_fullpath().empty(), tex); + return tex; } } @@ -503,7 +512,7 @@ ns_load_3d_texture(const Filename &filename_pattern, BamCache *cache = BamCache::get_global_ptr(); bool compressed_cache_record = false; - try_load_cache(tex, cache, filename, record, compressed_cache_record, + try_load_cache(tex, cache, key._fullpath, record, compressed_cache_record, options); if (tex == nullptr || @@ -511,12 +520,12 @@ ns_load_3d_texture(const Filename &filename_pattern, // The texture was neither in the pool, nor found in the on-disk cache; it // needs to be loaded from its source image(s). gobj_cat.info() - << "Loading 3-d texture " << filename << "\n"; - tex = ns_make_texture(filename.get_extension()); + << "Loading 3-d texture " << key._fullpath << "\n"; + tex = ns_make_texture(key._fullpath.get_extension()); tex->setup_3d_texture(); - if (!tex->read(filename, 0, 0, true, read_mipmaps, options)) { + if (!tex->read(key._fullpath, 0, 0, true, read_mipmaps, options)) { // This texture was not found or could not be read. - report_texture_unreadable(filename); + report_texture_unreadable(key._fullpath); return nullptr; } store_record = (record != nullptr); @@ -545,23 +554,23 @@ ns_load_3d_texture(const Filename &filename_pattern, // Set the original filename, before we searched along the path. nassertr(tex != nullptr, nullptr); tex->set_filename(filename_pattern); - tex->set_fullpath(filename); - tex->_texture_pool_key = filename; + tex->set_fullpath(key._fullpath); + tex->_texture_pool_key = key._fullpath; { MutexHolder holder(_lock); // Now look again. Textures::const_iterator ti; - ti = _textures.find(filename); + ti = _textures.find(key); if (ti != _textures.end()) { - if ((*ti).second->get_texture_type() == Texture::TT_3d_texture) { - // This texture was previously loaded, as a 3d texture - return (*ti).second; - } + // This texture was previously loaded. + Texture *tex = (*ti).second; + nassertr(!tex->get_fullpath().empty(), tex); + return tex; } - _textures[filename] = tex; + _textures[std::move(key)] = tex; } if (store_record && tex->is_cacheable()) { @@ -583,21 +592,19 @@ ns_load_2d_texture_array(const Filename &filename_pattern, Filename orig_filename(filename_pattern); orig_filename.set_pattern(true); - Filename filename; - Filename unique_filename; //differentiate 3d-textures from 2d-texture arrays + LookupKey key; + key._texture_type = Texture::TT_2d_texture_array; { MutexHolder holder(_lock); - resolve_filename(filename, orig_filename, read_mipmaps, options); - // Differentiate from preloaded 3d textures - unique_filename = filename + ".2DARRAY"; + resolve_filename(key._fullpath, orig_filename, read_mipmaps, options); Textures::const_iterator ti; - ti = _textures.find(unique_filename); + ti = _textures.find(key); if (ti != _textures.end()) { - if ((*ti).second->get_texture_type() == Texture::TT_2d_texture_array) { - // This texture was previously loaded, as a 2d texture array - return (*ti).second; - } + // This texture was previously loaded. + Texture *tex = (*ti).second; + nassertr(!tex->get_fullpath().empty(), tex); + return tex; } } @@ -607,7 +614,7 @@ ns_load_2d_texture_array(const Filename &filename_pattern, BamCache *cache = BamCache::get_global_ptr(); bool compressed_cache_record = false; - try_load_cache(tex, cache, filename, record, compressed_cache_record, + try_load_cache(tex, cache, key._fullpath, record, compressed_cache_record, options); if (tex == nullptr || @@ -615,12 +622,12 @@ ns_load_2d_texture_array(const Filename &filename_pattern, // The texture was neither in the pool, nor found in the on-disk cache; it // needs to be loaded from its source image(s). gobj_cat.info() - << "Loading 2-d texture array " << filename << "\n"; - tex = ns_make_texture(filename.get_extension()); + << "Loading 2-d texture array " << key._fullpath << "\n"; + tex = ns_make_texture(key._fullpath.get_extension()); tex->setup_2d_texture_array(); - if (!tex->read(filename, 0, 0, true, read_mipmaps, options)) { + if (!tex->read(key._fullpath, 0, 0, true, read_mipmaps, options)) { // This texture was not found or could not be read. - report_texture_unreadable(filename); + report_texture_unreadable(key._fullpath); return nullptr; } store_record = (record != nullptr); @@ -649,23 +656,23 @@ ns_load_2d_texture_array(const Filename &filename_pattern, // Set the original filename, before we searched along the path. nassertr(tex != nullptr, nullptr); tex->set_filename(filename_pattern); - tex->set_fullpath(filename); - tex->_texture_pool_key = unique_filename; + tex->set_fullpath(key._fullpath); + tex->_texture_pool_key = key._fullpath; { MutexHolder holder(_lock); // Now look again. Textures::const_iterator ti; - ti = _textures.find(unique_filename); + ti = _textures.find(key); if (ti != _textures.end()) { - if ((*ti).second->get_texture_type() == Texture::TT_2d_texture_array) { - // This texture was previously loaded, as a 2d texture array - return (*ti).second; - } + // This texture was previously loaded. + Texture *tex = (*ti).second; + nassertr(!tex->get_fullpath().empty(), tex); + return tex; } - _textures[unique_filename] = tex; + _textures[std::move(key)] = tex; } if (store_record && tex->is_cacheable()) { @@ -687,16 +694,19 @@ ns_load_cube_map(const Filename &filename_pattern, bool read_mipmaps, Filename orig_filename(filename_pattern); orig_filename.set_pattern(true); - Filename filename; + LookupKey key; + key._texture_type = Texture::TT_cube_map; { MutexHolder holder(_lock); - resolve_filename(filename, orig_filename, read_mipmaps, options); + resolve_filename(key._fullpath, orig_filename, read_mipmaps, options); Textures::const_iterator ti; - ti = _textures.find(filename); + ti = _textures.find(key); if (ti != _textures.end()) { // This texture was previously loaded. - return (*ti).second; + Texture *tex = (*ti).second; + nassertr(!tex->get_fullpath().empty(), tex); + return tex; } } @@ -706,7 +716,7 @@ ns_load_cube_map(const Filename &filename_pattern, bool read_mipmaps, BamCache *cache = BamCache::get_global_ptr(); bool compressed_cache_record = false; - try_load_cache(tex, cache, filename, record, compressed_cache_record, + try_load_cache(tex, cache, key._fullpath, record, compressed_cache_record, options); if (tex == nullptr || @@ -714,12 +724,12 @@ ns_load_cube_map(const Filename &filename_pattern, bool read_mipmaps, // The texture was neither in the pool, nor found in the on-disk cache; it // needs to be loaded from its source image(s). gobj_cat.info() - << "Loading cube map texture " << filename << "\n"; - tex = ns_make_texture(filename.get_extension()); + << "Loading cube map texture " << key._fullpath << "\n"; + tex = ns_make_texture(key._fullpath.get_extension()); tex->setup_cube_map(); - if (!tex->read(filename, 0, 0, true, read_mipmaps, options)) { + if (!tex->read(key._fullpath, 0, 0, true, read_mipmaps, options)) { // This texture was not found or could not be read. - report_texture_unreadable(filename); + report_texture_unreadable(key._fullpath); return nullptr; } store_record = (record != nullptr); @@ -748,21 +758,23 @@ ns_load_cube_map(const Filename &filename_pattern, bool read_mipmaps, // Set the original filename, before we searched along the path. nassertr(tex != nullptr, nullptr); tex->set_filename(filename_pattern); - tex->set_fullpath(filename); - tex->_texture_pool_key = filename; + tex->set_fullpath(key._fullpath); + tex->_texture_pool_key = key._fullpath; { MutexHolder holder(_lock); // Now look again. Textures::const_iterator ti; - ti = _textures.find(filename); + ti = _textures.find(key); if (ti != _textures.end()) { // This texture was previously loaded. - return (*ti).second; + Texture *tex = (*ti).second; + nassertr(!tex->get_fullpath().empty(), tex); + return tex; } - _textures[filename] = tex; + _textures[std::move(key)] = tex; } if (store_record && tex->is_cacheable()) { @@ -819,15 +831,22 @@ ns_add_texture(Texture *tex) { if (!tex->_texture_pool_key.empty()) { ns_release_texture(tex); } - string filename = tex->get_fullpath(); - if (filename.empty()) { + + Texture::CDReader tex_cdata(tex->_cycler); + if (tex_cdata->_fullpath.empty()) { gobj_cat.error() << "Attempt to call add_texture() on an unnamed texture.\n"; + return; } + LookupKey key; + key._fullpath = tex_cdata->_fullpath; + key._alpha_fullpath = tex_cdata->_alpha_fullpath; + key._alpha_file_channel = tex_cdata->_alpha_file_channel; + key._texture_type = tex_cdata->_texture_type; + // We blow away whatever texture was there previously, if any. - tex->_texture_pool_key = filename; - _textures[filename] = tex; - nassertv(!tex->get_fullpath().empty()); + tex->_texture_pool_key = key._fullpath; + _textures[key] = tex; } /** @@ -837,13 +856,13 @@ void TexturePool:: ns_release_texture(Texture *tex) { MutexHolder holder(_lock); - if (!tex->_texture_pool_key.empty()) { - Textures::iterator ti; - ti = _textures.find(tex->_texture_pool_key); - if (ti != _textures.end() && (*ti).second == tex) { + Textures::iterator ti; + for (ti = _textures.begin(); ti != _textures.end(); ++ti) { + if (tex == (*ti).second) { _textures.erase(ti); + tex->_texture_pool_key = string(); + break; } - tex->_texture_pool_key = string(); } // Blow away the cache of resolved relative filenames. @@ -886,7 +905,7 @@ ns_garbage_collect() { if (tex->get_ref_count() == 1) { if (gobj_cat.is_debug()) { gobj_cat.debug() - << "Releasing " << (*ti).first << "\n"; + << "Releasing " << (*ti).first._fullpath << "\n"; } ++num_released; tex->_texture_pool_key = string(); @@ -927,14 +946,14 @@ ns_list_contents(ostream &out) const { total_ram_size = 0; for (ti = _textures.begin(); ti != _textures.end(); ++ti) { Texture *tex = (*ti).second; - out << (*ti).first << "\n"; + out << (*ti).first._fullpath << "\n"; out << " (count = " << tex->get_ref_count() << ", ram = " << tex->get_ram_image_size() << ", size = " << tex->get_ram_page_size() << ", w = " << tex->get_x_size() << ", h = " << tex->get_y_size() << ")\n"; - nassertv(tex->_texture_pool_key == (*ti).first); + nassertv(tex->_texture_pool_key == (*ti).first._fullpath); total_ram_size += tex->get_ram_image_size(); total_size += tex->get_ram_page_size(); } diff --git a/panda/src/gobj/texturePool.h b/panda/src/gobj/texturePool.h index 866374ec96..de6812e4d5 100644 --- a/panda/src/gobj/texturePool.h +++ b/panda/src/gobj/texturePool.h @@ -149,8 +149,17 @@ private: static TexturePool *_global_ptr; Mutex _lock; - typedef pmap Textures; - Textures _textures; // indexed by fullpath + struct LookupKey { + Filename _fullpath; + Filename _alpha_fullpath; + int _primary_file_num_channels = 0; + int _alpha_file_channel = 0; + Texture::TextureType _texture_type = Texture::TT_2d_texture; + + INLINE bool operator < (const LookupKey &other) const; + }; + typedef pmap Textures; + Textures _textures; typedef pmap RelpathLookup; RelpathLookup _relpath_lookup; From 4b8ff0573e8b912591d02062e1240c2726e09323 Mon Sep 17 00:00:00 2001 From: rdb Date: Tue, 31 Jul 2018 14:57:55 +0200 Subject: [PATCH 074/125] tests: add TexturePool unit tests --- tests/gobj/test_texture_pool.py | 196 ++++++++++++++++++++++++++++++++ 1 file changed, 196 insertions(+) create mode 100644 tests/gobj/test_texture_pool.py diff --git a/tests/gobj/test_texture_pool.py b/tests/gobj/test_texture_pool.py new file mode 100644 index 0000000000..b07e8a0cb9 --- /dev/null +++ b/tests/gobj/test_texture_pool.py @@ -0,0 +1,196 @@ +from panda3d import core +import pytest +import tempfile + +@pytest.fixture(scope='function') +def pool(): + "This fixture ensures the pool is properly emptied" + pool = core.TexturePool + pool.release_all_textures() + yield pool + pool.release_all_textures() + + +def write_image(filename, channels): + img = core.PNMImage(1, 1, channels) + img.set_xel_a(0, 0, (0.0, 0.25, 0.5, 0.75)) + assert img.write(filename) + + +@pytest.fixture(scope='session') +def image_rgb_path(): + "Generates an RGB image." + + file = tempfile.NamedTemporaryFile(suffix='-rgb.png') + write_image(file.name, 3) + yield file.name + file.close() + + +@pytest.fixture(scope='session') +def image_rgba_path(): + "Generates an RGBA image." + + file = tempfile.NamedTemporaryFile(suffix='-rgba.png') + write_image(file.name, 4) + yield file.name + file.close() + + +@pytest.fixture(scope='session') +def image_gray_path(): + "Generates a grayscale image." + + file = tempfile.NamedTemporaryFile(suffix='-gray.png') + write_image(file.name, 1) + yield file.name + file.close() + + +def test_load_texture_rgba(pool, image_rgba_path): + tex = pool.load_texture(image_rgba_path) + assert pool.has_texture(image_rgba_path) + assert tex.num_components == 4 + + +def test_load_texture_rgba4(pool, image_rgba_path): + tex = pool.load_texture(image_rgba_path, 4) + assert pool.has_texture(image_rgba_path) + assert tex.num_components == 4 + + +def test_load_texture_rgba3(pool, image_rgba_path): + tex = pool.load_texture(image_rgba_path, 3) + assert pool.has_texture(image_rgba_path) + assert tex.num_components == 3 + + +def test_load_texture_rgba2(pool, image_rgba_path): + tex = pool.load_texture(image_rgba_path, 2) + assert pool.has_texture(image_rgba_path) + assert tex.num_components == 2 + + +def test_load_texture_rgba1(pool, image_rgba_path): + tex = pool.load_texture(image_rgba_path, 1) + assert pool.has_texture(image_rgba_path) + assert tex.num_components == 1 + + +def test_load_texture_rgb(pool, image_rgb_path): + tex = pool.load_texture(image_rgb_path) + assert pool.has_texture(image_rgb_path) + assert tex.num_components == 3 + + +def test_load_texture_rgb4(pool, image_rgb_path): + # Will not increase this + tex = pool.load_texture(image_rgb_path, 4) + assert pool.has_texture(image_rgb_path) + assert tex.num_components == 3 + + +def test_load_texture_rgb3(pool, image_rgb_path): + tex = pool.load_texture(image_rgb_path, 3) + assert pool.has_texture(image_rgb_path) + assert tex.num_components == 3 + + +def test_load_texture_rgb2(pool, image_rgb_path): + # Cannot reduce this, since it would add an alpha channel + tex = pool.load_texture(image_rgb_path, 2) + assert pool.has_texture(image_rgb_path) + assert tex.num_components == 3 + + +def test_load_texture_rgb1(pool, image_rgb_path): + tex = pool.load_texture(image_rgb_path, 1) + assert pool.has_texture(image_rgb_path) + assert tex.num_components == 1 + + +def test_load_texture_rgba_alpha(pool, image_rgba_path, image_gray_path): + tex = pool.load_texture(image_rgba_path, image_gray_path) + assert tex.num_components == 4 + + +def test_load_texture_rgba4_alpha(pool, image_rgba_path, image_gray_path): + tex = pool.load_texture(image_rgba_path, image_gray_path, 4) + assert tex.num_components == 4 + + +def test_load_texture_rgba3_alpha(pool, image_rgba_path, image_gray_path): + tex = pool.load_texture(image_rgba_path, image_gray_path, 3) + assert tex.num_components == 4 + + +def test_load_texture_rgba2_alpha(pool, image_rgba_path, image_gray_path): + #FIXME: why is this not consistent with test_load_texture_rgb2_alpha? + tex = pool.load_texture(image_rgba_path, image_gray_path, 2) + assert tex.num_components == 2 + + +def test_load_texture_rgba1_alpha(pool, image_rgba_path, image_gray_path): + tex = pool.load_texture(image_rgba_path, image_gray_path, 1) + assert tex.num_components == 2 + + +def test_load_texture_rgb_alpha(pool, image_rgb_path, image_gray_path): + tex = pool.load_texture(image_rgb_path, image_gray_path) + assert tex.num_components == 4 + + +def test_load_texture_rgb4_alpha(pool, image_rgb_path, image_gray_path): + tex = pool.load_texture(image_rgb_path, image_gray_path, 4) + assert tex.num_components == 4 + + +def test_load_texture_rgb3_alpha(pool, image_rgb_path, image_gray_path): + tex = pool.load_texture(image_rgb_path, image_gray_path, 3) + assert tex.num_components == 4 + + +def test_load_texture_rgb2_alpha(pool, image_rgb_path, image_gray_path): + #FIXME: why is this not consistent with test_load_texture_rgba2_alpha? + tex = pool.load_texture(image_rgb_path, image_gray_path, 2) + assert tex.num_components == 4 + + +def test_load_texture_rgb1_alpha(pool, image_rgb_path, image_gray_path): + tex = pool.load_texture(image_rgb_path, image_gray_path, 1) + assert tex.num_components == 2 + + +def test_reload_texture_fewer_channels(pool, image_rgba_path): + tex = pool.load_texture(image_rgba_path) + assert pool.has_texture(image_rgba_path) + assert tex.num_components == 4 + + tex = pool.load_texture(image_rgba_path, 3) + assert tex.num_components == 3 + + +def test_reload_texture_more_channels(pool, image_rgba_path): + tex = pool.load_texture(image_rgba_path, 3) + assert pool.has_texture(image_rgba_path) + assert tex.num_components == 3 + + tex = pool.load_texture(image_rgba_path) + assert tex.num_components == 4 + + +def test_reload_texture_with_alpha(pool, image_rgb_path, image_gray_path): + tex = pool.load_texture(image_rgb_path) + assert pool.has_texture(image_rgb_path) + assert tex.num_components == 3 + + tex = pool.load_texture(image_rgb_path, image_gray_path) + assert tex.num_components == 4 + + +def test_reload_texture_without_alpha(pool, image_rgb_path, image_gray_path): + tex = pool.load_texture(image_rgb_path, image_gray_path) + assert tex.num_components == 4 + + tex = pool.load_texture(image_rgb_path) + assert tex.num_components == 3 From 2b7ef93e2f2acad2762b2be31f72df7c7bd4dd33 Mon Sep 17 00:00:00 2001 From: rdb Date: Thu, 2 Aug 2018 20:28:07 +0200 Subject: [PATCH 075/125] travis: set skip_join to false The IRC channel had +n mode set to it due to spam problems, which disallows external send. --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 582c7fd62f..9de0326d78 100644 --- a/.travis.yml +++ b/.travis.yml @@ -51,4 +51,4 @@ notifications: on_success: change on_failure: always use_notice: true - skip_join: true + skip_join: false From f813d2fb60f13405e9973ac10552d41b2fdac757 Mon Sep 17 00:00:00 2001 From: rdb Date: Thu, 2 Aug 2018 20:29:48 +0200 Subject: [PATCH 076/125] stdpy: fix broken threading.Event --- direct/src/stdpy/threading.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/direct/src/stdpy/threading.py b/direct/src/stdpy/threading.py index 466a198a3a..45409f9e18 100644 --- a/direct/src/stdpy/threading.py +++ b/direct/src/stdpy/threading.py @@ -312,7 +312,7 @@ class Event: object. """ def __init__(self): - self.__lock = core.Lock("Python Event") + self.__lock = core.Mutex("Python Event") self.__cvar = core.ConditionVarFull(self.__lock) self.__flag = False @@ -325,7 +325,7 @@ class Event: self.__lock.acquire() try: self.__flag = True - self.__cvar.signalAll() + self.__cvar.notifyAll() finally: self.__lock.release() From 0fbfeb712fc3303ce235e77a9ee6b539cba35b36 Mon Sep 17 00:00:00 2001 From: rdb Date: Thu, 2 Aug 2018 20:30:54 +0200 Subject: [PATCH 077/125] ParticlePanel: comment out unimplemented OrientedParticleFactory --- direct/src/tkpanels/ParticlePanel.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/direct/src/tkpanels/ParticlePanel.py b/direct/src/tkpanels/ParticlePanel.py index 81d00aefc9..9c4ba56a79 100644 --- a/direct/src/tkpanels/ParticlePanel.py +++ b/direct/src/tkpanels/ParticlePanel.py @@ -263,7 +263,8 @@ class ParticlePanel(AppShell): 'Factory', 'Factory Type', 'Select type of particle factory', ('PointParticleFactory', 'ZSpinParticleFactory', - 'OrientedParticleFactory'), + #'OrientedParticleFactory' + ), self.selectFactoryType) factoryWidgets = ( ('Factory', 'Life Span', From 2a2b48134b8008417887d4f175f50e63dd4ba415 Mon Sep 17 00:00:00 2001 From: rdb Date: Thu, 2 Aug 2018 21:24:37 +0200 Subject: [PATCH 078/125] parser-inc: fix bad socklen_t definition in ws2tcpip.h --- dtool/src/parser-inc/ws2tcpip.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dtool/src/parser-inc/ws2tcpip.h b/dtool/src/parser-inc/ws2tcpip.h index 49262434c5..002bb035b5 100644 --- a/dtool/src/parser-inc/ws2tcpip.h +++ b/dtool/src/parser-inc/ws2tcpip.h @@ -1 +1 @@ -typedef DWORD socklen_t; +typedef int socklen_t; From c959d274be1cf3eee4320454a16e4c266a5a4f00 Mon Sep 17 00:00:00 2001 From: rdb Date: Fri, 3 Aug 2018 20:22:09 +0200 Subject: [PATCH 079/125] makewheel: add __version__ and docstring to panda3d/__init__.py --- makepanda/makewheel.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/makepanda/makewheel.py b/makepanda/makewheel.py index f727f10e73..e490f1c05e 100644 --- a/makepanda/makewheel.py +++ b/makepanda/makewheel.py @@ -488,7 +488,10 @@ def makewheel(version, output_dir, platform=default_platform): # Write the panda3d tree. We use a custom empty __init__ since the # default one adds the bin directory to the PATH, which we don't have. - whl.write_file_data('panda3d/__init__.py', '') + whl.write_file_data('panda3d/__init__.py', """"Python bindings for the Panda3D libraries" + +__version__ = '{0}' +""".format(version)) ext_suffix = GetExtensionSuffix() From 668a093c26f3b4f7873d65c224d38f1b751646e9 Mon Sep 17 00:00:00 2001 From: rdb Date: Fri, 3 Aug 2018 20:45:29 +0200 Subject: [PATCH 080/125] gobj: try to fix some deadlocks modifying geometry while rendering The correct locking order should be: the Geom's GeomVertexArrayData first, *then* the GeomPrimitive. --- panda/src/cull/cullBinBackToFront.cxx | 5 ++- panda/src/cull/cullBinFixed.cxx | 5 ++- panda/src/cull/cullBinFrontToBack.cxx | 5 ++- panda/src/cull/cullBinStateSorted.cxx | 5 ++- panda/src/cull/cullBinUnsorted.cxx | 8 ++-- panda/src/gobj/geom.cxx | 61 +++++++++++++++++++++------ panda/src/gobj/geomPrimitive.I | 14 ++++-- panda/src/gobj/geomPrimitive.h | 1 + 8 files changed, 76 insertions(+), 28 deletions(-) diff --git a/panda/src/cull/cullBinBackToFront.cxx b/panda/src/cull/cullBinBackToFront.cxx index 00c6ba7c32..c27c7e8ed4 100644 --- a/panda/src/cull/cullBinBackToFront.cxx +++ b/panda/src/cull/cullBinBackToFront.cxx @@ -96,9 +96,10 @@ draw(bool force, Thread *current_thread) { nassertd(object->_geom != nullptr) continue; _gsg->set_state_and_transform(object->_state, object->_internal_transform); - data_reader.set_object(object->_munged_data); + + GeomPipelineReader geom_reader(object->_geom, current_thread); + GeomVertexDataPipelineReader data_reader(object->_munged_data, current_thread); data_reader.check_array_readers(); - geom_reader.set_object(object->_geom); geom_reader.draw(_gsg, &data_reader, force); } else { // It has a callback associated. diff --git a/panda/src/cull/cullBinFixed.cxx b/panda/src/cull/cullBinFixed.cxx index 557b3435a3..3507ce4582 100644 --- a/panda/src/cull/cullBinFixed.cxx +++ b/panda/src/cull/cullBinFixed.cxx @@ -82,9 +82,10 @@ draw(bool force, Thread *current_thread) { nassertd(object->_geom != nullptr) continue; _gsg->set_state_and_transform(object->_state, object->_internal_transform); - data_reader.set_object(object->_munged_data); + + GeomPipelineReader geom_reader(object->_geom, current_thread); + GeomVertexDataPipelineReader data_reader(object->_munged_data, current_thread); data_reader.check_array_readers(); - geom_reader.set_object(object->_geom); geom_reader.draw(_gsg, &data_reader, force); } else { // It has a callback associated. diff --git a/panda/src/cull/cullBinFrontToBack.cxx b/panda/src/cull/cullBinFrontToBack.cxx index 4337b42d7c..5f5d99e51c 100644 --- a/panda/src/cull/cullBinFrontToBack.cxx +++ b/panda/src/cull/cullBinFrontToBack.cxx @@ -96,9 +96,10 @@ draw(bool force, Thread *current_thread) { nassertd(object->_geom != nullptr) continue; _gsg->set_state_and_transform(object->_state, object->_internal_transform); - data_reader.set_object(object->_munged_data); + + GeomPipelineReader geom_reader(object->_geom, current_thread); + GeomVertexDataPipelineReader data_reader(object->_munged_data, current_thread); data_reader.check_array_readers(); - geom_reader.set_object(object->_geom); geom_reader.draw(_gsg, &data_reader, force); } else { // It has a callback associated. diff --git a/panda/src/cull/cullBinStateSorted.cxx b/panda/src/cull/cullBinStateSorted.cxx index ad4d26cd12..3e2fca2e9a 100644 --- a/panda/src/cull/cullBinStateSorted.cxx +++ b/panda/src/cull/cullBinStateSorted.cxx @@ -81,9 +81,10 @@ draw(bool force, Thread *current_thread) { nassertd(object->_geom != nullptr) continue; _gsg->set_state_and_transform(object->_state, object->_internal_transform); - data_reader.set_object(object->_munged_data); + + GeomPipelineReader geom_reader(object->_geom, current_thread); + GeomVertexDataPipelineReader data_reader(object->_munged_data, current_thread); data_reader.check_array_readers(); - geom_reader.set_object(object->_geom); geom_reader.draw(_gsg, &data_reader, force); } else { // It has a callback associated. diff --git a/panda/src/cull/cullBinUnsorted.cxx b/panda/src/cull/cullBinUnsorted.cxx index 14766f9bbd..0f37ae97b0 100644 --- a/panda/src/cull/cullBinUnsorted.cxx +++ b/panda/src/cull/cullBinUnsorted.cxx @@ -55,9 +55,6 @@ void CullBinUnsorted:: draw(bool force, Thread *current_thread) { PStatTimer timer(_draw_this_pcollector, current_thread); - GeomPipelineReader geom_reader(current_thread); - GeomVertexDataPipelineReader data_reader(current_thread); - Objects::iterator oi; for (oi = _objects.begin(); oi != _objects.end(); ++oi) { CullableObject *object = (*oi); @@ -66,9 +63,10 @@ draw(bool force, Thread *current_thread) { nassertd(object->_geom != nullptr) continue; _gsg->set_state_and_transform(object->_state, object->_internal_transform); - data_reader.set_object(object->_munged_data); + + GeomPipelineReader geom_reader(object->_geom, current_thread); + GeomVertexDataPipelineReader data_reader(object->_munged_data, current_thread); data_reader.check_array_readers(); - geom_reader.set_object(object->_geom); geom_reader.draw(_gsg, &data_reader, force); } else { // It has a callback associated. diff --git a/panda/src/gobj/geom.cxx b/panda/src/gobj/geom.cxx index 5cf18838d8..565f8c47b4 100644 --- a/panda/src/gobj/geom.cxx +++ b/panda/src/gobj/geom.cxx @@ -195,6 +195,9 @@ offset_vertices(const GeomVertexData *data, int offset) { cdata->_data = (GeomVertexData *)data; #ifndef NDEBUG + GeomVertexDataPipelineReader data_reader(data, current_thread); + data_reader.check_array_readers(); + bool all_is_valid = true; #endif Primitives::iterator pi; @@ -203,7 +206,7 @@ offset_vertices(const GeomVertexData *data, int offset) { prim->offset_vertices(offset); #ifndef NDEBUG - if (!prim->check_valid(data)) { + if (!prim->check_valid(&data_reader)) { gobj_cat.warning() << *prim << " is invalid for " << *data << ":\n"; prim->write(gobj_cat.warning(false), 4); @@ -423,6 +426,9 @@ decompose_in_place() { CDWriter cdata(_cycler, true, current_thread); #ifndef NDEBUG + GeomVertexDataPipelineReader data_reader(cdata->_data.get_read_pointer(current_thread), current_thread); + data_reader.check_array_readers(); + bool all_is_valid = true; #endif Primitives::iterator pi; @@ -431,7 +437,7 @@ decompose_in_place() { (*pi) = (GeomPrimitive *)new_prim.p(); #ifndef NDEBUG - if (!new_prim->check_valid(cdata->_data.get_read_pointer(current_thread))) { + if (!new_prim->check_valid(&data_reader)) { all_is_valid = false; } #endif @@ -457,6 +463,9 @@ doubleside_in_place() { CDWriter cdata(_cycler, true, current_thread); #ifndef NDEBUG + GeomVertexDataPipelineReader data_reader(cdata->_data.get_read_pointer(current_thread), current_thread); + data_reader.check_array_readers(); + bool all_is_valid = true; #endif Primitives::iterator pi; @@ -465,7 +474,7 @@ doubleside_in_place() { (*pi) = (GeomPrimitive *)new_prim.p(); #ifndef NDEBUG - if (!new_prim->check_valid(cdata->_data.get_read_pointer(current_thread))) { + if (!new_prim->check_valid(&data_reader)) { all_is_valid = false; } #endif @@ -491,6 +500,9 @@ reverse_in_place() { CDWriter cdata(_cycler, true, current_thread); #ifndef NDEBUG + GeomVertexDataPipelineReader data_reader(cdata->_data.get_read_pointer(current_thread), current_thread); + data_reader.check_array_readers(); + bool all_is_valid = true; #endif Primitives::iterator pi; @@ -499,7 +511,7 @@ reverse_in_place() { (*pi) = (GeomPrimitive *)new_prim.p(); #ifndef NDEBUG - if (!new_prim->check_valid(cdata->_data.get_read_pointer(current_thread))) { + if (!new_prim->check_valid(&data_reader)) { all_is_valid = false; } #endif @@ -525,6 +537,9 @@ rotate_in_place() { CDWriter cdata(_cycler, true, current_thread); #ifndef NDEBUG + GeomVertexDataPipelineReader data_reader(cdata->_data.get_read_pointer(current_thread), current_thread); + data_reader.check_array_readers(); + bool all_is_valid = true; #endif Primitives::iterator pi; @@ -533,7 +548,7 @@ rotate_in_place() { (*pi) = (GeomPrimitive *)new_prim.p(); #ifndef NDEBUG - if (!new_prim->check_valid(cdata->_data.get_read_pointer(current_thread))) { + if (!new_prim->check_valid(&data_reader)) { all_is_valid = false; } #endif @@ -640,6 +655,9 @@ unify_in_place(int max_indices, bool preserve_order) { // primitives.) nassertv(false); } + + GeomVertexDataPipelineReader data_reader(cdata->_data.get_read_pointer(current_thread), current_thread); + data_reader.check_array_readers(); #endif // Finally, iterate through the remaining primitives, and copy them to the @@ -649,7 +667,7 @@ unify_in_place(int max_indices, bool preserve_order) { for (npi = new_prims.begin(); npi != new_prims.end(); ++npi) { GeomPrimitive *prim = (*npi).second; - nassertv(prim->check_valid(cdata->_data.get_read_pointer(current_thread))); + nassertv(prim->check_valid(&data_reader)); // Each new primitive, naturally, inherits the Geom's overall shade model. prim->set_shade_model(cdata->_shade_model); @@ -748,6 +766,9 @@ make_lines_in_place() { CDWriter cdata(_cycler, true, current_thread); #ifndef NDEBUG + GeomVertexDataPipelineReader data_reader(cdata->_data.get_read_pointer(current_thread), current_thread); + data_reader.check_array_readers(); + bool all_is_valid = true; #endif Primitives::iterator pi; @@ -756,7 +777,7 @@ make_lines_in_place() { (*pi) = (GeomPrimitive *)new_prim.p(); #ifndef NDEBUG - if (!new_prim->check_valid(cdata->_data.get_read_pointer(current_thread))) { + if (!new_prim->check_valid(&data_reader)) { all_is_valid = false; } #endif @@ -782,6 +803,9 @@ make_points_in_place() { CDWriter cdata(_cycler, true, current_thread); #ifndef NDEBUG + GeomVertexDataPipelineReader data_reader(cdata->_data.get_read_pointer(current_thread), current_thread); + data_reader.check_array_readers(); + bool all_is_valid = true; #endif Primitives::iterator pi; @@ -790,7 +814,7 @@ make_points_in_place() { (*pi) = (GeomPrimitive *)new_prim.p(); #ifndef NDEBUG - if (!new_prim->check_valid(cdata->_data.get_read_pointer(current_thread))) { + if (!new_prim->check_valid(&data_reader)) { all_is_valid = false; } #endif @@ -816,6 +840,9 @@ make_patches_in_place() { CDWriter cdata(_cycler, true, current_thread); #ifndef NDEBUG + GeomVertexDataPipelineReader data_reader(cdata->_data.get_read_pointer(current_thread), current_thread); + data_reader.check_array_readers(); + bool all_is_valid = true; #endif Primitives::iterator pi; @@ -824,7 +851,7 @@ make_patches_in_place() { (*pi) = (GeomPrimitive *)new_prim.p(); #ifndef NDEBUG - if (!new_prim->check_valid(cdata->_data.get_read_pointer(current_thread))) { + if (!new_prim->check_valid(&data_reader)) { all_is_valid = false; } #endif @@ -850,6 +877,9 @@ make_adjacency_in_place() { CDWriter cdata(_cycler, true, current_thread); #ifndef NDEBUG + GeomVertexDataPipelineReader data_reader(cdata->_data.get_read_pointer(current_thread), current_thread); + data_reader.check_array_readers(); + bool all_is_valid = true; #endif Primitives::iterator pi; @@ -859,7 +889,7 @@ make_adjacency_in_place() { (*pi) = (GeomPrimitive *)new_prim.p(); #ifndef NDEBUG - if (!new_prim->check_valid(cdata->_data.get_read_pointer(current_thread))) { + if (!new_prim->check_valid(&data_reader)) { all_is_valid = false; } #endif @@ -1465,13 +1495,20 @@ clear_prepared(PreparedGraphicsObjects *prepared_objects) { */ bool Geom:: check_will_be_valid(const GeomVertexData *vertex_data) const { - CDReader cdata(_cycler); + Thread *current_thread = Thread::get_current_thread(); + + CDReader cdata(_cycler, current_thread); + + GeomVertexDataPipelineReader data_reader(vertex_data, current_thread); + data_reader.check_array_readers(); Primitives::const_iterator pi; for (pi = cdata->_primitives.begin(); pi != cdata->_primitives.end(); ++pi) { - if (!(*pi).get_read_pointer()->check_valid(vertex_data)) { + GeomPrimitivePipelineReader reader((*pi).get_read_pointer(), current_thread); + reader.check_minmax(); + if (!reader.check_valid(&data_reader)) { return false; } } diff --git a/panda/src/gobj/geomPrimitive.I b/panda/src/gobj/geomPrimitive.I index 0984dbecb3..f314c81090 100644 --- a/panda/src/gobj/geomPrimitive.I +++ b/panda/src/gobj/geomPrimitive.I @@ -223,11 +223,19 @@ get_modified() const { INLINE bool GeomPrimitive:: check_valid(const GeomVertexData *vertex_data) const { Thread *current_thread = Thread::get_current_thread(); - GeomPrimitivePipelineReader reader(this, current_thread); - reader.check_minmax(); GeomVertexDataPipelineReader data_reader(vertex_data, current_thread); data_reader.check_array_readers(); - return reader.check_valid(&data_reader); + return check_valid(&data_reader); +} + +/** + * + */ +INLINE bool GeomPrimitive:: +check_valid(const GeomVertexDataPipelineReader *data_reader) const { + GeomPrimitivePipelineReader reader(this, data_reader->get_current_thread()); + reader.check_minmax(); + return reader.check_valid(data_reader); } /** diff --git a/panda/src/gobj/geomPrimitive.h b/panda/src/gobj/geomPrimitive.h index b8012507b8..392fffe1cf 100644 --- a/panda/src/gobj/geomPrimitive.h +++ b/panda/src/gobj/geomPrimitive.h @@ -146,6 +146,7 @@ PUBLISHED: bool request_resident(Thread *current_thread = Thread::get_current_thread()) const; INLINE bool check_valid(const GeomVertexData *vertex_data) const; + INLINE bool check_valid(const GeomVertexDataPipelineReader *data_reader) const; virtual void output(std::ostream &out) const; virtual void write(std::ostream &out, int indent_level) const; From 7e290b221bc58fd7bc496fcf3540920840dce4b2 Mon Sep 17 00:00:00 2001 From: rdb Date: Fri, 3 Aug 2018 21:05:12 +0200 Subject: [PATCH 081/125] Remove a few unused and obsolete C++ test files --- makepanda/makepanda.vcproj | 3 -- panda/src/collide/test_collide.cxx | 70 --------------------------- panda/src/gobj/test_gobj.cxx | 25 ---------- panda/src/testbed/text_test.cxx | 78 ------------------------------ 4 files changed, 176 deletions(-) delete mode 100644 panda/src/collide/test_collide.cxx delete mode 100644 panda/src/gobj/test_gobj.cxx delete mode 100644 panda/src/testbed/text_test.cxx diff --git a/makepanda/makepanda.vcproj b/makepanda/makepanda.vcproj index 23ed91cdf5..6be22d7d1a 100644 --- a/makepanda/makepanda.vcproj +++ b/makepanda/makepanda.vcproj @@ -760,7 +760,6 @@ - @@ -1114,7 +1113,6 @@ - @@ -3705,7 +3703,6 @@ - diff --git a/panda/src/collide/test_collide.cxx b/panda/src/collide/test_collide.cxx deleted file mode 100644 index 38736d5d38..0000000000 --- a/panda/src/collide/test_collide.cxx +++ /dev/null @@ -1,70 +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_collide.cxx - * @author drose - * @date 2000-04-24 - */ - -#include "collisionTraverser.h" -#include "collisionNode.h" -#include "collisionSphere.h" -#include "collisionPlane.h" -#include "collisionHandlerPusher.h" - -#include "namedNode.h" -#include "pt_NamedNode.h" -#include "pointerTo.h" -#include "transformTransition.h" -#include "luse.h" -#include "get_rel_pos.h" -#include "renderRelation.h" - -int -main(int argc, char *argv[]) { - PT_NamedNode r = new NamedNode("r"); - - PT_NamedNode a = new NamedNode("a"); - PT_NamedNode b = new NamedNode("b"); - - PT(CollisionNode) aa = new CollisionNode("aa"); - PT(CollisionNode) ab = new CollisionNode("ab"); - PT(CollisionNode) ba = new CollisionNode("ba"); - - RenderRelation *r_a = new RenderRelation(r, a); - RenderRelation *r_b = new RenderRelation(r, b); - - RenderRelation *a_aa = new RenderRelation(a, aa); - RenderRelation *a_ab = new RenderRelation(a, ab); - RenderRelation *b_ba = new RenderRelation(b, ba); - - - CollisionSphere *aa1 = new CollisionSphere(LPoint3f(0, 0, 0), 1); - aa->add_solid(aa1); - a_aa->set_transition(new TransformTransition(LMatrix4f::translate_mat(0, -5, 0))); - - CollisionSphere *ab1 = new CollisionSphere(LPoint3f(0, 2, 0), 1.5); - ab->add_solid(ab1); - - Planef plane(LVector3f(0, 1, 0), LPoint3f(0, 0, 0)); - CollisionPlane *ba1 = new CollisionPlane(plane); - ba->add_solid(ba1); - - CollisionTraverser ct; - PT(CollisionHandlerPusher) chp = new CollisionHandlerPusher; - chp->add_collider(aa, a_aa); - ct.add_collider(aa, chp); - - ct.traverse(r); - - nout << "\nFrame 2:\n\n"; - - ct.traverse(r); - - return (0); -} diff --git a/panda/src/gobj/test_gobj.cxx b/panda/src/gobj/test_gobj.cxx deleted file mode 100644 index 0bbe93e907..0000000000 --- a/panda/src/gobj/test_gobj.cxx +++ /dev/null @@ -1,25 +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_gobj.cxx - * @author shochet - * @date 2000-02-02 - */ - -#include "geom.h" -#include "perspectiveProjection.h" - -int main() { - nout << "running test_gobj" << std::endl; - PT(GeomTri) triangle = new GeomTri; - Frustumf frust; - PT(PerspectiveProjection) proj = new PerspectiveProjection(frust); - LMatrix4f mat = proj->get_projection_mat(); - nout << "default proj matrix: " << mat; - return 0; -} diff --git a/panda/src/testbed/text_test.cxx b/panda/src/testbed/text_test.cxx deleted file mode 100644 index f0689940ad..0000000000 --- a/panda/src/testbed/text_test.cxx +++ /dev/null @@ -1,78 +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 text_test.cxx - */ - -#include "eventHandler.h" -#include "chancfg.h" -#include "textNode.h" -#include "eggLoader.h" -#include "pnotify.h" -#include "pt_NamedNode.h" - -extern PT_NamedNode render; -extern PT_NamedNode egg_root; -extern EventHandler event_handler; - -extern int framework_main(int argc, char *argv[]); -extern void (*define_keys)(EventHandler&); - -PT(TextNode) text_node; -char *textStr; - -void event_p(CPT_Event) { - text_node->set_text("I'm a woo woo woo!"); - - nout << "text is " << text_node->get_width() << " by " - << text_node->get_height() << "\n"; -} - -void event_s(CPT_Event) { - text_node->set_wordwrap(5.0); - - nout << "text is " << text_node->get_width() << " by " - << text_node->get_height() << "\n"; -} - -void text_keys(EventHandler& eh) { - eh.add_hook("p", event_p); - eh.add_hook("s", event_s); - - text_node = new TextNode("text_node"); - PT_NamedNode font = loader.load_sync("cmr12"); - text_node->set_font(font.p()); - text_node->set_wordwrap(20.0); - text_node->set_card_as_margin(0.25, 0.25, 0.25, 0.25); - PT(Texture) tex = new Texture; - tex->set_name("genericButton.rgb"); - tex->set_minfilter(SamplerState::FT_linear); - tex->set_magfilter(SamplerState::FT_linear); - tex->read("/beta/toons/textures/smGreyButtonUp.rgb"); - text_node->set_card_texture( tex ); - text_node->set_card_border(0.1, 0.1); - text_node->set_text( textStr ); - text_node->set_text_color( 0.0, 0.0, 0.0, 1.0 ); - if (text_node->has_card_texture()) - nout << "I've got a texture!" << "\n"; - else - nout << "I don't have a texture..." << "\n"; - nout << "text is " << text_node->get_width() << " by " - << text_node->get_height() << "\n"; - - new RenderRelation(egg_root, text_node); -} - -int main(int argc, char *argv[]) { - define_keys = &text_keys; - if (argc > 1) - textStr = argv[1]; - else - textStr = argv[0]; - return framework_main(argc, argv); -} From 1e9a64fe6324d8b4ac96daafa7427e9f55e6dd38 Mon Sep 17 00:00:00 2001 From: rdb Date: Fri, 3 Aug 2018 21:10:26 +0200 Subject: [PATCH 082/125] tests: add Geom.decompose tests --- tests/gobj/test_geom.py | 42 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 tests/gobj/test_geom.py diff --git a/tests/gobj/test_geom.py b/tests/gobj/test_geom.py new file mode 100644 index 0000000000..2a5a462659 --- /dev/null +++ b/tests/gobj/test_geom.py @@ -0,0 +1,42 @@ +from panda3d import core + +empty_format = core.GeomVertexFormat.get_empty() + + +def test_geom_decompose_in_place(): + vertex_data = core.GeomVertexData("", empty_format, core.GeomEnums.UH_static) + prim = core.GeomTristrips(core.GeomEnums.UH_static) + prim.add_vertex(0) + prim.add_vertex(1) + prim.add_vertex(2) + prim.add_vertex(3) + prim.close_primitive() + + geom = core.Geom(vertex_data) + geom.add_primitive(prim) + + geom.decompose_in_place() + + prim = geom.get_primitive(0) + assert tuple(prim.get_vertex_list()) == (0, 1, 2, 2, 1, 3) + + +def test_geom_decompose(): + vertex_data = core.GeomVertexData("", empty_format, core.GeomEnums.UH_static) + prim = core.GeomTristrips(core.GeomEnums.UH_static) + prim.add_vertex(0) + prim.add_vertex(1) + prim.add_vertex(2) + prim.add_vertex(3) + prim.close_primitive() + + geom = core.Geom(vertex_data) + geom.add_primitive(prim) + + new_geom = geom.decompose() + + new_prim = new_geom.get_primitive(0) + assert tuple(new_prim.get_vertex_list()) == (0, 1, 2, 2, 1, 3) + + # Old primitive should still be unchanged + assert prim == geom.get_primitive(0) From 9ba2d7242e6ed91da981829b27f9842943cf8329 Mon Sep 17 00:00:00 2001 From: rdb Date: Fri, 3 Aug 2018 21:27:58 +0200 Subject: [PATCH 083/125] gobj: get rid of enforce-attrib-lock, just DTRT instead This setting causes asserts when modifying certain material flags after they are assigned to a node, in case a shader has been generated that uses the materials, which cannot efficiently detect whether the material has changed. However, we already sort of have a (inefficient, but effective) solution for this in TextureStage (see #178) that we could just apply here as well: changing the material attributes after such a shader has been generated could call GraphicsStateGuardianBase::mark_rehash_generated_shaders(). In the future, we should replace the material model with one that does not require shader regeneration for such seemingly trivial property changes. Fixes #370 --- panda/src/gobj/config_gobj.cxx | 12 ----- panda/src/gobj/config_gobj.h | 1 - panda/src/gobj/material.I | 58 ++++++++++++++++------ panda/src/gobj/material.cxx | 59 ++++++++++------------- panda/src/gobj/material.h | 6 +++ panda/src/pgraphnodes/shaderGenerator.cxx | 8 ++- 6 files changed, 80 insertions(+), 64 deletions(-) diff --git a/panda/src/gobj/config_gobj.cxx b/panda/src/gobj/config_gobj.cxx index b7d0e02eb5..7da3b1d31e 100644 --- a/panda/src/gobj/config_gobj.cxx +++ b/panda/src/gobj/config_gobj.cxx @@ -260,18 +260,6 @@ ConfigVariableBool cache_generated_shaders PRC_DESC("Set this true to cause all generated shaders to be cached in " "memory. This is useful to prevent unnecessary recompilation.")); -ConfigVariableBool enforce_attrib_lock -("enforce-attrib-lock", true, - PRC_DESC("When a MaterialAttrib, TextureAttrib, or LightAttrib is " - "constructed, the corresponding Material, Texture, or Light " - "is 'attrib locked.' The attrib lock prevents qualitative " - "changes to the object. This makes it possible to hardwire " - "information about material, light, and texture properties " - "into generated shaders. This config variable can disable " - "the attrib lock. Disabling the lock will break the shader " - "generator, but doing so may be necessary for backward " - "compatibility with old code.")); - ConfigVariableBool vertices_float64 ("vertices-float64", false, PRC_DESC("When this is true, the default float format for vertices " diff --git a/panda/src/gobj/config_gobj.h b/panda/src/gobj/config_gobj.h index d3b651d3d4..7e769c0f45 100644 --- a/panda/src/gobj/config_gobj.h +++ b/panda/src/gobj/config_gobj.h @@ -51,7 +51,6 @@ extern EXPCL_PANDA_GOBJ ConfigVariableBool connect_triangle_strips; extern EXPCL_PANDA_GOBJ ConfigVariableBool preserve_triangle_strips; extern EXPCL_PANDA_GOBJ ConfigVariableBool dump_generated_shaders; extern EXPCL_PANDA_GOBJ ConfigVariableBool cache_generated_shaders; -extern EXPCL_PANDA_GOBJ ConfigVariableBool enforce_attrib_lock; extern EXPCL_PANDA_GOBJ ConfigVariableBool vertices_float64; extern EXPCL_PANDA_GOBJ ConfigVariableInt vertex_column_alignment; extern EXPCL_PANDA_GOBJ ConfigVariableBool vertex_animation_align_16; diff --git a/panda/src/gobj/material.I b/panda/src/gobj/material.I index b9e30ba262..dcaef86980 100644 --- a/panda/src/gobj/material.I +++ b/panda/src/gobj/material.I @@ -32,8 +32,18 @@ Material(const std::string &name) : Namable(name) { * */ INLINE Material:: -Material(const Material ©) : Namable(copy) { - operator = (copy); +Material(const Material ©) : + Namable(copy) , + _base_color(copy._base_color), + _ambient(copy._ambient), + _diffuse(copy._diffuse), + _specular(copy._specular), + _emission(copy._emission), + _shininess(copy._shininess), + _roughness(copy._roughness), + _metallic(copy._metallic), + _refractive_index(copy._refractive_index), + _flags(copy._flags & ~(F_attrib_lock | F_used_by_auto_shader)) { } /** @@ -99,8 +109,8 @@ get_ambient() const { */ INLINE void Material:: clear_ambient() { - if (enforce_attrib_lock) { - nassertv(!is_attrib_locked()); + if (has_ambient() && is_used_by_auto_shader()) { + GraphicsStateGuardianBase::mark_rehash_generated_shaders(); } _flags &= ~F_ambient; _ambient = _base_color; @@ -129,8 +139,8 @@ get_diffuse() const { */ INLINE void Material:: clear_diffuse() { - if (enforce_attrib_lock) { - nassertv(!is_attrib_locked()); + if (has_diffuse() && is_used_by_auto_shader()) { + GraphicsStateGuardianBase::mark_rehash_generated_shaders(); } _flags &= ~F_diffuse; _diffuse = _base_color * (1 - _metallic); @@ -177,8 +187,8 @@ get_emission() const { */ INLINE void Material:: clear_emission() { - if (enforce_attrib_lock) { - nassertv(!is_attrib_locked()); + if (has_emission() && is_used_by_auto_shader()) { + GraphicsStateGuardianBase::mark_rehash_generated_shaders(); } _flags &= ~F_emission; _emission.set(0.0f, 0.0f, 0.0f, 0.0f); @@ -253,8 +263,8 @@ get_local() const { */ INLINE void Material:: set_local(bool local) { - if (enforce_attrib_lock) { - nassertv(!is_attrib_locked()); + if (is_used_by_auto_shader() && get_local() != local) { + GraphicsStateGuardianBase::mark_rehash_generated_shaders(); } if (local) { _flags |= F_local; @@ -278,8 +288,8 @@ get_twoside() const { */ INLINE void Material:: set_twoside(bool twoside) { - if (enforce_attrib_lock) { - nassertv(!is_attrib_locked()); + if (is_used_by_auto_shader() && get_twoside() != twoside) { + GraphicsStateGuardianBase::mark_rehash_generated_shaders(); } if (twoside) { _flags |= F_twoside; @@ -313,7 +323,7 @@ operator < (const Material &other) const { } /** - * + * @deprecated This no longer has any meaning in 1.10. */ INLINE bool Material:: is_attrib_locked() const { @@ -321,17 +331,35 @@ is_attrib_locked() const { } /** - * + * @deprecated This no longer has any meaning in 1.10. */ INLINE void Material:: set_attrib_lock() { _flags |= F_attrib_lock; } +/** + * Internal. Returns true if a shader has been generated that uses this. + */ +INLINE bool Material:: +is_used_by_auto_shader() const { + return (_flags & F_attrib_lock) != 0; +} + +/** + * Called by the shader generator to indicate that a shader has been generated + * that uses this material. + */ +INLINE void Material:: +mark_used_by_auto_shader() { + _flags |= F_used_by_auto_shader; +} + /** * */ INLINE int Material:: get_flags() const { - return _flags; + // F_used_by_auto_shader is an internal flag, ignore it. + return _flags & ~F_used_by_auto_shader; } diff --git a/panda/src/gobj/material.cxx b/panda/src/gobj/material.cxx index 1952066649..24bc0fb590 100644 --- a/panda/src/gobj/material.cxx +++ b/panda/src/gobj/material.cxx @@ -28,6 +28,11 @@ PT(Material) Material::_default; void Material:: operator = (const Material ©) { Namable::operator = (copy); + + if (is_used_by_auto_shader()) { + GraphicsStateGuardianBase::mark_rehash_generated_shaders(); + } + _base_color = copy._base_color; _ambient = copy._ambient; _diffuse = copy._diffuse; @@ -37,7 +42,7 @@ operator = (const Material ©) { _roughness = copy._roughness; _metallic = copy._metallic; _refractive_index = copy._refractive_index; - _flags = copy._flags & (~F_attrib_lock); + _flags = (copy._flags & ~(F_attrib_lock | F_used_by_auto_shader)) | (_flags & (F_attrib_lock | F_used_by_auto_shader)); } /** @@ -53,10 +58,8 @@ operator = (const Material ©) { */ void Material:: set_base_color(const LColor &color) { - if (enforce_attrib_lock) { - if ((_flags & F_base_color) == 0) { - nassertv(!is_attrib_locked()); - } + if (!has_base_color() && is_used_by_auto_shader()) { + GraphicsStateGuardianBase::mark_rehash_generated_shaders(); } _base_color = color; _flags |= F_base_color | F_metallic; @@ -81,8 +84,8 @@ set_base_color(const LColor &color) { */ void Material:: clear_base_color() { - if (enforce_attrib_lock) { - nassertv(!is_attrib_locked()); + if (has_base_color() && is_used_by_auto_shader()) { + GraphicsStateGuardianBase::mark_rehash_generated_shaders(); } _flags &= ~F_base_color; _base_color.set(0.0f, 0.0f, 0.0f, 0.0f); @@ -116,10 +119,8 @@ clear_base_color() { */ void Material:: set_ambient(const LColor &color) { - if (enforce_attrib_lock) { - if ((_flags & F_ambient)==0) { - nassertv(!is_attrib_locked()); - } + if (!has_ambient() && is_used_by_auto_shader()) { + GraphicsStateGuardianBase::mark_rehash_generated_shaders(); } _ambient = color; _flags |= F_ambient; @@ -137,10 +138,8 @@ set_ambient(const LColor &color) { */ void Material:: set_diffuse(const LColor &color) { - if (enforce_attrib_lock) { - if ((_flags & F_diffuse)==0) { - nassertv(!is_attrib_locked()); - } + if (!has_diffuse() && is_used_by_auto_shader()) { + GraphicsStateGuardianBase::mark_rehash_generated_shaders(); } _diffuse = color; _flags |= F_diffuse; @@ -160,10 +159,8 @@ set_diffuse(const LColor &color) { */ void Material:: set_specular(const LColor &color) { - if (enforce_attrib_lock) { - if ((_flags & F_specular)==0) { - nassertv(!is_attrib_locked()); - } + if (!has_specular() && is_used_by_auto_shader()) { + GraphicsStateGuardianBase::mark_rehash_generated_shaders(); } _specular = color; _flags |= F_specular; @@ -174,8 +171,8 @@ set_specular(const LColor &color) { */ void Material:: clear_specular() { - if (enforce_attrib_lock) { - nassertv(!is_attrib_locked()); + if (has_specular() && is_used_by_auto_shader()) { + GraphicsStateGuardianBase::mark_rehash_generated_shaders(); } _flags &= ~F_specular; @@ -201,10 +198,8 @@ clear_specular() { */ void Material:: set_emission(const LColor &color) { - if (enforce_attrib_lock) { - if ((_flags & F_emission)==0) { - nassertv(!is_attrib_locked()); - } + if (!has_emission() && is_used_by_auto_shader()) { + GraphicsStateGuardianBase::mark_rehash_generated_shaders(); } _emission = color; _flags |= F_emission; @@ -275,11 +270,6 @@ set_roughness(PN_stdfloat roughness) { */ void Material:: set_metallic(PN_stdfloat metallic) { - if (enforce_attrib_lock) { - if ((_flags & F_metallic) == 0) { - nassertv(!is_attrib_locked()); - } - } _metallic = metallic; _flags |= F_metallic; @@ -305,9 +295,6 @@ set_metallic(PN_stdfloat metallic) { */ void Material:: clear_metallic() { - if (enforce_attrib_lock) { - nassertv(!is_attrib_locked()); - } _flags &= ~F_metallic; _metallic = 0; @@ -482,7 +469,7 @@ write_datagram(BamWriter *manager, Datagram &me) { me.add_string(get_name()); if (manager->get_file_minor_ver() >= 39) { - me.add_int32(_flags); + me.add_int32(_flags & ~F_used_by_auto_shader); if (_flags & F_metallic) { // Metalness workflow. @@ -570,4 +557,8 @@ fillin(DatagramIterator &scan, BamReader *manager) { set_roughness(_shininess); } } + + if (is_used_by_auto_shader()) { + GraphicsStateGuardianBase::mark_rehash_generated_shaders(); + } } diff --git a/panda/src/gobj/material.h b/panda/src/gobj/material.h index 5835a81ae3..259d5d6874 100644 --- a/panda/src/gobj/material.h +++ b/panda/src/gobj/material.h @@ -21,6 +21,7 @@ #include "luse.h" #include "numeric_types.h" #include "config_gobj.h" +#include "graphicsStateGuardianBase.h" class FactoryParams; @@ -127,7 +128,11 @@ PUBLISHED: MAKE_PROPERTY(local, get_local, set_local); MAKE_PROPERTY(twoside, get_twoside, set_twoside); +protected: + INLINE bool is_used_by_auto_shader() const; + public: + INLINE void mark_used_by_auto_shader(); INLINE int get_flags() const; enum Flags { @@ -142,6 +147,7 @@ public: F_metallic = 0x100, F_base_color = 0x200, F_refractive_index = 0x400, + F_used_by_auto_shader = 0x800, }; private: diff --git a/panda/src/pgraphnodes/shaderGenerator.cxx b/panda/src/pgraphnodes/shaderGenerator.cxx index 71379ddbac..1673b82358 100644 --- a/panda/src/pgraphnodes/shaderGenerator.cxx +++ b/panda/src/pgraphnodes/shaderGenerator.cxx @@ -252,8 +252,12 @@ analyze_renderstate(ShaderKey &key, const RenderState *rs) { // Store the material flags (not the material values itself). const MaterialAttrib *material; rs->get_attrib_def(material); - if (material->get_material() != nullptr) { - key._material_flags = material->get_material()->get_flags(); + Material *mat = material->get_material(); + if (mat != nullptr) { + // The next time the Material flags change, the Material should cause the + // states to be rehashed. + mat->mark_used_by_auto_shader(); + key._material_flags = mat->get_flags(); } // Break out the lights by type. From 8806dedb51d3c25cbf6e6507b73c8597058b2c27 Mon Sep 17 00:00:00 2001 From: rdb Date: Fri, 3 Aug 2018 22:24:48 +0200 Subject: [PATCH 084/125] ShaderGenerator: avoid writing vtx_color input if unneeded --- panda/src/pgraphnodes/shaderGenerator.cxx | 27 ++++++++++++++++++----- 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/panda/src/pgraphnodes/shaderGenerator.cxx b/panda/src/pgraphnodes/shaderGenerator.cxx index 1673b82358..91729f6e79 100644 --- a/panda/src/pgraphnodes/shaderGenerator.cxx +++ b/panda/src/pgraphnodes/shaderGenerator.cxx @@ -735,6 +735,19 @@ synthesize_shader(const RenderState *rs, const GeomVertexAnimationSpec &anim) { } } + bool need_color = false; + if (key._color_type == ColorAttrib::T_vertex) { + if (key._lighting) { + if ((key._material_flags & Material::F_ambient) == 0 || + (key._material_flags & Material::F_diffuse) == 0 || + key._calc_primary_alpha) { + need_color = true; + } + } else { + need_color = true; + } + } + text << "void vshader(\n"; for (size_t i = 0; i < key._textures.size(); ++i) { const ShaderKey::TextureInfo &tex = key._textures[i]; @@ -798,7 +811,7 @@ synthesize_shader(const RenderState *rs, const GeomVertexAnimationSpec &anim) { text << "\t out float4 l_tangent : " << tangent_freg << ",\n"; text << "\t out float4 l_binormal : " << binormal_freg << ",\n"; } - if (key._color_type == ColorAttrib::T_vertex) { + if (need_color && key._color_type == ColorAttrib::T_vertex) { text << "\t in float4 vtx_color : " << color_vreg << ",\n"; text << "\t out float4 l_color : COLOR0,\n"; } @@ -919,7 +932,7 @@ synthesize_shader(const RenderState *rs, const GeomVertexAnimationSpec &anim) { string tcname = it->first->join("_"); text << "\t l_" << tcname << " = vtx_" << tcname << ";\n"; } - if (key._color_type == ColorAttrib::T_vertex) { + if (need_color && key._color_type == ColorAttrib::T_vertex) { text << "\t l_color = vtx_color;\n"; } if (key._texture_flags & ShaderKey::TF_map_normal) { @@ -1019,10 +1032,12 @@ synthesize_shader(const RenderState *rs, const GeomVertexAnimationSpec &anim) { } text << "\t out float4 o_color : COLOR0,\n"; - if (key._color_type == ColorAttrib::T_vertex) { - text << "\t in float4 l_color : COLOR0,\n"; - } else if (key._color_type == ColorAttrib::T_flat) { - text << "\t uniform float4 attr_color,\n"; + if (need_color) { + if (key._color_type == ColorAttrib::T_vertex) { + text << "\t in float4 l_color : COLOR0,\n"; + } else if (key._color_type == ColorAttrib::T_flat) { + text << "\t uniform float4 attr_color,\n"; + } } for (int i = 0; i < key._num_clip_planes; ++i) { From 929808b8676dfc6b4a31d92d5cb6136838e3e500 Mon Sep 17 00:00:00 2001 From: rdb Date: Fri, 3 Aug 2018 22:58:29 +0200 Subject: [PATCH 085/125] ShaderGenerator: fix regression with flat colors --- panda/src/pgraphnodes/shaderGenerator.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/panda/src/pgraphnodes/shaderGenerator.cxx b/panda/src/pgraphnodes/shaderGenerator.cxx index 91729f6e79..47d735c781 100644 --- a/panda/src/pgraphnodes/shaderGenerator.cxx +++ b/panda/src/pgraphnodes/shaderGenerator.cxx @@ -736,7 +736,7 @@ synthesize_shader(const RenderState *rs, const GeomVertexAnimationSpec &anim) { } bool need_color = false; - if (key._color_type == ColorAttrib::T_vertex) { + if (key._color_type != ColorAttrib::T_off) { if (key._lighting) { if ((key._material_flags & Material::F_ambient) == 0 || (key._material_flags & Material::F_diffuse) == 0 || From b836a60adb9942ff7137231ddcd6c4ebf8776bdf Mon Sep 17 00:00:00 2001 From: rdb Date: Fri, 3 Aug 2018 22:59:04 +0200 Subject: [PATCH 086/125] cull: remove unused variable declarations --- panda/src/cull/cullBinBackToFront.cxx | 3 --- panda/src/cull/cullBinFixed.cxx | 3 --- panda/src/cull/cullBinFrontToBack.cxx | 3 --- panda/src/cull/cullBinStateSorted.cxx | 3 --- 4 files changed, 12 deletions(-) diff --git a/panda/src/cull/cullBinBackToFront.cxx b/panda/src/cull/cullBinBackToFront.cxx index c27c7e8ed4..34eef90ccf 100644 --- a/panda/src/cull/cullBinBackToFront.cxx +++ b/panda/src/cull/cullBinBackToFront.cxx @@ -85,9 +85,6 @@ void CullBinBackToFront:: draw(bool force, Thread *current_thread) { PStatTimer timer(_draw_this_pcollector, current_thread); - GeomPipelineReader geom_reader(current_thread); - GeomVertexDataPipelineReader data_reader(current_thread); - Objects::const_iterator oi; for (oi = _objects.begin(); oi != _objects.end(); ++oi) { CullableObject *object = (*oi)._object; diff --git a/panda/src/cull/cullBinFixed.cxx b/panda/src/cull/cullBinFixed.cxx index 3507ce4582..8bd81cf8fe 100644 --- a/panda/src/cull/cullBinFixed.cxx +++ b/panda/src/cull/cullBinFixed.cxx @@ -71,9 +71,6 @@ void CullBinFixed:: draw(bool force, Thread *current_thread) { PStatTimer timer(_draw_this_pcollector, current_thread); - GeomPipelineReader geom_reader(current_thread); - GeomVertexDataPipelineReader data_reader(current_thread); - Objects::const_iterator oi; for (oi = _objects.begin(); oi != _objects.end(); ++oi) { CullableObject *object = (*oi)._object; diff --git a/panda/src/cull/cullBinFrontToBack.cxx b/panda/src/cull/cullBinFrontToBack.cxx index 5f5d99e51c..a552c027fa 100644 --- a/panda/src/cull/cullBinFrontToBack.cxx +++ b/panda/src/cull/cullBinFrontToBack.cxx @@ -85,9 +85,6 @@ void CullBinFrontToBack:: draw(bool force, Thread *current_thread) { PStatTimer timer(_draw_this_pcollector, current_thread); - GeomPipelineReader geom_reader(current_thread); - GeomVertexDataPipelineReader data_reader(current_thread); - Objects::const_iterator oi; for (oi = _objects.begin(); oi != _objects.end(); ++oi) { CullableObject *object = (*oi)._object; diff --git a/panda/src/cull/cullBinStateSorted.cxx b/panda/src/cull/cullBinStateSorted.cxx index 3e2fca2e9a..2bd71094bd 100644 --- a/panda/src/cull/cullBinStateSorted.cxx +++ b/panda/src/cull/cullBinStateSorted.cxx @@ -70,9 +70,6 @@ void CullBinStateSorted:: draw(bool force, Thread *current_thread) { PStatTimer timer(_draw_this_pcollector, current_thread); - GeomPipelineReader geom_reader(current_thread); - GeomVertexDataPipelineReader data_reader(current_thread); - Objects::const_iterator oi; for (oi = _objects.begin(); oi != _objects.end(); ++oi) { CullableObject *object = (*oi)._object; From 60468b0becbe1b11aefd068c90b72d0398a19ec3 Mon Sep 17 00:00:00 2001 From: rdb Date: Sun, 5 Aug 2018 12:48:48 +0200 Subject: [PATCH 087/125] ShaderGenerator: additional case where vtx_color isn't needed See sample code in a comment in #370 --- panda/src/pgraphnodes/shaderGenerator.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/panda/src/pgraphnodes/shaderGenerator.cxx b/panda/src/pgraphnodes/shaderGenerator.cxx index 47d735c781..f52d0f4579 100644 --- a/panda/src/pgraphnodes/shaderGenerator.cxx +++ b/panda/src/pgraphnodes/shaderGenerator.cxx @@ -738,7 +738,7 @@ synthesize_shader(const RenderState *rs, const GeomVertexAnimationSpec &anim) { bool need_color = false; if (key._color_type != ColorAttrib::T_off) { if (key._lighting) { - if ((key._material_flags & Material::F_ambient) == 0 || + if (((key._material_flags & Material::F_ambient) == 0 && key._have_separate_ambient) || (key._material_flags & Material::F_diffuse) == 0 || key._calc_primary_alpha) { need_color = true; From 8348f16665e5e8c68609472a6a6faeb1ce29c6bd Mon Sep 17 00:00:00 2001 From: rdb Date: Sun, 5 Aug 2018 12:51:27 +0200 Subject: [PATCH 088/125] glgsg: fix incorrect behavior if mat has either ambient or diffuse This might have only been an issue in some drivers (not sure, spec is a bit vague here). Apparently we need to call glMaterial *after* the color material setting has been disabled for it to stick. Fixes #369 --- panda/src/glstuff/glGraphicsStateGuardian_src.cxx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx index 25a57a9a17..8fe943108b 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx @@ -7633,7 +7633,6 @@ do_issue_material() { } else if (material->has_ambient()) { // The material specifies an ambient, but not a diffuse component. The // diffuse component comes from the object's color. - call_glMaterialfv(face, GL_AMBIENT, material->get_ambient()); if (has_material_force_color) { glDisable(GL_COLOR_MATERIAL); call_glMaterialfv(face, GL_DIFFUSE, _material_force_color); @@ -7643,11 +7642,11 @@ do_issue_material() { #endif // OPENGLES glEnable(GL_COLOR_MATERIAL); } + call_glMaterialfv(face, GL_AMBIENT, material->get_ambient()); } else if (material->has_diffuse()) { // The material specifies a diffuse, but not an ambient component. The // ambient component comes from the object's color. - call_glMaterialfv(face, GL_DIFFUSE, material->get_diffuse()); if (has_material_force_color) { glDisable(GL_COLOR_MATERIAL); call_glMaterialfv(face, GL_AMBIENT, _material_force_color); @@ -7657,6 +7656,7 @@ do_issue_material() { #endif // OPENGLES glEnable(GL_COLOR_MATERIAL); } + call_glMaterialfv(face, GL_DIFFUSE, material->get_diffuse()); } else { // The material specifies neither a diffuse nor an ambient component. From 2556d006f708a5e4d84361e917764d618c497c02 Mon Sep 17 00:00:00 2001 From: rdb Date: Sun, 5 Aug 2018 13:01:42 +0200 Subject: [PATCH 089/125] glgsg: a few version check tweaks --- panda/src/glstuff/glGraphicsStateGuardian_src.cxx | 14 +++++++++----- panda/src/glstuff/glGraphicsStateGuardian_src.h | 1 + 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx index 8fe943108b..fb22fdb644 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx @@ -2286,8 +2286,10 @@ reset() { if (is_at_least_gl_version(4, 5) || has_extension("GL_ARB_direct_state_access")) { _glGenerateTextureMipmap = (PFNGLGENERATETEXTUREMIPMAPPROC) get_extension_func("glGenerateTextureMipmap"); + + _supports_dsa = true; } else { - _glGenerateTextureMipmap = nullptr; + _supports_dsa = false; } #endif @@ -2830,7 +2832,9 @@ reset() { // Check availability of anisotropic texture filtering. _supports_anisotropy = false; _max_anisotropy = 1.0; - if (has_extension("GL_EXT_texture_filter_anisotropic")) { + if (is_at_least_gl_version(4, 6) || + has_extension("GL_EXT_texture_filter_anisotropic") || + has_extension("GL_ARB_texture_filter_anisotropic")) { GLfloat max_anisotropy; glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &max_anisotropy); _max_anisotropy = (PN_stdfloat)max_anisotropy; @@ -3237,7 +3241,7 @@ reset() { if (GLCAT.is_debug()) { if (_supports_get_program_binary) { GLCAT.debug() - << "Supported shader binary formats:\n"; + << "Supported program binary formats:\n"; GLCAT.debug() << " "; pset::const_iterator it; @@ -3249,7 +3253,7 @@ reset() { } GLCAT.debug(false) << "\n"; } else { - GLCAT.debug() << "No shader binary formats supported.\n"; + GLCAT.debug() << "No program binary formats supported.\n"; } } #endif @@ -13193,7 +13197,7 @@ upload_texture_image(CLP(TextureContext) *gtc, bool needs_reload, void CLP(GraphicsStateGuardian):: generate_mipmaps(CLP(TextureContext) *gtc) { #ifndef OPENGLES - if (_glGenerateTextureMipmap != nullptr) { + if (_supports_dsa) { // OpenGL 4.5 offers an easy way to do this without binding. _glGenerateTextureMipmap(gtc->_index); return; diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.h b/panda/src/glstuff/glGraphicsStateGuardian_src.h index a8cd3a2e3b..99c8296336 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.h +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.h @@ -909,6 +909,7 @@ public: PFNGLBINDPROGRAMARBPROC _glBindProgram; #ifndef OPENGLES + bool _supports_dsa; PFNGLGENERATETEXTUREMIPMAPPROC _glGenerateTextureMipmap; #endif From 7c375ac53101b933f5969871ed8c854299f20e24 Mon Sep 17 00:00:00 2001 From: bfrisby2000 Date: Tue, 7 Aug 2018 20:23:16 -0400 Subject: [PATCH 090/125] showbase: Add blendType argument for Fade/Iris/Letterbox This allows the 'blendType' argument to be passed through the three transitions' Lerp Intervals. --- direct/src/showbase/Transitions.py | 32 +++++++++++++++++++----------- 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/direct/src/showbase/Transitions.py b/direct/src/showbase/Transitions.py index 5c449c6997..9e05daad3e 100644 --- a/direct/src/showbase/Transitions.py +++ b/direct/src/showbase/Transitions.py @@ -89,7 +89,7 @@ class Transitions: self.fade.setBin('unsorted', 0) self.fade.setColor(0,0,0,0) - def getFadeInIval(self, t=0.5, finishIval=None): + def getFadeInIval(self, t=0.5, finishIval=None, blendType='noBlend'): """ Returns an interval without starting it. This is particularly useful in cutscenes, so when the cutsceneIval is escaped out of we can finish the fade immediately @@ -103,6 +103,7 @@ class Transitions: self.lerpFunc(self.fade, t, self.alphaOff, # self.alphaOn, + blendType=blendType ), Func(self.fade.detachNode), name = self.fadeTaskName, @@ -111,7 +112,7 @@ class Transitions: transitionIval.append(finishIval) return transitionIval - def getFadeOutIval(self, t=0.5, finishIval=None): + def getFadeOutIval(self, t=0.5, finishIval=None, blendType='noBlend'): """ Create a sequence that lerps the color out, then parents the fade to hidden @@ -125,6 +126,7 @@ class Transitions: self.lerpFunc(self.fade, t, self.alphaOn, # self.alphaOff, + blendType=blendType ), name = self.fadeTaskName, ) @@ -132,7 +134,7 @@ class Transitions: transitionIval.append(finishIval) return transitionIval - def fadeIn(self, t=0.5, finishIval=None): + def fadeIn(self, t=0.5, finishIval=None, blendType='noBlend'): """ Play a fade in transition over t seconds. Places a polygon on the aspect2d plane then lerps the color @@ -159,13 +161,13 @@ class Transitions: else: # Create a sequence that lerps the color out, then # parents the fade to hidden - self.transitionIval = self.getFadeInIval(t, finishIval) + self.transitionIval = self.getFadeInIval(t, finishIval, blendType) self.transitionIval.append(Func(self.__finishTransition)) self.__transitionFuture = AsyncFuture() self.transitionIval.start() return self.__transitionFuture - def fadeOut(self, t=0.5, finishIval=None): + def fadeOut(self, t=0.5, finishIval=None, blendType='noBlend'): """ Play a fade out transition over t seconds. Places a polygon on the aspect2d plane then lerps the color @@ -189,7 +191,7 @@ class Transitions: else: # Create a sequence that lerps the color out, then # parents the fade to hidden - self.transitionIval = self.getFadeOutIval(t, finishIval) + self.transitionIval = self.getFadeOutIval(t, finishIval, blendType) self.transitionIval.append(Func(self.__finishTransition)) self.__transitionFuture = AsyncFuture() self.transitionIval.start() @@ -264,7 +266,7 @@ class Transitions: self.iris = loader.loadModel(self.IrisModelName) self.iris.setPos(0, 0, 0) - def irisIn(self, t=0.5, finishIval=None): + def irisIn(self, t=0.5, finishIval=None, blendType = 'noBlend'): """ Play an iris in transition over t seconds. Places a polygon on the aspect2d plane then lerps the scale @@ -284,7 +286,8 @@ class Transitions: scale = 0.18 * max(base.a2dRight, base.a2dTop) self.transitionIval = Sequence(LerpScaleInterval(self.iris, t, scale = scale, - startScale = 0.01), + startScale = 0.01, + blendType=blendType), Func(self.iris.detachNode), Func(self.__finishTransition), name = self.irisTaskName, @@ -295,7 +298,7 @@ class Transitions: self.transitionIval.start() return self.__transitionFuture - def irisOut(self, t=0.5, finishIval=None): + def irisOut(self, t=0.5, finishIval=None, blendType='noBlend'): """ Play an iris out transition over t seconds. Places a polygon on the aspect2d plane then lerps the scale @@ -318,7 +321,8 @@ class Transitions: scale = 0.18 * max(base.a2dRight, base.a2dTop) self.transitionIval = Sequence(LerpScaleInterval(self.iris, t, scale = 0.01, - startScale = scale), + startScale = scale, + blendType=blendType), Func(self.iris.detachNode), # Use the fade to cover up the hole that the iris would leave Func(self.fadeOut, 0), @@ -441,7 +445,7 @@ class Transitions: self.__letterboxFuture.setResult(None) self.__letterboxFuture = None - def letterboxOn(self, t=0.25, finishIval=None): + def letterboxOn(self, t=0.25, finishIval=None, blendType='noBlend'): """ Move black bars in over t seconds. """ @@ -461,11 +465,13 @@ class Transitions: t, pos = Vec3(0, 0, -1), #startPos = Vec3(0, 0, -1.2), + blendType=blendType ), LerpPosInterval(self.letterboxTop, t, pos = Vec3(0, 0, 0.8), # startPos = Vec3(0, 0, 1), + blendType=blendType ), ), Func(self.__finishLetterbox), @@ -476,7 +482,7 @@ class Transitions: self.letterboxIval.start() return self.__letterboxFuture - def letterboxOff(self, t=0.25, finishIval=None): + def letterboxOff(self, t=0.25, finishIval=None, blendType='noBlend'): """ Move black bars away over t seconds. """ @@ -495,11 +501,13 @@ class Transitions: t, pos = Vec3(0, 0, -1.2), # startPos = Vec3(0, 0, -1), + blendType=blendType ), LerpPosInterval(self.letterboxTop, t, pos = Vec3(0, 0, 1), # startPos = Vec3(0, 0, 0.8), + blendType=blendType ), ), Func(self.letterbox.stash), From ee318a73f3df14eccdefca1f5db34c354e94063a Mon Sep 17 00:00:00 2001 From: rdb Date: Wed, 8 Aug 2018 20:16:11 +0200 Subject: [PATCH 091/125] interval: prevent hypothetical stack overflow --- direct/src/interval/cMetaInterval.cxx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/direct/src/interval/cMetaInterval.cxx b/direct/src/interval/cMetaInterval.cxx index d43ea9cebf..08f8887706 100644 --- a/direct/src/interval/cMetaInterval.cxx +++ b/direct/src/interval/cMetaInterval.cxx @@ -679,7 +679,7 @@ write(std::ostream &out, int indent_level) const { int total_digits = num_decimals + 4; static const int max_digits = 32; // totally arbitrary nassertv(total_digits <= max_digits); - char format_str[12]; + char format_str[16]; sprintf(format_str, "%%%d.%df", total_digits, num_decimals); indent(out, indent_level) << get_name() << ":\n"; @@ -708,7 +708,7 @@ timeline(std::ostream &out) const { int total_digits = num_decimals + 4; static const int max_digits = 32; // totally arbitrary nassertv(total_digits <= max_digits); - char format_str[12]; + char format_str[16]; sprintf(format_str, "%%%d.%df", total_digits, num_decimals); int extra_indent_level = 0; From 433f734d43afe0a138b402afaf166778145dd4f6 Mon Sep 17 00:00:00 2001 From: rdb Date: Wed, 8 Aug 2018 20:18:37 +0200 Subject: [PATCH 092/125] mathutil: BoundingPlane improvements --- panda/src/mathutil/boundingHexahedron.cxx | 9 +++++++++ panda/src/mathutil/boundingHexahedron.h | 1 + panda/src/mathutil/boundingPlane.cxx | 24 ++++++++++++++++++++++- panda/src/mathutil/boundingPlane.h | 3 +++ 4 files changed, 36 insertions(+), 1 deletion(-) diff --git a/panda/src/mathutil/boundingHexahedron.cxx b/panda/src/mathutil/boundingHexahedron.cxx index 1e500cb64c..7046215821 100644 --- a/panda/src/mathutil/boundingHexahedron.cxx +++ b/panda/src/mathutil/boundingHexahedron.cxx @@ -14,6 +14,7 @@ #include "boundingHexahedron.h" #include "boundingSphere.h" #include "boundingBox.h" +#include "boundingPlane.h" #include "config_mathutil.h" #include @@ -356,6 +357,14 @@ contains_box(const BoundingBox *box) const { return result; } +/** + * + */ +int BoundingHexahedron:: +contains_plane(const BoundingPlane *plane) const { + return plane->contains_hexahedron(this) & ~IF_all; +} + /** * */ diff --git a/panda/src/mathutil/boundingHexahedron.h b/panda/src/mathutil/boundingHexahedron.h index ac87135509..de09e03dac 100644 --- a/panda/src/mathutil/boundingHexahedron.h +++ b/panda/src/mathutil/boundingHexahedron.h @@ -79,6 +79,7 @@ protected: virtual int contains_lineseg(const LPoint3 &a, const LPoint3 &b) const; virtual int contains_sphere(const BoundingSphere *sphere) const; virtual int contains_box(const BoundingBox *box) const; + virtual int contains_plane(const BoundingPlane *plane) const; virtual int contains_hexahedron(const BoundingHexahedron *hexahedron) const; private: diff --git a/panda/src/mathutil/boundingPlane.cxx b/panda/src/mathutil/boundingPlane.cxx index 9690bb8dae..5c2ee9b386 100644 --- a/panda/src/mathutil/boundingPlane.cxx +++ b/panda/src/mathutil/boundingPlane.cxx @@ -202,7 +202,29 @@ contains_line(const BoundingLine *line) const { */ int BoundingPlane:: contains_plane(const BoundingPlane *plane) const { - return IF_possible; + // We assume the plane normals are normalized. + LPlane other_plane = plane->get_plane(); + PN_stdfloat dot = _plane.get_normal().dot(other_plane.get_normal()); + if (dot >= 1.0) { + // The planes are parallel, with the same normal. + if (_plane.get_w() <= other_plane.get_w()) { + return IF_possible | IF_some | IF_all; + } else { + return IF_possible | IF_some; + } + + } else if (dot <= -1.0) { + // The planes are opposing. + if (_plane.get_w() >= -other_plane.get_w()) { + return IF_no_intersection; + } else { + return IF_possible | IF_some; + } + + } else { + // The planes are not parallel, so they inevitably intersect. + return IF_possible | IF_some; + } } /** diff --git a/panda/src/mathutil/boundingPlane.h b/panda/src/mathutil/boundingPlane.h index 82e02870a0..ecfdfea4ca 100644 --- a/panda/src/mathutil/boundingPlane.h +++ b/panda/src/mathutil/boundingPlane.h @@ -42,6 +42,8 @@ public: PUBLISHED: INLINE_MATHUTIL const LPlane &get_plane() const; + MAKE_PROPERTY(plane, get_plane); + public: virtual const BoundingPlane *as_bounding_plane() const; @@ -82,6 +84,7 @@ private: friend class BoundingSphere; friend class BoundingBox; + friend class BoundingHexahedron; }; #include "boundingPlane.I" From aa66d8313ee66c329fc49423a699c988d383eeda Mon Sep 17 00:00:00 2001 From: rdb Date: Wed, 8 Aug 2018 20:21:09 +0200 Subject: [PATCH 093/125] tests: add BoundingPlane unit tests --- tests/mathutil/test_bounding_plane.py | 64 +++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 tests/mathutil/test_bounding_plane.py diff --git a/tests/mathutil/test_bounding_plane.py b/tests/mathutil/test_bounding_plane.py new file mode 100644 index 0000000000..eeb9b2b11e --- /dev/null +++ b/tests/mathutil/test_bounding_plane.py @@ -0,0 +1,64 @@ +from panda3d.core import Plane, BoundingPlane, BoundingSphere, BoundingVolume + + +def test_plane_contains_sphere(): + plane = BoundingPlane((0, 0, 1, 0)) + + # Sphere above plane + assert plane.contains(BoundingSphere((0, 0, 2), 1)) == BoundingVolume.IF_no_intersection + + # Sphere intersecting surface of plane + assert plane.contains(BoundingSphere((0, 0, 0), 1)) == BoundingVolume.IF_possible | BoundingVolume.IF_some + + # Sphere below plane + assert plane.contains(BoundingSphere((0, 0, -2), 1)) == BoundingVolume.IF_possible | BoundingVolume.IF_some | BoundingVolume.IF_all + + +def test_plane_contains_plane(): + # Plane should always fully contain itself. + a = BoundingPlane((1, 0, 0, 1)) + assert a.contains(a) == BoundingVolume.IF_possible | BoundingVolume.IF_some | BoundingVolume.IF_all + + # Plane with its mirror image + a = BoundingPlane((1, 0, 0, 1)) + b = BoundingPlane((-1, 0, 0, -1)) + assert a.contains(b) == BoundingVolume.IF_no_intersection + assert b.contains(a) == BoundingVolume.IF_no_intersection + + # One plane above the other + a = BoundingPlane(Plane((1, 0, 0), (1, 0, 0))) + b = BoundingPlane(Plane((1, 0, 0), (2, 0, 0))) + assert a.contains(b) == BoundingVolume.IF_possible | BoundingVolume.IF_some + assert b.contains(a) == BoundingVolume.IF_possible | BoundingVolume.IF_some | BoundingVolume.IF_all + + # Opposing planes with distance between them. + a = BoundingPlane(Plane((1, 0, 0), (1, 0, 0))) + b = BoundingPlane(Plane((-1, 0, 0), (2, 0, 0))) + assert a.contains(b) == BoundingVolume.IF_no_intersection + assert b.contains(a) == BoundingVolume.IF_no_intersection + + # Planes overlapping in the same axis. + a = BoundingPlane(Plane((1, 0, 0), (2, 0, 0))) + b = BoundingPlane(Plane((-1, 0, 0), (1, 0, 0))) + assert a.contains(b) == BoundingVolume.IF_possible | BoundingVolume.IF_some + assert b.contains(a) == BoundingVolume.IF_possible | BoundingVolume.IF_some + + # Planes overlapping due to not sharing a normal vector. + a = BoundingPlane(Plane((1, 0, 0), (2, 0, 0))) + b = BoundingPlane(Plane((0.8, 0.6, 0), (4, 0, 0))) + assert a.contains(b) == BoundingVolume.IF_possible | BoundingVolume.IF_some + assert b.contains(a) == BoundingVolume.IF_possible | BoundingVolume.IF_some + + # Same as above. + a = BoundingPlane(Plane((1, 0, 0), (2, 0, 0))) + b = BoundingPlane(Plane((-0.8, -0.6, 0), (4, 0, 0))) + assert a.contains(b) == BoundingVolume.IF_possible | BoundingVolume.IF_some + assert b.contains(a) == BoundingVolume.IF_possible | BoundingVolume.IF_some + + # Planes pointing along different major axes. + a = BoundingPlane(Plane((1, 0, 0, 0))) + b = BoundingPlane(Plane((0, 1, 0, 0))) + c = BoundingPlane(Plane((0, 0, 1, 0))) + assert a.contains(b) == BoundingVolume.IF_possible | BoundingVolume.IF_some + assert b.contains(c) == BoundingVolume.IF_possible | BoundingVolume.IF_some + assert a.contains(c) == BoundingVolume.IF_possible | BoundingVolume.IF_some From eb0f753a3c59fcbe70448c10ca538837746d9d63 Mon Sep 17 00:00:00 2001 From: deflected Date: Wed, 8 Aug 2018 21:26:28 +0200 Subject: [PATCH 094/125] x11display: fix loading cursor from compressed/encrypted stream --- panda/src/x11display/x11GraphicsWindow.cxx | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/panda/src/x11display/x11GraphicsWindow.cxx b/panda/src/x11display/x11GraphicsWindow.cxx index 45c04909a2..17f6ca0a2a 100644 --- a/panda/src/x11display/x11GraphicsWindow.cxx +++ b/panda/src/x11display/x11GraphicsWindow.cxx @@ -2193,7 +2193,13 @@ get_cursor(const Filename &filename) { << "Could not read from cursor file " << filename << "\n"; return None; } - str->seekg(0, istream::beg); + + // Put back the read bytes. Do not use seekg, because this will + // corrupt the stream if it points to encrypted/compressed file + str->putback(magic[3]); + str->putback(magic[2]); + str->putback(magic[1]); + str->putback(magic[0]); X11_Cursor h = None; if (memcmp(magic, "Xcur", 4) == 0) { From 4ff619b75fab6b80cd6fe717effbef1c4c3d8723 Mon Sep 17 00:00:00 2001 From: rdb Date: Thu, 9 Aug 2018 14:56:40 +0200 Subject: [PATCH 095/125] pystub: fix some definitions that should be variables, not funcs This is needed to compile Panda3D with -flto. --- dtool/src/pystub/pystub.cxx | 37 ++++++++++++++++++------------------- 1 file changed, 18 insertions(+), 19 deletions(-) diff --git a/dtool/src/pystub/pystub.cxx b/dtool/src/pystub/pystub.cxx index ac6586c6ff..b2e9d4d62f 100644 --- a/dtool/src/pystub/pystub.cxx +++ b/dtool/src/pystub/pystub.cxx @@ -36,7 +36,6 @@ extern "C" { EXPCL_PYSTUB int PyDict_SetItem(...); EXPCL_PYSTUB int PyDict_SetItemString(...); EXPCL_PYSTUB int PyDict_Size(...); - EXPCL_PYSTUB int PyDict_Type(...); EXPCL_PYSTUB int PyErr_Clear(...); EXPCL_PYSTUB int PyErr_ExceptionMatches(...); EXPCL_PYSTUB int PyErr_Fetch(...); @@ -54,9 +53,7 @@ extern "C" { EXPCL_PYSTUB int PyEval_SaveThread(...); EXPCL_PYSTUB int PyFloat_AsDouble(...); EXPCL_PYSTUB int PyFloat_FromDouble(...); - EXPCL_PYSTUB int PyFloat_Type(...); EXPCL_PYSTUB int PyGen_Check(...); - EXPCL_PYSTUB int PyGen_Type(...); EXPCL_PYSTUB int PyGILState_Ensure(...); EXPCL_PYSTUB int PyGILState_Release(...); EXPCL_PYSTUB int PyImport_GetModuleDict(...); @@ -65,14 +62,12 @@ extern "C" { EXPCL_PYSTUB int PyInt_AsSsize_t(...); EXPCL_PYSTUB int PyInt_FromLong(...); EXPCL_PYSTUB int PyInt_FromSize_t(...); - EXPCL_PYSTUB int PyInt_Type(...); EXPCL_PYSTUB int PyIter_Next(...); EXPCL_PYSTUB int PyList_Append(...); EXPCL_PYSTUB int PyList_AsTuple(...); EXPCL_PYSTUB int PyList_GetItem(...); EXPCL_PYSTUB int PyList_New(...); EXPCL_PYSTUB int PyList_SetItem(...); - EXPCL_PYSTUB int PyList_Type(...); EXPCL_PYSTUB int PyLong_AsLong(...); EXPCL_PYSTUB int PyLong_AsLongLong(...); EXPCL_PYSTUB int PyLong_AsSsize_t(...); @@ -83,7 +78,6 @@ extern "C" { EXPCL_PYSTUB int PyLong_FromSize_t(...); EXPCL_PYSTUB int PyLong_FromUnsignedLong(...); EXPCL_PYSTUB int PyLong_FromUnsignedLongLong(...); - EXPCL_PYSTUB int PyLong_Type(...); EXPCL_PYSTUB int PyMapping_GetItemString(...); EXPCL_PYSTUB int PyMem_Free(...); EXPCL_PYSTUB int PyMemoryView_FromObject(...); @@ -124,7 +118,6 @@ extern "C" { EXPCL_PYSTUB int PyObject_SetAttr(...); EXPCL_PYSTUB int PyObject_SetAttrString(...); EXPCL_PYSTUB int PyObject_Str(...); - EXPCL_PYSTUB int PyObject_Type(...); EXPCL_PYSTUB int PySeqIter_New(...); EXPCL_PYSTUB int PySequence_Check(...); EXPCL_PYSTUB int PySequence_Fast(...); @@ -139,7 +132,6 @@ extern "C" { EXPCL_PYSTUB int PyString_InternFromString(...); EXPCL_PYSTUB int PyString_InternInPlace(...); EXPCL_PYSTUB int PyString_Size(...); - EXPCL_PYSTUB int PyString_Type(...); EXPCL_PYSTUB int PySys_GetObject(...); EXPCL_PYSTUB int PyThreadState_Clear(...); EXPCL_PYSTUB int PyThreadState_Delete(...); @@ -181,7 +173,6 @@ extern "C" { EXPCL_PYSTUB int PyUnicode_GetSize(...); EXPCL_PYSTUB int PyUnicode_InternFromString(...); EXPCL_PYSTUB int PyUnicode_InternInPlace(...); - EXPCL_PYSTUB int PyUnicode_Type(...); EXPCL_PYSTUB int Py_BuildValue(...); EXPCL_PYSTUB int Py_GetVersion(...); EXPCL_PYSTUB int Py_InitModule4(...); @@ -233,8 +224,17 @@ extern "C" { EXPCL_PYSTUB extern void *PyExc_SystemExit; EXPCL_PYSTUB extern void *PyExc_TypeError; EXPCL_PYSTUB extern void *PyExc_ValueError; + EXPCL_PYSTUB extern void *PyDict_Type; + EXPCL_PYSTUB extern void *PyFloat_Type; + EXPCL_PYSTUB extern void *PyGen_Type; + EXPCL_PYSTUB extern void *PyInt_Type; + EXPCL_PYSTUB extern void *PyList_Type; + EXPCL_PYSTUB extern void *PyLong_Type; + EXPCL_PYSTUB extern void *PyObject_Type; + EXPCL_PYSTUB extern void *PyString_Type; EXPCL_PYSTUB extern void *PyTuple_Type; EXPCL_PYSTUB extern void *PyType_Type; + EXPCL_PYSTUB extern void *PyUnicode_Type; EXPCL_PYSTUB extern void *_PyThreadState_Current; EXPCL_PYSTUB extern void *_Py_FalseStruct; EXPCL_PYSTUB extern void *_Py_NoneStruct; @@ -266,7 +266,6 @@ int PyDict_Next(...) { return 0; }; int PyDict_SetItem(...) { return 0; }; int PyDict_SetItemString(...) { return 0; }; int PyDict_Size(...){ return 0; } -int PyDict_Type(...) { return 0; }; int PyErr_Clear(...) { return 0; }; int PyErr_ExceptionMatches(...) { return 0; }; int PyErr_Fetch(...) { return 0; } @@ -285,9 +284,7 @@ int PyEval_RestoreThread(...) { return 0; } int PyEval_SaveThread(...) { return 0; } int PyFloat_AsDouble(...) { return 0; } int PyFloat_FromDouble(...) { return 0; } -int PyFloat_Type(...) { return 0; } int PyGen_Check(...) { return 0; } -int PyGen_Type(...) { return 0; } int PyGILState_Ensure(...) { return 0; } int PyGILState_Release(...) { return 0; } int PyImport_GetModuleDict(...) { return 0; } @@ -296,14 +293,12 @@ int PyInt_AsLong(...) { return 0; } int PyInt_AsSsize_t(...) { return 0; } int PyInt_FromLong(...) { return 0; } int PyInt_FromSize_t(...) { return 0; } -int PyInt_Type(...) { return 0; } int PyIter_Next(...) { return 0; } int PyList_Append(...) { return 0; } int PyList_AsTuple(...) { return 0; } int PyList_GetItem(...) { return 0; } int PyList_New(...) { return 0; } int PyList_SetItem(...) { return 0; } -int PyList_Type(...) { return 0; } int PyLong_AsLong(...) { return 0; } int PyLong_AsLongLong(...) { return 0; } int PyLong_AsSsize_t(...) { return 0; } @@ -314,7 +309,6 @@ int PyLong_FromLongLong(...) { return 0; } int PyLong_FromSize_t(...) { return 0; } int PyLong_FromUnsignedLong(...) { return 0; } int PyLong_FromUnsignedLongLong(...) { return 0; } -int PyLong_Type(...) { return 0; } int PyMapping_GetItemString(...) { return 0; } int PyMem_Free(...) { return 0; } int PyMemoryView_FromObject(...) { return 0; } @@ -355,7 +349,6 @@ int PyObject_SelfIter(...) { return 0; } int PyObject_SetAttr(...) { return 0; } int PyObject_SetAttrString(...) { return 0; } int PyObject_Str(...) { return 0; } -int PyObject_Type(...) { return 0; } int PySeqIter_New(...) { return 0; } int PySequence_Check(...) { return 0; } int PySequence_Fast(...) { return 0; } @@ -369,8 +362,6 @@ int PyString_FromString(...) { return 0; } int PyString_FromStringAndSize(...) { return 0; } int PyString_InternFromString(...) { return 0; } int PyString_InternInPlace(...) { return 0; } -int PyString_Size(...) { return 0; } -int PyString_Type(...) { return 0; } int PySys_GetObject(...) { return 0; } int PyThreadState_Clear(...) { return 0; } int PyThreadState_Delete(...) { return 0; } @@ -412,7 +403,6 @@ int PyUnicode_FromWideChar(...) { return 0; } int PyUnicode_GetSize(...) { return 0; } int PyUnicode_InternFromString(...) { return 0; } int PyUnicode_InternInPlace(...) { return 0; } -int PyUnicode_Type(...) { return 0; } int Py_GetVersion(...) { return 0; } int Py_BuildValue(...) { return 0; } int Py_InitModule4(...) { return 0; } @@ -470,8 +460,17 @@ void *PyExc_StopIteration = nullptr; void *PyExc_SystemExit = nullptr; void *PyExc_TypeError = nullptr; void *PyExc_ValueError = nullptr; +void *PyDict_Type = nullptr; +void *PyFloat_Type = nullptr; +void *PyGen_Type = nullptr; +void *PyInt_Type = nullptr; +void *PyList_Type = nullptr; +void *PyLong_Type = nullptr; +void *PyObject_Type = nullptr; +void *PyString_Type = nullptr; void *PyTuple_Type = nullptr; void *PyType_Type = nullptr; +void *PyUnicode_Type = nullptr; void *_PyThreadState_Current = nullptr; void *_Py_FalseStruct = nullptr; void *_Py_NoneStruct = nullptr; From be19411cf894b480b37575a4e43e9085c9aff7c3 Mon Sep 17 00:00:00 2001 From: rdb Date: Fri, 10 Aug 2018 14:28:02 +0200 Subject: [PATCH 096/125] Add support for Maya 2018 --- makepanda/makepandacore.py | 3 ++- pandatool/src/maya/mayaShader.h | 1 - pandatool/src/maya/mayaShaderColorDef.cxx | 16 +++++++++++----- pandatool/src/maya/mayaShaderColorDef.h | 2 -- pandatool/src/maya/mayaShaders.h | 1 - pandatool/src/maya/maya_funcs.h | 1 - pandatool/src/maya/pre_maya_include.h | 17 +++++++++++++++++ pandatool/src/mayaegg/mayaToEggConverter.cxx | 17 +++++++++++------ pandatool/src/mayaegg/mayaToEggConverter.h | 9 --------- pandatool/src/mayaprogs/mayaCopy.cxx | 3 ++- pandatool/src/mayaprogs/mayaCopy.h | 8 ++++++-- pandatool/src/mayaprogs/mayapath.cxx | 1 + 12 files changed, 50 insertions(+), 29 deletions(-) diff --git a/makepanda/makepandacore.py b/makepanda/makepandacore.py index f738d8affa..76dec39406 100644 --- a/makepanda/makepandacore.py +++ b/makepanda/makepandacore.py @@ -102,7 +102,8 @@ MAYAVERSIONINFO = [("MAYA6", "6.0"), ("MAYA2015","2015"), ("MAYA2016","2016"), ("MAYA20165","2016.5"), - ("MAYA2017","2017") + ("MAYA2017","2017"), + ("MAYA2018","2018"), ] MAXVERSIONINFO = [("MAX6", "SOFTWARE\\Autodesk\\3DSMAX\\6.0", "installdir", "maxsdk\\cssdk\\include"), diff --git a/pandatool/src/maya/mayaShader.h b/pandatool/src/maya/mayaShader.h index 41c9bdf77f..34ff13a808 100644 --- a/pandatool/src/maya/mayaShader.h +++ b/pandatool/src/maya/mayaShader.h @@ -21,7 +21,6 @@ #include "lmatrix.h" #include "namable.h" -class MObject; /** * Corresponds to a single "shader" in Maya. This extracts out all the diff --git a/pandatool/src/maya/mayaShaderColorDef.cxx b/pandatool/src/maya/mayaShaderColorDef.cxx index 73d2978d7c..cbaa82d5b7 100644 --- a/pandatool/src/maya/mayaShaderColorDef.cxx +++ b/pandatool/src/maya/mayaShaderColorDef.cxx @@ -367,15 +367,17 @@ find_textures_legacy(MayaShader *shader, MObject color, bool trans) { if (li > -1) { // found a blend mode if (maya_cat.is_spam()) { + MString name = inputsPlug.name(); maya_cat.spam() << "*** Start doIt... ***" << endl; - maya_cat.spam() << "inputsPlug Name: " << inputsPlug.name() << endl; + maya_cat.spam() << "inputsPlug Name: " << name.asChar() << endl; } status = blendModePlug.selectAncestorLogicalIndex(li,inputsPlug); blendModePlug.getValue(blendValue); if (maya_cat.is_spam()) { + MString name = blendModePlug.name(); maya_cat.spam() - << blendModePlug.name() << ": has value " << blendValue << endl; + << name.asChar() << ": has value " << blendValue << endl; } MFnEnumAttribute blendModeEnum(blendModePlug); @@ -397,9 +399,13 @@ find_textures_legacy(MayaShader *shader, MObject color, bool trans) { bt = BT_add; break; } - maya_cat.info() << layered_fn.name() << ": blendMode used " << blendName << endl; - if (maya_cat.is_spam()) { - maya_cat.spam() << "*** END doIt... ***" << endl; + + if (maya_cat.is_info()) { + MString name = layered_fn.name(); + maya_cat.info() << name.asChar() << ": blendMode used " << blendName.asChar() << endl; + if (maya_cat.is_spam()) { + maya_cat.spam() << "*** END doIt... ***" << endl; + } } // advance to the next plug, because that is where the shader info are diff --git a/pandatool/src/maya/mayaShaderColorDef.h b/pandatool/src/maya/mayaShaderColorDef.h index ca2d532f13..2609f2bb43 100644 --- a/pandatool/src/maya/mayaShaderColorDef.h +++ b/pandatool/src/maya/mayaShaderColorDef.h @@ -21,8 +21,6 @@ #include "pmap.h" #include "pvector.h" -class MObject; -class MPlug; class MayaShader; class MayaShaderColorDef; typedef pvector MayaShaderColorList; diff --git a/pandatool/src/maya/mayaShaders.h b/pandatool/src/maya/mayaShaders.h index f1c107a755..5428ab5f73 100644 --- a/pandatool/src/maya/mayaShaders.h +++ b/pandatool/src/maya/mayaShaders.h @@ -21,7 +21,6 @@ #include "mayaShaderColorDef.h" class MayaShader; -class MObject; /** * Collects the set of MayaShaders that have been encountered so far. diff --git a/pandatool/src/maya/maya_funcs.h b/pandatool/src/maya/maya_funcs.h index 2966fef9e3..ad0a7210b3 100644 --- a/pandatool/src/maya/maya_funcs.h +++ b/pandatool/src/maya/maya_funcs.h @@ -28,7 +28,6 @@ #include #include "post_maya_include.h" -class MObject; bool get_maya_plug(MObject &node, const std::string &attribute_name, MPlug &plug); diff --git a/pandatool/src/maya/pre_maya_include.h b/pandatool/src/maya/pre_maya_include.h index 0244ec7ba4..85442c1e7b 100644 --- a/pandatool/src/maya/pre_maya_include.h +++ b/pandatool/src/maya/pre_maya_include.h @@ -43,4 +43,21 @@ #if MAYA_API_VERSION < 201600 #include #endif +#else +// This defines MAYA_API_VERSION +#include +#endif + +#if MAYA_API_VERSION >= 20180000 +#include +#else +class MObject; +class MDagPath; +class MFloatArray; +class MFnDagNode; +class MFnMesh; +class MFnNurbsCurve; +class MFnNurbsSurface; +class MPlug; +class MPointArray; #endif diff --git a/pandatool/src/mayaegg/mayaToEggConverter.cxx b/pandatool/src/mayaegg/mayaToEggConverter.cxx index 7943f07f03..747c8ac279 100644 --- a/pandatool/src/mayaegg/mayaToEggConverter.cxx +++ b/pandatool/src/mayaegg/mayaToEggConverter.cxx @@ -838,12 +838,14 @@ process_model_node(MayaNodeDesc *node_desc) { // Extract some interesting Camera data if (mayaegg_cat.is_spam()) { MPoint eyePoint = camera.eyePoint(MSpace::kWorld); + MVector upDirection = camera.upDirection(MSpace::kWorld); + MVector viewDirection = camera.viewDirection(MSpace::kWorld); mayaegg_cat.spam() << " eyePoint: " << eyePoint.x << " " << eyePoint.y << " " << eyePoint.z << endl; - mayaegg_cat.spam() << " upDirection: " - << camera.upDirection(MSpace::kWorld) << endl; - mayaegg_cat.spam() << " viewDirection: " - << camera.viewDirection(MSpace::kWorld) << endl; + mayaegg_cat.spam() << " upDirection: " << upDirection.x << " " + << upDirection.y << " " << upDirection.z << endl; + mayaegg_cat.spam() << " viewDirection: " << viewDirection.x << " " + << viewDirection.y << " " << viewDirection.z << endl; mayaegg_cat.spam() << " aspectRatio: " << camera.aspectRatio() << endl; mayaegg_cat.spam() << " horizontalFilmAperture: " << camera.horizontalFilmAperture() << endl; @@ -922,9 +924,12 @@ process_model_node(MayaNodeDesc *node_desc) { mayaegg_cat.error() << "light extraction failed" << endl; return false; } - mayaegg_cat.info() << "-- Light found -- tranlations in cm, rotations in rads\n"; - mayaegg_cat.info() << "\"" << dag_path.partialPathName() << "\" : \n"; + if (mayaegg_cat.is_info()) { + MString name = dag_path.partialPathName(); + mayaegg_cat.info() << "-- Light found -- tranlations in cm, rotations in rads\n"; + mayaegg_cat.info() << "\"" << name.asChar() << "\" : \n"; + } // Get the translationrotationscale data MObject transformNode = dag_path.transform(&status); diff --git a/pandatool/src/mayaegg/mayaToEggConverter.h b/pandatool/src/mayaegg/mayaToEggConverter.h index 3e3782a601..c2266e0096 100644 --- a/pandatool/src/mayaegg/mayaToEggConverter.h +++ b/pandatool/src/mayaegg/mayaToEggConverter.h @@ -42,15 +42,6 @@ class EggPrimitive; class EggXfmSAnim; class MayaShaderColorDef; -class MObject; -class MDagPath; -class MFnDagNode; -class MFnNurbsSurface; -class MFnNurbsCurve; -class MFnMesh; -class MPointArray; -class MFloatArray; - /** * This class supervises the construction of an EggData structure from a * single Maya file, or from the data already in the global Maya model space. diff --git a/pandatool/src/mayaprogs/mayaCopy.cxx b/pandatool/src/mayaprogs/mayaCopy.cxx index 247e0b43ad..d10ed8e0aa 100644 --- a/pandatool/src/mayaprogs/mayaCopy.cxx +++ b/pandatool/src/mayaprogs/mayaCopy.cxx @@ -16,7 +16,6 @@ #include "mayaCopy.h" #include "config_maya.h" #include "cvsSourceDirectory.h" -#include "mayaShader.h" #include "dcast.h" #include "pre_maya_include.h" @@ -32,6 +31,8 @@ #include #include "post_maya_include.h" +#include "mayaShader.h" + using std::endl; using std::string; diff --git a/pandatool/src/mayaprogs/mayaCopy.h b/pandatool/src/mayaprogs/mayaCopy.h index 90ceddfbc0..38f0aef9de 100644 --- a/pandatool/src/mayaprogs/mayaCopy.h +++ b/pandatool/src/mayaprogs/mayaCopy.h @@ -17,15 +17,19 @@ #include "pandatoolbase.h" #include "cvsCopy.h" #include "mayaApi.h" -#include "mayaShaders.h" #include "dSearchPath.h" #include "pointerTo.h" #include "pset.h" +#include "pre_maya_include.h" +#include +#include "post_maya_include.h" + +#include "mayaShaders.h" + class MayaShader; class MayaShaderColorDef; -class MDagPath; /** * A program to copy Maya .mb files into the cvs tree. diff --git a/pandatool/src/mayaprogs/mayapath.cxx b/pandatool/src/mayaprogs/mayapath.cxx index ae9ad39ac2..441a22c0e2 100644 --- a/pandatool/src/mayaprogs/mayapath.cxx +++ b/pandatool/src/mayaprogs/mayapath.cxx @@ -105,6 +105,7 @@ struct MayaVerInfo maya_versions[] = { { "MAYA2016", "2016"}, { "MAYA20165", "2016.5"}, { "MAYA2017", "2017"}, + { "MAYA2018", "2018"}, { 0, 0 }, }; From e99f8a7bcc709e4de9a3031b1fab6478e5b6e1ff Mon Sep 17 00:00:00 2001 From: John Cote Date: Fri, 10 Aug 2018 23:10:22 +0200 Subject: [PATCH 097/125] sceneeditor: clean up scene editor code, removing deprecated calls Closes #373 --- contrib/src/sceneeditor/collisionWindow.py | 2 +- contrib/src/sceneeditor/lightingPanel.py | 2 +- contrib/src/sceneeditor/propertyWindow.py | 2 +- contrib/src/sceneeditor/quad.py | 4 +-- contrib/src/sceneeditor/sceneEditor.py | 13 +++++--- contrib/src/sceneeditor/seCameraControl.py | 3 +- contrib/src/sceneeditor/seFileSaver.py | 2 +- contrib/src/sceneeditor/seForceGroup.py | 4 +-- contrib/src/sceneeditor/seGeometry.py | 2 +- contrib/src/sceneeditor/seLights.py | 2 +- contrib/src/sceneeditor/seManipulation.py | 2 +- contrib/src/sceneeditor/seMopathRecorder.py | 30 +++++++++---------- contrib/src/sceneeditor/seParticleEffect.py | 2 +- contrib/src/sceneeditor/seParticles.py | 24 ++------------- contrib/src/sceneeditor/sePlacer.py | 8 ++--- .../src/sceneeditor/seSceneGraphExplorer.py | 4 +-- contrib/src/sceneeditor/seSelection.py | 23 +++++++++----- contrib/src/sceneeditor/seSession.py | 9 ++++-- contrib/src/sceneeditor/seTree.py | 2 +- 19 files changed, 66 insertions(+), 74 deletions(-) diff --git a/contrib/src/sceneeditor/collisionWindow.py b/contrib/src/sceneeditor/collisionWindow.py index 7122e801bb..3c6b70e607 100644 --- a/contrib/src/sceneeditor/collisionWindow.py +++ b/contrib/src/sceneeditor/collisionWindow.py @@ -11,7 +11,7 @@ from direct.tkwidgets import Floater from direct.tkwidgets import Slider from Tkinter import * import string, math, types -from pandac.PandaModules import * +from panda3d.core import * class collisionWindow(AppShell): diff --git a/contrib/src/sceneeditor/lightingPanel.py b/contrib/src/sceneeditor/lightingPanel.py index edca358d61..729186a78d 100644 --- a/contrib/src/sceneeditor/lightingPanel.py +++ b/contrib/src/sceneeditor/lightingPanel.py @@ -9,7 +9,7 @@ from direct.tkwidgets.VectorWidgets import Vector3Entry from direct.tkwidgets.Slider import Slider from Tkinter import Frame, Button, Menubutton, Menu import string, math, types, Pmw, Tkinter -from pandac.PandaModules import * +from panda3d.core import * class lightingPanel(AppShell): ################################################################# diff --git a/contrib/src/sceneeditor/propertyWindow.py b/contrib/src/sceneeditor/propertyWindow.py index 35f239eee5..7406d33ffa 100644 --- a/contrib/src/sceneeditor/propertyWindow.py +++ b/contrib/src/sceneeditor/propertyWindow.py @@ -11,7 +11,7 @@ from direct.tkwidgets import Floater from direct.tkwidgets import Dial from direct.tkwidgets import Slider from direct.tkwidgets import VectorWidgets -from pandac.PandaModules import * +from panda3d.core import * from Tkinter import * import Pmw diff --git a/contrib/src/sceneeditor/quad.py b/contrib/src/sceneeditor/quad.py index 47524739ae..329dcb92a3 100644 --- a/contrib/src/sceneeditor/quad.py +++ b/contrib/src/sceneeditor/quad.py @@ -9,10 +9,8 @@ from direct.showbase.ShowBaseGlobal import * from direct.interval.IntervalGlobal import * from direct.showbase.DirectObject import DirectObject -from pandac.PandaModules import * +from panda3d.core import * import math -#Manakel 2/12/2005: replace from pandac import by from pandac.PandaModules import -from pandac.PandaModules import MouseWatcher class ViewPort: diff --git a/contrib/src/sceneeditor/sceneEditor.py b/contrib/src/sceneeditor/sceneEditor.py index ca35baa92b..37d05c3a08 100644 --- a/contrib/src/sceneeditor/sceneEditor.py +++ b/contrib/src/sceneeditor/sceneEditor.py @@ -3,8 +3,10 @@ import sys try: import _tkinter except: sys.exit("Please install python module 'Tkinter'") -import direct -from direct.directbase.DirectStart import* +from direct.showbase.ShowBase import ShowBase + +ShowBase() + from direct.showbase.TkGlobal import spawnTkLoop from Tkinter import * from tkFileDialog import * @@ -251,7 +253,10 @@ class myLevelEditor(AppShell): for event in self.actionEvents: self.accept(event[0], event[1], extraArgs = event[2:]) - camera.toggleVis() + if camera.is_hidden(): + camera.show() + else: + camera.hide() self.selectNode(base.camera) ## Initially, we select camera as the first node... def appInit(self): @@ -1705,4 +1710,4 @@ class myLevelEditor(AppShell): editor = myLevelEditor(parent = base.tkRoot) -run() +base.run() diff --git a/contrib/src/sceneeditor/seCameraControl.py b/contrib/src/sceneeditor/seCameraControl.py index 31ab30ee9f..721ebe9c31 100644 --- a/contrib/src/sceneeditor/seCameraControl.py +++ b/contrib/src/sceneeditor/seCameraControl.py @@ -392,8 +392,7 @@ class DirectCameraControl(DirectObject): sf = 0.1 self.coaMarker.setScale(sf) # Lerp color to fade out - self.coaMarker.lerpColor(VBase4(1,0,0,1), VBase4(1,0,0,0), 3.0, - task = 'fadeAway') + self.coaMarker.colorInterval(3.0, VBase4(1, 0, 0, 0), name='fadeAway').start() def homeCam(self): # Record undo point diff --git a/contrib/src/sceneeditor/seFileSaver.py b/contrib/src/sceneeditor/seFileSaver.py index 317c9427f2..0b2e088e12 100644 --- a/contrib/src/sceneeditor/seFileSaver.py +++ b/contrib/src/sceneeditor/seFileSaver.py @@ -3,7 +3,7 @@ # This code saves the scene out as python code... the scene is stored in the various dictionaries in "dataHolder.py" ...the class "AllScene" # #################################################################################################################################################### -from pandac.PandaModules import * +from panda3d.core import * from direct.showbase.ShowBaseGlobal import * import os diff --git a/contrib/src/sceneeditor/seForceGroup.py b/contrib/src/sceneeditor/seForceGroup.py index 7d27c78ebd..87c08a4904 100644 --- a/contrib/src/sceneeditor/seForceGroup.py +++ b/contrib/src/sceneeditor/seForceGroup.py @@ -1,8 +1,6 @@ -from pandac.PandaModules import * +from panda3d.core import * from direct.showbase.DirectObject import DirectObject from direct.showbase.PhysicsManagerGlobal import * -#Manakel 2/12/2005: replace from pandac import by from pandac.PandaModules import -from pandac.PandaModules import ForceNode from direct.directnotify import DirectNotifyGlobal import sys diff --git a/contrib/src/sceneeditor/seGeometry.py b/contrib/src/sceneeditor/seGeometry.py index 79115e5531..4074c986a2 100644 --- a/contrib/src/sceneeditor/seGeometry.py +++ b/contrib/src/sceneeditor/seGeometry.py @@ -12,7 +12,7 @@ # ################################################################# -from pandac.PandaModules import * +from panda3d.core import * from direct.directtools.DirectGlobals import * from direct.directtools.DirectUtil import * import math diff --git a/contrib/src/sceneeditor/seLights.py b/contrib/src/sceneeditor/seLights.py index ccc58ce0cd..09c5b2140a 100644 --- a/contrib/src/sceneeditor/seLights.py +++ b/contrib/src/sceneeditor/seLights.py @@ -5,7 +5,7 @@ from direct.showbase.DirectObject import * from string import lower from direct.directtools import DirectUtil -from pandac.PandaModules import * +from panda3d.core import * import string diff --git a/contrib/src/sceneeditor/seManipulation.py b/contrib/src/sceneeditor/seManipulation.py index e4d50d81dc..4d0c781b1e 100644 --- a/contrib/src/sceneeditor/seManipulation.py +++ b/contrib/src/sceneeditor/seManipulation.py @@ -520,7 +520,7 @@ class ObjectHandles(NodePath,DirectObject): # To avoid recreating a vec every frame self.hitPt = Vec3(0) # Get a handle on the components - self.xHandles = self.find('**/X') + self.xHandles = self.find('**/ohScalingNode') self.xPostGroup = self.xHandles.find('**/x-post-group') self.xPostCollision = self.xHandles.find('**/x-post') self.xRingGroup = self.xHandles.find('**/x-ring-group') diff --git a/contrib/src/sceneeditor/seMopathRecorder.py b/contrib/src/sceneeditor/seMopathRecorder.py index 7ba2ee52d7..0f856237d2 100644 --- a/contrib/src/sceneeditor/seMopathRecorder.py +++ b/contrib/src/sceneeditor/seMopathRecorder.py @@ -682,16 +682,16 @@ class MopathRecorder(AppShell, DirectObject): marker if subnode selected """ taskMgr.remove(self.name + '-curveEditTask') - print nodePath.id() - if nodePath.id() in self.playbackMarkerIds: + print nodePath.get_key() + if nodePath.get_key() in self.playbackMarkerIds: SEditor.select(self.playbackMarker) - elif nodePath.id() in self.tangentMarkerIds: + elif nodePath.get_key() in self.tangentMarkerIds: SEditor.select(self.tangentMarker) - elif nodePath.id() == self.playbackMarker.id(): + elif nodePath.get_key() == self.playbackMarker.get_key(): self.tangentGroup.show() taskMgr.add(self.curveEditTask, self.name + '-curveEditTask') - elif nodePath.id() == self.tangentMarker.id(): + elif nodePath.get_key() == self.tangentMarker.get_key(): self.tangentGroup.show() taskMgr.add(self.curveEditTask, self.name + '-curveEditTask') @@ -699,7 +699,7 @@ class MopathRecorder(AppShell, DirectObject): self.tangentGroup.hide() def getChildIds(self, nodePath): - ids = [nodePath.id()] + ids = [nodePath.get_key()] kids = nodePath.getChildren() for kid in kids: ids += self.getChildIds(kid) @@ -710,14 +710,14 @@ class MopathRecorder(AppShell, DirectObject): Hook called upon deselection of a node path used to select playback marker if subnode selected """ - if ((nodePath.id() == self.playbackMarker.id()) or - (nodePath.id() == self.tangentMarker.id())): + if ((nodePath.get_key() == self.playbackMarker.get_key()) or + (nodePath.get_key() == self.tangentMarker.get_key())): self.tangentGroup.hide() def curveEditTask(self,state): if self.curveCollection != None: # Update curve position - if self.manipulandumId == self.playbackMarker.id(): + if self.manipulandumId == self.playbackMarker.get_key(): # Show playback marker self.playbackMarker.getChild(0).show() pos = Point3(0) @@ -731,7 +731,7 @@ class MopathRecorder(AppShell, DirectObject): # Note: this calls recompute on the curves self.nurbsCurveDrawer.draw() # Update tangent - if self.manipulandumId == self.tangentMarker.id(): + if self.manipulandumId == self.tangentMarker.get_key(): # If manipulating marker, update tangent # Hide playback marker self.playbackMarker.getChild(0).hide() @@ -766,10 +766,10 @@ class MopathRecorder(AppShell, DirectObject): def manipulateObjectStartHook(self): self.manipulandumId = None if SEditor.selected.last: - if SEditor.selected.last.id() == self.playbackMarker.id(): - self.manipulandumId = self.playbackMarker.id() - elif SEditor.selected.last.id() == self.tangentMarker.id(): - self.manipulandumId = self.tangentMarker.id() + if SEditor.selected.last.get_key() == self.playbackMarker.get_key(): + self.manipulandumId = self.playbackMarker.get_key() + elif SEditor.selected.last.get_key() == self.tangentMarker.get_key(): + self.manipulandumId = self.tangentMarker.get_key() def manipulateObjectCleanupHook(self): # Clear flag @@ -1282,7 +1282,7 @@ class MopathRecorder(AppShell, DirectObject): dictName = name else: # Generate a unique name for the dict - dictName = name # + '-' + `nodePath.id()` + dictName = name # + '-' + `nodePath.get_key()` if not dict.has_key(dictName): # Update combo box to include new item names.append(dictName) diff --git a/contrib/src/sceneeditor/seParticleEffect.py b/contrib/src/sceneeditor/seParticleEffect.py index 068f8f234e..8ad3a658a8 100644 --- a/contrib/src/sceneeditor/seParticleEffect.py +++ b/contrib/src/sceneeditor/seParticleEffect.py @@ -1,4 +1,4 @@ -from pandac.PandaModules import * +from panda3d.core import * import seParticles import seForceGroup from direct.directnotify import DirectNotifyGlobal diff --git a/contrib/src/sceneeditor/seParticles.py b/contrib/src/sceneeditor/seParticles.py index b062a3e00a..655d06b804 100644 --- a/contrib/src/sceneeditor/seParticles.py +++ b/contrib/src/sceneeditor/seParticles.py @@ -1,28 +1,8 @@ -from pandac.PandaModules import * +from panda3d.core import * +from panda3d.physics import * from direct.particles.ParticleManagerGlobal import * from direct.showbase.PhysicsManagerGlobal import * -#Manakel 2/12/2005: replace from pandac import by from pandac.PandaModules import -from pandac.PandaModules import ParticleSystem -from pandac.PandaModules import BaseParticleFactory -from pandac.PandaModules import PointParticleFactory -from pandac.PandaModules import ZSpinParticleFactory #import OrientedParticleFactory -from pandac.PandaModules import BaseParticleRenderer -from pandac.PandaModules import PointParticleRenderer -from pandac.PandaModules import LineParticleRenderer -from pandac.PandaModules import GeomParticleRenderer -from pandac.PandaModules import SparkleParticleRenderer -from pandac.PandaModules import SpriteParticleRenderer -from pandac.PandaModules import BaseParticleEmitter -from pandac.PandaModules import BoxEmitter -from pandac.PandaModules import DiscEmitter -from pandac.PandaModules import LineEmitter -from pandac.PandaModules import PointEmitter -from pandac.PandaModules import RectangleEmitter -from pandac.PandaModules import RingEmitter -from pandac.PandaModules import SphereSurfaceEmitter -from pandac.PandaModules import SphereVolumeEmitter -from pandac.PandaModules import TangentRingEmitter import string import os from direct.directnotify import DirectNotifyGlobal diff --git a/contrib/src/sceneeditor/sePlacer.py b/contrib/src/sceneeditor/sePlacer.py index 108ef7fbc6..3f2b3b4b75 100644 --- a/contrib/src/sceneeditor/sePlacer.py +++ b/contrib/src/sceneeditor/sePlacer.py @@ -6,7 +6,7 @@ from direct.tkwidgets.AppShell import AppShell from direct.tkwidgets.Dial import AngleDial from direct.tkwidgets.Floater import Floater from Tkinter import Button, Menubutton, Menu, StringVar -from pandac.PandaModules import * +from panda3d.core import * import Tkinter, Pmw """ TODO: @@ -428,7 +428,7 @@ class Placer(AppShell): background = self.nodePathMenuBG) # Check to see if node path and ref node path are the same if ((self.refCS != None) and - (self.refCS.id() == self['nodePath'].id())): + (self.refCS.get_key() == self['nodePath'].get_key())): # Yes they are, use temp CS as ref # This calls updatePlacer self.setReferenceNodePath(self.tempCS) @@ -473,7 +473,7 @@ class Placer(AppShell): listbox = self.refNodePathMenu.component('scrolledlist') listbox.setlist(self.refNodePathNames) # Check to see if node path and ref node path are the same - if (nodePath != None) and (nodePath.id() == self['nodePath'].id()): + if (nodePath != None) and (nodePath.get_key() == self['nodePath'].get_key()): # Yes they are, use temp CS and update listbox accordingly nodePath = self.tempCS self.refNodePathMenu.selectitem('parent') @@ -508,7 +508,7 @@ class Placer(AppShell): dictName = name else: # Generate a unique name for the dict - dictName = name + '-' + `nodePath.id()` + dictName = name + '-' + `nodePath.get_key()` if not dict.has_key(dictName): # Update combo box to include new item names.append(dictName) diff --git a/contrib/src/sceneeditor/seSceneGraphExplorer.py b/contrib/src/sceneeditor/seSceneGraphExplorer.py index a864d11e90..fc7f29370a 100644 --- a/contrib/src/sceneeditor/seSceneGraphExplorer.py +++ b/contrib/src/sceneeditor/seSceneGraphExplorer.py @@ -141,7 +141,7 @@ class seSceneGraphExplorer(Pmw.MegaWidget, DirectObject): self._node.deselecttree() def selectNodePath(self,nodePath, callBack=True): - item = self._node.find(nodePath.id()) + item = self._node.find(nodePath.get_key()) if item!= None: item.select(callBack) else: @@ -164,7 +164,7 @@ class SceneGraphExplorerItem(TreeItem): return name def GetKey(self): - return self.nodePath.id() + return self.nodePath.get_key() def IsEditable(self): # All nodes' names can be edited nowadays. diff --git a/contrib/src/sceneeditor/seSelection.py b/contrib/src/sceneeditor/seSelection.py index 73cdb1ea46..0d34ad120a 100644 --- a/contrib/src/sceneeditor/seSelection.py +++ b/contrib/src/sceneeditor/seSelection.py @@ -11,7 +11,7 @@ # (If we do change original directools, it will force user has to install the latest version of OUR Panda) # ################################################################# -from pandac.PandaModules import GeomNode +from panda3d.core import GeomNode from direct.directtools.DirectGlobals import * from direct.directtools.DirectUtil import * from seGeometry import * @@ -78,7 +78,7 @@ class SelectedNodePaths(DirectObject): self.deselectAll() # Get this pointer - id = nodePath.id() + id = nodePath.get_key() # First see if its already in the selected dictionary dnp = self.getSelectedDict(id) # If so, we're done @@ -96,7 +96,7 @@ class SelectedNodePaths(DirectObject): # Show its bounding box dnp.highlight() # Add it to the selected dictionary - self.selectedDict[dnp.id()] = dnp + self.selectedDict[dnp.get_key()] = dnp # And update last __builtins__["last"] = self.last = dnp return dnp @@ -104,7 +104,7 @@ class SelectedNodePaths(DirectObject): def deselect(self, nodePath): """ Deselect the specified node path """ # Get this pointer - id = nodePath.id() + id = nodePath.get_key() # See if it is in the selected dictionary dnp = self.getSelectedDict(id) if dnp: @@ -204,15 +204,24 @@ class SelectedNodePaths(DirectObject): # Remove all selected nodePaths from the Scene Graph self.forEachSelectedNodePathDo(NodePath.remove) + def toggleVis(self, nodePath): + if nodePath.is_hidden(): + nodePath.show() + else: + nodePath.hide() + def toggleVisSelected(self): selected = self.last # Toggle visibility of selected node paths if selected: - selected.toggleVis() + if selected.is_hidden(): + selected.show() + else: + selected.hide() def toggleVisAll(self): # Toggle viz for all selected node paths - self.forEachSelectedNodePathDo(NodePath.toggleVis) + self.forEachSelectedNodePathDo(self.toggleVis) def isolateSelected(self): selected = self.last @@ -221,7 +230,7 @@ class SelectedNodePaths(DirectObject): def getDirectNodePath(self, nodePath): # Get this pointer - id = nodePath.id() + id = nodePath.get_key() # First check selected dict dnp = self.getSelectedDict(id) if dnp: diff --git a/contrib/src/sceneeditor/seSession.py b/contrib/src/sceneeditor/seSession.py index 95f235829b..ab466c4388 100644 --- a/contrib/src/sceneeditor/seSession.py +++ b/contrib/src/sceneeditor/seSession.py @@ -388,7 +388,7 @@ class SeSession(DirectObject): ### Customized DirectSession messenger.send('DIRECT_preSelectNodePath', [dnp]) if fResetAncestry: # Update ancestry - self.ancestry = dnp.getAncestors() + self.ancestry = list(dnp.getAncestors()) self.ancestry.reverse() self.ancestryIndex = 0 # Update the selectedNPReadout @@ -479,7 +479,7 @@ class SeSession(DirectObject): ### Customized DirectSession def isNotCycle(self, nodePath, parent): - if nodePath.id() == parent.id(): + if nodePath.get_key() == parent.get_key(): print 'DIRECT.reparent: Invalid parent' return 0 elif parent.hasParent(): @@ -520,7 +520,10 @@ class SeSession(DirectObject): ### Customized DirectSession nodePath = self.selected.last if nodePath: # Now toggle node path's visibility state - nodePath.toggleVis() + if nodePath.is_hidden(): + nodePath.show() + else: + nodePath.hide() def removeNodePath(self, nodePath = 'None Given'): if nodePath == 'None Given': diff --git a/contrib/src/sceneeditor/seTree.py b/contrib/src/sceneeditor/seTree.py index 018d6af410..9685d54b35 100644 --- a/contrib/src/sceneeditor/seTree.py +++ b/contrib/src/sceneeditor/seTree.py @@ -15,7 +15,7 @@ import os, sys, string, Pmw, Tkinter from direct.showbase.DirectObject import DirectObject from Tkinter import IntVar, Menu, PhotoImage, Label, Frame, Entry -from pandac.PandaModules import * +from panda3d.core import * # Initialize icon directory ICONDIR = getModelPath().findFile(Filename('icons')).toOsSpecific() From 3d383a3d9c04f2a7322a42e22d58f6bd8194c14f Mon Sep 17 00:00:00 2001 From: rdb Date: Fri, 10 Aug 2018 23:53:33 +0200 Subject: [PATCH 098/125] sceneeditor: get it to run with Python 3 --- contrib/src/sceneeditor/MetadataPanel.py | 2 +- contrib/src/sceneeditor/SideWindow.py | 66 ++-- contrib/src/sceneeditor/collisionWindow.py | 5 +- contrib/src/sceneeditor/controllerWindow.py | 366 +++++++++--------- contrib/src/sceneeditor/dataHolder.py | 98 ++--- contrib/src/sceneeditor/duplicateWindow.py | 4 +- contrib/src/sceneeditor/lightingPanel.py | 55 +-- contrib/src/sceneeditor/propertyWindow.py | 7 +- contrib/src/sceneeditor/quad.py | 10 +- contrib/src/sceneeditor/sceneEditor.py | 72 ++-- contrib/src/sceneeditor/seAnimPanel.py | 14 +- contrib/src/sceneeditor/seBlendAnimPanel.py | 14 +- contrib/src/sceneeditor/seCameraControl.py | 18 +- contrib/src/sceneeditor/seColorEntry.py | 10 +- contrib/src/sceneeditor/seFileSaver.py | 34 +- contrib/src/sceneeditor/seGeometry.py | 14 +- contrib/src/sceneeditor/seLights.py | 19 +- contrib/src/sceneeditor/seMopathRecorder.py | 273 ++++++------- contrib/src/sceneeditor/seParticleEffect.py | 6 +- contrib/src/sceneeditor/seParticlePanel.py | 51 +-- contrib/src/sceneeditor/seParticles.py | 6 +- contrib/src/sceneeditor/sePlacer.py | 55 +-- .../src/sceneeditor/seSceneGraphExplorer.py | 21 +- contrib/src/sceneeditor/seSelection.py | 8 +- contrib/src/sceneeditor/seSession.py | 6 +- contrib/src/sceneeditor/seTree.py | 22 +- 26 files changed, 665 insertions(+), 591 deletions(-) diff --git a/contrib/src/sceneeditor/MetadataPanel.py b/contrib/src/sceneeditor/MetadataPanel.py index 7510f3d7fc..9f6bc222f4 100644 --- a/contrib/src/sceneeditor/MetadataPanel.py +++ b/contrib/src/sceneeditor/MetadataPanel.py @@ -36,7 +36,7 @@ class MetadataPanel(AppShell,Pmw.MegaWidget): def appInit(self): - print "Metadata Panel" + print("Metadata Panel") def createInterface(self): interior = self.interior() diff --git a/contrib/src/sceneeditor/SideWindow.py b/contrib/src/sceneeditor/SideWindow.py index 58a41a05be..96c225c58f 100644 --- a/contrib/src/sceneeditor/SideWindow.py +++ b/contrib/src/sceneeditor/SideWindow.py @@ -6,8 +6,16 @@ from direct.tkwidgets.AppShell import AppShell from direct.tkwidgets.VectorWidgets import ColorEntry from direct.showbase.TkGlobal import spawnTkLoop import seSceneGraphExplorer -from Tkinter import Frame, IntVar, Checkbutton, Toplevel -import Pmw, Tkinter + +import Pmw, sys + +if sys.version_info >= (3, 0): + from tkinter import Frame, IntVar, Checkbutton, Toplevel + import tkinter +else: + from Tkinter import Frame, IntVar, Checkbutton, Toplevel + import Tkinter as tkinter + class sideWindow(AppShell): ################################################################# @@ -65,7 +73,7 @@ class sideWindow(AppShell): self.parent.resizable(False,False) ## Disable the ability to resize for this Window. def appInit(self): - print '----SideWindow is Initialized!!' + print('----SideWindow is Initialized!!') def createInterface(self): # The interior of the toplevel panel @@ -73,7 +81,7 @@ class sideWindow(AppShell): mainFrame = Frame(interior) ## Creat NoteBook self.notebookFrame = Pmw.NoteBook(mainFrame) - self.notebookFrame.pack(fill=Tkinter.BOTH,expand=1) + self.notebookFrame.pack(fill=tkinter.BOTH,expand=1) sgePage = self.notebookFrame.add('Tree Graph') envPage = self.notebookFrame.add('World Setting') self.notebookFrame['raisecommand'] = self.updateInfo @@ -83,7 +91,7 @@ class sideWindow(AppShell): sgePage, nodePath = render, scrolledCanvas_hull_width = 270, scrolledCanvas_hull_height = 570) - self.SGE.pack(fill = Tkinter.BOTH, expand = 0) + self.SGE.pack(fill = tkinter.BOTH, expand = 0) ## World Setting Page envPage = Frame(envPage) @@ -95,8 +103,8 @@ class sideWindow(AppShell): text = 'Enable Lighting', variable = self.LightingVar, command = self.toggleLights) - self.LightingButton.pack(side=Tkinter.LEFT, expand=False) - pageFrame.pack(side=Tkinter.TOP, fill=Tkinter.X, expand=True) + self.LightingButton.pack(side=tkinter.LEFT, expand=False) + pageFrame.pack(side=tkinter.TOP, fill=tkinter.X, expand=True) pageFrame = Frame(envPage) self.CollisionVar = IntVar() @@ -106,8 +114,8 @@ class sideWindow(AppShell): text = 'Show Collision Object', variable = self.CollisionVar, command = self.showCollision) - self.CollisionButton.pack(side=Tkinter.LEFT, expand=False) - pageFrame.pack(side=Tkinter.TOP, fill=Tkinter.X, expand=True) + self.CollisionButton.pack(side=tkinter.LEFT, expand=False) + pageFrame.pack(side=tkinter.TOP, fill=tkinter.X, expand=True) pageFrame = Frame(envPage) self.ParticleVar = IntVar() @@ -117,8 +125,8 @@ class sideWindow(AppShell): text = 'Show Particle Dummy', variable = self.ParticleVar, command = self.enableParticle) - self.ParticleButton.pack(side=Tkinter.LEFT, expand=False) - pageFrame.pack(side=Tkinter.TOP, fill=Tkinter.X, expand=True) + self.ParticleButton.pack(side=tkinter.LEFT, expand=False) + pageFrame.pack(side=tkinter.TOP, fill=tkinter.X, expand=True) pageFrame = Frame(envPage) self.baseUseDriveVar = IntVar() @@ -128,8 +136,8 @@ class sideWindow(AppShell): text = 'Enable base.usedrive', variable = self.baseUseDriveVar, command = self.enablebaseUseDrive) - self.baseUseDriveButton.pack(side=Tkinter.LEFT, expand=False) - pageFrame.pack(side=Tkinter.TOP, fill=Tkinter.X, expand=True) + self.baseUseDriveButton.pack(side=tkinter.LEFT, expand=False) + pageFrame.pack(side=tkinter.TOP, fill=tkinter.X, expand=True) pageFrame = Frame(envPage) self.backfaceVar = IntVar() @@ -139,8 +147,8 @@ class sideWindow(AppShell): text = 'Enable BackFace', variable = self.backfaceVar, command = self.toggleBackface) - self.backfaceButton.pack(side=Tkinter.LEFT, expand=False) - pageFrame.pack(side=Tkinter.TOP, fill=Tkinter.X, expand=True) + self.backfaceButton.pack(side=tkinter.LEFT, expand=False) + pageFrame.pack(side=tkinter.TOP, fill=tkinter.X, expand=True) pageFrame = Frame(envPage) self.textureVar = IntVar() @@ -150,8 +158,8 @@ class sideWindow(AppShell): text = 'Enable Texture', variable = self.textureVar, command = self.toggleTexture) - self.textureButton.pack(side=Tkinter.LEFT, expand=False) - pageFrame.pack(side=Tkinter.TOP, fill=Tkinter.X, expand=True) + self.textureButton.pack(side=tkinter.LEFT, expand=False) + pageFrame.pack(side=tkinter.TOP, fill=tkinter.X, expand=True) pageFrame = Frame(envPage) self.wireframeVar = IntVar() @@ -161,8 +169,8 @@ class sideWindow(AppShell): text = 'Enable Wireframe', variable = self.wireframeVar, command = self.toggleWireframe) - self.wireframeButton.pack(side=Tkinter.LEFT, expand=False) - pageFrame.pack(side=Tkinter.TOP, fill=Tkinter.X, expand=True) + self.wireframeButton.pack(side=tkinter.LEFT, expand=False) + pageFrame.pack(side=tkinter.TOP, fill=tkinter.X, expand=True) pageFrame = Frame(envPage) self.gridVar = IntVar() @@ -172,8 +180,8 @@ class sideWindow(AppShell): text = 'Enable Grid', variable = self.gridVar, command = self.toggleGrid) - self.gridButton.pack(side=Tkinter.LEFT, expand=False) - pageFrame.pack(side=Tkinter.TOP, fill=Tkinter.X, expand=True) + self.gridButton.pack(side=tkinter.LEFT, expand=False) + pageFrame.pack(side=tkinter.TOP, fill=tkinter.X, expand=True) pageFrame = Frame(envPage) self.widgetVisVar = IntVar() @@ -183,8 +191,8 @@ class sideWindow(AppShell): text = 'Enable WidgetVisible', variable = self.widgetVisVar, command = self.togglewidgetVis) - self.widgetVisButton.pack(side=Tkinter.LEFT, expand=False) - pageFrame.pack(side=Tkinter.TOP, fill=Tkinter.X, expand=True) + self.widgetVisButton.pack(side=tkinter.LEFT, expand=False) + pageFrame.pack(side=tkinter.TOP, fill=tkinter.X, expand=True) pageFrame = Frame(envPage) self.enableAutoCameraVar = IntVar() @@ -194,17 +202,17 @@ class sideWindow(AppShell): text = 'Enable Auto Camera Movement for Loading Objects', variable = self.enableAutoCameraVar, command = self.toggleAutoCamera) - self.enableAutoCameraButton.pack(side=Tkinter.LEFT, expand=False) - pageFrame.pack(side=Tkinter.TOP, fill=Tkinter.X, expand=True) + self.enableAutoCameraButton.pack(side=tkinter.LEFT, expand=False) + pageFrame.pack(side=tkinter.TOP, fill=tkinter.X, expand=True) pageFrame = Frame(envPage) self.backgroundColor = ColorEntry( pageFrame, text = 'BG Color', value=self.worldColor) self.backgroundColor['command'] = self.setBackgroundColorVec self.backgroundColor['resetValue'] = [0,0,0,0] - self.backgroundColor.pack(side=Tkinter.LEFT, expand=False) + self.backgroundColor.pack(side=tkinter.LEFT, expand=False) self.bind(self.backgroundColor, 'Set background color') - pageFrame.pack(side=Tkinter.TOP, fill=Tkinter.X, expand=True) + pageFrame.pack(side=tkinter.TOP, fill=tkinter.X, expand=True) envPage.pack(expand=False) @@ -320,11 +328,11 @@ class sideWindow(AppShell): # ################################################################# if self.enableBaseUseDrive==0: - print 'Enabled' + print('Enabled') base.useDrive() self.enableBaseUseDrive = 1 else: - print 'disabled' + print('disabled') #base.useTrackball() base.disableMouse() self.enableBaseUseDrive = 0 diff --git a/contrib/src/sceneeditor/collisionWindow.py b/contrib/src/sceneeditor/collisionWindow.py index 3c6b70e607..9155db871a 100644 --- a/contrib/src/sceneeditor/collisionWindow.py +++ b/contrib/src/sceneeditor/collisionWindow.py @@ -9,7 +9,6 @@ from seColorEntry import * from direct.tkwidgets import VectorWidgets from direct.tkwidgets import Floater from direct.tkwidgets import Slider -from Tkinter import * import string, math, types from panda3d.core import * @@ -195,7 +194,7 @@ class collisionWindow(AppShell): # put the object into a CollisionNode and attach it to the target nodePath ################################################################# collisionObject = None - print self.objType + print(self.objType) if self.objType=='collisionPolygon': pointA = Point3(float(self.widgetDict['PolygonPoint A'][0]._entry.get()), float(self.widgetDict['PolygonPoint A'][1]._entry.get()), @@ -236,7 +235,7 @@ class collisionWindow(AppShell): float(self.widgetDict['RayDirection'][1]._entry.get()), float(self.widgetDict['RayDirection'][2]._entry.get())) - print vector, point + print(vector, point) collisionObject = CollisionRay() collisionObject.setOrigin(point) diff --git a/contrib/src/sceneeditor/controllerWindow.py b/contrib/src/sceneeditor/controllerWindow.py index b66e390c73..03ca35d6d8 100644 --- a/contrib/src/sceneeditor/controllerWindow.py +++ b/contrib/src/sceneeditor/controllerWindow.py @@ -4,8 +4,14 @@ ################################################################# from direct.tkwidgets.AppShell import AppShell -from Tkinter import Frame, Label, Button -import string, Pmw, Tkinter +import sys, Pmw + +if sys.version_info >= (3, 0): + from tkinter import Frame, Label, Button + import tkinter +else: + from Tkinter import Frame, Label, Button + import Tkinter as tkinter # Define the Category KEYBOARD = 'Keyboard-' @@ -75,11 +81,11 @@ class controllerWindow(AppShell): self.cotrollerTypeEntry = self.createcomponent( 'Controller Type', (), None, Pmw.ComboBox, (frame,), - labelpos = Tkinter.W, label_text='Controller Type:', entry_width = 20,entry_state = Tkinter.DISABLED, + labelpos = tkinter.W, label_text='Controller Type:', entry_width = 20,entry_state = tkinter.DISABLED, selectioncommand = self.setControllerType, scrolledlist_items = self.controllerList) - self.cotrollerTypeEntry.pack(side=Tkinter.LEFT) - frame.pack(side=Tkinter.TOP, fill=Tkinter.X, expand=False, pady = 3) + self.cotrollerTypeEntry.pack(side=tkinter.LEFT) + frame.pack(side=tkinter.TOP, fill=tkinter.X, expand=False, pady = 3) self.cotrollerTypeEntry.selectitem('Keyboard', setentry=True) self.inputZone = Pmw.Group(mainFrame, tag_pyclass = None) @@ -102,7 +108,7 @@ class controllerWindow(AppShell): keyboardPage = self.objNotebook.add('Keyboard') tarckerPage = self.objNotebook.add('Tracker') self.objNotebook.selectpage('Keyboard') - self.objNotebook.pack(side = Tkinter.TOP, fill='both',expand=False) + self.objNotebook.pack(side = tkinter.TOP, fill='both',expand=False) # Put this here so it isn't called right away self.objNotebook['raisecommand'] = self.updateControlInfo @@ -113,11 +119,11 @@ class controllerWindow(AppShell): widget = self.createcomponent( 'Target Type', (), None, Pmw.ComboBox, (Interior,), - labelpos = Tkinter.W, label_text='Target Object:', entry_width = 20, entry_state = Tkinter.DISABLED, + labelpos = tkinter.W, label_text='Target Object:', entry_width = 20, entry_state = tkinter.DISABLED, selectioncommand = self.setTargetObj, scrolledlist_items = self.listOfObj) - widget.pack(side=Tkinter.LEFT, padx=3) - Interior.pack(side=Tkinter.TOP, fill=Tkinter.X, expand=True, pady = 5) + widget.pack(side=tkinter.LEFT, padx=3) + Interior.pack(side=tkinter.TOP, fill=tkinter.X, expand=True, pady = 5) widget.selectitem(self.nameOfNode, setentry=True) self.widgetsDict[KEYBOARD+'ObjList'] = widget @@ -126,411 +132,411 @@ class controllerWindow(AppShell): settingFrame = inputZone.interior() Interior = Frame(settingFrame) - widget = Label(Interior, text = 'Assign a Key For:').pack(side=Tkinter.LEFT, expand = False) - Interior.pack(side=Tkinter.TOP, fill=Tkinter.X, expand=True,pady = 6 ) + widget = Label(Interior, text = 'Assign a Key For:').pack(side=tkinter.LEFT, expand = False) + Interior.pack(side=tkinter.TOP, fill=tkinter.X, expand=True,pady = 6 ) Interior = Frame(settingFrame) - widget = Label(Interior, text = 'Forward :', width = 20, anchor = Tkinter.W).pack(side=Tkinter.LEFT, expand = False) + widget = Label(Interior, text = 'Forward :', width = 20, anchor = tkinter.W).pack(side=tkinter.LEFT, expand = False) widget = self.createcomponent( 'Forward key', (), None, Pmw.EntryField, (Interior,), value = self.keyboardMapDict['KeyForward'], - labelpos = Tkinter.W, label_text='Key :', entry_width = 10) - widget.pack(side=Tkinter.LEFT, expand = False) + labelpos = tkinter.W, label_text='Key :', entry_width = 10) + widget.pack(side=tkinter.LEFT, expand = False) self.widgetsDict[KEYBOARD+'KeyForward'] = widget - widget = Label(Interior, text = ' ').pack(side=Tkinter.LEFT, expand = False) + widget = Label(Interior, text = ' ').pack(side=tkinter.LEFT, expand = False) widget = self.createcomponent( 'Forward Speed', (), None, Pmw.EntryField, (Interior,), value = self.keyboardSpeedDict['SpeedForward'], - labelpos = Tkinter.W, label_text='Speed :', entry_width = 10) - widget.pack(side=Tkinter.LEFT, expand = False) + labelpos = tkinter.W, label_text='Speed :', entry_width = 10) + widget.pack(side=tkinter.LEFT, expand = False) self.widgetsDict[KEYBOARD+'SpeedForward'] = widget - widget = Label(Interior, text = 'Per Second').pack(side=Tkinter.LEFT, expand = False) - Interior.pack(side=Tkinter.TOP, fill=Tkinter.X, expand=True, pady = 4 ) + widget = Label(Interior, text = 'Per Second').pack(side=tkinter.LEFT, expand = False) + Interior.pack(side=tkinter.TOP, fill=tkinter.X, expand=True, pady = 4 ) Interior = Frame(settingFrame) - widget = Label(Interior, text = 'Backward :', width = 20, anchor = Tkinter.W).pack(side=Tkinter.LEFT, expand = False) + widget = Label(Interior, text = 'Backward :', width = 20, anchor = tkinter.W).pack(side=tkinter.LEFT, expand = False) widget = self.createcomponent( 'Backward key', (), None, Pmw.EntryField, (Interior,), value = self.keyboardMapDict['KeyBackward'], - labelpos = Tkinter.W, label_text='Key :', entry_width = 10) - widget.pack(side=Tkinter.LEFT, expand = False) + labelpos = tkinter.W, label_text='Key :', entry_width = 10) + widget.pack(side=tkinter.LEFT, expand = False) self.widgetsDict[KEYBOARD+'KeyBackward'] = widget - widget = Label(Interior, text = ' ').pack(side=Tkinter.LEFT, expand = False) + widget = Label(Interior, text = ' ').pack(side=tkinter.LEFT, expand = False) widget = self.createcomponent( 'Backward Speed', (), None, Pmw.EntryField, (Interior,), value = self.keyboardSpeedDict['SpeedBackward'], - labelpos = Tkinter.W, label_text='Speed :', entry_width = 10) - widget.pack(side=Tkinter.LEFT, expand = False) + labelpos = tkinter.W, label_text='Speed :', entry_width = 10) + widget.pack(side=tkinter.LEFT, expand = False) self.widgetsDict[KEYBOARD+'SpeedBackward'] = widget - widget = Label(Interior, text = 'Per Second').pack(side=Tkinter.LEFT, expand = False) - Interior.pack(side=Tkinter.TOP, fill=Tkinter.X, expand=True, pady = 4 ) + widget = Label(Interior, text = 'Per Second').pack(side=tkinter.LEFT, expand = False) + Interior.pack(side=tkinter.TOP, fill=tkinter.X, expand=True, pady = 4 ) Interior = Frame(settingFrame) - widget = Label(Interior, text = 'Right :', width = 20, anchor = Tkinter.W).pack(side=Tkinter.LEFT, expand = False) + widget = Label(Interior, text = 'Right :', width = 20, anchor = tkinter.W).pack(side=tkinter.LEFT, expand = False) widget = self.createcomponent( 'Right key', (), None, Pmw.EntryField, (Interior,), value = self.keyboardMapDict['KeyRight'], - labelpos = Tkinter.W, label_text='Key :', entry_width = 10) - widget.pack(side=Tkinter.LEFT, expand = False) + labelpos = tkinter.W, label_text='Key :', entry_width = 10) + widget.pack(side=tkinter.LEFT, expand = False) self.widgetsDict[KEYBOARD+'KeyRight'] = widget - widget = Label(Interior, text = ' ').pack(side=Tkinter.LEFT, expand = False) + widget = Label(Interior, text = ' ').pack(side=tkinter.LEFT, expand = False) widget = self.createcomponent( 'Right Speed', (), None, Pmw.EntryField, (Interior,), value = self.keyboardSpeedDict['SpeedRight'], - labelpos = Tkinter.W, label_text='Speed :', entry_width = 10) - widget.pack(side=Tkinter.LEFT, expand = False) + labelpos = tkinter.W, label_text='Speed :', entry_width = 10) + widget.pack(side=tkinter.LEFT, expand = False) self.widgetsDict[KEYBOARD+'SpeedRight'] = widget - widget = Label(Interior, text = 'Per Second').pack(side=Tkinter.LEFT, expand = False) - Interior.pack(side=Tkinter.TOP, fill=Tkinter.X, expand=True, pady = 4 ) + widget = Label(Interior, text = 'Per Second').pack(side=tkinter.LEFT, expand = False) + Interior.pack(side=tkinter.TOP, fill=tkinter.X, expand=True, pady = 4 ) Interior = Frame(settingFrame) - widget = Label(Interior, text = 'Left :', width = 20, anchor = Tkinter.W).pack(side=Tkinter.LEFT, expand = False) + widget = Label(Interior, text = 'Left :', width = 20, anchor = tkinter.W).pack(side=tkinter.LEFT, expand = False) widget = self.createcomponent( 'Left key', (), None, Pmw.EntryField, (Interior,), value = self.keyboardMapDict['KeyLeft'], - labelpos = Tkinter.W, label_text='Key :', entry_width = 10) - widget.pack(side=Tkinter.LEFT, expand = False) + labelpos = tkinter.W, label_text='Key :', entry_width = 10) + widget.pack(side=tkinter.LEFT, expand = False) self.widgetsDict[KEYBOARD+'KeyLeft'] = widget - widget = Label(Interior, text = ' ').pack(side=Tkinter.LEFT, expand = False) + widget = Label(Interior, text = ' ').pack(side=tkinter.LEFT, expand = False) widget = self.createcomponent( 'Left Speed', (), None, Pmw.EntryField, (Interior,), value = self.keyboardSpeedDict['SpeedLeft'], - labelpos = Tkinter.W, label_text='Speed :', entry_width = 10) - widget.pack(side=Tkinter.LEFT, expand = False) + labelpos = tkinter.W, label_text='Speed :', entry_width = 10) + widget.pack(side=tkinter.LEFT, expand = False) self.widgetsDict[KEYBOARD+'SpeedLeft'] = widget - widget = Label(Interior, text = 'Per Second').pack(side=Tkinter.LEFT, expand = False) - Interior.pack(side=Tkinter.TOP, fill=Tkinter.X, expand=True, pady = 4 ) + widget = Label(Interior, text = 'Per Second').pack(side=tkinter.LEFT, expand = False) + Interior.pack(side=tkinter.TOP, fill=tkinter.X, expand=True, pady = 4 ) Interior = Frame(settingFrame) - widget = Label(Interior, text = 'Up :', width = 20, anchor = Tkinter.W).pack(side=Tkinter.LEFT, expand = False) + widget = Label(Interior, text = 'Up :', width = 20, anchor = tkinter.W).pack(side=tkinter.LEFT, expand = False) widget = self.createcomponent( 'Up key', (), None, Pmw.EntryField, (Interior,), value = self.keyboardMapDict['KeyUp'], - labelpos = Tkinter.W, label_text='Key :', entry_width = 10) - widget.pack(side=Tkinter.LEFT, expand = False) + labelpos = tkinter.W, label_text='Key :', entry_width = 10) + widget.pack(side=tkinter.LEFT, expand = False) self.widgetsDict[KEYBOARD+'KeyUp'] = widget - widget = Label(Interior, text = ' ').pack(side=Tkinter.LEFT, expand = False) + widget = Label(Interior, text = ' ').pack(side=tkinter.LEFT, expand = False) widget = self.createcomponent( 'Up Speed', (), None, Pmw.EntryField, (Interior,), value = self.keyboardSpeedDict['SpeedUp'], - labelpos = Tkinter.W, label_text='Speed :', entry_width = 10) - widget.pack(side=Tkinter.LEFT, expand = False) + labelpos = tkinter.W, label_text='Speed :', entry_width = 10) + widget.pack(side=tkinter.LEFT, expand = False) self.widgetsDict[KEYBOARD+'SpeedUp'] = widget - widget = Label(Interior, text = 'Per Second').pack(side=Tkinter.LEFT, expand = False) - Interior.pack(side=Tkinter.TOP, fill=Tkinter.X, expand=True, pady = 4 ) + widget = Label(Interior, text = 'Per Second').pack(side=tkinter.LEFT, expand = False) + Interior.pack(side=tkinter.TOP, fill=tkinter.X, expand=True, pady = 4 ) Interior = Frame(settingFrame) - widget = Label(Interior, text = 'Down :', width = 20, anchor = Tkinter.W).pack(side=Tkinter.LEFT, expand = False) + widget = Label(Interior, text = 'Down :', width = 20, anchor = tkinter.W).pack(side=tkinter.LEFT, expand = False) widget = self.createcomponent( 'Down key', (), None, Pmw.EntryField, (Interior,), value = self.keyboardMapDict['KeyDown'], - labelpos = Tkinter.W, label_text='Key :', entry_width = 10) - widget.pack(side=Tkinter.LEFT, expand = False) + labelpos = tkinter.W, label_text='Key :', entry_width = 10) + widget.pack(side=tkinter.LEFT, expand = False) self.widgetsDict[KEYBOARD+'KeyDown'] = widget - widget = Label(Interior, text = ' ').pack(side=Tkinter.LEFT, expand = False) + widget = Label(Interior, text = ' ').pack(side=tkinter.LEFT, expand = False) widget = self.createcomponent( 'Down Speed', (), None, Pmw.EntryField, (Interior,), value = self.keyboardSpeedDict['SpeedDown'], - labelpos = Tkinter.W, label_text='Speed :', entry_width = 10) - widget.pack(side=Tkinter.LEFT, expand = False) + labelpos = tkinter.W, label_text='Speed :', entry_width = 10) + widget.pack(side=tkinter.LEFT, expand = False) self.widgetsDict[KEYBOARD+'SpeedDown'] = widget - widget = Label(Interior, text = 'Per Second').pack(side=Tkinter.LEFT, expand = False) - Interior.pack(side=Tkinter.TOP, fill=Tkinter.X, expand=True, pady = 4 ) + widget = Label(Interior, text = 'Per Second').pack(side=tkinter.LEFT, expand = False) + Interior.pack(side=tkinter.TOP, fill=tkinter.X, expand=True, pady = 4 ) Interior = Frame(settingFrame) - widget = Label(Interior, text = 'Turn Right:', width = 20, anchor = Tkinter.W).pack(side=Tkinter.LEFT, expand = False) + widget = Label(Interior, text = 'Turn Right:', width = 20, anchor = tkinter.W).pack(side=tkinter.LEFT, expand = False) widget = self.createcomponent( 'Turn Right key', (), None, Pmw.EntryField, (Interior,), value = self.keyboardMapDict['KeyTurnRight'], - labelpos = Tkinter.W, label_text='Key :', entry_width = 10) - widget.pack(side=Tkinter.LEFT, expand = False) + labelpos = tkinter.W, label_text='Key :', entry_width = 10) + widget.pack(side=tkinter.LEFT, expand = False) self.widgetsDict[KEYBOARD+'KeyTurnRight'] = widget - widget = Label(Interior, text = ' ').pack(side=Tkinter.LEFT, expand = False) + widget = Label(Interior, text = ' ').pack(side=tkinter.LEFT, expand = False) widget = self.createcomponent( 'Turn Right Speed', (), None, Pmw.EntryField, (Interior,), value = self.keyboardSpeedDict['SpeedTurnRight'], - labelpos = Tkinter.W, label_text='Speed :', entry_width = 10) - widget.pack(side=Tkinter.LEFT, expand = False) + labelpos = tkinter.W, label_text='Speed :', entry_width = 10) + widget.pack(side=tkinter.LEFT, expand = False) self.widgetsDict[KEYBOARD+'SpeedTurnRight'] = widget - widget = Label(Interior, text = 'Per Second').pack(side=Tkinter.LEFT, expand = False) - Interior.pack(side=Tkinter.TOP, fill=Tkinter.X, expand=True, pady = 4 ) + widget = Label(Interior, text = 'Per Second').pack(side=tkinter.LEFT, expand = False) + Interior.pack(side=tkinter.TOP, fill=tkinter.X, expand=True, pady = 4 ) Interior = Frame(settingFrame) - widget = Label(Interior, text = 'Turn Left :', width = 20, anchor = Tkinter.W).pack(side=Tkinter.LEFT, expand = False) + widget = Label(Interior, text = 'Turn Left :', width = 20, anchor = tkinter.W).pack(side=tkinter.LEFT, expand = False) widget = self.createcomponent( 'Turn Left key', (), None, Pmw.EntryField, (Interior,), value = self.keyboardMapDict['KeyTurnLeft'], - labelpos = Tkinter.W, label_text='Key :', entry_width = 10) - widget.pack(side=Tkinter.LEFT, expand = False) + labelpos = tkinter.W, label_text='Key :', entry_width = 10) + widget.pack(side=tkinter.LEFT, expand = False) self.widgetsDict[KEYBOARD+'KeyTurnLeft'] = widget - widget = Label(Interior, text = ' ').pack(side=Tkinter.LEFT, expand = False) + widget = Label(Interior, text = ' ').pack(side=tkinter.LEFT, expand = False) widget = self.createcomponent( 'Turn Left Speed', (), None, Pmw.EntryField, (Interior,), value = self.keyboardSpeedDict['SpeedTurnLeft'], - labelpos = Tkinter.W, label_text='Speed :', entry_width = 10) - widget.pack(side=Tkinter.LEFT, expand = False) + labelpos = tkinter.W, label_text='Speed :', entry_width = 10) + widget.pack(side=tkinter.LEFT, expand = False) self.widgetsDict[KEYBOARD+'SpeedTurnLeft'] = widget - widget = Label(Interior, text = 'Per Second').pack(side=Tkinter.LEFT, expand = False) - Interior.pack(side=Tkinter.TOP, fill=Tkinter.X, expand=True, pady = 4 ) + widget = Label(Interior, text = 'Per Second').pack(side=tkinter.LEFT, expand = False) + Interior.pack(side=tkinter.TOP, fill=tkinter.X, expand=True, pady = 4 ) Interior = Frame(settingFrame) - widget = Label(Interior, text = 'Turn UP :', width = 20, anchor = Tkinter.W).pack(side=Tkinter.LEFT, expand = False) + widget = Label(Interior, text = 'Turn UP :', width = 20, anchor = tkinter.W).pack(side=tkinter.LEFT, expand = False) widget = self.createcomponent( 'Turn UP key', (), None, Pmw.EntryField, (Interior,), value = self.keyboardMapDict['KeyTurnUp'], - labelpos = Tkinter.W, label_text='Key :', entry_width = 10) - widget.pack(side=Tkinter.LEFT, expand = False) + labelpos = tkinter.W, label_text='Key :', entry_width = 10) + widget.pack(side=tkinter.LEFT, expand = False) self.widgetsDict[KEYBOARD+'KeyTurnUp'] = widget - widget = Label(Interior, text = ' ').pack(side=Tkinter.LEFT, expand = False) + widget = Label(Interior, text = ' ').pack(side=tkinter.LEFT, expand = False) widget = self.createcomponent( 'Turn UP Speed', (), None, Pmw.EntryField, (Interior,), value = self.keyboardSpeedDict['SpeedTurnUp'], - labelpos = Tkinter.W, label_text='Speed :', entry_width = 10) - widget.pack(side=Tkinter.LEFT, expand = False) + labelpos = tkinter.W, label_text='Speed :', entry_width = 10) + widget.pack(side=tkinter.LEFT, expand = False) self.widgetsDict[KEYBOARD+'SpeedTurnUp'] = widget - widget = Label(Interior, text = 'Per Second').pack(side=Tkinter.LEFT, expand = False) - Interior.pack(side=Tkinter.TOP, fill=Tkinter.X, expand=True, pady = 4 ) + widget = Label(Interior, text = 'Per Second').pack(side=tkinter.LEFT, expand = False) + Interior.pack(side=tkinter.TOP, fill=tkinter.X, expand=True, pady = 4 ) Interior = Frame(settingFrame) - widget = Label(Interior, text = 'Turn Down :', width = 20, anchor = Tkinter.W).pack(side=Tkinter.LEFT, expand = False) + widget = Label(Interior, text = 'Turn Down :', width = 20, anchor = tkinter.W).pack(side=tkinter.LEFT, expand = False) widget = self.createcomponent( 'Turn Down key', (), None, Pmw.EntryField, (Interior,), value = self.keyboardMapDict['KeyTurnDown'], - labelpos = Tkinter.W, label_text='Key :', entry_width = 10) - widget.pack(side=Tkinter.LEFT, expand = False) + labelpos = tkinter.W, label_text='Key :', entry_width = 10) + widget.pack(side=tkinter.LEFT, expand = False) self.widgetsDict[KEYBOARD+'KeyTurnDown'] = widget - widget = Label(Interior, text = ' ').pack(side=Tkinter.LEFT, expand = False) + widget = Label(Interior, text = ' ').pack(side=tkinter.LEFT, expand = False) widget = self.createcomponent( 'Turn Down Speed', (), None, Pmw.EntryField, (Interior,), value = self.keyboardSpeedDict['SpeedTurnDown'], - labelpos = Tkinter.W, label_text='Speed :', entry_width = 10) - widget.pack(side=Tkinter.LEFT, expand = False) + labelpos = tkinter.W, label_text='Speed :', entry_width = 10) + widget.pack(side=tkinter.LEFT, expand = False) self.widgetsDict[KEYBOARD+'SpeedTurnDown'] = widget - widget = Label(Interior, text = 'Per Second').pack(side=Tkinter.LEFT, expand = False) - Interior.pack(side=Tkinter.TOP, fill=Tkinter.X, expand=True, pady = 4 ) + widget = Label(Interior, text = 'Per Second').pack(side=tkinter.LEFT, expand = False) + Interior.pack(side=tkinter.TOP, fill=tkinter.X, expand=True, pady = 4 ) Interior = Frame(settingFrame) - widget = Label(Interior, text = 'Roll Right:', width = 20, anchor = Tkinter.W).pack(side=Tkinter.LEFT, expand = False) + widget = Label(Interior, text = 'Roll Right:', width = 20, anchor = tkinter.W).pack(side=tkinter.LEFT, expand = False) widget = self.createcomponent( 'Roll Right key', (), None, Pmw.EntryField, (Interior,), value = self.keyboardMapDict['KeyRollRight'], - labelpos = Tkinter.W, label_text='Key :', entry_width = 10) - widget.pack(side=Tkinter.LEFT, expand = False) + labelpos = tkinter.W, label_text='Key :', entry_width = 10) + widget.pack(side=tkinter.LEFT, expand = False) self.widgetsDict[KEYBOARD+'KeyRollRight'] = widget - widget = Label(Interior, text = ' ').pack(side=Tkinter.LEFT, expand = False) + widget = Label(Interior, text = ' ').pack(side=tkinter.LEFT, expand = False) widget = self.createcomponent( 'Roll Right Speed', (), None, Pmw.EntryField, (Interior,), value = self.keyboardSpeedDict['SpeedRollRight'], - labelpos = Tkinter.W, label_text='Speed :', entry_width = 10) - widget.pack(side=Tkinter.LEFT, expand = False) + labelpos = tkinter.W, label_text='Speed :', entry_width = 10) + widget.pack(side=tkinter.LEFT, expand = False) self.widgetsDict[KEYBOARD+'SpeedRollRight'] = widget - widget = Label(Interior, text = 'Per Second').pack(side=Tkinter.LEFT, expand = False) - Interior.pack(side=Tkinter.TOP, fill=Tkinter.X, expand=True, pady = 4 ) + widget = Label(Interior, text = 'Per Second').pack(side=tkinter.LEFT, expand = False) + Interior.pack(side=tkinter.TOP, fill=tkinter.X, expand=True, pady = 4 ) Interior = Frame(settingFrame) - widget = Label(Interior, text = 'Roll Left :', width = 20, anchor = Tkinter.W).pack(side=Tkinter.LEFT, expand = False) + widget = Label(Interior, text = 'Roll Left :', width = 20, anchor = tkinter.W).pack(side=tkinter.LEFT, expand = False) widget = self.createcomponent( 'Roll Left key', (), None, Pmw.EntryField, (Interior,), value = self.keyboardMapDict['KeyRollLeft'], - labelpos = Tkinter.W, label_text='Key :', entry_width = 10) - widget.pack(side=Tkinter.LEFT, expand = False) + labelpos = tkinter.W, label_text='Key :', entry_width = 10) + widget.pack(side=tkinter.LEFT, expand = False) self.widgetsDict[KEYBOARD+'KeyRollLeft'] = widget - widget = Label(Interior, text = ' ').pack(side=Tkinter.LEFT, expand = False) + widget = Label(Interior, text = ' ').pack(side=tkinter.LEFT, expand = False) widget = self.createcomponent( 'Roll Left Speed', (), None, Pmw.EntryField, (Interior,), value = self.keyboardSpeedDict['SpeedRollLeft'], - labelpos = Tkinter.W, label_text='Speed :', entry_width = 10) - widget.pack(side=Tkinter.LEFT, expand = False) + labelpos = tkinter.W, label_text='Speed :', entry_width = 10) + widget.pack(side=tkinter.LEFT, expand = False) self.widgetsDict[KEYBOARD+'SpeedRollLeft'] = widget - widget = Label(Interior, text = 'Per Second').pack(side=Tkinter.LEFT, expand = False) - Interior.pack(side=Tkinter.TOP, fill=Tkinter.X, expand=True, pady = 4 ) + widget = Label(Interior, text = 'Per Second').pack(side=tkinter.LEFT, expand = False) + Interior.pack(side=tkinter.TOP, fill=tkinter.X, expand=True, pady = 4 ) Interior = Frame(settingFrame) - widget = Label(Interior, text = 'Scale UP :', width = 20, anchor = Tkinter.W).pack(side=Tkinter.LEFT, expand = False) + widget = Label(Interior, text = 'Scale UP :', width = 20, anchor = tkinter.W).pack(side=tkinter.LEFT, expand = False) widget = self.createcomponent( 'Scale UP key', (), None, Pmw.EntryField, (Interior,), value = self.keyboardMapDict['KeyScaleUp'], - labelpos = Tkinter.W, label_text='Key :', entry_width = 10) - widget.pack(side=Tkinter.LEFT, expand = False) + labelpos = tkinter.W, label_text='Key :', entry_width = 10) + widget.pack(side=tkinter.LEFT, expand = False) self.widgetsDict[KEYBOARD+'KeyScaleUp'] = widget - widget = Label(Interior, text = ' ').pack(side=Tkinter.LEFT, expand = False) + widget = Label(Interior, text = ' ').pack(side=tkinter.LEFT, expand = False) widget = self.createcomponent( 'Scale UP Speed', (), None, Pmw.EntryField, (Interior,), value = self.keyboardSpeedDict['SpeedScaleUp'], - labelpos = Tkinter.W, label_text='Speed :', entry_width = 10) - widget.pack(side=Tkinter.LEFT, expand = False) + labelpos = tkinter.W, label_text='Speed :', entry_width = 10) + widget.pack(side=tkinter.LEFT, expand = False) self.widgetsDict[KEYBOARD+'SpeedScaleUp'] = widget - widget = Label(Interior, text = 'Per Second').pack(side=Tkinter.LEFT, expand = False) - Interior.pack(side=Tkinter.TOP, fill=Tkinter.X, expand=True, pady = 4 ) + widget = Label(Interior, text = 'Per Second').pack(side=tkinter.LEFT, expand = False) + Interior.pack(side=tkinter.TOP, fill=tkinter.X, expand=True, pady = 4 ) Interior = Frame(settingFrame) - widget = Label(Interior, text = 'Scale Down:', width = 20, anchor = Tkinter.W).pack(side=Tkinter.LEFT, expand = False) + widget = Label(Interior, text = 'Scale Down:', width = 20, anchor = tkinter.W).pack(side=tkinter.LEFT, expand = False) widget = self.createcomponent( 'Scale Down key', (), None, Pmw.EntryField, (Interior,), value = self.keyboardMapDict['KeyScaleDown'], - labelpos = Tkinter.W, label_text='Key :', entry_width = 10) - widget.pack(side=Tkinter.LEFT, expand = False) + labelpos = tkinter.W, label_text='Key :', entry_width = 10) + widget.pack(side=tkinter.LEFT, expand = False) self.widgetsDict[KEYBOARD+'KeyScaleDown'] = widget - widget = Label(Interior, text = ' ').pack(side=Tkinter.LEFT, expand = False) + widget = Label(Interior, text = ' ').pack(side=tkinter.LEFT, expand = False) widget = self.createcomponent( 'Scale Down Speed', (), None, Pmw.EntryField, (Interior,), value = self.keyboardSpeedDict['SpeedScaleDown'], - labelpos = Tkinter.W, label_text='Speed :', entry_width = 10) - widget.pack(side=Tkinter.LEFT, expand = False) + labelpos = tkinter.W, label_text='Speed :', entry_width = 10) + widget.pack(side=tkinter.LEFT, expand = False) self.widgetsDict[KEYBOARD+'SpeedScaleDown'] = widget - widget = Label(Interior, text = 'Per Second').pack(side=Tkinter.LEFT, expand = False) - Interior.pack(side=Tkinter.TOP, fill=Tkinter.X, expand=True, pady = 4 ) + widget = Label(Interior, text = 'Per Second').pack(side=tkinter.LEFT, expand = False) + Interior.pack(side=tkinter.TOP, fill=tkinter.X, expand=True, pady = 4 ) Interior = Frame(settingFrame) - widget = Label(Interior, text = 'Scale X UP :', width = 20, anchor = Tkinter.W).pack(side=Tkinter.LEFT, expand = False) + widget = Label(Interior, text = 'Scale X UP :', width = 20, anchor = tkinter.W).pack(side=tkinter.LEFT, expand = False) widget = self.createcomponent( 'Scale X UP key', (), None, Pmw.EntryField, (Interior,), value = self.keyboardMapDict['KeyScaleXUp'], - labelpos = Tkinter.W, label_text='Key :', entry_width = 10) - widget.pack(side=Tkinter.LEFT, expand = False) + labelpos = tkinter.W, label_text='Key :', entry_width = 10) + widget.pack(side=tkinter.LEFT, expand = False) self.widgetsDict[KEYBOARD+'KeyScaleXUp'] = widget - widget = Label(Interior, text = ' ').pack(side=Tkinter.LEFT, expand = False) + widget = Label(Interior, text = ' ').pack(side=tkinter.LEFT, expand = False) widget = self.createcomponent( 'Scale X UP Speed', (), None, Pmw.EntryField, (Interior,), value = self.keyboardSpeedDict['SpeedScaleXUp'], - labelpos = Tkinter.W, label_text='Speed :', entry_width = 10) - widget.pack(side=Tkinter.LEFT, expand = False) + labelpos = tkinter.W, label_text='Speed :', entry_width = 10) + widget.pack(side=tkinter.LEFT, expand = False) self.widgetsDict[KEYBOARD+'SpeedScaleXUp'] = widget - widget = Label(Interior, text = 'Per Second').pack(side=Tkinter.LEFT, expand = False) - Interior.pack(side=Tkinter.TOP, fill=Tkinter.X, expand=True, pady = 4 ) + widget = Label(Interior, text = 'Per Second').pack(side=tkinter.LEFT, expand = False) + Interior.pack(side=tkinter.TOP, fill=tkinter.X, expand=True, pady = 4 ) Interior = Frame(settingFrame) - widget = Label(Interior, text = 'Scale X Down:', width = 20, anchor = Tkinter.W).pack(side=Tkinter.LEFT, expand = False) + widget = Label(Interior, text = 'Scale X Down:', width = 20, anchor = tkinter.W).pack(side=tkinter.LEFT, expand = False) widget = self.createcomponent( 'Scale X Down key', (), None, Pmw.EntryField, (Interior,), value = self.keyboardMapDict['KeyScaleXDown'], - labelpos = Tkinter.W, label_text='Key :', entry_width = 10) - widget.pack(side=Tkinter.LEFT, expand = False) + labelpos = tkinter.W, label_text='Key :', entry_width = 10) + widget.pack(side=tkinter.LEFT, expand = False) self.widgetsDict[KEYBOARD+'KeyScaleXDown'] = widget - widget = Label(Interior, text = ' ').pack(side=Tkinter.LEFT, expand = False) + widget = Label(Interior, text = ' ').pack(side=tkinter.LEFT, expand = False) widget = self.createcomponent( 'Scale Down X Speed', (), None, Pmw.EntryField, (Interior,), value = self.keyboardSpeedDict['SpeedScaleXDown'], - labelpos = Tkinter.W, label_text='Speed :', entry_width = 10) - widget.pack(side=Tkinter.LEFT, expand = False) + labelpos = tkinter.W, label_text='Speed :', entry_width = 10) + widget.pack(side=tkinter.LEFT, expand = False) self.widgetsDict[KEYBOARD+'SpeedScaleXDown'] = widget - widget = Label(Interior, text = 'Per Second').pack(side=Tkinter.LEFT, expand = False) - Interior.pack(side=Tkinter.TOP, fill=Tkinter.X, expand=True, pady = 4 ) + widget = Label(Interior, text = 'Per Second').pack(side=tkinter.LEFT, expand = False) + Interior.pack(side=tkinter.TOP, fill=tkinter.X, expand=True, pady = 4 ) Interior = Frame(settingFrame) - widget = Label(Interior, text = 'Scale Y UP :', width = 20, anchor = Tkinter.W).pack(side=Tkinter.LEFT, expand = False) + widget = Label(Interior, text = 'Scale Y UP :', width = 20, anchor = tkinter.W).pack(side=tkinter.LEFT, expand = False) widget = self.createcomponent( 'Scale Y UP key', (), None, Pmw.EntryField, (Interior,), value = self.keyboardMapDict['KeyScaleYUp'], - labelpos = Tkinter.W, label_text='Key :', entry_width = 10) - widget.pack(side=Tkinter.LEFT, expand = False) + labelpos = tkinter.W, label_text='Key :', entry_width = 10) + widget.pack(side=tkinter.LEFT, expand = False) self.widgetsDict[KEYBOARD+'KeyScaleYUp'] = widget - widget = Label(Interior, text = ' ').pack(side=Tkinter.LEFT, expand = False) + widget = Label(Interior, text = ' ').pack(side=tkinter.LEFT, expand = False) widget = self.createcomponent( 'Scale Y UP Speed', (), None, Pmw.EntryField, (Interior,), value = self.keyboardSpeedDict['SpeedScaleYUp'], - labelpos = Tkinter.W, label_text='Speed :', entry_width = 10) - widget.pack(side=Tkinter.LEFT, expand = False) + labelpos = tkinter.W, label_text='Speed :', entry_width = 10) + widget.pack(side=tkinter.LEFT, expand = False) self.widgetsDict[KEYBOARD+'SpeedScaleYUp'] = widget - widget = Label(Interior, text = 'Per Second').pack(side=Tkinter.LEFT, expand = False) - Interior.pack(side=Tkinter.TOP, fill=Tkinter.X, expand=True, pady = 4 ) + widget = Label(Interior, text = 'Per Second').pack(side=tkinter.LEFT, expand = False) + Interior.pack(side=tkinter.TOP, fill=tkinter.X, expand=True, pady = 4 ) Interior = Frame(settingFrame) - widget = Label(Interior, text = 'Scale Y Down:', width = 20, anchor = Tkinter.W).pack(side=Tkinter.LEFT, expand = False) + widget = Label(Interior, text = 'Scale Y Down:', width = 20, anchor = tkinter.W).pack(side=tkinter.LEFT, expand = False) widget = self.createcomponent( 'Scale Y Down key', (), None, Pmw.EntryField, (Interior,), value = self.keyboardMapDict['KeyScaleYDown'], - labelpos = Tkinter.W, label_text='Key :', entry_width = 10) - widget.pack(side=Tkinter.LEFT, expand = False) + labelpos = tkinter.W, label_text='Key :', entry_width = 10) + widget.pack(side=tkinter.LEFT, expand = False) self.widgetsDict[KEYBOARD+'KeyScaleYDown'] = widget - widget = Label(Interior, text = ' ').pack(side=Tkinter.LEFT, expand = False) + widget = Label(Interior, text = ' ').pack(side=tkinter.LEFT, expand = False) widget = self.createcomponent( 'Scale Down XY Speed', (), None, Pmw.EntryField, (Interior,), value = self.keyboardSpeedDict['SpeedScaleYDown'], - labelpos = Tkinter.W, label_text='Speed :', entry_width = 10) - widget.pack(side=Tkinter.LEFT, expand = False) + labelpos = tkinter.W, label_text='Speed :', entry_width = 10) + widget.pack(side=tkinter.LEFT, expand = False) self.widgetsDict[KEYBOARD+'SpeedScaleYDown'] = widget - widget = Label(Interior, text = 'Per Second').pack(side=Tkinter.LEFT, expand = False) - Interior.pack(side=Tkinter.TOP, fill=Tkinter.X, expand=True, pady = 4 ) + widget = Label(Interior, text = 'Per Second').pack(side=tkinter.LEFT, expand = False) + Interior.pack(side=tkinter.TOP, fill=tkinter.X, expand=True, pady = 4 ) Interior = Frame(settingFrame) - widget = Label(Interior, text = 'Scale Z UP :', width = 20, anchor = Tkinter.W).pack(side=Tkinter.LEFT, expand = False) + widget = Label(Interior, text = 'Scale Z UP :', width = 20, anchor = tkinter.W).pack(side=tkinter.LEFT, expand = False) widget = self.createcomponent( 'Scale Z UP key', (), None, Pmw.EntryField, (Interior,), value = self.keyboardMapDict['KeyScaleZUp'], - labelpos = Tkinter.W, label_text='Key :', entry_width = 10) - widget.pack(side=Tkinter.LEFT, expand = False) + labelpos = tkinter.W, label_text='Key :', entry_width = 10) + widget.pack(side=tkinter.LEFT, expand = False) self.widgetsDict[KEYBOARD+'KeyScaleZUp'] = widget - widget = Label(Interior, text = ' ').pack(side=Tkinter.LEFT, expand = False) + widget = Label(Interior, text = ' ').pack(side=tkinter.LEFT, expand = False) widget = self.createcomponent( 'Scale Z UP Speed', (), None, Pmw.EntryField, (Interior,), value = self.keyboardSpeedDict['SpeedScaleZUp'], - labelpos = Tkinter.W, label_text='Speed :', entry_width = 10) - widget.pack(side=Tkinter.LEFT, expand = False) + labelpos = tkinter.W, label_text='Speed :', entry_width = 10) + widget.pack(side=tkinter.LEFT, expand = False) self.widgetsDict[KEYBOARD+'SpeedScaleZUp'] = widget - widget = Label(Interior, text = 'Per Second').pack(side=Tkinter.LEFT, expand = False) - Interior.pack(side=Tkinter.TOP, fill=Tkinter.X, expand=True, pady = 4 ) + widget = Label(Interior, text = 'Per Second').pack(side=tkinter.LEFT, expand = False) + Interior.pack(side=tkinter.TOP, fill=tkinter.X, expand=True, pady = 4 ) Interior = Frame(settingFrame) - widget = Label(Interior, text = 'Scale Z Down:', width = 20, anchor = Tkinter.W).pack(side=Tkinter.LEFT, expand = False) + widget = Label(Interior, text = 'Scale Z Down:', width = 20, anchor = tkinter.W).pack(side=tkinter.LEFT, expand = False) widget = self.createcomponent( 'Scale Z Down key', (), None, Pmw.EntryField, (Interior,), value = self.keyboardMapDict['KeyScaleZDown'], - labelpos = Tkinter.W, label_text='Key :', entry_width = 10) - widget.pack(side=Tkinter.LEFT, expand = False) + labelpos = tkinter.W, label_text='Key :', entry_width = 10) + widget.pack(side=tkinter.LEFT, expand = False) self.widgetsDict[KEYBOARD+'KeyScaleZDown'] = widget - widget = Label(Interior, text = ' ').pack(side=Tkinter.LEFT, expand = False) + widget = Label(Interior, text = ' ').pack(side=tkinter.LEFT, expand = False) widget = self.createcomponent( 'Scale Down Z Speed', (), None, Pmw.EntryField, (Interior,), value = self.keyboardSpeedDict['SpeedScaleZDown'], - labelpos = Tkinter.W, label_text='Speed :', entry_width = 10) - widget.pack(side=Tkinter.LEFT, expand = False) + labelpos = tkinter.W, label_text='Speed :', entry_width = 10) + widget.pack(side=tkinter.LEFT, expand = False) self.widgetsDict[KEYBOARD+'SpeedScaleZDown'] = widget - widget = Label(Interior, text = 'Per Second').pack(side=Tkinter.LEFT, expand = False) - Interior.pack(side=Tkinter.TOP, fill=Tkinter.X, expand=True, pady = 4 ) + widget = Label(Interior, text = 'Per Second').pack(side=tkinter.LEFT, expand = False) + Interior.pack(side=tkinter.TOP, fill=tkinter.X, expand=True, pady = 4 ) - assignFrame.pack(side=Tkinter.TOP, expand=True, fill = Tkinter.X) - keyboardPage.pack(side=Tkinter.TOP, expand=True, fill = Tkinter.X) + assignFrame.pack(side=tkinter.TOP, expand=True, fill = tkinter.X) + keyboardPage.pack(side=tkinter.TOP, expand=True, fill = tkinter.X) #################################################################### #################################################################### @@ -539,12 +545,12 @@ class controllerWindow(AppShell): #################################################################### # Pack the mainFrame frame = Frame(mainFrame) - widget = Button(frame, text='OK', width = 13, command=self.ok_press).pack(side=Tkinter.RIGHT) - widget = Button(frame, text='Enable Control', width = 13, command=self.enableControl).pack(side=Tkinter.LEFT) - widget = Button(frame, text='Disable Control', width = 13, command=self.disableControl).pack(side=Tkinter.LEFT) - widget = Button(frame, text='Save & Keep', width = 13, command=self.saveKeepControl).pack(side=Tkinter.LEFT) - frame.pack(side = Tkinter.BOTTOM, expand=1, fill = Tkinter.X) - mainFrame.pack(expand=1, fill = Tkinter.BOTH) + widget = Button(frame, text='OK', width = 13, command=self.ok_press).pack(side=tkinter.RIGHT) + widget = Button(frame, text='Enable Control', width = 13, command=self.enableControl).pack(side=tkinter.LEFT) + widget = Button(frame, text='Disable Control', width = 13, command=self.disableControl).pack(side=tkinter.LEFT) + widget = Button(frame, text='Save & Keep', width = 13, command=self.saveKeepControl).pack(side=tkinter.LEFT) + frame.pack(side = tkinter.BOTTOM, expand=1, fill = tkinter.X) + mainFrame.pack(expand=1, fill = tkinter.BOTH) def onDestroy(self, event): # Check if user wish to keep the control after the window closed. @@ -688,7 +694,7 @@ class controllerWindow(AppShell): self.keyboardMapDict[index] = self.widgetsDict['Keyboard-'+index].getvalue() for index in self.keyboardSpeedDict: self.keyboardSpeedDict[index] = float(self.widgetsDict['Keyboard-'+index].getvalue()) - print self.nodePath + print(self.nodePath) messenger.send('ControlW_saveSetting', ['Keyboard', [self.nodePath, self.keyboardMapDict, self.keyboardSpeedDict]]) return diff --git a/contrib/src/sceneeditor/dataHolder.py b/contrib/src/sceneeditor/dataHolder.py index 0981df643d..4e01ab2fa4 100644 --- a/contrib/src/sceneeditor/dataHolder.py +++ b/contrib/src/sceneeditor/dataHolder.py @@ -2,13 +2,15 @@ # TK and PMW INTERFACE MODULES# ############################### from direct.showbase.TkGlobal import* -from tkFileDialog import * import Pmw -import tkFileDialog -import tkMessageBox from direct.tkwidgets import Dial from direct.tkwidgets import Floater +if sys.version_info >= (3, 0): + from tkinter.filedialog import askopenfilename +else: + from tkFileDialog import askopenfilename + ############################# # Scene Editor Python Files # @@ -154,7 +156,7 @@ class dataHolder: self.ActorNum=0 self.theScene=None messenger.send('SGE_Update Explorer',[render]) - print 'Scene should be cleaned up!' + print('Scene should be cleaned up!') def removeObj(self, nodePath): ################################################################# @@ -169,7 +171,7 @@ class dataHolder: childrenList = nodePath.getChildren() - if self.ModelDic.has_key(name): + if name in self.ModelDic: del self.ModelDic[name] del self.ModelRefDic[name] if len(childrenList) != 0: @@ -178,7 +180,7 @@ class dataHolder: nodePath.removeNode() self.ModelNum -= 1 pass - elif self.ActorDic.has_key(name): + elif name in self.ActorDic: del self.ActorDic[name] del self.ActorRefDic[name] if len(childrenList) != 0: @@ -187,14 +189,14 @@ class dataHolder: nodePath.removeNode() self.ActorNum -= 1 pass - elif self.collisionDict.has_key(name): + elif name in self.collisionDict: del self.collisionDict[name] if len(childrenList) != 0: for node in childrenList: self.removeObj(node) nodePath.removeNode() pass - elif self.dummyDict.has_key(name): + elif name in self.dummyDict: del self.dummyDict[name] if len(childrenList) != 0: for node in childrenList: @@ -207,12 +209,12 @@ class dataHolder: self.removeObj(node) list = self.lightManager.delete(name) return list - elif self.particleNodes.has_key(name): + elif name in self.particleNodes: self.particleNodes[name].removeNode() del self.particleNodes[name] del self.particleDict[name] else: - print 'You cannot remove this NodePath' + print('You cannot remove this NodePath') return messenger.send('SGE_Update Explorer',[render]) @@ -237,15 +239,15 @@ class dataHolder: cHpr = hpr cScale = scale parent = nodePath.getParent() - if self.ActorDic.has_key(name): + if name in self.ActorDic: holder = self.ActorDic holderRef = self.ActorRefDic isModel = False - elif self.ModelDic.has_key(name): + elif name in self.ModelDic: holder = self.ModelDic holderRef = self.ModelRefDic else: - print '---- DataHolder: Target Obj is not a legal object could be duplicate!' + print('---- DataHolder: Target Obj is not a legal object could be duplicate!') return FilePath = holderRef[name] @@ -356,7 +358,7 @@ class dataHolder: # This funciton will return True if there is an Actor in the scene named "name" # and will return False if not. ########################################################################### - return self.ActorDic.has_key(name) + return name in self.ActorDic def getActor(self, name): ########################################################################### @@ -366,7 +368,7 @@ class dataHolder: if self.isActor(name): return self.ActorDic[name] else: - print '----No Actor named: ', name + print('----No Actor named: ', name) return None def getModel(self, name): @@ -377,7 +379,7 @@ class dataHolder: if self.isModel(name): return self.ModelDic[name] else: - print '----No Model named: ', name + print('----No Model named: ', name) return None def isModel(self, name): @@ -386,7 +388,7 @@ class dataHolder: # This funciton will return True if there is a Model in the scene named "name" # and will return False if not. ########################################################################### - return self.ModelDic.has_key(name) + return name in self.ModelDic def loadAnimation(self,name, Dic): ########################################################################### @@ -406,7 +408,7 @@ class dataHolder: messenger.send('DataH_loadFinish'+name) return else: - print '------ Error when loading animation for Actor: ', name + print('------ Error when loading animation for Actor: ', name) def removeAnimation(self, name, anim): ########################################################################### @@ -527,7 +529,7 @@ class dataHolder: self.ActorDic[nName]= self.ActorDic[oName] self.ActorRefDic[nName]= self.ActorRefDic[oName] self.ActorDic[nName].setName(nName) - if self.blendAnimDict.has_key(oName): + if oName in self.blendAnimDict: self.blendAnimDict[nName] = self.blendAnimDict[oName] del self.blendAnimDict[oName] del self.ActorDic[oName] @@ -540,16 +542,16 @@ class dataHolder: del self.ModelRefDic[oName] elif self.lightManager.isLight(oName): list, lightNode = self.lightManager.rename(oName, nName) - elif self.dummyDict.has_key(oName): + elif oName in self.dummyDict: self.dummyDict[nName]= self.dummyDict[oName] self.dummyDict[nName].setName(nName) del self.dummyDict[oName] - elif self.collisionDict.has_key(oName): + elif oName in self.collisionDict: self.collisionDict[nName]= self.collisionDict[oName] self.collisionDict[nName].setName(nName) del self.collisionDict[oName] - elif self.particleNodes.has_key(oName): + elif oName in self.particleNodes: self.particleNodes[nName]= self.particleNodes[oName] self.particleDict[nName]= self.particleDict[oName] self.particleDict[nName].setName(nName) @@ -557,9 +559,9 @@ class dataHolder: del self.particleNodes[oName] del self.particleDict[oName] else: - print '----Error: This Object is not allowed to this function!' + print('----Error: This Object is not allowed to this function!') - if self.curveDict.has_key(oName): + if oName in self.curveDict: self.curveDict[nName] = self.curveDict[oName] del self.curveDict[oName] @@ -578,11 +580,11 @@ class dataHolder: return True elif self.lightManager.isLight(name): return True - elif self.dummyDict.has_key(name): + elif name in self.dummyDict: return True - elif self.collisionDict.has_key(name): + elif name in self.collisionDict: return True - elif self.particleNodes.has_key(name): + elif name in self.particleNodes: return True elif (name == 'render')or(name == 'SEditor')or(name == 'Lights')or(name == 'camera'): return True @@ -596,7 +598,7 @@ class dataHolder: # using the node name as a reference to assosiate a list which contains all curves related to that node. ########################################################################### name = node.getName() - if self.curveDict.has_key(name): + if name in self.curveDict: self.curveDict[name].append(curveCollection) return else: @@ -612,7 +614,7 @@ class dataHolder: # If the input node has not been bindedwith any curve, it will return None. ########################################################################### name = nodePath.getName() - if self.curveDict.has_key(name): + if name in self.curveDict: return self.curveDict[name] else: return None @@ -626,7 +628,7 @@ class dataHolder: # This message will be caught by Property Window for this node. ########################################################################### name =nodePath.getName() - if self.curveDict.has_key(name): + if name in self.curveDict: index = None for curve in self.curveDict[name]: if curve.getCurve(0).getName() == curveName: @@ -677,12 +679,12 @@ class dataHolder: elif self.isLight(name): type = 'Light' info['lightNode'] = self.lightManager.getLightNode(name) - elif self.dummyDict.has_key(name): + elif name in self.dummyDict: type = 'dummy' - elif self.collisionDict.has_key(name): + elif name in self.collisionDict: type = 'collisionNode' info['collisionNode'] = self.collisionDict[name] - if self.curveDict.has_key(name): + if name in self.curveDict: info['curveList'] = self.getCurveList(nodePath) return type, info @@ -794,7 +796,7 @@ class dataHolder: # The formate of thsi dictionary is # {"name of Blend Animation" : ["Animation A, Animation B, Effect(Float, 0~1)"]} ########################################################################### - if self.blendAnimDict.has_key(name): + if name in self.blendAnimDict: return self.blendAnimDict[name] else: return {} @@ -808,8 +810,8 @@ class dataHolder: # Also, if this blend is the first blend animation that the target actor has, # this function will add a "Blending" tag on this actor which is "True". ########################################################################### - if self.blendAnimDict.has_key(actorName): - if self.blendAnimDict[actorName].has_key(blendName): + if actorName in self.blendAnimDict: + if blendName in self.blendAnimDict[actorName]: ### replace the original setting self.blendAnimDict[actorName][blendName][0] = animNameA self.blendAnimDict[actorName][blendName][1] = animNameB @@ -832,7 +834,7 @@ class dataHolder: # it will also rewrite the data to the newest one. ########################################################################### self.removeBlendAnim(actorName,oName) - print self.blendAnimDict + print(self.blendAnimDict) return self.saveBlendAnim(actorName, nName, animNameA, animNameB, effect) def removeBlendAnim(self, actorName, blendName): @@ -844,8 +846,8 @@ class dataHolder: # Also, it will check that there is any blended animation remained for this actor, # If none, this function will clear the "Blending" tag of this object. ########################################################################### - if self.blendAnimDict.has_key(actorName): - if self.blendAnimDict[actorName].has_key(blendName): + if actorName in self.blendAnimDict: + if blendName in self.blendAnimDict[actorName]: ### replace the original setting del self.blendAnimDict[actorName][blendName] if len(self.blendAnimDict[actorName])==0: @@ -876,15 +878,15 @@ class dataHolder: ########################################################################### if name == 'camera': return camera - elif self.ModelDic.has_key(name): + elif name in self.ModelDic: return self.ModelDic[name] - elif self.ActorDic.has_key(name): + elif name in self.ActorDic: return self.ActorDic[name] - elif self.collisionDict.has_key(name): + elif name in self.collisionDict: return self.collisionDict[name] - elif self.dummyDict.has_key(name): + elif name in self.dummyDict: return self.dummyDict[name] - elif self.particleNodes.has_key(name): + elif name in self.particleNodes: return self.particleNodes[name] elif self.lightManager.isLight(name): return self.lightManager.getLightNode(name) @@ -935,13 +937,13 @@ class dataHolder: ########################################################################### ### Ask for a filename - OpenFilename = tkFileDialog.askopenfilename(filetypes = [("PY","py")],title = "Load Scene") + OpenFilename = askopenfilename(filetypes = [("PY","py")],title = "Load Scene") if(not OpenFilename): return None f=Filename.fromOsSpecific(OpenFilename) fileName=f.getBasenameWoExtension() dirName=f.getFullpathWoExtension() - print "DATAHOLDER::" + dirName + print("DATAHOLDER::" + dirName) ############################################################################ # Append the path to this file to our sys path where python looks for modules # We do this so that we can use "import" on our saved scene code and execute it @@ -976,7 +978,7 @@ class dataHolder: self.ActorDic[actor]=self.Scene.ActorDic[actor] #self.ActorRefDic[actor]=self.Scene.ActorRefDic[actor] # Old way of doing absolute paths self.ActorRefDic[actor]=Filename(dirName + "/" + self.Scene.ActorRefDic[actor]) # Relative Paths - if(self.Scene.blendAnimDict.has_key(str(actor))): + if(str(actor) in self.Scene.blendAnimDict): self.blendAnimDict[actor]=self.Scene.blendAnimDict[actor] self.ActorNum=self.ActorNum+1 @@ -1006,7 +1008,7 @@ class dataHolder: atten=alight.getAttenuation() self.lightManager.create('spot',alight.getColor(),alight.getSpecularColor(),thenode.getPos(),thenode.getHpr(),atten.getX(),atten.getY(),atten.getZ(),alight.getExponent(),name=alight.getName(),tag=thenode.getTag("Metadata")) else: - print 'Invalid light type' + print('Invalid light type') ############################################################################ # Populate Dummy related Dictionaries diff --git a/contrib/src/sceneeditor/duplicateWindow.py b/contrib/src/sceneeditor/duplicateWindow.py index 24f20b7d09..b82a5449e1 100644 --- a/contrib/src/sceneeditor/duplicateWindow.py +++ b/contrib/src/sceneeditor/duplicateWindow.py @@ -45,7 +45,7 @@ class duplicateWindow(AppShell): self.parent.resizable(False,False) ## Disable the ability to resize for this Window. def appInit(self): - print '----SideWindow is Initialized!!' + print('----SideWindow is Initialized!!') def createInterface(self): # The interior of the toplevel panel @@ -122,7 +122,7 @@ class duplicateWindow(AppShell): # This message will be caught by sceneEditor. ################################################################# if not self.allEntryValid(): - print '---- Duplication Window: Invalid value!!' + print('---- Duplication Window: Invalid value!!') return x = self.move_x.getvalue() y = self.move_y.getvalue() diff --git a/contrib/src/sceneeditor/lightingPanel.py b/contrib/src/sceneeditor/lightingPanel.py index 729186a78d..eeb8cafa20 100644 --- a/contrib/src/sceneeditor/lightingPanel.py +++ b/contrib/src/sceneeditor/lightingPanel.py @@ -7,10 +7,17 @@ from direct.tkwidgets.AppShell import AppShell from seColorEntry import * from direct.tkwidgets.VectorWidgets import Vector3Entry from direct.tkwidgets.Slider import Slider -from Tkinter import Frame, Button, Menubutton, Menu -import string, math, types, Pmw, Tkinter +import sys, math, types, Pmw from panda3d.core import * +if sys.version_info >= (3, 0): + from tkinter import Frame, Button, Menubutton, Menu + import tkinter +else: + from Tkinter import Frame, Button, Menubutton, Menu + import Tkinter as tkinter + + class lightingPanel(AppShell): ################################################################# # lightingPanel(AppShell) @@ -51,25 +58,25 @@ class lightingPanel(AppShell): mainFrame = Frame(interior) self.listZone = Pmw.Group(mainFrame,tag_pyclass = None) - self.listZone.pack(expand=0, fill=Tkinter.X,padx=3,pady=3) + self.listZone.pack(expand=0, fill=tkinter.X,padx=3,pady=3) listFrame = self.listZone.interior() self.lightEntry = self.createcomponent( 'Lights List', (), None, Pmw.ComboBox, (listFrame,),label_text='Light :', - labelpos = Tkinter.W, entry_width = 25, selectioncommand = self.selectLight, + labelpos = tkinter.W, entry_width = 25, selectioncommand = self.selectLight, scrolledlist_items = self.lightList) - self.lightEntry.pack(side=Tkinter.LEFT) + self.lightEntry.pack(side=tkinter.LEFT) self.renameButton = self.createcomponent( 'Rename Light', (), None, Button, (listFrame,), text = ' Rename ', command = self.renameLight) - self.renameButton.pack(side=Tkinter.LEFT) + self.renameButton.pack(side=tkinter.LEFT) self.addLighZone = Pmw.Group(listFrame,tag_pyclass = None) - self.addLighZone.pack(side=Tkinter.LEFT) + self.addLighZone.pack(side=tkinter.LEFT) insideFrame = self.addLighZone.interior() self.lightsButton = Menubutton(insideFrame, text = 'Add light',borderwidth = 3, activebackground = '#909090') @@ -91,13 +98,13 @@ class lightingPanel(AppShell): Button, (listFrame,), text = ' Delete ', command = self.deleteLight) - self.deleteButton.pack(side=Tkinter.LEFT) + self.deleteButton.pack(side=tkinter.LEFT) self.lightColor = seColorEntry( mainFrame, text = 'Light Color', value=self.lightColor) self.lightColor['command'] = self.setLightingColorVec self.lightColor['resetValue'] = [0.3*255,0.3*255,0.3*255,0] - self.lightColor.pack(fill=Tkinter.X,expand=0) + self.lightColor.pack(fill=tkinter.X,expand=0) self.bind(self.lightColor, 'Set light color') # Notebook pages for light specific controls @@ -114,27 +121,27 @@ class lightingPanel(AppShell): self.dSpecularColor = seColorEntry( directionalPage, text = 'Specular Color') self.dSpecularColor['command'] = self.setSpecularColor - self.dSpecularColor.pack(fill = Tkinter.X, expand = 0) + self.dSpecularColor.pack(fill = tkinter.X, expand = 0) self.bind(self.dSpecularColor, 'Set directional light specular color') self.dPosition = Vector3Entry( directionalPage, text = 'Position') self.dPosition['command'] = self.setPosition self.dPosition['resetValue'] = [0,0,0,0] - self.dPosition.pack(fill = Tkinter.X, expand = 0) + self.dPosition.pack(fill = tkinter.X, expand = 0) self.bind(self.dPosition, 'Set directional light position') self.dOrientation = Vector3Entry( directionalPage, text = 'Orientation') self.dOrientation['command'] = self.setOrientation self.dOrientation['resetValue'] = [0,0,0,0] - self.dOrientation.pack(fill = Tkinter.X, expand = 0) + self.dOrientation.pack(fill = tkinter.X, expand = 0) self.bind(self.dOrientation, 'Set directional light orientation') # Point light controls self.pSpecularColor = seColorEntry( pointPage, text = 'Specular Color') self.pSpecularColor['command'] = self.setSpecularColor - self.pSpecularColor.pack(fill = Tkinter.X, expand = 0) + self.pSpecularColor.pack(fill = tkinter.X, expand = 0) self.bind(self.pSpecularColor, 'Set point light specular color') @@ -142,7 +149,7 @@ class lightingPanel(AppShell): pointPage, text = 'Position') self.pPosition['command'] = self.setPosition self.pPosition['resetValue'] = [0,0,0,0] - self.pPosition.pack(fill = Tkinter.X, expand = 0) + self.pPosition.pack(fill = tkinter.X, expand = 0) self.bind(self.pPosition, 'Set point light position') self.pConstantAttenuation = Slider( @@ -152,7 +159,7 @@ class lightingPanel(AppShell): resolution = 0.01, value = 1.0) self.pConstantAttenuation['command'] = self.setConstantAttenuation - self.pConstantAttenuation.pack(fill = Tkinter.X, expand = 0) + self.pConstantAttenuation.pack(fill = tkinter.X, expand = 0) self.bind(self.pConstantAttenuation, 'Set point light constant attenuation') @@ -163,7 +170,7 @@ class lightingPanel(AppShell): resolution = 0.01, value = 0.0) self.pLinearAttenuation['command'] = self.setLinearAttenuation - self.pLinearAttenuation.pack(fill = Tkinter.X, expand = 0) + self.pLinearAttenuation.pack(fill = tkinter.X, expand = 0) self.bind(self.pLinearAttenuation, 'Set point light linear attenuation') @@ -174,7 +181,7 @@ class lightingPanel(AppShell): resolution = 0.01, value = 0.0) self.pQuadraticAttenuation['command'] = self.setQuadraticAttenuation - self.pQuadraticAttenuation.pack(fill = Tkinter.X, expand = 0) + self.pQuadraticAttenuation.pack(fill = tkinter.X, expand = 0) self.bind(self.pQuadraticAttenuation, 'Set point light quadratic attenuation') @@ -182,7 +189,7 @@ class lightingPanel(AppShell): self.sSpecularColor = seColorEntry( spotPage, text = 'Specular Color') self.sSpecularColor['command'] = self.setSpecularColor - self.sSpecularColor.pack(fill = Tkinter.X, expand = 0) + self.sSpecularColor.pack(fill = tkinter.X, expand = 0) self.bind(self.sSpecularColor, 'Set spot light specular color') @@ -193,7 +200,7 @@ class lightingPanel(AppShell): resolution = 0.01, value = 1.0) self.sConstantAttenuation['command'] = self.setConstantAttenuation - self.sConstantAttenuation.pack(fill = Tkinter.X, expand = 0) + self.sConstantAttenuation.pack(fill = tkinter.X, expand = 0) self.bind(self.sConstantAttenuation, 'Set spot light constant attenuation') @@ -204,7 +211,7 @@ class lightingPanel(AppShell): resolution = 0.01, value = 0.0) self.sLinearAttenuation['command'] = self.setLinearAttenuation - self.sLinearAttenuation.pack(fill = Tkinter.X, expand = 0) + self.sLinearAttenuation.pack(fill = tkinter.X, expand = 0) self.bind(self.sLinearAttenuation, 'Set spot light linear attenuation') @@ -215,7 +222,7 @@ class lightingPanel(AppShell): resolution = 0.01, value = 0.0) self.sQuadraticAttenuation['command'] = self.setQuadraticAttenuation - self.sQuadraticAttenuation.pack(fill = Tkinter.X, expand = 0) + self.sQuadraticAttenuation.pack(fill = tkinter.X, expand = 0) self.bind(self.sQuadraticAttenuation, 'Set spot light quadratic attenuation') @@ -226,16 +233,16 @@ class lightingPanel(AppShell): resolution = 0.01, value = 0.0) self.sExponent['command'] = self.setExponent - self.sExponent.pack(fill = Tkinter.X, expand = 0) + self.sExponent.pack(fill = tkinter.X, expand = 0) self.bind(self.sExponent, 'Set spot light exponent') # MRM: Add frustum controls self.lightNotebook.setnaturalsize() - self.lightNotebook.pack(expand = 1, fill = Tkinter.BOTH) + self.lightNotebook.pack(expand = 1, fill = tkinter.BOTH) - mainFrame.pack(expand=1, fill = Tkinter.BOTH) + mainFrame.pack(expand=1, fill = tkinter.BOTH) def onDestroy(self, event): messenger.send('LP_close') diff --git a/contrib/src/sceneeditor/propertyWindow.py b/contrib/src/sceneeditor/propertyWindow.py index 7406d33ffa..d741324271 100644 --- a/contrib/src/sceneeditor/propertyWindow.py +++ b/contrib/src/sceneeditor/propertyWindow.py @@ -12,7 +12,6 @@ from direct.tkwidgets import Dial from direct.tkwidgets import Slider from direct.tkwidgets import VectorWidgets from panda3d.core import * -from Tkinter import * import Pmw class propertyWindow(AppShell,Pmw.MegaWidget): @@ -108,7 +107,7 @@ class propertyWindow(AppShell,Pmw.MegaWidget): self.curveFrame = None #### If nodePath has been binded with any curves - if self.info.has_key('curveList'): + if 'curveList' in self.info: self.createCurveFrame(self.contentFrame) ## Set all stuff done @@ -271,7 +270,7 @@ class propertyWindow(AppShell,Pmw.MegaWidget): # And, it will set the call back function to setNodeColorVec() ################################################################# color = self.nodePath.getColor() - print color + print(color) self.nodeColor = VectorWidgets.ColorEntry( contentFrame, text = 'Node Color', value=[color.getX()*255, color.getY()*255, @@ -725,7 +724,7 @@ class propertyWindow(AppShell,Pmw.MegaWidget): # But, not directly removed be this function. # This function will send out a message to notice dataHolder to remove this animation ################################################################# - print anim + print(anim) widget = self.widgetsDict[anim] self.accept('animRemovedFromNode',self.redrawAnimProperty) messenger.send('PW_removeAnimFromNode',[self.name, anim]) diff --git a/contrib/src/sceneeditor/quad.py b/contrib/src/sceneeditor/quad.py index 329dcb92a3..6f4fcf03d0 100644 --- a/contrib/src/sceneeditor/quad.py +++ b/contrib/src/sceneeditor/quad.py @@ -504,7 +504,7 @@ class QuadView(DirectObject): ansY=-1.0+y2 self.xy=[ansX,ansY] - print "Sent X:%f Sent Y:%f"%(ansX,ansY) + print("Sent X:%f Sent Y:%f"%(ansX,ansY)) #SEditor.iRay.pick(render,self.xy) SEditor.manipulationControl.manipulationStop(self.xy) #print "MouseX " + str(base.mouseWatcherNode.getMouseX()) + "MouseY " + str(base.mouseWatcherNode.getMouseY()) + "\n" @@ -548,28 +548,28 @@ class QuadView(DirectObject): dr.setDimensions(0.5,1,0,0.5) def setLeft(self): - print "LEFT" + print("LEFT") self.CurrentQuad=3 self.ChangeBaseDR() self.Left.setCam() #self.Left.setDR(self.mouseWatcherNode) def setTop(self): - print "TOP" + print("TOP") self.CurrentQuad=2 self.ChangeBaseDR() self.Top.setCam() #self.Top.setDR(self.mouseWatcherNode) def setPerspective(self): - print "PERSPECTIVE" + print("PERSPECTIVE") self.CurrentQuad=4 self.ChangeBaseDR() self.Perspective.setCam() #self.Perspective.setDR(self.mouseWatcherNode) def setFront(self): - print "FRONT" + print("FRONT") self.CurrentQuad=1 self.ChangeBaseDR() self.Front.setCam() diff --git a/contrib/src/sceneeditor/sceneEditor.py b/contrib/src/sceneeditor/sceneEditor.py index 37d05c3a08..1565e9eaed 100644 --- a/contrib/src/sceneeditor/sceneEditor.py +++ b/contrib/src/sceneeditor/sceneEditor.py @@ -8,8 +8,14 @@ from direct.showbase.ShowBase import ShowBase ShowBase() from direct.showbase.TkGlobal import spawnTkLoop -from Tkinter import * -from tkFileDialog import * + +if sys.version_info >= (3, 0): + from tkinter import * + from tkinter.filedialog import * +else: + from Tkinter import * + from tkFileDialog import * + from direct.directtools.DirectGlobals import * from direct.tkwidgets.AppShell import* @@ -391,31 +397,31 @@ class myLevelEditor(AppShell): self.showAbout() return elif buttonIndex==12: - print "You haven't defined the function for this Button, Number %d."%buttonIndex + print("You haven't defined the function for this Button, Number %d."%buttonIndex) return elif buttonIndex==13: - print "You haven't defined the function for this Button, Number %d."%buttonIndex + print("You haven't defined the function for this Button, Number %d."%buttonIndex) return elif buttonIndex==14: - print "You haven't defined the function for this Button, Number %d."%buttonIndex + print("You haven't defined the function for this Button, Number %d."%buttonIndex) return elif buttonIndex==15: - print "You haven't defined the function for this Button, Number %d."%buttonIndex + print("You haven't defined the function for this Button, Number %d."%buttonIndex) return elif buttonIndex==16: - print "Your scene will be eliminated within five seconds, Save your world!!!, Number %d."%buttonIndex + print("Your scene will be eliminated within five seconds, Save your world!!!, Number %d."%buttonIndex) return elif buttonIndex==17: - print "You haven't defined the function for this Button, Number %d."%buttonIndex + print("You haven't defined the function for this Button, Number %d."%buttonIndex) return elif buttonIndex==18: - print "You haven't defined the function for this Button, Number %d."%buttonIndex + print("You haven't defined the function for this Button, Number %d."%buttonIndex) return elif buttonIndex==19: - print "You haven't defined the function for this Button, Number %d."%buttonIndex + print("You haven't defined the function for this Button, Number %d."%buttonIndex) return elif buttonIndex==20: - print "You haven't defined the function for this Button, Number %d."%buttonIndex + print("You haven't defined the function for this Button, Number %d."%buttonIndex) return return @@ -671,17 +677,17 @@ class myLevelEditor(AppShell): ################################################################# type, info = AllScene.getInfoOfThisNode(nodePath) name = nodePath.getName() - if not self.propertyWindow.has_key(name): + if name not in self.propertyWindow: self.propertyWindow[name] = propertyWindow(nodePath, type,info ) pass def closePropertyWindow(self, name): - if self.propertyWindow.has_key(name): + if name in self.propertyWindow: del self.propertyWindow[name] return def openMetadataPanel(self,nodePath=None): - print nodePath + print(nodePath) self.MetadataPanel=MetadataPanel(nodePath) pass @@ -690,7 +696,7 @@ class myLevelEditor(AppShell): # duplicate(self, nodePath = None) # This function will be called when user try to open the duplication window ################################################################# - print '----Duplication!!' + print('----Duplication!!') if nodePath != None: self.duplicateWindow = duplicateWindow(nodePath = nodePath) pass @@ -796,8 +802,8 @@ class myLevelEditor(AppShell): ################################################################# name = nodePath.getName() if AllScene.isActor(name): - if self.animPanel.has_key(name): - print '---- You already have an animation panel for this Actor!' + if name in self.animPanel: + print('---- You already have an animation panel for this Actor!') return else: Actor = AllScene.getActor(name) @@ -847,9 +853,9 @@ class myLevelEditor(AppShell): # Let us actually remove the scene from sys modules... this is done because every scene is loaded as a module # And if we reload a scene python wont reload since its already in sys.modules... and hence we delete it # If there is ever a garbage colleciton bug..this might be a point to look at - if sys.modules.has_key(currentModName): + if currentModName in sys.modules: del sys.modules[currentModName] - print sys.getrefcount(AllScene.theScene) + print(sys.getrefcount(AllScene.theScene)) del AllScene.theScene else: AllScene.resetAll() @@ -877,9 +883,9 @@ class myLevelEditor(AppShell): # Let us actually remove the scene from sys modules... this is done because every scene is loaded as a module # And if we reload a scene python wont reload since its already in sys.modules... and hence we delete it # If there is ever a garbage colleciton bug..this might be a point to look at - if sys.modules.has_key(currentModName): + if currentModName in sys.modules: del sys.modules[currentModName] - print sys.getrefcount(AllScene.theScene) + print(sys.getrefcount(AllScene.theScene)) del AllScene.theScene else: AllScene.resetAll() @@ -891,7 +897,7 @@ class myLevelEditor(AppShell): thefile=Filename(self.CurrentFileName) thedir=thefile.getFullpathWoExtension() - print "SCENE EDITOR::" + thedir + print("SCENE EDITOR::" + thedir) self.CurrentDirName=thedir if self.CurrentFileName != None: self.parent.title('Scene Editor - '+ Filename.fromOsSpecific(self.CurrentFileName).getBasenameWoExtension()) @@ -939,7 +945,7 @@ class myLevelEditor(AppShell): theScene.writeBamFile(fileName) else: render.writeBamFile(fileName+".bad") - print " Scenegraph saved as :" +str(fileName) + print(" Scenegraph saved as :" +str(fileName)) def loadFromBam(self): fileName = tkFileDialog.askopenfilename(filetypes = [("BAM",".bam")],title = "Load Scenegraph from Bam file") @@ -964,7 +970,7 @@ class myLevelEditor(AppShell): ############################################################################### # !!!!! See if a module exists by this name... if it does you cannot use this filename !!!!! ############################################################################### - if(sys.modules.has_key(fCheck.getBasenameWoExtension())): + if(fCheck.getBasenameWoExtension() in sys.modules): tkMessageBox.showwarning( "Save file", "Cannot save with this name because there is a system module with the same name. Please resave as something else." @@ -998,7 +1004,7 @@ class myLevelEditor(AppShell): if modelFilename: self.makeDirty() if not AllScene.loadModel(modelFilename, Filename.fromOsSpecific(modelFilename)): - print '----Error! No Such Model File!' + print('----Error! No Such Model File!') pass def loadActor(self): @@ -1021,12 +1027,12 @@ class myLevelEditor(AppShell): if ActorFilename: self.makeDirty() if not AllScene.loadActor(ActorFilename, Filename.fromOsSpecific(ActorFilename)): - print '----Error! No Such Model File!' + print('----Error! No Such Model File!') pass def importScene(self): self.makeDirty() - print '----God bless you Please Import!' + print('----God bless you Please Import!') pass @@ -1500,7 +1506,7 @@ class myLevelEditor(AppShell): return def animPanelClose(self, name): - if self.animPanel.has_key(name): + if name in self.animPanel: del self.animPanel[name] return @@ -1513,8 +1519,8 @@ class myLevelEditor(AppShell): ################################################################ name = nodePath.getName() if AllScene.isActor(name): - if self.animBlendPanel.has_key(name): - print '---- You already have an Blend Animation Panel for this Actor!' + if name in self.animBlendPanel: + print('---- You already have an Blend Animation Panel for this Actor!') return else: Actor = AllScene.getActor(name) @@ -1559,7 +1565,7 @@ class myLevelEditor(AppShell): # This function will be called when Blend panel has been closed. # Here we will reset the reference dictionary so it can be open again. ################################################################ - if self.animBlendPanel.has_key(name): + if name in self.animBlendPanel: del self.animBlendPanel[name] return @@ -1618,7 +1624,7 @@ class myLevelEditor(AppShell): def openAlignPanel(self, nodePath=None): name = nodePath.getName() - if not self.alignPanelDict.has_key(name): + if name not in self.alignPanelDict: list = AllScene.getAllObjNameAsList() if name in list: list.remove(name) @@ -1628,7 +1634,7 @@ class myLevelEditor(AppShell): return def closeAlignPanel(self, name=None): - if self.alignPanelDict.has_key(name): + if name in self.alignPanelDict: del self.alignPanelDict[name] def alignObject(self, nodePath, name, list): diff --git a/contrib/src/sceneeditor/seAnimPanel.py b/contrib/src/sceneeditor/seAnimPanel.py index 86c245a3ef..2dd3ceee53 100644 --- a/contrib/src/sceneeditor/seAnimPanel.py +++ b/contrib/src/sceneeditor/seAnimPanel.py @@ -5,12 +5,16 @@ # Import Tkinter, Pmw, and the floater code from this directory tree. from direct.tkwidgets.AppShell import * from direct.showbase.TkGlobal import * -from tkSimpleDialog import askfloat import string import math import types from direct.task import Task +if sys.version_info >= (3, 0): + from tkinter.simpledialog import askfloat +else: + from tkSimpleDialog import askfloat + FRAMES = 0 SECONDS = 1 @@ -112,7 +116,7 @@ class AnimPanel(AppShell): self.playRateEntry.selectitem('1.0') ### Loop checkbox - Label(actorFrame, text= "Loop:", font=('MSSansSerif', 12)).place(x=420,y=05,anchor=NW) + Label(actorFrame, text= "Loop:", font=('MSSansSerif', 12)).place(x=420,y=5,anchor=NW) self.loopVar = IntVar() self.loopVar.set(0) @@ -250,7 +254,7 @@ class AnimPanel(AppShell): self['animList'] = self['actor'].getAnimNames() animL = self['actor'].getAnimNames() self.AnimEntry.setlist(animL) - print '-----',animL + print('-----',animL) return def loadAnimation(self): @@ -278,7 +282,7 @@ class AnimPanel(AppShell): taskMgr.add(self.playTask, self.id + '_UpdateTask') self.stopButton.config(state=NORMAL) else: - print '----Illegal Animaion name!!', self.animName + print('----Illegal Animaion name!!', self.animName) return def playTask(self, task): @@ -591,7 +595,7 @@ class LoadAnimPanel(AppShell): else: self.animList.append(name) self.AnimName_1.setlist(self.animList) - print self.animDic + print(self.animDic) return def ok_press(self): diff --git a/contrib/src/sceneeditor/seBlendAnimPanel.py b/contrib/src/sceneeditor/seBlendAnimPanel.py index 6895b81417..2ab28210c5 100644 --- a/contrib/src/sceneeditor/seBlendAnimPanel.py +++ b/contrib/src/sceneeditor/seBlendAnimPanel.py @@ -5,12 +5,16 @@ # Import Tkinter, Pmw, and the floater code from this directory tree. from direct.tkwidgets.AppShell import * from direct.showbase.TkGlobal import * -from tkSimpleDialog import askfloat import string import math import types from direct.task import Task +if sys.version_info >= (3, 0): + from tkinter.simpledialog import askfloat +else: + from tkSimpleDialog import askfloat + FRAMES = 0 SECONDS = 1 @@ -304,7 +308,7 @@ class BlendAnimPanel(AppShell): taskMgr.add(self.playTask, self.id + '_UpdateTask') self.stopButton.config(state=NORMAL) else: - print '----Illegal Animaion name!!', self.animNameA + ', '+ self.animNameB + print('----Illegal Animaion name!!', self.animNameA + ', '+ self.animNameB) return def playTask(self, task): @@ -348,7 +352,7 @@ class BlendAnimPanel(AppShell): # setAnimation(self, animation, AB = 'a') # see play(self) ################################################################# - print 'OK!!!' + print('OK!!!') if AB == 'a': if self.animNameA != None: self['actor'].setControlEffect(self.animNameA, 1.0, 'modelRoot','lodRoot') @@ -519,7 +523,7 @@ class BlendAnimPanel(AppShell): # then this function will set Animation A to "a" and animation B # to "b" and set the ratio slider to "c" position. ################################################################# - if self.blendDict.has_key(name): + if name in self.blendDict: self.currentBlendName = name animA = self.blendDict[name][0] animB = self.blendDict[name][1] @@ -544,7 +548,7 @@ class BlendAnimPanel(AppShell): self.blendDict.clear() del self.blendDict self.blendDict = dict.copy() - print self.blendDict + print(self.blendDict) if len(self.blendDict)>0: self.blendList = self.blendDict.keys() else: diff --git a/contrib/src/sceneeditor/seCameraControl.py b/contrib/src/sceneeditor/seCameraControl.py index 721ebe9c31..95237db8be 100644 --- a/contrib/src/sceneeditor/seCameraControl.py +++ b/contrib/src/sceneeditor/seCameraControl.py @@ -55,14 +55,14 @@ class DirectCameraControl(DirectObject): ['n', self.pickNextCOA], ['u', self.orbitUprightCam], ['shift-u', self.uprightCam], - [`1`, self.spawnMoveToView, 1], - [`2`, self.spawnMoveToView, 2], - [`3`, self.spawnMoveToView, 3], - [`4`, self.spawnMoveToView, 4], - [`5`, self.spawnMoveToView, 5], - [`6`, self.spawnMoveToView, 6], - [`7`, self.spawnMoveToView, 7], - [`8`, self.spawnMoveToView, 8], + ['1', self.spawnMoveToView, 1], + ['2', self.spawnMoveToView, 2], + ['3', self.spawnMoveToView, 3], + ['4', self.spawnMoveToView, 4], + ['5', self.spawnMoveToView, 5], + ['6', self.spawnMoveToView, 6], + ['7', self.spawnMoveToView, 7], + ['8', self.spawnMoveToView, 8], ['9', self.swingCamAboutWidget, -90.0, t], ['0', self.swingCamAboutWidget, 90.0, t], ['`', self.removeManipulateCameraTask], @@ -351,7 +351,7 @@ class DirectCameraControl(DirectObject): # MRM: Would be nice to be able to control this # At least display it dist = pow(10.0, self.nullHitPointCount) - SEditor.message('COA Distance: ' + `dist`) + SEditor.message('COA Distance: ' + repr(dist)) coa.set(0,dist,0) # Compute COA Dist coaDist = Vec3(coa - ZERO_POINT).length() diff --git a/contrib/src/sceneeditor/seColorEntry.py b/contrib/src/sceneeditor/seColorEntry.py index 6cc14b27c6..9dcb3136f7 100644 --- a/contrib/src/sceneeditor/seColorEntry.py +++ b/contrib/src/sceneeditor/seColorEntry.py @@ -12,9 +12,15 @@ from direct.tkwidgets import Valuator from direct.tkwidgets import Floater from direct.tkwidgets import Slider -import string, Pmw, Tkinter, tkColorChooser +import sys, Pmw from direct.tkwidgets.VectorWidgets import VectorEntry +if sys.version_info >= (3, 0): + from tkinter.colorchooser import askcolor +else: + from tkColorChooser import askcolor + + class seColorEntry(VectorEntry): def __init__(self, parent = None, **kw): # Initialize options for the class (overriding some superclass options) @@ -41,7 +47,7 @@ class seColorEntry(VectorEntry): def popupColorPicker(self): # Can pass in current color with: color = (255, 0, 0) - color = tkColorChooser.askcolor( + color = askcolor( parent = self.interior(), # Initialize it to current color initialcolor = tuple(self.get()[:3]))[0] diff --git a/contrib/src/sceneeditor/seFileSaver.py b/contrib/src/sceneeditor/seFileSaver.py index 0b2e088e12..9d58fa0580 100644 --- a/contrib/src/sceneeditor/seFileSaver.py +++ b/contrib/src/sceneeditor/seFileSaver.py @@ -42,7 +42,7 @@ class FileSaver: i1=" " # indentation i2=i1+i1 # double indentation out_file = open(filename,"w") - print "dirname:" + dirname + print("dirname:" + dirname) if( not os.path.isdir(dirname)): os.mkdir(dirname) savepathname=Filename(filename) @@ -176,7 +176,7 @@ class FileSaver: newtexpathF=Filename(newtexpath) newtexpathSpecific=newtexpathF.toOsSpecific() - print "TEXTURE SAVER:: copying" + oldtexpath + " to " + newtexpathSpecific + print("TEXTURE SAVER:: copying" + oldtexpath + " to " + newtexpathSpecific) if(oldtexpath != newtexpathSpecific): shutil.copyfile(oldtexpath,newtexpathSpecific) @@ -187,7 +187,7 @@ class FileSaver: # Copy the file over to the relative directory oldModelpath=AllScene.ModelRefDic[model].toOsSpecific() - print "FILESAVER:: copying from " + AllScene.ModelRefDic[model].toOsSpecific() + "to" + newpathSpecific + print("FILESAVER:: copying from " + AllScene.ModelRefDic[model].toOsSpecific() + "to" + newpathSpecific) if(oldModelpath!=newpathSpecific): shutil.copyfile(oldModelpath,newpathSpecific) @@ -197,7 +197,7 @@ class FileSaver: etc=EggTextureCollection() etc.extractTextures(e) for index in range(len(fnamelist)): - print fnamelist[index] + print(fnamelist[index]) tex=etc.findFilename(Filename(fnamelist[index])) fn=Filename(tex.getFilename()) fn.setDirname("") @@ -305,14 +305,14 @@ class FileSaver: newtexpath=dirname + "/" + texfilename.getBasename() newtexpathF=Filename(newtexpath) newtexpathSpecific=newtexpathF.toOsSpecific() - print "TEXTURE SAVER:: copying" + oldtexpath + " to " + newtexpathSpecific + print("TEXTURE SAVER:: copying" + oldtexpath + " to " + newtexpathSpecific) if(oldtexpath != newtexpathSpecific): shutil.copyfile(oldtexpath,newtexpathSpecific) # Copy the file over to the relative directory oldActorpath=AllScene.ActorRefDic[actor].toOsSpecific() - print "FILESAVER:: copying from " + AllScene.ActorRefDic[actor].toOsSpecific() + "to" + newpathSpecific + print("FILESAVER:: copying from " + AllScene.ActorRefDic[actor].toOsSpecific() + "to" + newpathSpecific) if(oldActorpath!=newpathSpecific): shutil.copyfile(oldActorpath,newpathSpecific) @@ -322,7 +322,7 @@ class FileSaver: etc=EggTextureCollection() etc.extractTextures(e) for index in range(len(actorfnamelist)): - print actorfnamelist[index] + print(actorfnamelist[index]) tex=etc.findFilename(Filename(actorfnamelist[index])) fn=Filename(tex.getFilename()) fn.setDirname("") @@ -362,12 +362,12 @@ class FileSaver: #out_file.write(i2+ "self."+ actorS + ".loadAnims(" + str(ActorAnimations) +")\n") # Old way with absolute paths #Manakel 2/12/2004: solve the not empty but not defined animation case if not animation is None: - print "ACTOR ANIMATIONS:" + ActorAnimations[animation] + print("ACTOR ANIMATIONS:" + ActorAnimations[animation]) oldAnimPath=Filename(ActorAnimations[animation]) oldAnim=oldAnimPath.toOsSpecific() dirOS=Filename(dirname) newAnim=dirOS.toOsSpecific() + "\\" + oldAnimPath.getBasename() - print "ACTOR ANIM SAVER:: Comparing" + oldAnim +"and" + newAnim + print("ACTOR ANIM SAVER:: Comparing" + oldAnim +"and" + newAnim) if(oldAnim!=newAnim): shutil.copyfile(oldAnim,newAnim) newAnimF=Filename.fromOsSpecific(newAnim) @@ -379,16 +379,16 @@ class FileSaver: out_file.write(i2+ i1+"self."+ actorS + ".loadAnims(" + str(ActorAnimations) +")\n") # Now with new relative paths out_file.write(i2+"else:\n") theloadAnimString=str(ActorAnimationsInvoke)# We hack the "self.executionpath" part into the dictionary as a variable using string replace - print "LOAD ANIM STRING BEFORE" + theloadAnimString + print("LOAD ANIM STRING BEFORE" + theloadAnimString) theloadAnimString=theloadAnimString.replace('\'self.executionpath +','self.executionpath + \'') - print "LOAD ANIM STRING AFTER" + theloadAnimString + print("LOAD ANIM STRING AFTER" + theloadAnimString) out_file.write(i2+ i1+"self."+ actorS + ".loadAnims(" + theloadAnimString +")\n") # Now with new relative paths based on editor invocation out_file.write(i2+ "self.ActorDic[\'" + actorS + "\']=self." + AllScene.ActorDic[actor].getName()+"\n") #out_file.write(i2+ "self.ActorRefDic[\'" + actorS + "\']=Filename(\'"+AllScene.ActorRefDic[actor].getFullpath() +"\')\n") # Old way with absolute paths out_file.write(i2+ "self.ActorRefDic[\'" + actorS + "\']=\'"+ AllScene.ActorRefDic[actor].getBasename() +"\'\n")# Relative paths out_file.write(i2+ "self.ActorDic[\'"+ actorS + "\'].setName(\'"+ actorS +"\')\n") - if(AllScene.blendAnimDict.has_key(actor)): # Check if a dictionary of blended animations exists + if(actor in AllScene.blendAnimDict): # Check if a dictionary of blended animations exists out_file.write(i2+ "self.blendAnimDict[\"" + actorS +"\"]=" + str(AllScene.blendAnimDict[actor]) + "\n") @@ -458,7 +458,7 @@ class FileSaver: pass else: - print "Invalid Collision Node: " + nodetype + print("Invalid Collision Node: " + nodetype) out_file.write("\n") @@ -653,7 +653,7 @@ class FileSaver: if(parent=="render" or parent=="camera"): out_file.write(i2+ "self."+ modelS + ".reparentTo(" + parent + ")\n") else: - if(AllScene.particleDict.has_key(parent)): + if(parent in AllScene.particleDict): out_file.write(i2+ "self."+ modelS + ".reparentTo(self." + parent + ".getEffect())\n") else: out_file.write(i2+ "self."+ modelS + ".reparentTo(self." + parent + ")\n") @@ -666,7 +666,7 @@ class FileSaver: if(parent=="render" or parent=="camera"): out_file.write(i2+ "self."+ dummyS + ".reparentTo(" + parent + ")\n") else: - if(AllScene.particleDict.has_key(parent)): + if(parent in AllScene.particleDict): out_file.write(i2+ "self."+ dummyS + ".reparentTo(self." + parent + ".getEffect())\n") else: out_file.write(i2+ "self."+ dummyS + ".reparentTo(self." + parent + ")\n") @@ -680,7 +680,7 @@ class FileSaver: if(parent=="render" or parent=="camera"): out_file.write(i2+ "self."+ actorS + ".reparentTo(" + parent + ")\n") else: - if(AllScene.particleDict.has_key(parent)): + if(parent in AllScene.particleDict): out_file.write(i2+ "self."+ actorS + ".reparentTo(self." + parent + ".getEffect())\n") else: out_file.write(i2+ "self."+ actorS + ".reparentTo(self." + parent + ")\n") @@ -698,7 +698,7 @@ class FileSaver: out_file.write(i2+"self.collisionDict[\"" + collnodeS + "\"]="+ parentname + ".attachNewNode(self." + collnodeS + "_Node)\n") else: #Manakel 2/12/2005: parent replaced by parent Name but why Parent name in partice and parent for other objects? - if(AllScene.particleDict.has_key(parentname)): + if(parentname in AllScene.particleDict): out_file.write(i2+"self.collisionDict[\"" + collnodeS + "\"]=self."+ parentname + "getEffect().attachNewNode(self." + collnodeS + "_Node)\n") else: out_file.write(i2+"self.collisionDict[\"" + collnodeS + "\"]=self."+ parentname + ".attachNewNode(self." + collnodeS + "_Node)\n") diff --git a/contrib/src/sceneeditor/seGeometry.py b/contrib/src/sceneeditor/seGeometry.py index 4074c986a2..99afa62a1f 100644 --- a/contrib/src/sceneeditor/seGeometry.py +++ b/contrib/src/sceneeditor/seGeometry.py @@ -41,10 +41,10 @@ class LineNodePath(NodePath): ls.setColor(colorVec) def moveTo( self, *_args ): - apply( self.lineSegs.moveTo, _args ) + self.lineSegs.moveTo(*_args) def drawTo( self, *_args ): - apply( self.lineSegs.drawTo, _args ) + self.lineSegs.drawTo(*_args) def create( self, frameAccurate = 0 ): self.lineSegs.create( self.lineNode, frameAccurate ) @@ -60,13 +60,13 @@ class LineNodePath(NodePath): self.lineSegs.setThickness( thickness ) def setColor( self, *_args ): - apply( self.lineSegs.setColor, _args ) + self.lineSegs.setColor(*_args) def setVertex( self, *_args): - apply( self.lineSegs.setVertex, _args ) + self.lineSegs.setVertex(*_args) def setVertexColor( self, vertex, *_args ): - apply( self.lineSegs.setVertexColor, (vertex,) + _args ) + self.lineSegs.setVertexColor(*(vertex,) + _args) def getCurrentPosition( self ): return self.lineSegs.getCurrentPosition() @@ -132,9 +132,9 @@ class LineNodePath(NodePath): Given a list of lists of points, draw a separate line for each list """ for pointList in lineList: - apply(self.moveTo, pointList[0]) + self.moveTo(*pointList[0]) for point in pointList[1:]: - apply(self.drawTo, point) + self.drawTo(*point) ## ## Given a point in space, and a direction, find the point of intersection diff --git a/contrib/src/sceneeditor/seLights.py b/contrib/src/sceneeditor/seLights.py index 09c5b2140a..2353512af5 100644 --- a/contrib/src/sceneeditor/seLights.py +++ b/contrib/src/sceneeditor/seLights.py @@ -3,7 +3,6 @@ # Written by Yi-Hong Lin, yihhongl@andrew.cmu.edu, 2004 ################################################################# from direct.showbase.DirectObject import * -from string import lower from direct.directtools import DirectUtil from panda3d.core import * import string @@ -341,7 +340,7 @@ class seLightManager(NodePath): if type == 'ambient': self.ambientCount += 1 if(name=='DEFAULT_NAME'): - light = AmbientLight('ambient_' + `self.ambientCount`) + light = AmbientLight('ambient_' + repr(self.ambientCount)) else: light = AmbientLight(name) @@ -350,7 +349,7 @@ class seLightManager(NodePath): elif type == 'directional': self.directionalCount += 1 if(name=='DEFAULT_NAME'): - light = DirectionalLight('directional_' + `self.directionalCount`) + light = DirectionalLight('directional_' + repr(self.directionalCount)) else: light = DirectionalLight(name) @@ -360,7 +359,7 @@ class seLightManager(NodePath): elif type == 'point': self.pointCount += 1 if(name=='DEFAULT_NAME'): - light = PointLight('point_' + `self.pointCount`) + light = PointLight('point_' + repr(self.pointCount)) else: light = PointLight(name) @@ -371,7 +370,7 @@ class seLightManager(NodePath): elif type == 'spot': self.spotCount += 1 if(name=='DEFAULT_NAME'): - light = Spotlight('spot_' + `self.spotCount`) + light = Spotlight('spot_' + repr(self.spotCount)) else: light = Spotlight(name) @@ -382,7 +381,7 @@ class seLightManager(NodePath): light.setAttenuation(Vec3(constant, linear, quadratic)) light.setExponent(exponent) else: - print 'Invalid light type' + print('Invalid light type') return None # Create the seLight objects and put the light object we just created into it. @@ -411,7 +410,7 @@ class seLightManager(NodePath): # Attention!! # only Spotlight obj nneds to be specified a lens node first. i.e. setLens() first! ################################################################# - type = lower(light.getType().getName()) + type = light.getType().getName().lower() specularColor = VBase4(1) position = Point3(0,0,0) @@ -451,7 +450,7 @@ class seLightManager(NodePath): quadratic = Attenuation.getZ() exponent = light.getExponent() else: - print 'Invalid light type' + print('Invalid light type') return None lightNode = seLight(light,self,type, @@ -508,7 +507,7 @@ class seLightManager(NodePath): # isLight(self.name) # Use a string as a index to check if there existing a light named "name" ################################################################# - return self.lightDict.has_key(name) + return name in self.lightDict def rename(self,oName,nName): ################################################################# @@ -523,7 +522,7 @@ class seLightManager(NodePath): del self.lightDict[oName] return self.lightDict.keys(),lightNode else: - print '----Light Mnager: No such Light!' + print('----Light Mnager: No such Light!') def getLightNodeList(self): ################################################################# diff --git a/contrib/src/sceneeditor/seMopathRecorder.py b/contrib/src/sceneeditor/seMopathRecorder.py index 0f856237d2..dc8bbd8d22 100644 --- a/contrib/src/sceneeditor/seMopathRecorder.py +++ b/contrib/src/sceneeditor/seMopathRecorder.py @@ -25,10 +25,17 @@ from direct.tkwidgets.Slider import Slider from direct.tkwidgets.EntryScale import EntryScale from direct.tkwidgets.VectorWidgets import Vector2Entry, Vector3Entry from direct.tkwidgets.VectorWidgets import ColorEntry -from Tkinter import Button, Frame, Radiobutton, Checkbutton, Label -from Tkinter import StringVar, BooleanVar, Entry, Scale -import os, string, Tkinter, Pmw -import __builtin__ +import os, string, sys, Pmw + +if sys.version_info >= (3, 0): + from tkinter import Button, Frame, Radiobutton, Checkbutton, Label + from tkinter import StringVar, BooleanVar, Entry, Scale + import tkinter +else: + from Tkinter import Button, Frame, Radiobutton, Checkbutton, Label + from Tkinter import StringVar, BooleanVar, Entry, Scale + import Tkinter as tkinter + PRF_UTILITIES = [ 'lambda: camera.lookAt(render)', @@ -123,7 +130,7 @@ class MopathRecorder(AppShell, DirectObject): self.postPoints = [] self.pointSetDict = {} self.pointSetCount = 0 - self.pointSetName = self.name + '-ps-' + `self.pointSetCount` + self.pointSetName = self.name + '-ps-' + repr(self.pointSetCount) # User callback to call before recording point self.samplingMode = 'Continuous' self.preRecordFunc = None @@ -233,7 +240,7 @@ class MopathRecorder(AppShell, DirectObject): self.undoButton['state'] = 'normal' else: self.undoButton['state'] = 'disabled' - self.undoButton.pack(side = Tkinter.LEFT, expand = 0) + self.undoButton.pack(side = tkinter.LEFT, expand = 0) self.bind(self.undoButton, 'Undo last operation') self.redoButton = Button(self.menuFrame, text = 'Redo', @@ -242,19 +249,19 @@ class MopathRecorder(AppShell, DirectObject): self.redoButton['state'] = 'normal' else: self.redoButton['state'] = 'disabled' - self.redoButton.pack(side = Tkinter.LEFT, expand = 0) + self.redoButton.pack(side = tkinter.LEFT, expand = 0) self.bind(self.redoButton, 'Redo last operation') # Record button - mainFrame = Frame(interior, relief = Tkinter.SUNKEN, borderwidth = 2) + mainFrame = Frame(interior, relief = tkinter.SUNKEN, borderwidth = 2) frame = Frame(mainFrame) # Active node path # Button to select active node path widget = self.createButton(frame, 'Recording', 'Node Path:', 'Select Active Mopath Node Path', lambda s = self: SEditor.select(s.nodePath), - side = Tkinter.LEFT, expand = 0) - widget['relief'] = Tkinter.FLAT + side = tkinter.LEFT, expand = 0) + widget['relief'] = tkinter.FLAT self.nodePathMenu = Pmw.ComboBox( frame, entry_width = 20, selectioncommand = self.selectNodePathNamed, @@ -264,7 +271,7 @@ class MopathRecorder(AppShell, DirectObject): self.nodePathMenu.component('entryfield_entry')) self.nodePathMenuBG = ( self.nodePathMenuEntry.configure('background')[3]) - self.nodePathMenu.pack(side = Tkinter.LEFT, fill = Tkinter.X, expand = 1) + self.nodePathMenu.pack(side = tkinter.LEFT, fill = tkinter.X, expand = 1) self.bind(self.nodePathMenu, 'Select active node path used for recording and playback') # Recording type @@ -285,81 +292,81 @@ class MopathRecorder(AppShell, DirectObject): 'Recording', 'Extend', ('Next record session extends existing path'), self.recordingType, 'Extend', expand = 0) - frame.pack(fill = Tkinter.X, expand = 1) + frame.pack(fill = tkinter.X, expand = 1) frame = Frame(mainFrame) widget = self.createCheckbutton( frame, 'Recording', 'Record', 'On: path is being recorded', self.toggleRecord, 0, - side = Tkinter.LEFT, fill = Tkinter.BOTH, expand = 1) - widget.configure(foreground = 'Red', relief = Tkinter.RAISED, borderwidth = 2, - anchor = Tkinter.CENTER, width = 16) + side = tkinter.LEFT, fill = tkinter.BOTH, expand = 1) + widget.configure(foreground = 'Red', relief = tkinter.RAISED, borderwidth = 2, + anchor = tkinter.CENTER, width = 16) widget = self.createButton(frame, 'Recording', 'Add Keyframe', 'Add Keyframe To Current Path', self.addKeyframe, - side = Tkinter.LEFT, expand = 1) + side = tkinter.LEFT, expand = 1) widget = self.createButton(frame, 'Recording', 'Bind Path to Node', 'Bind Motion Path to selected Object', self.bindMotionPathToNode, - side = Tkinter.LEFT, expand = 1) + side = tkinter.LEFT, expand = 1) - frame.pack(fill = Tkinter.X, expand = 1) + frame.pack(fill = tkinter.X, expand = 1) - mainFrame.pack(expand = 1, fill = Tkinter.X, pady = 3) + mainFrame.pack(expand = 1, fill = tkinter.X, pady = 3) # Playback controls - playbackFrame = Frame(interior, relief = Tkinter.SUNKEN, + playbackFrame = Frame(interior, relief = tkinter.SUNKEN, borderwidth = 2) Label(playbackFrame, text = 'PLAYBACK CONTROLS', - font=('MSSansSerif', 12, 'bold')).pack(fill = Tkinter.X) + font=('MSSansSerif', 12, 'bold')).pack(fill = tkinter.X) # Main playback control slider widget = self.createEntryScale( playbackFrame, 'Playback', 'Time', 'Set current playback time', - resolution = 0.01, command = self.playbackGoTo, side = Tkinter.TOP) - widget.component('hull')['relief'] = Tkinter.RIDGE + resolution = 0.01, command = self.playbackGoTo, side = tkinter.TOP) + widget.component('hull')['relief'] = tkinter.RIDGE # Kill playback task if drag slider widget['preCallback'] = self.stopPlayback # Jam duration entry into entry scale self.createLabeledEntry(widget.labelFrame, 'Resample', 'Path Duration', 'Set total curve duration', command = self.setPathDuration, - side = Tkinter.LEFT, expand = 0) + side = tkinter.LEFT, expand = 0) # Start stop buttons frame = Frame(playbackFrame) widget = self.createButton(frame, 'Playback', '<<', 'Jump to start of playback', self.jumpToStartOfPlayback, - side = Tkinter.LEFT, expand = 1) + side = tkinter.LEFT, expand = 1) widget['font'] = (('MSSansSerif', 12, 'bold')) widget = self.createCheckbutton(frame, 'Playback', 'Play', 'Start/Stop playback', self.startStopPlayback, 0, - side = Tkinter.LEFT, fill = Tkinter.BOTH, expand = 1) + side = tkinter.LEFT, fill = tkinter.BOTH, expand = 1) widget.configure(anchor = 'center', justify = 'center', - relief = Tkinter.RAISED, font = ('MSSansSerif', 12, 'bold')) + relief = tkinter.RAISED, font = ('MSSansSerif', 12, 'bold')) widget = self.createButton(frame, 'Playback', '>>', 'Jump to end of playback', self.jumpToEndOfPlayback, - side = Tkinter.LEFT, expand = 1) + side = tkinter.LEFT, expand = 1) widget['font'] = (('MSSansSerif', 12, 'bold')) self.createCheckbutton(frame, 'Playback', 'Loop', 'On: loop playback', self.setLoopPlayback, self.loopPlayback, - side = Tkinter.LEFT, fill = Tkinter.BOTH, expand = 0) - frame.pack(fill = Tkinter.X, expand = 1) + side = tkinter.LEFT, fill = tkinter.BOTH, expand = 0) + frame.pack(fill = tkinter.X, expand = 1) # Speed control frame = Frame(playbackFrame) - widget = Button(frame, text = 'PB Speed Vernier', relief = Tkinter.FLAT, + widget = Button(frame, text = 'PB Speed Vernier', relief = tkinter.FLAT, command = lambda s = self: s.setSpeedScale(1.0)) - widget.pack(side = Tkinter.LEFT, expand = 0) + widget.pack(side = tkinter.LEFT, expand = 0) self.speedScale = Scale(frame, from_ = -1, to = 1, resolution = 0.01, showvalue = 0, width = 10, orient = 'horizontal', command = self.setPlaybackSF) - self.speedScale.pack(side = Tkinter.LEFT, fill = Tkinter.X, expand = 1) + self.speedScale.pack(side = tkinter.LEFT, fill = tkinter.X, expand = 1) self.speedVar = StringVar() self.speedVar.set("0.00") self.speedEntry = Entry(frame, textvariable = self.speedVar, @@ -368,14 +375,14 @@ class MopathRecorder(AppShell, DirectObject): '', lambda e = None, s = self: s.setSpeedScale( string.atof(s.speedVar.get()))) - self.speedEntry.pack(side = Tkinter.LEFT, expand = 0) - frame.pack(fill = Tkinter.X, expand = 1) + self.speedEntry.pack(side = tkinter.LEFT, expand = 0) + frame.pack(fill = tkinter.X, expand = 1) - playbackFrame.pack(fill = Tkinter.X, pady = 2) + playbackFrame.pack(fill = tkinter.X, pady = 2) # Create notebook pages self.mainNotebook = Pmw.NoteBook(interior) - self.mainNotebook.pack(fill = Tkinter.BOTH, expand = 1) + self.mainNotebook.pack(fill = tkinter.BOTH, expand = 1) self.resamplePage = self.mainNotebook.add('Resample') self.refinePage = self.mainNotebook.add('Refine') self.extendPage = self.mainNotebook.add('Extend') @@ -386,35 +393,35 @@ class MopathRecorder(AppShell, DirectObject): ## RESAMPLE PAGE label = Label(self.resamplePage, text = 'RESAMPLE CURVE', font=('MSSansSerif', 12, 'bold')) - label.pack(fill = Tkinter.X) + label.pack(fill = tkinter.X) # Resample resampleFrame = Frame( - self.resamplePage, relief = Tkinter.SUNKEN, borderwidth = 2) + self.resamplePage, relief = tkinter.SUNKEN, borderwidth = 2) label = Label(resampleFrame, text = 'RESAMPLE CURVE', font=('MSSansSerif', 12, 'bold')).pack() widget = self.createSlider( resampleFrame, 'Resample', 'Num. Samples', 'Number of samples in resampled curve', resolution = 1, min = 2, max = 1000, command = self.setNumSamples) - widget.component('hull')['relief'] = Tkinter.RIDGE + widget.component('hull')['relief'] = tkinter.RIDGE widget['postCallback'] = self.sampleCurve frame = Frame(resampleFrame) self.createButton( frame, 'Resample', 'Make Even', 'Apply timewarp so resulting path has constant velocity', - self.makeEven, side = Tkinter.LEFT, fill = Tkinter.X, expand = 1) + self.makeEven, side = tkinter.LEFT, fill = tkinter.X, expand = 1) self.createButton( frame, 'Resample', 'Face Forward', 'Compute HPR so resulting hpr curve faces along xyz tangent', - self.faceForward, side = Tkinter.LEFT, fill = Tkinter.X, expand = 1) - frame.pack(fill = Tkinter.X, expand = 0) - resampleFrame.pack(fill = Tkinter.X, expand = 0, pady = 2) + self.faceForward, side = tkinter.LEFT, fill = tkinter.X, expand = 1) + frame.pack(fill = tkinter.X, expand = 0) + resampleFrame.pack(fill = tkinter.X, expand = 0, pady = 2) # Desample desampleFrame = Frame( - self.resamplePage, relief = Tkinter.SUNKEN, borderwidth = 2) + self.resamplePage, relief = tkinter.SUNKEN, borderwidth = 2) Label(desampleFrame, text = 'DESAMPLE CURVE', font=('MSSansSerif', 12, 'bold')).pack() widget = self.createSlider( @@ -422,16 +429,16 @@ class MopathRecorder(AppShell, DirectObject): 'Specify number of points to skip between samples', min = 1, max = 100, resolution = 1, command = self.setDesampleFrequency) - widget.component('hull')['relief'] = Tkinter.RIDGE + widget.component('hull')['relief'] = tkinter.RIDGE widget['postCallback'] = self.desampleCurve - desampleFrame.pack(fill = Tkinter.X, expand = 0, pady = 2) + desampleFrame.pack(fill = tkinter.X, expand = 0, pady = 2) ## REFINE PAGE ## - refineFrame = Frame(self.refinePage, relief = Tkinter.SUNKEN, + refineFrame = Frame(self.refinePage, relief = tkinter.SUNKEN, borderwidth = 2) label = Label(refineFrame, text = 'REFINE CURVE', font=('MSSansSerif', 12, 'bold')) - label.pack(fill = Tkinter.X) + label.pack(fill = tkinter.X) widget = self.createSlider(refineFrame, 'Refine Page', 'Refine From', @@ -460,14 +467,14 @@ class MopathRecorder(AppShell, DirectObject): command = self.setRefineStop) widget['preCallback'] = self.setRefineMode widget['postCallback'] = self.getPostPoints - refineFrame.pack(fill = Tkinter.X) + refineFrame.pack(fill = tkinter.X) ## EXTEND PAGE ## - extendFrame = Frame(self.extendPage, relief = Tkinter.SUNKEN, + extendFrame = Frame(self.extendPage, relief = tkinter.SUNKEN, borderwidth = 2) label = Label(extendFrame, text = 'EXTEND CURVE', font=('MSSansSerif', 12, 'bold')) - label.pack(fill = Tkinter.X) + label.pack(fill = tkinter.X) widget = self.createSlider(extendFrame, 'Extend Page', 'Extend From', @@ -483,14 +490,14 @@ class MopathRecorder(AppShell, DirectObject): resolution = 0.01, command = self.setControlStart) widget['preCallback'] = self.setExtendMode - extendFrame.pack(fill = Tkinter.X) + extendFrame.pack(fill = tkinter.X) ## CROP PAGE ## - cropFrame = Frame(self.cropPage, relief = Tkinter.SUNKEN, + cropFrame = Frame(self.cropPage, relief = tkinter.SUNKEN, borderwidth = 2) label = Label(cropFrame, text = 'CROP CURVE', font=('MSSansSerif', 12, 'bold')) - label.pack(fill = Tkinter.X) + label.pack(fill = tkinter.X) widget = self.createSlider( cropFrame, @@ -508,11 +515,11 @@ class MopathRecorder(AppShell, DirectObject): self.createButton(cropFrame, 'Crop Page', 'Crop Curve', 'Crop curve to specified from to times', - self.cropCurve, fill = Tkinter.NONE) - cropFrame.pack(fill = Tkinter.X) + self.cropCurve, fill = tkinter.NONE) + cropFrame.pack(fill = tkinter.X) ## DRAW PAGE ## - drawFrame = Frame(self.drawPage, relief = Tkinter.SUNKEN, + drawFrame = Frame(self.drawPage, relief = tkinter.SUNKEN, borderwidth = 2) self.sf = Pmw.ScrolledFrame(self.drawPage, horizflex = 'elastic') @@ -521,57 +528,57 @@ class MopathRecorder(AppShell, DirectObject): label = Label(sfFrame, text = 'CURVE RENDERING STYLE', font=('MSSansSerif', 12, 'bold')) - label.pack(fill = Tkinter.X) + label.pack(fill = tkinter.X) frame = Frame(sfFrame) - Label(frame, text = 'SHOW:').pack(side = Tkinter.LEFT, expand = 0) + Label(frame, text = 'SHOW:').pack(side = tkinter.LEFT, expand = 0) widget = self.createCheckbutton( frame, 'Style', 'Path', 'On: path is visible', self.setPathVis, 1, - side = Tkinter.LEFT, fill = Tkinter.X, expand = 1) + side = tkinter.LEFT, fill = tkinter.X, expand = 1) widget = self.createCheckbutton( frame, 'Style', 'Knots', 'On: path knots are visible', self.setKnotVis, 1, - side = Tkinter.LEFT, fill = Tkinter.X, expand = 1) + side = tkinter.LEFT, fill = tkinter.X, expand = 1) widget = self.createCheckbutton( frame, 'Style', 'CVs', 'On: path CVs are visible', self.setCvVis, 0, - side = Tkinter.LEFT, fill = Tkinter.X, expand = 1) + side = tkinter.LEFT, fill = tkinter.X, expand = 1) widget = self.createCheckbutton( frame, 'Style', 'Hull', 'On: path hull is visible', self.setHullVis, 0, - side = Tkinter.LEFT, fill = Tkinter.X, expand = 1) + side = tkinter.LEFT, fill = tkinter.X, expand = 1) widget = self.createCheckbutton( frame, 'Style', 'Trace', 'On: record is visible', self.setTraceVis, 0, - side = Tkinter.LEFT, fill = Tkinter.X, expand = 1) + side = tkinter.LEFT, fill = tkinter.X, expand = 1) widget = self.createCheckbutton( frame, 'Style', 'Marker', 'On: playback marker is visible', self.setMarkerVis, 0, - side = Tkinter.LEFT, fill = Tkinter.X, expand = 1) - frame.pack(fill = Tkinter.X, expand = 1) + side = tkinter.LEFT, fill = tkinter.X, expand = 1) + frame.pack(fill = tkinter.X, expand = 1) # Sliders widget = self.createSlider( sfFrame, 'Style', 'Num Segs', 'Set number of segments used to approximate each parametric unit', min = 1.0, max = 400, resolution = 1.0, value = 40, - command = self.setNumSegs, side = Tkinter.TOP) - widget.component('hull')['relief'] = Tkinter.RIDGE + command = self.setNumSegs, side = tkinter.TOP) + widget.component('hull')['relief'] = tkinter.RIDGE widget = self.createSlider( sfFrame, 'Style', 'Num Ticks', 'Set number of tick marks drawn for each unit of time', min = 0.0, max = 10.0, resolution = 1.0, value = 0.0, - command = self.setNumTicks, side = Tkinter.TOP) - widget.component('hull')['relief'] = Tkinter.RIDGE + command = self.setNumTicks, side = tkinter.TOP) + widget.component('hull')['relief'] = tkinter.RIDGE widget = self.createSlider( sfFrame, 'Style', 'Tick Scale', 'Set visible size of time tick marks', min = 0.01, max = 100.0, resolution = 0.01, value = 5.0, - command = self.setTickScale, side = Tkinter.TOP) - widget.component('hull')['relief'] = Tkinter.RIDGE + command = self.setTickScale, side = tkinter.TOP) + widget.component('hull')['relief'] = tkinter.RIDGE self.createColorEntry( sfFrame, 'Style', 'Path Color', 'Color of curve', @@ -598,14 +605,14 @@ class MopathRecorder(AppShell, DirectObject): command = self.setHullColor, value = [255.0,128.0,128.0,255.0]) - #drawFrame.pack(fill = Tkinter.X) + #drawFrame.pack(fill = tkinter.X) ## OPTIONS PAGE ## - optionsFrame = Frame(self.optionsPage, relief = Tkinter.SUNKEN, + optionsFrame = Frame(self.optionsPage, relief = tkinter.SUNKEN, borderwidth = 2) label = Label(optionsFrame, text = 'RECORDING OPTIONS', font=('MSSansSerif', 12, 'bold')) - label.pack(fill = Tkinter.X) + label.pack(fill = tkinter.X) # Hooks frame = Frame(optionsFrame) widget = self.createLabeledEntry( @@ -614,7 +621,7 @@ class MopathRecorder(AppShell, DirectObject): value = self.startStopHook, command = self.setStartStopHook)[0] label = self.getWidget('Recording', 'Record Hook-Label') - label.configure(width = 16, anchor = Tkinter.W) + label.configure(width = 16, anchor = tkinter.W) self.setStartStopHook() widget = self.createLabeledEntry( frame, 'Recording', 'Keyframe Hook', @@ -622,9 +629,9 @@ class MopathRecorder(AppShell, DirectObject): value = self.keyframeHook, command = self.setKeyframeHook)[0] label = self.getWidget('Recording', 'Keyframe Hook-Label') - label.configure(width = 16, anchor = Tkinter.W) + label.configure(width = 16, anchor = tkinter.W) self.setKeyframeHook() - frame.pack(expand = 1, fill = Tkinter.X) + frame.pack(expand = 1, fill = tkinter.X) # PreRecordFunc frame = Frame(optionsFrame) widget = self.createComboBox( @@ -632,17 +639,17 @@ class MopathRecorder(AppShell, DirectObject): 'Function called before sampling each point', PRF_UTILITIES, self.setPreRecordFunc, history = 1, expand = 1) - widget.configure(label_width = 16, label_anchor = Tkinter.W) + widget.configure(label_width = 16, label_anchor = tkinter.W) widget.configure(entryfield_entry_state = 'normal') # Initialize preRecordFunc self.preRecordFunc = eval(PRF_UTILITIES[0]) self.createCheckbutton(frame, 'Recording', 'PRF Active', 'On: Pre Record Func enabled', None, 0, - side = Tkinter.LEFT, fill = Tkinter.BOTH, expand = 0) - frame.pack(expand = 1, fill = Tkinter.X) + side = tkinter.LEFT, fill = tkinter.BOTH, expand = 0) + frame.pack(expand = 1, fill = tkinter.X) # Pack record frame - optionsFrame.pack(fill = Tkinter.X, pady = 2) + optionsFrame.pack(fill = tkinter.X, pady = 2) self.mainNotebook.setnaturalsize() @@ -682,7 +689,7 @@ class MopathRecorder(AppShell, DirectObject): marker if subnode selected """ taskMgr.remove(self.name + '-curveEditTask') - print nodePath.get_key() + print(nodePath.get_key()) if nodePath.get_key() in self.playbackMarkerIds: SEditor.select(self.playbackMarker) elif nodePath.get_key() in self.tangentMarkerIds: @@ -799,7 +806,7 @@ class MopathRecorder(AppShell, DirectObject): def createNewPointSet(self, curveName = None): if curveName == None: - self.pointSetName = self.name + '-ps-' + `self.pointSetCount` + self.pointSetName = self.name + '-ps-' + repr(self.pointSetCount) else: self.pointSetName = curveName # Update dictionary and record pointer to new point set @@ -1137,7 +1144,7 @@ class MopathRecorder(AppShell, DirectObject): def computeCurves(self): # Check to make sure curve fitters have points if (self.curveFitter.getNumSamples() == 0): - print 'MopathRecorder.computeCurves: Must define curve first' + print('MopathRecorder.computeCurves: Must define curve first') return # Create curves # XYZ @@ -1282,8 +1289,8 @@ class MopathRecorder(AppShell, DirectObject): dictName = name else: # Generate a unique name for the dict - dictName = name # + '-' + `nodePath.get_key()` - if not dict.has_key(dictName): + dictName = name # + '-' + repr(nodePath.get_key()) + if dictName not in dict: # Update combo box to include new item names.append(dictName) listbox = menu.component('scrolledlist') @@ -1386,7 +1393,7 @@ class MopathRecorder(AppShell, DirectObject): def desampleCurve(self): if (self.curveFitter.getNumSamples() == 0): - print 'MopathRecorder.desampleCurve: Must define curve first' + print('MopathRecorder.desampleCurve: Must define curve first') return # NOTE: This is destructive, points will be deleted from curve fitter self.curveFitter.desample(self.desampleFrequency) @@ -1400,7 +1407,7 @@ class MopathRecorder(AppShell, DirectObject): def sampleCurve(self, fCompute = 1, curveName = None): if self.curveCollection == None: - print 'MopathRecorder.sampleCurve: Must define curve first' + print('MopathRecorder.sampleCurve: Must define curve first') return # Reset curve fitters self.curveFitter.reset() @@ -1617,7 +1624,7 @@ class MopathRecorder(AppShell, DirectObject): def cropCurve(self): if self.pointSet == None: - print 'Empty Point Set' + print('Empty Point Set') return # Keep handle on old points oldPoints = self.pointSet @@ -1653,15 +1660,15 @@ class MopathRecorder(AppShell, DirectObject): # Use first directory in model path mPath = getModelPath() if mPath.getNumDirectories() > 0: - if `mPath.getDirectory(0)` == '.': + if repr(mPath.getDirectory(0)) == '.': path = '.' else: path = mPath.getDirectory(0).toOsSpecific() else: path = '.' if not os.path.isdir(path): - print 'MopathRecorder Info: Empty Model Path!' - print 'Using current directory' + print('MopathRecorder Info: Empty Model Path!') + print('Using current directory') path = '.' mopathFilename = askopenfilename( defaultextension = '.egg', @@ -1692,15 +1699,15 @@ class MopathRecorder(AppShell, DirectObject): # Use first directory in model path mPath = getModelPath() if mPath.getNumDirectories() > 0: - if `mPath.getDirectory(0)` == '.': + if repr(mPath.getDirectory(0)) == '.': path = '.' else: path = mPath.getDirectory(0).toOsSpecific() else: path = '.' if not os.path.isdir(path): - print 'MopathRecorder Info: Empty Model Path!' - print 'Using current directory' + print('MopathRecorder Info: Empty Model Path!') + print('Using current directory') path = '.' mopathFilename = asksaveasfilename( defaultextension = '.egg', @@ -1734,28 +1741,28 @@ class MopathRecorder(AppShell, DirectObject): def createLabeledEntry(self, parent, category, text, balloonHelp, value = '', command = None, - relief = 'sunken', side = Tkinter.LEFT, + relief = 'sunken', side = tkinter.LEFT, expand = 1, width = 12): frame = Frame(parent) variable = StringVar() variable.set(value) label = Label(frame, text = text) - label.pack(side = Tkinter.LEFT, fill = Tkinter.X) + label.pack(side = tkinter.LEFT, fill = tkinter.X) self.bind(label, balloonHelp) self.widgetDict[category + '-' + text + '-Label'] = label entry = Entry(frame, width = width, relief = relief, textvariable = variable) - entry.pack(side = Tkinter.LEFT, fill = Tkinter.X, expand = expand) + entry.pack(side = tkinter.LEFT, fill = tkinter.X, expand = expand) self.bind(entry, balloonHelp) self.widgetDict[category + '-' + text] = entry self.variableDict[category + '-' + text] = variable if command: entry.bind('', command) - frame.pack(side = side, fill = Tkinter.X, expand = expand) + frame.pack(side = side, fill = tkinter.X, expand = expand) return (frame, label, entry) def createButton(self, parent, category, text, balloonHelp, command, - side = 'top', expand = 0, fill = Tkinter.X): + side = 'top', expand = 0, fill = tkinter.X): widget = Button(parent, text = text) # Do this after the widget so command isn't called on creation widget['command'] = command @@ -1766,10 +1773,10 @@ class MopathRecorder(AppShell, DirectObject): def createCheckbutton(self, parent, category, text, balloonHelp, command, initialState, - side = 'top', fill = Tkinter.X, expand = 0): + side = 'top', fill = tkinter.X, expand = 0): bool = BooleanVar() bool.set(initialState) - widget = Checkbutton(parent, text = text, anchor = Tkinter.W, + widget = Checkbutton(parent, text = text, anchor = tkinter.W, variable = bool) # Do this after the widget so command isn't called on creation widget['command'] = command @@ -1781,8 +1788,8 @@ class MopathRecorder(AppShell, DirectObject): def createRadiobutton(self, parent, side, category, text, balloonHelp, variable, value, - command = None, fill = Tkinter.X, expand = 0): - widget = Radiobutton(parent, text = text, anchor = Tkinter.W, + command = None, fill = tkinter.X, expand = 0): + widget = Radiobutton(parent, text = text, anchor = tkinter.W, variable = variable, value = value) # Do this after the widget so command isn't called on creation widget['command'] = command @@ -1798,10 +1805,10 @@ class MopathRecorder(AppShell, DirectObject): kw['min'] = min kw['maxVelocity'] = maxVelocity kw['resolution'] = resolution - widget = apply(Floater, (parent,), kw) + widget = Floater(parent, **kw) # Do this after the widget so command isn't called on creation widget['command'] = command - widget.pack(fill = Tkinter.X) + widget.pack(fill = tkinter.X) self.bind(widget, balloonHelp) self.widgetDict[category + '-' + text] = widget return widget @@ -1809,10 +1816,10 @@ class MopathRecorder(AppShell, DirectObject): def createAngleDial(self, parent, category, text, balloonHelp, command = None, **kw): kw['text'] = text - widget = apply(AngleDial,(parent,), kw) + widget = AngleDial(parent, **kw) # Do this after the widget so command isn't called on creation widget['command'] = command - widget.pack(fill = Tkinter.X) + widget.pack(fill = tkinter.X) self.bind(widget, balloonHelp) self.widgetDict[category + '-' + text] = widget return widget @@ -1820,13 +1827,13 @@ class MopathRecorder(AppShell, DirectObject): def createSlider(self, parent, category, text, balloonHelp, command = None, min = 0.0, max = 1.0, resolution = None, - side = Tkinter.TOP, fill = Tkinter.X, expand = 1, **kw): + side = tkinter.TOP, fill = tkinter.X, expand = 1, **kw): kw['text'] = text kw['min'] = min kw['max'] = max kw['resolution'] = resolution #widget = apply(EntryScale, (parent,), kw) - widget = apply(Slider, (parent,), kw) + widget = Slider(parent, **kw) # Do this after the widget so command isn't called on creation widget['command'] = command widget.pack(side = side, fill = fill, expand = expand) @@ -1837,12 +1844,12 @@ class MopathRecorder(AppShell, DirectObject): def createEntryScale(self, parent, category, text, balloonHelp, command = None, min = 0.0, max = 1.0, resolution = None, - side = Tkinter.TOP, fill = Tkinter.X, expand = 1, **kw): + side = tkinter.TOP, fill = tkinter.X, expand = 1, **kw): kw['text'] = text kw['min'] = min kw['max'] = max kw['resolution'] = resolution - widget = apply(EntryScale, (parent,), kw) + widget = EntryScale(parent, **kw) # Do this after the widget so command isn't called on creation widget['command'] = command widget.pack(side = side, fill = fill, expand = expand) @@ -1854,10 +1861,10 @@ class MopathRecorder(AppShell, DirectObject): command = None, **kw): # Set label's text kw['text'] = text - widget = apply(Vector2Entry, (parent,), kw) + widget = Vector2Entry(parent, **kw) # Do this after the widget so command isn't called on creation widget['command'] = command - widget.pack(fill = Tkinter.X) + widget.pack(fill = tkinter.X) self.bind(widget, balloonHelp) self.widgetDict[category + '-' + text] = widget return widget @@ -1866,10 +1873,10 @@ class MopathRecorder(AppShell, DirectObject): command = None, **kw): # Set label's text kw['text'] = text - widget = apply(Vector3Entry, (parent,), kw) + widget = Vector3Entry(parent, **kw) # Do this after the widget so command isn't called on creation widget['command'] = command - widget.pack(fill = Tkinter.X) + widget.pack(fill = tkinter.X) self.bind(widget, balloonHelp) self.widgetDict[category + '-' + text] = widget return widget @@ -1878,10 +1885,10 @@ class MopathRecorder(AppShell, DirectObject): command = None, **kw): # Set label's text kw['text'] = text - widget = apply(ColorEntry, (parent,) ,kw) + widget = ColorEntry(parent, **kw) # Do this after the widget so command isn't called on creation widget['command'] = command - widget.pack(fill = Tkinter.X) + widget.pack(fill = tkinter.X) self.bind(widget, balloonHelp) self.widgetDict[category + '-' + text] = widget return widget @@ -1891,13 +1898,13 @@ class MopathRecorder(AppShell, DirectObject): optionVar = StringVar() if len(items) > 0: optionVar.set(items[0]) - widget = Pmw.OptionMenu(parent, labelpos = Tkinter.W, label_text = text, + widget = Pmw.OptionMenu(parent, labelpos = tkinter.W, label_text = text, label_width = 12, menu_tearoff = 1, menubutton_textvariable = optionVar, items = items) # Do this after the widget so command isn't called on creation widget['command'] = command - widget.pack(fill = Tkinter.X) + widget.pack(fill = tkinter.X) self.bind(widget.component('menubutton'), balloonHelp) self.widgetDict[category + '-' + text] = widget self.variableDict[category + '-' + text] = optionVar @@ -1905,9 +1912,9 @@ class MopathRecorder(AppShell, DirectObject): def createComboBox(self, parent, category, text, balloonHelp, items, command, history = 0, - side = Tkinter.LEFT, expand = 0, fill = Tkinter.X): + side = tkinter.LEFT, expand = 0, fill = tkinter.X): widget = Pmw.ComboBox(parent, - labelpos = Tkinter.W, + labelpos = tkinter.W, label_text = text, label_anchor = 'e', label_width = 12, @@ -1959,14 +1966,14 @@ class MopathRecorder(AppShell, DirectObject): def bindMotionPathToNode(self): if self.curveCollection == None: - print '----Error: you need to select or create a curve first!' + print('----Error: you need to select or create a curve first!') return self.accept('MP_checkName', self.bindMotionPath) self.askName = namePathPanel(MopathRecorder.count) return def bindMotionPath(self,name=None,test=None): - print test + print(test) self.ignore('MP_checkName') del self.askName self.curveCollection.getCurve(0).setName(name) @@ -1993,7 +2000,7 @@ class MopathRecorder(AppShell, DirectObject): If the list is not None, it will put the vurve back into the curve list. else, do nothing. ''' - print curveList + print(curveList) self.ignore('curveListFor'+self.name) if curveList != None: for collection in curveList: @@ -2037,8 +2044,8 @@ class namePathPanel(AppShell): dataFrame = Frame(mainFrame) label = Label(dataFrame, text='This name will be used as a reference for this Path.',font=('MSSansSerif', 10)) - label.pack(side = Tkinter.TOP, expand = 0, fill = Tkinter.X) - dataFrame.pack(side = Tkinter.TOP, expand = 0, fill = Tkinter.X, padx=5, pady=10) + label.pack(side = tkinter.TOP, expand = 0, fill = tkinter.X) + dataFrame.pack(side = tkinter.TOP, expand = 0, fill = tkinter.X, padx=5, pady=10) dataFrame = Frame(mainFrame) self.inputZone = Pmw.EntryField(dataFrame, labelpos='w', label_text = 'Name Selected Path: ', @@ -2046,14 +2053,14 @@ class namePathPanel(AppShell): label_font=('MSSansSerif', 10), validate = None, entry_width = 20) - self.inputZone.pack(side = Tkinter.LEFT, fill=Tkinter.X,expand=0) + self.inputZone.pack(side = tkinter.LEFT, fill=tkinter.X,expand=0) self.button_ok = Button(dataFrame, text="OK", command=self.ok_press,width=10) - self.button_ok.pack(fill=Tkinter.X,expand=0,side=Tkinter.LEFT, padx = 3) + self.button_ok.pack(fill=tkinter.X,expand=0,side=tkinter.LEFT, padx = 3) - dataFrame.pack(side = Tkinter.TOP, expand = 0, fill = Tkinter.X, padx=10, pady=10) + dataFrame.pack(side = tkinter.TOP, expand = 0, fill = tkinter.X, padx=10, pady=10) - mainFrame.pack(expand = 1, fill = Tkinter.BOTH) + mainFrame.pack(expand = 1, fill = tkinter.BOTH) diff --git a/contrib/src/sceneeditor/seParticleEffect.py b/contrib/src/sceneeditor/seParticleEffect.py index 8ad3a658a8..a36f7d4025 100644 --- a/contrib/src/sceneeditor/seParticleEffect.py +++ b/contrib/src/sceneeditor/seParticleEffect.py @@ -209,9 +209,9 @@ class ParticleEffect(NodePath): """loadConfig(filename)""" #try: # if vfs: - print vfs.readFile(filename) - exec vfs.readFile(filename) - print "Particle Effect Reading using VFS" + print(vfs.readFile(filename)) + exec(vfs.readFile(filename)) + print("Particle Effect Reading using VFS") # else: # execfile(filename.toOsSpecific()) # print "Shouldnt be wrong" diff --git a/contrib/src/sceneeditor/seParticlePanel.py b/contrib/src/sceneeditor/seParticlePanel.py index 099e31012d..3c359e2628 100644 --- a/contrib/src/sceneeditor/seParticlePanel.py +++ b/contrib/src/sceneeditor/seParticlePanel.py @@ -2,9 +2,7 @@ # Import Tkinter, Pmw, and the floater code from this directory tree. from direct.tkwidgets.AppShell import AppShell -from tkFileDialog import * -from tkSimpleDialog import askstring -import os, Pmw, Tkinter +import os, Pmw, sys from direct.tkwidgets.Dial import AngleDial from direct.tkwidgets.Floater import Floater from direct.tkwidgets.Slider import Slider @@ -15,6 +13,15 @@ import seForceGroup import seParticles import seParticleEffect + +if sys.version_info >= (3, 0): + from tkinter.filedialog import * + from tkinter.simpledialog import askstring +else: + from tkFileDialog import * + from tkSimpleDialog import askstring + + class ParticlePanel(AppShell): # Override class variables appname = 'Particle Panel' @@ -774,7 +781,7 @@ class ParticlePanel(AppShell): kw['min'] = min kw['resolution'] = resolution kw['numDigits'] = numDigits - widget = apply(Floater, (parent,), kw) + widget = Floater(parent, **kw) # Do this after the widget so command isn't called on creation widget['command'] = command widget.pack(fill = X) @@ -786,7 +793,7 @@ class ParticlePanel(AppShell): command = None, **kw): kw['text'] = text kw['style'] = 'mini' - widget = apply(AngleDial,(parent,), kw) + widget = AngleDial(parent, **kw) # Do this after the widget so command isn't called on creation widget['command'] = command widget.pack(fill = X) @@ -801,7 +808,7 @@ class ParticlePanel(AppShell): kw['min'] = min kw['max'] = max kw['resolution'] = resolution - widget = apply(Slider, (parent,), kw) + widget = Slider(parent, **kw) # Do this after the widget so command isn't called on creation widget['command'] = command widget.pack(fill = X) @@ -813,7 +820,7 @@ class ParticlePanel(AppShell): command = None, **kw): # Set label's text kw['text'] = text - widget = apply(Vector2Entry, (parent,), kw) + widget = Vector2Entry(parent, **kw) # Do this after the widget so command isn't called on creation widget['command'] = command widget.pack(fill = X) @@ -825,7 +832,7 @@ class ParticlePanel(AppShell): command = None, **kw): # Set label's text kw['text'] = text - widget = apply(Vector3Entry, (parent,), kw) + widget = Vector3Entry(parent, **kw) # Do this after the widget so command isn't called on creation widget['command'] = command widget.pack(fill = X) @@ -837,7 +844,7 @@ class ParticlePanel(AppShell): command = None, **kw): # Set label's text kw['text'] = text - widget = apply(ColorEntry, (parent,) ,kw) + widget = ColorEntry(parent, **kw) # Do this after the widget so command isn't called on creation widget['command'] = command widget.pack(fill = X) @@ -992,7 +999,7 @@ class ParticlePanel(AppShell): self.mainNotebook.selectpage('System') self.updateInfo('System') else: - print 'ParticlePanel: No effect named ' + name + print('ParticlePanel: No effect named ' + name) def toggleEffect(self, effect, var): if var.get(): @@ -1041,15 +1048,15 @@ class ParticlePanel(AppShell): # Find path to particle directory pPath = getParticlePath() if pPath.getNumDirectories() > 0: - if `pPath.getDirectory(0)` == '.': + if repr(pPath.getDirectory(0)) == '.': path = '.' else: path = pPath.getDirectory(0).toOsSpecific() else: path = '.' if not os.path.isdir(path): - print 'ParticlePanel Warning: Invalid default DNA directory!' - print 'Using current directory' + print('ParticlePanel Warning: Invalid default DNA directory!') + print('Using current directory') path = '.' particleFilename = askopenfilename( defaultextension = '.ptf', @@ -1070,15 +1077,15 @@ class ParticlePanel(AppShell): # Find path to particle directory pPath = getParticlePath() if pPath.getNumDirectories() > 0: - if `pPath.getDirectory(0)` == '.': + if repr(pPath.getDirectory(0)) == '.': path = '.' else: path = pPath.getDirectory(0).toOsSpecific() else: path = '.' if not os.path.isdir(path): - print 'ParticlePanel Warning: Invalid default DNA directory!' - print 'Using current directory' + print('ParticlePanel Warning: Invalid default DNA directory!') + print('Using current directory') path = '.' particleFilename = asksaveasfilename( defaultextension = '.ptf', @@ -1654,7 +1661,7 @@ class ParticlePanel(AppShell): def setRendererSpriteNonAnimatedTheta(self, theta): self.particles.renderer.setNonanimatedTheta(theta) def setRendererSpriteBlendMethod(self, blendMethod): - print blendMethod + print(blendMethod) if blendMethod == 'PP_NO_BLEND': bMethod = BaseParticleRenderer.PPNOBLEND elif blendMethod == 'PP_BLEND_LINEAR': @@ -1863,7 +1870,7 @@ class ParticlePanel(AppShell): count, force): def setVec(vec, f = force): f.setVector(vec[0], vec[1], vec[2]) - forceName = 'Vector Force-' + `count` + forceName = 'Vector Force-' + repr(count) frame = self.createForceFrame(forcePage, forceName, force) self.createLinearForceWidgets(frame, pageName, forceName, force) vec = force.getLocalVector() @@ -1875,7 +1882,7 @@ class ParticlePanel(AppShell): def createLinearRandomForceWidget(self, forcePage, pageName, count, force, type): - forceName = type + ' Force-' + `count` + forceName = type + ' Force-' + repr(count) frame = self.createForceFrame(forcePage, forceName, force) self.createLinearForceWidgets(frame, pageName, forceName, force) self.createForceActiveWidget(frame, pageName, forceName, force) @@ -1884,7 +1891,7 @@ class ParticlePanel(AppShell): count, force): def setCoef(coef, f = force): f.setCoef(coef) - forceName = 'Friction Force-' + `count` + forceName = 'Friction Force-' + repr(count) frame = self.createForceFrame(forcePage, forceName, force) self.createLinearForceWidgets(frame, pageName, forceName, force) self.createFloater(frame, pageName, forceName + ' Coef', @@ -1895,7 +1902,7 @@ class ParticlePanel(AppShell): def createLinearCylinderVortexForceWidget(self, forcePage, pageName, count, force): - forceName = 'Vortex Force-' + `count` + forceName = 'Vortex Force-' + repr(count) def setCoef(coef, f = force): f.setCoef(coef) def setLength(length, f = force): @@ -1934,7 +1941,7 @@ class ParticlePanel(AppShell): f.setForceCenter(Point3(vec[0], vec[1], vec[2])) def setRadius(radius, f = force): f.setRadius(radius) - forceName = type + ' Force-' + `count` + forceName = type + ' Force-' + repr(count) frame = self.createForceFrame(forcePage, forceName, force) self.createLinearForceWidgets(frame, pageName, forceName, force) var = self.createOptionMenu( diff --git a/contrib/src/sceneeditor/seParticles.py b/contrib/src/sceneeditor/seParticles.py index 655d06b804..a4f0d0e5d6 100644 --- a/contrib/src/sceneeditor/seParticles.py +++ b/contrib/src/sceneeditor/seParticles.py @@ -93,7 +93,7 @@ class Particles(ParticleSystem): elif (type == "OrientedParticleFactory"): self.factory = OrientedParticleFactory.OrientedParticleFactory() else: - print "unknown factory type: %s" % type + print("unknown factory type: %s" % type) return None self.factory.setLifespanBase(0.5) ParticleSystem.ParticleSystem.setFactory(self, self.factory) @@ -132,7 +132,7 @@ class Particles(ParticleSystem): # See sourceFileName and sourceNodeName in SpriteParticleRenderer-extensions.py self.renderer.setTextureFromNode() else: - print "unknown renderer type: %s" % type + print("unknown renderer type: %s" % type) return None ParticleSystem.ParticleSystem.setRenderer(self, self.renderer) @@ -163,7 +163,7 @@ class Particles(ParticleSystem): elif (type == "TangentRingEmitter"): self.emitter = TangentRingEmitter.TangentRingEmitter() else: - print "unknown emitter type: %s" % type + print("unknown emitter type: %s" % type) return None ParticleSystem.ParticleSystem.setEmitter(self, self.emitter) diff --git a/contrib/src/sceneeditor/sePlacer.py b/contrib/src/sceneeditor/sePlacer.py index 3f2b3b4b75..15804629a7 100644 --- a/contrib/src/sceneeditor/sePlacer.py +++ b/contrib/src/sceneeditor/sePlacer.py @@ -5,9 +5,16 @@ from direct.directtools.DirectGlobals import * from direct.tkwidgets.AppShell import AppShell from direct.tkwidgets.Dial import AngleDial from direct.tkwidgets.Floater import Floater -from Tkinter import Button, Menubutton, Menu, StringVar from panda3d.core import * -import Tkinter, Pmw +import sys, Pmw + +if sys.version_info >= (3, 0): + from tkinter import Button, Menubutton, Menu, StringVar + import tkinter +else: + from Tkinter import Button, Menubutton, Menu, StringVar + import Tkinter as tkinter + """ TODO: Task to monitor pose @@ -84,7 +91,7 @@ class Placer(AppShell): def createInterface(self): # The interior of the toplevel panel interior = self.interior() - interior['relief'] = Tkinter.FLAT + interior['relief'] = tkinter.FLAT # Add placer commands to menubar self.menuBar.addmenu('Placer', 'Placer Panel Operations') self.menuBar.addmenuitem('Placer', 'command', @@ -113,7 +120,7 @@ class Placer(AppShell): # Get a handle to the menu frame menuFrame = self.menuFrame self.nodePathMenu = Pmw.ComboBox( - menuFrame, labelpos = Tkinter.W, label_text = 'Node Path:', + menuFrame, labelpos = tkinter.W, label_text = 'Node Path:', entry_width = 20, selectioncommand = self.selectNodePathNamed, scrolledlist_items = self.nodePathNames) @@ -168,7 +175,7 @@ class Placer(AppShell): tag_text = 'Position', tag_font=('MSSansSerif', 14), tag_activebackground = '#909090', - ring_relief = Tkinter.RIDGE) + ring_relief = tkinter.RIDGE) posMenubutton = posGroup.component('tag') self.bind(posMenubutton, 'Position menu operations') posMenu = Menu(posMenubutton, tearoff = 0) @@ -182,7 +189,7 @@ class Placer(AppShell): # Create the dials self.posX = self.createcomponent('posX', (), None, Floater, (posInterior,), - text = 'X', relief = Tkinter.FLAT, + text = 'X', relief = tkinter.FLAT, value = 0.0, label_foreground = 'Red') self.posX['commandData'] = ['x'] @@ -193,7 +200,7 @@ class Placer(AppShell): self.posY = self.createcomponent('posY', (), None, Floater, (posInterior,), - text = 'Y', relief = Tkinter.FLAT, + text = 'Y', relief = tkinter.FLAT, value = 0.0, label_foreground = '#00A000') self.posY['commandData'] = ['y'] @@ -204,7 +211,7 @@ class Placer(AppShell): self.posZ = self.createcomponent('posZ', (), None, Floater, (posInterior,), - text = 'Z', relief = Tkinter.FLAT, + text = 'Z', relief = tkinter.FLAT, value = 0.0, label_foreground = 'Blue') self.posZ['commandData'] = ['z'] @@ -219,7 +226,7 @@ class Placer(AppShell): tag_text = 'Orientation', tag_font=('MSSansSerif', 14), tag_activebackground = '#909090', - ring_relief = Tkinter.RIDGE) + ring_relief = tkinter.RIDGE) hprMenubutton = hprGroup.component('tag') self.bind(hprMenubutton, 'Orientation menu operations') hprMenu = Menu(hprMenubutton, tearoff = 0) @@ -234,7 +241,7 @@ class Placer(AppShell): AngleDial, (hprInterior,), style = 'mini', text = 'H', value = 0.0, - relief = Tkinter.FLAT, + relief = tkinter.FLAT, label_foreground = 'blue') self.hprH['commandData'] = ['h'] self.hprH['preCallback'] = self.xformStart @@ -246,7 +253,7 @@ class Placer(AppShell): AngleDial, (hprInterior,), style = 'mini', text = 'P', value = 0.0, - relief = Tkinter.FLAT, + relief = tkinter.FLAT, label_foreground = 'red') self.hprP['commandData'] = ['p'] self.hprP['preCallback'] = self.xformStart @@ -258,7 +265,7 @@ class Placer(AppShell): AngleDial, (hprInterior,), style = 'mini', text = 'R', value = 0.0, - relief = Tkinter.FLAT, + relief = tkinter.FLAT, label_foreground = '#00A000') self.hprR['commandData'] = ['r'] self.hprR['preCallback'] = self.xformStart @@ -276,7 +283,7 @@ class Placer(AppShell): tag_pyclass = Menubutton, tag_font=('MSSansSerif', 14), tag_activebackground = '#909090', - ring_relief = Tkinter.RIDGE) + ring_relief = tkinter.RIDGE) self.scaleMenubutton = scaleGroup.component('tag') self.bind(self.scaleMenubutton, 'Scale menu operations') self.scaleMenubutton['textvariable'] = self.scalingMode @@ -302,7 +309,7 @@ class Placer(AppShell): self.scaleX = self.createcomponent('scaleX', (), None, Floater, (scaleInterior,), text = 'X Scale', - relief = Tkinter.FLAT, + relief = tkinter.FLAT, min = 0.0001, value = 1.0, resetValue = 1.0, label_foreground = 'Red') @@ -315,7 +322,7 @@ class Placer(AppShell): self.scaleY = self.createcomponent('scaleY', (), None, Floater, (scaleInterior,), text = 'Y Scale', - relief = Tkinter.FLAT, + relief = tkinter.FLAT, min = 0.0001, value = 1.0, resetValue = 1.0, label_foreground = '#00A000') @@ -328,7 +335,7 @@ class Placer(AppShell): self.scaleZ = self.createcomponent('scaleZ', (), None, Floater, (scaleInterior,), text = 'Z Scale', - relief = Tkinter.FLAT, + relief = tkinter.FLAT, min = 0.0001, value = 1.0, resetValue = 1.0, label_foreground = 'Blue') @@ -508,8 +515,8 @@ class Placer(AppShell): dictName = name else: # Generate a unique name for the dict - dictName = name + '-' + `nodePath.get_key()` - if not dict.has_key(dictName): + dictName = name + '-' + repr(nodePath.get_key()) + if dictName not in dict: # Update combo box to include new item names.append(dictName) listbox = menu.component('scrolledlist') @@ -769,12 +776,12 @@ class Placer(AppShell): posString = '%.2f, %.2f, %.2f' % (pos[0], pos[1], pos[2]) hprString = '%.2f, %.2f, %.2f' % (hpr[0], hpr[1], hpr[2]) scaleString = '%.2f, %.2f, %.2f' % (scale[0], scale[1], scale[2]) - print 'NodePath: %s' % name - print 'Pos: %s' % posString - print 'Hpr: %s' % hprString - print 'Scale: %s' % scaleString - print ('%s.setPosHprScale(%s, %s, %s)' % - (name, posString, hprString, scaleString)) + print('NodePath: %s' % name) + print('Pos: %s' % posString) + print('Hpr: %s' % hprString) + print('Scale: %s' % scaleString) + print(('%s.setPosHprScale(%s, %s, %s)' % + (name, posString, hprString, scaleString))) def onDestroy(self, event): # Remove hooks diff --git a/contrib/src/sceneeditor/seSceneGraphExplorer.py b/contrib/src/sceneeditor/seSceneGraphExplorer.py index fc7f29370a..163287965c 100644 --- a/contrib/src/sceneeditor/seSceneGraphExplorer.py +++ b/contrib/src/sceneeditor/seSceneGraphExplorer.py @@ -9,9 +9,16 @@ # ################################################################# from direct.showbase.DirectObject import DirectObject -from Tkinter import IntVar, Frame, Label from seTree import TreeNode, TreeItem -import Pmw, Tkinter + +import Pmw, sys + +if sys.version_info >= (3, 0): + from tkinter import IntVar, Frame, Label + import tkinter +else: + from Tkinter import IntVar, Frame, Label + import Tkinter as tkinter # changing these strings requires changing sceneEditor.py SGE_ strs too! # This list of items will be showed on the pop out window when user right click on @@ -57,7 +64,7 @@ class seSceneGraphExplorer(Pmw.MegaWidget, DirectObject): # Setup up container interior = self.interior() - interior.configure(relief = Tkinter.GROOVE, borderwidth = 2) + interior.configure(relief = tkinter.GROOVE, borderwidth = 2) # Create a label and an entry self._scrolledCanvas = self.createcomponent( @@ -69,7 +76,7 @@ class seSceneGraphExplorer(Pmw.MegaWidget, DirectObject): self._canvas = self._scrolledCanvas.component('canvas') self._canvas['scrollregion'] = ('0i', '0i', '2i', '4i') self._scrolledCanvas.resizescrollregion() - self._scrolledCanvas.pack(padx = 3, pady = 3, expand=1, fill = Tkinter.BOTH) + self._scrolledCanvas.pack(padx = 3, pady = 3, expand=1, fill = tkinter.BOTH) self._canvas.bind('', self.mouse2Down) self._canvas.bind('', self.mouse2Motion) @@ -91,8 +98,8 @@ class seSceneGraphExplorer(Pmw.MegaWidget, DirectObject): (), None, Label, (interior,), text = 'Active Reparent Target: ', - anchor = Tkinter.W, justify = Tkinter.LEFT) - self._label.pack(fill = Tkinter.X) + anchor = tkinter.W, justify = tkinter.LEFT) + self._label.pack(fill = tkinter.X) # Add update parent label def updateLabel(nodePath = None, s = self): @@ -145,7 +152,7 @@ class seSceneGraphExplorer(Pmw.MegaWidget, DirectObject): if item!= None: item.select(callBack) else: - print '----SGE: Error Selection' + print('----SGE: Error Selection') class SceneGraphExplorerItem(TreeItem): diff --git a/contrib/src/sceneeditor/seSelection.py b/contrib/src/sceneeditor/seSelection.py index 0d34ad120a..b7d9b260dc 100644 --- a/contrib/src/sceneeditor/seSelection.py +++ b/contrib/src/sceneeditor/seSelection.py @@ -70,7 +70,7 @@ class SelectedNodePaths(DirectObject): """ Select the specified node path. Multiselect as required """ # Do nothing if nothing selected if not nodePath: - print 'Nothing selected!!' + print('Nothing selected!!') return None # Reset selected objects and highlight if multiSelect is false @@ -124,7 +124,7 @@ class SelectedNodePaths(DirectObject): Return a list of all selected node paths. No verification of connectivity is performed on the members of the list """ - return self.selectedDict.values()[:] + return list(self.selectedDict.values()) def __getitem__(self,index): return self.getSelectedAsList()[index] @@ -141,7 +141,7 @@ class SelectedNodePaths(DirectObject): return None def getDeselectedAsList(self): - return self.deselectedDict.values()[:] + return list(self.deselectedDict.values()) def getDeselectedDict(self, id): """ @@ -385,7 +385,7 @@ class DirectBoundingBox: return '%.2f %.2f %.2f' % (vec[0], vec[1], vec[2]) def __repr__(self): - return (`self.__class__` + + return (repr(self.__class__) + '\nNodePath:\t%s\n' % self.nodePath.getName() + 'Min:\t\t%s\n' % self.vecAsString(self.min) + 'Max:\t\t%s\n' % self.vecAsString(self.max) + diff --git a/contrib/src/sceneeditor/seSession.py b/contrib/src/sceneeditor/seSession.py index ab466c4388..c8e7a1a20f 100644 --- a/contrib/src/sceneeditor/seSession.py +++ b/contrib/src/sceneeditor/seSession.py @@ -480,7 +480,7 @@ class SeSession(DirectObject): ### Customized DirectSession def isNotCycle(self, nodePath, parent): if nodePath.get_key() == parent.get_key(): - print 'DIRECT.reparent: Invalid parent' + print('DIRECT.reparent: Invalid parent') return 0 elif parent.hasParent(): return self.isNotCycle(nodePath, parent.getParent()) @@ -735,8 +735,8 @@ class SeSession(DirectObject): ### Customized DirectSession hprB = base.camera.getHpr() posE = Point3((radius*-1.41)+center.getX(), (radius*-1.41)+center.getY(), (radius*1.41)+center.getZ()) hprE = Point3(-45, -38, 0) - print posB, hprB - print posE, hprE + print(posB, hprB) + print(posE, hprE) posInterval1 = base.camera.posInterval(time, posE, bakeInStart = 1) posInterval2 = base.camera.posInterval(time, posB, bakeInStart = 1) diff --git a/contrib/src/sceneeditor/seTree.py b/contrib/src/sceneeditor/seTree.py index 9685d54b35..9927c11112 100644 --- a/contrib/src/sceneeditor/seTree.py +++ b/contrib/src/sceneeditor/seTree.py @@ -12,15 +12,21 @@ # ################################################################# -import os, sys, string, Pmw, Tkinter +import os, sys, string, Pmw from direct.showbase.DirectObject import DirectObject -from Tkinter import IntVar, Menu, PhotoImage, Label, Frame, Entry from panda3d.core import * +if sys.version_info >= (3, 0): + import tkinter + from tkinter import IntVar, Menu, PhotoImage, Label, Frame, Entry +else: + import Tkinter as tkinter + from Tkinter import IntVar, Menu, PhotoImage, Label, Frame, Entry + # Initialize icon directory ICONDIR = getModelPath().findFile(Filename('icons')).toOsSpecific() if not os.path.isdir(ICONDIR): - raise RuntimeError, "can't find DIRECT icon directory (%s)" % `ICONDIR` + raise RuntimeError("can't find DIRECT icon directory (%r)" % ICONDIR) class TreeNode: @@ -187,9 +193,9 @@ class TreeNode: oldcursor = self.canvas['cursor'] self.canvas['cursor'] = "watch" self.canvas.update() - self.canvas.delete(Tkinter.ALL) # XXX could be more subtle + self.canvas.delete(tkinter.ALL) # XXX could be more subtle self.draw(7, 2) - x0, y0, x1, y1 = self.canvas.bbox(Tkinter.ALL) + x0, y0, x1, y1 = self.canvas.bbox(tkinter.ALL) self.canvas.configure(scrollregion=(0, 0, x1, y1)) self.canvas['cursor'] = oldcursor @@ -208,7 +214,7 @@ class TreeNode: self.kidKeys = [] for item in sublist: key = item.GetKey() - if self.children.has_key(key): + if key in self.children: child = self.children[key] else: child = TreeNode(self.canvas, self, item, self.menuList) @@ -309,7 +315,7 @@ class TreeNode: def edit(self, event=None): self.entry = Entry(self.label, bd=0, highlightthickness=1, width=0) self.entry.insert(0, self.label['text']) - self.entry.selection_range(0, Tkinter.END) + self.entry.selection_range(0, tkinter.END) self.entry.pack(ipadx=5) self.entry.focus_set() self.entry.bind("", self.edit_finish) @@ -344,7 +350,7 @@ class TreeNode: for item in sublist: key = item.GetKey() # Use existing child or create new TreeNode if none exists - if self.children.has_key(key): + if key in self.children: child = self.children[key] else: child = TreeNode(self.canvas, self, item, self.menuList) From 54ec57547233fae4e3bb65e1ab0c8066c5cc53d0 Mon Sep 17 00:00:00 2001 From: rdb Date: Sun, 12 Aug 2018 22:05:25 +0200 Subject: [PATCH 099/125] egg: add properties to EggData / EggNode --- panda/src/egg/eggData.h | 6 ++++++ panda/src/egg/eggGroupNode.h | 1 + panda/src/egg/eggNode.h | 15 +++++++++------ 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/panda/src/egg/eggData.h b/panda/src/egg/eggData.h index ad5d3a9917..0352de17e3 100644 --- a/panda/src/egg/eggData.h +++ b/panda/src/egg/eggData.h @@ -68,6 +68,12 @@ PUBLISHED: INLINE void set_egg_timestamp(time_t egg_timestamp); INLINE time_t get_egg_timestamp() const; + MAKE_PROPERTY(auto_resolve_externals, get_auto_resolve_externals, + set_auto_resolve_externals); + MAKE_PROPERTY(coordinate_system, get_coordinate_system, set_coordinate_system); + MAKE_PROPERTY(egg_filename, get_egg_filename, set_egg_filename); + MAKE_PROPERTY(egg_timestamp, get_egg_timestamp, set_egg_timestamp); + INLINE void recompute_vertex_normals(double threshold); INLINE void recompute_polygon_normals(); INLINE void strip_normals(); diff --git a/panda/src/egg/eggGroupNode.h b/panda/src/egg/eggGroupNode.h index 346c2ed817..8bbf48aea0 100644 --- a/panda/src/egg/eggGroupNode.h +++ b/panda/src/egg/eggGroupNode.h @@ -109,6 +109,7 @@ PUBLISHED: EggNode *get_next_child(); EXTENSION(PyObject *get_children() const); + MAKE_PROPERTY(children, get_children); EggNode *add_child(EggNode *node); PT(EggNode) remove_child(EggNode *node); diff --git a/panda/src/egg/eggNode.h b/panda/src/egg/eggNode.h index c2d811859e..950ae5e257 100644 --- a/panda/src/egg/eggNode.h +++ b/panda/src/egg/eggNode.h @@ -44,6 +44,9 @@ PUBLISHED: INLINE bool is_under_transform() const; INLINE bool is_local_coord() const; + MAKE_PROPERTY(parent, get_parent); + MAKE_PROPERTY(depth, get_depth); + INLINE const LMatrix4d &get_vertex_frame() const; INLINE const LMatrix4d &get_node_frame() const; INLINE const LMatrix4d &get_vertex_frame_inv() const; @@ -51,12 +54,12 @@ PUBLISHED: INLINE const LMatrix4d &get_vertex_to_node() const; INLINE const LMatrix4d &get_node_to_vertex() const; - INLINE const LMatrix4d *get_vertex_frame_ptr()const; - INLINE const LMatrix4d *get_node_frame_ptr()const; - INLINE const LMatrix4d *get_vertex_frame_inv_ptr()const; - INLINE const LMatrix4d *get_node_frame_inv_ptr()const; - INLINE const LMatrix4d *get_vertex_to_node_ptr()const; - INLINE const LMatrix4d *get_node_to_vertex_ptr()const; + INLINE const LMatrix4d *get_vertex_frame_ptr() const; + INLINE const LMatrix4d *get_node_frame_ptr() const; + INLINE const LMatrix4d *get_vertex_frame_inv_ptr() const; + INLINE const LMatrix4d *get_node_frame_inv_ptr() const; + INLINE const LMatrix4d *get_vertex_to_node_ptr() const; + INLINE const LMatrix4d *get_node_to_vertex_ptr() const; INLINE void transform(const LMatrix4d &mat); INLINE void transform_vertices_only(const LMatrix4d &mat); From 72e593800f3866d92ca34580cfa412ae16a1fc39 Mon Sep 17 00:00:00 2001 From: rdb Date: Sun, 12 Aug 2018 22:06:13 +0200 Subject: [PATCH 100/125] gobj: don't recalculate proj mat on set_near/far with existing value --- panda/src/gobj/lens.I | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/panda/src/gobj/lens.I b/panda/src/gobj/lens.I index 91fb6e7170..d20d53bfd7 100644 --- a/panda/src/gobj/lens.I +++ b/panda/src/gobj/lens.I @@ -667,9 +667,11 @@ do_get_film_offset(const CData *cdata) const { */ INLINE void Lens:: do_set_near(CData *cdata, PN_stdfloat near_distance) { - cdata->_near_distance = near_distance; - do_adjust_comp_flags(cdata, CF_projection_mat | CF_projection_mat_inv, 0); - do_throw_change_event(cdata); + if (near_distance != cdata->_near_distance) { + cdata->_near_distance = near_distance; + do_adjust_comp_flags(cdata, CF_projection_mat | CF_projection_mat_inv, 0); + do_throw_change_event(cdata); + } } /** @@ -685,9 +687,11 @@ do_get_near(const CData *cdata) const { */ INLINE void Lens:: do_set_far(CData *cdata, PN_stdfloat far_distance) { - cdata->_far_distance = far_distance; - do_adjust_comp_flags(cdata, CF_projection_mat | CF_projection_mat_inv, 0); - do_throw_change_event(cdata); + if (far_distance != cdata->_far_distance) { + cdata->_far_distance = far_distance; + do_adjust_comp_flags(cdata, CF_projection_mat | CF_projection_mat_inv, 0); + do_throw_change_event(cdata); + } } /** @@ -703,10 +707,12 @@ do_get_far(const CData *cdata) const { */ INLINE void Lens:: do_set_near_far(CData *cdata, PN_stdfloat near_distance, PN_stdfloat far_distance) { - cdata->_near_distance = near_distance; - cdata->_far_distance = far_distance; - do_adjust_comp_flags(cdata, CF_projection_mat | CF_projection_mat_inv, 0); - do_throw_change_event(cdata); + if (near_distance != cdata->_near_distance || far_distance != cdata->_far_distance) { + cdata->_near_distance = near_distance; + cdata->_far_distance = far_distance; + do_adjust_comp_flags(cdata, CF_projection_mat | CF_projection_mat_inv, 0); + do_throw_change_event(cdata); + } } INLINE std::ostream & From 838d238f6ef4529dd9e7649c78fb617b4133082e Mon Sep 17 00:00:00 2001 From: rdb Date: Sun, 12 Aug 2018 22:11:42 +0200 Subject: [PATCH 101/125] tests: add various test cases to test egg loading and transforms Used to track down and reproduce the issue in #228. --- tests/egg/test_egg_transform.py | 134 ++++++++++++++++++++++++++++ tests/egg2pg/test_egg_coordsys.py | 103 +++++++++++++++++++++ tests/linmath/test_matrix_invert.py | 20 +++++ 3 files changed, 257 insertions(+) create mode 100644 tests/egg/test_egg_transform.py create mode 100644 tests/egg2pg/test_egg_coordsys.py create mode 100644 tests/linmath/test_matrix_invert.py diff --git a/tests/egg/test_egg_transform.py b/tests/egg/test_egg_transform.py new file mode 100644 index 0000000000..70e4d17fc6 --- /dev/null +++ b/tests/egg/test_egg_transform.py @@ -0,0 +1,134 @@ +import pytest +from panda3d import core + +# Skip these tests if we can't import egg. +egg = pytest.importorskip("panda3d.egg") + + +EGG_TRANSFORM_MISSING = """ + { %s } + { +} +""" + +EGG_TRANSFORM_EMPTY = """ + { %s } + { + { + } +} +""" + +EGG_TRANSFORM_IDENT = """ + { %s } + { + { + { + 1 0 0 0 + 0 1 0 0 + 0 0 1 0 + 0 0 0 1 + } + } +} +""" + +EGG_TRANSFORM_MATRIX = """ + { %s } + { + { + { + 5 2 -3 4 + 5 6 7 8 + 9 1 -3 2 + 5 2 5 2 + } + } +} +""" + +COORD_SYSTEMS = { + core.CS_zup_right: "zup-right", + core.CS_yup_right: "yup-right", + core.CS_zup_left: "zup-left", + core.CS_yup_left: "yup-left", +} + +def read_egg_string(string): + """Reads an EggData from a string.""" + stream = core.StringStream(string.encode('utf-8')) + data = egg.EggData() + assert data.read(stream) + return data + + +@pytest.mark.parametrize("coordsys", COORD_SYSTEMS.keys()) +def test_egg_transform_missing(coordsys): + data = read_egg_string(EGG_TRANSFORM_MISSING % COORD_SYSTEMS[coordsys]) + assert data.get_coordinate_system() == coordsys + + child, = data.get_children() + assert not child.has_transform3d() + assert child.transform_is_identity() + + assert child.get_vertex_frame() == core.Mat4D.ident_mat() + assert child.get_node_frame() == core.Mat4D.ident_mat() + assert child.get_vertex_frame_inv() == core.Mat4D.ident_mat() + assert child.get_node_frame_inv() == core.Mat4D.ident_mat() + assert child.get_vertex_to_node() == core.Mat4D.ident_mat() + assert child.get_node_to_vertex() == core.Mat4D.ident_mat() + + +@pytest.mark.parametrize("coordsys", COORD_SYSTEMS.keys()) +def test_egg_transform_empty(coordsys): + data = read_egg_string(EGG_TRANSFORM_EMPTY % COORD_SYSTEMS[coordsys]) + assert data.get_coordinate_system() == coordsys + + child, = data.get_children() + assert not child.has_transform3d() + assert child.transform_is_identity() + + assert child.get_vertex_frame() == core.Mat4D.ident_mat() + assert child.get_node_frame() == core.Mat4D.ident_mat() + assert child.get_vertex_frame_inv() == core.Mat4D.ident_mat() + assert child.get_node_frame_inv() == core.Mat4D.ident_mat() + assert child.get_vertex_to_node() == core.Mat4D.ident_mat() + assert child.get_node_to_vertex() == core.Mat4D.ident_mat() + + +@pytest.mark.parametrize("coordsys", COORD_SYSTEMS.keys()) +def test_egg_transform_ident(coordsys): + data = read_egg_string(EGG_TRANSFORM_IDENT % COORD_SYSTEMS[coordsys]) + assert data.get_coordinate_system() == coordsys + + child, = data.get_children() + assert child.has_transform3d() + assert child.transform_is_identity() + + assert child.get_vertex_frame() == core.Mat4D.ident_mat() + assert child.get_node_frame() == core.Mat4D.ident_mat() + assert child.get_vertex_frame_inv() == core.Mat4D.ident_mat() + assert child.get_node_frame_inv() == core.Mat4D.ident_mat() + assert child.get_vertex_to_node() == core.Mat4D.ident_mat() + assert child.get_node_to_vertex() == core.Mat4D.ident_mat() + + +@pytest.mark.parametrize("coordsys", COORD_SYSTEMS.keys()) +def test_egg_transform_matrix(coordsys): + data = read_egg_string(EGG_TRANSFORM_MATRIX % COORD_SYSTEMS[coordsys]) + assert data.get_coordinate_system() == coordsys + + mat = core.Mat4D(5, 2, -3, 4, 5, 6, 7, 8, 9, 1, -3, 2, 5, 2, 5, 2) + mat_inv = core.invert(mat) + + child, = data.get_children() + assert child.has_transform3d() + assert not child.transform_is_identity() + assert child.get_transform3d() == mat + + assert child.get_vertex_frame() == core.Mat4D.ident_mat() + assert child.get_node_frame() == mat + assert child.get_vertex_frame_inv() == core.Mat4D.ident_mat() + assert child.get_node_frame_inv() == mat_inv + assert child.get_vertex_to_node() == mat_inv + assert child.get_node_to_vertex() == mat diff --git a/tests/egg2pg/test_egg_coordsys.py b/tests/egg2pg/test_egg_coordsys.py new file mode 100644 index 0000000000..b3c5583075 --- /dev/null +++ b/tests/egg2pg/test_egg_coordsys.py @@ -0,0 +1,103 @@ +import pytest +from panda3d import core + +# Skip these tests if we can't import egg. +egg = pytest.importorskip("panda3d.egg") + + +COORD_SYSTEMS = [core.CS_zup_right, core.CS_yup_right, core.CS_zup_left, core.CS_yup_left] + + +@pytest.mark.parametrize("egg_coordsys", COORD_SYSTEMS) +@pytest.mark.parametrize("coordsys", COORD_SYSTEMS) +def test_egg2pg_transform_ident(egg_coordsys, coordsys): + # Ensures that an identity matrix always remains untouched. + group = egg.EggGroup("group") + group.add_matrix4(core.Mat4D.ident_mat()) + assert group.transform_is_identity() + + assert group.get_vertex_frame() == core.Mat4D.ident_mat() + assert group.get_node_frame() == core.Mat4D.ident_mat() + assert group.get_vertex_frame_inv() == core.Mat4D.ident_mat() + assert group.get_node_frame_inv() == core.Mat4D.ident_mat() + assert group.get_vertex_to_node() == core.Mat4D.ident_mat() + assert group.get_node_to_vertex() == core.Mat4D.ident_mat() + + data = egg.EggData() + data.set_coordinate_system(egg_coordsys) + data.add_child(group) + + root = egg.load_egg_data(data, coordsys) + assert root + node, = root.children + + assert node.transform.is_identity() + + +@pytest.mark.parametrize("coordsys", COORD_SYSTEMS) +def test_egg2pg_transform_mat_unchanged(coordsys): + # Ensures that the matrix remains unchanged if coordinate system is same. + mat = (5, 2, -3, 4, 5, 6, 7, 8, 9, 1, -3, 2, 5, 2, 5, 2) + group = egg.EggGroup("group") + group.add_matrix4(mat) + assert not group.transform_is_identity() + + assert group.get_vertex_frame() == core.Mat4D.ident_mat() + assert group.get_node_frame() == mat + assert group.get_vertex_frame_inv() == core.Mat4D.ident_mat() + assert group.get_node_frame_inv() == core.invert(mat) + assert group.get_vertex_to_node() == core.invert(mat) + assert group.get_node_to_vertex() == mat + + data = egg.EggData() + data.set_coordinate_system(coordsys) + data.add_child(group) + + root = egg.load_egg_data(data, coordsys) + assert root + node, = root.children + + assert node.transform.mat == mat + + +@pytest.mark.parametrize("egg_coordsys", COORD_SYSTEMS) +@pytest.mark.parametrize("coordsys", COORD_SYSTEMS) +def test_egg2pg_transform_pos3d(egg_coordsys, coordsys): + vpool = egg.EggVertexPool("vpool") + vtx = vpool.make_new_vertex(core.Point3D.rfu(-8, 0.5, 4.5, egg_coordsys)) + + point = egg.EggPoint() + point.add_vertex(vtx) + + group = egg.EggGroup("group") + group.add_translate3d(core.Point3D.rfu(1, 2, 3, egg_coordsys)) + assert not group.transform_is_identity() + group.add_child(point) + + mat = group.get_transform3d() + assert group.get_vertex_frame() == core.Mat4D.ident_mat() + assert group.get_node_frame() == mat + assert group.get_vertex_frame_inv() == core.Mat4D.ident_mat() + assert group.get_node_frame_inv() == core.invert(mat) + assert group.get_vertex_to_node() == core.invert(mat) + assert group.get_node_to_vertex() == mat + + assert group.get_vertex_frame_ptr() is None + assert group.get_vertex_frame_inv_ptr() is None + + data = egg.EggData() + data.set_coordinate_system(egg_coordsys) + data.add_child(vpool) + data.add_child(group) + + root = egg.load_egg_data(data, coordsys) + assert root + node, = root.children + + # Ensure the node has the expected position. + assert node.transform.pos == core.Point3.rfu(1, 2, 3, coordsys) + + # Get the location of the vertex. This is a quick, hacky way to get it. + point = core.NodePath(node).get_tight_bounds()[0] + assert point == core.Point3.rfu(-8, 0.5, 4.5, coordsys) + diff --git a/tests/linmath/test_matrix_invert.py b/tests/linmath/test_matrix_invert.py new file mode 100644 index 0000000000..b2e6dd49bf --- /dev/null +++ b/tests/linmath/test_matrix_invert.py @@ -0,0 +1,20 @@ +import pytest +from panda3d import core + + +@pytest.mark.parametrize("type", (core.Mat4, core.Mat4D)) +def test_mat4_invert(type): + mat = type((1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, 0, + 1, 2, 3, 1)) + inv = type() + assert inv.invert_from(mat) + + assert inv == type(( 1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, 0, + -1, -2, -3, 1)) + + assert (mat * inv).is_identity() + assert (inv * mat).is_identity() From f84b0840f90011f3d34097d624551ca9a8850f0d Mon Sep 17 00:00:00 2001 From: rdb Date: Sun, 12 Aug 2018 22:15:40 +0200 Subject: [PATCH 102/125] makepanda: work around GCC/Eigen double matrix invert bug Fixes #228 --- makepanda/makepanda.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/makepanda/makepanda.py b/makepanda/makepanda.py index df25c49f39..6181ccf87e 100755 --- a/makepanda/makepanda.py +++ b/makepanda/makepanda.py @@ -1351,6 +1351,9 @@ def CompileCxx(obj,src,opts): # Fast math is nice, but we'd like to see NaN in dev builds. cmd += " -fno-finite-math-only" + # Make sure this is off to avoid GCC/Eigen bug (see GitHub #228) + cmd += " -fno-unsafe-math-optimizations" + if (optlevel==1): cmd += " -ggdb -D_DEBUG" if (optlevel==2): cmd += " -O1 -D_DEBUG" if (optlevel==3): cmd += " -O2" From 00b5c9d168b225bbd5bc17acf78c24654aa6f27f Mon Sep 17 00:00:00 2001 From: rdb Date: Sun, 12 Aug 2018 22:22:25 +0200 Subject: [PATCH 103/125] assimp: add various config variables, change default winding order --- pandatool/src/assimp/assimpLoader.cxx | 31 ++++++++++++++++-- pandatool/src/assimp/config_assimp.cxx | 44 ++++++++++++++++++++++++++ pandatool/src/assimp/config_assimp.h | 11 ++++++- 3 files changed, 82 insertions(+), 4 deletions(-) diff --git a/pandatool/src/assimp/assimpLoader.cxx b/pandatool/src/assimp/assimpLoader.cxx index 61c7514aa6..d04c1d55ad 100644 --- a/pandatool/src/assimp/assimpLoader.cxx +++ b/pandatool/src/assimp/assimpLoader.cxx @@ -103,9 +103,34 @@ bool AssimpLoader:: read(const Filename &filename) { _filename = filename; - // I really don't know why we need to flip the winding order, but otherwise - // the models I tested with are showing inside out. - _scene = _importer.ReadFile(_filename.c_str(), aiProcess_Triangulate | aiProcess_GenUVCoords | aiProcess_FlipWindingOrder); + unsigned int flags = aiProcess_Triangulate | aiProcess_GenUVCoords; + + if (assimp_calc_tangent_space) { + flags |= aiProcess_CalcTangentSpace; + } + if (assimp_join_identical_vertices) { + flags |= aiProcess_JoinIdenticalVertices; + } + if (assimp_improve_cache_locality) { + flags |= aiProcess_ImproveCacheLocality; + } + if (assimp_remove_redundant_materials) { + flags |= aiProcess_RemoveRedundantMaterials; + } + if (assimp_fix_infacing_normals) { + flags |= aiProcess_FixInfacingNormals; + } + if (assimp_optimize_meshes) { + flags |= aiProcess_OptimizeMeshes; + } + if (assimp_optimize_graph) { + flags |= aiProcess_OptimizeGraph; + } + if (assimp_flip_winding_order) { + flags |= aiProcess_FlipWindingOrder; + } + + _scene = _importer.ReadFile(_filename.c_str(), flags); if (_scene == nullptr) { _error = true; return false; diff --git a/pandatool/src/assimp/config_assimp.cxx b/pandatool/src/assimp/config_assimp.cxx index 6e7dfcfe86..2dbf29fa16 100644 --- a/pandatool/src/assimp/config_assimp.cxx +++ b/pandatool/src/assimp/config_assimp.cxx @@ -25,6 +25,50 @@ ConfigureFn(config_assimp) { init_libassimp(); } +ConfigVariableBool assimp_calc_tangent_space +("assimp-calc-tangent-space", false, + PRC_DESC("Calculates tangents and binormals for meshes imported via Assimp.")); + +ConfigVariableBool assimp_join_identical_vertices +("assimp-join-identical-vertices", true, + PRC_DESC("Merges duplicate vertices. Set this to false if you want each " + "vertex to only be in use on one triangle.")); + +ConfigVariableBool assimp_improve_cache_locality +("assimp-improve-cache-locality", true, + PRC_DESC("Improves rendering performance of the loaded meshes by reordering " + "triangles for better vertex cache locality. Set this to false if " + "you need geometry to be loaded in the exact order that it was " + "specified in the file, or to improve load performance.")); + +ConfigVariableBool assimp_remove_redundant_materials +("assimp-remove-redundant-materials", true, + PRC_DESC("Removes redundant/unreferenced materials from assets.")); + +ConfigVariableBool assimp_fix_infacing_normals +("assimp-fix-infacing-normals", false, + PRC_DESC("Determines which normal vectors are facing inward and inverts them " + "so that they are facing outward.")); + +ConfigVariableBool assimp_optimize_meshes +("assimp-optimize-meshes", true, + PRC_DESC("Removes the number of draw calls by unifying geometry with the same " + "materials. Especially effective in conjunction with " + "assimp-optimize-graph and assimp-remove-redundant-materials.")); + +ConfigVariableBool assimp_optimize_graph +("assimp-optimize-graph", false, + PRC_DESC("Optimizes the scene geometry by flattening the scene hierarchy. " + "This is very efficient (combined with assimp-optimize-meshes), but " + "it may result the hierarchy to become lost, so it is disabled by " + "default.")); + +ConfigVariableBool assimp_flip_winding_order +("assimp-flip-winding-order", false, + PRC_DESC("Set this true to flip the winding order of all models loaded via " + "the Assimp loader. Note that you may need to clear the model-cache " + "after changing this.")); + /** * Initializes the library. This must be called at least once before any of * the functions or classes in this library can be used. Normally it will be diff --git a/pandatool/src/assimp/config_assimp.h b/pandatool/src/assimp/config_assimp.h index 7ca6a98094..16efc8a754 100644 --- a/pandatool/src/assimp/config_assimp.h +++ b/pandatool/src/assimp/config_assimp.h @@ -15,12 +15,21 @@ #define CONFIG_ASSIMP_H #include "pandatoolbase.h" - +#include "configVariableBool.h" #include "dconfig.h" ConfigureDecl(config_assimp, EXPCL_ASSIMP, EXPTP_ASSIMP); NotifyCategoryDecl(assimp, EXPCL_ASSIMP, EXPTP_ASSIMP); +extern ConfigVariableBool assimp_calc_tangent_space; +extern ConfigVariableBool assimp_join_identical_vertices; +extern ConfigVariableBool assimp_improve_cache_locality; +extern ConfigVariableBool assimp_remove_redundant_materials; +extern ConfigVariableBool assimp_fix_infacing_normals; +extern ConfigVariableBool assimp_optimize_meshes; +extern ConfigVariableBool assimp_optimize_graph; +extern ConfigVariableBool assimp_flip_winding_order; + extern EXPCL_ASSIMP void init_libassimp(); #endif From 6105953b40d424e932a8f4a8446b0ecca19dd6b7 Mon Sep 17 00:00:00 2001 From: Sam Edwards Date: Tue, 14 Aug 2018 17:23:48 -0600 Subject: [PATCH 104/125] general: Add forgotten include --- panda/src/collide/collisionBox.cxx | 1 + 1 file changed, 1 insertion(+) diff --git a/panda/src/collide/collisionBox.cxx b/panda/src/collide/collisionBox.cxx index 119284f905..a8af257456 100644 --- a/panda/src/collide/collisionBox.cxx +++ b/panda/src/collide/collisionBox.cxx @@ -16,6 +16,7 @@ #include "collisionRay.h" #include "collisionSphere.h" #include "collisionSegment.h" +#include "collisionTube.h" #include "collisionHandler.h" #include "collisionEntry.h" #include "config_collide.h" From 06f7da521548609f2e32b549b6728253c81c5162 Mon Sep 17 00:00:00 2001 From: Sam Edwards Date: Tue, 14 Aug 2018 21:56:52 -0600 Subject: [PATCH 105/125] express: Fix misclassified EXPCL_PANDA_ macro --- panda/src/express/zStreamBuf.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/panda/src/express/zStreamBuf.h b/panda/src/express/zStreamBuf.h index 35446090db..3dadd1543d 100644 --- a/panda/src/express/zStreamBuf.h +++ b/panda/src/express/zStreamBuf.h @@ -24,7 +24,7 @@ /** * The streambuf object that implements IDecompressStream and OCompressStream. */ -class EXPCL_PANDA_DOWNLOADER ZStreamBuf : public std::streambuf { +class EXPCL_PANDA_EXPRESS ZStreamBuf : public std::streambuf { public: ZStreamBuf(); virtual ~ZStreamBuf(); From 97d6d84adef4f072e6273d5a1b05c41f612fe228 Mon Sep 17 00:00:00 2001 From: Sam Edwards Date: Wed, 15 Aug 2018 20:38:00 -0600 Subject: [PATCH 106/125] dcparser: Add BUILDING_DIRECT_DCPARSER switch Resolves GH #342. --- direct/src/dcparser/dcArrayParameter.h | 2 +- direct/src/dcparser/dcAtomicField.h | 2 +- direct/src/dcparser/dcClass.h | 2 +- direct/src/dcparser/dcClassParameter.h | 2 +- direct/src/dcparser/dcDeclaration.h | 2 +- direct/src/dcparser/dcField.h | 2 +- direct/src/dcparser/dcFile.h | 2 +- direct/src/dcparser/dcKeyword.h | 2 +- direct/src/dcparser/dcKeywordList.h | 2 +- direct/src/dcparser/dcMolecularField.h | 2 +- direct/src/dcparser/dcNumericRange.h | 2 +- direct/src/dcparser/dcPackData.h | 2 +- direct/src/dcparser/dcPacker.h | 2 +- direct/src/dcparser/dcPackerCatalog.h | 2 +- direct/src/dcparser/dcPackerInterface.h | 2 +- direct/src/dcparser/dcParameter.h | 2 +- direct/src/dcparser/dcParserDefs.h | 2 +- direct/src/dcparser/dcSimpleParameter.h | 2 +- direct/src/dcparser/dcSwitch.h | 2 +- direct/src/dcparser/dcSwitchParameter.h | 2 +- direct/src/dcparser/dcTypedef.h | 2 +- direct/src/dcparser/dcbase.h | 5 +++++ direct/src/dcparser/hashGenerator.h | 2 +- direct/src/dcparser/primeNumberGenerator.h | 2 +- direct/src/directbase/directsymbols.h | 9 +++++++++ 25 files changed, 37 insertions(+), 23 deletions(-) diff --git a/direct/src/dcparser/dcArrayParameter.h b/direct/src/dcparser/dcArrayParameter.h index fd5008fb97..97fb32bdf0 100644 --- a/direct/src/dcparser/dcArrayParameter.h +++ b/direct/src/dcparser/dcArrayParameter.h @@ -23,7 +23,7 @@ * parameter type accepts an arbitrary (or possibly fixed) number of nested * fields, all of which are of the same type. */ -class DCArrayParameter : public DCParameter { +class EXPCL_DIRECT_DCPARSER DCArrayParameter : public DCParameter { public: DCArrayParameter(DCParameter *element_type, const DCUnsignedIntRange &size = DCUnsignedIntRange()); diff --git a/direct/src/dcparser/dcAtomicField.h b/direct/src/dcparser/dcAtomicField.h index e0d7cee58e..9eb92e2527 100644 --- a/direct/src/dcparser/dcAtomicField.h +++ b/direct/src/dcparser/dcAtomicField.h @@ -27,7 +27,7 @@ * This defines an interface to the Distributed Class, and is always * implemented as a remote procedure method. */ -class DCAtomicField : public DCField { +class EXPCL_DIRECT_DCPARSER DCAtomicField : public DCField { public: DCAtomicField(const std::string &name, DCClass *dclass, bool bogus_field); virtual ~DCAtomicField(); diff --git a/direct/src/dcparser/dcClass.h b/direct/src/dcparser/dcClass.h index 9f7945b372..cd69716470 100644 --- a/direct/src/dcparser/dcClass.h +++ b/direct/src/dcparser/dcClass.h @@ -41,7 +41,7 @@ class DCParameter; /** * Defines a particular DistributedClass as read from an input .dc file. */ -class DCClass : public DCDeclaration { +class EXPCL_DIRECT_DCPARSER DCClass : public DCDeclaration { public: DCClass(DCFile *dc_file, const std::string &name, bool is_struct, bool bogus_class); diff --git a/direct/src/dcparser/dcClassParameter.h b/direct/src/dcparser/dcClassParameter.h index 3657190bf9..05b84e84c3 100644 --- a/direct/src/dcparser/dcClassParameter.h +++ b/direct/src/dcparser/dcClassParameter.h @@ -23,7 +23,7 @@ class DCClass; * This represents a class (or struct) object used as a parameter itself. * This means that all the fields of the class get packed into the message. */ -class DCClassParameter : public DCParameter { +class EXPCL_DIRECT_DCPARSER DCClassParameter : public DCParameter { public: DCClassParameter(const DCClass *dclass); DCClassParameter(const DCClassParameter ©); diff --git a/direct/src/dcparser/dcDeclaration.h b/direct/src/dcparser/dcDeclaration.h index 0fd4392ca6..c6b8b7dd54 100644 --- a/direct/src/dcparser/dcDeclaration.h +++ b/direct/src/dcparser/dcDeclaration.h @@ -26,7 +26,7 @@ class DCSwitch; * only purpose is so that classes and typedefs can be stored in one list * together so they can be ordered correctly on output. */ -class DCDeclaration { +class EXPCL_DIRECT_DCPARSER DCDeclaration { public: virtual ~DCDeclaration(); diff --git a/direct/src/dcparser/dcField.h b/direct/src/dcparser/dcField.h index 6744ea93d4..dc06ff76f2 100644 --- a/direct/src/dcparser/dcField.h +++ b/direct/src/dcparser/dcField.h @@ -34,7 +34,7 @@ class HashGenerator; /** * A single field of a Distributed Class, either atomic or molecular. */ -class DCField : public DCPackerInterface, public DCKeywordList { +class EXPCL_DIRECT_DCPARSER DCField : public DCPackerInterface, public DCKeywordList { public: DCField(); DCField(const std::string &name, DCClass *dclass); diff --git a/direct/src/dcparser/dcFile.h b/direct/src/dcparser/dcFile.h index 7d7550804f..37ebbe9181 100644 --- a/direct/src/dcparser/dcFile.h +++ b/direct/src/dcparser/dcFile.h @@ -29,7 +29,7 @@ class DCDeclaration; * Represents the complete list of Distributed Class descriptions as read from * a .dc file. */ -class DCFile { +class EXPCL_DIRECT_DCPARSER DCFile { PUBLISHED: DCFile(); ~DCFile(); diff --git a/direct/src/dcparser/dcKeyword.h b/direct/src/dcparser/dcKeyword.h index a82bd1ef0f..7447b6ed78 100644 --- a/direct/src/dcparser/dcKeyword.h +++ b/direct/src/dcparser/dcKeyword.h @@ -25,7 +25,7 @@ class HashGenerator; * define a communication property associated with a field, for instance * "broadcast" or "airecv". */ -class DCKeyword : public DCDeclaration { +class EXPCL_DIRECT_DCPARSER DCKeyword : public DCDeclaration { public: DCKeyword(const std::string &name, int historical_flag = ~0); virtual ~DCKeyword(); diff --git a/direct/src/dcparser/dcKeywordList.h b/direct/src/dcparser/dcKeywordList.h index d9905c64db..ac0ed574fe 100644 --- a/direct/src/dcparser/dcKeywordList.h +++ b/direct/src/dcparser/dcKeywordList.h @@ -23,7 +23,7 @@ class HashGenerator; * This is a list of keywords (see DCKeyword) that may be set on a particular * field. */ -class DCKeywordList { +class EXPCL_DIRECT_DCPARSER DCKeywordList { public: DCKeywordList(); DCKeywordList(const DCKeywordList ©); diff --git a/direct/src/dcparser/dcMolecularField.h b/direct/src/dcparser/dcMolecularField.h index db7d850e00..8983eddab0 100644 --- a/direct/src/dcparser/dcMolecularField.h +++ b/direct/src/dcparser/dcMolecularField.h @@ -25,7 +25,7 @@ class DCParameter; * This represents a combination of two or more related atomic fields, that * will often be treated as a unit. */ -class DCMolecularField : public DCField { +class EXPCL_DIRECT_DCPARSER DCMolecularField : public DCField { public: DCMolecularField(const std::string &name, DCClass *dclass); diff --git a/direct/src/dcparser/dcNumericRange.h b/direct/src/dcparser/dcNumericRange.h index b3450f89e4..f751323b01 100644 --- a/direct/src/dcparser/dcNumericRange.h +++ b/direct/src/dcparser/dcNumericRange.h @@ -23,7 +23,7 @@ * to constrain simple numeric types, as well as array sizes. */ template -class DCNumericRange { +class EXPCL_DIRECT_DCPARSER DCNumericRange { public: typedef NUM Number; diff --git a/direct/src/dcparser/dcPackData.h b/direct/src/dcparser/dcPackData.h index 7f891a1d5d..e5a3b53e5d 100644 --- a/direct/src/dcparser/dcPackData.h +++ b/direct/src/dcparser/dcPackData.h @@ -19,7 +19,7 @@ /** * This is a block of data that receives the results of DCPacker. */ -class DCPackData { +class EXPCL_DIRECT_DCPARSER DCPackData { PUBLISHED: INLINE DCPackData(); INLINE ~DCPackData(); diff --git a/direct/src/dcparser/dcPacker.h b/direct/src/dcparser/dcPacker.h index 9de32ff2cd..68a01a5999 100644 --- a/direct/src/dcparser/dcPacker.h +++ b/direct/src/dcparser/dcPacker.h @@ -31,7 +31,7 @@ class DCSwitchParameter; * See also direct/src/doc/dcPacker.txt for a more complete description and * examples of using this class. */ -class DCPacker { +class EXPCL_DIRECT_DCPARSER DCPacker { PUBLISHED: DCPacker(); ~DCPacker(); diff --git a/direct/src/dcparser/dcPackerCatalog.h b/direct/src/dcparser/dcPackerCatalog.h index c03b1b5fc6..9a37f84a41 100644 --- a/direct/src/dcparser/dcPackerCatalog.h +++ b/direct/src/dcparser/dcPackerCatalog.h @@ -26,7 +26,7 @@ class DCSwitchParameter; * requested from a particular field; its ownership is retained by the field * so it must not be deleted. */ -class DCPackerCatalog { +class EXPCL_DIRECT_DCPARSER DCPackerCatalog { private: DCPackerCatalog(const DCPackerInterface *root); DCPackerCatalog(const DCPackerCatalog ©); diff --git a/direct/src/dcparser/dcPackerInterface.h b/direct/src/dcparser/dcPackerInterface.h index 171ed3f0ca..ef28b85647 100644 --- a/direct/src/dcparser/dcPackerInterface.h +++ b/direct/src/dcparser/dcPackerInterface.h @@ -64,7 +64,7 @@ END_PUBLISH * Normally these methods are called only by the DCPacker object; the user * wouldn't normally call these directly. */ -class DCPackerInterface { +class EXPCL_DIRECT_DCPARSER DCPackerInterface { public: DCPackerInterface(const std::string &name = std::string()); DCPackerInterface(const DCPackerInterface ©); diff --git a/direct/src/dcparser/dcParameter.h b/direct/src/dcparser/dcParameter.h index 59a34dc440..49e6df12fe 100644 --- a/direct/src/dcparser/dcParameter.h +++ b/direct/src/dcparser/dcParameter.h @@ -32,7 +32,7 @@ class HashGenerator; * This may also be a typedef reference to another type, which has the same * properties as the referenced type, but a different name. */ -class DCParameter : public DCField { +class EXPCL_DIRECT_DCPARSER DCParameter : public DCField { protected: DCParameter(); DCParameter(const DCParameter ©); diff --git a/direct/src/dcparser/dcParserDefs.h b/direct/src/dcparser/dcParserDefs.h index da1747ab15..28659a37e3 100644 --- a/direct/src/dcparser/dcParserDefs.h +++ b/direct/src/dcparser/dcParserDefs.h @@ -43,7 +43,7 @@ extern DCFile *dc_file; // that has member functions in a union), so we'll use a class instead. That // means we need to declare it externally, here. -class DCTokenType { +class EXPCL_DIRECT_DCPARSER DCTokenType { public: union U { int s_int; diff --git a/direct/src/dcparser/dcSimpleParameter.h b/direct/src/dcparser/dcSimpleParameter.h index b6da9a8bff..7b47773a3d 100644 --- a/direct/src/dcparser/dcSimpleParameter.h +++ b/direct/src/dcparser/dcSimpleParameter.h @@ -25,7 +25,7 @@ * divisor, which is meaningful only for the numeric type elements (and * represents a fixed-point numeric convention). */ -class DCSimpleParameter : public DCParameter { +class EXPCL_DIRECT_DCPARSER DCSimpleParameter : public DCParameter { public: DCSimpleParameter(DCSubatomicType type, unsigned int divisor = 1); DCSimpleParameter(const DCSimpleParameter ©); diff --git a/direct/src/dcparser/dcSwitch.h b/direct/src/dcparser/dcSwitch.h index 17e4e856a2..ac58f5439d 100644 --- a/direct/src/dcparser/dcSwitch.h +++ b/direct/src/dcparser/dcSwitch.h @@ -27,7 +27,7 @@ class DCField; * and represents two or more alternative unpacking schemes based on the first * field read. */ -class DCSwitch : public DCDeclaration { +class EXPCL_DIRECT_DCPARSER DCSwitch : public DCDeclaration { public: DCSwitch(const std::string &name, DCField *key_parameter); virtual ~DCSwitch(); diff --git a/direct/src/dcparser/dcSwitchParameter.h b/direct/src/dcparser/dcSwitchParameter.h index 51b8b673f6..7d123493aa 100644 --- a/direct/src/dcparser/dcSwitchParameter.h +++ b/direct/src/dcparser/dcSwitchParameter.h @@ -23,7 +23,7 @@ class DCSwitch; * This represents a switch object used as a parameter itself, which packs the * appropriate fields of the switch into the message. */ -class DCSwitchParameter : public DCParameter { +class EXPCL_DIRECT_DCPARSER DCSwitchParameter : public DCParameter { public: DCSwitchParameter(const DCSwitch *dswitch); DCSwitchParameter(const DCSwitchParameter ©); diff --git a/direct/src/dcparser/dcTypedef.h b/direct/src/dcparser/dcTypedef.h index 654c8998a8..769f1f129f 100644 --- a/direct/src/dcparser/dcTypedef.h +++ b/direct/src/dcparser/dcTypedef.h @@ -23,7 +23,7 @@ class DCParameter; * This represents a single typedef declaration in the dc file. It assigns a * particular type to a new name, just like a C typedef. */ -class DCTypedef : public DCDeclaration { +class EXPCL_DIRECT_DCPARSER DCTypedef : public DCDeclaration { public: DCTypedef(DCParameter *parameter, bool implicit = false); DCTypedef(const std::string &name); diff --git a/direct/src/dcparser/dcbase.h b/direct/src/dcparser/dcbase.h index 4f2712f148..64ef117158 100644 --- a/direct/src/dcparser/dcbase.h +++ b/direct/src/dcparser/dcbase.h @@ -70,6 +70,11 @@ #define END_PUBLISH #define BLOCKING +// These control the declspec(dllexport/dllimport) on Windows. When compiling +// outside of Panda, we assume we aren't part of a DLL. +#define EXPCL_DIRECT_DCPARSER +#define EXPTP_DIRECT_DCPARSER + // Panda defines some assert-type macros. We map those to the standard assert // macro outside of Panda. #define nassertr(condition, return_value) assert(condition) diff --git a/direct/src/dcparser/hashGenerator.h b/direct/src/dcparser/hashGenerator.h index 94031cd2f6..29ae1a6609 100644 --- a/direct/src/dcparser/hashGenerator.h +++ b/direct/src/dcparser/hashGenerator.h @@ -20,7 +20,7 @@ /** * This class generates an arbitrary hash number from a sequence of ints. */ -class HashGenerator { +class EXPCL_DIRECT_DCPARSER HashGenerator { public: HashGenerator(); diff --git a/direct/src/dcparser/primeNumberGenerator.h b/direct/src/dcparser/primeNumberGenerator.h index 8b24ae6b5c..7aa49e09a9 100644 --- a/direct/src/dcparser/primeNumberGenerator.h +++ b/direct/src/dcparser/primeNumberGenerator.h @@ -30,7 +30,7 @@ typedef std::vector vector_int; * For a given integer n, it will return the nth prime number. This will * involve a recompute step only if n is greater than any previous n. */ -class PrimeNumberGenerator { +class EXPCL_DIRECT_DCPARSER PrimeNumberGenerator { public: PrimeNumberGenerator(); diff --git a/direct/src/directbase/directsymbols.h b/direct/src/directbase/directsymbols.h index cdd07e1a0c..55fd2bd4e8 100644 --- a/direct/src/directbase/directsymbols.h +++ b/direct/src/directbase/directsymbols.h @@ -18,6 +18,7 @@ /* BUILDING_DIRECT is just a buildsystem shortcut for all of these: */ #ifdef BUILDING_DIRECT + #define BUILDING_DIRECT_DCPARSER #define BUILDING_DIRECT_DEADREC #define BUILDING_DIRECT_DIRECTD #define BUILDING_DIRECT_INTERVAL @@ -26,6 +27,14 @@ #define BUILDING_DIRECT_DISTRIBUTED #endif +#ifdef BUILDING_DIRECT_DCPARSER + #define EXPCL_DIRECT_DCPARSER EXPORT_CLASS + #define EXPTP_DIRECT_DCPARSER EXPORT_TEMPL +#else + #define EXPCL_DIRECT_DCPARSER IMPORT_CLASS + #define EXPTP_DIRECT_DCPARSER IMPORT_TEMPL +#endif + #ifdef BUILDING_DIRECT_DEADREC #define EXPCL_DIRECT_DEADREC EXPORT_CLASS #define EXPTP_DIRECT_DEADREC EXPORT_TEMPL From ba345d590fbeba5c0103b1458971f576461bd526 Mon Sep 17 00:00:00 2001 From: rdb Date: Sun, 19 Aug 2018 13:40:38 +0200 Subject: [PATCH 107/125] express: make Datagram.get_message() return bytes in Python 3 This is done using a Python extension function, which also happens to make the call more efficient as this avoids an extra copy. The C++ version still returns std::string as there is still a lot of C++ code that relies on that. Fixes #297 --- panda/src/express/datagram.I | 12 ---------- panda/src/express/datagram.h | 7 +++++- panda/src/express/datagram_ext.I | 35 ++++++++++++++++++++++++++++ panda/src/express/datagram_ext.h | 40 ++++++++++++++++++++++++++++++++ 4 files changed, 81 insertions(+), 13 deletions(-) create mode 100644 panda/src/express/datagram_ext.I create mode 100644 panda/src/express/datagram_ext.h diff --git a/panda/src/express/datagram.I b/panda/src/express/datagram.I index 98b71820e5..8c555c777d 100644 --- a/panda/src/express/datagram.I +++ b/panda/src/express/datagram.I @@ -316,18 +316,6 @@ get_message() const { } } -/** - * Returns the datagram's data as a bytes object. - */ -INLINE vector_uchar Datagram:: -__bytes__() const { - if (!_data.empty()) { - return vector_uchar(_data.v()); - } else { - return vector_uchar(); - } -} - /** * Returns a pointer to the beginning of the datagram's data. */ diff --git a/panda/src/express/datagram.h b/panda/src/express/datagram.h index 69dce69e31..b2a3acb363 100644 --- a/panda/src/express/datagram.h +++ b/panda/src/express/datagram.h @@ -85,11 +85,16 @@ PUBLISHED: void append_data(const void *data, size_t size); INLINE void append_data(const vector_uchar &data); +public: void assign(const void *data, size_t size); INLINE std::string get_message() const; - INLINE vector_uchar __bytes__() const; INLINE const void *get_data() const; + +PUBLISHED: + EXTENSION(INLINE PyObject *get_message() const); + EXTENSION(INLINE PyObject *__bytes__() const); + INLINE size_t get_length() const; INLINE void set_array(PTA_uchar data); diff --git a/panda/src/express/datagram_ext.I b/panda/src/express/datagram_ext.I new file mode 100644 index 0000000000..a35c5410b2 --- /dev/null +++ b/panda/src/express/datagram_ext.I @@ -0,0 +1,35 @@ +/** + * 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 datagram_ext.I + * @author rdb + * @date 2018-08-19 + */ + +/** + * Returns the datagram's data as a bytes object. + */ +INLINE PyObject *Extension:: +get_message() const { + const char *data = (const char *)_this->get_data(); + size_t size = _this->get_length(); + +#if PY_MAJOR_VERSION >= 3 + return PyBytes_FromStringAndSize((char *)data, size); +#else + return PyString_FromStringAndSize((char *)data, size); +#endif +} + +/** + * Returns the datagram's data as a bytes object. + */ +PyObject *Extension:: +__bytes__() const { + return get_message(); +} diff --git a/panda/src/express/datagram_ext.h b/panda/src/express/datagram_ext.h new file mode 100644 index 0000000000..35f2e32bc6 --- /dev/null +++ b/panda/src/express/datagram_ext.h @@ -0,0 +1,40 @@ +/** + * 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 datagram_ext.h + * @author rdb + * @date 2018-08-19 + */ + +#ifndef DATAGRAM_EXT_H +#define DATAGRAM_EXT_H + +#include "dtoolbase.h" + +#ifdef HAVE_PYTHON + +#include "extension.h" +#include "datagram.h" +#include "py_panda.h" + +/** + * This class defines the extension methods for Datagram, which are called + * instead of any C++ methods with the same prototype. + */ +template<> +class Extension : public ExtensionBase { +public: + INLINE PyObject *get_message() const; + INLINE PyObject *__bytes__() const; +}; + +#include "datagram_ext.I" + +#endif // HAVE_PYTHON + +#endif // DATAGRAM_EXT_H From 74442e41f14539504305b0f9d50e61f4af4af6ec Mon Sep 17 00:00:00 2001 From: rdb Date: Sun, 19 Aug 2018 14:21:23 +0200 Subject: [PATCH 108/125] express: slight Datagram constructor cleanup --- panda/src/express/datagram.I | 29 ++--------------------------- panda/src/express/datagram.h | 9 +++++++-- 2 files changed, 9 insertions(+), 29 deletions(-) diff --git a/panda/src/express/datagram.I b/panda/src/express/datagram.I index 8c555c777d..350fa3d30c 100644 --- a/panda/src/express/datagram.I +++ b/panda/src/express/datagram.I @@ -11,30 +11,11 @@ * @date 2000-06-06 */ -/** - * Constructs an empty datagram. - */ -INLINE Datagram:: -Datagram() : -#ifdef STDFLOAT_DOUBLE - _stdfloat_double(true) -#else - _stdfloat_double(false) -#endif -{ -} - /** * Constructs a datagram from an existing block of data. */ INLINE Datagram:: -Datagram(const void *data, size_t size) : -#ifdef STDFLOAT_DOUBLE - _stdfloat_double(true) -#else - _stdfloat_double(false) -#endif -{ +Datagram(const void *data, size_t size) { append_data(data, size); } @@ -43,13 +24,7 @@ Datagram(const void *data, size_t size) : */ INLINE Datagram:: Datagram(vector_uchar data) : - _data(std::move(data)), -#ifdef STDFLOAT_DOUBLE - _stdfloat_double(true) -#else - _stdfloat_double(false) -#endif -{ + _data(std::move(data)) { } /** diff --git a/panda/src/express/datagram.h b/panda/src/express/datagram.h index b2a3acb363..420175c114 100644 --- a/panda/src/express/datagram.h +++ b/panda/src/express/datagram.h @@ -37,7 +37,7 @@ */ class EXPCL_PANDA_EXPRESS Datagram : public TypedObject { PUBLISHED: - INLINE Datagram(); + INLINE Datagram() = default; INLINE Datagram(const void *data, size_t size); INLINE explicit Datagram(vector_uchar data); Datagram(const Datagram ©) = default; @@ -114,7 +114,12 @@ PUBLISHED: private: PTA_uchar _data; - bool _stdfloat_double; + +#ifdef STDFLOAT_DOUBLE + bool _stdfloat_double = true; +#else + bool _stdfloat_double = false; +#endif public: From b1d21110372250b1c91a3829ae0c3f809a7d99d2 Mon Sep 17 00:00:00 2001 From: rdb Date: Sun, 19 Aug 2018 16:01:39 +0200 Subject: [PATCH 109/125] express: add Datagram add_blob and add_blob32, et al. This is for writing Python 2/3 agnostic code for writing binary data to a datagram, and reading from it using DatagramIterator. --- direct/src/distributed/PyDatagram.py | 4 +-- direct/src/distributed/PyDatagramIterator.py | 4 +-- panda/src/express/datagram.I | 34 ++++++++++++++++++++ panda/src/express/datagram.h | 5 +++ panda/src/express/datagramIterator.I | 21 ++++++++++++ panda/src/express/datagramIterator.h | 3 ++ panda/src/recorder/socketStreamRecorder.cxx | 5 +-- tests/putil/test_datagram.py | 12 +++++++ 8 files changed, 80 insertions(+), 8 deletions(-) diff --git a/direct/src/distributed/PyDatagram.py b/direct/src/distributed/PyDatagram.py index eebc06e440..f45c3c52c1 100755 --- a/direct/src/distributed/PyDatagram.py +++ b/direct/src/distributed/PyDatagram.py @@ -25,8 +25,8 @@ class PyDatagram(Datagram): STUint64: (Datagram.addUint64, int), STFloat64: (Datagram.addFloat64, None), STString: (Datagram.addString, None), - STBlob: (Datagram.addString, None), - STBlob32: (Datagram.addString32, None), + STBlob: (Datagram.addBlob, None), + STBlob32: (Datagram.addBlob32, None), } #def addChannel(self, channelId): diff --git a/direct/src/distributed/PyDatagramIterator.py b/direct/src/distributed/PyDatagramIterator.py index 60267a1ab9..6ce96e77e4 100755 --- a/direct/src/distributed/PyDatagramIterator.py +++ b/direct/src/distributed/PyDatagramIterator.py @@ -23,8 +23,8 @@ class PyDatagramIterator(DatagramIterator): STUint64: DatagramIterator.getUint64, STFloat64: DatagramIterator.getFloat64, STString: DatagramIterator.getString, - STBlob: DatagramIterator.getString, - STBlob32: DatagramIterator.getString32, + STBlob: DatagramIterator.getBlob, + STBlob32: DatagramIterator.getBlob32, } getChannel = DatagramIterator.getUint64 diff --git a/panda/src/express/datagram.I b/panda/src/express/datagram.I index 350fa3d30c..42cc6b9cf1 100644 --- a/panda/src/express/datagram.I +++ b/panda/src/express/datagram.I @@ -270,6 +270,35 @@ add_fixed_string(const std::string &str, size_t size) { } } +/** + * Adds a variable-length binary blob to the datagram. This actually adds a + * count followed by n bytes. + */ +INLINE void Datagram:: +add_blob(const vector_uchar &data) { + // The max sendable size for a blob is 2^16. + nassertv(data.size() <= (uint16_t)0xffff); + + // Blobs always are preceded by their size + add_uint16((uint16_t)data.size()); + + // Add the blob + append_data(data.data(), data.size()); +} + +/** + * Adds a variable-length binary blob to the datagram, using a 32-bit length + * field to allow very long blobs. + */ +INLINE void Datagram:: +add_blob32(const vector_uchar &data) { + // Blobs always are preceded by their size + add_uint32((uint32_t)data.size()); + + // Add the blob + append_data(data.data(), data.size()); +} + /** * Appends some more raw data to the end of the datagram. */ @@ -445,3 +474,8 @@ INLINE void generic_write_datagram(Datagram &dest, const std::wstring &value) { dest.add_wstring(value); } + +INLINE void +generic_write_datagram(Datagram &dest, const vector_uchar &value) { + dest.add_blob(value); +} diff --git a/panda/src/express/datagram.h b/panda/src/express/datagram.h index 420175c114..9611645eed 100644 --- a/panda/src/express/datagram.h +++ b/panda/src/express/datagram.h @@ -81,6 +81,9 @@ PUBLISHED: INLINE void add_fixed_string(const std::string &str, size_t size); void add_wstring(const std::wstring &str); + INLINE void add_blob(const vector_uchar &); + INLINE void add_blob32(const vector_uchar &); + void pad_bytes(size_t size); void append_data(const void *data, size_t size); INLINE void append_data(const vector_uchar &data); @@ -158,6 +161,8 @@ INLINE void generic_write_datagram(Datagram &dest, const std::string &value); INLINE void generic_write_datagram(Datagram &dest, const std::wstring &value); +INLINE void +generic_write_datagram(Datagram &dest, const vector_uchar &value); #include "datagram.I" diff --git a/panda/src/express/datagramIterator.I b/panda/src/express/datagramIterator.I index 763850b60c..140151089a 100644 --- a/panda/src/express/datagramIterator.I +++ b/panda/src/express/datagramIterator.I @@ -400,6 +400,22 @@ get_be_float64() { return tempvar; } +/** + * Extracts a variable-length binary blob. + */ +INLINE vector_uchar DatagramIterator:: +get_blob() { + return extract_bytes(get_uint16()); +} + +/** + * Extracts a variable-length binary blob with a 32-bit size field. + */ +INLINE vector_uchar DatagramIterator:: +get_blob32() { + return extract_bytes(get_uint32()); +} + /** * Skips over the indicated number of bytes in the datagram. */ @@ -485,3 +501,8 @@ INLINE void generic_read_datagram(std::wstring &result, DatagramIterator &source) { result = source.get_wstring(); } + +INLINE void +generic_read_datagram(vector_uchar &result, DatagramIterator &source) { + result = source.get_blob(); +} diff --git a/panda/src/express/datagramIterator.h b/panda/src/express/datagramIterator.h index 570e34c3c4..867c7de58c 100644 --- a/panda/src/express/datagramIterator.h +++ b/panda/src/express/datagramIterator.h @@ -61,6 +61,9 @@ PUBLISHED: std::string get_fixed_string(size_t size); std::wstring get_wstring(); + INLINE vector_uchar get_blob(); + INLINE vector_uchar get_blob32(); + INLINE void skip_bytes(size_t size); vector_uchar extract_bytes(size_t size); size_t extract_bytes(unsigned char *into, size_t size); diff --git a/panda/src/recorder/socketStreamRecorder.cxx b/panda/src/recorder/socketStreamRecorder.cxx index 5ee6168d44..8418485b20 100644 --- a/panda/src/recorder/socketStreamRecorder.cxx +++ b/panda/src/recorder/socketStreamRecorder.cxx @@ -82,10 +82,7 @@ play_frame(DatagramIterator &scan, BamReader *manager) { int num_packets = scan.get_uint16(); for (int i = 0; i < num_packets; i++) { - size_t size = scan.get_uint16(); - vector_uchar packet(size); - scan.extract_bytes(&packet[0], size); - _data.push_back(Datagram(std::move(packet))); + _data.push_back(Datagram(scan.get_blob())); } } diff --git a/tests/putil/test_datagram.py b/tests/putil/test_datagram.py index 171363109a..7919a1360f 100644 --- a/tests/putil/test_datagram.py +++ b/tests/putil/test_datagram.py @@ -28,6 +28,9 @@ def datagram_small(request): dg.add_string32('this is another string') dg.add_string('this is yet a third string') + dg.add_blob(b'blob data \x00\xf2\xa0\x00\x00') + dg.add_blob32(b'\xc9\x8f\x00 test blob32') + dg.add_stdfloat(800.2) dg.add_stdfloat(3.1415926) dg.add_stdfloat(2.7182818) @@ -49,6 +52,9 @@ def datagram_small(request): assert dgi.get_string32() == 'this is another string' assert dgi.get_string() == 'this is yet a third string' + assert dgi.get_blob() == b'blob data \x00\xf2\xa0\x00\x00' + assert dgi.get_blob32() == b'\xc9\x8f\x00 test blob32' + assert dgi.get_stdfloat() == pytest.approx(800.2) assert dgi.get_stdfloat() == pytest.approx(3.1415926) assert dgi.get_stdfloat() == pytest.approx(2.7182818) @@ -88,6 +94,12 @@ def test_datagram_bytes(): dgi.get_remaining_bytes() == b'abc\x00\xff123' +def test_datagram_get_message(): + dg = core.Datagram(b'abc\x00') + dg.append_data(b'\xff123') + assert dg.get_message() == b'abc\x00\xff123' + + def test_iterator(datagram_small): """This tests Datagram/DatagramIterator, and sort of serves as a self-check of the test fixtures too.""" From 5da8b63a668e8266ba9a81dd661bfc690e9cf65b Mon Sep 17 00:00:00 2001 From: rdb Date: Sun, 19 Aug 2018 16:04:56 +0200 Subject: [PATCH 110/125] cppparser: fix formatting of typecast operator --- dtool/src/cppparser/cppFunctionType.cxx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/dtool/src/cppparser/cppFunctionType.cxx b/dtool/src/cppparser/cppFunctionType.cxx index 27699d711b..731b6b0cf5 100644 --- a/dtool/src/cppparser/cppFunctionType.cxx +++ b/dtool/src/cppparser/cppFunctionType.cxx @@ -292,6 +292,10 @@ output_instance(ostream &out, int indent_level, CPPScope *scope, out << str; + } else if (_flags & F_operator_typecast) { + out << "operator "; + _return_type->output_instance(out, indent_level, scope, complete, "", prename + str); + } else { if (prename.empty()) { _return_type->output_instance(out, indent_level, scope, complete, From 21f5e77467a72197d096f36759e12b0f117a5dd1 Mon Sep 17 00:00:00 2001 From: rdb Date: Sun, 19 Aug 2018 16:05:39 +0200 Subject: [PATCH 111/125] dtoolbase: prefer GCC AtomicAdjust implementation over i386 asm one --- dtool/src/dtoolbase/atomicAdjust.h | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/dtool/src/dtoolbase/atomicAdjust.h b/dtool/src/dtoolbase/atomicAdjust.h index 1180529ded..804224e5c3 100644 --- a/dtool/src/dtoolbase/atomicAdjust.h +++ b/dtool/src/dtoolbase/atomicAdjust.h @@ -30,6 +30,20 @@ struct AtomicAdjust { #include "atomicAdjustDummyImpl.h" typedef AtomicAdjustDummyImpl AtomicAdjust; +#elif (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7))) || (defined(__clang__) && (__clang_major__ >= 3)) +// GCC 4.7 and above has built-in __atomic functions for atomic operations. +// Clang 3.0 and above also supports them. + +#include "atomicAdjustGccImpl.h" +typedef AtomicAdjustGccImpl AtomicAdjust; + +#if (__GCC_ATOMIC_INT_LOCK_FREE + __GCC_ATOMIC_LONG_LOCK_FREE) > 0 +#define HAVE_ATOMIC_COMPARE_AND_EXCHANGE 1 +#endif +#if __GCC_ATOMIC_POINTER_LOCK_FREE > 0 +#define HAVE_ATOMIC_COMPARE_AND_EXCHANGE_PTR 1 +#endif + #elif (defined(__i386__) || defined(_M_IX86)) && !defined(__APPLE__) // For an i386 architecture, we'll always use the i386 implementation. It // should be safe for any OS, and it might be a bit faster than any OS- @@ -45,20 +59,6 @@ typedef AtomicAdjustI386Impl AtomicAdjust; #define HAVE_ATOMIC_COMPARE_AND_EXCHANGE 1 #define HAVE_ATOMIC_COMPARE_AND_EXCHANGE_PTR 1 -#elif (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7))) || (defined(__clang__) && (__clang_major__ >= 3)) -// GCC 4.7 and above has built-in __atomic functions for atomic operations. -// Clang 3.0 and above also supports them. - -#include "atomicAdjustGccImpl.h" -typedef AtomicAdjustGccImpl AtomicAdjust; - -#if (__GCC_ATOMIC_INT_LOCK_FREE + __GCC_ATOMIC_INT_LOCK_FREE) > 0 -#define HAVE_ATOMIC_COMPARE_AND_EXCHANGE 1 -#endif -#if __GCC_ATOMIC_POINTER_LOCK_FREE > 0 -#define HAVE_ATOMIC_COMPARE_AND_EXCHANGE_PTR 1 -#endif - #elif defined(THREAD_WIN32_IMPL) #include "atomicAdjustWin32Impl.h" From c4b657b5b23c72fcaeaf4d2d0205cdbcf1482c25 Mon Sep 17 00:00:00 2001 From: rdb Date: Sun, 19 Aug 2018 16:06:16 +0200 Subject: [PATCH 112/125] interrogate: support implicit typecast operators in some cases For example, this will let us pass a ConfigVariableFilename to anything that accepts a Filename, just like in C++. Does not work if the return value if the typecast operator requires management. --- .../interfaceMakerPythonNative.cxx | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/dtool/src/interrogate/interfaceMakerPythonNative.cxx b/dtool/src/interrogate/interfaceMakerPythonNative.cxx index 3134fcb2eb..e20aff91ef 100644 --- a/dtool/src/interrogate/interfaceMakerPythonNative.cxx +++ b/dtool/src/interrogate/interfaceMakerPythonNative.cxx @@ -1089,6 +1089,27 @@ write_class_details(ostream &out, Object *obj) { } } + // Are there any implicit cast operators that can cast this object to our + // desired pointer? + for (Function *func : obj->_methods) { + for (FunctionRemap *remap : func->_remaps) { + if (remap->_type == FunctionRemap::T_typecast_method && + is_remap_legal(remap) && + !remap->_return_type->return_value_needs_management() && + (remap->_cppfunc->_storage_class & CPPInstance::SC_explicit) == 0 && + TypeManager::is_pointer(remap->_return_type->get_new_type())) { + + CPPType *cast_type = remap->_return_type->get_orig_type(); + CPPType *obj_type = TypeManager::unwrap(TypeManager::resolve_type(remap->_return_type->get_new_type())); + string return_expr = "(" + cast_type->get_local_name(&parser) + ")*local_this"; + out << " // " << *remap->_cppfunc << "\n"; + out << " if (requested_type == Dtool_Ptr_" << make_safe_name(obj_type->get_local_name(&parser)) << ") {\n"; + out << " return (void *)(" << remap->_return_type->get_return_expr(return_expr) << ");\n"; + out << " }\n"; + } + } + } + out << " return nullptr;\n"; out << "}\n\n"; From 371c34d13bcd138a0daea42d3612e7dee1850240 Mon Sep 17 00:00:00 2001 From: rdb Date: Sun, 19 Aug 2018 16:40:35 +0200 Subject: [PATCH 113/125] linmath: allow constructing matrix from rows This also enables using mat[n] wherever an LVecBase4 is accepted, as well as Mat4(*mat). --- panda/src/linmath/lmatrix3_src.I | 42 ++++++++++++++++++++++++++ panda/src/linmath/lmatrix3_src.h | 12 +++++--- panda/src/linmath/lmatrix4_src.I | 51 ++++++++++++++++++++++++++++++++ panda/src/linmath/lmatrix4_src.h | 14 ++++++--- 4 files changed, 111 insertions(+), 8 deletions(-) diff --git a/panda/src/linmath/lmatrix3_src.I b/panda/src/linmath/lmatrix3_src.I index 8bfb3909ce..782c8599ee 100644 --- a/panda/src/linmath/lmatrix3_src.I +++ b/panda/src/linmath/lmatrix3_src.I @@ -44,6 +44,14 @@ size() { return 3; } +/** + * + */ +INLINE_LINMATH FLOATNAME(LMatrix3)::Row:: +operator const FLOATNAME(LVecBase3) &() const { + return *(const FLOATNAME(LVecBase3) *)_row; +} + /** * Defines a row-level constant accessor to the matrix. */ @@ -68,6 +76,14 @@ size() { return 3; } +/** + * + */ +INLINE_LINMATH FLOATNAME(LMatrix3)::CRow:: +operator const FLOATNAME(LVecBase3) &() const { + return *(const FLOATNAME(LVecBase3) *)_row; +} + /** * Returns an identity matrix. * @@ -132,6 +148,32 @@ FLOATNAME(LMatrix3)(FLOATTYPE e00, FLOATTYPE e01, FLOATTYPE e02, _m(2, 2) = e22; } +/** + * Constructs the matrix from three individual rows. + */ +INLINE_LINMATH FLOATNAME(LMatrix3):: +FLOATNAME(LMatrix3)(const FLOATNAME(LVecBase3) &row0, + const FLOATNAME(LVecBase3) &row1, + const FLOATNAME(LVecBase3) &row2) { + TAU_PROFILE("LMatrix3::LMatrix3(const LVecBase3 &, ...)", " ", TAU_USER); + +#ifdef HAVE_EIGEN + _m.row(0) = row0._v; + _m.row(1) = row1._v; + _m.row(2) = row2._v; +#else + _m(0, 0) = row0._v(0); + _m(0, 1) = row0._v(1); + _m(0, 2) = row0._v(2); + _m(1, 0) = row1._v(0); + _m(1, 1) = row1._v(1); + _m(1, 2) = row1._v(2); + _m(2, 0) = row2._v(0); + _m(2, 1) = row2._v(1); + _m(2, 2) = row2._v(2); +#endif // HAVE_EIGEN +} + /** * */ diff --git a/panda/src/linmath/lmatrix3_src.h b/panda/src/linmath/lmatrix3_src.h index 399508ed5f..2138f0fc39 100644 --- a/panda/src/linmath/lmatrix3_src.h +++ b/panda/src/linmath/lmatrix3_src.h @@ -38,6 +38,7 @@ PUBLISHED: INLINE_LINMATH FLOATTYPE operator [](int i) const; INLINE_LINMATH FLOATTYPE &operator [](int i); INLINE_LINMATH static int size(); + INLINE_LINMATH operator const FLOATNAME(LVecBase3) &() const; public: FLOATTYPE *_row; friend class FLOATNAME(LMatrix3); @@ -48,6 +49,7 @@ PUBLISHED: PUBLISHED: INLINE_LINMATH FLOATTYPE operator [](int i) const; INLINE_LINMATH static int size(); + INLINE_LINMATH operator const FLOATNAME(LVecBase3) &() const; public: const FLOATTYPE *_row; friend class FLOATNAME(LMatrix3); @@ -58,10 +60,12 @@ PUBLISHED: INLINE_LINMATH FLOATNAME(LMatrix3) &operator = ( const FLOATNAME(LMatrix3) &other); INLINE_LINMATH FLOATNAME(LMatrix3) &operator = (FLOATTYPE fill_value); - INLINE_LINMATH FLOATNAME(LMatrix3)( - FLOATTYPE e00, FLOATTYPE e01, FLOATTYPE e02, - FLOATTYPE e10, FLOATTYPE e11, FLOATTYPE e12, - FLOATTYPE e20, FLOATTYPE e21, FLOATTYPE e22); + INLINE_LINMATH FLOATNAME(LMatrix3)(FLOATTYPE, FLOATTYPE, FLOATTYPE, + FLOATTYPE, FLOATTYPE, FLOATTYPE, + FLOATTYPE, FLOATTYPE, FLOATTYPE); + INLINE_LINMATH FLOATNAME(LMatrix3)(const FLOATNAME(LVecBase3) &, + const FLOATNAME(LVecBase3) &, + const FLOATNAME(LVecBase3) &); ALLOC_DELETED_CHAIN(FLOATNAME(LMatrix3)); EXTENSION(INLINE_LINMATH PyObject *__reduce__(PyObject *self) const); diff --git a/panda/src/linmath/lmatrix4_src.I b/panda/src/linmath/lmatrix4_src.I index d5c16d5ce7..a887d393f1 100644 --- a/panda/src/linmath/lmatrix4_src.I +++ b/panda/src/linmath/lmatrix4_src.I @@ -44,6 +44,14 @@ size() { return 4; } +/** + * + */ +INLINE_LINMATH FLOATNAME(LMatrix4)::Row:: +operator const FLOATNAME(LVecBase4) &() const { + return *(const FLOATNAME(LVecBase4) *)_row; +} + /** * Defines a row-level constant accessor to the matrix. */ @@ -68,6 +76,14 @@ size() { return 4; } +/** + * + */ +INLINE_LINMATH FLOATNAME(LMatrix4)::CRow:: +operator const FLOATNAME(LVecBase4) &() const { + return *(const FLOATNAME(LVecBase4) *)_row; +} + /** * Returns an identity matrix. * @@ -178,6 +194,41 @@ FLOATNAME(LMatrix4)(FLOATTYPE e00, FLOATTYPE e01, FLOATTYPE e02, FLOATTYPE e03, _m(3, 3) = e33; } +/** + * Constructs the matrix from four individual rows. + */ +INLINE_LINMATH FLOATNAME(LMatrix4):: +FLOATNAME(LMatrix4)(const FLOATNAME(LVecBase4) &row0, + const FLOATNAME(LVecBase4) &row1, + const FLOATNAME(LVecBase4) &row2, + const FLOATNAME(LVecBase4) &row3) { + TAU_PROFILE("LMatrix4::LMatrix4(const LVecBase4 &, ...)", " ", TAU_USER); + +#ifdef HAVE_EIGEN + _m.row(0) = row0._v; + _m.row(1) = row1._v; + _m.row(2) = row2._v; + _m.row(3) = row3._v; +#else + _m(0, 0) = row0._v(0); + _m(0, 1) = row0._v(1); + _m(0, 2) = row0._v(2); + _m(0, 3) = row0._v(3); + _m(1, 0) = row1._v(0); + _m(1, 1) = row1._v(1); + _m(1, 2) = row1._v(2); + _m(1, 3) = row1._v(3); + _m(2, 0) = row2._v(0); + _m(2, 1) = row2._v(1); + _m(2, 2) = row2._v(2); + _m(2, 3) = row2._v(3); + _m(3, 0) = row3._v(0); + _m(3, 1) = row3._v(1); + _m(3, 2) = row3._v(2); + _m(3, 3) = row3._v(3); +#endif // HAVE_EIGEN +} + /** * */ diff --git a/panda/src/linmath/lmatrix4_src.h b/panda/src/linmath/lmatrix4_src.h index 4d749cddd5..a66a5ab45f 100644 --- a/panda/src/linmath/lmatrix4_src.h +++ b/panda/src/linmath/lmatrix4_src.h @@ -36,6 +36,7 @@ PUBLISHED: INLINE_LINMATH FLOATTYPE operator [](int i) const; INLINE_LINMATH FLOATTYPE &operator [](int i); INLINE_LINMATH static int size(); + INLINE_LINMATH operator const FLOATNAME(LVecBase4) &() const; public: FLOATTYPE *_row; friend class FLOATNAME(LMatrix4); @@ -46,6 +47,7 @@ PUBLISHED: PUBLISHED: INLINE_LINMATH FLOATTYPE operator [](int i) const; INLINE_LINMATH static int size(); + INLINE_LINMATH operator const FLOATNAME(LVecBase4) &() const; public: const FLOATTYPE *_row; friend class FLOATNAME(LMatrix4); @@ -60,10 +62,14 @@ PUBLISHED: const FLOATNAME(UnalignedLMatrix4) &other); INLINE_LINMATH FLOATNAME(LMatrix4) &operator = (FLOATTYPE fill_value); - INLINE_LINMATH FLOATNAME(LMatrix4)(FLOATTYPE e00, FLOATTYPE e01, FLOATTYPE e02, FLOATTYPE e03, - FLOATTYPE e10, FLOATTYPE e11, FLOATTYPE e12, FLOATTYPE e13, - FLOATTYPE e20, FLOATTYPE e21, FLOATTYPE e22, FLOATTYPE e23, - FLOATTYPE e30, FLOATTYPE e31, FLOATTYPE e32, FLOATTYPE e33); + INLINE_LINMATH FLOATNAME(LMatrix4)(FLOATTYPE, FLOATTYPE, FLOATTYPE, FLOATTYPE, + FLOATTYPE, FLOATTYPE, FLOATTYPE, FLOATTYPE, + FLOATTYPE, FLOATTYPE, FLOATTYPE, FLOATTYPE, + FLOATTYPE, FLOATTYPE, FLOATTYPE, FLOATTYPE); + INLINE_LINMATH FLOATNAME(LMatrix4)(const FLOATNAME(LVecBase4) &, + const FLOATNAME(LVecBase4) &, + const FLOATNAME(LVecBase4) &, + const FLOATNAME(LVecBase4) &); ALLOC_DELETED_CHAIN(FLOATNAME(LMatrix4)); EXTENSION(INLINE_LINMATH PyObject *__reduce__(PyObject *self) const); From b4abea17d59416ce77580adfcb73aeb58a1e009b Mon Sep 17 00:00:00 2001 From: rdb Date: Sun, 19 Aug 2018 16:43:34 +0200 Subject: [PATCH 114/125] tests: add various matrix unit tests --- tests/linmath/test_lmatrix3.py | 62 ++++++++++++++++++++ tests/linmath/test_lmatrix4.py | 89 +++++++++++++++++++++++++++++ tests/linmath/test_matrix_invert.py | 20 ------- 3 files changed, 151 insertions(+), 20 deletions(-) create mode 100644 tests/linmath/test_lmatrix3.py create mode 100644 tests/linmath/test_lmatrix4.py delete mode 100644 tests/linmath/test_matrix_invert.py diff --git a/tests/linmath/test_lmatrix3.py b/tests/linmath/test_lmatrix3.py new file mode 100644 index 0000000000..b0ce53685a --- /dev/null +++ b/tests/linmath/test_lmatrix3.py @@ -0,0 +1,62 @@ +import pytest +from copy import copy +from panda3d import core + + +def test_mat3_aliases(): + assert core.LMatrix3 is core.Mat3 + assert core.LMatrix3f is core.Mat3F + assert core.LMatrix3d is core.Mat3D + + assert (core.LMatrix3f is core.Mat3) != (core.LMatrix3d is core.Mat3) + + +@pytest.mark.parametrize("type", (core.LMatrix3f, core.LMatrix3d)) +def test_mat3_constructor(type): + # Test that three ways of construction produce the same matrix. + mat1 = type((1, 2, 3), + (4, 5, 6), + (7, 8, 9)) + + mat2 = type(1, 2, 3, 4, 5, 6, 7, 8, 9) + + mat3 = type((1, 2, 3, 4, 5, 6, 7, 8, 9)) + + assert mat1 == mat2 + assert mat2 == mat3 + assert mat1 == mat3 + + +@pytest.mark.parametrize("type", (core.LMatrix3d, core.LMatrix3f)) +def test_mat3_copy_constuctor(type): + mat1 = type((1, 2, 3), + (4, 5, 6), + (7, 8, 9)) + + # Make a copy. Changing it should not change the original. + mat2 = type(mat1) + assert mat1 == mat2 + mat2[0][0] = 100 + assert mat1 != mat2 + + # Make a copy by unpacking. + mat2 = type(*mat1) + assert mat1 == mat2 + mat2[0][0] = 100 + assert mat1 != mat2 + + # Make a copy by calling copy.copy. + mat2 = copy(mat1) + assert mat1 == mat2 + mat2[0][0] = 100 + assert mat1 != mat2 + + +@pytest.mark.parametrize("type", (core.LMatrix3d, core.LMatrix3f)) +def test_mat3_invert_same_type(type): + mat = type((1, 0, 0, + 0, 1, 0, + 1, 2, 3)) + + inv = core.invert(mat) + assert mat.__class__ == inv.__class__ diff --git a/tests/linmath/test_lmatrix4.py b/tests/linmath/test_lmatrix4.py new file mode 100644 index 0000000000..23c1bcc5e9 --- /dev/null +++ b/tests/linmath/test_lmatrix4.py @@ -0,0 +1,89 @@ +import pytest +from copy import copy +from panda3d import core + + +def test_mat4_aliases(): + assert core.LMatrix4 is core.Mat4 + assert core.LMatrix4f is core.Mat4F + assert core.LMatrix4d is core.Mat4D + + assert (core.LMatrix4f is core.Mat4) != (core.LMatrix4d is core.Mat4) + + +@pytest.mark.parametrize("type", (core.LMatrix4d, core.LMatrix4f)) +def test_mat4_constructor(type): + # Test that three ways of construction produce the same matrix. + mat1 = type((1, 2, 3, 4), + (5, 6, 7, 8), + (9, 10, 11, 12), + (13, 14, 15, 16)) + + mat2 = type(1, 2, 3, 4, + 5, 6, 7, 8, + 9, 10, 11, 12, + 13, 14, 15, 16) + + mat3 = type((1, 2, 3, 4, + 5, 6, 7, 8, + 9, 10, 11, 12, + 13, 14, 15, 16)) + + assert mat1 == mat2 + assert mat2 == mat3 + assert mat1 == mat3 + + +@pytest.mark.parametrize("type", (core.LMatrix4d, core.LMatrix4f)) +def test_mat4_copy_constuctor(type): + mat1 = type((1, 2, 3, 4), + (5, 6, 7, 8), + (9, 10, 11, 12), + (13, 14, 15, 16)) + + # Make a copy. Changing it should not change the original. + mat2 = type(mat1) + assert mat1 == mat2 + mat2[0][0] = 100 + assert mat1 != mat2 + + # Make a copy by unpacking. + mat2 = type(*mat1) + assert mat1 == mat2 + mat2[0][0] = 100 + assert mat1 != mat2 + + # Make a copy by calling copy.copy. + mat2 = copy(mat1) + assert mat1 == mat2 + mat2[0][0] = 100 + assert mat1 != mat2 + + +@pytest.mark.parametrize("type", (core.LMatrix4d, core.LMatrix4f)) +def test_mat4_invert_same_type(type): + mat = type((1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, 0, + 1, 2, 3, 1)) + + inv = core.invert(mat) + assert mat.__class__ == inv.__class__ + + +@pytest.mark.parametrize("type", (core.LMatrix4d, core.LMatrix4f)) +def test_mat4_invert_correct(type): + mat = type((1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, 0, + 1, 2, 3, 1)) + inv = type() + assert inv.invert_from(mat) + + assert inv == type(( 1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, 0, + -1, -2, -3, 1)) + + assert (mat * inv).is_identity() + assert (inv * mat).is_identity() diff --git a/tests/linmath/test_matrix_invert.py b/tests/linmath/test_matrix_invert.py deleted file mode 100644 index b2e6dd49bf..0000000000 --- a/tests/linmath/test_matrix_invert.py +++ /dev/null @@ -1,20 +0,0 @@ -import pytest -from panda3d import core - - -@pytest.mark.parametrize("type", (core.Mat4, core.Mat4D)) -def test_mat4_invert(type): - mat = type((1, 0, 0, 0, - 0, 1, 0, 0, - 0, 0, 1, 0, - 1, 2, 3, 1)) - inv = type() - assert inv.invert_from(mat) - - assert inv == type(( 1, 0, 0, 0, - 0, 1, 0, 0, - 0, 0, 1, 0, - -1, -2, -3, 1)) - - assert (mat * inv).is_identity() - assert (inv * mat).is_identity() From 91ae68f04bef3241c2b254b5529590477602803e Mon Sep 17 00:00:00 2001 From: rdb Date: Sun, 19 Aug 2018 16:49:54 +0200 Subject: [PATCH 115/125] tests: attempt to fix egg2pg test failure on macOS --- tests/egg2pg/test_egg_coordsys.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/egg2pg/test_egg_coordsys.py b/tests/egg2pg/test_egg_coordsys.py index b3c5583075..1c014ebf46 100644 --- a/tests/egg2pg/test_egg_coordsys.py +++ b/tests/egg2pg/test_egg_coordsys.py @@ -37,7 +37,8 @@ def test_egg2pg_transform_ident(egg_coordsys, coordsys): @pytest.mark.parametrize("coordsys", COORD_SYSTEMS) def test_egg2pg_transform_mat_unchanged(coordsys): # Ensures that the matrix remains unchanged if coordinate system is same. - mat = (5, 2, -3, 4, 5, 6, 7, 8, 9, 1, -3, 2, 5, 2, 5, 2) + matv = (5, 2, -3, 4, 5, 6, 7, 8, 9, 1, -3, 2, 5, 2, 5, 2) + mat = core.Mat4D(*matv) group = egg.EggGroup("group") group.add_matrix4(mat) assert not group.transform_is_identity() @@ -57,7 +58,7 @@ def test_egg2pg_transform_mat_unchanged(coordsys): assert root node, = root.children - assert node.transform.mat == mat + assert node.transform.mat == core.Mat4(*matv) @pytest.mark.parametrize("egg_coordsys", COORD_SYSTEMS) From 044d84c8fd42c1cec89fb4660280b0080eec01b8 Mon Sep 17 00:00:00 2001 From: rdb Date: Sun, 19 Aug 2018 16:53:03 +0200 Subject: [PATCH 116/125] mayaegg: fix various compilation warnings --- pandatool/src/mayaegg/mayaEggLoader.cxx | 18 +++++++++--------- pandatool/src/mayaegg/mayaToEggConverter.cxx | 4 ++-- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/pandatool/src/mayaegg/mayaEggLoader.cxx b/pandatool/src/mayaegg/mayaEggLoader.cxx index 4baf1dff86..68fcb8d0f7 100644 --- a/pandatool/src/mayaegg/mayaEggLoader.cxx +++ b/pandatool/src/mayaegg/mayaEggLoader.cxx @@ -837,12 +837,12 @@ int MayaEggGeom::GetVert(EggVertex *vert, EggGroup *context) void MayaEggGeom::AssignNames(void) { string name = _pool->get_name(); - int nsize = name.size(); - if ((nsize > 6) && (name.rfind(".verts")==(nsize-6))) { - name.resize(nsize-6); + size_t nsize = name.size(); + if (nsize > 6 && name.rfind(".verts") == (nsize - 6)) { + name.resize(nsize - 6); } - if ((nsize > 4) && (name.rfind(".cvs")==(nsize-4))) { - name.resize(nsize-4); + if (nsize > 4 && name.rfind(".cvs") == (nsize - 4)) { + name.resize(nsize - 4); } MFnDependencyNode dnshape(_shapeNode); @@ -913,7 +913,7 @@ void MayaEggGeom::AddEggFlag(MString fieldName) { typedef phash_map TVertTable; typedef phash_map CVertTable; -class MayaEggMesh : public MayaEggGeom +class MayaEggMesh final : public MayaEggGeom { public: MColorArray _faceColorArray; @@ -937,7 +937,7 @@ public: int GetCVert(const LColor &col); int AddFace(unsigned numVertices, MIntArray mvertIndices, MIntArray mtvertIndices, MayaEggTex *tex); - void ConnectTextures(void); + void ConnectTextures(void) override; }; int MayaEggMesh::GetTVert(const LTexCoordd &uv) @@ -2012,7 +2012,7 @@ void MayaEggLoader::PrintData(MayaEggMesh *mesh) void MayaEggLoader::ParseFrameInfo(string comment) { - int pos, ls, le; + size_t pos, ls, le; pos = comment.find("-fri"); if (pos != string::npos) { @@ -2143,7 +2143,7 @@ bool MayaEggLoader::ConvertEggFile(const char *name, bool merge, bool model, boo MObject MayaEggLoader::GetDependencyNode(string givenName) { MObject node = MObject::kNullObj; - int pos; + size_t pos; string name; pos = givenName.find(":"); diff --git a/pandatool/src/mayaegg/mayaToEggConverter.cxx b/pandatool/src/mayaegg/mayaToEggConverter.cxx index 747c8ac279..3f693dd004 100644 --- a/pandatool/src/mayaegg/mayaToEggConverter.cxx +++ b/pandatool/src/mayaegg/mayaToEggConverter.cxx @@ -2742,7 +2742,7 @@ set_shader_legacy(EggPrimitive &primitive, const MayaShader &shader, // shader on the list is the base one, which should always pick up // the alpha from the texture file. But the top textures may have // to strip the alpha - if (i!=shader._color.size()-1) { + if ((size_t)i != shader._color.size() - 1) { if (!i && is_interpolate) { // this is the grass path mode where alpha on this texture // determines whether to show layer1 or layer2. Since by now @@ -2846,7 +2846,7 @@ set_shader_legacy(EggPrimitive &primitive, const MayaShader &shader, _textures.create_unique_texture(tex, ~0); if (mesh) { - if (uvset_name.find("not found") == -1) { + if (uvset_name.find("not found") == string::npos) { primitive.add_texture(new_tex); color_def->_uvset_name.assign(uvset_name.c_str()); if (uvset_name != "map1") { From f663d215d56bb24bb316339c8bf621b674618d37 Mon Sep 17 00:00:00 2001 From: Mitchell Stokes Date: Sun, 19 Aug 2018 16:55:07 +0200 Subject: [PATCH 117/125] Remove some unused variables --- dtool/src/interrogate/interfaceMakerPythonNative.cxx | 5 +---- panda/src/egg/eggPrimitive.cxx | 2 +- panda/src/egg2pg/eggLoader.cxx | 1 - panda/src/pgraph/geomNode.cxx | 1 - panda/src/pgraph/geomTransformer.cxx | 1 - panda/src/text/dynamicTextFont.cxx | 1 - 6 files changed, 2 insertions(+), 9 deletions(-) diff --git a/dtool/src/interrogate/interfaceMakerPythonNative.cxx b/dtool/src/interrogate/interfaceMakerPythonNative.cxx index e20aff91ef..5752fe126b 100644 --- a/dtool/src/interrogate/interfaceMakerPythonNative.cxx +++ b/dtool/src/interrogate/interfaceMakerPythonNative.cxx @@ -789,8 +789,6 @@ InterfaceMakerPythonNative:: */ void InterfaceMakerPythonNative:: write_prototypes(ostream &out_code, ostream *out_h) { - Functions::iterator fi; - if (out_h != nullptr) { *out_h << "#include \"py_panda.h\"\n\n"; } @@ -917,7 +915,6 @@ write_prototypes_class_external(ostream &out, Object *obj) { void InterfaceMakerPythonNative:: write_prototypes_class(ostream &out_code, ostream *out_h, Object *obj) { std::string ClassName = make_safe_name(obj->_itype.get_scoped_name()); - Functions::iterator fi; out_code << "/**\n"; out_code << " * Forward declarations for top-level class " << ClassName << "\n"; @@ -3322,7 +3319,7 @@ write_prototype_for(ostream &out, InterfaceMaker::Function *func) { */ void InterfaceMakerPythonNative:: write_prototype_for_name(ostream &out, InterfaceMaker::Function *func, const std::string &function_namename) { - Function::Remaps::const_iterator ri; +// Function::Remaps::const_iterator ri; // for (ri = func->_remaps.begin(); ri != func->_remaps.end(); ++ri) { // FunctionRemap *remap = (*ri); diff --git a/panda/src/egg/eggPrimitive.cxx b/panda/src/egg/eggPrimitive.cxx index f4985dfc90..158866855f 100644 --- a/panda/src/egg/eggPrimitive.cxx +++ b/panda/src/egg/eggPrimitive.cxx @@ -558,7 +558,7 @@ remove_doubled_verts(bool closed) { */ void EggPrimitive:: remove_nonunique_verts() { - Vertices::iterator vi, vj; + Vertices::iterator vi; Vertices new_vertices; int num_removed = 0; diff --git a/panda/src/egg2pg/eggLoader.cxx b/panda/src/egg2pg/eggLoader.cxx index e26a4120b9..9d885e0234 100644 --- a/panda/src/egg2pg/eggLoader.cxx +++ b/panda/src/egg2pg/eggLoader.cxx @@ -2661,7 +2661,6 @@ set_occluder_polygon(EggGroup *egg_group, OccluderNode *pnode) { } else { LMatrix4d mat = poly->get_vertex_to_node(); - EggPolygon::const_iterator vi; LPoint3d v0 = (*poly)[0]->get_pos3() * mat; LPoint3d v1 = (*poly)[1]->get_pos3() * mat; LPoint3d v2 = (*poly)[2]->get_pos3() * mat; diff --git a/panda/src/pgraph/geomNode.cxx b/panda/src/pgraph/geomNode.cxx index 328870364a..16e95442c2 100644 --- a/panda/src/pgraph/geomNode.cxx +++ b/panda/src/pgraph/geomNode.cxx @@ -115,7 +115,6 @@ apply_attribs_to_vertices(const AccumulatedAttribs &attribs, int attrib_types, Thread *current_thread = Thread::get_current_thread(); OPEN_ITERATE_CURRENT_AND_UPSTREAM(_cycler, current_thread) { CDStageWriter cdata(_cycler, pipeline_stage, current_thread); - GeomList::iterator gi; PT(GeomList) geoms = cdata->modify_geoms(); // Iterate based on the number of geoms, not using STL iterators. This diff --git a/panda/src/pgraph/geomTransformer.cxx b/panda/src/pgraph/geomTransformer.cxx index cfc023b528..fe6b022d2d 100644 --- a/panda/src/pgraph/geomTransformer.cxx +++ b/panda/src/pgraph/geomTransformer.cxx @@ -742,7 +742,6 @@ make_compatible_state(GeomNode *node) { } GeomNode::CDWriter cdata(node->_cycler); - GeomNode::GeomList::iterator gi; PT(GeomNode::GeomList) geoms = cdata->modify_geoms(); // For each geom, calculate a canonicalized RenderState, and classify all diff --git a/panda/src/text/dynamicTextFont.cxx b/panda/src/text/dynamicTextFont.cxx index 4eb4afc96a..347841a92f 100644 --- a/panda/src/text/dynamicTextFont.cxx +++ b/panda/src/text/dynamicTextFont.cxx @@ -1072,7 +1072,6 @@ render_polygon_contours(TextGlyph *glyph, bool face, bool extrude) { // create more vertices--they don't share the same normals. for (ci = _contours.begin(); ci != _contours.end(); ++ci) { const Contour &contour = (*ci); - Points::const_iterator pi; for (size_t i = 0; i < contour._points.size(); ++i) { const ContourPoint &cp = contour._points[i]; From 35fff81b6ab9fffff61def1bae96f8142a780db1 Mon Sep 17 00:00:00 2001 From: rdb Date: Sun, 19 Aug 2018 18:52:48 +0200 Subject: [PATCH 118/125] makepanda: fix missing BUILDING_DIRECT_DCPARSER [skip ci] --- direct/src/dcparser/dcNumericRange.I | 10 +++++----- direct/src/dcparser/dcNumericRange.h | 10 +++++----- makepanda/makepanda.py | 2 +- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/direct/src/dcparser/dcNumericRange.I b/direct/src/dcparser/dcNumericRange.I index bd41418205..92973d4410 100644 --- a/direct/src/dcparser/dcNumericRange.I +++ b/direct/src/dcparser/dcNumericRange.I @@ -52,7 +52,7 @@ operator = (const DCNumericRange ©) { * otherwise. */ template -bool DCNumericRange:: +INLINE bool DCNumericRange:: is_in_range(Number num) const { if (_ranges.empty()) { return true; @@ -106,7 +106,7 @@ get_one_value() const { * */ template -void DCNumericRange:: +INLINE void DCNumericRange:: generate_hash(HashGenerator &hashgen) const { if (!_ranges.empty()) { hashgen.add_int(_ranges.size()); @@ -124,7 +124,7 @@ generate_hash(HashGenerator &hashgen) const { * */ template -void DCNumericRange:: +INLINE void DCNumericRange:: output(std::ostream &out, Number divisor) const { if (!_ranges.empty()) { typename Ranges::const_iterator ri; @@ -144,7 +144,7 @@ output(std::ostream &out, Number divisor) const { * characters. */ template -void DCNumericRange:: +INLINE void DCNumericRange:: output_char(std::ostream &out, Number divisor) const { if (divisor != 1) { output(out, divisor); @@ -179,7 +179,7 @@ clear() { * minmax overlaps an existing minmax. */ template -bool DCNumericRange:: +INLINE bool DCNumericRange:: add_range(Number min, Number max) { // Check for an overlap. This is probably indicative of a typo and should // be reported. diff --git a/direct/src/dcparser/dcNumericRange.h b/direct/src/dcparser/dcNumericRange.h index f751323b01..888c54939e 100644 --- a/direct/src/dcparser/dcNumericRange.h +++ b/direct/src/dcparser/dcNumericRange.h @@ -32,20 +32,20 @@ public: INLINE DCNumericRange(const DCNumericRange ©); INLINE void operator = (const DCNumericRange ©); - bool is_in_range(Number num) const; + INLINE bool is_in_range(Number num) const; INLINE void validate(Number num, bool &range_error) const; INLINE bool has_one_value() const; INLINE Number get_one_value() const; - void generate_hash(HashGenerator &hashgen) const; + INLINE void generate_hash(HashGenerator &hashgen) const; - void output(std::ostream &out, Number divisor = 1) const; - void output_char(std::ostream &out, Number divisor = 1) const; + INLINE void output(std::ostream &out, Number divisor = 1) const; + INLINE void output_char(std::ostream &out, Number divisor = 1) const; public: INLINE void clear(); - bool add_range(Number min, Number max); + INLINE bool add_range(Number min, Number max); INLINE bool is_empty() const; INLINE int get_num_ranges() const; diff --git a/makepanda/makepanda.py b/makepanda/makepanda.py index 6181ccf87e..00dd2c3cd3 100755 --- a/makepanda/makepanda.py +++ b/makepanda/makepanda.py @@ -5219,7 +5219,7 @@ if (PkgSkip("DIRECT")==0): # if (PkgSkip("DIRECT")==0): - OPTS=['DIR:direct/src/dcparser', 'WITHINPANDA', 'BISONPREFIX_dcyy', 'PYTHON'] + OPTS=['DIR:direct/src/dcparser', 'BUILDING:DIRECT_DCPARSER', 'WITHINPANDA', 'BISONPREFIX_dcyy', 'PYTHON'] CreateFile(GetOutputDir()+"/include/dcParser.h") TargetAdd('p3dcparser_dcParser.obj', opts=OPTS, input='dcParser.yxx') TargetAdd('dcParser.h', input='p3dcparser_dcParser.obj', opts=['DEPENDENCYONLY']) From 4f9a2aca85c530e9026f675fa44fa524f82a5023 Mon Sep 17 00:00:00 2001 From: rdb Date: Mon, 20 Aug 2018 16:25:55 +0200 Subject: [PATCH 119/125] tests: fix issues with temp files without correct case on Windows --- tests/gobj/test_texture_pool.py | 18 ++++++++++------ tests/putil/test_datagram.py | 37 ++++++++++++++++++++------------- 2 files changed, 35 insertions(+), 20 deletions(-) diff --git a/tests/gobj/test_texture_pool.py b/tests/gobj/test_texture_pool.py index b07e8a0cb9..c8ac5ae44a 100644 --- a/tests/gobj/test_texture_pool.py +++ b/tests/gobj/test_texture_pool.py @@ -22,8 +22,10 @@ def image_rgb_path(): "Generates an RGB image." file = tempfile.NamedTemporaryFile(suffix='-rgb.png') - write_image(file.name, 3) - yield file.name + path = core.Filename.from_os_specific(file.name) + path.make_true_case() + write_image(path, 3) + yield path file.close() @@ -32,8 +34,10 @@ def image_rgba_path(): "Generates an RGBA image." file = tempfile.NamedTemporaryFile(suffix='-rgba.png') - write_image(file.name, 4) - yield file.name + path = core.Filename.from_os_specific(file.name) + path.make_true_case() + write_image(path, 4) + yield path file.close() @@ -42,8 +46,10 @@ def image_gray_path(): "Generates a grayscale image." file = tempfile.NamedTemporaryFile(suffix='-gray.png') - write_image(file.name, 1) - yield file.name + path = core.Filename.from_os_specific(file.name) + path.make_true_case() + write_image(path, 1) + yield path file.close() diff --git a/tests/putil/test_datagram.py b/tests/putil/test_datagram.py index 7919a1360f..751ea0dc03 100644 --- a/tests/putil/test_datagram.py +++ b/tests/putil/test_datagram.py @@ -1,6 +1,7 @@ import pytest from panda3d import core import sys +import tempfile # Fixtures for generating interesting datagrams (and verification functions) on # the fly... @@ -147,30 +148,39 @@ def do_file_test(dg, verify, filename): dgi = core.DatagramIterator(dg2) verify(dgi) -def test_file_small(datagram_small, tmpdir): +@pytest.fixture +def tmpfile(): + file = tempfile.NamedTemporaryFile(suffix='.bin') + yield file + file.close() + +def test_file_small(datagram_small, tmpfile): """This tests DatagramOutputFile/DatagramInputFile on small datagrams.""" dg, verify = datagram_small - p = tmpdir.join('datagram.bin') - filename = core.Filename.from_os_specific(str(p)) + file = tempfile.NamedTemporaryFile(suffix='.bin') + filename = core.Filename.from_os_specific(file.name) + filename.make_true_case() do_file_test(dg, verify, filename) -def test_file_large(datagram_large, tmpdir): +def test_file_large(datagram_large, tmpfile): """This tests DatagramOutputFile/DatagramInputFile on very large datagrams.""" dg, verify = datagram_large - p = tmpdir.join('datagram.bin') - filename = core.Filename.from_os_specific(str(p)) + file = tempfile.NamedTemporaryFile(suffix='.bin') + filename = core.Filename.from_os_specific(file.name) + filename.make_true_case() do_file_test(dg, verify, filename) -def test_file_corrupt(datagram_small, tmpdir): +def test_file_corrupt(datagram_small, tmpfile): """This tests DatagramInputFile's handling of a corrupt size header.""" dg, verify = datagram_small - p = tmpdir.join('datagram.bin') - filename = core.Filename.from_os_specific(str(p)) + file = tempfile.NamedTemporaryFile(suffix='.bin') + filename = core.Filename.from_os_specific(file.name) + filename.make_true_case() dof = core.DatagramOutputFile() dof.open(filename) @@ -178,9 +188,9 @@ def test_file_corrupt(datagram_small, tmpdir): dof.close() # Corrupt the size header to 1GB - with p.open(mode='r+b') as f: - f.seek(0) - f.write(b'\xFF\xFF\xFF\x4F') + file.seek(0) + file.write(b'\xFF\xFF\xFF\x4F') + file.flush() dg2 = core.Datagram() dif = core.DatagramInputFile() @@ -190,8 +200,7 @@ def test_file_corrupt(datagram_small, tmpdir): # Truncate the file for size in [12, 8, 4, 3, 2, 1, 0]: - with p.open(mode='r+b') as f: - f.truncate(size) + file.truncate(size) dg2 = core.Datagram() dif = core.DatagramInputFile() From 5147674980d3d81314bbe3e5ddbad4c01e9ffc21 Mon Sep 17 00:00:00 2001 From: rdb Date: Mon, 20 Aug 2018 16:57:34 +0200 Subject: [PATCH 120/125] Add script to run test suite on a wheel in a virtualenv [skip ci] --- makepanda/test_wheel.py | 61 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100755 makepanda/test_wheel.py diff --git a/makepanda/test_wheel.py b/makepanda/test_wheel.py new file mode 100755 index 0000000000..00555a5e60 --- /dev/null +++ b/makepanda/test_wheel.py @@ -0,0 +1,61 @@ +#!/usr/bin/env python +""" +Tests a .whl file by installing it and pytest into a virtual environment and +running the test suite. + +Requires pip to be installed, as well as 'virtualenv' on Python 2. +""" + +import os +import sys +import shutil +import subprocess +import tempfile +from optparse import OptionParser + + +def test_wheel(wheel, verbose=False): + envdir = tempfile.mkdtemp(prefix="venv-") + print("Setting up virtual environment in {0}".format(envdir)) + + if sys.version_info >= (3, 0): + subprocess.call([sys.executable, "-m", "venv", "--clear", envdir]) + else: + subprocess.call([sys.executable, "-m", "virtualenv", "--clear", envdir]) + + # Install pytest into the environment, as well as our wheel. + if sys.platform == "win32": + pip = os.path.join(envdir, "Scripts", "pip.exe") + else: + pip = os.path.join(envdir, "bin", "pip") + if subprocess.call([pip, "install", "pytest", wheel]) != 0: + shutil.rmtree(envdir) + sys.exit(1) + + # Run the test suite. + if sys.platform == "win32": + python = os.path.join(envdir, "Scripts", "python.exe") + else: + python = os.path.join(envdir, "bin", "python") + test_cmd = [python, "-m", "pytest", "tests"] + if verbose: + test_cmd.append("--verbose") + + exit_code = subprocess.call(test_cmd) + shutil.rmtree(envdir) + + if exit_code != 0: + sys.exit(exit_code) + + +if __name__ == "__main__": + parser = OptionParser(usage="%prog [options] file...") + parser.add_option('', '--verbose', dest = 'verbose', help = 'Enable verbose output', action = 'store_true', default = False) + (options, args) = parser.parse_args() + + if not args: + parser.print_usage() + sys.exit(1) + + for arg in args: + test_wheel(arg, verbose=options.verbose) From c9372c369981e196efa51aecf1c4d9812c5c01d1 Mon Sep 17 00:00:00 2001 From: rdb Date: Sun, 26 Aug 2018 14:02:33 +0200 Subject: [PATCH 121/125] Fix a few GCC compile warnings --- dtool/src/dtoolbase/stl_compares.I | 2 +- panda/src/event/asyncTask.cxx | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/dtool/src/dtoolbase/stl_compares.I b/dtool/src/dtoolbase/stl_compares.I index 501435f547..4190cca45f 100644 --- a/dtool/src/dtoolbase/stl_compares.I +++ b/dtool/src/dtoolbase/stl_compares.I @@ -169,7 +169,7 @@ add_hash(size_t hash, const Key &key) { #ifdef _DEBUG // We assume that the sequence is laid out sequentially in memory. if (key.size() > 0) { - assert(&key[key.size() - 1] - &key[0] == key.size() - 1); + assert(&key[key.size() - 1] - &key[0] == (ptrdiff_t)key.size() - 1); } #endif size_t num_bytes = (key.size() * sizeof(key[0])); diff --git a/panda/src/event/asyncTask.cxx b/panda/src/event/asyncTask.cxx index 806d8e87af..e00b4f46e3 100644 --- a/panda/src/event/asyncTask.cxx +++ b/panda/src/event/asyncTask.cxx @@ -403,6 +403,9 @@ unlock_and_do_task() { Thread *current_thread = Thread::get_current_thread(); nassertr(current_thread->_current_task == nullptr, DS_interrupt); +#ifdef __GNUC__ + __attribute__((unused)) +#endif void *ptr = AtomicAdjust::compare_and_exchange_ptr (current_thread->_current_task, nullptr, (TypedReferenceCount *)this); From a90159271bd5b6ea10c81c6bf53dcbb62fe72a30 Mon Sep 17 00:00:00 2001 From: rdb Date: Sun, 26 Aug 2018 14:02:52 +0200 Subject: [PATCH 122/125] tests: remove unused fixture from Datagram tests --- tests/putil/test_datagram.py | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/tests/putil/test_datagram.py b/tests/putil/test_datagram.py index 751ea0dc03..5a654b75ed 100644 --- a/tests/putil/test_datagram.py +++ b/tests/putil/test_datagram.py @@ -148,13 +148,7 @@ def do_file_test(dg, verify, filename): dgi = core.DatagramIterator(dg2) verify(dgi) -@pytest.fixture -def tmpfile(): - file = tempfile.NamedTemporaryFile(suffix='.bin') - yield file - file.close() - -def test_file_small(datagram_small, tmpfile): +def test_file_small(datagram_small): """This tests DatagramOutputFile/DatagramInputFile on small datagrams.""" dg, verify = datagram_small @@ -164,7 +158,7 @@ def test_file_small(datagram_small, tmpfile): do_file_test(dg, verify, filename) -def test_file_large(datagram_large, tmpfile): +def test_file_large(datagram_large): """This tests DatagramOutputFile/DatagramInputFile on very large datagrams.""" dg, verify = datagram_large @@ -174,7 +168,7 @@ def test_file_large(datagram_large, tmpfile): do_file_test(dg, verify, filename) -def test_file_corrupt(datagram_small, tmpfile): +def test_file_corrupt(datagram_small): """This tests DatagramInputFile's handling of a corrupt size header.""" dg, verify = datagram_small From 115f8df4d593649fda3d2917339519a3e1303a35 Mon Sep 17 00:00:00 2001 From: rdb Date: Sun, 26 Aug 2018 14:03:44 +0200 Subject: [PATCH 123/125] putil: work around GCC bug causing undefined reference in debug build --- panda/src/putil/bitMask.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/panda/src/putil/bitMask.h b/panda/src/putil/bitMask.h index cb11fe10bf..ca5c9d8362 100644 --- a/panda/src/putil/bitMask.h +++ b/panda/src/putil/bitMask.h @@ -37,7 +37,7 @@ PUBLISHED: enum { num_bits = nbits }; constexpr BitMask() = default; - constexpr BitMask(WordType init_value); + ALWAYS_INLINE constexpr BitMask(WordType init_value); INLINE static BitMask all_on(); INLINE static BitMask all_off(); From 27dbad6fd9012438a234f27d713ce7884ad9509a Mon Sep 17 00:00:00 2001 From: rdb Date: Sun, 26 Aug 2018 14:04:19 +0200 Subject: [PATCH 124/125] leveleditor: add missing import --- direct/src/leveleditor/ProtoPalette.py | 1 + 1 file changed, 1 insertion(+) diff --git a/direct/src/leveleditor/ProtoPalette.py b/direct/src/leveleditor/ProtoPalette.py index 0f8aacee3b..12a3c4605c 100755 --- a/direct/src/leveleditor/ProtoPalette.py +++ b/direct/src/leveleditor/ProtoPalette.py @@ -3,6 +3,7 @@ Palette for Prototyping """ from .ProtoPaletteBase import * +import os class ProtoPalette(ProtoPaletteBase): def __init__(self): From b1fc88027abff8810b67c3e36cbf3014ed2155b5 Mon Sep 17 00:00:00 2001 From: rdb Date: Sun, 26 Aug 2018 14:04:48 +0200 Subject: [PATCH 125/125] dtoolbase: add missing DTOOL_PLATFORM for linux_aarch64 --- dtool/src/dtoolbase/dtool_platform.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/dtool/src/dtoolbase/dtool_platform.h b/dtool/src/dtoolbase/dtool_platform.h index 2a6ed12a9b..16ea54d88a 100644 --- a/dtool/src/dtoolbase/dtool_platform.h +++ b/dtool/src/dtoolbase/dtool_platform.h @@ -63,6 +63,9 @@ #define DTOOL_PLATFORM "android_i386" #endif +#elif defined(__aarch64__) +#define DTOOL_PLATFORM "linux_aarch64" + #elif defined(__x86_64) #define DTOOL_PLATFORM "linux_amd64"