summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/Messages.zig47
-rw-r--r--src/Output.zig3
-rw-r--r--src/pardes.zig8
3 files changed, 31 insertions, 27 deletions
diff --git a/src/Messages.zig b/src/Messages.zig
index 6b041369..053950da 100644
--- a/src/Messages.zig
+++ b/src/Messages.zig
@@ -19,6 +19,15 @@ const Key = pardes.Key;
const Rect = layout.Rect;
const Pardes = pardes.Pardes;
+const Messages = @This();
+
+/// The message-row log: a fixed ring, never allocated, never grown. See
+/// `logMessage` and the `Messages` builtin.
+log: [limits.message_log]LoggedMessage = @splat(.{}),
+/// Next slot to write. `len` saturates at the ring's size.
+head: usize = 0,
+len: usize = 0,
+
pub const LoggedMessage = struct {
pub const cap = 256;
text: [cap]u8 = undefined,
@@ -347,8 +356,8 @@ fn logMessage(p: *Pardes, id: usize, text: []const u8) void {
// /log hears every one: a client that retried and failed the same way
// is waiting on that second line. Only the +Messages view collapses.
ctlfs.events.noteMessage(p, serial, kept);
- if (p.messages_len > 0) {
- const last = &p.messages[(p.messages_head + limits.message_log - 1) % limits.message_log];
+ if (p.messages.len > 0) {
+ const last = &p.messages.log[(p.messages.head + limits.message_log - 1) % limits.message_log];
if (last.serial == serial and
std.mem.eql(u8, Message.body(last.slice()), Message.body(kept)))
{
@@ -360,20 +369,20 @@ fn logMessage(p: *Pardes, id: usize, text: []const u8) void {
return;
}
}
- const slot = &p.messages[p.messages_head];
+ const slot = &p.messages.log[p.messages.head];
slot.len = @intCast(kept.len);
@memcpy(slot.text[0..slot.len], kept);
slot.serial = serial;
slot.repeats = 1;
- p.messages_head = (p.messages_head + 1) % limits.message_log;
- p.messages_len = @min(p.messages_len + 1, limits.message_log);
+ p.messages.head = (p.messages.head + 1) % limits.message_log;
+ p.messages.len = @min(p.messages.len + 1, limits.message_log);
}
/// The log oldest-first, which is reading order.
-pub fn messageLog(p: *const Pardes, i: usize) ?*const LoggedMessage {
- if (i >= p.messages_len) return null;
- const first = (p.messages_head + limits.message_log - p.messages_len) % limits.message_log;
- return &p.messages[(first + i) % limits.message_log];
+pub fn messageLog(m: *const Messages, i: usize) ?*const LoggedMessage {
+ if (i >= m.len) return null;
+ const first = (m.head + limits.message_log - m.len) % limits.message_log;
+ return &m.log[(first + i) % limits.message_log];
}
pub fn reportError(p: *Pardes, id: usize, operation: []const u8, err: anyerror) void {
@@ -432,38 +441,38 @@ test "the message log keeps what the row forgets, and collapses repeats" {
setMessage(p, 0, "14:32:09 saved /x.zig"); // same event, later clock
setMessage(p, 0, "save: AccessDenied");
- try std.testing.expectEqual(@as(usize, 2), p.messages_len);
- const first = messageLog(p, 0).?;
+ try std.testing.expectEqual(@as(usize, 2), p.messages.len);
+ const first = p.messages.messageLog(0).?;
try std.testing.expectEqual(@as(u16, 2), first.repeats);
// ...and the NEWEST wording is what survives, so the row carries the last
// time it happened rather than the first.
try std.testing.expectEqualStrings("14:32:09 saved /x.zig", first.slice());
- try std.testing.expectEqualStrings("save: AccessDenied", messageLog(p, 1).?.slice());
- try std.testing.expect(messageLog(p, 2) == null);
+ try std.testing.expectEqualStrings("save: AccessDenied", p.messages.messageLog(1).?.slice());
+ try std.testing.expect(p.messages.messageLog(2) == null);
// The same text from a DIFFERENT pane is a different event: one pane's
// failure must not be recorded as another's.
p.newScratchBelow(0);
const other = p.active;
setMessage(p, other, "save: AccessDenied");
- try std.testing.expectEqual(@as(usize, 3), p.messages_len);
- try std.testing.expectEqual(p.panes[other].?.serial, messageLog(p, 2).?.serial);
+ try std.testing.expectEqual(@as(usize, 3), p.messages.len);
+ try std.testing.expectEqual(p.panes[other].?.serial, p.messages.messageLog(2).?.serial);
// Progress is NOT logged: it arrives several times a second for a whole
// index and would push everything else out (`setStatus`).
setStatus(p, 0, "14:32:10 lsp rust-analyzer: Indexing 47%");
- try std.testing.expectEqual(@as(usize, 3), p.messages_len);
+ try std.testing.expectEqual(@as(usize, 3), p.messages.len);
// The ring wraps rather than grows, and still reads oldest-first.
for (0..limits.message_log + 5) |i| {
var buf: [32]u8 = undefined;
setMessage(p, 0, std.fmt.bufPrint(&buf, "line {d}", .{i}) catch unreachable);
}
- try std.testing.expectEqual(@as(usize, limits.message_log), p.messages_len);
- try std.testing.expectEqualStrings("line 5", messageLog(p, 0).?.slice());
+ try std.testing.expectEqual(@as(usize, limits.message_log), p.messages.len);
+ try std.testing.expectEqualStrings("line 5", p.messages.messageLog(0).?.slice());
var last_buf: [32]u8 = undefined;
const want_last = std.fmt.bufPrint(&last_buf, "line {d}", .{limits.message_log + 4}) catch unreachable;
- try std.testing.expectEqualStrings(want_last, messageLog(p, limits.message_log - 1).?.slice());
+ try std.testing.expectEqualStrings(want_last, p.messages.messageLog(limits.message_log - 1).?.slice());
}
test "Msg writes the transient row by hand, bare or with text, and input ends it" {
diff --git a/src/Output.zig b/src/Output.zig
index b216c0cf..6df2fd34 100644
--- a/src/Output.zig
+++ b/src/Output.zig
@@ -4,7 +4,6 @@ const panes = @import("panes.zig");
const std = @import("std");
const pardes = @import("pardes.zig");
const exec = @import("exec.zig");
-const Messages = @import("Messages.zig");
const config = @import("config.zig");
const Pardes = pardes.Pardes;
const modal = @import("modal.zig");
@@ -686,7 +685,7 @@ pub fn openMessages(p: *Pardes, id: usize) !void {
var out: std.Io.Writer.Allocating = .init(p.gpa);
errdefer out.deinit();
var i: usize = 0;
- while (Messages.messageLog(p, i)) |m| : (i += 1) {
+ while (p.messages.messageLog(i)) |m| : (i += 1) {
if (m.serial != 0) try out.writer.print("{d}: ", .{m.serial});
try out.writer.writeAll(m.slice());
if (m.repeats > 1) try out.writer.print(" (x{d})", .{m.repeats});
diff --git a/src/pardes.zig b/src/pardes.zig
index 44f0d2ea..d2ac5868 100644
--- a/src/pardes.zig
+++ b/src/pardes.zig
@@ -3777,12 +3777,8 @@ pub const Pardes = struct {
/// The in-program answers behind every unimplemented host method. Per
/// instance, so several cores behind one fan-out host stay independent.
fallback: host_io.Fallback,
- /// The message-row log: a fixed ring, never allocated, never grown. See
- /// `logMessage` and the `Messages` builtin.
- messages: [limits.message_log]Messages.LoggedMessage = @splat(.{}),
- /// Next slot to write. `messages_len` saturates at the ring's size.
- messages_head: usize = 0,
- messages_len: usize = 0,
+ /// The message-row log (see Messages.zig).
+ messages: Messages = .{},
in_q: [64]Event = undefined,
in_head: usize = 0,
in_len: usize = 0,