1discard """Copyright (c) 2002-2012 Lee Salzman
2
3Permission is hereby granted, free of charge, to any person obtaining a copy of
4this software and associated documentation files (the "Software"), to deal in
5the Software without restriction, including without limitation the rights to
6use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
7the Software, and to permit persons to whom the Software is furnished to do so,
8subject to the following conditions:
9
10The above copyright notice and this permission notice shall be included in all
11copies or substantial portions of the Software.
12
13THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
15FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
16COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
17IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
18CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19"""
20
21const Lib = "libenet.so.1(|.0.3)"
22
23const
24  ENET_VERSION_MAJOR* = 1
25  ENET_VERSION_MINOR* = 3
26  ENET_VERSION_PATCH* = 3
27template ENET_VERSION_CREATE(major, minor, patch: untyped): untyped =
28  (((major) shl 16) or ((minor) shl 8) or (patch))
29
30const
31  ENET_VERSION* = ENET_VERSION_CREATE(ENET_VERSION_MAJOR, ENET_VERSION_MINOR,
32                                      ENET_VERSION_PATCH)
33type
34  TVersion* = cuint
35  TSocketType*{.size: sizeof(cint).} = enum
36    ENET_SOCKET_TYPE_STREAM = 1, ENET_SOCKET_TYPE_DATAGRAM = 2
37  TSocketWait*{.size: sizeof(cint).} = enum
38    ENET_SOCKET_WAIT_NONE = 0, ENET_SOCKET_WAIT_SEND = (1 shl 0),
39    ENET_SOCKET_WAIT_RECEIVE = (1 shl 1)
40  TSocketOption*{.size: sizeof(cint).} = enum
41    ENET_SOCKOPT_NONBLOCK = 1, ENET_SOCKOPT_BROADCAST = 2,
42    ENET_SOCKOPT_RCVBUF = 3, ENET_SOCKOPT_SNDBUF = 4,
43    ENET_SOCKOPT_REUSEADDR = 5
44const
45  ENET_HOST_ANY* = 0
46  ENET_HOST_BROADCAST* = 0xFFFFFFFF
47  ENET_PORT_ANY* = 0
48
49  ENET_PROTOCOL_MINIMUM_MTU* = 576
50  ENET_PROTOCOL_MAXIMUM_MTU* = 4096
51  ENET_PROTOCOL_MAXIMUM_PACKET_COMMANDS* = 32
52  ENET_PROTOCOL_MINIMUM_WINDOW_SIZE* = 4096
53  ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE* = 32768
54  ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT* = 1
55  ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT* = 255
56  ENET_PROTOCOL_MAXIMUM_PEER_ID* = 0x00000FFF
57type
58  PAddress* = ptr TAddress
59  TAddress*{.pure, final.} = object
60    host*: cuint
61    port*: cushort
62
63  TPacketFlag*{.size: sizeof(cint).} = enum
64    FlagReliable = (1 shl 0),
65    FlagUnsequenced = (1 shl 1),
66    NoAllocate = (1 shl 2),
67    UnreliableFragment = (1 shl 3)
68
69  TENetListNode*{.pure, final.} = object
70      next*: ptr T_ENetListNode
71      previous*: ptr T_ENetListNode
72
73  PENetListIterator* = ptr TENetListNode
74  TENetList*{.pure, final.} = object
75    sentinel*: TENetListNode
76
77  T_ENetPacket*{.pure, final.} = object
78  TPacketFreeCallback* = proc (a2: ptr T_ENetPacket){.cdecl.}
79
80  PPacket* = ptr TPacket
81  TPacket*{.pure, final.} = object
82    referenceCount: csize_t
83    flags*: cint
84    data*: cstring#ptr cuchar
85    dataLength*: csize_t
86    freeCallback*: TPacketFreeCallback
87
88  PAcknowledgement* = ptr TAcknowledgement
89  TAcknowledgement*{.pure, final.} = object
90    acknowledgementList*: TEnetListNode
91    sentTime*: cuint
92    command*: TEnetProtocol
93
94  POutgoingCommand* = ptr TOutgoingCommand
95  TOutgoingCommand*{.pure, final.} = object
96    outgoingCommandList*: TEnetListNode
97    reliableSequenceNumber*: cushort
98    unreliableSequenceNumber*: cushort
99    sentTime*: cuint
100    roundTripTimeout*: cuint
101    roundTripTimeoutLimit*: cuint
102    fragmentOffset*: cuint
103    fragmentLength*: cushort
104    sendAttempts*: cushort
105    command*: TEnetProtocol
106    packet*: PPacket
107
108  PIncomingCommand* = ptr TIncomingCommand
109  TIncomingCommand*{.pure, final.} = object
110    incomingCommandList*: TEnetListNode
111    reliableSequenceNumber*: cushort
112    unreliableSequenceNumber*: cushort
113    command*: TEnetProtocol
114    fragmentCount*: cuint
115    fragmentsRemaining*: cuint
116    fragments*: ptr cuint
117    packet*: ptr TPacket
118
119  TPeerState*{.size: sizeof(cint).} = enum
120    ENET_PEER_STATE_DISCONNECTED = 0, ENET_PEER_STATE_CONNECTING = 1,
121    ENET_PEER_STATE_ACKNOWLEDGING_CONNECT = 2,
122    ENET_PEER_STATE_CONNECTION_PENDING = 3,
123    ENET_PEER_STATE_CONNECTION_SUCCEEDED = 4, ENET_PEER_STATE_CONNECTED = 5,
124    ENET_PEER_STATE_DISCONNECT_LATER = 6, ENET_PEER_STATE_DISCONNECTING = 7,
125    ENET_PEER_STATE_ACKNOWLEDGING_DISCONNECT = 8, ENET_PEER_STATE_ZOMBIE = 9
126
127  TENetProtocolCommand*{.size: sizeof(cint).} = enum
128    ENET_PROTOCOL_COMMAND_NONE = 0, ENET_PROTOCOL_COMMAND_ACKNOWLEDGE = 1,
129    ENET_PROTOCOL_COMMAND_CONNECT = 2,
130    ENET_PROTOCOL_COMMAND_VERIFY_CONNECT = 3,
131    ENET_PROTOCOL_COMMAND_DISCONNECT = 4, ENET_PROTOCOL_COMMAND_PING = 5,
132    ENET_PROTOCOL_COMMAND_SEND_RELIABLE = 6,
133    ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE = 7,
134    ENET_PROTOCOL_COMMAND_SEND_FRAGMENT = 8,
135    ENET_PROTOCOL_COMMAND_SEND_UNSEQUENCED = 9,
136    ENET_PROTOCOL_COMMAND_BANDWIDTH_LIMIT = 10,
137    ENET_PROTOCOL_COMMAND_THROTTLE_CONFIGURE = 11,
138    ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE_FRAGMENT = 12,
139    ENET_PROTOCOL_COMMAND_COUNT = 13, ENET_PROTOCOL_COMMAND_MASK = 0x0000000F
140  TENetProtocolFlag*{.size: sizeof(cint).} = enum
141    ENET_PROTOCOL_HEADER_SESSION_SHIFT = 12,
142    ENET_PROTOCOL_COMMAND_FLAG_UNSEQUENCED = (1 shl 6),
143    ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE = (1 shl 7),
144    ENET_PROTOCOL_HEADER_SESSION_MASK = (3 shl 12),
145    ENET_PROTOCOL_HEADER_FLAG_COMPRESSED = (1 shl 14),
146    ENET_PROTOCOL_HEADER_FLAG_SENT_TIME = (1 shl 15),
147    ENET_PROTOCOL_HEADER_FLAG_MASK = ENET_PROTOCOL_HEADER_FLAG_COMPRESSED.cint or
148        ENET_PROTOCOL_HEADER_FLAG_SENT_TIME.cint
149
150  TENetProtocolHeader*{.pure, final.} = object
151    peerID*: cushort
152    sentTime*: cushort
153
154  TENetProtocolCommandHeader*{.pure, final.} = object
155    command*: cuchar
156    channelID*: cuchar
157    reliableSequenceNumber*: cushort
158
159  TENetProtocolAcknowledge*{.pure, final.} = object
160    header*: TENetProtocolCommandHeader
161    receivedReliableSequenceNumber*: cushort
162    receivedSentTime*: cushort
163
164  TENetProtocolConnect*{.pure, final.} = object
165    header*: TENetProtocolCommandHeader
166    outgoingPeerID*: cushort
167    incomingSessionID*: cuchar
168    outgoingSessionID*: cuchar
169    mtu*: cuint
170    windowSize*: cuint
171    channelCount*: cuint
172    incomingBandwidth*: cuint
173    outgoingBandwidth*: cuint
174    packetThrottleInterval*: cuint
175    packetThrottleAcceleration*: cuint
176    packetThrottleDeceleration*: cuint
177    connectID*: cuint
178    data*: cuint
179
180  TENetProtocolVerifyConnect*{.pure, final.} = object
181    header*: TENetProtocolCommandHeader
182    outgoingPeerID*: cushort
183    incomingSessionID*: cuchar
184    outgoingSessionID*: cuchar
185    mtu*: cuint
186    windowSize*: cuint
187    channelCount*: cuint
188    incomingBandwidth*: cuint
189    outgoingBandwidth*: cuint
190    packetThrottleInterval*: cuint
191    packetThrottleAcceleration*: cuint
192    packetThrottleDeceleration*: cuint
193    connectID*: cuint
194
195  TENetProtocolBandwidthLimit*{.pure, final.} = object
196    header*: TENetProtocolCommandHeader
197    incomingBandwidth*: cuint
198    outgoingBandwidth*: cuint
199
200  TENetProtocolThrottleConfigure*{.pure, final.} = object
201    header*: TENetProtocolCommandHeader
202    packetThrottleInterval*: cuint
203    packetThrottleAcceleration*: cuint
204    packetThrottleDeceleration*: cuint
205
206  TENetProtocolDisconnect*{.pure, final.} = object
207    header*: TENetProtocolCommandHeader
208    data*: cuint
209
210  TENetProtocolPing*{.pure, final.} = object
211    header*: TENetProtocolCommandHeader
212
213  TENetProtocolSendReliable*{.pure, final.} = object
214    header*: TENetProtocolCommandHeader
215    dataLength*: cushort
216
217  TENetProtocolSendUnreliable*{.pure, final.} = object
218    header*: TENetProtocolCommandHeader
219    unreliableSequenceNumber*: cushort
220    dataLength*: cushort
221
222  TENetProtocolSendUnsequenced*{.pure, final.} = object
223    header*: TENetProtocolCommandHeader
224    unsequencedGroup*: cushort
225    dataLength*: cushort
226
227  TENetProtocolSendFragment*{.pure, final.} = object
228    header*: TENetProtocolCommandHeader
229    startSequenceNumber*: cushort
230    dataLength*: cushort
231    fragmentCount*: cuint
232    fragmentNumber*: cuint
233    totalLength*: cuint
234    fragmentOffset*: cuint
235
236  ## this is incomplete; need helper templates or something
237  ## ENetProtocol
238  TENetProtocol*{.pure, final.} = object
239    header*: TENetProtocolCommandHeader
240const
241  ENET_BUFFER_MAXIMUM* = (1 + 2 * ENET_PROTOCOL_MAXIMUM_PACKET_COMMANDS)
242  ENET_HOST_RECEIVE_BUFFER_SIZE          = 256 * 1024
243  ENET_HOST_SEND_BUFFER_SIZE             = 256 * 1024
244  ENET_HOST_BANDWIDTH_THROTTLE_INTERVAL  = 1000
245  ENET_HOST_DEFAULT_MTU                  = 1400
246
247  ENET_PEER_DEFAULT_ROUND_TRIP_TIME      = 500
248  ENET_PEER_DEFAULT_PACKET_THROTTLE      = 32
249  ENET_PEER_PACKET_THROTTLE_SCALE        = 32
250  ENET_PEER_PACKET_THROTTLE_COUNTER      = 7
251  ENET_PEER_PACKET_THROTTLE_ACCELERATION = 2
252  ENET_PEER_PACKET_THROTTLE_DECELERATION = 2
253  ENET_PEER_PACKET_THROTTLE_INTERVAL     = 5000
254  ENET_PEER_PACKET_LOSS_SCALE            = (1 shl 16)
255  ENET_PEER_PACKET_LOSS_INTERVAL         = 10000
256  ENET_PEER_WINDOW_SIZE_SCALE            = 64 * 1024
257  ENET_PEER_TIMEOUT_LIMIT                = 32
258  ENET_PEER_TIMEOUT_MINIMUM              = 5000
259  ENET_PEER_TIMEOUT_MAXIMUM              = 30000
260  ENET_PEER_PING_INTERVAL                = 500
261  ENET_PEER_UNSEQUENCED_WINDOWS          = 64
262  ENET_PEER_UNSEQUENCED_WINDOW_SIZE      = 1024
263  ENET_PEER_FREE_UNSEQUENCED_WINDOWS     = 32
264  ENET_PEER_RELIABLE_WINDOWS             = 16
265  ENET_PEER_RELIABLE_WINDOW_SIZE         = 0x1000
266  ENET_PEER_FREE_RELIABLE_WINDOWS        = 8
267
268when defined(linux) or true:
269  import posix
270  const
271    ENET_SOCKET_NULL*: cint = -1
272  type
273    TENetSocket* = cint
274    PEnetBuffer* = ptr object
275    TENetBuffer*{.pure, final.} = object
276      data*: pointer
277      dataLength*: csize_t
278    TENetSocketSet* = Tfd_set
279  ## see if these are different on win32, if not then get rid of these
280  template ENET_HOST_TO_NET_16*(value: untyped): untyped =
281    (htons(value))
282  template ENET_HOST_TO_NET_32*(value: untyped): untyped =
283    (htonl(value))
284  template ENET_NET_TO_HOST_16*(value: untyped): untyped =
285    (ntohs(value))
286  template ENET_NET_TO_HOST_32*(value: untyped): untyped =
287    (ntohl(value))
288
289  template ENET_SOCKETSET_EMPTY*(sockset: untyped): untyped =
290    FD_ZERO(addr((sockset)))
291  template ENET_SOCKETSET_ADD*(sockset, socket: untyped): untyped =
292    FD_SET(socket, addr((sockset)))
293  template ENET_SOCKETSET_REMOVE*(sockset, socket: untyped): untyped =
294    FD_CLEAR(socket, addr((sockset)))
295  template ENET_SOCKETSET_CHECK*(sockset, socket: untyped): untyped =
296    FD_ISSET(socket, addr((sockset)))
297
298when defined(windows):
299  ## put the content of win32.h in here
300
301
302type
303  PChannel* = ptr TChannel
304  TChannel*{.pure, final.} = object
305    outgoingReliableSequenceNumber*: cushort
306    outgoingUnreliableSequenceNumber*: cushort
307    usedReliableWindows*: cushort
308    reliableWindows*: array[0..ENET_PEER_RELIABLE_WINDOWS - 1, cushort]
309    incomingReliableSequenceNumber*: cushort
310    incomingUnreliableSequenceNumber*: cushort
311    incomingReliableCommands*: TENetList
312    incomingUnreliableCommands*: TENetList
313
314  PPeer* = ptr TPeer
315  TPeer*{.pure, final.} = object
316    dispatchList*: TEnetListNode
317    host*: ptr THost
318    outgoingPeerID*: cushort
319    incomingPeerID*: cushort
320    connectID*: cuint
321    outgoingSessionID*: cuchar
322    incomingSessionID*: cuchar
323    address*: TAddress
324    data*: pointer
325    state*: TPeerState
326    channels*: PChannel
327    channelCount*: csize_t
328    incomingBandwidth*: cuint
329    outgoingBandwidth*: cuint
330    incomingBandwidthThrottleEpoch*: cuint
331    outgoingBandwidthThrottleEpoch*: cuint
332    incomingDataTotal*: cuint
333    outgoingDataTotal*: cuint
334    lastSendTime*: cuint
335    lastReceiveTime*: cuint
336    nextTimeout*: cuint
337    earliestTimeout*: cuint
338    packetLossEpoch*: cuint
339    packetsSent*: cuint
340    packetsLost*: cuint
341    packetLoss*: cuint
342    packetLossVariance*: cuint
343    packetThrottle*: cuint
344    packetThrottleLimit*: cuint
345    packetThrottleCounter*: cuint
346    packetThrottleEpoch*: cuint
347    packetThrottleAcceleration*: cuint
348    packetThrottleDeceleration*: cuint
349    packetThrottleInterval*: cuint
350    lastRoundTripTime*: cuint
351    lowestRoundTripTime*: cuint
352    lastRoundTripTimeVariance*: cuint
353    highestRoundTripTimeVariance*: cuint
354    roundTripTime*: cuint
355    roundTripTimeVariance*: cuint
356    mtu*: cuint
357    windowSize*: cuint
358    reliableDataInTransit*: cuint
359    outgoingReliableSequenceNumber*: cushort
360    acknowledgements*: TENetList
361    sentReliableCommands*: TENetList
362    sentUnreliableCommands*: TENetList
363    outgoingReliableCommands*: TENetList
364    outgoingUnreliableCommands*: TENetList
365    dispatchedCommands*: TENetList
366    needsDispatch*: cint
367    incomingUnsequencedGroup*: cushort
368    outgoingUnsequencedGroup*: cushort
369    unsequencedWindow*: array[0..ENET_PEER_UNSEQUENCED_WINDOW_SIZE div 32 - 1,
370                              cuint]
371    eventData*: cuint
372
373  PCompressor* = ptr TCompressor
374  TCompressor*{.pure, final.} = object
375    context*: pointer
376    compress*: proc (context: pointer; inBuffers: ptr TEnetBuffer;
377                     inBufferCount: csize_t; inLimit: csize_t;
378                     outData: ptr cuchar; outLimit: csize_t): csize_t{.cdecl.}
379    decompress*: proc (context: pointer; inData: ptr cuchar; inLimit: csize_t;
380                       outData: ptr cuchar; outLimit: csize_t): csize_t{.cdecl.}
381    destroy*: proc (context: pointer){.cdecl.}
382
383  TChecksumCallback* = proc (buffers: ptr TEnetBuffer; bufferCount: csize_t): cuint{.
384      cdecl.}
385
386  PHost* = ptr THost
387  THost*{.pure, final.} = object
388    socket*: TEnetSocket
389    address*: TAddress
390    incomingBandwidth*: cuint
391    outgoingBandwidth*: cuint
392    bandwidthThrottleEpoch*: cuint
393    mtu*: cuint
394    randomSeed*: cuint
395    recalculateBandwidthLimits*: cint
396    peers*: ptr TPeer
397    peerCount*: csize_t
398    channelLimit*: csize_t
399    serviceTime*: cuint
400    dispatchQueue*: TEnetList
401    continueSending*: cint
402    packetSize*: csize_t
403    headerFlags*: cushort
404    commands*: array[0..ENET_PROTOCOL_MAXIMUM_PACKET_COMMANDS - 1,
405                     TEnetProtocol]
406    commandCount*: csize_t
407    buffers*: array[0..ENET_BUFFER_MAXIMUM - 1, TEnetBuffer]
408    bufferCount*: csize_t
409    checksum*: TChecksumCallback
410    compressor*: TCompressor
411    packetData*: array[0..ENET_PROTOCOL_MAXIMUM_MTU - 1,
412                       array[0..2 - 1, cuchar]]
413    receivedAddress*: TAddress
414    receivedData*: ptr cuchar
415    receivedDataLength*: csize_t
416    totalSentData*: cuint
417    totalSentPackets*: cuint
418    totalReceivedData*: cuint
419    totalReceivedPackets*: cuint
420
421  TEventType*{.size: sizeof(cint).} = enum
422    EvtNone = 0, EvtConnect = 1,
423    EvtDisconnect = 2, EvtReceive = 3
424  PEvent* = ptr TEvent
425  TEvent*{.pure, final.} = object
426    kind*: TEventType
427    peer*: ptr TPeer
428    channelID*: cuchar
429    data*: cuint
430    packet*: ptr TPacket
431
432  TENetCallbacks*{.pure, final.} = object
433    malloc*: proc (size: csize_t): pointer{.cdecl.}
434    free*: proc (memory: pointer){.cdecl.}
435    no_memory*: proc (){.cdecl.}
436
437{.push callConv:cdecl.}
438proc enet_malloc*(a2: csize_t): pointer{.
439  importc: "enet_malloc", dynlib: Lib.}
440proc enet_free*(a2: pointer){.
441  importc: "enet_free", dynlib: Lib.}
442
443proc enetInit*(): cint{.
444  importc: "enet_initialize", dynlib: Lib.}
445proc enetInit*(version: TVersion; inits: ptr TENetCallbacks): cint{.
446  importc: "enet_initialize_with_callbacks", dynlib: Lib.}
447proc enetDeinit*(){.
448  importc: "enet_deinitialize", dynlib: Lib.}
449proc enet_time_get*(): cuint{.
450  importc: "enet_time_get", dynlib: Lib.}
451proc enet_time_set*(a2: cuint){.
452  importc: "enet_time_set", dynlib: Lib.}
453
454#enet docs are pretty lacking, i'm not sure what the names of these arguments should be
455proc createSocket*(kind: TSocketType): TEnetSocket{.
456  importc: "enet_socket_create", dynlib: Lib.}
457proc bindTo*(socket: TEnetSocket; address: var TAddress): cint{.
458  importc: "enet_socket_bind", dynlib: Lib.}
459proc bindTo*(socket: TEnetSocket; address: ptr TAddress): cint{.
460  importc: "enet_socket_bind", dynlib: Lib.}
461proc listen*(socket: TEnetSocket; a3: cint): cint{.
462  importc: "enet_socket_listen", dynlib: Lib.}
463proc accept*(socket: TEnetSocket; address: var TAddress): TEnetSocket{.
464  importc: "enet_socket_accept", dynlib: Lib.}
465proc accept*(socket: TEnetSocket; address: ptr TAddress): TEnetSocket{.
466  importc: "enet_socket_accept", dynlib: Lib.}
467proc connect*(socket: TEnetSocket; address: var TAddress): cint{.
468  importc: "enet_socket_connect", dynlib: Lib.}
469proc connect*(socket: TEnetSocket; address: ptr TAddress): cint{.
470  importc: "enet_socket_connect", dynlib: Lib.}
471proc send*(socket: TEnetSocket; address: var TAddress; buffer: ptr TEnetBuffer; size: csize_t): cint{.
472  importc: "enet_socket_send", dynlib: Lib.}
473proc send*(socket: TEnetSocket; address: ptr TAddress; buffer: ptr TEnetBuffer; size: csize_t): cint{.
474  importc: "enet_socket_send", dynlib: Lib.}
475proc receive*(socket: TEnetSocket; address: var TAddress;
476               buffer: ptr TEnetBuffer; size: csize_t): cint{.
477  importc: "enet_socket_receive", dynlib: Lib.}
478proc receive*(socket: TEnetSocket; address: ptr TAddress;
479               buffer: ptr TEnetBuffer; size: csize_t): cint{.
480  importc: "enet_socket_receive", dynlib: Lib.}
481proc wait*(socket: TEnetSocket; a3: ptr cuint; a4: cuint): cint{.
482  importc: "enet_socket_wait", dynlib: Lib.}
483proc setOption*(socket: TEnetSocket; a3: TSocketOption; a4: cint): cint{.
484  importc: "enet_socket_set_option", dynlib: Lib.}
485proc destroy*(socket: TEnetSocket){.
486  importc: "enet_socket_destroy", dynlib: Lib.}
487proc select*(socket: TEnetSocket; a3: ptr TENetSocketSet;
488              a4: ptr TENetSocketSet; a5: cuint): cint{.
489  importc: "enet_socketset_select", dynlib: Lib.}
490
491proc setHost*(address: PAddress; hostName: cstring): cint{.
492  importc: "enet_address_set_host", dynlib: Lib.}
493proc setHost*(address: var TAddress; hostName: cstring): cint{.
494  importc: "enet_address_set_host", dynlib: Lib.}
495proc getHostIP*(address: var TAddress; hostName: cstring; nameLength: csize_t): cint{.
496  importc: "enet_address_get_host_ip", dynlib: Lib.}
497proc getHost*(address: var TAddress; hostName: cstring; nameLength: csize_t): cint{.
498  importc: "enet_address_get_host", dynlib: Lib.}
499
500## Call the above two funcs but trim the result string
501proc getHostIP*(address: var TAddress; hostName: var string; nameLength: csize_t): cint{.inline.} =
502  hostName.setLen nameLength
503  result = getHostIP(address, cstring(hostName), nameLength)
504  if result == 0:
505    hostName.setLen(len(cstring(hostName)))
506proc getHost*(address: var TAddress; hostName: var string; nameLength: csize_t): cint{.inline.} =
507  hostName.setLen nameLength
508  result = getHost(address, cstring(hostName), nameLength)
509  if result == 0:
510    hostName.setLen(len(cstring(hostName)))
511
512proc createPacket*(data: pointer; len: csize_t; flag: TPacketFlag): PPacket{.
513  importc: "enet_packet_create", dynlib: Lib.}
514proc destroy*(packet: PPacket){.
515  importc: "enet_packet_destroy", dynlib: Lib.}
516proc resize*(packet: PPacket; dataLength: csize_t): cint{.
517  importc: "enet_packet_resize", dynlib: Lib.}
518
519proc crc32*(buffers: ptr TEnetBuffer; bufferCount: csize_t): cuint{.
520  importc: "enet_crc32", dynlib: Lib.}
521
522proc createHost*(address: ptr TAddress; maxConnections, maxChannels: csize_t; downSpeed, upSpeed: cuint): PHost{.
523  importc: "enet_host_create", dynlib: Lib.}
524proc createHost*(address: var TAddress; maxConnections, maxChannels: csize_t; downSpeed, upSpeed: cuint): PHost{.
525  importc: "enet_host_create", dynlib: Lib.}
526proc destroy*(host: PHost){.
527  importc: "enet_host_destroy", dynlib: Lib.}
528proc connect*(host: PHost; address: ptr TAddress; channelCount: csize_t; data: cuint): PPeer{.
529  importc: "enet_host_connect", dynlib: Lib.}
530proc connect*(host: PHost; address: var TAddress; channelCount: csize_t; data: cuint): PPeer{.
531  importc: "enet_host_connect", dynlib: Lib.}
532
533proc checkEvents*(host: PHost; event: var TEvent): cint{.
534  importc: "enet_host_check_events", dynlib: Lib.}
535proc checkEvents*(host: PHost; event: ptr TEvent): cint{.
536  importc: "enet_host_check_events", dynlib: Lib.}
537proc hostService*(host: PHost; event: var TEvent; timeout: cuint): cint{.
538  importc: "enet_host_service", dynlib: Lib.}
539proc hostService*(host: PHost; event: ptr TEvent; timeout: cuint): cint{.
540  importc: "enet_host_service", dynlib: Lib.}
541proc flush*(host: PHost){.
542  importc: "enet_host_flush", dynlib: Lib.}
543proc broadcast*(host: PHost; channelID: cuchar; packet: PPacket){.
544  importc: "enet_host_broadcast", dynlib: Lib.}
545proc compress*(host: PHost; compressor: PCompressor){.
546  importc: "enet_host_compress", dynlib: Lib.}
547proc compressWithRangeCoder*(host: PHost): cint{.
548  importc: "enet_host_compress_with_range_coder", dynlib: Lib.}
549proc channelLimit*(host: PHost; channelLimit: csize_t){.
550  importc: "enet_host_channel_limit", dynlib: Lib.}
551proc bandwidthLimit*(host: PHost; incoming, outgoing: cuint){.
552  importc: "enet_host_bandwidth_limit", dynlib: Lib.}
553proc bandwidthThrottle*(host: PHost){.
554  importc: "enet_host_bandwidth_throttle", dynlib: Lib.}
555
556
557proc send*(peer: PPeer; channel: cuchar; packet: PPacket): cint{.
558  importc: "enet_peer_send", dynlib: Lib.}
559proc receive*(peer: PPeer; channelID: ptr cuchar): PPacket{.
560  importc: "enet_peer_receive", dynlib: Lib.}
561proc ping*(peer: PPeer){.
562  importc: "enet_peer_ping", dynlib: Lib.}
563proc reset*(peer: PPeer){.
564  importc: "enet_peer_reset", dynlib: Lib.}
565proc disconnect*(peer: PPeer; a3: cuint){.
566  importc: "enet_peer_disconnect", dynlib: Lib.}
567proc disconnectNow*(peer: PPeer; a3: cuint){.
568  importc: "enet_peer_disconnect_now", dynlib: Lib.}
569proc disconnectLater*(peer: PPeer; a3: cuint){.
570  importc: "enet_peer_disconnect_later", dynlib: Lib.}
571proc throttleConfigure*(peer: PPeer; interval, acceleration, deceleration: cuint){.
572  importc: "enet_peer_throttle_configure", dynlib: Lib.}
573proc throttle*(peer: PPeer; rtt: cuint): cint{.
574  importc: "enet_peer_throttle", dynlib: Lib.}
575proc resetQueues*(peer: PPeer){.
576  importc: "enet_peer_reset_queues", dynlib: Lib.}
577proc setupOutgoingCommand*(peer: PPeer; outgoingCommand: POutgoingCommand){.
578  importc: "enet_peer_setup_outgoing_command", dynlib: Lib.}
579
580proc queueOutgoingCommand*(peer: PPeer; command: ptr TEnetProtocol;
581          packet: PPacket; offset: cuint; length: cushort): POutgoingCommand{.
582  importc: "enet_peer_queue_outgoing_command", dynlib: Lib.}
583proc queueIncomingCommand*(peer: PPeer; command: ptr TEnetProtocol;
584                    packet: PPacket; fragmentCount: cuint): PIncomingCommand{.
585  importc: "enet_peer_queue_incoming_command", dynlib: Lib.}
586proc queueAcknowledgement*(peer: PPeer; command: ptr TEnetProtocol;
587                            sentTime: cushort): PAcknowledgement{.
588  importc: "enet_peer_queue_acknowledgement", dynlib: Lib.}
589proc dispatchIncomingUnreliableCommands*(peer: PPeer; channel: PChannel){.
590  importc: "enet_peer_dispatch_incoming_unreliable_commands", dynlib: Lib.}
591proc dispatchIncomingReliableCommands*(peer: PPeer; channel: PChannel){.
592  importc: "enet_peer_dispatch_incoming_reliable_commands", dynlib: Lib.}
593
594proc createRangeCoder*(): pointer{.
595  importc: "enet_range_coder_create", dynlib: Lib.}
596proc rangeCoderDestroy*(context: pointer){.
597  importc: "enet_range_coder_destroy", dynlib: Lib.}
598proc rangeCoderCompress*(context: pointer; inBuffers: PEnetBuffer; inLimit,
599               bufferCount: csize_t; outData: cstring; outLimit: csize_t): csize_t{.
600  importc: "enet_range_coder_compress", dynlib: Lib.}
601proc rangeCoderDecompress*(context: pointer; inData: cstring; inLimit: csize_t;
602                            outData: cstring; outLimit: csize_t): csize_t{.
603  importc: "enet_range_coder_decompress", dynlib: Lib.}
604proc protocolCommandSize*(commandNumber: cuchar): csize_t{.
605  importc: "enet_protocol_command_size", dynlib: Lib.}
606
607{.pop.}
608
609from hashes import `!$`, `!&`, Hash, hash
610proc hash*(x: TAddress): Hash {.nimcall, noSideEffect.} =
611  result = !$(hash(x.host.int32) !& hash(x.port.int16))
612