Skip to content

Commit

Permalink
Remove dependency from ctypes in client code
Browse files Browse the repository at this point in the history
  • Loading branch information
intrueder committed Jun 27, 2022
1 parent 651c038 commit c42f8dd
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 44 deletions.
38 changes: 22 additions & 16 deletions src/cuesdk/enums.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
from ctypes import c_uint

__all__ = [
'CorsairDeviceType', 'CorsairPhysicalLayout', 'CorsairLogicalLayout',
'CorsairDeviceCaps', 'CorsairAccessMode', 'CorsairError',
Expand All @@ -8,38 +6,46 @@
]


class EnumerationType(type(c_uint)):
def __new__(metacls, name, bases, dictcls):
if "_members_" not in dictcls:
_members_ = {}
for key, value in dictcls.items():
if not key.startswith("_"):
_members_[key] = value
class EnumerationType(type):

dictcls["_members_"] = _members_
def __new__(metacls, name, bases, namespace):
if "_members_" not in namespace:
_members_ = {
k: v
for k, v in namespace.items() if not k.startswith("_")
}
namespace["_members_"] = _members_
else:
_members_ = dictcls["_members_"]
_members_ = namespace["_members_"]

dictcls["_reverse_map_"] = {v: k for k, v in _members_.items()}
return type(c_uint).__new__(metacls, name, bases, dictcls)
namespace["_reverse_map_"] = {v: k for k, v in _members_.items()}
return super().__new__(metacls, name, bases, namespace)

def __repr__(self):
return "<Enumeration %s>" % self.__name__


class Enumeration(c_uint, metaclass=EnumerationType):
_members_ = {}
class Enumeration(metaclass=EnumerationType):

def __init__(self, value):
if value not in self._reverse_map_:
raise ValueError("%d is not a valid value for %s" %
(value, type(self).__name__))
self.value = value

def __repr__(self):
return "<%s: %d>" % (self.__str__(), self.value)

def __str__(self):
return "%s.%s" % (self.__class__.__name__,
return "%s.%s" % (type(self).__name__,
self._reverse_map_.get(self.value, '(unknown)'))

def __hash__(self):
return self.value

def __int__(self):
return self.value

def __eq__(self, other):
if isinstance(other, int):
return self.value == other
Expand Down
10 changes: 7 additions & 3 deletions src/cuesdk/native/capi.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import sys
from ctypes import (CDLL, CFUNCTYPE, POINTER, c_bool, c_char, c_int32,
c_void_p)
from ..enums import (CorsairAccessMode, CorsairError, CorsairLedId,
CorsairDevicePropertyId)
c_uint32, c_void_p)
from . import (CorsairProtocolDetails, CorsairDeviceInfo, CorsairLedPositions,
CorsairLedColor, CorsairEvent)

Expand All @@ -17,6 +15,12 @@ def load_library(library_path):
sys.exit()


CorsairError = c_uint32
CorsairLedId = c_uint32
CorsairAccessMode = c_uint32
CorsairDevicePropertyId = c_uint32


class CorsairNativeApi():

def __init__(self, libpath):
Expand Down
19 changes: 9 additions & 10 deletions src/cuesdk/native/structs.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,7 @@ class CorsairProtocolDetails(ctypes.Structure):


class CorsairChannelDeviceInfo(ctypes.Structure):
_fields_ = [('type', CorsairChannelDeviceType),
('deviceLedCount', ctypes.c_int32)]
_fields_ = [('type', ctypes.c_uint), ('deviceLedCount', ctypes.c_int32)]


class CorsairChannelInfo(ctypes.Structure):
Expand All @@ -38,16 +37,16 @@ class CorsairChannelsInfo(ctypes.Structure):


class CorsairDeviceInfo(ctypes.Structure):
_fields_ = [('type', CorsairDeviceType), ('model', ctypes.c_char_p),
('physicalLayout', CorsairPhysicalLayout),
('logicalLayout', CorsairLogicalLayout),
('capsMask', ctypes.c_int32), ('ledsCount', ctypes.c_int32),
_fields_ = [('type', ctypes.c_uint), ('model', ctypes.c_char_p),
('physicalLayout', ctypes.c_uint),
('logicalLayout', ctypes.c_uint), ('capsMask', ctypes.c_int32),
('ledsCount', ctypes.c_int32),
('channels', CorsairChannelsInfo),
('deviceId', ctypes.c_char * CORSAIR_DEVICE_ID_MAX)]


class CorsairLedPosition(ctypes.Structure):
_fields_ = [('ledId', CorsairLedId), ('top', ctypes.c_double),
_fields_ = [('ledId', ctypes.c_uint), ('top', ctypes.c_double),
('left', ctypes.c_double), ('height', ctypes.c_double),
('width', ctypes.c_double)]

Expand All @@ -58,7 +57,7 @@ class CorsairLedPositions(ctypes.Structure):


class CorsairLedColor(ctypes.Structure):
_fields_ = [('ledId', CorsairLedId), ('r', ctypes.c_int32),
_fields_ = [('ledId', ctypes.c_uint), ('r', ctypes.c_int32),
('g', ctypes.c_int32), ('b', ctypes.c_int32)]


Expand All @@ -69,7 +68,7 @@ class CorsairDeviceConnectionStatusChangedEvent(ctypes.Structure):

class CorsairKeyEvent(ctypes.Structure):
_fields_ = [('deviceId', ctypes.c_char * CORSAIR_DEVICE_ID_MAX),
('keyId', CorsairKeyId), ('isPressed', ctypes.c_bool)]
('keyId', ctypes.c_uint), ('isPressed', ctypes.c_bool)]


class CorsairEventPayload(ctypes.Union):
Expand All @@ -80,4 +79,4 @@ class CorsairEventPayload(ctypes.Union):

class CorsairEvent(ctypes.Structure):
_anonymous_ = ("payload", )
_fields_ = [('id', CorsairEventId), ('payload', CorsairEventPayload)]
_fields_ = [('id', ctypes.c_uint), ('payload', CorsairEventPayload)]
35 changes: 20 additions & 15 deletions src/cuesdk/structs.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@ class CorsairChannelDeviceInfo():

@staticmethod
def create(nobj):
return CorsairChannelDeviceInfo(nobj.type, nobj.deviceLedCount)
return CorsairChannelDeviceInfo(CorsairChannelDeviceType(nobj.type),
nobj.deviceLedCount)


@dataclass(frozen=True)
Expand Down Expand Up @@ -77,10 +78,12 @@ def create(nobj):
for chi in range(s.channels.channelsCount)
]

return CorsairDeviceInfo(bytes_to_str_or_default(s.deviceId), s.type,
return CorsairDeviceInfo(bytes_to_str_or_default(s.deviceId),
CorsairDeviceType(s.type),
bytes_to_str_or_default(s.model),
s.physicalLayout, s.logicalLayout, s.capsMask,
s.ledsCount, channels)
CorsairPhysicalLayout(s.physicalLayout),
CorsairLogicalLayout(s.logicalLayout),
s.capsMask, s.ledsCount, channels)


@dataclass(frozen=True)
Expand All @@ -93,8 +96,8 @@ class CorsairLedPosition():

@staticmethod
def create(nobj):
return CorsairLedPosition(nobj.ledId, nobj.top, nobj.left, nobj.height,
nobj.width)
return CorsairLedPosition(CorsairLedId(nobj.ledId), nobj.top,
nobj.left, nobj.height, nobj.width)


class CorsairLedPositions(Mapping):
Expand Down Expand Up @@ -133,7 +136,8 @@ class CorsairLedColor():

@staticmethod
def create(nobj):
return CorsairLedColor(nobj.ledId, nobj.r, nobj.g, nobj.b)
return CorsairLedColor(CorsairLedId(nobj.ledId), nobj.r, nobj.g,
nobj.b)


@dataclass(frozen=True)
Expand All @@ -155,23 +159,24 @@ class CorsairKeyEvent():

@staticmethod
def create(nobj):
return CorsairKeyEvent(nobj.deviceId.decode(), nobj.keyId,
nobj.isPressed)
return CorsairKeyEvent(nobj.deviceId.decode(),
CorsairKeyId(nobj.keyId), nobj.isPressed)


@dataclass(frozen=True)
class CorsairEvent():
id: str
id: CorsairEventId
data: Union[CorsairKeyEvent, CorsairDeviceConnectionStatusChangedEvent]

@staticmethod
def create(nobj):
e = nobj[0]
if (e.id == CorsairEventId.DeviceConnectionStatusChangedEvent):
id = CorsairEventId(e.id)
if (id == CorsairEventId.DeviceConnectionStatusChangedEvent):
return CorsairEvent(
e.id,
id,
CorsairDeviceConnectionStatusChangedEvent.create(
e.deviceConnectionStatusChangedEvent[0]))
elif (e.id == CorsairEventId.KeyEvent):
return CorsairEvent(e.id, CorsairKeyEvent.create(e.keyEvent[0]))
raise ValueError("Unknown event id={id}".format(id=e.id))
elif (id == CorsairEventId.KeyEvent):
return CorsairEvent(id, CorsairKeyEvent.create(e.keyEvent[0]))
raise ValueError("Unknown event id={id}".format(id=id))

0 comments on commit c42f8dd

Please sign in to comment.