拓冰建站拓冰建站
首页 / 资讯中心 / 正文

TiXL 设置系统重构指南:三层设置模型与编辑器状态持久化架构解析

TiXL 设置系统重构指南三层设置模型与编辑器状态持久化架构解析【免费下载链接】t3TiXL is an open source software to create realtime motion graphics.项目地址: https://gitcode.com/GitHub_Trending/t3/t3本篇技术指南以 TiXLt3项目中的设置重构规划文档Plan_ProjectSettings.md为骨架系统讲解 TiXL 当前采用的三层设置模型——App 级CoreSettings、Composition 级CompositionSettings、Project-global 级根 Operator 的.t3ui状态以及渲染设置、输出窗口状态、时间线状态、窗口布局等编辑器状态的持久化机制。读完本文你将掌握 TiXL 各类设置分别存于哪个文件、由哪个访问器读取、如何通过 breadcrumb 继承、如何进行旧格式迁移与克隆并能据此理解或排查 TiXL 项目中设置不生效 / 状态丢失 / 布局未恢复一类问题。一、背景与动机一次同名异义驱动的设置重构在 TiXL 早期代码中ProjectSettings这个名字同时被用于全局设置与每个 Symbol 的播放设置导致以下混乱全局的ProjectSettings保存于projectSettings.json与 per-symbol 的PlaybackSettings命名歧义部分本应属于单个 Composition 的字段IO、性能开关却散落在应用级配置里设置界面长期以弹窗Popup形式存在缺乏格式版本管理与窗口化交互切换 Composition 时渲染设置存在引用共享的克隆缺陷。重构的核心动作对应规划文档 Completed Work 部分可以归纳为三次重命名 一次分层重构前重构后序列化位置用途全局ProjectSettingsCoreSettingsprojectSettings.json应用级设置保持原文件名不变per-symbolPlaybackSettingsCompositionSettings历经ProjectSettings→SymbolSettings过渡.t3文件每个 Composition 的播放 / 音频 / 导出配置Symbol.ProjectSettingsSymbol.CompositionSettings—Symbol 数据模型上的挂载点同时设置类整体迁移到T3.Core.Settings命名空间目录 Core/SettingsFileLocations与UserData也随之迁入GlobalMute/GlobalPlaybackVolume更名为AppMute/AppVolumeIO 与性能配置被移回CoreSettings它们是应用级而非 per-composition 的。出于向后兼容.t3文件中的 JSON key 仍保留ProjectSettings。二、三层设置模型总览重构后的架构将设置严格划分为三个层级每一层都有独立的存储文件、生命周期与访问入口层级存储位置典型内容访问方式Project-global项目全局根 Operator 的.t3ui输出窗口状态、窗口布局与可见性IOOSC 端口与性能开关则在CoreSettingsOutputWindow.State经_lastSyncedSymbolUi读取根 op 的 SymbolUiPer-symbol Composition随 Composition 继承所在 Symbol 的.t3渲染设置与时间线状态在.t3ui播放配置BPM、soundtrack、音频源、同步方式、音频混音、导出配置、渲染设置、时间线视图状态CompositionSettings.Currentbreadcrumb 向上遍历继承App-level应用级projectSettings.jsonAppMute/AppVolume、MIDI 捕获限制、默认 OSC 端口、性能与日志开关CoreSettings.Config、UserSettings.Config三个层级中最关键的设计意图是随项目走的数据进入.t3/.t3ui随机器/用户走的数据进入projectSettings.json与用户配置文件。例如音频输入设备在CompositionSettings.Playback.AudioInputDeviceName中按项目记录而机器特定的默认输入设备则通过CoreSettings.ConfigData.LocalAudioInputDeviceName保留在projectSettings.json中从而保证共享项目在另一台机器上仍能解析到真实输入设备。三、App 级设置CoreSettings 与 projectSettings.jsonCoreSettings源码Core/IO/CoreSettings.cs是跨 Core、Editor、Player 三端共享的全局应用设置序列化到设置目录下的projectSettings.json文件名在重构中刻意保留避免迁移成本。其ConfigData内嵌类包含字段默认值说明AppMute/AppVolumefalse/1全局静音与音量由工具栏音频 toggle 直接切换而非 per-project 的 SoundtrackMuteLimitMidiDeviceCapturenull限制 MIDI 设备捕获DefaultOscPort8000默认 OSC 端口LocalAudioInputDeviceName空机器特定的 WASAPI 输入设备保持共享项目可移植TimeClipSuspendingtrue时间剪辑挂起优化开关SkipOptimizationfalse跳过优化EnableDirectXDebugfalseDirectX 调试层开关EnableBeatSyncProfilingfalseBeat 同步性能剖析LogAssemblyVersionMismatches/LogCompilationDetails/LogAssemblyLoadingDetails/LogFileEventsfalse各类日志开关UseProcessScopedShadowCopiesfalse4.3 之前的进程级 shadow copy 逃生舱底层机制SettingsT 基类CoreSettings继承自通用的 Core/IO/Settings.cs 中的SettingsT基类该基类承担了所有 JSON 配置文件的读写职责通过SettingsT.Defaults提供默认值SettingsT.Config为当前生效实例构造时从FileLocations.SettingsDirectory下加载 JSON文件缺失时以默认值新建若文件存在但无法读取被其他实例锁定或损坏会保留磁盘文件不动_preserveFileOnDisk避免退出时用默认值覆盖用户真实配置并记录警告注册ProcessExit事件在退出时自动Save()子类可重写OnBeforeSave()在序列化前归一化数据。四、Composition 级设置CompositionSettings 与 breadcrumb 继承CompositionSettings源码Core/Settings/CompositionSettings.cs是本次重构的核心成果——每个 Symbol 可以拥有自己的项目设置并且通过图层次breadcrumb向上遍历继承当某 Composition 未定义设置时会沿父级查找直到找到最近的定义设置的 Symbol。CompositionSettings.Current静态访问器等价于Animation.Playback.Current?.Settings ?? Defaults即 null 安全地回退到默认值。4.1 顶层结构与主要枚举public sealed class CompositionSettings { public static CompositionSettings Defaults { get; } new(); public static CompositionSettings Current Animation.Playback.Current?.Settings ?? Defaults; public bool Enabled { get; set; } public PlaybackConfig Playback { get; init; } new(); public AudioMixConfig Audio { get; init; } new(); public ExportConfig Export { get; init; } new(); public ProxyConfig Proxy { get; init; } new(); }Enabled是本 Symbol 是否主动定义设置的总开关——关闭时 UI 会提示当前继承自哪个父 Composition。其中几个关键枚举在 CompositionSettings.cs 的#region Enums中定义AudioSourcesProjectSoundTrack时间线驱动的项目配乐/ExternalDevice外部设备SyncModesTimeline/Tapping手动打拍子驱动时钟BeatLockSourcesOnsetDetection经典瞬态检测/PhaseModelDanceAi 神经网络的 bar-phase 模型/PhaseModelRaw网络原始输出供对比BpmChangeModesStretchWithBeat保持 bar 数值不变内容随 BPM 变速/KeepSeconds保持秒数不变仅移动网格。4.2 四个配置子类与默认值PlaybackConfig播放配置字段默认值说明Bpm120项目速度TiXL 动画单位是 barBPM 直接控制动画速度OnBpmChange—BPM 修改对 bar 定时内容剪辑位置、关键帧、循环范围的处理方式AudioClips空列表时间线音频剪辑TimelineAudioClip列表AudioSource—音频源项目配乐或外部设备Syncing—同步方式Timeline 或 TappingUsesBeatTapping计算属性AudioSource ExternalDevice Syncing Tapping时成立AudioInputDeviceName空输入设备名空 用默认输入AudioGainFactor/AudioDecayFactor1/0.9输入信号增益与 [AudioReaction] 的衰减因子EnableAudioBeatLockingtrue是否启用音频节拍锁定编辑器会寻找低音瞬态、hi-hat、军鼓并锁定播放速度BeatLockSource/BeatLockSmoothing— /0.5节拍锁定来源与平滑度0 紧跟模型可能抖动1 信任运行节奏缓慢修正BeatLockAudioOffsetSec0相位偏移±1s 范围用于补偿视频处理设备造成的输出延迟AudioMixConfig音频混音字段默认值说明SoundtrackMute/OperatorMutefalse/false配乐 / Operator 静音SoundtrackVolume/OperatorVolume0.5/1配乐 / Operator 音量AudioResyncThreshold0.04音频偏离动画超过该阈值推荐 0.02s~0.05s时触发重新同步ExportConfig导出可执行文件配置Title/Author空则分别回退到 Operator 名/包名、DefaultWindowMode Fullscreen、EnablePlaybackControlWithKeyboard true方向键跳转 空格暂停、PreferredWidth/Height 1920×1080、ShowLogs false、SkipStartupDialog false仍可用--dialog强制呼出、StripUnusedOperators true只打包与导出输出相连的 Operator 及自动播放的音频 Operator。ProxyConfig预览代理配置Format ProRes仅限 all-intra/LGPL 编码绝不使用 H.264/HEVC 即 libx264/libx265因其为 GPL、Resolution 0.5源分辨率的比例、UseForPreview true预览/拖动时播放代理渲染始终用全分辨率源。4.3 序列化与旧格式迁移CompositionSettings.WriteToJson仅在Enabled、存在音频剪辑或 Proxy 非默认时写出写出的 JSON key 为ProjectSettings顶层对象下包含Playback、Audio、Export、Proxy四个子对象。读取端ReadFromJson则做了三重兼容新格式优先优先取ProjectSettingskey若其下存在Playback子对象则按新嵌套格式读取旧 key 兼容找不到ProjectSettings时回退到旧的PlaybackSettingskey旧扁平格式迁移若ProjectSettings内没有Playback子对象按旧版扁平格式读取——包括将音频剪辑从 Symbol 根或 settings 根读取以及BPM 迁移旧项目把 BPM 存在剪辑本身新模型只保留在Playback.Bpm加载时若发现Playback.Bpm 0而主配乐剪辑带LegacyBpmForMigration会一次性复制进Playback.Bpm并自动Enabled true。此外加载音频剪辑时对绝对路径已不存在的非主配乐剪辑会直接丢弃并告警IsUnmanageableMissingClip因为这类死引用没有 UI 可以移除避免每帧重复注册和报错相对包路径的剪辑则保留交由资源消费者延迟解析。4.4 克隆用序列化做深拷贝规划文档特别提到修复了切换 Composition 时克隆 bug原来是共享引用现在克隆。CompositionSettings.Clone()的实现策略是通过自己的序列化往返深拷贝先把设置写入 JSON再ReadFromJson读回保证克隆结果与源设置的 save/load 往返完全一致——用于将 Symbol 复制为新类型时隔离设置实例。五、Project-global 设置根 Operator 的 .t3ui 状态这一层存储于根 Operator 的.t3ui整个项目只有一份包含输出窗口状态与窗口布局。规划文档强调这些数据属于项目而非属于某个 Composition因此读取时使用ProjectView.Focused.RootInstance而非当前 Composition。5.1 OutputWindowState输出窗口状态源码 Editor/Gui/Windows/Output/OutputWindowState.cs 定义了每个输出窗口的持久化状态以 JSON 数组形式存储在.t3ui的OutputWindowskey 下支持多个输出窗口GizmoShowGizmos默认On、TransformGizmoMode默认Move——直接以State作为后备存储无拷贝背景与相机BackgroundColor、CameraControlMode默认AutoUseFirstCam另有SceneViewerFollowing/UseViewer/PickedACamera、CameraPosition默认[0,0,2.414]即默认相机距离、CameraTarget、CameraRoll、CameraSpeed——基于拷贝每帧通过SyncCopyFieldsToState()同步分辨率ResolutionTitle、ResolutionWidth/Height、ResolutionUseAsAspectRatioPinning钉住IsPinned、PinnedInstancePathGuid[]、PinnedOutputId。5.2 TimelineState时间线视图状态源码 Editor/Gui/Windows/TimeLine/TimelineState.cs 存储每个 Symbol 的.t3ui中Timelinekey。刻意只持久化视图状态ScaleX、ScrollX、ModeDopeView/CurveEditor而 Loop 范围与播放位置保持为Playback对象上的运行时状态不落盘。切换 Composition 时通过SyncStateWithComposition完成保存/加载。此外还包含TimelineHeight项目级窗口布局仅根 Symbol 的副本会被写入、InlineDataClipEditEnabled、DetailsAreaHeight内联编辑面板高度默认 200px、SourceExtentSymbol 有意义内容的 bar 范围供 TimeClip 使用等字段。5.3 窗口布局与可见性SymbolUi.WindowLayout——ImGui 布局 INI 字符串经SaveIniSettingsToMemory()获取SymbolUi.WindowLayoutImGuiVersion——版本标记仅当 ImGui 主版本号一致时才恢复布局避免跨版本布局错乱SymbolUi.WindowVisibility——Dictionarystring, bool窗口标题 → 可见性保存时机为ProjectView.Close()恢复时机为ProjectView.SetAsFocused()通过UserSettings.Config.SaveWindowLayoutsWithProjects默认true见 Editor/Gui/UiHelpers/UserSettings.cs选择是否随项目保存布局。规划文档还记录了该层的三处修复ProjectView.Close不再调用Unpin()而是保存状态Pinning 在项目关闭/重开后仍能存活陈旧的 ProjectView 会重新解析到当前实例切换项目时状态保存到正确的项目跟踪_lastSyncedSymbolUi。六、渲染设置RenderSettings 直接读写 SymbolUi规划文档提到移除了ForNextExport中间层——RenderSettings.Current直接从SymbolUi.RenderSettings读写。源码 Editor/Gui/Windows/RenderExport/RenderSettings.cs 印证了这一点RenderSettings.Current从聚焦的 Composition的 SymbolUi 读取首次访问时以默认值 旧版路径迁移初始化迁移UserSettings中遗留的RenderVideoFilePath、RenderSequenceFilePath、RenderSequenceFileName、RenderSequencePrefix且不标记为已修改——因为该 getter 会被纯 UI 读取触发如输出窗口的渲染提示不应弄脏 Composition字段集TimeReferenceBars/Seconds/Frames、StartInBars、EndInBars默认8、FrameRate默认60、OverrideMotionBlurSamples默认-1即不覆盖、RenderModeVideo/ImageSequence、VideoCodec默认 H264、Bitrate默认25_000_000、AutoIncrementVersionNumber/CreateSubFolder/AutoIncrementSubFolder默认true、ExportAudio默认true、FileFormat、TimeRangeCustom/Loop/Soundtrack/Continuous、连续捕获时钟Realtime/Deterministic与帧率模式FixedFps/VariableVariable 保留未实现、ResolutionFactor默认1以及渲染路径VideoFilePath ./Render/render-v01.mp4、SequenceFilePath ./ImageSequence/、SequenceFileName v01、SequencePrefix render序列化 key 为.t3ui中的RenderExportClone()/CopyFrom()用于复制与切换 Composition 时隔离实例。渲染导出时输出窗口使用的是RenderProcess.GetActiveOrRequestedSettings()而不是Current确保正在渲染中与UI 当前显示互不干扰。另外修复了AddInt重置按钮因缺少isDefault检查而从不高亮的问题。七、Composition Settings 窗口从弹窗到可停靠窗口规划文档记录设置界面已从 Popup 升级为可停靠的Window类ProjectSettingsWindow。源码 Editor/Gui/Windows/TimeLine/ProjectSettingsWindow.cs 显示其标题为 Composition Settings左侧导航分五个分类分类面板标题核心内容PlaybackTiming项目模式AnimationProjectSoundTrack / Live InteractiveExternalDevice、BPM、On BPM Change 行为、Sync Mode、Beat Lock 源与平滑度、Beat Sync OffsetAudioProject AudioResync Threshold、Main Volume、输入设备选择、Gain/Decay、电平表、Main Soundtrack 管理ProxiesVideo ProxiesUse proxies for preview、Proxy FormatProRes/Hap/Hap Alpha/Hap Q、Resolution 比例、最小可用磁盘、代理存储清理RecordingRecordingRecord 按钮捕获范围Capture Audio、Capture IOMIDI/OSC 子开关ExecutableExportTitle/Author、Window Mode、键盘播放控制、Preferred 分辨率、Skip Startup Dialog、Show Logs、Strip Unused Operators 与导出按钮该窗口的交互细节与文档互相印证顶部主开关 Specify settings for SymbolName 控制Enabled未定义时提示 Currently inheriting settings from …Soundtrack 由 [AudioClip] Operator 拥有窗口只负责创建或聚焦主配乐——Create Soundtrack 会以一条可撤销的宏命令添加AudioClipopAutoPlaytrue、DisplayBackgroundImage、StyleWaveform剪辑的路径、偏移、修剪全部交给该 opCompositionSettings.TryGetMainSoundtrack也同时支持设置列表与 op 提供的剪辑两种来源窗口各面板的修改统一通过SymbolUi.FlagAsModified()标记脏状态切换项目模式时UpdatePlaybackAndTimeline会同步切换Playback.Current时间线或打拍时钟、时间线可见性、归一化遗留的Syncing值。在菜单与入口方面App 菜单显示 Composition Settings 并在当前聚焦 op 定义设置时带勾选标记时间线齿轮图标切换窗口可见性工具栏音频 toggle 切换的是应用级AppMute而非 per-project 的 SoundtrackMute。八、访问模式速查规划文档归纳了五个访问入口全部与源码一一对应访问器语义源码依据CompositionSettings.Currentper-symbol Composition 配置null 安全回退 Defaultsbreadcrumb 继承Core/Settings/CompositionSettings.csRenderSettings.Current直接读写聚焦 SymbolUi 的渲染设置lazy-init 旧版迁移Editor/Gui/Windows/RenderExport/RenderSettings.csOutputWindow.State经_lastSyncedSymbolUi读写根 op SymbolUi 的输出窗口状态Editor/Gui/Windows/Output/OutputWindowState.csCoreSettings.ConfigApp 级设置projectSettings.jsonCore/IO/CoreSettings.csUserSettings.Config用户偏好含SaveWindowLayoutsWithProjects、ViewedCanvasAreaForSymbolChildId等Editor/Gui/UiHelpers/UserSettings.cs九、后续演进方向规划文档的 Future Work 部分列出了尚未完成的演进计划从源码结构看其中部分已有雏形Graph View State每个 Symbol 的画布位置与缩放UserSettings.ViewedCanvasAreaForSymbolChildId已有部分实现、选中 Operator 集合的持久化默认 Composition 设置计划在UserSettings.ConfigData增加DefaultCompositionSettings字段让新 Composition 从用户默认值初始化并使 Composition Settings 窗口的恢复默认按钮使用该默认值自动视觉测试以编辑器状态持久化为前提——加载测试项目 → 恢复编辑器状态 → 截图 → 与参考图对比见规划文档中提及的另一份文档 Plan_AutomaticTests.md状态持久化是确定性测试截图的前置条件其他每项目首选分辨率/宽高比列表、每项目 key-value 参数存储、已钉住的动画参数DopeSheetArea.PinnedParametersHashes。这些内容属于规划中的方向而非已落地功能读者在阅读源码时应以当前实际实现为准。总结TiXL 的设置系统经过本轮重构后形成了清晰的分层边界应用级数据进projectSettings.json随 Composition 的数据进.t3CompositionSettingsJSON keyProjectSettings兼容旧版项目全局的窗口/布局/输出窗口状态进根 Operator 的.t3ui。CompositionSettings.Current的 breadcrumb 继承、RenderSettings.Current的直接读写、基于序列化的深拷贝克隆、以及SettingsT基类的损坏保护与退出自动保存共同构成了这套既可移植共享、又可逐机定制的持久化架构。对于想要为 TiXL 贡献新设置项或排查状态持久化问题的开发者而言本文的层级对照表与访问模式速查是快速定位的入口。【免费下载链接】t3TiXL is an open source software to create realtime motion graphics.项目地址: https://gitcode.com/GitHub_Trending/t3/t3创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门