diff options
| author | Cliff Click <cliffc@acm.org> | 2026-09-21 21:26:03 -0700 |
|---|---|---|
| committer | Cliff Click <cliffc@acm.org> | 2026-09-21 21:26:03 -0700 |
| commit | e587a11049129866bf3fd6db0a0f72d44ad6b39f (patch) | |
| tree | 6282cc18061dfe9e2835847b535794137f047a2c /chapter25/src/main/java/com | |
| parent | 21b9bdf9da645a9b392db0e7ec132fb9aeed5339 (diff) | |
| download | Simple-e587a11049129866bf3fd6db0a0f72d44ad6b39f.tar.gz Simple-e587a11049129866bf3fd6db0a0f72d44ad6b39f.zip | |
Change protocol between compiler and browser
Diffstat (limited to 'chapter25/src/main/java/com')
| -rw-r--r-- | chapter25/src/main/java/com/seaofnodes/simple/print/JSViewer.java | 24 | ||||
| -rw-r--r-- | chapter25/src/main/java/com/seaofnodes/simple/print/SimpleWebSocket.java | 30 |
2 files changed, 34 insertions, 20 deletions
diff --git a/chapter25/src/main/java/com/seaofnodes/simple/print/JSViewer.java b/chapter25/src/main/java/com/seaofnodes/simple/print/JSViewer.java index 156f1fe9..a9f6bfd4 100644 --- a/chapter25/src/main/java/com/seaofnodes/simple/print/JSViewer.java +++ b/chapter25/src/main/java/com/seaofnodes/simple/print/JSViewer.java @@ -1,5 +1,6 @@ package com.seaofnodes.simple.print; +import com.seaofnodes.graph.GraphJson; import com.seaofnodes.simple.codegen.CodeGen; import com.seaofnodes.simple.node.*; import com.seaofnodes.simple.type.*; @@ -11,8 +12,10 @@ import java.nio.file.Files; import java.nio.file.Path; import java.net.URI; import java.util.Collection; +import java.util.ArrayList; import java.util.Arrays; import java.util.Stack; +import java.util.UUID; import static com.seaofnodes.simple.codegen.CodeGen.CODE; public class JSViewer implements AutoCloseable { @@ -28,7 +31,9 @@ public class JSViewer implements AutoCloseable { // WebSocket to the browser for display static SimpleWebSocket SERVER; - static int N; // Dot frames + static long N; // Snapshot step within this compilation + static String COMP; + static final SimpleGraphAdapter GRAPH = new SimpleGraphAdapter(); JSViewer() throws Exception { // Launch server; handshake @@ -60,6 +65,7 @@ public class JSViewer implements AutoCloseable { System.out.println(src); try { N=0; + COMP = UUID.randomUUID().toString(); // Use parser scope, xscope when building views CodeGen code = new CodeGen(src); SHOW = true; @@ -93,10 +99,19 @@ public class JSViewer implements AutoCloseable { return; boolean midParse = CODE._phase == CodeGen.Phase.Parse; Stack<ScopeNode> xScopes = midParse ? CODE.P._xScopes : null; + var roots = new ArrayList<Node>(); + roots.add(CODE._stop); + if( midParse ) { + roots.add(CODE.P._scope); + roots.addAll(xScopes); + } + long step = N++; + var snap = GRAPH.snap(COMP, step, roots.toArray(Node[]::new)); + int pos = midParse ? CODE.P.pos() : -1; Collection<Node> all = GraphVisualizer.findAll(xScopes, CODE._stop, midParse ? CODE.P._scope: null); SB sb = new SB(); - sb.p("digraph view_").p(N++).p(" {\n").ii(); + sb.p("digraph view_").p(step).p(" {\n").ii(); if( midParse ) sb.i().p("// POS: ").p(CODE.P.pos()).nl(); @@ -139,11 +154,10 @@ public class JSViewer implements AutoCloseable { sb.p("}\n").di(); - // Tell client another DOT frame + // Send the model and its current DOT rendering as one playback frame. String dot = sb.toString(); - System.out.println(dot); try { - SERVER.put(dot); + SERVER.put(GraphJson.frame(snap, pos, dot)); } catch( IOException ioe ) { try { SERVER.close();} catch( IOException ignored ){} } diff --git a/chapter25/src/main/java/com/seaofnodes/simple/print/SimpleWebSocket.java b/chapter25/src/main/java/com/seaofnodes/simple/print/SimpleWebSocket.java index d7fa8bf2..ae500879 100644 --- a/chapter25/src/main/java/com/seaofnodes/simple/print/SimpleWebSocket.java +++ b/chapter25/src/main/java/com/seaofnodes/simple/print/SimpleWebSocket.java @@ -139,7 +139,7 @@ class SimpleWebSocket extends ServerSocket { for( int i=0; i<len; i++ ) _str[i] = (byte)(rawget() ^ _key[i & 3]); - return new String(_str,0,len); + return new String(_str,0,len,StandardCharsets.UTF_8); } // Client closes case 8: return null; @@ -155,24 +155,24 @@ class SimpleWebSocket extends ServerSocket { } } - // Classic put to browser client. No encoding. + // Server text frames are UTF-8 and unmasked. public void put(String msg) throws IOException { - int len = msg.length(); + byte[] bytes = msg.getBytes(StandardCharsets.UTF_8); + int len = bytes.length; + _out.write(129); // FIN, opcode 1 - whole text message if( len <= 125 ) { - _out.write(129); // FIN, opcode 1 - whole text message _out.write(len); - for( int i=0; i<msg.length(); i++ ) - _out.write(msg.charAt(i)); - return; + } else if( len <= 65535 ) { + _out.write(126); + _out.write(len>>>8); + _out.write(len&255); + } else { + _out.write(127); + for( int shift = 56; shift >= 0; shift -= 8 ) + _out.write((int)((long)len >>> shift) & 255); } - if( len > 65535 ) - throw Utils.TODO("MOAR LENGTH"); - _out.write(129); // FIN, opcode 1 - whole text message - _out.write(126); // Length is 16b - _out.write(len>>>8); - _out.write(len&255); - for( int i=0; i<msg.length(); i++ ) - _out.write(msg.charAt(i)); + _out.write(bytes); + _out.flush(); } @Override public void close() throws IOException { |
