Skip to content

feat: autocomplete system, runtime scheduler, IR unification, and compiler purification#14

Merged
ABKQPO merged 144 commits into
ABKQPO:masterfrom
Windorain:autocomplete
Jun 7, 2026
Merged

feat: autocomplete system, runtime scheduler, IR unification, and compiler purification#14
ABKQPO merged 144 commits into
ABKQPO:masterfrom
Windorain:autocomplete

Conversation

@Windorain

@Windorain Windorain commented May 14, 2026

Copy link
Copy Markdown
Collaborator

Summary

为 Guide 编辑器引入 AST 驱动的自动补全系统,并对核心编译与运行时架构进行三个阶段重构:统一调度器替换分散的 Forge 事件订阅、MdAst→MdxJsx IR 统一消除双 AST 表示、编译器纯化将游戏侧工作延迟至 MOUNT 时执行。整体目标是分离编译期与运行时的职责边界,使编译流水线不再依赖 Minecraft 运行时,同时为编辑器提供智能补全能力。


一、自动补全系统

动机: 编辑器缺乏语法感知的补全提示,编写 guide 页面时需手动记忆标签名、属性名和属性值格式。

方案: 基于 MDX AST 的上下文解析器 MdxSyntaxResolver 遍历语法树,根据光标位置判定当前处于标签名、属性名、属性值、frontmatter 键/值、围栏语言还是普通文本。18 个补全提供者按 (MatchType, tagName, attrName) 键注册,支持通配符匹配,覆盖物品、方块、实体、矿物词典、按键绑定、页面引用、锚点、命令、颜色、数值等类别。UI 层面实现 AutocompletePopup 组件,含滚动、高亮、鼠标交互和视口翻转。提交服务依据 AttrType 自动决定引号/大括号包裹和终止符处理。


二、MDX 解析器错误容忍

动机: 编辑过程中输入通常是语法不完整的半成品。原解析器对格式错误的输入抛出异常,导致自动补全无法查询任何语法上下文。

方案: 对 tokenizer 和 AST 编译器进行系统改造,所有用户输入驱动的 throw 替换为 graceful recovery 或递归栈展开。Recovery 产生的 MDX 元素标记 recovered=true,上下文解析器自动跳过这些不完整节点。


三、第 1 阶段 — 统一调度器

动机: 后台工作分散在多个 Forge 事件订阅(GuideWarmupPumpGuideDevWatcherPump),各自独立竞争渲染线程,缺乏优先级和时延控制。

方案: MasterScheduler 以三级优先级队列(HIGH/MEDIUM/LOW)统一管理所有后台工作,每 tick 分配固定预算(4+2+2ms),WorkItem 通过 YIELD/DONE 返回值控制自身生命周期。LytHost 作为统一的运行时引擎,集中管理文档树生命周期、事件分派、脚本执行和页面缓存。NavigationState 整合三个旧单例(GuideScreenMemoryGuideBookmarkStateGuideScreenHomeHistory),ViewportState 封装视口状态。


四、第 2A 阶段 — IR 统一

动机: 编译流水线同时处理原生 Micromark AST(MdAstHeadingMdAstParagraph 等 15+ 种类型)和 MdxJsx 元素,PageCompiler 通过 instanceof 分支区分,新增标签编译器需修改核心代码。

方案: MdAstToMdxConverter 将所有原生 mdast 节点深度优先转换为统一的 MdxJsx 元素(<h1>-<h6><p><a><img><pre><blockquote><table> 等),包括下划线、Mark、剧透等自定义扩展,以及 Kramdown {: ...} 属性行。转换后 PageCompiler 仅需处理 MdxJsxFlowElementMdxJsxTextElementMdAstText 三种节点类型,通过 Map<String, TagCompiler> 策略模式分派。新增 14 个标准元素的 TagCompiler 实现。F3+T 重载通过 parseFrontmatterOnly() 仅提取 YAML(约 200ns/页),首次 getAstRoot() 调用时才触发完整 Micromark 解析。


五、第 3 阶段 — 编译器纯化

动机: 标签编译器在编译阶段直接调用物品注册表、NEI、纹理管理器等运行时 API,导致编译与 Minecraft 运行时紧耦合,且大型页面的编译时工作集中在单帧内导致卡顿。

方案: 21 个标签编译器重构为仅生成轻量级占位符(公开 final 字段的数据容器),实际游戏侧工作由 LytScript 在 MOUNT 时执行。MOUNT 分派分两阶段:同步脚本立即执行;异步脚本排队为 MaterializeTask 并支持 timeToYield() 跨 tick 执行。节点 UID 结果缓存和页面级 LRU 缓存(32 页)避免重复脚本执行;预热管线在浏览当前页面时后台预编译相邻页面。


六、文档树生命周期基础设施

动机: 脚本系统需要标准化的树变异方式(占位符→实际内容的替换)和资源生命周期回调(挂载时加载、卸载时释放)。

方案: LytNode 新增 onAttach()/onDetach() 回调、replaceChild() 变异方法、isAttached() 状态查询、nodeUid/styleClass 标识字段。LytDocument.live 通过 cascadeLive 递归触发整棵树的附着/脱离。LytBoxappend/removeChild/replaceChild 在文档活动时自动调用生命周期钩子。交互模型从 HitTestResult 升级为 DocumentInteractionSnapshot + FlowInteractionPath,支持剧透检测和祖先链追踪。新增 LytImageBlock(脚本实现的图片占位符)和 LytSpoilerSpan(剧透标记)。IdUtils 提供统一的物品引用解析,消除 ItemImageScriptItemGridScript 中重复的解析逻辑。


七、Mermaid 思维导图渲染修复

动机: Mermaid 思维导图节点内嵌内容(NodeContent)中的 BlockImage 场景、精灵图标、LaTeX 公式和 NEI 配方在缩放时出现多种渲染异常——场景视口偏移、UV 纹理图集边缘渗色、raw-GL 块完全不可见。

方案:NodeContentRenderContext 注入到 Blit/GL 渲染路径中。精灵渲染通过覆写 blitGuiSprite 在 GL 矩阵中缩放显示尺寸同时保持 UV 固定在原始精灵范围。LaTeX 和 raw-GL 块(ItemImage、NEI 配方框)通过 usesRawGl() 检测后单独应用 GL 平移+缩放矩阵。BlockImage 场景通过 sceneViewportOverride 逐帧控制 GL 视口,以 mindmap 缩放比例缩放同时锁定相机视口为原始尺寸。CameraSettings.setZoom() 更正为标记投影矩阵脏位而非视图矩阵脏位。


八、场景渲染坐标系统一

动机: Ponder 控件和 overlay 的坐标计算在 Mermaid 画布和普通页面中使用了不同的坐标系(部分手动 lastDocZoom 乘法,部分 instanceof 硬编码判断),导致缩放行为不一致。

方案: RenderContext 接口新增 beginLocalView()/endLocalView() 方法,NodeContentRenderContext 覆写以推送 GL 平移+缩放。Ponder 控件渲染改用 context.toScreenRect() 计算所有屏幕空间命中测试坐标。Overlay 渲染将屏幕空间视口传递与裁剪区域分离。registerRuntimeScenes() 扫描文档树中的 LytGuidebookScene 实例并注册到 Ponder tick 分派管线,使异步 SceneScript 创建的 Scene 能收到按钮点击和切换事件。


九、其他修复

  • F3+T 资源重载时清空 GuideLatexTextureCacheGuideSceneStructureCache 和 5 个 StructureLibBoundedCache
  • 编辑器预览文档的 MOUNT 分派,异步脚本在分屏预览中正确渲染
  • BlockImageScript 恢复丢失的 scene 属性(showBackground、gridVisible 等)
  • 7 个不可见占位符编译器添加 PLACEHOLDER_STYLE(Category、Special、StructureView 等)
  • 图片资源缺失时降级为 missing-texture 图标,而非错误段落
  • Category 页面恢复标题解析、isWrapped 模式和间距
  • Category 和 Special 页面的深度搜索索引恢复
  • UTF-8 BOM 剥离(修复 "0 navigation entries")
  • super.initGui() 初始化 NEI GuiContainerManager(修复 Mixin NPE)
  • drawTiledBackgroundupdateScreenhandleKeyboardInput 的 mc==null 防护
  • 基于二分搜索的高度加权列分布算法,替换 ceil(N/C) 条目分布
  • 段落合并恢复,相邻内联元素合并为一个段落避免碎片化
  • NBT 解析失败添加日志而非静默忽略
  • Kramdown table widths 解析、NFE 防护
  • 空行 Enter 键智能换行

Windorain and others added 30 commits May 13, 2026 21:09
Implements the dropdown popup UI for autocomplete suggestions with
scrollable candidate list, selection highlighting, scrollbar, and
viewport clamping.
…, and value range

- Fix keyboard typing not triggering autocomplete (schedule polluted state)
- Fix popup position anchoring to cursor pixel instead of hardcoded offset
- Fix popup flip above cursor when insufficient room below
- Fix Backspace consumed by navigation instead of forwarded to textarea
- Fix modal scroll wheel (popup only when mouse inside)
- Fix ItemCandidate icon offset
- Fix fallback regex replaceEnd to scan forward for closing quote
- Add cursor pixel position API to SceneEditorMultilineTextArea
- Add throttled diagnostic logging
- Remove debug printlns
- Cache MdAstRoot to skip re-parse on cursor-only moves
- Store pendingContext to avoid re-resolve on commit
- Preserve popup scroll/selection when candidate list unchanged
- Extract getAutocompleteAnchorX/Y(), eliminate magic numbers
- Extract SyntaxUtils shared by 3 resolvers
- Fix fallback regex for lowercase tags
- Fix raw Map type, COWList→ArrayList, skip redundant computeSize
…name completion

- Add CompositeResolver to chain Frontmatter→Mdx→WordBoundary resolvers
- Add FrontmatterResolver for YAML frontmatter key/value detection
- Add MdxValueContext, MdxAttrNameContext, TagStartContext, FrontmatterContext
- Extend MdxSyntaxResolver with TAG_START and ATTRIBUTE_NAME detection
- Extend AutocompleteProviders with 4-way context dispatch
- Add AttributeNameProvider using TagAttributeRegistry
- Add ColorCandidate and RegistryCandidate rendering stubs
- Wire CompositeResolver into GuideScreen
- Boolean, EnumValue, Color, OreDict, BlockId, EntityName providers
- KeyBind, PageReference (stub), Anchor (stub), Command providers
- NumericValue, Expression, Domain, FormatPattern providers
- RecipeFilter, TagName providers
- Fix RegistryCandidate to support ItemStack icon rendering
- Register all providers in ClientProxy
…oviders

- FrontmatterKeyProvider and FrontmatterValueProvider
- MarkdownInlineProvider, MarkdownBlockProvider, FencedBlockLanguageProvider (stubs)
- NbtProvider, Vector3Provider, DataProvider for structural template hints
- Add autocomplete-test.md guide page for manual testing
…filter, fix registry gaps

- Remove Boolean, Vector3, Nbt, Data, MarkdownInline, MarkdownBlock providers
- Merge RecipeFilterProvider into ItemIdProvider (add input/output keys)
- Simplify ColorProvider to symbolic names only
- Add chart tags (Bar/Column/Line/Scatter/PieChart) to TagAttributeRegistry
- Add chart child tags (Series, LineSeries, Slice, PieInset)
- Add FunctionGraph child tags (Plot, Point)
- Extend GameScene/Scene with camera attributes
- Extend Function/FunctionGraph with container attributes
- Extend Entity with rotation attributes
- Extend Latex with sourceScale, showTooltip, offset
- Extend ImportStructure, PlaceBlock, ReplaceBlock with bounds attrs
- Add Block scene element tag
…, FencedBlockLanguage providers

- FencedBlockLanguageProvider: return language list filtered by partial text
- PageReferenceProvider: static setPages() wired from GuideScreen, suggests page paths
- AnchorProvider: static setDocumentText() wired from GuideScreen, parses headings
- FrontmatterValueProvider: contextual hints per frontmatter key
…estions

Scans resource pack asset directories for .png/.snbt/.csv/.json/.mmd files.
Uses AccessorFMLClientHandler mixin for resource pack access, same pattern
as DataDrivenGuideLoader.
…ders

- Fix crash-causing format patterns (%d/%f) and domain syntax
- Separate Anchor display/replacement, limit Color to Color/id
- Filter NumericValueProvider by attr name, add missing tag keys
- Handle # inside frontmatter quotes
- Disable TagNameProvider, AttributeNameProvider: unreliable until parser supports error-recovery
- Remove EnumValueProvider, FencedBlockLanguageProvider registrations
- Roll back EntityNameProvider hardcoded aliases
…en throws

- FactoryTag: fix recover() token exit order (LIFO), handle EOF vs non-EOF
  consume, remove crashEol, unify optionalEsWhitespace to always allow lazy
  lines
- FactoryMdxExpression: add recovery token for lazy-line bailout path
- MdxMdastExtension: replace 6 ParseException throws with graceful recovery
  or recursive stack unwind in onErrorRightIsTag/onErrorLeftIsTag
- MdastCompiler: replace 3 throws (exit open==null, defaultOnError x2) with
  recursive unwind + stack restoration; guard onexitlineending against empty
  stack

The tokenizer and mdast compiler now produce a partial AST for any input,
ensuring autocomplete can always query syntax context.
…, nested MDX elements

- YAML list items with colons in value (e.g. "guidenh:guide_icon") now
  correctly resolve to their parent key context via isYamlListMarker
  check before colon-split
- Top-level keys with prevIndent=0 now return their own context for
  list items and empty lines, instead of falling back to plain text
- findEnclosingMdxElement: search children first for innermost match,
  fixing nested MDX element attribute/tag-start autocomplete
- resolveTagStart: extend to detect partial tag names after '<'
  (e.g. <I|, <Item|) by walking back to '<' and extracting partialText
  for TagNameProvider filtering. Closing tags (</I) are excluded.
- applySmartNewline: when the current line is blank (trimmed empty),
  move cursor to the next line instead of inserting an extra blank line.
ABKQPO and others added 4 commits June 5, 2026 15:11
All Scene rendering now uses layout coordinates exclusively, with coordinate
conversion handled by the context — no manual screen-space computation.

- NodeContentRenderContext.toScreenRect: chain through delegate to include
  documentOrigin and scrollOffset, returning absolute screen coordinates
- Scene: remove instanceof LytGuidebookScene special case from Mermaid canvas,
  render through generic block.render(nodeContext) path
- Scene: camera viewport defaults to sceneW/sceneH (cameraViewportOverride
  retained only for offscreen export callers)
- Scene buttons, ponder controls, slider tracks: all raw GL parts wrapped in
  conditional GL transform (push/pop only for non-VanillaRenderContext)
- Slider render path: separate layout-space rects (resolveSliderTrackLayoutRect)
  from screen-space hit-test rects
- VanillaRenderContext.toScreenRect: scale dimensions by zoom

All drawSceneButtons, drawPonderControls, drawSlider, and resolveSliderTrackRect
now use layout coordinates. Hover detection uses context.toScreenRect() to
convert layout to screen coords before comparing against mouseX/mouseY.
…rdinate mixing

- RenderContext: add beginLocalView()/endLocalView() default no-ops
- NodeContentRenderContext: override to push GL translate+scale for raw GL
- drawSceneButtons, drawPonderControls, drawSlider: use context.beginLocalView()
  instead of instanceof VanillaRenderContext check + manual pushGlTransform
- drawPonderControls: use context.toScreenRect() for all screen-space hit-test
  coordinates instead of manual lastDocZoom multiplication
- drawPonderKeyframeNodes: pass context+scale for hover via toScreenRect
- Overlay rendering: pass screen-space viewport to o.render(), keep scissor
  separate via pushLocalScissor(sceneRect)
- Store cachedPonderBtnScreenW/H from toScreenRect for ponderButtonAt and
  containsPonderButtons
@Windorain Windorain changed the title Autocomplete feat: autocomplete system, runtime scheduler, IR unification, and compiler purification Jun 5, 2026
@ABKQPO

ABKQPO commented Jun 7, 2026

Copy link
Copy Markdown
Owner

Mermaid 相关链路增强为优先读取原始标签体文本,而非直接消费 Markdown 解析后的内容。

这一调整规避了 Mermaid DSL 中方括号、链接及其它保留语法在进入 Mermaid 解析器之前被 Markdown 改写的问题,同时统一通过源码级剥离 NodeContent 片段,隔离图定义与节点内嵌内容的解析边界。

@ABKQPO

ABKQPO commented Jun 7, 2026

Copy link
Copy Markdown
Owner

MdxBlockTagSourceExtractor 增强了对源码定位偏移的容错能力。

新实现优先基于语法树记录的行号与列号定位 opening tag,再以 offset 搜索作为回退路径。
这一改动统一增强了所有依赖原始块源码的标签编译稳定性,并降低了预处理、换行规整及源码位移对提取结果的影响。

@ABKQPO

ABKQPO commented Jun 7, 2026

Copy link
Copy Markdown
Owner

引入 ContentTabs 功能,用于支持页面内标签页式内容切换。

适用于同一主题下的多方案说明、多版本差异、多语言示例或并列视图组织。相较于连续堆叠内容块,ContentTabs 强化了页面结构分段能力,也为后续导出与交互扩展预留了更清晰的组件边界。

@ABKQPO

ABKQPO commented Jun 7, 2026

Copy link
Copy Markdown
Owner

Guide 编辑器动作实现进一步统一到 GuideScreen 内部。

工具栏动作、右键菜单项以及文本插入行为不再依赖原有的分散注册路径,而是改为更集中的屏幕内组织方式。
这一调整强化了编辑器行为入口的一致性,降低了中间层转发成本,并同步移除了若干已无实际入口或不再维护的编辑器项。

@ABKQPO

ABKQPO commented Jun 7, 2026

Copy link
Copy Markdown
Owner

文档交互与布局链路同步进行了收敛。

部分交互包装层被移除,界面逻辑更多回归到轻量的命中结果与当前文档状态之上。
这一调整强化了交互路径的可追踪性,减少了不必要的抽象层级,并降低了后续修改时的连带复杂度。

@ABKQPO

ABKQPO commented Jun 7, 2026

Copy link
Copy Markdown
Owner

NEI 配方跳转逻辑进行了统一与简化。

实现路径更集中于 recipeId 定位,保留必要的锚定物品解析,同时移除了多级 fallback、反射构造及特定处理器分支。
这一调整强化了行为边界的一致性,并降低了旧兼容路径的维护负担。

@ABKQPO

ABKQPO commented Jun 7, 2026

Copy link
Copy Markdown
Owner

命令、文档与语言资源同步完成了一轮清理。

本次变更移除了 dumppagelang 相关命令与文案,裁剪了未继续保留的编辑器语言条目,并同步清理了对应 wiki 页面及站点导出残留内容。
这一部分主要用于收缩当前分支的功能边界,避免实现、界面与文档继续出现偏差。

@ABKQPO

ABKQPO commented Jun 7, 2026

Copy link
Copy Markdown
Owner

资源包示例与参考文档需要与本次功能同步补齐,尤其包括以下内容:

ContentTabs 的编写方式与使用示例
Mermaid 原始源码路径下的推荐写法
中英文示例页面的一致更新
这一项建议作为本次 PR 的组成部分处理,以保证实现层、示例层与文档层保持同步。

@ABKQPO ABKQPO merged commit 6efe25e into ABKQPO:master Jun 7, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants