From 038900de511f4c1f9f89202c62480b10d6509a2c Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Sat, 11 Jul 2020 15:57:35 +0100 Subject: [PATCH] wip new z --- src/bin/server.rs | 9 +++-- src/gamestate.rs | 10 +++++ src/global.rs | 11 +++++- src/sse.rs | 5 ++- templates/script.ts | 88 +++++++++++++++++++++++++++++++----------- templates/session.tera | 1 + 6 files changed, 94 insertions(+), 30 deletions(-) diff --git a/src/bin/server.rs b/src/bin/server.rs index 97ac32b0..726eb590 100644 --- a/src/bin/server.rs +++ b/src/bin/server.rs @@ -102,12 +102,14 @@ fn session(form : Json) -> Result { Some(o) => format!("{}",o), }; uses.push(format!( - r##""##, + r##""##, pri.id_use(), pri.id_piece(), pri.id, &gplayer, - pr.pos[0], pr.pos[1])); + pr.pos[0], pr.pos[1], + pr.zlevel.0, pr.zlevel.1, + )); } let src = SessionRenderContext { @@ -231,7 +233,6 @@ fn api_piece_op(form : Json>) client, sameclient_cseq : form.cseq, piece : pri_for_all.id, - zg : pc.zlevel.1, op : update, }); @@ -323,7 +324,7 @@ impl ApiPieceOp for ApiPieceUngrab { struct ApiPieceRaise { z : ZCoord, } -#[post("/_/api/raise", format="json", data="
")] +#[post("/_/api/setz", format="json", data="")] #[throws(OE)] fn api_raise(form : Json>) -> impl response::Responder<'static> { diff --git a/src/gamestate.rs b/src/gamestate.rs index f6169ee5..3d1f17b0 100644 --- a/src/gamestate.rs +++ b/src/gamestate.rs @@ -13,6 +13,11 @@ pub struct Generation (pub u64); impl Generation { pub fn increment(&mut self) { self.0 += 1 } } +impl Display for Generation { + fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { + Display::fmt(&self.0,f) + } +} visible_slotmap_key!{ VisiblePieceId('.') } @@ -69,6 +74,11 @@ impl Ord for ZCoord { } } impl Eq for ZCoord { } +impl Display for ZCoord { + fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { + Display::fmt(&self.0,f) + } +} #[derive(Debug)] pub struct PieceRecord { diff --git a/src/global.rs b/src/global.rs index f1910733..850a8516 100644 --- a/src/global.rs +++ b/src/global.rs @@ -30,7 +30,6 @@ pub enum PreparedUpdateEntry { sameclient_cseq : ClientSequence, piece : VisiblePieceId, op : PieceUpdateOp, - zg : Generation, }, Log (Arc), } @@ -84,6 +83,16 @@ impl PieceUpdateOp { SetZLevel(zl) => SetZLevel(zl), } } + pub fn new_z_generation(&self) -> Option { + use PieceUpdateOp::*; + match self { + Delete() => None, + Insert(_) => None, + Modify(_) => None, + Move(_) => None, + SetZLevel((_,zg)) => Some(*zg), + } + } } #[derive(Debug)] diff --git a/src/sse.rs b/src/sse.rs index 296b57f4..fe2b43b3 100644 --- a/src/sse.rs +++ b/src/sse.rs @@ -51,7 +51,7 @@ enum TransmitUpdate<'u> { Recorded { piece : VisiblePieceId, cseq : ClientSequence, - zg : Generation, + zg : Option, }, Piece { piece : VisiblePieceId, @@ -95,8 +95,9 @@ impl Read for UpdateReader { for u in &next.us { let tu = match u { &PreparedUpdateEntry::Piece - { piece, client, sameclient_cseq : cseq, zg, .. } + { piece, client, sameclient_cseq : cseq, ref op } if client== self.client => { + let zg = op.new_z_generation(); TransmitUpdate::Recorded { piece, cseq, zg } }, &PreparedUpdateEntry::Piece { piece, ref op, .. } => { diff --git a/templates/script.ts b/templates/script.ts index da9ee814..b6d03339 100644 --- a/templates/script.ts +++ b/templates/script.ts @@ -13,6 +13,7 @@ // .piece piece id (static) // .gplayer grabbed user (player id string, or "") // .cseq client sequence (see PROTOCOL.md) +// .z, .zg Z level // container to allow quick movement and hang stuff off // // delem @@ -60,6 +61,7 @@ var ctoken : string; var svg_ns : string; var space : SVGGraphicsElement; +var def_marker : SVGGraphicsElement; var logdiv : HTMLElement; var status_node : HTMLElement; @@ -129,12 +131,16 @@ function api_piece(f: (meth: string, payload: Object) => void, }) } +function svg_element(id: string): SVGGraphicsElement | null { + let elem = document.getElementById(id); + return elem as unknown as (SVGGraphicsElement | null); +} function piece_element(base: string, piece: PieceId): SVGGraphicsElement | null { - let elem = document.getElementById(base+piece); - return elem as unknown as (SVGGraphicsElement | null); + return svg_element(base+piece); } + // ----- clicking/dragging pieces ----- enum DRAGGING { // bitmask @@ -227,24 +233,21 @@ function drag_mousemove(e: MouseEvent) { function drag_mouseup(e: MouseEvent) { console.log('mouseup', dragging); let ddr2 : number = drag_mousemove(e); - let piece = drag_uelem!.dataset.piece!; + let uelem = drag_uelem!; + let piece = uelem.dataset.piece!; let pelem = piece_element('piece',piece)!; let dragraise = +pelem.dataset.dragraise!; console.log('CHECK RAISE ', dragraise, dragraise*dragraise, ddr2); if (dragraise > 0 && ddr2 >= dragraise*dragraise) { - let marker = piece_element('raisemarker',piece); - if (marker == null) { - marker = document.createElementNS(svg_ns,'defs')! as - SVGGraphicsElement; - marker.setAttributeNS(null,'id','raisemarker'+piece); - drag_uelem!.parentNode!.insertBefore(marker, drag_uelem!); - } - raise_piece(drag_uelem!); - api_piece(api, "raise", piece, drag_uelem!, { }); + piece_set_zlevel(uelem, (old_top) => { + let z = old_top.dataset.z! + 1; + uelem.dataset.z = z; + api_piece(api, "setz", piece, uelem, { z: z }); + }); } if (dragging == DRAGGING.MAYBE_UNGRAB || dragging == (DRAGGING.MAYBE_GRAB | DRAGGING.YES)) { - set_ungrab(drag_uelem!, pelem); + set_ungrab(uelem, pelem); api_piece(api, 'ungrab', piece, drag_uelem!, { }); } drag_cancel(); @@ -315,14 +318,36 @@ pieceops.Modify = function console.log('MODIFY DONE'); } -function raise_piece(uelem: SVGGraphicsElement) { - uelem.parentElement!.appendChild(uelem); +function piece_set_zlevel(uelem: SVGGraphicsElement, + modify : (old_top: SVGGraphicsElement) => void) { + // Calls modify, which should set .dataset.z and/or .gz, and/or + // make any necessary API call. + // + // Then moves uelem to the right place in the DOM. This is done + // by assuming that uelem ought to go at the end, so this is + // O(new depth), which is right (since the UI for inserting + // an object is itself O(new depth) UI operations to prepare. +/* + let old_top = def_marker.previousElementSibling! as unknown as SVGGraphicsElement; + modify(old_top); + let container = uelem.parentElement!; + container.insertBefore(def_marker, uelem); + + let previous = uelem | null; + while ((previous = previous.previousElementSibling) != null && + piece_z_before(uelem, previous)) { + } + if (previous != uelem) { + constainer.insertAfter(previous, uelem); + } +*/ } - -pieceops.Raise = function -(piece, info: { } ) { - var uelem = piece_element('use',piece)!; - raise_piece(uelem); +function piece_z_before(a: SVGGraphicsElement, b: SVGGraphicsElement) { + if (+(a.dataset.z !) < +(b.dataset.z !)) return true; + if (+(a.dataset.z !) > +(b.dataset.z !)) return false; + if (+(a.dataset.zg!) < +(b.dataset.zg!)) return true; + if (+(a.dataset.zg!) > +(b.dataset.zg!)) return false; + return false; } pieceops.Move = function @@ -333,10 +358,20 @@ pieceops.Move = function uelem.setAttributeNS(null, "y", info[1]+""); } +pieceops.SetZLevel = function +(piece, info: { z: Number, zg: Generation }) { + let uelem = piece_element('use',piece)!; + piece_set_zlevel(uelem, (old_top)=>{ + uelem.dataset.z = info.z +""; + uelem.dataset.zg = info.zg+""; + }); +} + messages.Recorded = function -(j: { piece: PieceId, cseq: ClientSeq, gen: Generation } ) { +(j: { piece: PieceId, cseq: ClientSeq, gen: Generation, + zg: Generation|null } ) { let piece = j.piece; - var uelem = document.getElementById('use'+piece)!; + var uelem = piece_element('use',piece)!; if (uelem.dataset.cseq != null && j.cseq >= +uelem.dataset.cseq) { delete uelem.dataset.cseq; let marker = piece_element('raisemarker',piece); @@ -344,6 +379,11 @@ messages.Recorded = function marker.remove(); } } + if (j.zg != null) { + piece_set_zlevel(uelem, (old_top: SVGGraphicsElement)=>{ + uelem.dataset.zg = j.zg+""; + }); + } gen = j.gen; } @@ -365,8 +405,10 @@ function startup() { gen = +body.dataset.gen!; status_node = document.getElementById('status')!; status_node.innerHTML = 'js-done'; - space = document.getElementById('space') as unknown as SVGGraphicsElement; logdiv = document.getElementById("log")!; + + space = svg_element('space')!; + def_marker = svg_element("def_marker")!; svg_ns = space.getAttribute('xmlns')!; var es = new EventSource("/_/updates/"+ctoken+'/'+gen); diff --git a/templates/session.tera b/templates/session.tera index fbcf1b02..c5b03d5f 100644 --- a/templates/session.tera +++ b/templates/session.tera @@ -17,6 +17,7 @@ {%- for piece in uses %} {{piece}} {%- endfor %} + {%- for piece in defs %} {{ piece.1 }} {%- endfor %} -- 2.30.2