From 70a93887df512c4e0665cf43fb72ec8f66c48c55 Mon Sep 17 00:00:00 2001 From: Philippe Pittoli Date: Fri, 24 Oct 2025 19:18:35 +0200 Subject: [PATCH] New examples: pong and pongd using the Zig library directly (no C bindings). --- build.zig | 16 +++++++- examples/pong.zig | 91 ++++++++++++++++++++++++++++++++++++++++++++++ examples/pongd.zig | 7 +++- 3 files changed, 111 insertions(+), 3 deletions(-) create mode 100644 examples/pong.zig diff --git a/build.zig b/build.zig index ea08e09..dc9a204 100644 --- a/build.zig +++ b/build.zig @@ -110,6 +110,21 @@ pub fn build(b: *std.Build) void { b.installArtifact(pongd_with_c_bindings); pongd_with_c_bindings.linkLibrary(static_lib); + // pong client using the zig library directly. + const pong = b.addExecutable(.{ + .name = "pong", // name of the executable + .root_module = b.createModule(.{ + .root_source_file = b.path("examples/pong.zig"), + .target = target, + .optimize = optimize, + + .imports = &.{ + .{ .name = "ipc", .module = mod }, + }, + }), + }); + b.installArtifact(pong); + // pong service using the zig library directly. const pongd = b.addExecutable(.{ .name = "pongd", // name of the executable @@ -118,7 +133,6 @@ pub fn build(b: *std.Build) void { .target = target, .optimize = optimize, - // No need for external modules to import. .imports = &.{ .{ .name = "ipc", .module = mod }, }, diff --git a/examples/pong.zig b/examples/pong.zig new file mode 100644 index 0000000..dd07ea4 --- /dev/null +++ b/examples/pong.zig @@ -0,0 +1,91 @@ +// Example of a `pong` client using the Zig library directly (not the C bindings). +const std = @import("std"); +const ipc = @import("ipc"); + +const hexdump = ipc.hexdump; +const Message = ipc.Message; +const util = ipc.util; + +const builtin = @import("builtin"); +const native_os = builtin.target.os.tag; +const print = std.debug.print; +const testing = std.testing; + +const service_name = "pong"; + +fn create_service() !void { + var gpa = std.heap.DebugAllocator(.{.safety = true}){}; + defer _ = gpa.deinit(); + const allocator = gpa.allocator(); + + var ctx = try ipc.Context.init(allocator); + defer { + std.debug.print("Deinit context.\n", .{}); + ctx.deinit(); // There. Can't leak. Isn't Zig wonderful? + } + + // CLIENT SIDE: connect to a service. + const servicefd = try ctx.connect_service(service_name); + + // Listen to the standard input (to quit the application). + try ctx.add_external(0); + + // Schedule a message. + const message = try Message.init(servicefd, allocator, "hello, plz bounce me"); + try ctx.schedule (message); + + var some_event: ipc.Event = undefined; + ctx.timer = 20000; // 2 seconds + var count: u32 = 0; + var should_continue = true; + + while(should_continue) { + some_event = try ctx.wait_event(); + switch (some_event.t) { + .EXTERNAL => { + should_continue = false; + }, + .TIMER => { + std.debug.print("\rTimer! ({d})", .{count}); + count += 1; + }, + + .CONNECTION => { + std.debug.print("Connection.\n", .{}); + }, + + .DISCONNECTION => { + std.debug.print("Disconnection.\n", .{}); + }, + + .MESSAGE_RX => { + if (some_event.m) |m| { + std.debug.print("Message received from {d} ({d} bytes)\n", .{m.fd, m.payload.len}); + util.print_message ("RECEIVED MESSAGE", m); + should_continue = false; + m.deinit(); + } + else { + std.debug.print("Error while receiving new message. Ignoring.\n", .{}); + } + }, + + .MESSAGE_TX => { + std.debug.print("Message sent to {d}.\n", .{some_event.origin}); + }, + + else => { + std.debug.print("Error: unexpected event\n", .{}); + std.debug.print("Quitting.\n", .{}); + should_continue = false; + }, + } + } + + std.debug.print("Goodbye\n", .{}); +} + +pub fn main() !u8 { + try create_service(); + return 0; +} diff --git a/examples/pongd.zig b/examples/pongd.zig index 4f5b569..38614c0 100644 --- a/examples/pongd.zig +++ b/examples/pongd.zig @@ -1,4 +1,4 @@ -// Example of a `pong` service using the C bindings. +// Example of a `pong` service using the Zig library directly (not the C bindings). const std = @import("std"); const ipc = @import("ipc"); @@ -11,6 +11,8 @@ const native_os = builtin.target.os.tag; const print = std.debug.print; const testing = std.testing; +const service_name = "pong"; + fn create_service() !void { var gpa = std.heap.DebugAllocator(.{.safety = true}){}; defer _ = gpa.deinit(); @@ -23,8 +25,9 @@ fn create_service() !void { } // SERVER SIDE: creating a service. - _ = try ctx.server_init("pong"); + _ = try ctx.server_init(service_name); + // Listen to the standard input (to quit the application). try ctx.add_external(0); var some_event: ipc.Event = undefined;