Archived
3
0

Crystal bindings update.

This commit is contained in:
Luka Vandervelden 2018-11-10 01:41:54 +09:00
parent be783e69b1
commit 345c2ad2d0

View File

@ -14,9 +14,15 @@ lib LibIPC
fd : LibC::Int
end
enum MessageType
ServerClose
Error
Data
end
struct Message
type : LibC::Char
length : LibC::UShort
type : UInt8
length : LibC::UInt
payload : LibC::Char*
end
@ -25,6 +31,21 @@ lib LibIPC
size : LibC::Int
end
enum EventType
NotSet
Error
Stdin
Connection
Disconnection
Message
end
struct Event
type : EventType
origin : Client*
m : Message*
end
# FIXME: IPC.initialize:
# - throw exceptions on error.
# - Make most arguments optional.
@ -39,6 +60,8 @@ lib LibIPC
fun ipc_server_select(Clients*, Service*, Clients*, LibC::Int*) : LibC::Int
fun ipc_service_poll_event(Clients*, Service*, Event*) : LibC::Int
fun ipc_application_connection(LibC::Char**, Service*, LibC::Char*) : LibC::Int
fun ipc_application_close(Service*) : LibC::Int
fun ipc_application_read(Service*, Message*) : LibC::Int
@ -99,53 +122,34 @@ class IPC::Service
end
def loop(&block)
active_clients = LibIPC::Clients.new
anyone_joined = 0_i32
message = LibIPC::Message.new
::loop do
if LibIPC.ipc_server_select(pointerof(@clients), pointerof(@service), pointerof(active_clients), pointerof(anyone_joined)) < 0
raise Exception.new "ipc_server_select < 0"
event = LibIPC::Event.new
r = LibIPC.ipc_service_poll_event pointerof(@clients), pointerof(@service), pointerof(event)
if r < 0
raise Exception.new "ipc_service_poll_event < 0"
end
if anyone_joined > 0
client = LibIPC::Client.new
if LibIPC.ipc_server_accept(pointerof(@service), pointerof(client)) < 0
raise Exception.new "ipc_server_accept < 0"
client = IPC::RemoteClient.new event.origin.unsafe_as(Pointer(LibIPC::Client)).value
pp! event
message = event.m.unsafe_as(Pointer(LibIPC::Message))
unless message.null?
pp! message.value
end
if LibIPC.ipc_client_add(pointerof(@clients), pointerof(client)) < 0
raise Exception.new "ipc_client_add < 0"
case event.type
when LibIPC::EventType::Connection
yield IPC::Event::Connection.new client
when LibIPC::EventType::Message
message = event.m.unsafe_as(Pointer(LibIPC::Message)).value
yield IPC::Event::Message.new IPC::Message.new(message.type, message.length, message.payload), client
when LibIPC::EventType::Disconnection
yield IPC::Event::Disconnection.new client
end
yield ::IPC::Event::Connection.new ::IPC::Server::Client.new client
end
i = 0
while i < active_clients.size
client_pointer = active_clients.clients[i]
return_value = LibIPC.ipc_server_read(client_pointer, pointerof(message))
if return_value < 0
raise Exception.new "ipc_server_read < 0"
elsif return_value == 1
LibIPC.ipc_client_del pointerof(@clients), client_pointer
# FIXME: Should probably not be a new Server::Client. Having unique
# variables helps in using Server::Clients as keys.
yield Event::Disconnection.new Server::Client.new client_pointer.value
else
yield Event::Message.new(IPC::Message.new(message.type, message.length, message.payload), Server::Client.new client_pointer.value)
end
i += 1
end
LibIPC.ipc_clients_free(pointerof(active_clients))
end
close
end
end
@ -162,32 +166,17 @@ class IPC::Message
getter payload : String
def initialize(type, length, payload)
@type = type
@type = type.to_u8
@payload = String.new payload, length
end
end
class IPC::Server::Client
@closed = false
getter client = LibIPC::Client.new
class IPC::RemoteClient
getter client : LibIPC::Client
def initialize(service : LibIPC::Service*)
if LibIPC.ipc_server_accept(service, pointerof(@client)) < 0
raise Exception.new "ipc_server_accept < 0"
end
end
def initialize(@client)
end
def read
message = LibIPC::Message.new
if LibIPC.ipc_server_read(pointerof(@client), pointerof(message)) < 0
raise Exception.new "ipc_server_read < 0"
end
Message.new message.type, message.length, message.payload
end
def send(type : UInt8, payload : String)
message = LibIPC::Message.new type: type, length: payload.size, payload: payload.to_unsafe
@ -195,32 +184,24 @@ class IPC::Server::Client
raise Exception.new "ipc_server_write < 0"
end
end
def close
return if @closed
LibIPC.ipc_server_close_client pointerof(@client)
end
def finalize
close
end
end
class IPC::Event
class Connection
getter client : ::IPC::Server::Client
getter client : IPC::RemoteClient
def initialize(@client)
end
end
class Disconnection
getter client : ::IPC::Server::Client
getter client : IPC::RemoteClient
def initialize(@client)
end
end
class Message
getter message : ::IPC::Message
getter client : ::IPC::Server::Client
getter client : IPC::RemoteClient
def initialize(@message, @client)
end
end