package com.chuangzhou.vivid2D.block; import com.google.gson.Gson; import com.google.gson.JsonSyntaxException; /** * 一个专门用于处理来自Blockly前端的JSON消息的处理器。 * 它负责解析请求,并将其分派给Vivid2DRendererBridge中的相应方法。 */ public class BlocklyMessageHandler { private final Vivid2DRendererBridge rendererBridge = new Vivid2DRendererBridge(); private final Gson gson = new Gson(); /** * 用于Gson解析JSON请求的内部数据结构类。 * 它必须与JavaScript中构建的request对象结构匹配。 * { "action": "...", "params": { ... } } */ private static class RequestData { String action; java.util.Map params; } /** * 尝试处理传入的请求字符串。 * * @param request 从JavaScript的onQuery回调中接收到的原始字符串。 * @return 如果请求被成功识别并处理,则返回 true;否则返回 false。 */ public boolean handle(String request) { try { // 1. 尝试将请求字符串解析为我们预定义的RequestData结构 RequestData data = gson.fromJson(request, RequestData.class); // 2. 验证解析结果。如果不是有效的JSON或缺少action字段,则这不是我们能处理的请求。 if (data == null || data.action == null) { return false; } // 3. 使用 switch 语句根据 action 的值将请求分派到不同的处理方法 switch (data.action) { case "moveObject": // 从参数Map中提取所需数据 String objectIdMove = data.params.get("objectId").toString(); // JSON数字默认被Gson解析为Double,需要转换 int x = ((Double) data.params.get("x")).intValue(); int y = ((Double) data.params.get("y")).intValue(); // 调用实际的业务逻辑 rendererBridge.moveObject(objectIdMove, x, y); // 表示我们已经成功处理了这个请求 return true; case "changeColor": // 从参数Map中提取所需数据 String objectIdColor = data.params.get("objectId").toString(); String colorHex = data.params.get("colorHex").toString(); // 调用实际的业务逻辑 rendererBridge.changeColor(objectIdColor, colorHex); // 表示我们已经成功处理了这个请求 return true; // 在这里可以为未来新的积木添加更多的 case ... default: // 请求是合法的JSON,但action是我们不认识的。记录一下,但不处理。 System.err.println("BlocklyMessageHandler: 收到一个未知的操作(action): " + data.action); return false; } } catch (JsonSyntaxException | ClassCastException | NullPointerException e) { // 如果发生以下情况,说明这个请求不是我们想要的格式: // - JsonSyntaxException: 字符串不是一个有效的JSON。 // - ClassCastException: JSON中的数据类型与我们预期的不符(例如,x坐标是字符串)。 // - NullPointerException: 缺少必要的参数(例如,params中没有"x"这个键)。 // 在这些情况下,我们静默地失败并返回false,让其他处理器有机会处理这个请求。 return false; } } }