-> (PieceUpdateOp<()>, Vec<LogEntry>);
}
-pub trait Lens {
+pub trait Lens : Debug {
fn pieceid2visible(&self, piece: PieceId) -> VisiblePieceId;
fn log_pri(&self, piece: PieceId, pc: &PieceState)
-> PieceRenderInstructions;
fn decode_visible_pieceid(&self, vpiece: VisiblePieceId, player: PlayerId)
-> PieceId;
}
+#[derive(Debug)]
pub struct TransparentLens {
// when lenses become nontrivial, make this nonconstructable
// to find all the places where a TransparentLens was bodged
let mut buf = PrepareUpdatesBuffer::new(g, Some((client, form.cseq)),
Some(1 + logents.len()));
- buf.piece_update(piece, update, &lens)?;
- buf.log_updates(logents)?;
+ buf.piece_update(piece, update, &lens);
+ buf.log_updates(logents);
eprintln!("API {:?} OK", &form);
}
let mut buf = PrepareUpdatesBuffer::new(g, None, Some(estimate));
for (upiece, uuop) in upieces {
let lens = TransparentLens { };
- buf.piece_update(upiece, uuop, &lens)?;
+ buf.piece_update(upiece, uuop, &lens);
}
- buf.log_updates(ulogs)?;
+ buf.log_updates(ulogs);
},
}
}
let mut buf = PrepareUpdatesBuffer::new(g, None, None);
for (upiece, uuop) in bulk.pieces {
let lens = TransparentLens { };
- buf.piece_update(upiece, uuop, &lens)?;
+ buf.piece_update(upiece, uuop, &lens);
}
buf.log_updates(vec![LogEntry {
html: "The facilitator (re)configured the game".to_owned(),
// xxx use cs.desc
- }])?;
+ }]);
},
Online => { },
}
op : PieceUpdateOp<PreparedPieceState>,
},
Log (Arc<LogEntry>),
+ RenderingError,
}
#[derive(Debug,Serialize)]
op : &'u PieceUpdateOp<PreparedPieceState>,
},
Log (&'u LogEntry),
+ ServerUpdateGenerationError,
}
// ========== implementation ==========
Log(logent) => {
logent.html.as_bytes().len() * 3
}
+ RenderingError => {
+ 100
+ }
}
}
}
}
#[throws(SVGProcessingError)]
- pub fn piece_update(&mut self, piece: PieceId, update: PieceUpdateOp<()>,
- lens: &dyn Lens) {
+ fn piece_update_fallible(&mut self, piece: PieceId,
+ update: PieceUpdateOp<()>,
+ lens: &dyn Lens) -> PreparedUpdateEntry {
let gs = &mut self.g.gs;
- // xxx check pos is within range, everywhere
+ // xxx enforce pos is within range, everywhere
let (update, piece) = match gs.pieces.byid_mut(piece) {
Ok(pc) => {
}
};
- self.us.push(PreparedUpdateEntry::Piece {
+ PreparedUpdateEntry::Piece {
piece,
client : self.by_client,
sameclient_cseq : self.cseq,
op : update,
- });
+ }
+ }
+
+ pub fn piece_update(&mut self, piece: PieceId, update: PieceUpdateOp<()>,
+ lens: &dyn Lens) {
+ // Caller needs us to be infallible since it is too late by
+ // this point to back out a game state change.
+
+ let update = self.piece_update_fallible(piece, update, lens)
+ .unwrap_or_else(|e| {
+ eprintln!("piece update error! piece={:?} lens={:?} error={:?}",
+ piece, &lens, &e);
+ PreparedUpdateEntry::RenderingError
+ });
+ self.us.push(update);
}
- #[throws(SVGProcessingError)]
pub fn log_updates(&mut self, logents: Vec<LogEntry>) {
for logentry in logents {
let logentry = Arc::new(logentry);
PreparedUpdateEntry::Log(logent) => {
TransmitUpdateEntry::Log(&logent)
},
+ PreparedUpdateEntry::RenderingError => {
+ TransmitUpdateEntry::ServerUpdateGenerationError
+ }
};
ents.push(ue);
};