Why do we use `ClientIndex`s over `ClientId`s for `Server`s methods?
This may be a dumb question.
For methods like Server.send, why do we take the ClientIndex as an arg over the ClientId? ClientIndex feels like a implementation detail, and ClientId feels like the key/unique ID of the client. Maybe I'm missing something though.
@benjamin-kirkbride The idea was to stay as close as possible to the upstream C implementation, which also uses client indexes in its external API: https://github.com/mas-bandwidth/netcode/blob/main/netcode.h#L237
You can use netcode::Server::client_id to get a ClientId from a ClientIndex
the upstream C implementation, which also uses client indexes in its external API
gotcha, makes sense why you did that then. Still not sure why it is that way.. but if that is the idiomatic way I will have the Python bindings do it that way as well.
Is there a way to get a list of connected ClientIndex? is the expectation that store them as they connect out of band, somehow?
presumably when sending out tokens ? but I don't see a way to query the status of a ClientIndex from the server?
Is the idea to run num_connected_clients then use that to create n ClientIndexs? I see:
pub(crate) fn iter_clients(&self) -> impl Iterator<Item = ClientIndex> + '_ {
self.conn_cache
.clients
.iter()
.filter(|(_, c)| c.is_connected())
.map(|(idx, _)| ClientIndex(idx))
}
in a test, which seems quite useful, but it's not actually part of the public API, right ?
Okay, after looking at https://github.com/benny-n/netcode/blob/main/examples/echo.rs am I correct in my thinking that the only way to get ClientIndexs for connected clients is by setting a callback to the on_connect method?
I was hoping to defer creating bindings for that feature (no idea how to map a python function as a callback for a rust function, probably complicated), but that leaves me in a rough spot.
How do you feel about a few methods being added to server to query the connection cache, iterate over it, etc?
I think I'd like to be able to implement the following things that I believe to be impossible currently in the Python bindings, and therefore would need to make changes to the Rust Crate (but am very open to feedback!!)
class Server:
clients: Iterable[ClientIndex]
client_addresses: Dict[Address: ClientIndex]
client_ids: Dict[ClientID: ClientIndex]
client_states: Dict[ClientState: Iterable[ClientIndex]]
Is there a way to get a list of connected
ClientIndex? is the expectation that store them as they connect out of band, somehow?
Yep, that's the expectation.
I was hoping to defer creating bindings for that feature (no idea how to map a python function as a callback for a rust function, probably complicated), but that leaves me in a rough spot.
I don't think there's a big difference in difficulty between that and other bindings, wouldn't it be just a lambda with **kwargs?
Anyway, IMO you shouldn't skip this feature. I think it's going to be hard getting by without having your own callbacks when clients connect/disconnect, in any non-trivial application.
How do you feel about a few methods being added to
serverto query the connection cache, iterate over it, etc?
I'll be honest with you, not too good actually. Making a lot of helper methods usually makes an API more hard to understand, and easier to misuse.
As mentioned above, the expectation from the users of the crate is to manage their own collection of client indexes, and hook into the on_connect/on_disconnect callbacks to update that collection.
There's also a Server::send_all method for broadcasts to all the connected clients.
I would prefer if you investigated the callbacks approach first, and if you can provide more technical details about why it's very hard (or impossible) to do with python bindings, I will consider making iter_clients public (and then when you have a ClientIndex, IDs and addresses are simple to obtain with Server::client_id and Server::client_addr)
Those are fair points. It's kind of moot right now because I'm having trouble getting the clients to actually connect as is, but I'll circle back around after I figure that out. Thanks!