package room import ( "github.com/rs/xid" "go.uber.org/zap/zapcore" "hexmap-server/action" ) // ClientMessage marks messages coming from clients to the room. type ClientMessage interface { zapcore.ObjectMarshaler // SourceID is the id of the client sending the message. ClientID() xid.ID } // JoinRequest is the message sent on the room's IncomingChannel by a new client joining the room. type JoinRequest struct { // id is the SourceID the client will use to identify itself in future messages. id xid.ID // returnChannel is a buffered channel the client is ready to receive messages from the room on. // This becomes the Client's OutgoingChannel. returnChannel chan<- Message // privateChannel is true iff the room can close returnChannel after completing a shutdown handshake. // This permits extra safety by causing channels that somehow leak into other contexts to become noticeable by // causing panics. privateChannel bool // broadcast is true iff the room should send action.Syncable from other clients to this one. broadcast bool // wantCurrentState indicates that the client would like the room to include a copy of the current state of the room // when it joins. wantCurrentState bool } func (j JoinRequest) MarshalLogObject(encoder zapcore.ObjectEncoder) error { encoder.AddString("type", "JoinRequest") encoder.AddString("id", j.id.String()) encoder.AddBool("broadcast", j.broadcast) encoder.AddBool("wantCurrentState", j.wantCurrentState) return nil } func (j JoinRequest) ClientID() xid.ID { return j.id } // RefreshRequest is the message sent on the room's IncomingChannel by a client which needs the current value. type RefreshRequest struct { id xid.ID } func (r RefreshRequest) MarshalLogObject(encoder zapcore.ObjectEncoder) error { encoder.AddString("type", "RefreshRequest") encoder.AddString("id", r.id.String()) return nil } func (r RefreshRequest) ClientID() xid.ID { return r.id } // ApplyRequest is the message sent on the room's IncomingChannel by a client which has received an action from the // websocket. type ApplyRequest struct { id xid.ID action action.IDed } func (f ApplyRequest) MarshalLogObject(encoder zapcore.ObjectEncoder) error { encoder.AddString("type", "ApplyRequest") encoder.AddString("id", f.id.String()) return encoder.AddObject("action", f.action) } func (f ApplyRequest) ClientID() xid.ID { return f.id } // LeaveRequest is the message sent on the room's IncomingChannel by a client which is shutting down. // The client is indicating that it will send no messages except a possible ShutdownResponse, in the event that a // LeaveRequest and a ShutdownRequest cross paths midflight. type LeaveRequest struct { id xid.ID } func (l LeaveRequest) MarshalLogObject(encoder zapcore.ObjectEncoder) error { encoder.AddString("type", "LeaveRequest") encoder.AddString("id", l.id.String()) return nil } func (l LeaveRequest) ClientID() xid.ID { return l.id } // StopRequest is the message sent on the room's IncomingChannel by a client which wants to make the room shut down. // The response to a StopRequest is a ShutdownRequest, which should be handled as normal. type StopRequest struct { id xid.ID } func (s StopRequest) MarshalLogObject(encoder zapcore.ObjectEncoder) error { encoder.AddString("type", "StopRequest") encoder.AddString("id", s.id.String()) return nil } func (s StopRequest) ClientID() xid.ID { return s.id } // ShutdownResponse is the message sent on the room's IncomingChannel by a client which has accepted the room's ShutdownRequest. type ShutdownResponse struct { id xid.ID } func (s ShutdownResponse) MarshalLogObject(encoder zapcore.ObjectEncoder) error { encoder.AddString("type", "ShutdownResponse") encoder.AddString("id", s.id.String()) return nil } func (s ShutdownResponse) ClientID() xid.ID { return s.id }