#[allow(non_camel_case_types)] type PUE_P = PreparedUpdateEntry_Piece;
#[allow(non_camel_case_types)] type TUE_P<'u> = TransmitUpdateEntry_Piece<'u>;
+#[allow(non_camel_case_types)] type PUE_I = PreparedUpdateEntry_Image;
+#[allow(non_camel_case_types)] type TUE_I<'u> = TransmitUpdateEntry_Image<'u>;
// ---------- newtypes, type aliases, basic definitions ----------
#[derive(Debug)]
pub enum PreparedUpdateEntry {
Piece(PreparedUpdateEntry_Piece),
+ Image(PreparedUpdateEntry_Image),
SetTableSize(Pos),
SetTableColour(Colour),
SetLinks(Arc<LinksTable>),
ops: SecondarySlotMap<PlayerId, PreparedPieceUpdate>,
}
+pub type PreparedPieceUpdate = PreparedPieceUpdateGeneral<
+ PieceUpdateOp<PreparedPieceState, ZLevel>
+ >;
+
+#[allow(non_camel_case_types)]
#[derive(Debug,Clone)]
-pub struct PreparedPieceUpdate {
+pub struct PreparedUpdateEntry_Image {
+ ims: SecondarySlotMap<PlayerId, PreparedPieceUpdateGeneral<
+ PreparedPieceImage
+ >>,
+}
+
+#[derive(Debug,Clone)]
+pub struct PreparedPieceUpdateGeneral<U> {
piece: VisiblePieceId,
- op: PieceUpdateOp<PreparedPieceState, ZLevel>,
+ op: U,
}
#[derive(Debug,Clone,Serialize)]
pub uos: Vec<UoDescription>,
}
+#[derive(Debug,Clone,Serialize)]
+pub struct PreparedPieceImage {
+ pub svg: Html,
+ pub uos: Vec<UoDescription>,
+}
+
#[derive(Serialize,Debug)]
pub struct DataLoadPlayer {
dasharray: Html,
}
+pub trait JsonLen {
+ fn json_len(&self) -> usize;
+}
+
+#[ext]
+impl<T:JsonLen> SecondarySlotMap<PlayerId, T> {
+ fn json_len(&self, player: PlayerId) -> usize {
+ if let Some(t) = self.get(player) {
+ 50 + t.json_len()
+ } else {
+ 50
+ }
+ }
+}
+
+impl JsonLen for Html {
+ fn json_len(&self) -> usize { self.0.as_bytes().len() }
+}
+
// ---------- piece updates ----------
#[derive(Debug,Clone,Copy,Serialize)]
svg: Option<&'u Html>, // IsResponseToClientOp::UpdateSvg
},
Piece(TransmitUpdateEntry_Piece<'u>),
+ Image(TransmitUpdateEntry_Image<'u>),
RecordedUnpredictable {
piece: VisiblePieceId,
cseq: ClientSequence,
op: PieceUpdateOp<&'u PreparedPieceState, &'u ZLevel>,
}
+#[allow(non_camel_case_types)]
+#[derive(Debug,Serialize)]
+struct TransmitUpdateEntry_Image<'u> {
+ piece: VisiblePieceId,
+ im: &'u PreparedPieceImage,
+}
+
#[derive(Debug,Serialize)]
struct FormattedLogEntry<'u> {
when: String,
impl PreparedUpdateEntry_Piece {
pub fn json_len(&self, player: PlayerId) -> usize {
- let PUE_P { ref ops, .. } = self;
- if let Some(op) = ops.get(player) {
- 50 +
- op.op.new_state().map(|x| x.svg.0.as_bytes().len()).unwrap_or(0)
- } else {
- 50
- }
+ 50 + self.ops.json_len(player)
+ }
+}
+
+impl<U:JsonLen> JsonLen for PreparedPieceUpdateGeneral<U> {
+ fn json_len(&self) -> usize { self.op.json_len() }
+}
+
+impl<NS:JsonLen, ZL> JsonLen for PieceUpdateOp<NS, ZL> {
+ fn json_len(&self) -> usize {
+ self.new_state().map(|x| x.json_len()).unwrap_or(0)
+ }
+}
+
+impl PreparedUpdateEntry_Image {
+ fn json_len(&self, player: PlayerId) -> usize {
+ self.ims.json_len(player)
}
}
+impl JsonLen for PreparedPieceState {
+ fn json_len(&self) -> usize { self.svg.json_len() + self.uos.json_len() }
+}
+
+impl JsonLen for PreparedPieceImage {
+ fn json_len(&self) -> usize { self.svg.json_len() + self.uos.json_len() }
+}
+impl<T:JsonLen> JsonLen for Vec<T> {
+ fn json_len(&self) -> usize { self.iter().map(|x| x.json_len() + 10).sum() }
+}
+impl JsonLen for UoDescription {
+ fn json_len(&self) -> usize { self.desc.json_len() + 50 }
+}
+
impl PreparedUpdateEntry {
pub fn json_len(&self, player: PlayerId) -> usize {
use PreparedUpdateEntry::*;
Piece(op) => {
op.json_len(player)
}
+ Image(ims) => {
+ ims.json_len(player)
+ }
Log(logent) => {
logent.logent.html.0.as_bytes().len() * 28
}
Some(TUE_P { piece, op: op.map_ref() })
}
+ fn pue_image_to_tue_i(pue_i: &PUE_I, player: PlayerId) -> Option<TUE_I> {
+ let im = pue_i.ims.get(player)?;
+ let PreparedPieceUpdateGeneral { piece, ref op } = *im;
+ Some(TUE_I { piece, im: op })
+ }
+
fn pue_piece_to_tue(pue_p: &PUE_P, player: PlayerId, dest: ClientId)
-> Option<TUE> {
let PUE_P { by_client, ref ops } = *pue_p;
_ => continue,
}
}
+ &PUE::Image(ref pue_i) => {
+ match pue_image_to_tue_i(pue_i, player) {
+ Some(tue) => TUE::Image(tue),
+ _ => continue,
+ }
+ }
PUE::Log(logent) => {
TUE::Log((&tz, &logent))
}
piece_error_handlers.Conflict = <PieceErrorHandler>function()
{ return true ; }
-function piece_modify(piece: PieceId, p: PieceInfo, info: PreparedPieceState,
- conflict_expected: boolean) {
+function piece_modify_image(piece: PieceId, p: PieceInfo,
+ info: PreparedPieceImage) {
p.delem.innerHTML = info.svg;
p.pelem= piece_element('piece',piece)!;
+ p.uos = info.uos;
+}
+
+function piece_modify(piece: PieceId, p: PieceInfo, info: PreparedPieceState,
+ conflict_expected: boolean) {
+ piece_modify_image(piece, p, info);
p.uelem.setAttributeNS(null, "x", info.pos[0]+"");
p.uelem.setAttributeNS(null, "y", info.pos[1]+"");
p.held = info.held;
p.pinned = info.pinned;
p.angle = info.angle;
- p.uos = info.uos;
piece_set_zlevel(piece,p, (oldtop_piece)=>{
p.z = info.z;
p.zg = info.zg;
console.log('MODIFY DONE');
}
+type PreparedPieceImage = {
+ svg: string,
+ uos: UoDescription[],
+}
+
+type TransmitUpdateEntry_Image = {
+ piece: PieceId,
+ im: PreparedPieceImage,
+};
+
+messages.Image = <MessageHandler>function(j: TransmitUpdateEntry_Image) {
+ console.log('IMAGE UPDATE ',j)
+ var piece = j.piece;
+ let p = pieces[piece]!;
+ piece_modify_image(piece, p, j.im);
+ redisplay_ancillaries(piece,p);
+ recompute_keybindings();
+ console.log('IMAGE DONE');
+}
+
/*
pieceops.Insert = <PieceHandler>function
(piece: PieceId, p: null,