pyglet 2.1.dev2__py3-none-any.whl → 2.1.dev4__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pyglet/__init__.py +355 -231
- pyglet/__init__.pyi +29 -6
- pyglet/app/__init__.py +6 -8
- pyglet/app/base.py +86 -88
- pyglet/app/win32.py +1 -1
- pyglet/clock.py +93 -117
- pyglet/display/__init__.py +26 -29
- pyglet/display/base.py +44 -100
- pyglet/display/cocoa.py +4 -4
- pyglet/display/headless.py +1 -1
- pyglet/display/win32.py +22 -2
- pyglet/display/xlib.py +13 -9
- pyglet/event.py +119 -105
- pyglet/experimental/hidraw.py +28 -87
- pyglet/experimental/particles.py +423 -0
- pyglet/extlibs/earcut.py +714 -0
- pyglet/font/__init__.py +56 -45
- pyglet/font/base.py +147 -133
- pyglet/font/directwrite.py +658 -600
- pyglet/font/fontconfig.py +109 -91
- pyglet/font/freetype.py +102 -71
- pyglet/font/freetype_lib.py +346 -306
- pyglet/font/quartz.py +42 -36
- pyglet/font/ttf.py +238 -239
- pyglet/font/user.py +166 -57
- pyglet/font/win32.py +32 -36
- pyglet/gl/__init__.py +23 -16
- pyglet/gl/agl.py +1 -1
- pyglet/gl/base.py +184 -216
- pyglet/gl/cocoa.py +69 -61
- pyglet/gl/gl.py +5 -2
- pyglet/gl/gl_compat.py +18 -3
- pyglet/gl/gl_info.py +47 -64
- pyglet/gl/glx.py +10 -19
- pyglet/gl/glx_info.py +38 -19
- pyglet/gl/glxext_arb.py +6 -10
- pyglet/gl/glxext_mesa.py +1 -1
- pyglet/gl/glxext_nv.py +4 -8
- pyglet/gl/headless.py +54 -40
- pyglet/gl/lib.py +21 -17
- pyglet/gl/lib_agl.py +10 -4
- pyglet/gl/lib_glx.py +16 -8
- pyglet/gl/lib_wgl.py +17 -11
- pyglet/gl/wgl.py +175 -199
- pyglet/gl/wgl_info.py +10 -12
- pyglet/gl/win32.py +77 -56
- pyglet/gl/xlib.py +63 -32
- pyglet/graphics/__init__.py +255 -161
- pyglet/graphics/allocation.py +61 -81
- pyglet/graphics/instance.py +77 -0
- pyglet/graphics/shader.py +732 -445
- pyglet/graphics/vertexarray.py +20 -11
- pyglet/graphics/vertexbuffer.py +106 -78
- pyglet/graphics/vertexdomain.py +556 -196
- pyglet/gui/__init__.py +1 -0
- pyglet/gui/frame.py +68 -38
- pyglet/gui/ninepatch.py +269 -0
- pyglet/gui/widgets.py +137 -129
- pyglet/image/__init__.py +148 -91
- pyglet/image/animation.py +38 -77
- pyglet/image/atlas.py +74 -110
- pyglet/image/buffer.py +91 -50
- pyglet/image/codecs/__init__.py +9 -8
- pyglet/input/__init__.py +27 -38
- pyglet/input/base.py +379 -427
- pyglet/input/controller.py +33 -37
- pyglet/input/linux/evdev.py +12 -64
- pyglet/input/win32/__init__.py +4 -4
- pyglet/input/win32/wintab.py +8 -10
- pyglet/lib.py +53 -55
- pyglet/libs/__init__.py +18 -0
- pyglet/libs/darwin/cocoapy/runtime.py +262 -31
- pyglet/libs/darwin/coreaudio.py +86 -19
- pyglet/libs/darwin/quartzkey.py +32 -13
- pyglet/libs/ioctl.py +129 -0
- pyglet/libs/win32/__init__.py +1 -1
- pyglet/libs/win32/dinput.py +12 -10
- pyglet/libs/x11/xlib.py +1480 -947
- pyglet/math.py +973 -460
- pyglet/media/__init__.py +22 -17
- pyglet/media/codecs/__init__.py +4 -1
- pyglet/media/player.py +34 -67
- pyglet/media/player_worker_thread.py +31 -21
- pyglet/media/synthesis.py +105 -81
- pyglet/model/__init__.py +106 -58
- pyglet/model/codecs/__init__.py +12 -3
- pyglet/resource.py +295 -363
- pyglet/shapes.py +898 -499
- pyglet/sprite.py +255 -260
- pyglet/text/__init__.py +237 -244
- pyglet/text/caret.py +49 -96
- pyglet/text/document.py +220 -214
- pyglet/text/formats/__init__.py +1 -4
- pyglet/text/formats/attributed.py +32 -29
- pyglet/text/formats/html.py +166 -166
- pyglet/text/formats/plaintext.py +10 -4
- pyglet/text/formats/structured.py +99 -87
- pyglet/text/layout/__init__.py +28 -16
- pyglet/text/layout/base.py +415 -407
- pyglet/text/layout/incremental.py +189 -258
- pyglet/text/layout/scrolling.py +77 -60
- pyglet/text/runlist.py +91 -84
- pyglet/window/__init__.py +461 -580
- pyglet/window/cocoa/__init__.py +66 -68
- pyglet/window/cocoa/pyglet_delegate.py +49 -36
- pyglet/window/cocoa/pyglet_textview.py +89 -69
- pyglet/window/cocoa/pyglet_view.py +75 -55
- pyglet/window/cocoa/pyglet_window.py +31 -18
- pyglet/window/cocoa/systemcursor.py +4 -2
- pyglet/window/event.py +57 -52
- pyglet/window/headless/__init__.py +39 -31
- pyglet/window/key.py +20 -33
- pyglet/window/mouse.py +48 -34
- pyglet/window/win32/__init__.py +375 -350
- pyglet/window/xlib/__init__.py +257 -221
- {pyglet-2.1.dev2.dist-info → pyglet-2.1.dev4.dist-info}/METADATA +7 -3
- pyglet-2.1.dev4.dist-info/RECORD +219 -0
- pyglet-2.1.dev2.dist-info/RECORD +0 -214
- {pyglet-2.1.dev2.dist-info → pyglet-2.1.dev4.dist-info}/LICENSE +0 -0
- {pyglet-2.1.dev2.dist-info → pyglet-2.1.dev4.dist-info}/WHEEL +0 -0
pyglet/__init__.py
CHANGED
|
@@ -2,25 +2,31 @@
|
|
|
2
2
|
|
|
3
3
|
More information is available at http://www.pyglet.org
|
|
4
4
|
"""
|
|
5
|
+
from __future__ import annotations
|
|
5
6
|
|
|
6
7
|
import os
|
|
7
8
|
import sys
|
|
9
|
+
from collections.abc import ItemsView, Sequence
|
|
10
|
+
from dataclasses import dataclass
|
|
11
|
+
from typing import TYPE_CHECKING
|
|
8
12
|
|
|
9
|
-
|
|
13
|
+
if TYPE_CHECKING:
|
|
14
|
+
from types import FrameType
|
|
15
|
+
from typing import Any, Callable, ItemsView, Sized
|
|
10
16
|
|
|
11
17
|
#: The release version
|
|
12
|
-
version = '2.1.
|
|
18
|
+
version = '2.1.dev4'
|
|
13
19
|
__version__ = version
|
|
14
20
|
|
|
15
21
|
MIN_PYTHON_VERSION = 3, 8
|
|
16
|
-
MIN_PYTHON_VERSION_STR =
|
|
22
|
+
MIN_PYTHON_VERSION_STR = ".".join([str(v) for v in MIN_PYTHON_VERSION])
|
|
17
23
|
|
|
18
24
|
if sys.version_info < MIN_PYTHON_VERSION:
|
|
19
|
-
|
|
25
|
+
msg = f"pyglet {version} requires Python {MIN_PYTHON_VERSION_STR} or newer."
|
|
26
|
+
raise Exception(msg)
|
|
20
27
|
|
|
21
|
-
if
|
|
22
|
-
|
|
23
|
-
_is_pyglet_doc_run = hasattr(sys, "is_pyglet_doc_run") and sys.is_pyglet_doc_run
|
|
28
|
+
if "sphinx" in sys.modules:
|
|
29
|
+
sys.is_pyglet_doc_run = True
|
|
24
30
|
|
|
25
31
|
# pyglet platform treats *BSD systems as Linux
|
|
26
32
|
compat_platform = sys.platform
|
|
@@ -28,192 +34,308 @@ if "bsd" in compat_platform:
|
|
|
28
34
|
compat_platform = "linux-compat"
|
|
29
35
|
|
|
30
36
|
_enable_optimisations = not __debug__
|
|
31
|
-
if getattr(sys,
|
|
37
|
+
if getattr(sys, "frozen", None):
|
|
32
38
|
_enable_optimisations = True
|
|
33
39
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
#:
|
|
39
|
-
#: import pyglet
|
|
40
|
-
#: pyglet.options['debug_gl'] = False
|
|
41
|
-
#:
|
|
42
|
-
#: The default options can be overridden from the OS environment. The
|
|
43
|
-
#: corresponding environment variable for each option key is prefaced by
|
|
44
|
-
#: ``PYGLET_``. For example, in Bash you can set the ``debug_gl`` option with::
|
|
45
|
-
#:
|
|
46
|
-
#: PYGLET_DEBUG_GL=True; export PYGLET_DEBUG_GL
|
|
47
|
-
#:
|
|
48
|
-
#: For options requiring a tuple of values, separate each value with a comma.
|
|
49
|
-
#:
|
|
50
|
-
#: The non-development options are:
|
|
51
|
-
#:
|
|
52
|
-
#: audio
|
|
53
|
-
#: A :py:class:`~typing.Sequence` of valid audio modules names. They will
|
|
54
|
-
#: be tried from first to last until either a driver loads or no entries
|
|
55
|
-
#: remain. See :ref:`guide-audio-driver-order` for more information.
|
|
56
|
-
#:
|
|
57
|
-
#: Valid driver names are:
|
|
58
|
-
#:
|
|
59
|
-
#: * ``'xaudio2'``, the Windows Xaudio2 audio module (Windows only)
|
|
60
|
-
#: * ``'directsound'``, the Windows DirectSound audio module (Windows only)
|
|
61
|
-
#: * ``'pulse'``, the :ref:`guide-audio-driver-pulseaudio` module
|
|
62
|
-
#: (Linux only, otherwise nearly ubiquitous. Limited features; use
|
|
63
|
-
#: ``'openal'`` for more.)
|
|
64
|
-
#: * ``'openal'``, the :ref:`guide-audio-driver-openal` audio module
|
|
65
|
-
#: (A library may need to be installed on Windows and Linux)
|
|
66
|
-
#: * ``'silent'``, no audio
|
|
67
|
-
#:
|
|
68
|
-
#: debug_lib
|
|
69
|
-
#: If True, prints the path of each dynamic library loaded.
|
|
70
|
-
#: debug_gl
|
|
71
|
-
#: If True, all calls to OpenGL functions are checked afterwards for
|
|
72
|
-
#: errors using ``glGetError``. This will severely impact performance,
|
|
73
|
-
#: but provides useful exceptions at the point of failure. By default,
|
|
74
|
-
#: this option is enabled if ``__debug__`` is (i.e., if Python was not run
|
|
75
|
-
#: with the -O option). It is disabled by default when pyglet is "frozen"
|
|
76
|
-
#: within a py2exe or py2app library archive.
|
|
77
|
-
#: shadow_window
|
|
78
|
-
#: By default, pyglet creates a hidden window with a GL context when
|
|
79
|
-
#: pyglet.gl is imported. This allows resources to be loaded before
|
|
80
|
-
#: the application window is created, and permits GL objects to be
|
|
81
|
-
#: shared between windows even after they've been closed. You can
|
|
82
|
-
#: disable the creation of the shadow window by setting this option to
|
|
83
|
-
#: False.
|
|
84
|
-
#:
|
|
85
|
-
#: Some OpenGL driver implementations may not support shared OpenGL
|
|
86
|
-
#: contexts and may require disabling the shadow window (and all resources
|
|
87
|
-
#: must be loaded after the window using them was created). Recommended
|
|
88
|
-
#: for advanced developers only.
|
|
89
|
-
#:
|
|
90
|
-
#: .. versionadded:: 1.1
|
|
91
|
-
#: vsync
|
|
92
|
-
#: If set, the `pyglet.window.Window.vsync` property is ignored, and
|
|
93
|
-
#: this option overrides it (to either force vsync on or off). If unset,
|
|
94
|
-
#: or set to None, the `pyglet.window.Window.vsync` property behaves
|
|
95
|
-
#: as documented.
|
|
96
|
-
#: search_local_libs
|
|
97
|
-
#: If False, pyglet won't try to search for libraries in the script
|
|
98
|
-
#: directory and its `lib` subdirectory. This is useful to load a local
|
|
99
|
-
#: library instead of the system installed version. This option is set
|
|
100
|
-
#: to True by default.
|
|
101
|
-
#:
|
|
102
|
-
#: .. versionadded:: 1.2
|
|
103
|
-
#:
|
|
104
|
-
options = {
|
|
105
|
-
'audio': ('xaudio2', 'directsound', 'openal', 'pulse', 'silent'),
|
|
106
|
-
'debug_font': False,
|
|
107
|
-
'debug_gl': not _enable_optimisations,
|
|
108
|
-
'debug_gl_trace': False,
|
|
109
|
-
'debug_gl_trace_args': False,
|
|
110
|
-
'debug_gl_shaders': False,
|
|
111
|
-
'debug_graphics_batch': False,
|
|
112
|
-
'debug_lib': False,
|
|
113
|
-
'debug_media': False,
|
|
114
|
-
'debug_texture': False,
|
|
115
|
-
'debug_trace': False,
|
|
116
|
-
'debug_trace_args': False,
|
|
117
|
-
'debug_trace_depth': 1,
|
|
118
|
-
'debug_trace_flush': True,
|
|
119
|
-
'debug_win32': False,
|
|
120
|
-
'debug_input': False,
|
|
121
|
-
'debug_x11': False,
|
|
122
|
-
'shadow_window': True,
|
|
123
|
-
'vsync': None,
|
|
124
|
-
'search_local_libs': True,
|
|
125
|
-
'win32_gdi_font': False,
|
|
126
|
-
'scale_with_dpi': False,
|
|
127
|
-
'headless': False,
|
|
128
|
-
'headless_device': 0,
|
|
129
|
-
'win32_disable_shaping': False,
|
|
130
|
-
'dw_legacy_naming': False,
|
|
131
|
-
'win32_disable_xinput': False,
|
|
132
|
-
'com_mta': False,
|
|
133
|
-
'osx_alt_loop': False
|
|
40
|
+
|
|
41
|
+
_SPECIAL_OPTION_VALIDATORS = {
|
|
42
|
+
"audio": lambda x: isinstance(x, Sequence),
|
|
43
|
+
"vsync": lambda x: x is None or isinstance(x, bool),
|
|
134
44
|
}
|
|
135
45
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
'debug_gl': bool,
|
|
140
|
-
'debug_gl_trace': bool,
|
|
141
|
-
'debug_gl_trace_args': bool,
|
|
142
|
-
'debug_gl_shaders': bool,
|
|
143
|
-
'debug_graphics_batch': bool,
|
|
144
|
-
'debug_lib': bool,
|
|
145
|
-
'debug_media': bool,
|
|
146
|
-
'debug_texture': bool,
|
|
147
|
-
'debug_trace': bool,
|
|
148
|
-
'debug_trace_args': bool,
|
|
149
|
-
'debug_trace_depth': int,
|
|
150
|
-
'debug_trace_flush': bool,
|
|
151
|
-
'debug_win32': bool,
|
|
152
|
-
'debug_input': bool,
|
|
153
|
-
'debug_x11': bool,
|
|
154
|
-
'shadow_window': bool,
|
|
155
|
-
'vsync': bool,
|
|
156
|
-
'search_local_libs': bool,
|
|
157
|
-
'win32_gdi_font': bool,
|
|
158
|
-
'scale_with_dpi': bool,
|
|
159
|
-
'headless': bool,
|
|
160
|
-
'headless_device': int,
|
|
161
|
-
'win32_disable_shaping': bool,
|
|
162
|
-
'dw_legacy_naming': bool,
|
|
163
|
-
'win32_disable_xinput': bool,
|
|
164
|
-
'com_mta': bool,
|
|
165
|
-
'osx_alt_loop': bool,
|
|
46
|
+
_OPTION_TYPE_VALIDATORS = {
|
|
47
|
+
"bool": lambda x: isinstance(x, bool),
|
|
48
|
+
"int": lambda x: isinstance(x, int),
|
|
166
49
|
}
|
|
167
50
|
|
|
51
|
+
@dataclass
|
|
52
|
+
class Options:
|
|
53
|
+
"""Dataclass for global pyglet options."""
|
|
54
|
+
|
|
55
|
+
audio: Sequence[str] = ("xaudio2", "directsound", "openal", "pulse", "silent")
|
|
56
|
+
"""A :py:class:`~typing.Sequence` of valid audio modules names. They will
|
|
57
|
+
be tried from first to last until either a driver loads or no entries
|
|
58
|
+
remain. See :ref:`guide-audio-driver-order` for more information.
|
|
59
|
+
|
|
60
|
+
Valid driver names are:
|
|
61
|
+
|
|
62
|
+
* ``'xaudio2'``, the Windows Xaudio2 audio module (Windows only)
|
|
63
|
+
* ``'directsound'``, the Windows DirectSound audio module (Windows only)
|
|
64
|
+
* ``'pulse'``, the :ref:`guide-audio-driver-pulseaudio` module
|
|
65
|
+
(Linux only, otherwise nearly ubiquitous. Limited features; use
|
|
66
|
+
``'openal'`` for more.)
|
|
67
|
+
* ``'openal'``, the :ref:`guide-audio-driver-openal` audio module
|
|
68
|
+
(A library may need to be installed on Windows and Linux)
|
|
69
|
+
* ``'silent'``, no audio"""
|
|
70
|
+
|
|
71
|
+
debug_font: bool = False
|
|
72
|
+
"""If ``True``, will print more verbose information when :py:class:`~pyglet.font.base.Font`'s are loaded."""
|
|
73
|
+
|
|
74
|
+
debug_gl: bool = True
|
|
75
|
+
"""If ``True``, all calls to OpenGL functions are checked afterwards for
|
|
76
|
+
errors using ``glGetError``. This will severely impact performance,
|
|
77
|
+
but provides useful exceptions at the point of failure. By default,
|
|
78
|
+
this option is enabled if ``__debug__`` is enabled (i.e., if Python was not run
|
|
79
|
+
with the -O option). It is disabled by default when pyglet is "frozen", such as
|
|
80
|
+
within pyinstaller or nuitka."""
|
|
81
|
+
|
|
82
|
+
debug_gl_trace: bool = False
|
|
83
|
+
"""If ``True``, will print the names of OpenGL calls being executed. For example, ``glBlendFunc``"""
|
|
84
|
+
|
|
85
|
+
debug_gl_trace_args: bool = False
|
|
86
|
+
"""If ``True``, in addition to printing the names of OpenGL calls, it will also print the arguments passed
|
|
87
|
+
into those calls. For example, ``glBlendFunc(770, 771)``
|
|
88
|
+
|
|
89
|
+
.. note:: Requires ``debug_gl_trace`` to be enabled."""
|
|
90
|
+
|
|
91
|
+
debug_gl_shaders: bool = False
|
|
92
|
+
"""If ``True``, prints shader compilation information such as creation and deletion of shader's. Also includes
|
|
93
|
+
information on shader ID's, attributes, and uniforms."""
|
|
94
|
+
|
|
95
|
+
debug_graphics_batch: bool = False
|
|
96
|
+
"""If ``True``, prints batch information being drawn, including :py:class:`~pyglet.graphics.Group`'s, VertexDomains,
|
|
97
|
+
and :py:class:`~pyglet.image.Texture` information. This can be useful to see how many Group's are being
|
|
98
|
+
consolidated."""
|
|
99
|
+
|
|
100
|
+
debug_lib: bool = False
|
|
101
|
+
"""If ``True``, prints the path of each dynamic library loaded."""
|
|
102
|
+
|
|
103
|
+
debug_media: bool = False
|
|
104
|
+
"""If ``True``, prints more detailed media information for audio codecs and drivers. Will be very verbose."""
|
|
105
|
+
|
|
106
|
+
debug_texture: bool = False
|
|
107
|
+
"""If ``True``, prints information on :py:class:`~pyglet.image.Texture` size (in bytes) when they are allocated and
|
|
108
|
+
deleted."""
|
|
109
|
+
|
|
110
|
+
debug_trace: bool = False
|
|
111
|
+
debug_trace_args: bool = False
|
|
112
|
+
debug_trace_depth: int = 1
|
|
113
|
+
debug_trace_flush: bool = True
|
|
114
|
+
|
|
115
|
+
debug_win32: bool = False
|
|
116
|
+
"""If ``True``, prints error messages related to Windows library calls. Usually get's information from
|
|
117
|
+
``Kernel32.GetLastError``. This information is output to a file called ``debug_win32.log``."""
|
|
118
|
+
|
|
119
|
+
debug_input: bool = False
|
|
120
|
+
"""If ``True``, prints information on input devices such as controllers, tablets, and more."""
|
|
121
|
+
|
|
122
|
+
debug_x11: bool = False
|
|
123
|
+
"""If ``True``, prints information related to Linux X11 calls. This can potentially help narrow down driver or
|
|
124
|
+
operating system issues."""
|
|
125
|
+
|
|
126
|
+
shadow_window: bool = True
|
|
127
|
+
"""By default, pyglet creates a hidden window with a GL context when
|
|
128
|
+
pyglet.gl is imported. This allows resources to be loaded before
|
|
129
|
+
the application window is created, and permits GL objects to be
|
|
130
|
+
shared between windows even after they've been closed. You can
|
|
131
|
+
disable the creation of the shadow window by setting this option to
|
|
132
|
+
False.
|
|
133
|
+
|
|
134
|
+
Some OpenGL driver implementations may not support shared OpenGL
|
|
135
|
+
contexts and may require disabling the shadow window (and all resources
|
|
136
|
+
must be loaded after the window using them was created). Recommended
|
|
137
|
+
for advanced developers only.
|
|
138
|
+
|
|
139
|
+
.. versionadded:: 1.1
|
|
140
|
+
"""
|
|
141
|
+
|
|
142
|
+
vsync: bool | None = None
|
|
143
|
+
"""If set, the `pyglet.window.Window.vsync` property is ignored, and
|
|
144
|
+
this option overrides it (to either force vsync on or off). If unset,
|
|
145
|
+
or set to None, the `pyglet.window.Window.vsync` property behaves
|
|
146
|
+
as documented.
|
|
147
|
+
"""
|
|
148
|
+
|
|
149
|
+
xsync: bool = True
|
|
150
|
+
"""If ``True`` (the default), pyglet will attempt to synchronise the
|
|
151
|
+
drawing of double-buffered windows to the border updates of the X11
|
|
152
|
+
window manager. This improves the appearance of the window during
|
|
153
|
+
resize operations. This option only affects double-buffered windows on
|
|
154
|
+
X11 servers supporting the Xsync extension with a window manager that
|
|
155
|
+
implements the _NET_WM_SYNC_REQUEST protocol.
|
|
156
|
+
|
|
157
|
+
.. versionadded:: 1.1
|
|
158
|
+
"""
|
|
159
|
+
|
|
160
|
+
xlib_fullscreen_override_redirect: bool = False
|
|
161
|
+
"""If ``True``, pass the xlib.CWOverrideRedirect flag when creating a fullscreen window.
|
|
162
|
+
This option is generally not necessary anymore and is considered deprecated.
|
|
163
|
+
"""
|
|
164
|
+
|
|
165
|
+
search_local_libs: bool = True
|
|
166
|
+
"""If ``False``, pyglet won't try to search for libraries in the script
|
|
167
|
+
directory and its ``lib`` subdirectory. This is useful to load a local
|
|
168
|
+
library instead of the system installed version."""
|
|
169
|
+
|
|
170
|
+
win32_gdi_font: bool = False
|
|
171
|
+
"""If ``True``, pyglet will fallback to the legacy ``GDIPlus`` font renderer for Windows. This may provide
|
|
172
|
+
better font compatibility for older fonts. The legacy renderer does not support shaping, colored fonts,
|
|
173
|
+
substitutions, or other OpenType features. It may also have issues with certain languages.
|
|
174
|
+
|
|
175
|
+
Due to those lack of features, it can potentially be more performant.
|
|
176
|
+
|
|
177
|
+
.. versionadded:: 2.0
|
|
178
|
+
"""
|
|
179
|
+
|
|
180
|
+
headless: bool = False
|
|
181
|
+
"""If ``True``, visible Windows are not created and a running desktop environment is not required. This option
|
|
182
|
+
is useful when running pyglet on a headless server, or compute cluster. OpenGL drivers with ``EGL`` support are
|
|
183
|
+
required for this mode.
|
|
184
|
+
"""
|
|
185
|
+
|
|
186
|
+
headless_device: int = 0
|
|
187
|
+
"""If using ``headless`` mode (``pyglet.options['headless'] = True``), this option allows you to set which
|
|
188
|
+
GPU to use. This is only useful on multi-GPU systems.
|
|
189
|
+
"""
|
|
190
|
+
|
|
191
|
+
win32_disable_shaping: bool = False
|
|
192
|
+
"""If ``True``, will disable the shaping process for the default Windows font renderer to offer a performance
|
|
193
|
+
speed up. If your font is simple, monospaced, or you require no advanced OpenType features, this option may be
|
|
194
|
+
useful. You can try enabling this to see if there is any impact on clarity for your font. The advance will be
|
|
195
|
+
determined by the glyph width.
|
|
196
|
+
|
|
197
|
+
.. note:: Shaping is the process of determining which character glyphs to use and specific placements of those
|
|
198
|
+
glyphs when given a full string of characters.
|
|
199
|
+
|
|
200
|
+
.. versionadded:: 2.0
|
|
201
|
+
"""
|
|
202
|
+
|
|
203
|
+
dw_legacy_naming: bool = False
|
|
204
|
+
"""If ``True``, will enable legacy naming support for the default Windows font renderer (``DirectWrite``).
|
|
205
|
+
Attempt to parse fonts by the passed name, to best match legacy RBIZ naming.
|
|
206
|
+
|
|
207
|
+
:see: https://learn.microsoft.com/en-us/windows/win32/directwrite/font-selection#rbiz-font-family-model
|
|
208
|
+
|
|
209
|
+
For example, this allows specifying ``"Arial Narrow"`` rather than ``"Arial"`` with a ``"condensed"`` stretch or
|
|
210
|
+
``"Arial Black"`` instead of ``"Arial"`` with a weight of ``black``. This may enhance naming compatibility
|
|
211
|
+
cross-platform for select fonts as older font renderers went by this naming scheme.
|
|
212
|
+
|
|
213
|
+
Starts by parsing the string for any known style names, and searches all font collections for a matching RBIZ name.
|
|
214
|
+
If a perfect match is not found, it will choose a second best match.
|
|
215
|
+
|
|
216
|
+
.. note:: Due to the high variation of styles and limited capability of some fonts, there is no guarantee the
|
|
217
|
+
second closest match will be exactly what the user wants.
|
|
218
|
+
|
|
219
|
+
.. note:: The ``debug_font`` option can provide information on what settings are being selected.
|
|
220
|
+
|
|
221
|
+
.. versionadded:: 2.0.3
|
|
222
|
+
"""
|
|
223
|
+
|
|
224
|
+
win32_disable_xinput: bool = False
|
|
225
|
+
"""If ``True``, this will disable the ``XInput`` controller usage in Windows and fallback to ``DirectInput``. Can
|
|
226
|
+
be useful for debugging or special uses cases. A controller can only be controlled by either ``XInput`` or
|
|
227
|
+
``DirectInput``, not both.
|
|
228
|
+
|
|
229
|
+
.. versionadded:: 2.0
|
|
230
|
+
"""
|
|
231
|
+
|
|
232
|
+
com_mta: bool = False
|
|
233
|
+
"""If ``True``, this will enforce COM Multithreaded Apartment Mode for Windows applications. By default, pyglet
|
|
234
|
+
has opted to go for Single-Threaded Apartment (STA) for compatibility reasons. Many other third party libraries
|
|
235
|
+
used with Python explicitly set STA. However, Windows recommends MTA with a lot of their API's such as Windows
|
|
236
|
+
Media Foundation (WMF).
|
|
237
|
+
|
|
238
|
+
:see: https://learn.microsoft.com/en-us/windows/win32/cossdk/com--threading-models
|
|
239
|
+
|
|
240
|
+
.. versionadded:: 2.0.5
|
|
241
|
+
"""
|
|
168
242
|
|
|
169
|
-
|
|
243
|
+
osx_alt_loop: bool = False
|
|
244
|
+
"""If ``True``, this will enable an alternative loop for Mac OSX. This is enforced for all ARM64 architecture Mac's.
|
|
245
|
+
|
|
246
|
+
Due to various issues with the ctypes interface with Objective C, Python, and Mac ARM64 processors, the standard
|
|
247
|
+
event loop eventually starts breaking down to where inputs are either missed or delayed. Even on Intel based Mac's
|
|
248
|
+
other odd behavior can be seen with the standard event loop such as randomly crashing from events.
|
|
249
|
+
|
|
250
|
+
.. versionadded:: 2.0.5"""
|
|
251
|
+
|
|
252
|
+
scale_with_dpi: bool = False
|
|
253
|
+
"""For 'HiDPI' ('Retina') displays, scale Window creation size with desktop scaling. Defaults to ``False``.
|
|
254
|
+
|
|
255
|
+
For high pixel density displays, it is common for the desktop to have some form of application window scaling.
|
|
256
|
+
Setting this option to ``True`` will make pyglet aware of these settings when Windows are created. For instance,
|
|
257
|
+
if the desktop scaling factor is set to 150%, a Window created with a resolution of 1000x1000 will have an actual
|
|
258
|
+
framebuffer size of 1500x1500. Keep in mind that pyglet objects may not be scaled proportionately, so this is left
|
|
259
|
+
up to the developer. The :py:attr:`~pyglet.window.Window.scale` & :py:attr:`~pyglet.window.Window.dpi` attributes
|
|
260
|
+
can be queried as a reference when determining object creation. By default, windows are created with the actual
|
|
261
|
+
number of pixels requested.
|
|
262
|
+
"""
|
|
263
|
+
|
|
264
|
+
shader_bind_management: bool = True
|
|
265
|
+
"""If ``True``, this will enable internal management of Uniform Block bindings for
|
|
266
|
+
:py:class:`~pyglet.graphics.shader.ShaderProgram`'s.
|
|
267
|
+
|
|
268
|
+
If ``False``, bindings will not be managed by Pyglet. The user will be responsible for either setting the binding
|
|
269
|
+
points through GLSL layouts (4.2 required) or manually through ``UniformBlock.set_binding``.
|
|
270
|
+
|
|
271
|
+
.. versionadded:: 2.0.16
|
|
272
|
+
"""
|
|
273
|
+
|
|
274
|
+
def get(self, item: str, default: Any = None) -> Any:
|
|
275
|
+
return self.__dict__.get(item, default)
|
|
276
|
+
|
|
277
|
+
def items(self) -> ItemsView[str, Any]:
|
|
278
|
+
return self.__dict__.items()
|
|
279
|
+
|
|
280
|
+
def __getitem__(self, item: str) -> Any:
|
|
281
|
+
return self.__dict__[item]
|
|
282
|
+
|
|
283
|
+
def __setitem__(self, key: str, value: Any) -> None:
|
|
284
|
+
assert key in self.__annotations__, f"Invalid option name: '{key}'"
|
|
285
|
+
assert (_SPECIAL_OPTION_VALIDATORS.get(key, None) or _OPTION_TYPE_VALIDATORS[self.__annotations__[key]])(value), \
|
|
286
|
+
f"Invalid type: '{type(value)}' for '{key}'"
|
|
287
|
+
self.__dict__[key] = value
|
|
288
|
+
|
|
289
|
+
|
|
290
|
+
#: Instance of :py:class:`~pyglet.Options` used to set runtime options.
|
|
291
|
+
options: Options = Options()
|
|
292
|
+
|
|
293
|
+
|
|
294
|
+
for _key, _type in options.__annotations__.items():
|
|
170
295
|
"""Check Environment Variables for pyglet options"""
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
options[_key] = _value
|
|
176
|
-
elif
|
|
177
|
-
options[_key] = _value in ('true', 'TRUE', 'True', '1')
|
|
178
|
-
elif _option_types[_key] is int:
|
|
296
|
+
if _value := os.environ.get(f"PYGLET_{_key.upper()}"):
|
|
297
|
+
if _type == 'tuple':
|
|
298
|
+
options[_key] = _value.split(",")
|
|
299
|
+
elif _type == 'bool':
|
|
300
|
+
options[_key] = _value in ("true", "TRUE", "True", "1")
|
|
301
|
+
elif _type == 'int':
|
|
179
302
|
options[_key] = int(_value)
|
|
180
303
|
|
|
181
304
|
|
|
182
|
-
if compat_platform ==
|
|
305
|
+
if compat_platform == "cygwin":
|
|
183
306
|
# This hack pretends that the posix-like ctypes provides windows
|
|
184
307
|
# functionality. COM does not work with this hack, so there is no
|
|
185
308
|
# DirectSound support.
|
|
186
309
|
import ctypes
|
|
187
310
|
|
|
188
|
-
ctypes.windll = ctypes.cdll
|
|
189
|
-
ctypes.oledll = ctypes.cdll
|
|
311
|
+
ctypes.windll = ctypes.cdll
|
|
312
|
+
ctypes.oledll = ctypes.cdll
|
|
190
313
|
ctypes.WINFUNCTYPE = ctypes.CFUNCTYPE
|
|
191
|
-
ctypes.HRESULT = ctypes.c_long
|
|
314
|
+
ctypes.HRESULT = ctypes.c_long
|
|
192
315
|
|
|
193
316
|
# Call tracing
|
|
194
317
|
# ------------
|
|
195
318
|
|
|
196
|
-
_trace_filename_abbreviations:
|
|
319
|
+
_trace_filename_abbreviations: dict[str, str] = {}
|
|
197
320
|
_trace_thread_count = 0
|
|
198
|
-
_trace_args = options[
|
|
199
|
-
_trace_depth = options[
|
|
200
|
-
_trace_flush = options[
|
|
321
|
+
_trace_args = options["debug_trace_args"]
|
|
322
|
+
_trace_depth = options["debug_trace_depth"]
|
|
323
|
+
_trace_flush = options["debug_trace_flush"]
|
|
201
324
|
|
|
202
325
|
|
|
203
|
-
def _trace_repr(value, size=40):
|
|
326
|
+
def _trace_repr(value: Sized, size: int=40) -> str:
|
|
204
327
|
value = repr(value)
|
|
205
328
|
if len(value) > size:
|
|
206
|
-
value = value[:size // 2 - 2] +
|
|
329
|
+
value = value[:size // 2 - 2] + "..." + value[-size // 2 - 1:]
|
|
207
330
|
return value
|
|
208
331
|
|
|
209
332
|
|
|
210
|
-
def _trace_frame(thread, frame, indent):
|
|
211
|
-
|
|
212
|
-
if frame.f_code is lib._TraceFunction.__call__.__code__:
|
|
333
|
+
def _trace_frame(thread: int, frame: FrameType, indent: str) -> None:
|
|
334
|
+
if frame.f_code is lib._TraceFunction.__call__.__code__: # noqa: SLF001
|
|
213
335
|
is_ctypes = True
|
|
214
|
-
func = frame.f_locals[
|
|
336
|
+
func = frame.f_locals["self"]._func # noqa: SLF001
|
|
215
337
|
name = func.__name__
|
|
216
|
-
location =
|
|
338
|
+
location = "[ctypes]"
|
|
217
339
|
else:
|
|
218
340
|
is_ctypes = False
|
|
219
341
|
code = frame.f_code
|
|
@@ -225,7 +347,7 @@ def _trace_frame(thread, frame, indent):
|
|
|
225
347
|
filename = _trace_filename_abbreviations[path]
|
|
226
348
|
except KeyError:
|
|
227
349
|
# Trim path down
|
|
228
|
-
directory =
|
|
350
|
+
directory = ""
|
|
229
351
|
path, filename = os.path.split(path)
|
|
230
352
|
|
|
231
353
|
while len(directory + filename) < 30:
|
|
@@ -234,51 +356,51 @@ def _trace_frame(thread, frame, indent):
|
|
|
234
356
|
if not directory:
|
|
235
357
|
break
|
|
236
358
|
else:
|
|
237
|
-
filename = os.path.join(
|
|
359
|
+
filename = os.path.join("...", filename)
|
|
238
360
|
_trace_filename_abbreviations[path] = filename
|
|
239
361
|
|
|
240
|
-
location = f
|
|
362
|
+
location = f"({filename}:{line})"
|
|
241
363
|
|
|
242
364
|
if indent:
|
|
243
|
-
name = f
|
|
244
|
-
print(f
|
|
365
|
+
name = f"Called from {name}"
|
|
366
|
+
print(f"[{thread}] {indent}{name} {location}")
|
|
245
367
|
|
|
246
368
|
if _trace_args:
|
|
247
369
|
if is_ctypes:
|
|
248
|
-
args = [_trace_repr(arg) for arg in frame.f_locals[
|
|
370
|
+
args = [_trace_repr(arg) for arg in frame.f_locals["args"]]
|
|
249
371
|
print(f' {indent}args=({", ".join(args)})')
|
|
250
372
|
else:
|
|
251
373
|
for argname in code.co_varnames[:code.co_argcount]:
|
|
252
374
|
try:
|
|
253
375
|
argvalue = _trace_repr(frame.f_locals[argname])
|
|
254
|
-
print(f
|
|
255
|
-
except:
|
|
376
|
+
print(f" {indent}{argname}={argvalue}")
|
|
377
|
+
except: # noqa: S110, E722, PERF203
|
|
256
378
|
pass
|
|
257
379
|
|
|
258
380
|
if _trace_flush:
|
|
259
381
|
sys.stdout.flush()
|
|
260
382
|
|
|
261
383
|
|
|
262
|
-
def _thread_trace_func(thread):
|
|
263
|
-
def _trace_func(frame, event, arg):
|
|
264
|
-
if event ==
|
|
265
|
-
indent =
|
|
266
|
-
for
|
|
384
|
+
def _thread_trace_func(thread: int) -> Callable[[FrameType, str, Any], object]:
|
|
385
|
+
def _trace_func(frame: FrameType, event: str, arg: Any) -> None:
|
|
386
|
+
if event == "call":
|
|
387
|
+
indent = ""
|
|
388
|
+
for _ in range(_trace_depth):
|
|
267
389
|
_trace_frame(thread, frame, indent)
|
|
268
|
-
indent +=
|
|
269
|
-
|
|
270
|
-
if not frame:
|
|
390
|
+
indent += " "
|
|
391
|
+
if frame.f_back is None:
|
|
271
392
|
break
|
|
393
|
+
frame = frame.f_back
|
|
272
394
|
|
|
273
|
-
elif event ==
|
|
395
|
+
elif event == "exception":
|
|
274
396
|
(exception, value, traceback) = arg
|
|
275
|
-
print(
|
|
397
|
+
print("First chance exception raised:", repr(exception))
|
|
276
398
|
|
|
277
399
|
return _trace_func
|
|
278
400
|
|
|
279
401
|
|
|
280
|
-
def _install_trace():
|
|
281
|
-
global _trace_thread_count
|
|
402
|
+
def _install_trace() -> None:
|
|
403
|
+
global _trace_thread_count # noqa: PLW0603
|
|
282
404
|
sys.setprofile(_thread_trace_func(_trace_thread_count))
|
|
283
405
|
_trace_thread_count += 1
|
|
284
406
|
|
|
@@ -289,82 +411,84 @@ def _install_trace():
|
|
|
289
411
|
class _ModuleProxy:
|
|
290
412
|
_module = None
|
|
291
413
|
|
|
292
|
-
def __init__(self, name: str):
|
|
293
|
-
self.__dict__[
|
|
414
|
+
def __init__(self, name: str) -> None:
|
|
415
|
+
self.__dict__["_module_name"] = name
|
|
294
416
|
|
|
295
|
-
def __getattr__(self, name):
|
|
417
|
+
def __getattr__(self, name: str): # noqa: ANN204
|
|
296
418
|
try:
|
|
297
419
|
return getattr(self._module, name)
|
|
298
420
|
except AttributeError:
|
|
299
421
|
if self._module is not None:
|
|
300
422
|
raise
|
|
301
423
|
|
|
302
|
-
import_name = f
|
|
424
|
+
import_name = f"pyglet.{self._module_name}"
|
|
303
425
|
__import__(import_name)
|
|
304
426
|
module = sys.modules[import_name]
|
|
305
|
-
object.__setattr__(self,
|
|
427
|
+
object.__setattr__(self, "_module", module)
|
|
306
428
|
globals()[self._module_name] = module
|
|
307
429
|
return getattr(module, name)
|
|
308
430
|
|
|
309
|
-
def __setattr__(self, name, value):
|
|
431
|
+
def __setattr__(self, name: str, value: Any): # noqa: ANN204
|
|
310
432
|
try:
|
|
311
433
|
setattr(self._module, name, value)
|
|
312
434
|
except AttributeError:
|
|
313
435
|
if self._module is not None:
|
|
314
436
|
raise
|
|
315
437
|
|
|
316
|
-
import_name = f
|
|
438
|
+
import_name = f"pyglet.{self._module_name}"
|
|
317
439
|
__import__(import_name)
|
|
318
440
|
module = sys.modules[import_name]
|
|
319
|
-
object.__setattr__(self,
|
|
441
|
+
object.__setattr__(self, "_module", module)
|
|
320
442
|
globals()[self._module_name] = module
|
|
321
443
|
setattr(module, name, value)
|
|
322
444
|
|
|
323
445
|
|
|
324
446
|
# Lazily load all modules, except if performing type checking or code inspection.
|
|
325
447
|
if TYPE_CHECKING:
|
|
326
|
-
from . import
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
448
|
+
from . import (
|
|
449
|
+
app,
|
|
450
|
+
clock,
|
|
451
|
+
customtypes,
|
|
452
|
+
display,
|
|
453
|
+
event,
|
|
454
|
+
font,
|
|
455
|
+
gl,
|
|
456
|
+
graphics,
|
|
457
|
+
gui,
|
|
458
|
+
image,
|
|
459
|
+
input,
|
|
460
|
+
lib,
|
|
461
|
+
math,
|
|
462
|
+
media,
|
|
463
|
+
model,
|
|
464
|
+
resource,
|
|
465
|
+
shapes,
|
|
466
|
+
sprite,
|
|
467
|
+
text,
|
|
468
|
+
window,
|
|
469
|
+
)
|
|
346
470
|
else:
|
|
347
|
-
app = _ModuleProxy(
|
|
348
|
-
clock = _ModuleProxy(
|
|
349
|
-
customtypes = _ModuleProxy(
|
|
350
|
-
display = _ModuleProxy(
|
|
351
|
-
event = _ModuleProxy(
|
|
352
|
-
font = _ModuleProxy(
|
|
353
|
-
gl = _ModuleProxy(
|
|
354
|
-
graphics = _ModuleProxy(
|
|
355
|
-
gui = _ModuleProxy(
|
|
356
|
-
image = _ModuleProxy(
|
|
357
|
-
input = _ModuleProxy(
|
|
358
|
-
lib = _ModuleProxy(
|
|
359
|
-
math = _ModuleProxy(
|
|
360
|
-
media = _ModuleProxy(
|
|
361
|
-
model = _ModuleProxy(
|
|
362
|
-
resource = _ModuleProxy(
|
|
363
|
-
sprite = _ModuleProxy(
|
|
364
|
-
shapes = _ModuleProxy(
|
|
365
|
-
text = _ModuleProxy(
|
|
366
|
-
window = _ModuleProxy(
|
|
471
|
+
app = _ModuleProxy("app") # type: ignore
|
|
472
|
+
clock = _ModuleProxy("clock") # type: ignore
|
|
473
|
+
customtypes = _ModuleProxy("customtypes") # type: ignore
|
|
474
|
+
display = _ModuleProxy("display") # type: ignore
|
|
475
|
+
event = _ModuleProxy("event") # type: ignore
|
|
476
|
+
font = _ModuleProxy("font") # type: ignore
|
|
477
|
+
gl = _ModuleProxy("gl") # type: ignore
|
|
478
|
+
graphics = _ModuleProxy("graphics") # type: ignore
|
|
479
|
+
gui = _ModuleProxy("gui") # type: ignore
|
|
480
|
+
image = _ModuleProxy("image") # type: ignore
|
|
481
|
+
input = _ModuleProxy("input") # type: ignore
|
|
482
|
+
lib = _ModuleProxy("lib") # type: ignore
|
|
483
|
+
math = _ModuleProxy("math") # type: ignore
|
|
484
|
+
media = _ModuleProxy("media") # type: ignore
|
|
485
|
+
model = _ModuleProxy("model") # type: ignore
|
|
486
|
+
resource = _ModuleProxy("resource") # type: ignore
|
|
487
|
+
sprite = _ModuleProxy("sprite") # type: ignore
|
|
488
|
+
shapes = _ModuleProxy("shapes") # type: ignore
|
|
489
|
+
text = _ModuleProxy("text") # type: ignore
|
|
490
|
+
window = _ModuleProxy("window") # type: ignore
|
|
367
491
|
|
|
368
492
|
# Call after creating proxies:
|
|
369
|
-
if options
|
|
493
|
+
if options.debug_trace is True:
|
|
370
494
|
_install_trace()
|