1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208
|
import ctypes
from .. import (timer, error, dll,
SDL_Init, SDL_InitSubSystem, SDL_Quit, SDL_QuitSubSystem, SDL_WasInit,
SDL_INIT_VIDEO, SDL_INIT_AUDIO, SDL_INIT_TIMER, SDL_INIT_HAPTIC,
SDL_INIT_JOYSTICK, SDL_INIT_GAMECONTROLLER, SDL_INIT_SENSOR, SDL_INIT_EVENTS,
)
from ..events import (
SDL_Event, SDL_PumpEvents, SDL_PeepEvents, SDL_PollEvent,
SDL_QUIT, SDL_GETEVENT, SDL_FIRSTEVENT, SDL_LASTEVENT,
)
from .compat import isiterable
from .err import raise_sdl_err
_HASSDLTTF = True
try:
from .. import sdlttf
except ImportError:
_HASSDLTTF = False
_HASSDLIMAGE = True
try:
from .. import sdlimage
except ImportError:
_HASSDLIMAGE = False
__all__ = ["init", "quit", "get_events", "quit_requested", "TestEventProcessor"]
_sdl_subsystems = {
'timer': SDL_INIT_TIMER,
'audio': SDL_INIT_AUDIO,
'video': SDL_INIT_VIDEO,
'joystick': SDL_INIT_JOYSTICK,
'haptic': SDL_INIT_HAPTIC,
'gamecontroller': SDL_INIT_GAMECONTROLLER,
'events': SDL_INIT_EVENTS,
'sensor': SDL_INIT_SENSOR,
}
def init(
video=True, audio=False, timer=False, joystick=False, controller=False,
haptic=False, sensor=False, events=True
):
"""Initializes SDL and its optional subsystems.
By default, only the video and events subsystems are initialized. Note that
the sensor subsystem requires SDL 2.0.9 or later.
Args:
video (bool, optional): Whether to initialize the SDL video subsystem.
If True, the events subsystem will also be initialized. Defaults
to True.
audio (bool, optional): Whether to initialize the SDL audio subsystem.
Defaults to False.
timer (bool, optional): Whether to initialize the SDL timer subsystem.
Defaults to False.
joystick (bool, optional): Whether to initialize the SDL joystick
subsystem. If True, the events subsystem will also be initialized.
Defaults to False.
controller (bool, optional): Whether to initialize the SDL gamecontroller
subsystem. If True, the joystick subsystem will also be initialized.
Defaults to False.
haptic (bool, optional): Whether to initialize the SDL haptic (force
feedback) subsystem. Defaults to False.
sensor (bool, optional): Whether to initialize the SDL sensor subsystem.
Defaults to False.
events (bool, optional): Whether to initialize the SDL events subsystem.
Will automatically be initialized if the video, joystick, or
gamecontroller subsystems are enabled. Defaults to False.
See :ref:`pygamers_pygame` for a comparison between this function and
``pygame.init()``.
Raises:
:exc:`SDLError`: If a requested SDL subsystem cannot be initialized.
"""
subsystems = []
if events:
subsystems.append("events")
if video:
subsystems.append("video")
if audio:
subsystems.append("audio")
if timer:
subsystems.append("timer")
if joystick:
subsystems.append("joystick")
if controller:
subsystems.append("gamecontroller")
if haptic:
subsystems.append("haptic")
if sensor:
subsystems.append("sensor")
if SDL_Init(0) != 0:
raise_sdl_err("initializing SDL2")
for s in subsystems:
if s == "sensor" and dll.version < 2009:
e = "The sensor subsystem requires SDL 2.0.9 or later."
raise RuntimeError(e)
if SDL_InitSubSystem(_sdl_subsystems[s]) != 0:
raise_sdl_err("initializing the {0} subsystem".format(s))
def quit():
"""Quits the SDL2 video subysystem.
If no other subsystems are active, this will also call
:func:`sdl2.SDL_Quit`, :func:`sdlttf.TTF_Quit` and
:func:`sdlimage.IMG_Quit`.
"""
# TODO: More subsystems? Also, is TTF_WasInit always 1?
SDL_QuitSubSystem(SDL_INIT_VIDEO)
if SDL_WasInit(0) != 0:
if _HASSDLTTF and sdlttf.TTF_WasInit() > 0:
sdlttf.TTF_Quit()
if _HASSDLIMAGE:
sdlimage.IMG_Quit()
SDL_Quit()
def get_events():
"""Gets all SDL events that are currently on the event queue.
Returns:
:obj:`List`: A list of all :obj:`~sdl2.SDL_Event` objects currently in
the event queue.
"""
SDL_PumpEvents()
evlist = []
while True:
evarray = (SDL_Event * 10)()
ptr = ctypes.cast(evarray, ctypes.POINTER(SDL_Event))
ret = SDL_PeepEvents(
ptr, 10, SDL_GETEVENT, SDL_FIRSTEVENT, SDL_LASTEVENT
)
if ret <= 0:
break
evlist += list(evarray)[:ret]
if ret < 10:
break
return evlist
def quit_requested(events):
"""Checks for quit requests in a given event queue.
Quit requests occur when an SDL recieves a system-level quit signal (e.g
clicking the 'close' button on an SDL window, pressing Command-Q on macOS).
This function makes it easier to handle these events in your code::
running = True
while running:
events = sdl2.ext.get_events()
if quit_requested(events):
running = False
Args:
events (list of :obj:`sdl2.SDL_Event`): A list of SDL events to check
for quit requests.
Returns:
bool: True if a quit request has occurred, otherwise False.
"""
# Ensure 'events' is iterable
if not isiterable(events):
events = [events]
# Check for any quit events in the queue
requested = False
for e in events:
if e.type == SDL_QUIT:
requested = True
break
return requested
class TestEventProcessor(object):
"""A simple event processor for testing purposes."""
def run(self, window):
"""Starts an event loop without actually processing any event.
This method will run endlessly until an ``SDL_QUIT`` event occurs.
Args:
window (:obj:`sdl2.ext.Window`): The window within which to run
the test event loop.
"""
event = SDL_Event()
running = True
while running:
ret = SDL_PollEvent(ctypes.byref(event), 1)
if ret == 1:
if event.type == SDL_QUIT:
running = False
break
window.refresh()
timer.SDL_Delay(10)
|