libipc/src/event.zig

99 lines
3.4 KiB
Zig

const std = @import("std");
const testing = std.testing;
const fmt = std.fmt;
const Message = @import("./message.zig").Message;
const print_eq = @import("./util.zig").print_eq;
pub const Event = struct {
// Event types.
// In the main event loop, servers and clients can receive connections,
// disconnections, errors or messages from their pairs. They also can
// set a timer so the loop will allow a periodic routine (sending ping
// messages for websockets, for instance).
//
// A few other events can occur.
//
// Extra socket
// The main loop waiting for an event can be used as an unique entry
// point for socket management. libipc users can register sockets via
// ipc_add_fd allowing them to trigger an event, so events unrelated
// to libipc are managed the same way.
// Switch
// libipc can be used to create protocol-related programs, such as a
// websocket proxy allowing libipc services to be accessible online.
// To help those programs (with TCP-complient sockets), two sockets
// can be bound together, each message coming from one end will be
// automatically transfered to the other socket and a Switch event
// will be triggered.
// Look Up
// When a client establishes a connection to a service, it asks the
// ipc daemon (ipcd) to locate the service and establish a connection
// to it. This is a lookup.
pub const Type = enum {
ERROR, // A problem occured.
CONNECTION, // New user.
DISCONNECTION, // User disconnected.
MESSAGE_RX, // New message.
MESSAGE_TX, // Message sent.
TIMER, // Timeout in the poll(2) function.
EXTERNAL, // Message received from a non IPC socket.
SWITCH_RX, // Message received from a switched FD.
SWITCH_TX, // Message sent to a switched fd.
};
t: Event.Type,
index: usize,
origin: i32, // socket fd
m: ?Message, // message
const Self = @This();
pub fn init(t: Event.Type, index: usize, origin: i32, m: ?Message) Self {
return Self{
.t = t,
.index = index,
.origin = origin,
.m = m,
};
}
pub fn set(self: *Self, t: Event.Type, index: usize, origin: i32, m: ?Message) void {
self.t = t;
self.index = index;
self.origin = origin;
self.m = m;
}
pub fn clean(self: *Self) void {
self.t = Event.Type.ERROR;
self.index = @as(usize, 0);
self.origin = @as(i32, 0);
if (self.m) |message| {
message.deinit();
}
self.m = null;
}
pub fn format(self: Self, comptime _: []const u8, _: fmt.FormatOptions, out_stream: anytype) !void {
try fmt.format(out_stream, "{}, origin: {}, index {}, message: [{?}]", .{ self.t, self.origin, self.index, self.m });
}
};
test "Event - creation and display" {
const config = .{ .safety = true };
var gpa = std.heap.GeneralPurposeAllocator(config){};
defer _ = gpa.deinit();
const allocator = gpa.allocator();
const s = "hello!!";
var m = try Message.init(1, allocator, s); // fd type payload
defer m.deinit();
const e = Event.init(Event.Type.CONNECTION, 5, 8, m); // type index origin message
try print_eq("event.Event.Type.CONNECTION, origin: 8, index 5, message: [fd: 1, payload: [hello!!]]", e);
}