TiXL t3 Symbol Browser:模糊搜索、类型过滤与使用频率排序的算子插入机制 📅 发布时间:2026/9/18 7:28:28 👁 浏览次数: TiXL t3 Symbol Browser模糊搜索、类型过滤与使用频率排序的算子插入机制【免费下载链接】t3TiXL is an open source software to create realtime motion graphics.项目地址: https://gitcode.com/GitHub_Trending/t3/t3本文以 TiXL t3开源实时动态图形工具项目路径GitHub_Trending/t3/t3编辑器的 Symbol Browser算子浏览器为主题讲解如何通过长按/双击画布或 Tab 键唤起该弹窗、在图中选定位置放置算子并结合 SymbolBrowser.cs、SymbolFilter.cs 与 SymbolAnalysis.cs 的源码剖析模糊搜索、输入类型过滤、使用频率排序以及“拖线先行”自动连接等机制的底层实现。一、Symbol Browser 是什么如何唤起按官方帮助文档 SymbolBrowser.md 的定义Symbol browser 是你用来查找算子operator/symbol并将其放置到图graph上指定位置的弹窗。它的核心交互包括长按或双击空白画布打开浏览器然后直接键入文字搜索搜索支持同义/缩写匹配——例如输入 LFO 即使不是算子的名字也能找到振荡器oscillator放置前可预览每个算子的产出效果若先拖出一条连接线浏览器只列出能匹配该输入类型的算子在单个被选中的算子上按 Tab可内联插入新算子候选项按“人们实际使用频率”排序常用算子浮在顶部。源码层面该弹窗对应 SymbolBrowser 类注释说明它“表示 GraphView 上新 GraphNode 的占位符可与其他节点连接并提供搜索功能本质上是 T2 的 CreateOperatorWindow”。它在 GraphView.cs#L107 中随视图构造创建graphView.SymbolBrowser new SymbolBrowser(projectView, graphView);唤起入口是OpenAt方法SymbolBrowser.cs#L39-L75签名揭示了它承载的全部过滤语义public void OpenAt(Vector2 positionOnCanvas, Type filterInputType, // 只保留有该类型输入的算子 Type filterOutputType, // 只保留有该类型输出的算子 bool onlyMultiInputs, // 仅保留多输入槽算子 string startingSearchString , System.ActionSymbol overrideCreate null)其中positionOnCanvas就是文档所说的“at a chosen spot”——新算子最终会以该坐标落入图中见下文CreateInstance。OpenAt还做了一个体验优化若放置点太靠近窗口边缘会先调用Canvas.FitAreaOnCanvas平移画布避免浏览器被裁切L41-L55。Tab 内联插入的路径可以在Draw()的未打开分支中找到SymbolBrowser.cs#L81-L128若当前恰好选中一个算子按 Tab 会走ConnectionMaker.OpenBrowserWithSingleSelection定义于 ConnectionMaker.cs#L699在新算子插入后自动建立与选中算子的连接——这就是文档所说的“inline insert”若没有选中算子则启动ConnectionMaker.StartOperation(_graphView, Add operator)并在鼠标位置打开浏览器L91-L96。二、打字即搜查询如何被编译成模糊正则文档称搜索“matches synonyms too”能匹配同义词/缩写。从源码看这一能力来自 SymbolFilter 的查询编译逻辑。UpdateFilters对输入串做了两步处理SymbolFilter.cs#L69-L1021. 两段式语法分离“算子名 预设名”。若查询含空格正则(.?)\s(.*)会把查询拆成symbolFilter前段用于匹配算子和PresetFilterString后段用于筛选预设// Check if template search was initiated var twoPartSearchResult new Regex((.?)\s(.*)).Match(search); if (twoPartSearchResult.Success) { symbolFilter twoPartSearchResult.Groups[1].Value; presetFilter twoPartSearchResult.Groups[2].Value; }2. 逐字符插入.*构建模糊正则。搜索词LFO会被编译为L.*F.*O忽略大小写var pattern string.Join(.*, symbolFilter.ToCharArray()); searchRegex new Regex(pattern, RegexOptions.IgnoreCase);这正是 “LFO 能找到振荡器”的机制只要算子名中 L、F、O 三个字符按序出现如 Low/Frequency/Oscillator 类命名即可命中无需字面包含 LFO。匹配时L156-L160满足以下任一条件即入选正则匹配算子名字_currentRegex.IsMatch(symbolUiSymbol.Name)命名空间包含过滤词忽略大小写的子串包含描述文本包含过滤词。命中集合随后按相关度排序并截断到前 100 条L174-L180保证浏览器响应始终流畅。另外UpdateMatchingSymbols会先把“当前组合及其所有祖先算子”的 Id 收集进parentSymbolIds并跳过L106-L120——这是为了防止把算子放进会形成循环引用的自己/祖先内部。浏览器主列表的绘制在DrawResultsListSymbolBrowser.cs#L264-L380每项以算子第一个输出的数据类型取色作为背景属于Lib.、Types.、Examples.Lib.、当前用户项目或当前组合命名空间的算子颜色饱和其余命名空间的颜色淡出到 40%color.Fade(0.4f)让用户一眼区分核心库与边缘算子。支持方向键上下移动高亮、滚轮/滚动自动跟随鼠标悬停也会即时切换选中项。三、“拖线先行”按连接类型过滤候选算子文档中“如果先拖出连接线浏览器只列出适配该输入的算子”对应OpenAt的filterInputType/filterOutputType/onlyMultiInputs参数在 SymbolFilter.UpdateMatchingSymbols 中强制执行if (_inputType ! null) { if (symbolUiSymbol.InputDefinitions.Count 0) continue; // 优先第一个输入类型匹配否则任意输入匹配 if (symbolUiSymbol.InputDefinitions[0].ValueType ! _inputType) { var matchingInput symbolUiSymbol.InputDefinitions.FirstOrDefault(i i.ValueType _inputType); if (matchingInput null) continue; } var matchingInputDef symbolUiSymbol.GetInputMatchingType(FilterInputType); if (matchingInputDef null) continue; // 新连接落在第一个匹配类型的输入上所以它必须是多输入槽... if (OnlyMultiInputs !matchingInputDef.IsMultiInput) continue; }这段代码解释了OnlyMultiInputs存在的原因新连接会落在第一个匹配类型的输入槽上因此当用户从已有输入槽继续拖线该槽可能已占位时只保留支持多输入multi-input的算子确保新连接能挂接成功。过滤生效后浏览器列表顶部会打印类型过滤头PrintTypeFilterSymbolBrowser.cs#L382-L402格式为输入类型[多输入标记] - 输出类型例如float[..] - float让操作者明确当前候选集合的约束。四、排序算法为什么“常用的算子浮在顶部”文档称“suggestions are ranked by how often people actually use them”。实现位于SymbolFilter.ComputeRelevancySymbolFilter.cs#L199-L409它为一个算子累积一系列乘性相关度因子。可确认的因子如下条件因子源码位置单字符查询且算子名以其开头×20L216-L219名字与查询完全相等忽略大小写×8.6L227-L231名字前缀匹配×8.5L233-L237名字包含查询×8.4L240-L245描述文本包含查询×1.01L247-L252Pascal 缩写匹配查询字符按序命中名字大写字母如 ds → DrawState×4L255-L279命名空间以Types.开头×4L221-L225命名空间以Lib开头×3L287-L288命名空间以examples开头×2L290-L294与当前项目同包同 SymbolPackage×2L310-L315命名空间以当前项目/组合的根命名空间开头×1.9L318-L335属于用户可编辑项目EditableSymbolProject×1.9L339-L343命名空间含dx11或下划线×0.1L281-L285名字以_开头内部算子×0.1L297-L301名字含OBSOLETE×0.01L303-L304标签为 Obsolete/NeedsFix/Research/Internal×0.3L385-L389标签为 Advanced×0.8L391-L395标签为 Essential×1.5L397-L401两个“使用频率”因子最能体现文档所述的排序意图1. 高频连接组合加成L345-L365。SymbolAnalysis会统计所有项目中“输出槽 → 输入槽”连接对的哈希计数SymbolAnalysis.cs#L24-L27 注释明确写着 “Used by SymbolBrowser for relevancy weighting of frequent combinations”。若候选算子的输出槽恰好常与当前拖线来源的输入槽配对相关度乘以1 4·count^(1/3)——即“社区里常用的一条接线”会显著上浮。2. 全局使用量加成L367-L383。当算子经过上述检查后相关度已超过 10即确实相关再乘以其被实例化次数的加成var count SymbolAnalysis.InformationForSymbolIds.TryGetValue(symbol.Id, out var info) ? info.UsageCount : 0; var totalUsageCountBoost (float)(1 (500.0 * (float)count / SymbolAnalysis.TotalUsageCount)); relevancy * totalUsageCountBoost;UsageCount由 SymbolAnalysis.UpdateSymbolUsageCounts 遍历所有包的算子子项统计而来因此被大量组合引用的算子会自然排在前面——与文档“ranked by how often people actually use them”的表述一一对应。五、放置与创建流程从点击到可撤销的“Insert Op”选中某项后回车确认或单击/双击列表项CreateInstance执行完整落盘流程SymbolBrowser.cs#L551-L640按位置插入子节点AddSymbolChildCommand(parentSymbol, symbol.Id) { PosOnCanvas PosOnCanvas }将新算子以浏览器打开时的画布坐标加入当前组合L565-L567——这就是“placed at a chosen spot”的实现应用预设如有若两段式搜索选中了某个 preset则presetPool.Apply(newInstance, _selectedPreset)把该 Variation 预设写入新实例L580-L584自动连接拖线前留下的临时连接遍历ConnectionMaker.GetTempConnectionsFor得到的草稿连接按类型在新算子上找匹配槽位GetOutputMatchingType/GetInputMatchingType为每条连接生成AddConnectionCommandL593-L633合并为一次可撤销操作ConnectionMaker.CompleteOperation(_graphView, commandsForUndo, Insert Op ...)把“插入算子 全部连接”打包进撤销栈一次 CtrlZ 全部回退L637自动弹出参数窗口ParameterPopUp.NodeIdRequestedForParameterWindowActivation newSymbolChild.Id放完即可调参L638。面板自身的布局也有细节搜索框下方 40 像素处渲染结果列表BrowserPositionOffset列表基准尺寸为250×300 × (2,1) × UiScaleFactorL648-L656ClampPanelToCanvas会把超出窗口右缘/下缘的面板回移或压缩L404-L419按住搜索框拖动还能整体平移浏览器位置DrawSearchInput中的IsMouseDragging分支L239-L242。取消操作同样宽松Esc、右键或点击窗口外都会Cancel()内部调用ConnectionMaker.AbortOperation丢弃草稿连接L223-L255。六、预设面板与描述/示例预览文档提到放置前可预览算子的产出。除列表项本身的类型色预览外源码还确认了右侧辅助面板从源码结构看这是浏览器提供“预览/上下文”的主要载体描述与示例面板DrawDescriptionPanelSymbolBrowser.cs#L473-L513当高亮算子有Description或通过ExampleSymbolLinking.ExampleIdsForSymbolsId关联到示例算子时在结果列表旁渲染说明文字与 Example 条目帮助用户在放置前了解该算子能做什么预设面板DrawPresetPanelSymbolBrowser.cs#L423-L471当使用两段式搜索如noise grain且算子存在 Variation 预设时列出标题包含预设过滤词的条目点击即创建实例并应用该预设CreateInstance中presetPool.Apply生效。面板定位由TryFindValidPanelPosition保证不越出窗口右缘放不下时翻转到左侧L515-L534。七、关键文件索引关注点文件浏览器 UI、Tab 唤起、放置与创建流程SymbolBrowser.cs查询编译、类型过滤、相关度排序SymbolFilter.cs使用量/连接频率统计排序数据源SymbolAnalysis.cs浏览器实例化入口GraphView.csTab 单选内联插入与临时连接管理ConnectionMaker.cs官方行为描述本文主体依据SymbolBrowser.md掌握以上内容后你可以完整解释 t3 图中“长按画布 → 输入 LFO 命中振荡器 → 列表按使用频率排序 → 回车落点并自动连线”这一整条高频工作流查询如何被编译为字符级模糊正则、拖线为何只剩“接得上”的算子、以及SymbolAnalysis的用量与连接统计如何把常用算子推到列表顶端。【免费下载链接】t3TiXL is an open source software to create realtime motion graphics.项目地址: https://gitcode.com/GitHub_Trending/t3/t3创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考