Files
Odin/vendor/ENet/enet.odin
2025-10-10 17:51:28 +02:00

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 ---
}