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