mirror of
https://github.com/odin-lang/Odin.git
synced 2026-06-14 14:23:43 +00:00
403 lines
14 KiB
Odin
403 lines
14 KiB
Odin
// Bindings for [[ ENet ; https://github.com/lsalzman/enet ]].
|
|
package ENet
|
|
|
|
when ODIN_OS == .Windows {
|
|
when ODIN_ARCH == .amd64 {
|
|
foreign import ENet {
|
|
"lib/enet64.lib",
|
|
"system:Ws2_32.lib",
|
|
"system:Winmm.lib",
|
|
}
|
|
} else {
|
|
foreign import ENet {
|
|
"lib/enet.lib",
|
|
"system:Ws2_32.lib",
|
|
"system:Winmm.lib",
|
|
}
|
|
}
|
|
} else {
|
|
foreign import ENet "system:enet"
|
|
}
|
|
|
|
VERSION_MAJOR :: u8(1)
|
|
VERSION_MINOR :: u8(3)
|
|
VERSION_PATCH :: u8(17)
|
|
|
|
VERSION_CREATE :: #force_inline proc "contextless" (major, minor, patch: u8) -> u32 {
|
|
return (u32(major) << 16) | (u32(minor) << 8) | u32(patch)
|
|
}
|
|
|
|
VERSION_GET_MAJOR :: #force_inline proc "contextless" (version: u32) -> u8 {
|
|
return u8((version >> 16) & 0xff)
|
|
}
|
|
VERSION_GET_MINOR :: #force_inline proc "contextless" (version: u32) -> u8 {
|
|
return u8((version >> 8) & 0xff)
|
|
}
|
|
VERSION_GET_PATCH :: #force_inline proc "contextless" (version: u32) -> u8 {
|
|
return u8(version & 0xff)
|
|
}
|
|
|
|
// Odin does not have "macros" or compile-time evaluation of functions, so the
|
|
// following is just the same as.
|
|
// VERSION :: VERSION_CREATE(VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH);
|
|
VERSION :: (u32(VERSION_MAJOR) << 16) | (u32(VERSION_MINOR) << 8) | u32(VERSION_PATCH)
|
|
|
|
// Network byte order is always Big Endian. Instead of using the method ENet
|
|
// uses (leveraging {n,h}to{n,h}{s,l}), we can just use Odin's endianess types
|
|
// to get the correct byte swaps, if any.
|
|
HOST_TO_NET_16 :: #force_inline proc "contextless" (value: u16) -> u16 {
|
|
return transmute(u16)u16be(value)
|
|
}
|
|
|
|
HOST_TO_NET_32 :: #force_inline proc "contextless" (value: u32) -> u32 {
|
|
return transmute(u32)u32be(value)
|
|
}
|
|
|
|
NET_TO_HOST_16 :: #force_inline proc "contextless" (value: u16) -> u16 {
|
|
return u16(transmute(u16be)value)
|
|
}
|
|
|
|
NET_TO_HOST_32 :: #force_inline proc "contextless" (value: u32) -> u32 {
|
|
return u32(transmute(u32be)value)
|
|
}
|
|
|
|
Version :: u32
|
|
|
|
SocketType :: enum i32 {
|
|
STREAM = 1,
|
|
DATAGRAM = 2,
|
|
}
|
|
|
|
SocketWait :: enum i32 {
|
|
NONE = 0,
|
|
SEND = 1 << 0,
|
|
RECEIVE = 1 << 1,
|
|
INTERRUPT = 1 << 2,
|
|
}
|
|
|
|
SocketOption :: enum i32 {
|
|
NONBLOCK = 1,
|
|
BROADCAST = 2,
|
|
RCVBUF = 3,
|
|
SNDBUF = 4,
|
|
REUSEADDR = 5,
|
|
RCVTIMEO = 6,
|
|
SNDTIMEO = 7,
|
|
ERROR = 8,
|
|
NODELAY = 9,
|
|
}
|
|
|
|
SocketShutdown :: enum i32 {
|
|
READ = 0,
|
|
WRITE = 1,
|
|
READ_WRITE = 2,
|
|
}
|
|
|
|
HOST_ANY :: u32(0)
|
|
HOST_BROADCAST :: u32(0xffffffff)
|
|
PORT_ANY :: u16(0)
|
|
|
|
Address :: struct {
|
|
host: u32,
|
|
port: u16,
|
|
}
|
|
|
|
PacketFlags :: bit_set[PacketFlag; i32]
|
|
PacketFlag :: enum i32 {
|
|
RELIABLE = 0,
|
|
UNSEQUENCED = 1,
|
|
NO_ALLOCATE = 2,
|
|
UNRELIABLE_FRAGMENT = 3,
|
|
FLAG_SENT = 8,
|
|
}
|
|
|
|
PacketFreeCallback :: proc "c" (packet: ^Packet)
|
|
|
|
Packet :: struct {
|
|
referenceCount: uint,
|
|
flags: u32,
|
|
data: [^]u8 `fmt:"v,dataLength"`,
|
|
dataLength: uint,
|
|
freeCallback: PacketFreeCallback,
|
|
userData: rawptr,
|
|
}
|
|
|
|
Acknowledgment :: struct {
|
|
acknowledgementList: ListNode,
|
|
sentTime: u32,
|
|
command: Protocol,
|
|
}
|
|
|
|
OutgoingCommand :: struct {
|
|
outgoingCommandList: ListNode,
|
|
reliableSequenceNumber: u16,
|
|
unreliableSequenceNumber: u16,
|
|
sentTime: u32,
|
|
roundTripTimeout: u32,
|
|
roundTripTimeoutLimit: u32,
|
|
fragmentOffset: u32,
|
|
fragmentLength: u16,
|
|
sendAttempts: u16,
|
|
command: Protocol,
|
|
packet: ^Packet,
|
|
}
|
|
|
|
IncomingCommand :: struct {
|
|
incomingCommandList: ListNode,
|
|
reliableSequenceNumber: u16,
|
|
unreliableSequenceNumber: u16,
|
|
command: Protocol,
|
|
fragmentCount: u32,
|
|
fragmentsRemaining: u32,
|
|
fragments: [^]u32 `fmt:"v,fragmentCount"`,
|
|
packet: ^Packet,
|
|
}
|
|
|
|
PeerState :: enum i32 {
|
|
DISCONNECTED,
|
|
CONNECTING,
|
|
ACKNOWLEDGING_CONNECT,
|
|
CONNECTION_PENDING,
|
|
CONNECTION_SUCCEEDED,
|
|
CONNECTED,
|
|
DISCONNECT_LATER,
|
|
DISCONNECTING,
|
|
ACKNOWLEDGING_DISCONNECT,
|
|
ZOMBIE,
|
|
}
|
|
|
|
BUFFER_MAXIMUM :: (1 + 2 * PROTOCOL_MAXIMUM_PACKET_COMMANDS)
|
|
|
|
HOST_RECEIVE_BUFFER_SIZE :: 256 * 1024
|
|
HOST_SEND_BUFFER_SIZE :: 256 * 1024
|
|
HOST_BANDWIDTH_THROTTLE_INTERVAL :: 1000
|
|
HOST_DEFAULT_MTU :: 1400
|
|
HOST_DEFAULT_MAXIMUM_PACKET_SIZE :: 32 * 1024 * 1024
|
|
HOST_DEFAULT_MAXIMUM_WAITING_DATA :: 32 * 1024 * 1024
|
|
|
|
PEER_DEFAULT_ROUND_TRIP_TIME :: 500
|
|
PEER_DEFAULT_PACKET_THROTTLE :: 32
|
|
PEER_PACKET_THROTTLE_SCALE :: 32
|
|
PEER_PACKET_THROTTLE_COUNTER :: 7
|
|
PEER_PACKET_THROTTLE_ACCELERATION :: 2
|
|
PEER_PACKET_THROTTLE_DECELERATION :: 2
|
|
PEER_PACKET_THROTTLE_INTERVAL :: 5000
|
|
PEER_PACKET_LOSS_SCALE :: 1 << 16
|
|
PEER_PACKET_LOSS_INTERVAL :: 10000
|
|
PEER_WINDOW_SIZE_SCALE :: 64 * 1024
|
|
PEER_TIMEOUT_LIMIT :: 32
|
|
PEER_TIMEOUT_MINIMUM :: 5000
|
|
PEER_TIMEOUT_MAXIMUM :: 30000
|
|
PEER_PING_INTERVAL :: 500
|
|
PEER_UNSEQUENCED_WINDOWS :: 64
|
|
PEER_UNSEQUENCED_WINDOW_SIZE :: 1024
|
|
PEER_FREE_UNSEQUENCED_WINDOWS :: 32
|
|
PEER_RELIABLE_WINDOWS :: 16
|
|
PEER_RELIABLE_WINDOW_SIZE :: 0x1000
|
|
PEER_FREE_RELIABLE_WINDOWS :: 8
|
|
|
|
Channel :: struct {
|
|
outgoingReliableSequenceNumber: u16,
|
|
outgoingUnreliableSequenceNumber: u16,
|
|
usedReliableWindows: u16,
|
|
reliableWindows: [PEER_RELIABLE_WINDOWS]u16,
|
|
incomingReliableSequenceNumber: u16,
|
|
incomingUnreliableSequenceNumber: u16,
|
|
incomingReliableCommands: List,
|
|
incomingUnreliableCommands: List,
|
|
}
|
|
|
|
PeerFlag :: enum i32 {
|
|
NEEDS_DISPATCH,
|
|
}
|
|
|
|
Peer :: struct {
|
|
dispatchList: ListNode,
|
|
host: ^Host,
|
|
outgoingPeerID: u16,
|
|
incomingPeerID: u16,
|
|
connectID: u32,
|
|
outgoingSessionID: u8,
|
|
incomingSessionID: u8,
|
|
address: Address,
|
|
data: rawptr,
|
|
state: PeerState,
|
|
channels: [^]Channel `fmt:"v,channelCount"`,
|
|
channelCount: uint,
|
|
incomingBandwidth: u32,
|
|
outgoingBandwidth: u32,
|
|
incomingBandwidthThrottleEpoch: u32,
|
|
outgoingBandwidthThrottleEpoch: u32,
|
|
incomingDataTotal: u32,
|
|
outgoingDataTotal: u32,
|
|
lastSendTime: u32,
|
|
lastReceiveTime: u32,
|
|
nextTimeout: u32,
|
|
earliestTimeout: u32,
|
|
packetLossEpoch: u32,
|
|
packetsSent: u32,
|
|
packetsLost: u32,
|
|
packetLoss: u32,
|
|
packetLossVariance: u32,
|
|
packetThrottle: u32,
|
|
packetThrottleLimit: u32,
|
|
packetThrottleCounter: u32,
|
|
packetThrottleEpoch: u32,
|
|
packetThrottleAcceleration: u32,
|
|
packetThrottleDeceleration: u32,
|
|
packetThrottleInterval: u32,
|
|
pingInterval: u32,
|
|
timeoutLimit: u32,
|
|
timeoutMinimum: u32,
|
|
timeoutMaximum: u32,
|
|
lastRoundTripTime: u32,
|
|
lowestRoundTripTime: u32,
|
|
lastRoundTripTimeVariance: u32,
|
|
highestRoundTripTimeVariance: u32,
|
|
roundTripTime: u32,
|
|
roundTripTimeVariance: u32,
|
|
mtu: u32,
|
|
windowSize: u32,
|
|
reliableDataInTransit: u32,
|
|
outgoingReliableSequenceNumber: u16,
|
|
acknowledgements: List,
|
|
sentReliableCommands: List,
|
|
sentUnreliableCommands: List,
|
|
outgoingCommands: List,
|
|
dispatchedCommands: List,
|
|
flags: u16,
|
|
reserved: u16,
|
|
incomingUnsequencedGroup: u16,
|
|
outgoingUnsequencedGroup: u16,
|
|
unsequencedWindow: [PEER_UNSEQUENCED_WINDOW_SIZE / 32]u32,
|
|
eventData: u32,
|
|
totalWaitingData: uint,
|
|
}
|
|
|
|
Compressor :: struct {
|
|
context_: rawptr,
|
|
compress: proc "c" (context_: rawptr, inBuffers: [^]Buffer, inBufferCount: uint, inLimit: uint, outData: [^]u8, outLimit: uint) -> uint,
|
|
decompress: proc "c" (context_: rawptr, inData: [^]u8, inLimit: uint, outData: [^]u8, outLimit: uint) -> uint,
|
|
destroy: proc "c" (context_: rawptr),
|
|
}
|
|
|
|
ChecksumCallback :: proc "c" (buffers: [^]Buffer, bufferCount: uint) -> u32
|
|
InterceptCallback :: proc "c" (host: ^Host, event: ^Event) -> i32
|
|
|
|
Host :: struct {
|
|
socket: Socket,
|
|
address: Address,
|
|
incomingBandwidth: u32,
|
|
outgoingBandwidth: u32,
|
|
bandwidthThrottleEpoch: u32,
|
|
mtu: u32,
|
|
randomSeed: u32,
|
|
recalculateBandwidthLimits: i32,
|
|
peers: [^]Peer `fmt:"v,peerCount"`,
|
|
peerCount: uint,
|
|
channelLimit: uint,
|
|
serviceTime: u32,
|
|
dispatchQueue: List,
|
|
continueSending: i32,
|
|
packetSize: uint,
|
|
headerFlags: u16,
|
|
commands: [PROTOCOL_MAXIMUM_PACKET_COMMANDS]Protocol,
|
|
commandCount: uint,
|
|
buffers: [BUFFER_MAXIMUM]Buffer,
|
|
bufferCount: uint,
|
|
checksum: ChecksumCallback,
|
|
compressor: Compressor,
|
|
packetData: [2][PROTOCOL_MAXIMUM_MTU]u8,
|
|
receivedAddress: Address,
|
|
receivedData: [^]u8 `fmt:"v,receivedDataLength"`,
|
|
receivedDataLength: uint,
|
|
totalSentData: u32,
|
|
totalSentPackets: u32,
|
|
totalReceivedData: u32,
|
|
totalReceivedPackets: u32,
|
|
intercept: InterceptCallback,
|
|
connectedPeers: uint,
|
|
bandwidthLimitedPeers: uint,
|
|
duplicatePeers: uint,
|
|
maximumPacketSize: uint,
|
|
maximumWaitingData: uint,
|
|
}
|
|
|
|
EventType :: enum i32 {
|
|
NONE = 0,
|
|
CONNECT = 1,
|
|
DISCONNECT = 2,
|
|
RECEIVE = 3,
|
|
}
|
|
|
|
Event :: struct {
|
|
type: EventType,
|
|
peer: ^Peer,
|
|
channelID: u8,
|
|
data: u32,
|
|
packet: ^Packet,
|
|
}
|
|
|
|
@(default_calling_convention="c", link_prefix="enet_")
|
|
foreign ENet {
|
|
initialize :: proc() -> i32 ---
|
|
initialize_with_callbacks :: proc(version: Version, inits: ^Callbacks) -> i32 ---
|
|
deinitialize :: proc() ---
|
|
linked_version :: proc() -> Version ---
|
|
time_get :: proc() -> u32 ---
|
|
time_set :: proc(newTimeBase: u32) ---
|
|
|
|
socket_create :: proc(SocketType) -> Socket ---
|
|
socket_bind :: proc(socket: Socket, address: ^Address) -> i32 ---
|
|
socket_get_address :: proc(socket: Socket, address: ^Address) -> i32 ---
|
|
socket_listen :: proc(socket: Socket, backlog: i32) -> i32 ---
|
|
socket_accept :: proc(socket: Socket, address: ^Address) -> Socket ---
|
|
socket_connect :: proc(socket: Socket, address: ^Address) -> i32 ---
|
|
socket_send :: proc(socket: Socket, address: ^Address, buffers: [^]Buffer, bufferCount: uint) -> i32 ---
|
|
socket_receive :: proc(socket: Socket, address: ^Address, buffers: [^]Buffer, bufferCount: uint) -> i32 ---
|
|
socket_wait :: proc(socket: Socket, condition: ^u32, timeout: u32) -> i32 ---
|
|
socket_set_option :: proc(socket: Socket, option: SocketOption, value: i32) -> i32 ---
|
|
socket_get_option :: proc(socket: Socket, option: SocketOption, value: ^i32) -> i32 ---
|
|
socket_shutdown :: proc(socket: Socket, how: SocketShutdown) -> i32 ---
|
|
socket_destroy :: proc(socket: Socket) ---
|
|
socketset_select :: proc(socket: Socket, readSet: ^SocketSet, writeSet: ^SocketSet, timeout: u32) -> i32 ---
|
|
|
|
address_set_host_ip :: proc(address: ^Address, hostName: cstring) -> i32 ---
|
|
address_set_host :: proc(address: ^Address, hostName: cstring) -> i32 ---
|
|
address_get_host_ip :: proc(address: ^Address, hostName: [^]u8, nameLength: uint) -> i32 ---
|
|
address_get_host :: proc(address: ^Address, hostName: [^]u8, nameLength: uint) -> i32 ---
|
|
|
|
packet_create :: proc(data: rawptr, dataLength: uint, flags: PacketFlags) -> ^Packet ---
|
|
packet_destroy :: proc(packet: ^Packet) ---
|
|
packet_resize :: proc(packet: ^Packet, dataLength: uint) -> i32 ---
|
|
crc32 :: proc(buffers: [^]Buffer, bufferCount: uint) -> u32 ---
|
|
|
|
host_create :: proc(address: ^Address, peerCount: uint, channelLimit: uint, incomingBandwidth: u32, outgoingBandwidth: u32) -> ^Host ---
|
|
host_destroy :: proc(host: ^Host) ---
|
|
host_connect :: proc(host: ^Host, address: ^Address, channelCount: uint, data: u32) -> ^Peer ---
|
|
host_check_events :: proc(host: ^Host, event: ^Event) -> i32 ---
|
|
host_service :: proc(host: ^Host, event: ^Event, timeout: u32) -> i32 ---
|
|
host_flush :: proc(host: ^Host) ---
|
|
host_broadcast :: proc(host: ^Host, channelID: u8, packet: ^Packet) ---
|
|
host_compress :: proc(host: ^Host, compressor: ^Compressor) ---
|
|
host_compress_with_range_coder :: proc(host: ^Host) -> i32 ---
|
|
host_channel_limit :: proc(host: ^Host, channelLimit: uint) ---
|
|
host_bandwidth_limit :: proc(host: ^Host, incomingBandwidth: u32, outgoingBandwidth: u32) ---
|
|
|
|
peer_send :: proc(peer: ^Peer, channelID: u8, packet: ^Packet) -> i32 ---
|
|
peer_receive :: proc(peer: ^Peer, channelID: ^u8) -> ^Packet ---
|
|
peer_ping :: proc(peer: ^Peer) ---
|
|
peer_ping_interval :: proc(peer: ^Peer, pingInterval: u32) ---
|
|
peer_timeout :: proc(peer: ^Peer, timoutLimit: u32, timeoutMinimum: u32, timeoutMaximum: u32) ---
|
|
peer_reset :: proc(peer: ^Peer) ---
|
|
peer_disconnect :: proc(peer: ^Peer, data: u32) ---
|
|
peer_disconnect_now :: proc(peer: ^Peer, data: u32) ---
|
|
peer_disconnect_later :: proc(peer: ^Peer, data: u32) ---
|
|
peer_throttle_configure :: proc(peer: ^Peer, interval: u32, acceleration: u32, deceleration: u32) ---
|
|
|
|
range_coder_create :: proc() -> rawptr ---
|
|
range_coder_destroy :: proc(ctx: rawptr) ---
|
|
range_coder_compress :: proc(ctx: rawptr, inBuffers: [^]Buffer, inBufferCount: uint, inLimit: uint, outData: [^]u8, outLimit: uint) -> uint ---
|
|
range_coder_decompress :: proc(ctx: rawptr, inData: [^]u8, inLimit: uint, outData: [^]u8, outLimit: uint) -> uint ---
|
|
}
|