mirror of https://github.com/fairyglade/ly.git
Add animation framework
Signed-off-by: AnErrupTion <anerruption@disroot.org>
This commit is contained in:
parent
fa0748ead2
commit
e0ed1b4eb1
|
@ -1,4 +1,5 @@
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
|
const Animation = @import("../tui/Animation.zig");
|
||||||
const TerminalBuffer = @import("../tui/TerminalBuffer.zig");
|
const TerminalBuffer = @import("../tui/TerminalBuffer.zig");
|
||||||
const utils = @import("../tui/utils.zig");
|
const utils = @import("../tui/utils.zig");
|
||||||
|
|
||||||
|
@ -43,7 +44,15 @@ pub fn init(terminal_buffer: *TerminalBuffer, col1: u32, col2: u32, col3: u32) C
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn draw(self: *ColorMix) void {
|
pub fn animation(self: *ColorMix) Animation {
|
||||||
|
return Animation.init(self, deinit, realloc, draw);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn deinit(_: *ColorMix) void {}
|
||||||
|
|
||||||
|
fn realloc(_: *ColorMix) anyerror!void {}
|
||||||
|
|
||||||
|
fn draw(self: *ColorMix) void {
|
||||||
self.frames +%= 1;
|
self.frames +%= 1;
|
||||||
const time: f32 = @as(f32, @floatFromInt(self.frames)) * time_scale;
|
const time: f32 = @as(f32, @floatFromInt(self.frames)) * time_scale;
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const Allocator = std.mem.Allocator;
|
const Allocator = std.mem.Allocator;
|
||||||
|
const Animation = @import("../tui/Animation.zig");
|
||||||
const TerminalBuffer = @import("../tui/TerminalBuffer.zig");
|
const TerminalBuffer = @import("../tui/TerminalBuffer.zig");
|
||||||
const utils = @import("../tui/utils.zig");
|
const utils = @import("../tui/utils.zig");
|
||||||
|
|
||||||
|
@ -38,17 +39,21 @@ pub fn init(allocator: Allocator, terminal_buffer: *TerminalBuffer, top_color: u
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn deinit(self: Doom) void {
|
pub fn animation(self: *Doom) Animation {
|
||||||
|
return Animation.init(self, deinit, realloc, draw);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn deinit(self: *Doom) void {
|
||||||
self.allocator.free(self.buffer);
|
self.allocator.free(self.buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn realloc(self: *Doom) !void {
|
fn realloc(self: *Doom) anyerror!void {
|
||||||
const buffer = try self.allocator.realloc(self.buffer, self.terminal_buffer.width * self.terminal_buffer.height);
|
const buffer = try self.allocator.realloc(self.buffer, self.terminal_buffer.width * self.terminal_buffer.height);
|
||||||
initBuffer(buffer, self.terminal_buffer.width);
|
initBuffer(buffer, self.terminal_buffer.width);
|
||||||
self.buffer = buffer;
|
self.buffer = buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn draw(self: Doom) void {
|
fn draw(self: *Doom) void {
|
||||||
for (0..self.terminal_buffer.width) |x| {
|
for (0..self.terminal_buffer.width) |x| {
|
||||||
for (1..self.terminal_buffer.height) |y| {
|
for (1..self.terminal_buffer.height) |y| {
|
||||||
const source = y * self.terminal_buffer.width + x;
|
const source = y * self.terminal_buffer.width + x;
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const Allocator = std.mem.Allocator;
|
const Allocator = std.mem.Allocator;
|
||||||
const Random = std.Random;
|
const Random = std.Random;
|
||||||
|
const Animation = @import("../tui/Animation.zig");
|
||||||
const TerminalBuffer = @import("../tui/TerminalBuffer.zig");
|
const TerminalBuffer = @import("../tui/TerminalBuffer.zig");
|
||||||
const utils = @import("../tui/utils.zig");
|
const utils = @import("../tui/utils.zig");
|
||||||
|
|
||||||
|
@ -54,12 +55,16 @@ pub fn init(allocator: Allocator, terminal_buffer: *TerminalBuffer, fg_ini: u32,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn deinit(self: Matrix) void {
|
pub fn animation(self: *Matrix) Animation {
|
||||||
|
return Animation.init(self, deinit, realloc, draw);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn deinit(self: *Matrix) void {
|
||||||
self.allocator.free(self.dots);
|
self.allocator.free(self.dots);
|
||||||
self.allocator.free(self.lines);
|
self.allocator.free(self.lines);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn realloc(self: *Matrix) !void {
|
fn realloc(self: *Matrix) anyerror!void {
|
||||||
const dots = try self.allocator.realloc(self.dots, self.terminal_buffer.width * (self.terminal_buffer.height + 1));
|
const dots = try self.allocator.realloc(self.dots, self.terminal_buffer.width * (self.terminal_buffer.height + 1));
|
||||||
const lines = try self.allocator.realloc(self.lines, self.terminal_buffer.width);
|
const lines = try self.allocator.realloc(self.lines, self.terminal_buffer.width);
|
||||||
|
|
||||||
|
@ -69,7 +74,7 @@ pub fn realloc(self: *Matrix) !void {
|
||||||
self.lines = lines;
|
self.lines = lines;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn draw(self: *Matrix) void {
|
fn draw(self: *Matrix) void {
|
||||||
const buf_height = self.terminal_buffer.height;
|
const buf_height = self.terminal_buffer.height;
|
||||||
const buf_width = self.terminal_buffer.width;
|
const buf_width = self.terminal_buffer.width;
|
||||||
self.count += 1;
|
self.count += 1;
|
||||||
|
|
63
src/main.zig
63
src/main.zig
|
@ -11,6 +11,7 @@ const interop = @import("interop.zig");
|
||||||
const Doom = @import("animations/Doom.zig");
|
const Doom = @import("animations/Doom.zig");
|
||||||
const Matrix = @import("animations/Matrix.zig");
|
const Matrix = @import("animations/Matrix.zig");
|
||||||
const ColorMix = @import("animations/ColorMix.zig");
|
const ColorMix = @import("animations/ColorMix.zig");
|
||||||
|
const Animation = @import("tui/Animation.zig");
|
||||||
const TerminalBuffer = @import("tui/TerminalBuffer.zig");
|
const TerminalBuffer = @import("tui/TerminalBuffer.zig");
|
||||||
const Session = @import("tui/components/Session.zig");
|
const Session = @import("tui/components/Session.zig");
|
||||||
const Text = @import("tui/components/Text.zig");
|
const Text = @import("tui/components/Text.zig");
|
||||||
|
@ -336,24 +337,24 @@ pub fn main() !void {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize the animation, if any
|
// Initialize the animation, if any
|
||||||
var doom: Doom = undefined;
|
var animation: Animation = undefined;
|
||||||
var matrix: Matrix = undefined;
|
|
||||||
var color_mix: ColorMix = undefined;
|
|
||||||
|
|
||||||
switch (config.animation) {
|
switch (config.animation) {
|
||||||
.none => {},
|
.none => {},
|
||||||
.doom => doom = try Doom.init(allocator, &buffer, config.doom_top_color, config.doom_middle_color, config.doom_bottom_color),
|
.doom => {
|
||||||
.matrix => matrix = try Matrix.init(allocator, &buffer, config.cmatrix_fg, config.cmatrix_min_codepoint, config.cmatrix_max_codepoint),
|
var doom = try Doom.init(allocator, &buffer, config.doom_top_color, config.doom_middle_color, config.doom_bottom_color);
|
||||||
.colormix => color_mix = ColorMix.init(&buffer, config.colormix_col1, config.colormix_col2, config.colormix_col3),
|
animation = doom.animation();
|
||||||
}
|
},
|
||||||
defer {
|
.matrix => {
|
||||||
switch (config.animation) {
|
var matrix = try Matrix.init(allocator, &buffer, config.cmatrix_fg, config.cmatrix_min_codepoint, config.cmatrix_max_codepoint);
|
||||||
.none => {},
|
animation = matrix.animation();
|
||||||
.doom => doom.deinit(),
|
},
|
||||||
.matrix => matrix.deinit(),
|
.colormix => {
|
||||||
.colormix => {},
|
var color_mix = ColorMix.init(&buffer, config.colormix_col1, config.colormix_col2, config.colormix_col3);
|
||||||
}
|
animation = color_mix.animation();
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
defer animation.deinit();
|
||||||
|
|
||||||
const animate = config.animation != .none;
|
const animate = config.animation != .none;
|
||||||
const shutdown_key = try std.fmt.parseInt(u8, config.shutdown_key[1..], 10);
|
const shutdown_key = try std.fmt.parseInt(u8, config.shutdown_key[1..], 10);
|
||||||
|
@ -382,7 +383,7 @@ pub fn main() !void {
|
||||||
|
|
||||||
while (run) {
|
while (run) {
|
||||||
// If there's no input or there's an animation, a resolution change needs to be checked
|
// If there's no input or there's an animation, a resolution change needs to be checked
|
||||||
if (!update or config.animation != .none) {
|
if (!update or animate) {
|
||||||
if (!update) std.time.sleep(std.time.ns_per_ms * 100);
|
if (!update) std.time.sleep(std.time.ns_per_ms * 100);
|
||||||
|
|
||||||
_ = termbox.tb_present(); // Required to update tb_width() and tb_height()
|
_ = termbox.tb_present(); // Required to update tb_width() and tb_height()
|
||||||
|
@ -396,16 +397,9 @@ pub fn main() !void {
|
||||||
buffer.width = width;
|
buffer.width = width;
|
||||||
buffer.height = height;
|
buffer.height = height;
|
||||||
|
|
||||||
switch (config.animation) {
|
animation.realloc() catch {
|
||||||
.none => {},
|
try info_line.addMessage(lang.err_alloc, config.error_bg, config.error_fg);
|
||||||
.doom => doom.realloc() catch {
|
};
|
||||||
try info_line.addMessage(lang.err_alloc, config.error_bg, config.error_fg);
|
|
||||||
},
|
|
||||||
.matrix => matrix.realloc() catch {
|
|
||||||
try info_line.addMessage(lang.err_alloc, config.error_bg, config.error_fg);
|
|
||||||
},
|
|
||||||
.colormix => {},
|
|
||||||
}
|
|
||||||
|
|
||||||
update = true;
|
update = true;
|
||||||
resolution_changed = true;
|
resolution_changed = true;
|
||||||
|
@ -417,14 +411,7 @@ pub fn main() !void {
|
||||||
if (auth_fails < config.auth_fails) {
|
if (auth_fails < config.auth_fails) {
|
||||||
_ = termbox.tb_clear();
|
_ = termbox.tb_clear();
|
||||||
|
|
||||||
if (!animation_timed_out) {
|
if (!animation_timed_out) animation.draw();
|
||||||
switch (config.animation) {
|
|
||||||
.none => {},
|
|
||||||
.doom => doom.draw(),
|
|
||||||
.matrix => matrix.draw(),
|
|
||||||
.colormix => color_mix.draw(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
buffer.drawLabel(ly_top_str, 0, 0);
|
buffer.drawLabel(ly_top_str, 0, 0);
|
||||||
|
|
||||||
|
@ -585,12 +572,7 @@ pub fn main() !void {
|
||||||
|
|
||||||
if (config.animation_timeout_sec > 0 and tv.tv_sec - tv_zero.tv_sec > config.animation_timeout_sec) {
|
if (config.animation_timeout_sec > 0 and tv.tv_sec - tv_zero.tv_sec > config.animation_timeout_sec) {
|
||||||
animation_timed_out = true;
|
animation_timed_out = true;
|
||||||
switch (config.animation) {
|
animation.deinit();
|
||||||
.none => {},
|
|
||||||
.doom => doom.deinit(),
|
|
||||||
.matrix => matrix.deinit(),
|
|
||||||
.colormix => {},
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else if (config.bigclock != .none and config.clock == null) {
|
} else if (config.bigclock != .none and config.clock == null) {
|
||||||
var tv: interop.system_time.timeval = undefined;
|
var tv: interop.system_time.timeval = undefined;
|
||||||
|
@ -736,9 +718,6 @@ pub fn main() !void {
|
||||||
const password_text = try allocator.dupeZ(u8, password.text.items);
|
const password_text = try allocator.dupeZ(u8, password.text.items);
|
||||||
defer allocator.free(password_text);
|
defer allocator.free(password_text);
|
||||||
|
|
||||||
// Give up control on the TTY
|
|
||||||
// _ = termbox.tb_shutdown();
|
|
||||||
|
|
||||||
session_pid = try std.posix.fork();
|
session_pid = try std.posix.fork();
|
||||||
if (session_pid == 0) {
|
if (session_pid == 0) {
|
||||||
const current_environment = session.label.list.items[session.label.current];
|
const current_environment = session.label.list.items[session.label.current];
|
||||||
|
|
|
@ -0,0 +1,61 @@
|
||||||
|
const Animation = @This();
|
||||||
|
|
||||||
|
const VTable = struct {
|
||||||
|
deinit_fn: *const fn (ptr: *anyopaque) void,
|
||||||
|
realloc_fn: *const fn (ptr: *anyopaque) anyerror!void,
|
||||||
|
draw_fn: *const fn (ptr: *anyopaque) void,
|
||||||
|
};
|
||||||
|
|
||||||
|
pointer: *anyopaque,
|
||||||
|
vtable: VTable,
|
||||||
|
|
||||||
|
pub fn init(
|
||||||
|
pointer: anytype,
|
||||||
|
comptime deinit_fn: fn (ptr: @TypeOf(pointer)) void,
|
||||||
|
comptime realloc_fn: fn (ptr: @TypeOf(pointer)) anyerror!void,
|
||||||
|
comptime draw_fn: fn (ptr: @TypeOf(pointer)) void,
|
||||||
|
) Animation {
|
||||||
|
const Pointer = @TypeOf(pointer);
|
||||||
|
const Impl = struct {
|
||||||
|
pub fn deinitImpl(ptr: *anyopaque) void {
|
||||||
|
const impl: Pointer = @ptrCast(@alignCast(ptr));
|
||||||
|
return @call(.always_inline, deinit_fn, .{impl});
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn reallocImpl(ptr: *anyopaque) anyerror!void {
|
||||||
|
const impl: Pointer = @ptrCast(@alignCast(ptr));
|
||||||
|
return @call(.always_inline, realloc_fn, .{impl});
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn drawImpl(ptr: *anyopaque) void {
|
||||||
|
const impl: Pointer = @ptrCast(@alignCast(ptr));
|
||||||
|
return @call(.always_inline, draw_fn, .{impl});
|
||||||
|
}
|
||||||
|
|
||||||
|
const vtable = VTable{
|
||||||
|
.deinit_fn = deinitImpl,
|
||||||
|
.realloc_fn = reallocImpl,
|
||||||
|
.draw_fn = drawImpl,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
return .{
|
||||||
|
.pointer = pointer,
|
||||||
|
.vtable = Impl.vtable,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn deinit(self: *Animation) void {
|
||||||
|
const impl: @TypeOf(self.pointer) = @ptrCast(@alignCast(self.pointer));
|
||||||
|
return @call(.auto, self.vtable.deinit_fn, .{impl});
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn realloc(self: *Animation) anyerror!void {
|
||||||
|
const impl: @TypeOf(self.pointer) = @ptrCast(@alignCast(self.pointer));
|
||||||
|
return @call(.auto, self.vtable.realloc_fn, .{impl});
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn draw(self: *Animation) void {
|
||||||
|
const impl: @TypeOf(self.pointer) = @ptrCast(@alignCast(self.pointer));
|
||||||
|
return @call(.auto, self.vtable.draw_fn, .{impl});
|
||||||
|
}
|
Loading…
Reference in New Issue