File element.py#
File List > build > lib.linux-armv7l-cpython-311 > pypisoundmicro > element.py
Go to the documentation of this file
from .swig import pypisoundmicro as psm
from ._utils import copy_doc
from typing import Optional, Self, Type, Union
from .name import ElementName
from .types import Pin, ElementType, PinDirection, PinPull, ActivityType
from .valuefd import ValueFd
import os
@copy_doc(psm.Element)
class Element:
def __init__(self, native_obj: Optional[psm.Element]=None) -> None:
"""Initialize an Element.
Args:
native_obj: The native SWIG-wrapped Element object
"""
psm.upisnd_init()
self._native_obj = native_obj if native_obj is not None else psm.Element()
@property
def is_valid(self) -> bool:
""" Checks if the element is valid."""
if self._native_obj:
return self._native_obj.isValid()
return False
def release(self) -> None:
""" Unreferences the underlying C #upisnd_element_ref_t handle and resets the object."""
if self._native_obj:
self._native_obj.release()
self._native_obj = None
psm.upisnd_uninit()
@property
def name(self) -> Optional[str]:
""" Gets the name of the element."""
if self._native_obj:
return self._native_obj.getName()
return None
@property
def type(self) -> ElementType:
""" Gets the type of the element."""
if self._native_obj:
return ElementType(self._native_obj.getType())
return ElementType.INVALID
@property
def pin(self) -> Pin:
""" Gets the pin of the element."""
if self._native_obj:
return Pin(self._native_obj.getPin())
return Pin.INVALID
def open_value_fd(self, flags: int=os.O_RDWR | os.O_CLOEXEC) -> Optional[ValueFd]:
"""
Opens the Element's `value` attribute as a file descriptor.
:type flags: int
:param flags: The flags to pass to ::open.
See also: upisnd_element_open_value_fd
"""
if self._native_obj:
native_fd = self._native_obj.openValueFd(flags)
if native_fd and native_fd.isValid():
return ValueFd(native_fd)
return None
def as_encoder(self) -> Optional['Encoder']:
"""Cast the element to an Encoder if possible."""
from .encoder import Encoder
if self._native_obj and self.typetypetype == ElementType.ENCODER:
swig_encoder = self._native_obj.as_encoder()
if swig_encoder and swig_encoder.isValid():
return Encoder(swig_encoder)
return None
def as_analog_input(self) -> Optional['AnalogInput']:
"""Cast the element to an AnalogInput if possible."""
from .analoginput import AnalogInput
if self._native_obj and self.typetypetype == ElementType.ANALOG_INPUT:
swig_analog = self._native_obj.as_analog_input()
if swig_analog and swig_analog.isValid():
return AnalogInput(swig_analog)
return None
def as_gpio(self) -> Optional['Gpio']:
"""Cast the element to a GPIO if possible."""
from .gpio import Gpio
if self._native_obj and self.typetypetype == ElementType.GPIO:
swig_gpio = self._native_obj.as_gpio()
if swig_gpio and swig_gpio.isValid():
return Gpio(swig_gpio)
return None
def as_activity(self) -> Optional['Activity']:
"""Cast the element to an Activity if possible."""
from .activity import Activity
if self._native_obj and self.typetypetype == ElementType.ACTIVITY:
swig_activity = self._native_obj.as_activity()
if swig_activity and swig_activity.isValid():
return Activity(swig_activity)
return None
@classmethod
def get(cls, name: Union[str, ElementName]) -> Optional[Self]:
"""
Gets an Element following ::upisnd_element_get semantics.
:type name: :py:class:`ElementName`
:param name: The name of the element to get. Can be provided as a string constant or `const char *`.
"""
if isinstance(name, str):
name = psm.ElementName.regular(name)
native_obj = psm.Element.get(name)
if native_obj.isValid():
return cls(native_obj)
return None
@classmethod
def setup(cls, name: Union[str, ElementName], setup: Union[int, 'Setup']) -> Optional[Self]:
"""
Sets up a new Element from a #upisnd_setup_t setup option container.
:type name: :py:class:`ElementName`
:param name: The name of the element to get. Can be provided as a string constant or `const char *`.
:type setup: int
:param setup: The setup option container. See ::upisnd_setup_set_element_type and the rest of the
upisnd_setup_* APIs in api.h.
"""
if isinstance(name, str):
name = psm.ElementName.regular(name)
if hasattr(setup, 'to_int'):
setup_value = setup.to_int()
else:
setup_value = setup
native_obj = psm.Element.setup(name, setup_value)
if native_obj.isValid():
return cls(native_obj)
return None
def __enter__(self) -> Self:
"""Context manager support."""
return self
def __exit__(self, exc_type, exc_val, exc_tb) -> None:
"""Context manager support for auto-releasing resources."""
self.releaserelease()
def __del__(self) -> None:
"""Destructor to ensure resources are released.
Note: This may not always be called immediately when the object goes out of scope,
especially if the object is part of a reference cycle. For deterministic cleanup,
use the release() method explicitly or use the object as a context manager.
"""
try:
if hasattr(self, '_native_obj') and self._native_obj:
self.releaserelease()
except Exception:
pass