command/input: support globs
This commit is contained in:
committed by
Isaac Freund
parent
7f1f9152f2
commit
931b6268e7
@ -16,6 +16,11 @@
|
||||
|
||||
const std = @import("std");
|
||||
const mem = std.mem;
|
||||
const meta = std.meta;
|
||||
const math = std.math;
|
||||
const sort = std.sort;
|
||||
|
||||
const globber = @import("globber");
|
||||
|
||||
const server = &@import("../main.zig").server;
|
||||
const util = @import("../util.zig");
|
||||
@ -39,7 +44,7 @@ pub fn listInputs(
|
||||
var it = server.input_manager.devices.iterator(.forward);
|
||||
while (it.next()) |device| {
|
||||
const configured = for (server.input_manager.configs.items) |*input_config| {
|
||||
if (mem.eql(u8, input_config.identifier, device.identifier)) {
|
||||
if (globber.match(device.identifier, input_config.glob)) {
|
||||
break true;
|
||||
}
|
||||
} else false;
|
||||
@ -82,36 +87,50 @@ pub fn input(
|
||||
if (args.len < 4) return Error.NotEnoughArguments;
|
||||
if (args.len > 4) return Error.TooManyArguments;
|
||||
|
||||
// Try to find an existing InputConfig with matching identifier, or create
|
||||
try globber.validate(args[1]);
|
||||
|
||||
// Try to find an existing InputConfig with matching glob pattern, or create
|
||||
// a new one if none was found.
|
||||
const input_config = for (server.input_manager.configs.items) |*input_config| {
|
||||
if (mem.eql(u8, input_config.identifier, args[1])) {
|
||||
for (server.input_manager.configs.items) |*input_config| {
|
||||
if (mem.eql(u8, input_config.glob, args[1])) {
|
||||
try input_config.parse(args[2], args[3]);
|
||||
break input_config;
|
||||
}
|
||||
} else blk: {
|
||||
const identifier_owned = try util.gpa.dupe(u8, args[1]);
|
||||
errdefer util.gpa.free(identifier_owned);
|
||||
} else {
|
||||
const glob_owned = try util.gpa.dupe(u8, args[1]);
|
||||
errdefer util.gpa.free(glob_owned);
|
||||
|
||||
try server.input_manager.configs.ensureUnusedCapacity(1);
|
||||
const input_config = server.input_manager.configs.addOneAssumeCapacity();
|
||||
errdefer _ = server.input_manager.configs.pop();
|
||||
|
||||
input_config.* = .{
|
||||
.identifier = identifier_owned,
|
||||
.glob = glob_owned,
|
||||
};
|
||||
try input_config.parse(args[2], args[3]);
|
||||
}
|
||||
|
||||
break :blk input_config;
|
||||
};
|
||||
// Sort input configs by generality.
|
||||
sort.insertion(InputConfig, server.input_manager.configs.items, {}, lessThan);
|
||||
|
||||
// Update matching existing input devices.
|
||||
// We need to update all input device matching the glob. The user may
|
||||
// add an input configuration at an arbitrary position in the generality
|
||||
// ordered list, so the simplest way to ensure the device is configured
|
||||
// correctly is to apply all input configurations again, in order.
|
||||
var it = server.input_manager.devices.iterator(.forward);
|
||||
while (it.next()) |device| {
|
||||
if (mem.eql(u8, device.identifier, args[1])) {
|
||||
input_config.apply(device);
|
||||
// We don't break here because it is common to have multiple input
|
||||
// devices with the same identifier.
|
||||
// Device does not match the glob given in the command, so its
|
||||
// configuration state after applying all configs again would be
|
||||
// the same.
|
||||
if (!globber.match(device.identifier, args[1])) continue;
|
||||
|
||||
for (server.input_manager.configs.items) |ic| {
|
||||
if (globber.match(device.identifier, ic.glob)) {
|
||||
ic.apply(device);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn lessThan(_: void, a: InputConfig, b: InputConfig) bool {
|
||||
return globber.order(a.glob, b.glob) == .gt;
|
||||
}
|
||||
|
Reference in New Issue
Block a user