Hi all, I’m writing a multiplayer game in Zig that I want to run in multiple environments (terminal, web, etc.), so I made a generic Player struct that takes in functions for drawing to the screen and playing sounds. Then, I made a Match struct that manages the interactions between multiple Players.
pub const Sound = enum {
// Types of sounds that might get played
};
pub fn Player(comptime drawAt: fn (x: u16, y: u16, char: u23) void, comptime playSound: fn (sound: Sound) void) type {
return struct {
// Actual usage of `drawAt` and `playSound`
};
}
pub fn Match(comptime drawAt: fn (x: u16, y: u16, char: u23) void, comptime playSound: fn (sound: Sound) void) type {
return struct {
const PlayerType = Player(drawAt, playSound);
players: []PlayerType,
// More code...
};
}
However, Match doesn’t care about drawAt and playSound at all, so really it should only be taking in the Player type as input:
pub fn Match(comptime PlayerType: type) type {
return struct {
players: []PlayerType,
// More code...
};
}
The problem I have with this is that comptime PlayerType: type
says nothing about the type’s interface, and so I don’t get any highlighting, autocomplete, etc. regarding Player while inside Match. Whereas with the first example, I get everything like as if Player were a concrete type.
I’m not familiar with metaprogramming in Zig, but is there someway to solve this by, say, somehow constraining PlayerType to only be an output of Player?
// @ReturnType() isn't a real function
pub fn Match(comptime PlayerType: @ReturnType(Player)) type