indexing description: "[ A UDP socket that can be used to send or receive data over a network using the non-reliable UDP protocol. ]" date: "$Date$" revision: "$Revision$" class EM_SIMPLE_UDP_SOCKET inherit EM_SHARED_ERROR_HANDLER export {NONE} all end EM_NETWORK_CONSTANTS export {NONE} all end EM_SHARED_SUBSYSTEMS export {NONE} all end SDL_NET_FUNCTIONS export {NONE} all end SDL_ERROR_FUNCTIONS export {NONE} all end MEMORY export {NONE} all redefine dispose end EXCEPTIONS export {NONE} all end create make feature {NONE} -- Initialisation make is -- Creates a new UDP socket. do create current_packet.make_shared (sdlnet_alloc_packet (max_udp_packet_size)) current_packet_item:= current_packet.item fetch_new_packet := True end feature -- Open/Close open (a_port: INTEGER) is -- Opens the socket for listening on `a_port'. require a_port_in_range: a_port > 0 and a_port < 65536 not_open: not is_open local zero: POINTER do socket := sdlnet_udp_open (a_port) if socket = zero then -- raise ("EM_NETWORK: "+ create {STRING}.make_from_c (sdl_get_error)) error_handler.set_error (error_handler.Em_error_udp_open) raise("EM_NETWORK: error") else is_open := True end ensure open: is_open no_error_occured: not error_handler.has_error_occured end close is -- Closes the current socket. require open: is_open do -- This always succeeds, so no return value, no error handling. sdlnet_udp_close (socket) socket:= default_pointer is_open := false ensure not_open: not is_open end feature -- Send/Receive send (a_packet: EM_UDP_PACKET) is -- Send `a_packet' to its destination. require open: is_open do if sdlnet_udp_send (socket, -1, a_packet.udp_packet_struct.item) = 0 then error_handler.raise_error( error_handler.Em_error_udp_send,[]) end end is_packet_ready: BOOLEAN is -- Is packet ready? -- If a packet is ready you usually want to call the command `reveice_packet' afterwards. -- Use this function in an eventloop for example: Receive a packet and generate an event. -- You should generally not use a seperate thread to poll for packets because this feature is non-blocking. require open: is_open local returned: INTEGER do if fetch_new_packet then returned := sdlnet_udp_recv (socket, current_packet.item) if returned = -1 then --raise ("EM_NETWORK:" + create {STRING}.make_from_c (sdl_get_error)) error_handler.set_error (error_handler.Em_error_udp_recv) raise("EM_NETWORK: error") elseif returned = 0 then -- There was no packet ready Result := False else -- OK, we got a packet Result := True fetch_new_packet := False end else Result := True end ensure no_error_occured: not error_handler.has_error_occured end receive_packet is -- Receive a packet. -- You can get the packet using the query `last_packet'. require open: is_open packet_ready: is_packet_ready do fetch_new_packet := true create last_packet.make_from_struct (current_packet) end feature -- Status is_open: BOOLEAN -- True if the socket is opened for listening on a local port. last_packet: EM_UDP_PACKET -- Last received packet feature {NONE} -- Implementation dispose is -- Dispose do sdlnet_free_packet (current_packet_item) Precursor end socket : POINTER -- The pointer to the c_struct representing the socket. current_packet : UDPPACKET_STRUCT -- The struct holding our current packet. current_packet_item: POINTER -- Pointer of current packet used for disposal without dereferencing. fetch_new_packet : BOOLEAN -- Used to create the illusion with the query `packet_ready' and `receive_packet'. invariant network_initialized : network_subsystem.is_enabled end