diff --git a/direct/src/dist/_dist_hooks.py b/direct/src/dist/_dist_hooks.py new file mode 100644 index 0000000000..a611c35dbc --- /dev/null +++ b/direct/src/dist/_dist_hooks.py @@ -0,0 +1,16 @@ +# This module should not import Panda3D modules globally as it contains hooks +# that may be invoked by setuptools even when Panda3D is not used. If the +# Panda3D installation is broken, it should not affect other applications. + +__all__ = ('finalize_distribution_options', ) + + +def finalize_distribution_options(dist): + """Entry point for compatibility with setuptools>=61, see #1394.""" + + options = dist.get_option_dict('build_apps') + if options.get('gui_apps') or options.get('console_apps'): + # Make sure this is set to avoid auto-discovery taking place. + if getattr(dist.metadata, 'py_modules', None) is None and \ + getattr(dist.metadata, 'packages', None) is None: + dist.py_modules = [] diff --git a/direct/src/dist/commands.py b/direct/src/dist/commands.py index 2ee6b12890..505e57697b 100644 --- a/direct/src/dist/commands.py +++ b/direct/src/dist/commands.py @@ -23,6 +23,7 @@ from . import FreezeTool from . import pefile from . import installers from .icon import Icon +from ._dist_hooks import finalize_distribution_options import panda3d.core as p3d @@ -1773,14 +1774,3 @@ class bdist_apps(setuptools.Command): continue self.installer_functions[installer](self, basename, build_dir) - - -def finalize_distribution_options(dist): - """Entry point for compatibility with setuptools>=61, see #1394.""" - - options = dist.get_option_dict('build_apps') - if options.get('gui_apps') or options.get('console_apps'): - # Make sure this is set to avoid auto-discovery taking place. - if getattr(dist.metadata, 'py_modules', None) is None and \ - getattr(dist.metadata, 'packages', None) is None: - dist.py_modules = [] diff --git a/direct/src/interval/LerpInterval.py b/direct/src/interval/LerpInterval.py index ae218fe0f2..e303b3a5d1 100644 --- a/direct/src/interval/LerpInterval.py +++ b/direct/src/interval/LerpInterval.py @@ -841,8 +841,12 @@ class LerpFunctionInterval(Interval.Interval): self.extraArgs = extraArgs # Generate unique name if necessary if name is None: + if hasattr(function, '__name__'): + name = function.__name__ + else: + name = '<' + function.__class__.__name__ + '>' name = ('LerpFunctionInterval-%s-%d' % - (function.__name__, + (name, LerpFunctionInterval.lerpFunctionIntervalNum)) LerpFunctionInterval.lerpFunctionIntervalNum += 1 else: diff --git a/makepanda/makepanda.py b/makepanda/makepanda.py index 4a06177670..1cecc7dbe8 100755 --- a/makepanda/makepanda.py +++ b/makepanda/makepanda.py @@ -3016,7 +3016,7 @@ build_apps = direct.dist.commands:build_apps bdist_apps = direct.dist.commands:bdist_apps [setuptools.finalize_distribution_options] -build_apps = direct.dist.commands:finalize_distribution_options +build_apps = direct.dist._dist_hooks:finalize_distribution_options """ if not PkgSkip("DIRECT"): diff --git a/makepanda/makewheel.py b/makepanda/makewheel.py index 5879b2546a..3b2f332260 100644 --- a/makepanda/makewheel.py +++ b/makepanda/makewheel.py @@ -878,7 +878,7 @@ if __debug__: entry_points += 'build_apps = direct.dist.commands:build_apps\n' entry_points += 'bdist_apps = direct.dist.commands:bdist_apps\n' entry_points += '[setuptools.finalize_distribution_options]\n' - entry_points += 'build_apps = direct.dist.commands:finalize_distribution_options\n' + entry_points += 'build_apps = direct.dist._dist_hooks:finalize_distribution_options\n' whl.write_file_data('panda3d_tools/__init__.py', PANDA3D_TOOLS_INIT.format(tools_init)) diff --git a/panda/src/audiotraits/openalAudioSound.cxx b/panda/src/audiotraits/openalAudioSound.cxx index 43036c73b0..f1bf7ef2ed 100644 --- a/panda/src/audiotraits/openalAudioSound.cxx +++ b/panda/src/audiotraits/openalAudioSound.cxx @@ -180,9 +180,20 @@ play() { if (_sd->_sample) { push_fresh_buffers(); + // The macOS implementation of alSourcePlay resets the offset, so we call + // it before and avoid calling restart_stalled_audio() afterwards (#1607) +#ifdef HAVE_OPENAL_FRAMEWORK + ALenum status; + alGetSourcei(_source, AL_SOURCE_STATE, &status); + if (status != AL_PLAYING) { + alSourcePlay(_source); + } +#endif alSourcef(_source, AL_SEC_OFFSET, _start_time); _stream_queued[0]._time_offset = _start_time; +#ifndef HAVE_OPENAL_FRAMEWORK restart_stalled_audio(); +#endif } else { audio_debug("Play: stream tell = " << _sd->_stream->tell() << " seeking " << _start_time); if (_sd->_stream->tell() != _start_time) { diff --git a/panda/src/pgui/pgEntry.I b/panda/src/pgui/pgEntry.I index e758a7ff8c..61262d87aa 100644 --- a/panda/src/pgui/pgEntry.I +++ b/panda/src/pgui/pgEntry.I @@ -134,7 +134,6 @@ get_cursor_position() const { /** * Returns the node position x of the cursor */ - INLINE PN_stdfloat PGEntry:: get_cursor_X() const { LightReMutexHolder holder(_lock); @@ -144,14 +143,12 @@ get_cursor_X() const { /** * Returns the node position y of the cursor */ - INLINE PN_stdfloat PGEntry:: get_cursor_Y() const { LightReMutexHolder holder(_lock); - return _cursor_def.get_y(); + return _cursor_def.get_z(); } - /** * Sets the maximum number of characters that may be typed into the entry. * This is a limit on the number of characters, as opposed to the width of the diff --git a/panda/src/text/dynamicTextFont.cxx b/panda/src/text/dynamicTextFont.cxx index 347841a92f..4d933619b5 100644 --- a/panda/src/text/dynamicTextFont.cxx +++ b/panda/src/text/dynamicTextFont.cxx @@ -621,6 +621,9 @@ make_glyph(int character, FT_Face face, int glyph_index) { render_distance_field(image, outline, bounds.xMin, bounds.yMin); glyph = slot_glyph(character, int_x_size, int_y_size, advance); + if (glyph == nullptr) { + return nullptr; + } if (!_needs_image_processing) { copy_pnmimage_to_texture(image, glyph); } else { @@ -633,6 +636,9 @@ make_glyph(int character, FT_Face face, int glyph_index) { // other processing before it goes to the texture, we can just copy it // directly into the texture. glyph = slot_glyph(character, bitmap.width, bitmap.rows, advance); + if (glyph == nullptr) { + return nullptr; + } copy_bitmap_to_texture(bitmap, glyph); } else { @@ -660,6 +666,9 @@ make_glyph(int character, FT_Face face, int glyph_index) { tex_x_size += outline * 2; tex_y_size += outline * 2; glyph = slot_glyph(character, int_x_size, int_y_size, advance); + if (glyph == nullptr) { + return nullptr; + } if (outline != 0) { // Pad the glyph image to make room for the outline. @@ -940,10 +949,7 @@ slot_glyph(int character, int x_size, int y_size, PN_stdfloat advance) { if (page->is_empty()) { // If we couldn't even put it on an empty page, we're screwed. - text_cat.error() - << "Glyph of size " << x_size << " by " << y_size - << " pixels won't fit on an empty page.\n"; - return nullptr; + goto does_not_fit; } pi = (pi + 1) % _pages.size(); @@ -954,15 +960,27 @@ slot_glyph(int character, int x_size, int y_size, PN_stdfloat advance) { if (garbage_collect() != 0) { // Yes, we just freed up some space. Try once more, recursively. return slot_glyph(character, x_size, y_size, advance); + } - } else { - // No good; all recorded glyphs are actually in use. We need to make a - // new page. + // No good; all recorded glyphs are actually in use. We need to make a new + // page. + { _preferred_page = _pages.size(); PT(DynamicTextPage) page = new DynamicTextPage(this, _preferred_page); _pages.push_back(page); - return page->slot_glyph(character, x_size, y_size, _texture_margin, advance); + + DynamicTextGlyph *glyph = page->slot_glyph(character, x_size, y_size, _texture_margin, advance); + if (glyph != nullptr) { + return glyph; + } } + +does_not_fit: + // If you get this error, increase text-page-size in Config.prc. + text_cat.error() + << "Glyph of size " << x_size << " by " << y_size + << " pixels won't fit on an empty page.\n"; + return nullptr; } /** diff --git a/panda/src/text/textNode.I b/panda/src/text/textNode.I index 188fb009a4..4ba8ead2ac 100644 --- a/panda/src/text/textNode.I +++ b/panda/src/text/textNode.I @@ -756,7 +756,9 @@ clear_wordwrap() { } /** - * + * Sets the color of the text. Note that this will modulate the color of all + * components of the text, including the shadow and outline. If you wish to + * only set the foreground color, see DynamicTextFont::set_fg(). */ INLINE void TextNode:: set_text_color(const LColor &text_color) { @@ -766,7 +768,9 @@ set_text_color(const LColor &text_color) { } /** - * + * Sets the color of the text. Note that this will modulate the color of all + * components of the text, including the shadow and outline. If you wish to + * only set the foreground color, see DynamicTextFont::set_fg(). */ INLINE void TextNode:: set_text_color(PN_stdfloat r, PN_stdfloat g, PN_stdfloat b, PN_stdfloat a) { diff --git a/panda/src/text/textProperties.I b/panda/src/text/textProperties.I index d56c354d46..c31cd883de 100644 --- a/panda/src/text/textProperties.I +++ b/panda/src/text/textProperties.I @@ -419,7 +419,9 @@ get_preserve_trailing_whitespace() const { } /** - * + * Sets the color of the text. Note that this will modulate the color of all + * components of the text, including the shadow and outline. If you wish to + * only set the foreground color, see DynamicTextFont::set_fg(). */ INLINE void TextProperties:: set_text_color(PN_stdfloat r, PN_stdfloat g, PN_stdfloat b, PN_stdfloat a) { @@ -427,7 +429,9 @@ set_text_color(PN_stdfloat r, PN_stdfloat g, PN_stdfloat b, PN_stdfloat a) { } /** - * + * Sets the color of the text. Note that this will modulate the color of all + * components of the text, including the shadow and outline. If you wish to + * only set the foreground color, see DynamicTextFont::set_fg(). */ INLINE void TextProperties:: set_text_color(const LColor &text_color) { @@ -448,7 +452,7 @@ clear_text_color() { } /** - * + * Returns true if a text color was specified with set_text_color(). */ INLINE bool TextProperties:: has_text_color() const { diff --git a/pandatool/src/palettizer/txaLine.cxx b/pandatool/src/palettizer/txaLine.cxx index d704fdb045..6d04b5daf1 100644 --- a/pandatool/src/palettizer/txaLine.cxx +++ b/pandatool/src/palettizer/txaLine.cxx @@ -495,7 +495,7 @@ match_texture(TextureImage *texture) const { case KW_mipmap: request._minfilter = EggTexture::FT_linear_mipmap_linear; - request._magfilter = EggTexture::FT_linear_mipmap_linear; + request._magfilter = EggTexture::FT_linear; break; case KW_anisotropic: