跟随 pyglet各种奇怪分支的更新

This commit is contained in:
shenjack 2023-02-07 11:27:15 +08:00
parent aa2341a806
commit c01058b14d
8 changed files with 109 additions and 84 deletions

View File

@ -9,7 +9,7 @@ import sys
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
#: The release version #: The release version
version = '2.0.3' version = '2.0.4'
__version__ = version __version__ = version
MIN_PYTHON_VERSION = 3, 8 MIN_PYTHON_VERSION = 3, 8

View File

@ -26,7 +26,7 @@ draws the entire batch::
car = pyglet.sprite.Sprite(car_image, batch=batch) car = pyglet.sprite.Sprite(car_image, batch=batch)
boat = pyglet.sprite.Sprite(boat_image, batch=batch) boat = pyglet.sprite.Sprite(boat_image, batch=batch)
def on_draw() def on_draw():
batch.draw() batch.draw()
Drawing a complete Batch is much faster than drawing the items in the batch Drawing a complete Batch is much faster than drawing the items in the batch
@ -46,7 +46,7 @@ before the car and the boat::
car = pyglet.sprite.Sprite(car_image, batch=batch, group=foreground) car = pyglet.sprite.Sprite(car_image, batch=batch, group=foreground)
boat = pyglet.sprite.Sprite(boat_image, batch=batch, group=foreground) boat = pyglet.sprite.Sprite(boat_image, batch=batch, group=foreground)
def on_draw() def on_draw():
batch.draw() batch.draw()
It's preferable to manage pyglet objects within as few batches as possible. If It's preferable to manage pyglet objects within as few batches as possible. If

View File

@ -82,7 +82,7 @@ class WidgetBase(EventDispatcher):
def aabb(self): def aabb(self):
"""Bounding box of the widget. """Bounding box of the widget.
Expresesed as (x, y, x + width, y + height) Expressed as (x, y, x + width, y + height)
:type: (int, int, int, int) :type: (int, int, int, int)
""" """

View File

@ -215,40 +215,40 @@ _element_lookup = {} # IOHIDElementRef to python HIDDeviceElement object
class HIDValue: class HIDValue:
def __init__(self, valueRef): def __init__(self, value_ref):
# Check that this is a valid IOHIDValue. # Check that this is a valid IOHIDValue.
assert valueRef assert value_ref
assert cf.CFGetTypeID(valueRef) == iokit.IOHIDValueGetTypeID() assert cf.CFGetTypeID(value_ref) == iokit.IOHIDValueGetTypeID()
self.valueRef = valueRef self.value_ref = value_ref
self.timestamp = iokit.IOHIDValueGetTimeStamp(valueRef) self.timestamp = iokit.IOHIDValueGetTimeStamp(value_ref)
self.length = iokit.IOHIDValueGetLength(valueRef) self.length = iokit.IOHIDValueGetLength(value_ref)
if self.length <= 4: if self.length <= 4:
self.intvalue = iokit.IOHIDValueGetIntegerValue(valueRef) self.intvalue = iokit.IOHIDValueGetIntegerValue(value_ref)
else: else:
# Values may be byte data rather than integers. # Values may be byte data rather than integers.
# e.g. the PS3 controller has a 39-byte HIDValue element. # e.g. the PS3 controller has a 39-byte HIDValue element.
# We currently do not try to handle these cases. # We currently do not try to handle these cases.
self.intvalue = None self.intvalue = None
elementRef = c_void_p(iokit.IOHIDValueGetElement(valueRef)) element_ref = c_void_p(iokit.IOHIDValueGetElement(value_ref))
self.element = HIDDeviceElement.get_element(elementRef) self.element = HIDDeviceElement.get_element(element_ref)
class HIDDevice: class HIDDevice:
@classmethod @classmethod
def get_device(cls, deviceRef): def get_device(cls, device_ref):
# deviceRef is a c_void_p pointing to an IOHIDDeviceRef # device_ref is a c_void_p pointing to an IOHIDDeviceRef
if deviceRef.value in _device_lookup: if device_ref.value in _device_lookup:
return _device_lookup[deviceRef.value] return _device_lookup[device_ref.value]
else: else:
device = HIDDevice(deviceRef) device = HIDDevice(device_ref)
return device return device
def __init__(self, deviceRef): def __init__(self, device_ref):
# Check that we've got a valid IOHIDDevice. # Check that we've got a valid IOHIDDevice.
assert deviceRef assert device_ref
assert cf.CFGetTypeID(deviceRef) == iokit.IOHIDDeviceGetTypeID() assert cf.CFGetTypeID(device_ref) == iokit.IOHIDDeviceGetTypeID()
_device_lookup[deviceRef.value] = self _device_lookup[device_ref.value] = self
self.deviceRef = deviceRef self.device_ref = device_ref
# Set attributes from device properties. # Set attributes from device properties.
self.transport = self.get_property("Transport") self.transport = self.get_property("Transport")
self.vendorID = self.get_property("VendorID") self.vendorID = self.get_property("VendorID")
@ -297,7 +297,7 @@ class HIDDevice:
def get_property(self, name): def get_property(self, name):
cfname = CFSTR(name) cfname = CFSTR(name)
cfvalue = c_void_p(iokit.IOHIDDeviceGetProperty(self.deviceRef, cfname)) cfvalue = c_void_p(iokit.IOHIDDeviceGetProperty(self.device_ref, cfname))
cf.CFRelease(cfname) cf.CFRelease(cfname)
return cftype_to_value(cfvalue) return cftype_to_value(cfvalue)
@ -306,25 +306,25 @@ class HIDDevice:
options = kIOHIDOptionsTypeSeizeDevice options = kIOHIDOptionsTypeSeizeDevice
else: else:
options = kIOHIDOptionsTypeNone options = kIOHIDOptionsTypeNone
return bool(iokit.IOHIDDeviceOpen(self.deviceRef, options)) return bool(iokit.IOHIDDeviceOpen(self.device_ref, options))
def close(self): def close(self):
return bool(iokit.IOHIDDeviceClose(self.deviceRef, kIOHIDOptionsTypeNone)) return bool(iokit.IOHIDDeviceClose(self.device_ref, kIOHIDOptionsTypeNone))
def schedule_with_run_loop(self): def schedule_with_run_loop(self):
iokit.IOHIDDeviceScheduleWithRunLoop( iokit.IOHIDDeviceScheduleWithRunLoop(
self.deviceRef, self.device_ref,
c_void_p(cf.CFRunLoopGetCurrent()), c_void_p(cf.CFRunLoopGetCurrent()),
kCFRunLoopDefaultMode) kCFRunLoopDefaultMode)
def unschedule_from_run_loop(self): def unschedule_from_run_loop(self):
iokit.IOHIDDeviceUnscheduleFromRunLoop( iokit.IOHIDDeviceUnscheduleFromRunLoop(
self.deviceRef, self.device_ref,
c_void_p(cf.CFRunLoopGetCurrent()), c_void_p(cf.CFRunLoopGetCurrent()),
kCFRunLoopDefaultMode) kCFRunLoopDefaultMode)
def _get_elements(self): def _get_elements(self):
cfarray = c_void_p(iokit.IOHIDDeviceCopyMatchingElements(self.deviceRef, None, 0)) cfarray = c_void_p(iokit.IOHIDDeviceCopyMatchingElements(self.device_ref, None, 0))
if not cfarray: if not cfarray:
# requires "Security & Privacy / Input Monitoring", see #95 # requires "Security & Privacy / Input Monitoring", see #95
return [] return []
@ -335,7 +335,7 @@ class HIDDevice:
# Page and usage IDs are from the HID usage tables located at # Page and usage IDs are from the HID usage tables located at
# https://usb.org/sites/default/files/hut1_3_0.pdf # https://usb.org/sites/default/files/hut1_3_0.pdf
def conforms_to(self, page, usage): def conforms_to(self, page, usage):
return bool(iokit.IOHIDDeviceConformsTo(self.deviceRef, page, usage)) return bool(iokit.IOHIDDeviceConformsTo(self.device_ref, page, usage))
def is_pointer(self): def is_pointer(self):
return self.conforms_to(0x01, 0x01) return self.conforms_to(0x01, 0x01)
@ -373,7 +373,7 @@ class HIDDevice:
def _register_removal_callback(self): def _register_removal_callback(self):
removal_callback = HIDDeviceCallback(self.py_removal_callback) removal_callback = HIDDeviceCallback(self.py_removal_callback)
iokit.IOHIDDeviceRegisterRemovalCallback(self.deviceRef, removal_callback, None) iokit.IOHIDDeviceRegisterRemovalCallback(self.device_ref, removal_callback, None)
return removal_callback return removal_callback
def add_removal_observer(self, observer): def add_removal_observer(self, observer):
@ -388,7 +388,7 @@ class HIDDevice:
def _register_input_value_callback(self): def _register_input_value_callback(self):
value_callback = HIDDeviceValueCallback(self.py_value_callback) value_callback = HIDDeviceValueCallback(self.py_value_callback)
iokit.IOHIDDeviceRegisterInputValueCallback(self.deviceRef, value_callback, None) iokit.IOHIDDeviceRegisterInputValueCallback(self.device_ref, value_callback, None)
return value_callback return value_callback
def add_value_observer(self, observer): def add_value_observer(self, observer):
@ -396,64 +396,64 @@ class HIDDevice:
def get_value(self, element): def get_value(self, element):
# If the device is not open, then returns None # If the device is not open, then returns None
valueRef = c_void_p() value_ref = c_void_p()
iokit.IOHIDDeviceGetValue(self.deviceRef, element.elementRef, byref(valueRef)) iokit.IOHIDDeviceGetValue(self.device_ref, element.element_ref, byref(value_ref))
if valueRef: if value_ref:
return HIDValue(valueRef) return HIDValue(value_ref)
else: else:
return None return None
class HIDDeviceElement: class HIDDeviceElement:
@classmethod @classmethod
def get_element(cls, elementRef): def get_element(cls, element_ref):
# elementRef is a c_void_p pointing to an IOHIDDeviceElementRef # element_ref is a c_void_p pointing to an IOHIDDeviceElementRef
if elementRef.value in _element_lookup: if element_ref.value in _element_lookup:
return _element_lookup[elementRef.value] return _element_lookup[element_ref.value]
else: else:
element = HIDDeviceElement(elementRef) element = HIDDeviceElement(element_ref)
return element return element
def __init__(self, elementRef): def __init__(self, element_ref):
# Check that we've been passed a valid IOHIDElement. # Check that we've been passed a valid IOHIDElement.
assert elementRef assert element_ref
assert cf.CFGetTypeID(elementRef) == iokit.IOHIDElementGetTypeID() assert cf.CFGetTypeID(element_ref) == iokit.IOHIDElementGetTypeID()
_element_lookup[elementRef.value] = self _element_lookup[element_ref.value] = self
self.elementRef = elementRef self.element_ref = element_ref
# Set element properties as attributes. # Set element properties as attributes.
self.cookie = iokit.IOHIDElementGetCookie(elementRef) self.cookie = iokit.IOHIDElementGetCookie(element_ref)
self.type = iokit.IOHIDElementGetType(elementRef) self.type = iokit.IOHIDElementGetType(element_ref)
if self.type == kIOHIDElementTypeCollection: if self.type == kIOHIDElementTypeCollection:
self.collectionType = iokit.IOHIDElementGetCollectionType(elementRef) self.collectionType = iokit.IOHIDElementGetCollectionType(element_ref)
else: else:
self.collectionType = None self.collectionType = None
self.usagePage = iokit.IOHIDElementGetUsagePage(elementRef) self.usagePage = iokit.IOHIDElementGetUsagePage(element_ref)
self.usage = iokit.IOHIDElementGetUsage(elementRef) self.usage = iokit.IOHIDElementGetUsage(element_ref)
self.isVirtual = bool(iokit.IOHIDElementIsVirtual(elementRef)) self.isVirtual = bool(iokit.IOHIDElementIsVirtual(element_ref))
self.isRelative = bool(iokit.IOHIDElementIsRelative(elementRef)) self.isRelative = bool(iokit.IOHIDElementIsRelative(element_ref))
self.isWrapping = bool(iokit.IOHIDElementIsWrapping(elementRef)) self.isWrapping = bool(iokit.IOHIDElementIsWrapping(element_ref))
self.isArray = bool(iokit.IOHIDElementIsArray(elementRef)) self.isArray = bool(iokit.IOHIDElementIsArray(element_ref))
self.isNonLinear = bool(iokit.IOHIDElementIsNonLinear(elementRef)) self.isNonLinear = bool(iokit.IOHIDElementIsNonLinear(element_ref))
self.hasPreferredState = bool(iokit.IOHIDElementHasPreferredState(elementRef)) self.hasPreferredState = bool(iokit.IOHIDElementHasPreferredState(element_ref))
self.hasNullState = bool(iokit.IOHIDElementHasNullState(elementRef)) self.hasNullState = bool(iokit.IOHIDElementHasNullState(element_ref))
self.name = cftype_to_value(iokit.IOHIDElementGetName(elementRef)) self.name = cftype_to_value(iokit.IOHIDElementGetName(element_ref))
self.reportID = iokit.IOHIDElementGetReportID(elementRef) self.reportID = iokit.IOHIDElementGetReportID(element_ref)
self.reportSize = iokit.IOHIDElementGetReportSize(elementRef) self.reportSize = iokit.IOHIDElementGetReportSize(element_ref)
self.reportCount = iokit.IOHIDElementGetReportCount(elementRef) self.reportCount = iokit.IOHIDElementGetReportCount(element_ref)
self.unit = iokit.IOHIDElementGetUnit(elementRef) self.unit = iokit.IOHIDElementGetUnit(element_ref)
self.unitExponent = iokit.IOHIDElementGetUnitExponent(elementRef) self.unitExponent = iokit.IOHIDElementGetUnitExponent(element_ref)
self.logicalMin = iokit.IOHIDElementGetLogicalMin(elementRef) self.logicalMin = iokit.IOHIDElementGetLogicalMin(element_ref)
self.logicalMax = iokit.IOHIDElementGetLogicalMax(elementRef) self.logicalMax = iokit.IOHIDElementGetLogicalMax(element_ref)
self.physicalMin = iokit.IOHIDElementGetPhysicalMin(elementRef) self.physicalMin = iokit.IOHIDElementGetPhysicalMin(element_ref)
self.physicalMax = iokit.IOHIDElementGetPhysicalMax(elementRef) self.physicalMax = iokit.IOHIDElementGetPhysicalMax(element_ref)
class HIDManager(EventDispatcher): class HIDManager(EventDispatcher):
def __init__(self): def __init__(self):
# Create the HID Manager. # Create the HID Manager.
self.managerRef = c_void_p(iokit.IOHIDManagerCreate(None, kIOHIDOptionsTypeNone)) self.manager_ref = c_void_p(iokit.IOHIDManagerCreate(None, kIOHIDOptionsTypeNone))
assert self.managerRef assert self.manager_ref
assert cf.CFGetTypeID(self.managerRef) == iokit.IOHIDManagerGetTypeID() assert cf.CFGetTypeID(self.manager_ref) == iokit.IOHIDManagerGetTypeID()
self.schedule_with_run_loop() self.schedule_with_run_loop()
self.matching_observers = set() self.matching_observers = set()
self.matching_callback = self._register_matching_callback() self.matching_callback = self._register_matching_callback()
@ -463,9 +463,9 @@ class HIDManager(EventDispatcher):
try: try:
# Tell manager that we are willing to match *any* device. # Tell manager that we are willing to match *any* device.
# (Alternatively, we could restrict by device usage, or usage page.) # (Alternatively, we could restrict by device usage, or usage page.)
iokit.IOHIDManagerSetDeviceMatching(self.managerRef, None) iokit.IOHIDManagerSetDeviceMatching(self.manager_ref, None)
# Copy the device set and convert it to python. # Copy the device set and convert it to python.
cfset = c_void_p(iokit.IOHIDManagerCopyDevices(self.managerRef)) cfset = c_void_p(iokit.IOHIDManagerCopyDevices(self.manager_ref))
devices = cfset_to_set(cfset) devices = cfset_to_set(cfset)
cf.CFRelease(cfset) cf.CFRelease(cfset)
except: except:
@ -473,20 +473,20 @@ class HIDManager(EventDispatcher):
return devices return devices
def open(self): def open(self):
iokit.IOHIDManagerOpen(self.managerRef, kIOHIDOptionsTypeNone) iokit.IOHIDManagerOpen(self.manager_ref, kIOHIDOptionsTypeNone)
def close(self): def close(self):
iokit.IOHIDManagerClose(self.managerRef, kIOHIDOptionsTypeNone) iokit.IOHIDManagerClose(self.manager_ref, kIOHIDOptionsTypeNone)
def schedule_with_run_loop(self): def schedule_with_run_loop(self):
iokit.IOHIDManagerScheduleWithRunLoop( iokit.IOHIDManagerScheduleWithRunLoop(
self.managerRef, self.manager_ref,
c_void_p(cf.CFRunLoopGetCurrent()), c_void_p(cf.CFRunLoopGetCurrent()),
kCFRunLoopDefaultMode) kCFRunLoopDefaultMode)
def unschedule_from_run_loop(self): def unschedule_from_run_loop(self):
iokit.IOHIDManagerUnscheduleFromRunLoop( iokit.IOHIDManagerUnscheduleFromRunLoop(
self.managerRef, self.manager_ref,
c_void_p(cf.CFRunLoopGetCurrent()), c_void_p(cf.CFRunLoopGetCurrent()),
kCFRunLoopDefaultMode) kCFRunLoopDefaultMode)
@ -500,7 +500,7 @@ class HIDManager(EventDispatcher):
def _register_matching_callback(self): def _register_matching_callback(self):
matching_callback = HIDManagerCallback(self._py_matching_callback) matching_callback = HIDManagerCallback(self._py_matching_callback)
iokit.IOHIDManagerRegisterDeviceMatchingCallback(self.managerRef, matching_callback, None) iokit.IOHIDManagerRegisterDeviceMatchingCallback(self.manager_ref, matching_callback, None)
return matching_callback return matching_callback

View File

@ -88,6 +88,7 @@ class DirectInputDevice(base.Device):
def _init_controls(self): def _init_controls(self):
self.controls = [] self.controls = []
self._device.EnumObjects(dinput.LPDIENUMDEVICEOBJECTSCALLBACK(self._object_enum), None, dinput.DIDFT_ALL) self._device.EnumObjects(dinput.LPDIENUMDEVICEOBJECTSCALLBACK(self._object_enum), None, dinput.DIDFT_ALL)
self.controls.sort(key=lambda c: c._type)
def _object_enum(self, object_instance, arg): def _object_enum(self, object_instance, arg):
control = _create_control(object_instance.contents) control = _create_control(object_instance.contents)
@ -207,7 +208,7 @@ _i_dinput = _init_directinput()
GUID_DEVINTERFACE_HID = com.GUID(0x4D1E55B2, 0xF16F, 0x11CF, 0x88, 0xCB, 0x00, 0x11, 0x11, 0x00, 0x00, 0x30) GUID_DEVINTERFACE_HID = com.GUID(0x4D1E55B2, 0xF16F, 0x11CF, 0x88, 0xCB, 0x00, 0x11, 0x11, 0x00, 0x00, 0x30)
class DIManager(EventDispatcher): class DIDeviceManager(EventDispatcher):
def __init__(self): def __init__(self):
# Pick any open window, or the shadow window if no windows have been created yet. # Pick any open window, or the shadow window if no windows have been created yet.
window = pyglet.gl._shadow_window window = pyglet.gl._shadow_window
@ -296,10 +297,10 @@ class DIManager(EventDispatcher):
self._recheck_devices() self._recheck_devices()
DIManager.register_event_type('on_connect') DIDeviceManager.register_event_type('on_connect')
DIManager.register_event_type('on_disconnect') DIDeviceManager.register_event_type('on_disconnect')
_di_manager = DIManager() _di_manager = DIDeviceManager()
class DIControllerManager(ControllerManager): class DIControllerManager(ControllerManager):

View File

@ -75,6 +75,13 @@ def add_default_codecs():
except ImportError: except ImportError:
pass pass
if pyglet.compat_platform.startswith("darwin"):
try:
from . import coreaudio
registry.add_decoders(coreaudio)
except ImportError:
pass
def have_ffmpeg(): def have_ffmpeg():
"""Check if FFmpeg library is available. """Check if FFmpeg library is available.

View File

@ -150,9 +150,12 @@ class CoreAudioSource(StreamingSource):
data = cast(self._bl.mBuffers[0].mData, POINTER(c_char)) data = cast(self._bl.mBuffers[0].mData, POINTER(c_char))
slice = data[:size] slice = data[:size]
return AudioData(slice, size, 0.0, 0.0, []) return AudioData(slice, size, 0.0, size / self.audio_format.sample_rate, [])
return None
def seek(self, timestamp): def seek(self, timestamp):
self._bl = None # invalidate buffer list.
timestamp = max(0.0, min(timestamp, self._duration)) timestamp = max(0.0, min(timestamp, self._duration))
position = int(timestamp / self._duration_per_frame) position = int(timestamp / self._duration_per_frame)
ca.ExtAudioFileSeek(self._audref, position) ca.ExtAudioFileSeek(self._audref, position)

View File

@ -78,9 +78,23 @@ def buttons_string(buttons):
return "|".join(button_names) return "|".join(button_names)
# Symbolic names for the mouse buttons #: Constant for the left mouse button.
#:
#: :meta hide-value:
LEFT = 1 << 0 LEFT = 1 << 0
#: Constant for the middle mouse button.
#:
#: :meta hide-value:
MIDDLE = 1 << 1 MIDDLE = 1 << 1
#: Constant for the right mouse button.
#:
#: :meta hide-value:
RIGHT = 1 << 2 RIGHT = 1 << 2
#: Constant for the mouse4 button.
#:
#: :meta hide-value:
MOUSE4 = 1 << 3 MOUSE4 = 1 << 3
#: Constant for the mouse5 button.
#:
#: :meta hide-value:
MOUSE5 = 1 << 4 MOUSE5 = 1 << 4