event_cursor := 0;
}
-TCP_Server :: struct {
- use connection: TCP_Connection;
-
- Client :: struct {
- use socket : Socket;
- address : Socket_Address;
- state : State;
-
- State :: enum {
- Alive;
- Dying;
- Dead;
- }
- }
- client_allocator: Allocator;
- clients: [] ^Client;
-
- // max clients is stored as clients.count.
- client_count: u32;
-
- listener_thread: thread.Thread;
-
- alive := true;
- pulse_time_ms := 500;
-
- get_events :: tcp_get_events
- listen :: tcp_server_listen
- pulse :: tcp_server_pulse
- send :: tcp_server_send
- broadcast :: tcp_server_broadcast
-}
-
-TCP_Client :: struct {
- use connection: TCP_Connection;
-
- get_events :: tcp_get_events
-}
-
TCP_Event :: struct {
kind: Kind;
data: rawptr;
Undefined;
Connection;
Disconnection;
- Message;
+ Data;
}
Connection :: struct {
client : ^TCP_Server.Client;
}
- Message :: struct {
+ Data :: struct {
address: ^Socket_Address;
// This is only set when the event is coming from the server.
client : ^TCP_Server.Client;
close :: (use conn: ^TCP_Connection) {
for events {
switch it.kind {
- case .Message {
- raw_free(event_allocator, (cast(^TCP_Event.Message) it.data).contents.data);
+ case .Data {
+ raw_free(event_allocator, (cast(^TCP_Event.Data) it.data).contents.data);
}
}
};
}
+
+//
+// TCP Server
+//
+
+TCP_Server :: struct {
+ use connection: TCP_Connection;
+
+ Client :: struct {
+ use socket : Socket;
+ address : Socket_Address;
+ state : State;
+
+ State :: enum {
+ Alive;
+ Dying;
+ Dead;
+ }
+ }
+ client_allocator: Allocator;
+ clients: [] ^Client;
+
+ // max clients is stored as clients.count.
+ client_count: u32;
+
+ listener_thread: thread.Thread;
+
+ alive := true;
+ pulse_time_ms := 500;
+
+ get_events :: tcp_get_events
+ listen :: tcp_server_listen
+ pulse :: tcp_server_pulse
+ send :: tcp_server_send
+ broadcast :: tcp_server_broadcast
+ handle_events :: tcp_server_handle_events
+}
+
tcp_server_make :: (max_clients := 32, allocator := context.allocator) -> ^TCP_Server {
socket, err := socket_create(.Inet, .Stream); // IPv6?
if err != .None do return null;
continue;
}
- msg_event := new(TCP_Event.Message, allocator=server.event_allocator);
- msg_event.client = it;
- msg_event.address = ^it.address;
- msg_event.contents = memory.copy_slice(msg_buffer[0 .. bytes_read], allocator=server.event_allocator);
- server.events << .{ .Message, msg_event };
+ data_event := new(TCP_Event.Data, allocator=server.event_allocator);
+ data_event.client = it;
+ data_event.address = ^it.address;
+ data_event.contents = memory.copy_slice(msg_buffer[0 .. bytes_read], allocator=server.event_allocator);
+ server.events << .{ .Data, data_event };
}
for clients {
}
}
+tcp_server_handle_events :: macro (server: ^TCP_Server, handler: Code) {
+ while server->pulse() {
+ for server->get_events() {
+ #insert handler;
+ }
+ }
+}
+
+
+//
+// TCP Client
+//
+
+TCP_Client :: struct {
+ use connection: TCP_Connection;
+
+ get_events :: tcp_get_events
+}
+
+
+
+
#local {
tcp_server_kill_client :: (use server: ^TCP_Server, client: ^TCP_Server.Client) {
client.state = .Dying;