3.0 KiB
3.0 KiB
| name | description |
|---|---|
| demo | W-07 实时演示模块 —— demo 会话管理、three.js 预览、状态隔离(演示改动不污染正式数据)、多人预览。开发/修改 demo 相关功能前必读。 |
demo 模块技能
架构
- 交互层业务模块(有自己的数据表 + dspy + bricks 前端),通过
load_demo(env)挂到宿主。 - 依赖宿主提供:sqlor/ahserver/ServerEnv;跨模块校验 world 存在性时按需用 world 模块(防御式 try/except)。
数据模型(models/*.json)
| 表 | 作用 | 关键字段 |
|---|---|---|
| demo_session | 演示会话 | status(preview/paused/ended), camera_mode(orbit/topdown/firstperson), viewer_count, extra_json |
| demo_session_state | 实体状态覆盖层 | session_id, entity_id, base_json(基线), demo_json(当前) |
| demo_hot_script | 热加载脚本 | session_id, script_id, script_type(python/expr), script_content |
| demo_presence | 多人预览在线 | session_id, user_id, user_name, last_seen_at |
关键端点(wwwroot/api/*.dspy,全部 logined)
start.dspy— world_id 必填;重复开始同世界 → 409stop.dspy— 删除覆盖层/脚本/在线表(状态隔离核心)entity_edit.dspy— session_id+entity_id+fields(对象) 必填;只写覆盖层entity_attrs.dspy— 返回 base/demo/mergedhotload.dspy— 语法校验(compile)通过才落库;SyntaxError → 400camera.dspy— camera_mode 白名单 orbit/topdown/firstpersonpause.dspy— paused=true/falsepresence.dspy— action=join/leave,viewer_count 实时回写fullscreen.dspy— enabled true/false,写入 extra_jsonstate.dspy— 前端 500ms 轮询,聚合实体状态+脚本+在线人数
状态机(会话级)
preview ⇄ paused(pause.dspy);preview/paused → ended(stop.dspy,唯一出口);ended 后任何操作 → 400。
模块专属坑
- 状态隔离是硬约束:任何实体修改只允许写
demo_session_state,严禁写 entity/scene/world 正式表。stop_demo 必须级联删除 3 张子表,否则正式数据被"演示污染"。 - 三处同步注册:新增函数必须同步 demo/demo.py、demo/init.py、demo/init.py 三处(env.xxx = xxx)。
- 异常→状态码映射:DemoParamError→400、DemoNotFoundError→404、DemoDuplicateError→409、DemoStateError→400;dspy 里必须 try/except 后返回
{"status":..., "message":...}。 - sor.C 必须显式带 created_at:sqlor 不自动补时间戳,缺 created_at 会导致插入静默丢失。
- dspy 禁止 import:所有函数经 load_demo 注册为全局;dspy 里直接
await start_demo(...)。 - 取库名:
get_module_dbname('demo')(dspy 全局)或ServerEnv().get_module_dbname('demo')(.py),禁止硬编码 DBNAME。 - dspy 显式 return:ahserver 包裹 async 函数,裸表达式返回 None。
- 前端
.js里可用 fetch/setInterval(非 script actiontype);bricks script actiontype 内禁止 fetch/setInterval。