From a655784d8d36b4fefd0e926a18c2bea52c3271fa Mon Sep 17 00:00:00 2001 From: rdb Date: Thu, 16 May 2024 20:28:26 +0200 Subject: [PATCH 1/9] x11: attempt to fix UTF-8 window titles (see #209) --- panda/src/x11display/x11GraphicsPipe.cxx | 1 + panda/src/x11display/x11GraphicsPipe.h | 1 + panda/src/x11display/x11GraphicsWindow.cxx | 9 +++++++++ 3 files changed, 11 insertions(+) diff --git a/panda/src/x11display/x11GraphicsPipe.cxx b/panda/src/x11display/x11GraphicsPipe.cxx index 42327d4582..c5e24e10bf 100644 --- a/panda/src/x11display/x11GraphicsPipe.cxx +++ b/panda/src/x11display/x11GraphicsPipe.cxx @@ -340,6 +340,7 @@ x11GraphicsPipe(const std::string &display) : // Get some X atom numbers. _wm_delete_window = XInternAtom(_display, "WM_DELETE_WINDOW", false); + _net_wm_name = XInternAtom(_display, "_NET_WM_NAME", false); _net_wm_pid = XInternAtom(_display, "_NET_WM_PID", false); _net_wm_window_type = XInternAtom(_display, "_NET_WM_WINDOW_TYPE", false); _net_wm_window_type_splash = XInternAtom(_display, "_NET_WM_WINDOW_TYPE_SPLASH", false); diff --git a/panda/src/x11display/x11GraphicsPipe.h b/panda/src/x11display/x11GraphicsPipe.h index e1abf80b00..c457332f9e 100644 --- a/panda/src/x11display/x11GraphicsPipe.h +++ b/panda/src/x11display/x11GraphicsPipe.h @@ -125,6 +125,7 @@ public: public: // Atom specifications. Atom _wm_delete_window; + Atom _net_wm_name; Atom _net_wm_pid; Atom _net_wm_window_type; Atom _net_wm_window_type_splash; diff --git a/panda/src/x11display/x11GraphicsWindow.cxx b/panda/src/x11display/x11GraphicsWindow.cxx index 7e03bb73c5..531a100e59 100644 --- a/panda/src/x11display/x11GraphicsWindow.cxx +++ b/panda/src/x11display/x11GraphicsWindow.cxx @@ -1188,6 +1188,15 @@ set_wm_properties(const WindowProperties &properties, bool already_mapped) { if (XStringListToTextProperty((char **)&name, 1, &window_name) != 0) { window_name_p = &window_name; } + +#ifdef X_HAVE_UTF8_STRING + XTextProperty wm_name; + if (Xutf8TextListToTextProperty(_display, (char **)&name, 1, + XUTF8StringStyle, &wm_name) == Success) { + XSetTextProperty(_display, _xwindow, &wm_name, x11_pipe->_net_wm_name); + XFree(wm_name.value); + } +#endif } // The size hints request a window of a particular size andor a particular From 105f938d68e7a2cff0201bf11f8f4b51f116e934 Mon Sep 17 00:00:00 2001 From: rdb Date: Tue, 28 May 2024 11:11:21 +0200 Subject: [PATCH 2/9] interrogate: Fix non-deterministic order of external import types Fixes #1651 --- .../src/interrogate/interfaceMakerPythonNative.cxx | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/dtool/src/interrogate/interfaceMakerPythonNative.cxx b/dtool/src/interrogate/interfaceMakerPythonNative.cxx index 0606965fa3..3850cefaf0 100644 --- a/dtool/src/interrogate/interfaceMakerPythonNative.cxx +++ b/dtool/src/interrogate/interfaceMakerPythonNative.cxx @@ -885,12 +885,19 @@ write_prototypes(ostream &out_code, ostream *out_h) { // Write out a table of the externally imported types that will be filled in // upon module initialization. - if (!_external_imports.empty()) { + std::vector ext_imports(_external_imports.begin(), _external_imports.end()); + if (!ext_imports.empty()) { out_code << "#ifndef LINK_ALL_STATIC\n"; out_code << "static Dtool_TypeDef imports[] = {\n"; + // Ensure that there is a deterministic ordering of external imports. + std::sort(ext_imports.begin(), ext_imports.end(), + [] (const CPPType *a, const CPPType *b) { + return a->get_local_name(&parser) < b->get_local_name(&parser); + }); + int idx = 0; - for (CPPType *type : _external_imports) { + for (CPPType *type : ext_imports) { string class_name = type->get_local_name(&parser); string safe_name = make_safe_name(class_name); @@ -903,7 +910,7 @@ write_prototypes(ostream &out_code, ostream *out_h) { out_code << "#endif\n\n"; } - for (CPPType *type : _external_imports) { + for (CPPType *type : ext_imports) { string class_name = type->get_local_name(&parser); string safe_name = make_safe_name(class_name); From b6ec48b27c17fdcdfb3a3604e157d107b73afa55 Mon Sep 17 00:00:00 2001 From: rdb Date: Tue, 28 May 2024 22:28:37 +0200 Subject: [PATCH 3/9] Fix invalid metadata version 2.0 (should be 2.1) --- makepanda/makepanda.py | 2 +- makepanda/makewheel.py | 2 +- tests/showbase/test_Loader.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/makepanda/makepanda.py b/makepanda/makepanda.py index d9e157d79a..f3839470a0 100755 --- a/makepanda/makepanda.py +++ b/makepanda/makepanda.py @@ -3271,7 +3271,7 @@ if not PkgSkip("PYTHON"): # This is just some basic stuff since setuptools just needs this file to # exist, otherwise it will not read the entry_points.txt file. Maybe we will # eventually want to merge this with the metadata generator in makewheel.py. -METADATA = """Metadata-Version: 2.0 +METADATA = """Metadata-Version: 2.1 Name: Panda3D Version: {version} License: BSD diff --git a/makepanda/makewheel.py b/makepanda/makewheel.py index 880fa277e6..3cd431c51d 100644 --- a/makepanda/makewheel.py +++ b/makepanda/makewheel.py @@ -122,7 +122,7 @@ PROJECT_URLS = dict([line.split('=', 1) for line in GetMetadataValue('project_ur METADATA = { "license": GetMetadataValue('license'), "name": GetMetadataValue('name'), - "metadata_version": "2.0", + "metadata_version": "2.1", "generator": "makepanda", "summary": GetMetadataValue('description'), "extensions": { diff --git a/tests/showbase/test_Loader.py b/tests/showbase/test_Loader.py index cac29dd34c..99a24a7b0d 100644 --- a/tests/showbase/test_Loader.py +++ b/tests/showbase/test_Loader.py @@ -90,7 +90,7 @@ class FnargleLoader: """) tmpdir.join("fnargle.dist-info").mkdir() tmpdir.join("fnargle.dist-info", "METADATA").write(""" -Metadata-Version: 2.0 +Metadata-Version: 2.1 Name: fnargle Version: 1.0.0 """) From 122453811d917b16e60e75f0de47b18e37c4dd7a Mon Sep 17 00:00:00 2001 From: rdb Date: Sun, 30 Jun 2024 11:53:17 +0200 Subject: [PATCH 4/9] glgsg: Fix clear of offscreen buffer if back buffers requested --- panda/src/glstuff/glGraphicsBuffer_src.cxx | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/panda/src/glstuff/glGraphicsBuffer_src.cxx b/panda/src/glstuff/glGraphicsBuffer_src.cxx index b66be51b3c..e63ea89b17 100644 --- a/panda/src/glstuff/glGraphicsBuffer_src.cxx +++ b/panda/src/glstuff/glGraphicsBuffer_src.cxx @@ -16,6 +16,18 @@ using std::max; using std::min; +/** + * Returns a copy of the FrameBufferProperties, but without back buffers. + * This is used since the GraphicsOutput constructor makes some decisions + * based on whether this is set, so we need to unset it early. + */ +static FrameBufferProperties +without_back_buffers(const FrameBufferProperties &fb_prop) { + FrameBufferProperties copy(fb_prop); + copy.set_back_buffers(0); + return copy; +} + TypeHandle CLP(GraphicsBuffer)::_type_handle; /** @@ -29,7 +41,7 @@ CLP(GraphicsBuffer)(GraphicsEngine *engine, GraphicsPipe *pipe, int flags, GraphicsStateGuardian *gsg, GraphicsOutput *host) : - GraphicsBuffer(engine, pipe, name, fb_prop, win_prop, flags, gsg, host), + GraphicsBuffer(engine, pipe, name, without_back_buffers(fb_prop), win_prop, flags, gsg, host), _bind_texture_pcollector(_draw_window_pcollector, "Bind textures"), _generate_mipmap_pcollector(_draw_window_pcollector, "Generate mipmaps"), _resolve_multisample_pcollector(_draw_window_pcollector, "Resolve multisamples"), From 46833e9144a7d1aab3b5f2b194e6385e6035045b Mon Sep 17 00:00:00 2001 From: rdb Date: Wed, 7 Aug 2024 11:56:55 +0200 Subject: [PATCH 5/9] Update BACKERS.md [skip ci] --- BACKERS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/BACKERS.md b/BACKERS.md index d1a9dd8727..dab94be04a 100644 --- a/BACKERS.md +++ b/BACKERS.md @@ -8,6 +8,7 @@ This is a list of all the people who are contributing financially to Panda3D. I * [Daniel Stokes](https://opencollective.com/daniel-stokes) * [David Rose](https://opencollective.com/david-rose) +* [Route4Me](https://route4me.com/) ## Benefactors From b8d6c7a2ef1dfaf80cd8d41a831365cb49d58765 Mon Sep 17 00:00:00 2001 From: rdb Date: Wed, 7 Aug 2024 11:57:19 +0200 Subject: [PATCH 6/9] workflow: Update macOS-11 to macOS-12 runner --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 990de25e94..1cdcbfdc07 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -6,7 +6,7 @@ jobs: if: "!contains(github.event.head_commit.message, '[skip ci]') && !contains(github.event.head_commit.message, '[ci skip]')" strategy: matrix: - os: [ubuntu-20.04, windows-2019, macOS-11] + os: [ubuntu-20.04, windows-2019, macOS-12] runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v1 From ca7ba4eab321fe84e4cdcb2dbee6197358818a57 Mon Sep 17 00:00:00 2001 From: rdb Date: Wed, 7 Aug 2024 15:53:27 +0200 Subject: [PATCH 7/9] py_panda: Add Dtool_GetPyTypeObject macro This is a cleaner, future-proof way of accessing a Panda type as PyTypeObject pointer --- dtool/src/interrogatedb/py_panda.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/dtool/src/interrogatedb/py_panda.h b/dtool/src/interrogatedb/py_panda.h index 026d1c6858..23a38c4f7f 100644 --- a/dtool/src/interrogatedb/py_panda.h +++ b/dtool/src/interrogatedb/py_panda.h @@ -161,6 +161,9 @@ static void Dtool_FreeInstance_##CLASS_NAME(PyObject *self) {\ Py_TYPE(self)->tp_free(self);\ } +// Extract the PyTypeObject pointer corresponding to a Dtool_PyTypedObject. +#define Dtool_GetPyTypeObject(type) (&(type)->_PyType) + // Use DtoolInstance_Check to check whether a PyObject* is a DtoolInstance. #define DtoolInstance_Check(obj) \ (Py_TYPE(obj)->tp_basicsize >= (int)sizeof(Dtool_PyInstDef) && \ From 8c8cbeea98abed875fbc2255e14bab2d0c7bf1b4 Mon Sep 17 00:00:00 2001 From: rdb Date: Wed, 7 Aug 2024 17:24:11 +0200 Subject: [PATCH 8/9] linmath: For repr, use as much precision as needed for roundtrip Will use as few digits as is necessary to ensure that round-tripping the same number with pstrtod will result in the same vector. This prevents eg. 3.3 formatting as 3.29999995 while still ensuring that two floats that are not equal (other than nan) are guaranteed to have a different string representation. Uses a hacky pftoa function that can be abandoned as soon as we adopt C++17, which has to_chars that does what we need Fixes #1671 --- dtool/src/dtoolbase/pdtoa.cxx | 158 ++++++++++++++++++++++++++ dtool/src/dtoolbase/pdtoa.h | 1 + dtool/src/dtoolutil/string_utils.I | 2 +- panda/src/linmath/dblnames.h | 13 +++ panda/src/linmath/fltnames.h | 13 +++ panda/src/linmath/intnames.h | 3 + panda/src/linmath/lmatrix3_ext_src.I | 27 +++-- panda/src/linmath/lmatrix4_ext_src.I | 35 +++--- panda/src/linmath/lpoint2_ext_src.I | 18 ++- panda/src/linmath/lpoint3_ext_src.I | 23 +++- panda/src/linmath/lpoint4_ext_src.I | 28 +++-- panda/src/linmath/lvecBase2_ext_src.I | 18 ++- panda/src/linmath/lvecBase3_ext_src.I | 24 +++- panda/src/linmath/lvecBase4_ext_src.I | 28 +++-- panda/src/linmath/lvector2_ext_src.I | 18 ++- panda/src/linmath/lvector3_ext_src.I | 23 +++- panda/src/linmath/lvector4_ext_src.I | 28 +++-- tests/linmath/test_lvector2.py | 11 ++ tests/linmath/test_lvector3.py | 13 +++ tests/linmath/test_lvector4.py | 7 ++ 20 files changed, 404 insertions(+), 87 deletions(-) diff --git a/dtool/src/dtoolbase/pdtoa.cxx b/dtool/src/dtoolbase/pdtoa.cxx index 2b508654ba..8055f6d49d 100644 --- a/dtool/src/dtoolbase/pdtoa.cxx +++ b/dtool/src/dtoolbase/pdtoa.cxx @@ -428,3 +428,161 @@ void pdtoa(double value, char *buffer) { Prettify(buffer, length, K); } } + +/** + * Version of pdtoa that tries hard to find the minimal string representation + * for a single-precision floating-point number. + */ +void pftoa(float value, char *buffer) { +#ifdef _MSC_VER + if (copysign(1.0f, value) < 0) { +#else + if (std::signbit(value)) { +#endif + *buffer++ = '-'; + value = -value; + } + if (cinf(value)) { + buffer[0] = 'i'; + buffer[1] = 'n'; + buffer[2] = 'f'; + buffer[3] = '\0'; + } else if (cnan(value)) { + buffer[0] = 'n'; + buffer[1] = 'a'; + buffer[2] = 'n'; + buffer[3] = '\0'; + } else if (value == 0.0f) { + buffer[0] = '0'; + buffer[1] = '.'; + buffer[2] = '0'; + buffer[3] = '\0'; + } else if (value == 1.0f) { + buffer[0] = '1'; + buffer[1] = '.'; + buffer[2] = '0'; + buffer[3] = '\0'; + } else { + int length, k; + Grisu2(value, buffer, &length, &k); + + const int kk = length + k; // 10^(kk-1) <= v < 10^kk + + if (length <= kk && kk <= 21) { + // 1234e7 -> 12340000000 + for (int i = length; i < kk; i++) + buffer[i] = '0'; + buffer[kk] = '.'; + buffer[kk + 1] = '0'; + buffer[kk + 2] = '\0'; + } + else if (0 < kk && kk <= 21) { + // 1234e-2 -> 12.34 + memmove(&buffer[kk + 1], &buffer[kk], length - kk); + + // We want the shortest possible representation, so keep reading digits + // until strtod would give the correct float value. + buffer[kk] = '\0'; + double v = (double)atoi(buffer); + buffer[kk] = '.'; + + double multiplicand = 0.1; + for (int i = kk + 1; i <= length; ++i) { + double vplus = v + (buffer[i] - '0' + 1) * multiplicand; + v += (buffer[i] - '0') * multiplicand; + multiplicand *= 0.1; + + if ((float)v == value) { + length = i; + break; + } + if (buffer[i] < '9' && (float)vplus == value) { + ++buffer[i]; + length = i; + break; + } + } + + buffer[length + 1] = '\0'; + } + else if (-6 < kk && kk <= 0) { + // 1234e-6 -> 0.001234 + const int offset = 2 - kk; + memmove(&buffer[offset], &buffer[0], length); + buffer[0] = '0'; + buffer[1] = '.'; + + // We want the shortest possible representation, so keep reading digits + // until strtod would give the correct float value. + double multiplicand = 1.0; + for (int i = 2; i < offset; i++) { + buffer[i] = '0'; + multiplicand *= 0.1; + } + if ((float)multiplicand == value) { + length = 0; + buffer[offset - 1] = '1'; + } else { + multiplicand *= 0.1; + double v = 0.0; + for (int i = offset; i < length + offset; ++i) { + double vplus = v + (buffer[i] - '0' + 1) * multiplicand; + v += (buffer[i] - '0') * multiplicand; + multiplicand *= 0.1; + + if ((float)v == value) { + buffer[i + 1] = '\0'; + break; + } + if (buffer[i] < '9' && (float)vplus == value) { + buffer[i]++; + buffer[i + 1] = '\0'; + break; + } + } + } + buffer[length + offset] = '\0'; + } + else if (length == 1) { + // 1e30 + buffer[1] = 'e'; + WriteExponent(kk - 1, &buffer[2]); + } + else { + // 1234e30 -> 1.234e33 + memmove(&buffer[2], &buffer[1], length - 1); + buffer[1] = '.'; + buffer[length + 1] = 'e'; + + double e_mult = pow(10.0, kk - 1); + if ((float)(10.0 * e_mult) == value) { + buffer[0] = '1'; + buffer[1] = 'e'; + WriteExponent(kk, &buffer[2]); + } else { + // We want the shortest possible representation, so keep reading + // digits until strtod would give the correct float value. + double v = buffer[0] - '0'; + double multiplicand = 0.1; + for (int i = 2; i < length + 2; ++i) { + double vplus = v + (buffer[i] - '0' + 1) * multiplicand; + v += (buffer[i] - '0') * multiplicand; + multiplicand *= 0.1; + + if ((float)(v * e_mult) == value) { + length = i; + buffer[i + 1] = 'e'; + break; + } + if (buffer[i] < '9' && (float)(vplus * e_mult) == value) { + buffer[i]++; + length = i; + buffer[i + 1] = 'e'; + break; + } + } + WriteExponent(kk - 1, &buffer[0 + length + 2]); + } + } + } +} diff --git a/dtool/src/dtoolbase/pdtoa.h b/dtool/src/dtoolbase/pdtoa.h index 908ca24deb..44b0d9e271 100644 --- a/dtool/src/dtoolbase/pdtoa.h +++ b/dtool/src/dtoolbase/pdtoa.h @@ -16,6 +16,7 @@ extern "C" { #endif EXPCL_DTOOL_DTOOLBASE void pdtoa(double value, char *buffer); +EXPCL_DTOOL_DTOOLBASE void pftoa(float value, char *buffer); #ifdef __cplusplus }; /* end of extern "C" */ diff --git a/dtool/src/dtoolutil/string_utils.I b/dtool/src/dtoolutil/string_utils.I index 1861e86ffa..d821deffdf 100644 --- a/dtool/src/dtoolutil/string_utils.I +++ b/dtool/src/dtoolutil/string_utils.I @@ -32,7 +32,7 @@ format_string(bool value) { INLINE std::string format_string(float value) { char buffer[32]; - pdtoa((double)value, buffer); + pftoa(value, buffer); return std::string(buffer); } diff --git a/panda/src/linmath/dblnames.h b/panda/src/linmath/dblnames.h index c2c646b750..a2e7363e3e 100644 --- a/panda/src/linmath/dblnames.h +++ b/panda/src/linmath/dblnames.h @@ -33,6 +33,7 @@ #undef FLOATTYPE_IS_INT #undef STRINGIFY #undef FLOATNAME_STR +#undef FLOATTYPE_REPR #define FLOATTYPE double #define FLOATNAME(ARG) ARG##d @@ -41,3 +42,15 @@ #define STRINGIFY(ARG) #ARG #define FLOATNAME_STR(ARG) STRINGIFY(ARG##d) + +#define FLOATTYPE_REPR(v, str) do { \ + double v_copy = (v); \ + char *into_str = (str); \ + if ((double)(long long)v_copy == v_copy) { \ + snprintf(into_str, 32, "%lld", (long long)v_copy); \ + } else { \ + pdtoa(v_copy, into_str); \ + } \ +} while (0) + +#include "pdtoa.h" diff --git a/panda/src/linmath/fltnames.h b/panda/src/linmath/fltnames.h index d8d4762ddb..a69d651f51 100644 --- a/panda/src/linmath/fltnames.h +++ b/panda/src/linmath/fltnames.h @@ -33,6 +33,7 @@ #undef FLOATTYPE_IS_INT #undef STRINGIFY #undef FLOATNAME_STR +#undef FLOATTYPE_REPR #define FLOATTYPE float #define FLOATNAME(ARG) ARG##f @@ -41,3 +42,15 @@ #define STRINGIFY(ARG) #ARG #define FLOATNAME_STR(ARG) STRINGIFY(ARG##f) + +#define FLOATTYPE_REPR(v, str) do { \ + float v_copy = (v); \ + char *into_str = (str); \ + if ((float)(int)v_copy == v_copy) { \ + snprintf(into_str, 32, "%d", (int)v_copy); \ + } else { \ + pftoa(v_copy, into_str); \ + } \ +} while (0) + +#include "pdtoa.h" diff --git a/panda/src/linmath/intnames.h b/panda/src/linmath/intnames.h index 2a01d71e05..a7e1ae7cb8 100644 --- a/panda/src/linmath/intnames.h +++ b/panda/src/linmath/intnames.h @@ -33,6 +33,7 @@ #undef FLOATTYPE_IS_INT #undef STRINGIFY #undef FLOATNAME_STR +#undef FLOATTYPE_REPR #define FLOATTYPE int #define FLOATNAME(ARG) ARG##i @@ -42,3 +43,5 @@ #define STRINGIFY(ARG) #ARG #define FLOATNAME_STR(ARG) STRINGIFY(ARG##i) + +#define FLOATTYPE_REPR(v, str) (snprintf((str), 12, "%d", (v))) diff --git a/panda/src/linmath/lmatrix3_ext_src.I b/panda/src/linmath/lmatrix3_ext_src.I index 0d92b37aa4..2d75898853 100644 --- a/panda/src/linmath/lmatrix3_ext_src.I +++ b/panda/src/linmath/lmatrix3_ext_src.I @@ -39,18 +39,21 @@ __reduce__(PyObject *self) const { */ INLINE_LINMATH std::string Extension:: __repr__() const { - std::ostringstream out; - out << "LMatrix3" << FLOATTOKEN << "(" - << MAYBE_ZERO(_this->_m(0, 0)) << ", " - << MAYBE_ZERO(_this->_m(0, 1)) << ", " - << MAYBE_ZERO(_this->_m(0, 2)) << ", " + char buf[32 * 17] = "LMatrix4"; + char *p = buf + strlen(buf); + *(p++) = FLOATTOKEN; + *(p++) = '('; + FLOATTYPE_REPR(_this->_m(0, 0), p); + p += strlen(p); - << MAYBE_ZERO(_this->_m(1, 0)) << ", " - << MAYBE_ZERO(_this->_m(1, 1)) << ", " - << MAYBE_ZERO(_this->_m(1, 2)) << ", " + for (int i = 1; i < 9; ++i) { + *(p++) = ','; + *(p++) = ' '; + FLOATTYPE_REPR(_this->get_data()[i], p); + p += strlen(p); + } - << MAYBE_ZERO(_this->_m(2, 0)) << ", " - << MAYBE_ZERO(_this->_m(2, 1)) << ", " - << MAYBE_ZERO(_this->_m(2, 2)) << ")"; - return out.str(); + *(p++) = ')'; + *p = '\0'; + return std::string(buf, p - buf); } diff --git a/panda/src/linmath/lmatrix4_ext_src.I b/panda/src/linmath/lmatrix4_ext_src.I index 68a2741bbb..a216c7f153 100644 --- a/panda/src/linmath/lmatrix4_ext_src.I +++ b/panda/src/linmath/lmatrix4_ext_src.I @@ -40,26 +40,21 @@ __reduce__(PyObject *self) const { */ INLINE_LINMATH std::string Extension:: __repr__() const { - std::ostringstream out; - out << "LMatrix4" << FLOATTOKEN << "(" - << MAYBE_ZERO(_this->_m(0, 0)) << ", " - << MAYBE_ZERO(_this->_m(0, 1)) << ", " - << MAYBE_ZERO(_this->_m(0, 2)) << ", " - << MAYBE_ZERO(_this->_m(0, 3)) << ", " + char buf[32 * 17] = "LMatrix4"; + char *p = buf + strlen(buf); + *(p++) = FLOATTOKEN; + *(p++) = '('; + FLOATTYPE_REPR(_this->_m(0, 0), p); + p += strlen(p); - << MAYBE_ZERO(_this->_m(1, 0)) << ", " - << MAYBE_ZERO(_this->_m(1, 1)) << ", " - << MAYBE_ZERO(_this->_m(1, 2)) << ", " - << MAYBE_ZERO(_this->_m(1, 3)) << ", " + for (int i = 1; i < 16; ++i) { + *(p++) = ','; + *(p++) = ' '; + FLOATTYPE_REPR(_this->get_data()[i], p); + p += strlen(p); + } - << MAYBE_ZERO(_this->_m(2, 0)) << ", " - << MAYBE_ZERO(_this->_m(2, 1)) << ", " - << MAYBE_ZERO(_this->_m(2, 2)) << ", " - << MAYBE_ZERO(_this->_m(2, 3)) << ", " - - << MAYBE_ZERO(_this->_m(3, 0)) << ", " - << MAYBE_ZERO(_this->_m(3, 1)) << ", " - << MAYBE_ZERO(_this->_m(3, 2)) << ", " - << MAYBE_ZERO(_this->_m(3, 3)) << ")"; - return out.str(); + *(p++) = ')'; + *p = '\0'; + return std::string(buf, p - buf); } diff --git a/panda/src/linmath/lpoint2_ext_src.I b/panda/src/linmath/lpoint2_ext_src.I index acfa098501..300836aa84 100644 --- a/panda/src/linmath/lpoint2_ext_src.I +++ b/panda/src/linmath/lpoint2_ext_src.I @@ -16,11 +16,19 @@ */ INLINE_LINMATH std::string Extension:: __repr__() const { - std::ostringstream out; - out << "LPoint2" << FLOATTOKEN << "(" - << MAYBE_ZERO(_this->_v(0)) << ", " - << MAYBE_ZERO(_this->_v(1)) << ")"; - return out.str(); + char buf[96] = "LPoint2"; + char *p = buf + strlen(buf); + *(p++) = FLOATTOKEN; + *(p++) = '('; + FLOATTYPE_REPR(_this->_v(0), p); + p += strlen(p); + *(p++) = ','; + *(p++) = ' '; + FLOATTYPE_REPR(_this->_v(1), p); + p += strlen(p); + *(p++) = ')'; + *p = '\0'; + return std::string(buf, p - buf); } /** diff --git a/panda/src/linmath/lpoint3_ext_src.I b/panda/src/linmath/lpoint3_ext_src.I index 95cb1dbdd3..30ebc380e9 100644 --- a/panda/src/linmath/lpoint3_ext_src.I +++ b/panda/src/linmath/lpoint3_ext_src.I @@ -16,12 +16,23 @@ */ INLINE_LINMATH std::string Extension:: __repr__() const { - std::ostringstream out; - out << "LPoint3" << FLOATTOKEN << "(" - << MAYBE_ZERO(_this->_v(0)) << ", " - << MAYBE_ZERO(_this->_v(1)) << ", " - << MAYBE_ZERO(_this->_v(2)) << ")"; - return out.str(); + char buf[128] = "LPoint3"; + char *p = buf + strlen(buf); + *(p++) = FLOATTOKEN; + *(p++) = '('; + FLOATTYPE_REPR(_this->_v(0), p); + p += strlen(p); + *(p++) = ','; + *(p++) = ' '; + FLOATTYPE_REPR(_this->_v(1), p); + p += strlen(p); + *(p++) = ','; + *(p++) = ' '; + FLOATTYPE_REPR(_this->_v(2), p); + p += strlen(p); + *(p++) = ')'; + *p = '\0'; + return std::string(buf, p - buf); } /** diff --git a/panda/src/linmath/lpoint4_ext_src.I b/panda/src/linmath/lpoint4_ext_src.I index e4101b5ed9..80075edd0b 100644 --- a/panda/src/linmath/lpoint4_ext_src.I +++ b/panda/src/linmath/lpoint4_ext_src.I @@ -16,13 +16,27 @@ */ INLINE_LINMATH std::string Extension:: __repr__() const { - std::ostringstream out; - out << "LPoint4" << FLOATTOKEN << "(" - << MAYBE_ZERO(_this->_v(0)) << ", " - << MAYBE_ZERO(_this->_v(1)) << ", " - << MAYBE_ZERO(_this->_v(2)) << ", " - << MAYBE_ZERO(_this->_v(3)) << ")"; - return out.str(); + char buf[160] = "LPoint4"; + char *p = buf + strlen(buf); + *(p++) = FLOATTOKEN; + *(p++) = '('; + FLOATTYPE_REPR(_this->_v(0), p); + p += strlen(p); + *(p++) = ','; + *(p++) = ' '; + FLOATTYPE_REPR(_this->_v(1), p); + p += strlen(p); + *(p++) = ','; + *(p++) = ' '; + FLOATTYPE_REPR(_this->_v(2), p); + p += strlen(p); + *(p++) = ','; + *(p++) = ' '; + FLOATTYPE_REPR(_this->_v(3), p); + p += strlen(p); + *(p++) = ')'; + *p = '\0'; + return std::string(buf, p - buf); } /** diff --git a/panda/src/linmath/lvecBase2_ext_src.I b/panda/src/linmath/lvecBase2_ext_src.I index da9f52388d..edb0a69af6 100644 --- a/panda/src/linmath/lvecBase2_ext_src.I +++ b/panda/src/linmath/lvecBase2_ext_src.I @@ -29,11 +29,19 @@ */ INLINE_LINMATH std::string Extension:: __repr__() const { - std::ostringstream out; - out << "LVecBase2" << FLOATTOKEN << "(" - << MAYBE_ZERO(_this->_v(0)) << ", " - << MAYBE_ZERO(_this->_v(1)) << ")"; - return out.str(); + char buf[96] = "LVecBase2"; + char *p = buf + strlen(buf); + *(p++) = FLOATTOKEN; + *(p++) = '('; + FLOATTYPE_REPR(_this->_v(0), p); + p += strlen(p); + *(p++) = ','; + *(p++) = ' '; + FLOATTYPE_REPR(_this->_v(1), p); + p += strlen(p); + *(p++) = ')'; + *p = '\0'; + return std::string(buf, p - buf); } /** diff --git a/panda/src/linmath/lvecBase3_ext_src.I b/panda/src/linmath/lvecBase3_ext_src.I index e59a032b89..72913c816c 100644 --- a/panda/src/linmath/lvecBase3_ext_src.I +++ b/panda/src/linmath/lvecBase3_ext_src.I @@ -29,12 +29,23 @@ */ INLINE_LINMATH std::string Extension:: __repr__() const { - std::ostringstream out; - out << "LVecBase3" << FLOATTOKEN << "(" - << MAYBE_ZERO(_this->_v(0)) << ", " - << MAYBE_ZERO(_this->_v(1)) << ", " - << MAYBE_ZERO(_this->_v(2)) << ")"; - return out.str(); + char buf[128] = "LVecBase3"; + char *p = buf + strlen(buf); + *(p++) = FLOATTOKEN; + *(p++) = '('; + FLOATTYPE_REPR(_this->_v(0), p); + p += strlen(p); + *(p++) = ','; + *(p++) = ' '; + FLOATTYPE_REPR(_this->_v(1), p); + p += strlen(p); + *(p++) = ','; + *(p++) = ' '; + FLOATTYPE_REPR(_this->_v(2), p); + p += strlen(p); + *(p++) = ')'; + *p = '\0'; + return std::string(buf, p - buf); } /** @@ -356,3 +367,4 @@ __ceil__(PyObject *self) const { #undef PYNUMBER_FLOATTYPE #undef PY_AS_FLOATTYPE +#undef FLOATTYPE_TO_STR diff --git a/panda/src/linmath/lvecBase4_ext_src.I b/panda/src/linmath/lvecBase4_ext_src.I index 9db21d73ee..1a120e678d 100644 --- a/panda/src/linmath/lvecBase4_ext_src.I +++ b/panda/src/linmath/lvecBase4_ext_src.I @@ -29,13 +29,27 @@ */ INLINE_LINMATH std::string Extension:: __repr__() const { - std::ostringstream out; - out << "LVecBase4" << FLOATTOKEN << "(" - << MAYBE_ZERO(_this->_v(0)) << ", " - << MAYBE_ZERO(_this->_v(1)) << ", " - << MAYBE_ZERO(_this->_v(2)) << ", " - << MAYBE_ZERO(_this->_v(3)) << ")"; - return out.str(); + char buf[160] = "LVecBase4"; + char *p = buf + strlen(buf); + *(p++) = FLOATTOKEN; + *(p++) = '('; + FLOATTYPE_REPR(_this->_v(0), p); + p += strlen(p); + *(p++) = ','; + *(p++) = ' '; + FLOATTYPE_REPR(_this->_v(1), p); + p += strlen(p); + *(p++) = ','; + *(p++) = ' '; + FLOATTYPE_REPR(_this->_v(2), p); + p += strlen(p); + *(p++) = ','; + *(p++) = ' '; + FLOATTYPE_REPR(_this->_v(3), p); + p += strlen(p); + *(p++) = ')'; + *p = '\0'; + return std::string(buf, p - buf); } /** diff --git a/panda/src/linmath/lvector2_ext_src.I b/panda/src/linmath/lvector2_ext_src.I index 0d9aaa0258..2774b0c186 100644 --- a/panda/src/linmath/lvector2_ext_src.I +++ b/panda/src/linmath/lvector2_ext_src.I @@ -16,11 +16,19 @@ */ INLINE_LINMATH std::string Extension:: __repr__() const { - std::ostringstream out; - out << "LVector2" << FLOATTOKEN << "(" - << MAYBE_ZERO(_this->_v(0)) << ", " - << MAYBE_ZERO(_this->_v(1)) << ")"; - return out.str(); + char buf[96] = "LVector2"; + char *p = buf + strlen(buf); + *(p++) = FLOATTOKEN; + *(p++) = '('; + FLOATTYPE_REPR(_this->_v(0), p); + p += strlen(p); + *(p++) = ','; + *(p++) = ' '; + FLOATTYPE_REPR(_this->_v(1), p); + p += strlen(p); + *(p++) = ')'; + *p = '\0'; + return std::string(buf, p - buf); } /** diff --git a/panda/src/linmath/lvector3_ext_src.I b/panda/src/linmath/lvector3_ext_src.I index ee620ba30a..2a0413cfcb 100644 --- a/panda/src/linmath/lvector3_ext_src.I +++ b/panda/src/linmath/lvector3_ext_src.I @@ -16,12 +16,23 @@ */ INLINE_LINMATH std::string Extension:: __repr__() const { - std::ostringstream out; - out << "LVector3" << FLOATTOKEN << "(" - << MAYBE_ZERO(_this->_v(0)) << ", " - << MAYBE_ZERO(_this->_v(1)) << ", " - << MAYBE_ZERO(_this->_v(2)) << ")"; - return out.str(); + char buf[128] = "LVector3"; + char *p = buf + strlen(buf); + *(p++) = FLOATTOKEN; + *(p++) = '('; + FLOATTYPE_REPR(_this->_v(0), p); + p += strlen(p); + *(p++) = ','; + *(p++) = ' '; + FLOATTYPE_REPR(_this->_v(1), p); + p += strlen(p); + *(p++) = ','; + *(p++) = ' '; + FLOATTYPE_REPR(_this->_v(2), p); + p += strlen(p); + *(p++) = ')'; + *p = '\0'; + return std::string(buf, p - buf); } /** diff --git a/panda/src/linmath/lvector4_ext_src.I b/panda/src/linmath/lvector4_ext_src.I index 6d4f7743b6..ec5765fc95 100644 --- a/panda/src/linmath/lvector4_ext_src.I +++ b/panda/src/linmath/lvector4_ext_src.I @@ -16,13 +16,27 @@ */ INLINE_LINMATH std::string Extension:: __repr__() const { - std::ostringstream out; - out << "LVector4" << FLOATTOKEN << "(" - << MAYBE_ZERO(_this->_v(0)) << ", " - << MAYBE_ZERO(_this->_v(1)) << ", " - << MAYBE_ZERO(_this->_v(2)) << ", " - << MAYBE_ZERO(_this->_v(3)) << ")"; - return out.str(); + char buf[160] = "LVector4"; + char *p = buf + strlen(buf); + *(p++) = FLOATTOKEN; + *(p++) = '('; + FLOATTYPE_REPR(_this->_v(0), p); + p += strlen(p); + *(p++) = ','; + *(p++) = ' '; + FLOATTYPE_REPR(_this->_v(1), p); + p += strlen(p); + *(p++) = ','; + *(p++) = ' '; + FLOATTYPE_REPR(_this->_v(2), p); + p += strlen(p); + *(p++) = ','; + *(p++) = ' '; + FLOATTYPE_REPR(_this->_v(3), p); + p += strlen(p); + *(p++) = ')'; + *p = '\0'; + return std::string(buf, p - buf); } /** diff --git a/tests/linmath/test_lvector2.py b/tests/linmath/test_lvector2.py index 50d1e2e393..fddbdb5328 100644 --- a/tests/linmath/test_lvector2.py +++ b/tests/linmath/test_lvector2.py @@ -142,3 +142,14 @@ def test_vec2_floordiv(type): v = type(i) v //= -j assert v.x == i // -j + + +def test_vec2_repr(): + assert repr(Vec2F(0.1, 0.2)) == "LVector2f(0.1, 0.2)" + assert repr(Vec2F(0.3, 0.4)) == "LVector2f(0.3, 0.4)" + assert repr(Vec2F(-0.9999999403953552, 1.00000001)) == "LVector2f(-0.99999994, 1)" + assert repr(Vec2F(0.00000001, 0.0)) == "LVector2f(1e-8, 0)" + assert repr(Vec2D(0.1, 0.2)) == "LVector2d(0.1, 0.2)" + assert repr(Vec2D(0.3, 0.4)) == "LVector2d(0.3, 0.4)" + assert repr(Vec2D(-0.9999999403953552, 1.00000001)) == "LVector2d(-0.9999999403953552, 1.00000001)" + assert repr(Vec2D(0.00000001, 0.0)) == "LVector2d(1e-8, 0)" diff --git a/tests/linmath/test_lvector3.py b/tests/linmath/test_lvector3.py index 03eafaa014..62d541f854 100644 --- a/tests/linmath/test_lvector3.py +++ b/tests/linmath/test_lvector3.py @@ -127,3 +127,16 @@ def test_vec3_floordiv(type): v = type(i) v //= -j assert v.x == i // -j + + +def test_vec3_repr(): + assert repr(Vec3F(0.1, 0.2, 0.3)) == "LVector3f(0.1, 0.2, 0.3)" + assert repr(Vec3F(-0.9999999403953552, 1.00000001, 1)) == "LVector3f(-0.99999994, 1, 1)" + assert repr(Vec3F(-9.451235e29, 9.451234e-19, 1e-11)) == "LVector3f(-9.451235e29, 9.451234e-19, 1e-11)" + assert repr(Vec3F(0.001, 0.0001, 0.00001)) == "LVector3f(0.001, 0.0001, 0.00001)" + assert repr(Vec3F(-0.001, -0.0001, -0.00001)) == "LVector3f(-0.001, -0.0001, -0.00001)" + assert repr(Vec3D(0.1, 0.2, 0.3)) == "LVector3d(0.1, 0.2, 0.3)" + assert repr(Vec3D(-0.9999999403953552, 1.00000001, 1)) == "LVector3d(-0.9999999403953552, 1.00000001, 1)" + assert repr(Vec3D(-9.451235e29, 9.451234e-19, 1e-11)) == "LVector3d(-9.451235e29, 9.451234e-19, 1e-11)" + assert repr(Vec3D(0.001, 0.0001, 0.00001)) == "LVector3d(0.001, 0.0001, 0.00001)" + assert repr(Vec3D(-0.001, -0.0001, -0.00001)) == "LVector3d(-0.001, -0.0001, -0.00001)" diff --git a/tests/linmath/test_lvector4.py b/tests/linmath/test_lvector4.py index a7ead81690..2bbe440b2c 100644 --- a/tests/linmath/test_lvector4.py +++ b/tests/linmath/test_lvector4.py @@ -143,3 +143,10 @@ def test_vec4_floordiv(type): v = type(i) v //= -j assert v.x == i // -j + + +def test_vec4_repr(): + assert repr(Vec4F(0.1, 0.2, 0.3, 0.4)) == "LVector4f(0.1, 0.2, 0.3, 0.4)" + assert repr(Vec4F(-0.9999999403953552, 1.000001, 1e-8, 0.0)) == "LVector4f(-0.99999994, 1.000001, 1e-8, 0)" + assert repr(Vec4D(0.1, 0.2, 0.3, 0.4)) == "LVector4d(0.1, 0.2, 0.3, 0.4)" + assert repr(Vec4D(-0.9999999403953552, 1.00000001, 1e-8, 0.0)) == "LVector4d(-0.9999999403953552, 1.00000001, 1e-8, 0)" From 057c3f547614f2c648455126ded49e02f9184270 Mon Sep 17 00:00:00 2001 From: rdb Date: Wed, 7 Aug 2024 22:26:33 +0200 Subject: [PATCH 9/9] Update BACKERS.md [skip ci] --- BACKERS.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BACKERS.md b/BACKERS.md index dab94be04a..a3eb53177b 100644 --- a/BACKERS.md +++ b/BACKERS.md @@ -4,7 +4,7 @@ This is a list of all the people who are contributing financially to Panda3D. I ## Bronze Sponsors -[ChangeCrab](https://changecrab.com/) ![Bronze Sponsors](https://opencollective.com/panda3d/tiers/bronze-sponsor.svg?avatarHeight=48&width=600) +[Route4Me](https://route4me.com/) * [Daniel Stokes](https://opencollective.com/daniel-stokes) * [David Rose](https://opencollective.com/david-rose)