let cl = &g.clients.byid(client)?;
// ^ can only fail if we raced
let player = cl.player;
+ let pl = g.gs.players.byid(player)?;
+ let g_updates = &mut g.updates;
+ let gs_pieces = &mut g.gs.pieces;
+ let gs_gen = &mut g.gs.gen;
let r : Result<(),GameError> = (||{
let piece = decode_visible_pieceid(form.piece);
- let gs = &mut g.gs;
- let p = gs.pieces.byid_mut(piece)?;
+ let p = gs_pieces.byid_mut(piece)?;
let q_gen = form.gen;
let u_gen =
if client == p.lastclient { p.gen_lastclient }
if u_gen > q_gen { Err(GameError::Conflict)? }
if p.held != None { Err(GameError::PieceHeld)? };
p.held = Some(player);
- gs.gen.increment();
- let gen = gs.gen;
+ gs_gen.increment();
+ let gen = *gs_gen;
if client != p.lastclient {
p.gen_before_lastclient = p.gen_lastclient;
p.lastclient = client;
let op = PieceUpdateOp::Modify(p.prep_piecestate(&pri));
let update = PreparedUpdate {
gen,
- us : vec![ PreparedUpdateEntry::Piece {
- client,
- sameclient_cseq : form.cseq,
- piece : vpiece,
- op,
- }],
+ us : vec![
+ PreparedUpdateEntry::Piece {
+ client,
+ sameclient_cseq : form.cseq,
+ piece : vpiece,
+ op,
+ },
+ PreparedUpdateEntry::Log {
+ msg : Arc::new(format!("{} grasped {}",
+ &htmlescape::encode_minimal(&pl.nick),
+ p.describe_html(&pri)
+ // split view: pri should be global
+ // (currently log is one global view)
+ )),
+ },
+ ],
};
let update = Arc::new(update);
eprintln!("UPDATE {:?}", &update);
// split vie wthing would go here, see also update.piece
p.gen_lastclient = gen;
- for (_tplayer, tplupdates) in &mut g.updates {
+ for (_tplayer, tplupdates) in g_updates {
tplupdates.log.push_back(update.clone());
tplupdates.cv.notify_all();
}
fn svg_select(&self, pri : &PieceRenderInstructions) -> String;
fn svg_x_ids(&self) -> VisiblePieceIdSvgIds;
fn svg_x_defs(&self, pri : &PieceRenderInstructions) -> String;
+ fn describe_html(&self, face : Option<FaceId>) -> String;
}
#[derive(Debug)]
// xxx want all piece's stuff in the same def
}
}
+
+ pub fn describe_html(&self, pri : &PieceRenderInstructions) -> String {
+ // xxx want to be able to hide things
+ self.p.describe_html(Some(pri.face))
+ }
}
#[derive(Debug)]
op : PieceUpdateOp<PreparedPieceState>,
},
Log {
+ msg : Arc<String>,
},
}
impl PreparedUpdateEntry {
50 +
op.new_state().map(|x| x.svg.len()).unwrap_or(0)
},
- Log { .. } => {
- todo!("json length of log")
+ Log { msg } => {
+ msg.as_bytes().len() * 3
}
}
}
#[derive(Debug)]
struct SimpleShape {
+ desc : String,
shape : String,
colours : IndexVec<FaceId,Colour>,
}
fn svg_x_defs(&self, pri : &PieceRenderInstructions) -> String {
format!(r#"<g id={}>{}</g>"#, pri.id_x("base"), self.shape)
}
+ fn describe_html(&self, face : Option<FaceId>) -> String {
+ if let Some(face) = face {
+ format!("a {} {}", self.colours[face], self.desc)
+ } else {
+ format!("a {}", self.desc)
+ }
+ }
}
pub fn xxx_make_pieces() -> Vec<(Pos, Box<dyn Piece>)> {
vec![
([ 90, 80 ],
Box::new(SimpleShape {
+ desc : "circle".to_owned(),
shape : r#"<circle cx="0" cy="0" r="10"/>"#.to_owned(),
colours : index_vec![ "red".to_string(), "grey".to_string() ],
})),
([ 90, 60 ],
Box::new(SimpleShape {
+ desc : "square".to_owned(),
shape : r#"<rect x="-10" y="-10" width="20" height="20"/>"#.to_owned(),
colours : index_vec![ "blue".to_string(), "grey".to_string() ],
})),
op : &'u PieceUpdateOp<PreparedPieceState>,
},
Log {
+ msg : &'u str,
},
}
&PreparedUpdateEntry::Piece { piece, ref op, .. } => {
TransmitUpdate::Piece { piece, op }
},
- PreparedUpdateEntry::Log { } => {
- TransmitUpdate::Log { }
+ PreparedUpdateEntry::Log { msg } => {
+ TransmitUpdate::Log { msg }
},
};
serde_json::to_writer(&mut buf, &tu)?;
return Err(io::Error::new(io::ErrorKind::WouldBlock,
FlushWouldBlockError{}));
}
+ // xxx this endless stream is a leak
+ // restart it occasionally
amig = cv.wait_timeout(amig, UPDATE_KEEPALIVE)
.map_err(|_| em("poison"))?.0;
// ----- logs -----
-messages.LogUpdate = function(data) {
+messages.Log = function(j) {
lastent = logdiv.lastElementChild;
in_scrollback =
// inspired by
lastent.getBoundingClientRect().bottom >
logdiv.getBoundingClientRect().bottom;
- console.log('LOG UPDATE ',in_scrollback,data);
+ console.log('LOG UPDATE ',in_scrollback, j);
if (!in_scrollback) {
lastent = logdiv.lastElementChild;