diff --git a/enet.pyx b/enet.pyx index 4134e03..0ac791e 100644 --- a/enet.pyx +++ b/enet.pyx @@ -3,6 +3,10 @@ import atexit from cpython cimport bool from libc.stdint cimport uintptr_t +cdef extern from "Python.h": + cdef void Py_INCREF(object o) + cdef void Py_DECREF(object o) + cdef extern from "enet/types.h": ctypedef unsigned char enet_uint8 ctypedef unsigned short enet_uint16 @@ -30,6 +34,7 @@ cdef extern from "enet/enet.h": ctypedef struct ENetEvent ctypedef int (__cdecl *ENetInterceptCallback) (ENetHost *host, ENetEvent *event) except -1 # __cdecl is standard on unix and overwriten for win32 + ctypedef void (__cdecl *ENetPacketFreeCallback) (ENetPacket *) ctypedef struct ENetAddress: enet_uint32 host @@ -46,6 +51,8 @@ cdef extern from "enet/enet.h": enet_uint32 flags enet_uint8 *data size_t dataLength + ENetPacketFreeCallback freeCallback + void* userData ctypedef enum ENetPeerState: ENET_PEER_STATE_DISCONNECTED = 0 @@ -307,6 +314,12 @@ cdef class Address: def __set__(self, value): self._enet_address.port = value +cdef void __cdecl _packet_free_callback(ENetPacket* packet) with gil: + cdef object func = packet.userData + func() + # the packet is about to be destroyed, so decrease the refcount + Py_DECREF(func) + cdef class Packet: """ Packet (str dataContents, int flags) @@ -359,6 +372,12 @@ cdef class Packet: else: return False + def set_free_callback(self, func): + self._enet_packet.freeCallback = _packet_free_callback + Py_INCREF(func) + # we're storing a reference, and need to INCREF accordingly + self._enet_packet.userData = func + property data: def __get__(self): if self.is_valid(): diff --git a/test_client.py b/test_client.py index a75bd36..e577997 100644 --- a/test_client.py +++ b/test_client.py @@ -28,6 +28,7 @@ continue msg = bytes(bytearray([random.randint(0,255) for i in range(40)])) packet = enet.Packet(msg) + packet.set_free_callback(lambda: print("%s: ACK %s" % (peer.address, counter))) peer.send(0, packet) counter += 1