feat(text): 添加富文本效果系统和颜色标记功能#251
Conversation
- 实现 RichTextEffectBase 基类提供统一的标签命名和参数读取逻辑 - 添加 RichTextBlueEffect、RichTextGoldEffect、RichTextGreenEffect 和 RichTextRedEffect 颜色标记效果 - 添加 RichTextFadeInEffect、RichTextFlyInEffect、RichTextJitterEffect 和 RichTextSineEffect 动画效果 - 实现 DefaultRichTextEffectRegistry 默认效果注册表 - 创建 GfRichTextLabel 富文本标签宿主组件 - 添加 IRichTextEffectRegistry 效果注册表接口 - 实现 RichTextEffectEntry、RichTextEffectsController 和 RichTextProfile 配置管理类 - 添加 RichTextMarkup 语义化标签构建辅助方法 - 创建 RichTextMarkupTests 和 RichTextProfileTests 单元测试
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthrough新增完整富文本效果子系统:资源与条目类型、效果注册表接口与默认实现、控制器与宿主节点、多种内置静态与动画效果、BBCode 构建工具,以及覆盖这些行为的单元测试与 CI 流程调整。 Changes
Sequence Diagram(s)sequenceDiagram
participant GfRichTextLabel
participant RichTextEffectsController
participant DefaultRegistry as DefaultRichTextEffectRegistry
participant RichTextEffect
participant Host as RichTextLabel
GfRichTextLabel->>RichTextEffectsController: EnsureController().Initialize()
activate RichTextEffectsController
RichTextEffectsController->>RichTextEffectsController: RefreshEffects()
RichTextEffectsController->>DefaultRegistry: CreateEffects(profile, animatedEnabled)
activate DefaultRegistry
DefaultRegistry->>RichTextEffect: CreateEffect(key) [for each enabled entry]
loop instantiate effects
DefaultRegistry-->>RichTextEffectsController: effect instance
end
DefaultRegistry-->>RichTextEffectsController: IReadOnlyList<RichTextEffect>
deactivate DefaultRegistry
RichTextEffectsController->>Host: CustomEffects = Array(effects)
deactivate RichTextEffectsController
Note over Host,RichTextEffect: 渲染时逐字符调用
Host->>RichTextEffect: _ProcessCustomFX(CharFXTransform)
RichTextEffect->>RichTextEffect: 读取 env、计算变换
RichTextEffect-->>Host: 修改字符变换
sequenceDiagram
participant Caller
participant RichTextMarkup
participant BBCode
Caller->>RichTextMarkup: Effect("Hello","fade_in", env)
activate RichTextMarkup
RichTextMarkup->>RichTextMarkup: 验证 tag/key 令牌
RichTextMarkup->>RichTextMarkup: 过滤 null 值、按 Ordinal 排序键、格式化值
RichTextMarkup-->>BBCode: "[fade_in speed=4 tick=0.1]Hello[/fade_in]"
deactivate RichTextMarkup
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 8
🧹 Nitpick comments (5)
GFramework.Godot/Text/RichTextMarkup.cs (1)
12-18: 公共 API 文档缺少异常契约说明。
Color与Effect会因无效tag抛出ArgumentException,建议在 XML 文档中补充<exception>,明确调用约束。As per coding guidelines:
All public, protected, and internal types and members MUST include XML documentation comments (...) with <exception> where applicable.Also applies to: 63-70
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@GFramework.Godot/Text/RichTextMarkup.cs` around lines 12 - 18, The public XML docs for Color (and similarly Effect) are missing an <exception> clause for invalid tags; update the XML comments for the Color method (and the Effect method at the indicated lines) to include an <exception cref="System.ArgumentException"> entry that states the method throws ArgumentException when the provided tag is null, empty, or otherwise invalid (i.e., does not constitute a valid BBCode tag), so callers know the contract and preconditions.GFramework.Godot/Text/IRichTextEffectRegistry.cs (1)
3-23: 作为核心 Registry 抽象,建议补齐“为何存在/何时使用/生命周期交互”文档。当前注释说明了“做什么”,但对与
RichTextEffectsController/GfRichTextLabel的交互时机、animatedEffectsEnabled的语义边界说明不足。As per coding guidelines:
Core framework components such as ... Registry ... MUST include high-level explanations of responsibilities, lifecycle, interaction with other components, why the abstraction exists, and when to use it instead of alternatives.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@GFramework.Godot/Text/IRichTextEffectRegistry.cs` around lines 3 - 23, Update the interface XML docs for IRichTextEffectRegistry to include high-level responsibilities and lifecycle guidance: explain why the registry exists (central mapping from profile keys to RichTextEffect instances), when it is used (called by RichTextEffectsController during profile application and by GfRichTextLabel when setting CustomEffects), expected lifetime/ownership of returned RichTextEffect instances, and precise semantics/boundary of the animatedEffectsEnabled parameter (what it enables/disables and when callers should toggle it). Also note when to prefer using the registry versus creating effects manually and reference RichTextProfile, CreateEffects, and CreateEffect in the remarks to make interactions explicit.GFramework.Godot/Text/Effects/RichTextEffectBase.cs (2)
15-18:bbcode属性使用小写命名符合 Godot 约定。这里的小写命名是 Godot
RichTextEffect的要求,建议在 XML 文档中补充说明这一点,以避免后续维护者误认为是命名规范违规。📝 建议补充文档说明
/// <summary> /// 获取 Godot 识别当前效果所需的 `bbcode` 属性。 + /// 属性名使用小写以符合 Godot RichTextEffect 的命名约定。 /// </summary> public string bbcode => TagName;🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@GFramework.Godot/Text/Effects/RichTextEffectBase.cs` around lines 15 - 18, The XML doc for the bbcode property should state that the lowercase name is intentional and required by Godot's RichTextEffect convention; update the documentation comment on the bbcode property (and/or the RichTextEffectBase class summary) to explicitly note that Godot expects a lowercase 'bbcode' identifier for RichTextEffect registration and that this property simply exposes TagName for that purpose, so future maintainers won't treat the lowercase name as a naming mistake.
27-52:GetBool和GetFloat缺少类型校验,与GetColor不一致。
GetColor在转换前检查value.VariantType == Variant.Type.Color,但GetBool和GetFloat直接调用AsBool()/AsDouble()。如果环境参数中存储了不兼容类型,可能导致意外的隐式转换行为。建议保持一致的防御性检查,或在 XML 文档中说明当前行为(Godot 的
Variant.AsBool()/Variant.AsDouble()对非预期类型的处理方式)。♻️ 可选:为 GetFloat 添加类型校验
protected float GetFloat(CharFXTransform transform, string key, float defaultValue) { - if (transform.Env.TryGetValue(Variant.From(key), out var value)) + if (transform.Env.TryGetValue(Variant.From(key), out var value) && + (value.VariantType == Variant.Type.Float || value.VariantType == Variant.Type.Int)) { return (float)value.AsDouble(); } return defaultValue; }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@GFramework.Godot/Text/Effects/RichTextEffectBase.cs` around lines 27 - 52, GetBool and GetFloat call value.AsBool()/AsDouble() without verifying value.VariantType, risking implicit/incorrect conversions; update both methods to mirror GetColor by checking value.VariantType (e.g., Variant.Type.Bool for GetBool and Variant.Type.Real/Variant.Type.Int as appropriate for GetFloat) before calling AsBool/AsDouble and return defaultValue when the type mismatches, using the same Variant.From(key) lookup on CharFXTransform.Env to locate the value.GFramework.Godot/Text/Effects/RichTextJitterEffect.cs (1)
45-55: 在_ProcessCustomFX中修改_noise.Seed可能存在状态污染风险。每次调用时修改
_noise.Seed依赖于 Godot 的效果处理是单线程顺序执行的假设。如果该效果实例被多个RichTextLabel共享或在未来版本中存在并发调用,可能导致不可预期的抖动行为。当前实现在单线程场景下是安全的,但建议在 XML 文档中注明线程安全假设,或考虑为每次调用创建局部
FastNoiseLite实例(会有性能开销)。🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@GFramework.Godot/Text/Effects/RichTextJitterEffect.cs` around lines 45 - 55, The code mutates shared _noise.Seed inside _ProcessCustomFX (RichTextJitterEffect) which can cause state pollution if the effect or _noise is shared or called concurrently; fix by not mutating the shared _noise: either document the single-threaded assumption in the XML/class comments for RichTextJitterEffect, or create a local FastNoiseLite per call (e.g., instantiate a new FastNoiseLite, copy necessary settings from _noise, set its Seed using (charFx.RelativeIndex + 1) * <prime>, then call GetNoise1D on that local instance to compute x and y before applying charFx.Offset and calling ApplyVisibility) to avoid changing _noise.Seed globally.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@GFramework.Godot.Tests/Text/RichTextMarkupTests.cs`:
- Around line 26-37: The test Effect_Should_Append_Environment_Parameters relies
on dictionary iteration order; fix by making RichTextMarkup.Effect
deterministic: when building the parameter string from the
IReadOnlyDictionary<string, object?> env, sort the keys (e.g., order by key)
before formatting key=value pairs so output is stable regardless of the
dictionary implementation; update the logic in RichTextMarkup.Effect that
iterates env to enumerate keys in a defined order and then join the pairs,
keeping the test unchanged.
In `@GFramework.Godot/Text/GfRichTextLabel.cs`:
- Around line 37-41: The EffectRegistry setter only updates _effectRegistry
leaving an already-created _controller (cached by EnsureController()) bound to
the old registry; when replacing EffectRegistry you must propagate the new
registry to the existing RichTextEffectsController instance (or recreate it).
Modify the EffectRegistry set accessor to, after assigning _effectRegistry,
check if _controller is non-null and then either set the controller's registry
property (e.g. _controller.EffectRegistry = _effectRegistry) or
dispose/clear/recreate the controller so EnsureController() will use the new
_effectRegistry; apply the same change pattern for the other analogous property
region mentioned (lines ~74-82).
- Around line 34-41: The EffectRegistry property setter can throw
ArgumentNullException when assigned a null value (it uses _effectRegistry ??=
new DefaultRichTextEffectRegistry() and the setter throws with nameof(value)),
so update the XML documentation for the internal property EffectRegistry to
include an <exception cref="System.ArgumentNullException"> entry that explains
the setter will throw if value is null; ensure the text mentions the setter and
the condition (null assignment) and keep the rest of the existing <summary>
intact.
- Around line 9-83: Add unit/integration tests for GfRichTextLabel to cover its
public API behavior: verify that toggling EnableFrameworkEffects enables
BbcodeEnabled and that AnimatedEffectsEnabled controls whether effects are
active (while still installing tags), verify Profile null fallback by asserting
EffectRegistry/default config is used when Profile is null, assert
RefreshFrameworkEffects() calls RefreshEffects on the RichTextEffectsController
(use a test double or mock for RichTextEffectsController via
EnsureController/DI), and verify replacing EffectRegistry updates installed
effects; focus tests on the methods/properties
GfRichTextLabel.RefreshFrameworkEffects, GfRichTextLabel.EnableFrameworkEffects,
GfRichTextLabel.AnimatedEffectsEnabled, GfRichTextLabel.Profile, EffectRegistry
and EnsureController behavior.
- Around line 46-51: In _Ready() the BbcodeEnabled flag is only set to true when
EnableFrameworkEffects is true, leaving it stale when effects are disabled;
change the logic to assign BbcodeEnabled directly from EnableFrameworkEffects
(i.e., BbcodeEnabled = EnableFrameworkEffects) so the two flags remain
symmetric, and ensure any related initialization in RefreshEffects() still
clears CustomEffects but does not rely on previous BbcodeEnabled state.
In `@GFramework.Godot/Text/RichTextEffectsController.cs`:
- Around line 25-39: Add XML documentation to the public constructor
RichTextEffectsController: include a <summary> describing the constructor and
add <param> entries for host, registry, profileAccessor,
frameworkEffectsEnabledAccessor, and animatedEffectsEnabledAccessor, and add
<exception cref="System.ArgumentNullException"> tags for each parameter that can
be null (host, registry, profileAccessor, frameworkEffectsEnabledAccessor,
animatedEffectsEnabledAccessor) indicating they will throw ArgumentNullException
if null; ensure the XML follows existing project style (///) and is placed
immediately above the constructor declaration.
In `@GFramework.Godot/Text/RichTextMarkup.cs`:
- Around line 72-90: The code in RichTextMarkup (the method that builds the
BBCode tag using ArgumentException.ThrowIfNullOrWhiteSpace(tag) and iterating
env pairs) currently writes raw tag and env keys into the BBCode token and can
produce invalid or injectable tokens; add a whitelist validation for the tag and
for each env key (the names used when appending pair.Key before
FormatValue(pair.Value)) to allow only a safe set of characters (e.g., ASCII
letters, digits, underscore and hyphen) and reject/throw for any key containing
whitespace or any of '[', ']', '=' or other characters outside the whitelist;
perform this check early (before building the StringBuilder) and ensure invalid
inputs result in ArgumentException (or skip/continue for env entries per current
behavior) so only validated tokens are emitted.
- Around line 80-91: Sort the env entries before building the attribute string
to ensure deterministic output: in the Effect method, enumerate env by ordering
its Keys (or the pairs by Key) prior to the foreach that appends
pair.Key/pair.Value so different IReadOnlyDictionary implementations produce
consistent BBCode; add XML doc <exception cref="ArgumentException"> tags to the
Effect method (for the ArgumentException.ThrowIfNullOrWhiteSpace(tag) case) and
to the Wrap method to document thrown exceptions; and add validation in Effect
and Wrap to reject/throw when tag or any env key contains BBCode control
characters like '[' ']' '=' (use ArgumentException) to prevent format injection.
---
Nitpick comments:
In `@GFramework.Godot/Text/Effects/RichTextEffectBase.cs`:
- Around line 15-18: The XML doc for the bbcode property should state that the
lowercase name is intentional and required by Godot's RichTextEffect convention;
update the documentation comment on the bbcode property (and/or the
RichTextEffectBase class summary) to explicitly note that Godot expects a
lowercase 'bbcode' identifier for RichTextEffect registration and that this
property simply exposes TagName for that purpose, so future maintainers won't
treat the lowercase name as a naming mistake.
- Around line 27-52: GetBool and GetFloat call value.AsBool()/AsDouble() without
verifying value.VariantType, risking implicit/incorrect conversions; update both
methods to mirror GetColor by checking value.VariantType (e.g.,
Variant.Type.Bool for GetBool and Variant.Type.Real/Variant.Type.Int as
appropriate for GetFloat) before calling AsBool/AsDouble and return defaultValue
when the type mismatches, using the same Variant.From(key) lookup on
CharFXTransform.Env to locate the value.
In `@GFramework.Godot/Text/Effects/RichTextJitterEffect.cs`:
- Around line 45-55: The code mutates shared _noise.Seed inside _ProcessCustomFX
(RichTextJitterEffect) which can cause state pollution if the effect or _noise
is shared or called concurrently; fix by not mutating the shared _noise: either
document the single-threaded assumption in the XML/class comments for
RichTextJitterEffect, or create a local FastNoiseLite per call (e.g.,
instantiate a new FastNoiseLite, copy necessary settings from _noise, set its
Seed using (charFx.RelativeIndex + 1) * <prime>, then call GetNoise1D on that
local instance to compute x and y before applying charFx.Offset and calling
ApplyVisibility) to avoid changing _noise.Seed globally.
In `@GFramework.Godot/Text/IRichTextEffectRegistry.cs`:
- Around line 3-23: Update the interface XML docs for IRichTextEffectRegistry to
include high-level responsibilities and lifecycle guidance: explain why the
registry exists (central mapping from profile keys to RichTextEffect instances),
when it is used (called by RichTextEffectsController during profile application
and by GfRichTextLabel when setting CustomEffects), expected lifetime/ownership
of returned RichTextEffect instances, and precise semantics/boundary of the
animatedEffectsEnabled parameter (what it enables/disables and when callers
should toggle it). Also note when to prefer using the registry versus creating
effects manually and reference RichTextProfile, CreateEffects, and CreateEffect
in the remarks to make interactions explicit.
In `@GFramework.Godot/Text/RichTextMarkup.cs`:
- Around line 12-18: The public XML docs for Color (and similarly Effect) are
missing an <exception> clause for invalid tags; update the XML comments for the
Color method (and the Effect method at the indicated lines) to include an
<exception cref="System.ArgumentException"> entry that states the method throws
ArgumentException when the provided tag is null, empty, or otherwise invalid
(i.e., does not constitute a valid BBCode tag), so callers know the contract and
preconditions.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: a98eae19-335b-4f67-88ac-71420cb6f858
📒 Files selected for processing (18)
GFramework.Godot.Tests/Text/RichTextMarkupTests.csGFramework.Godot.Tests/Text/RichTextProfileTests.csGFramework.Godot/Text/DefaultRichTextEffectRegistry.csGFramework.Godot/Text/Effects/RichTextBlueEffect.csGFramework.Godot/Text/Effects/RichTextEffectBase.csGFramework.Godot/Text/Effects/RichTextFadeInEffect.csGFramework.Godot/Text/Effects/RichTextFlyInEffect.csGFramework.Godot/Text/Effects/RichTextGoldEffect.csGFramework.Godot/Text/Effects/RichTextGreenEffect.csGFramework.Godot/Text/Effects/RichTextJitterEffect.csGFramework.Godot/Text/Effects/RichTextRedEffect.csGFramework.Godot/Text/Effects/RichTextSineEffect.csGFramework.Godot/Text/GfRichTextLabel.csGFramework.Godot/Text/IRichTextEffectRegistry.csGFramework.Godot/Text/RichTextEffectEntry.csGFramework.Godot/Text/RichTextEffectsController.csGFramework.Godot/Text/RichTextMarkup.csGFramework.Godot/Text/RichTextProfile.cs
📜 Review details
⏰ Context from checks skipped due to timeout of 900000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: Code Quality & Security
- GitHub Check: Analyze (C#)
🧰 Additional context used
📓 Path-based instructions (2)
**/*.cs
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.cs: Apply [Log] attribute for automatic logging field and logging helper method generation
Apply [Priority] attribute for automatic priority comparison implementation generation
Apply [GenerateEnumExtensions] attribute to generate enumeration extension capabilities
Apply [ContextAware] attribute to automatically implement IContextAware boilerplate logic
**/*.cs: All public, protected, and internal types and members MUST include XML documentation comments (///) with<summary>,<param>,<returns>,<exception>, and<remarks>where applicable
XML documentation comments must explain intent, contract, and usage constraints instead of restating syntax
If a member participates in lifecycle, threading, registration, or disposal behavior, document that behavior explicitly
Add inline comments for non-trivial logic, concurrency or threading behavior, performance-sensitive paths, workarounds, compatibility constraints or edge cases, and registration order or lifecycle sequencing
Avoid obvious comments such as// increment i
Core framework components such as Architecture, Module, System, Context, Registry, Service Module, and Lifecycle types MUST include high-level explanations of responsibilities, lifecycle, interaction with other components, why the abstraction exists, and when to use it instead of alternatives
Generated logic and generator pipelines MUST explain what is generated, why it is generated, the semantic assumptions the generator relies on, and any diagnostics or fallback behavior
Methods with non-trivial logic MUST document the core idea, key decisions, and edge case handling if any
Comments MUST NOT be trivial, redundant, or misleading; prefer explainingwhyandwhen, not justwhat
Prefer slightly more explanation over too little for framework code
Do not rely on implicit imports; declare every requiredusingexplicitly
Write null-safe code that respects nullable annotations instead of suppressing warnings by default
Use the namespac...
Files:
GFramework.Godot/Text/RichTextEffectEntry.csGFramework.Godot.Tests/Text/RichTextProfileTests.csGFramework.Godot/Text/Effects/RichTextRedEffect.csGFramework.Godot/Text/RichTextProfile.csGFramework.Godot/Text/Effects/RichTextGreenEffect.csGFramework.Godot/Text/Effects/RichTextBlueEffect.csGFramework.Godot.Tests/Text/RichTextMarkupTests.csGFramework.Godot/Text/IRichTextEffectRegistry.csGFramework.Godot/Text/Effects/RichTextGoldEffect.csGFramework.Godot/Text/Effects/RichTextSineEffect.csGFramework.Godot/Text/Effects/RichTextFlyInEffect.csGFramework.Godot/Text/DefaultRichTextEffectRegistry.csGFramework.Godot/Text/Effects/RichTextJitterEffect.csGFramework.Godot/Text/RichTextMarkup.csGFramework.Godot/Text/Effects/RichTextFadeInEffect.csGFramework.Godot/Text/RichTextEffectsController.csGFramework.Godot/Text/Effects/RichTextEffectBase.csGFramework.Godot/Text/GfRichTextLabel.cs
**/*.{cs,csproj,xml,yaml,json,md}
📄 CodeRabbit inference engine (AGENTS.md)
Use 4 spaces for indentation; do not use tabs
Files:
GFramework.Godot/Text/RichTextEffectEntry.csGFramework.Godot.Tests/Text/RichTextProfileTests.csGFramework.Godot/Text/Effects/RichTextRedEffect.csGFramework.Godot/Text/RichTextProfile.csGFramework.Godot/Text/Effects/RichTextGreenEffect.csGFramework.Godot/Text/Effects/RichTextBlueEffect.csGFramework.Godot.Tests/Text/RichTextMarkupTests.csGFramework.Godot/Text/IRichTextEffectRegistry.csGFramework.Godot/Text/Effects/RichTextGoldEffect.csGFramework.Godot/Text/Effects/RichTextSineEffect.csGFramework.Godot/Text/Effects/RichTextFlyInEffect.csGFramework.Godot/Text/DefaultRichTextEffectRegistry.csGFramework.Godot/Text/Effects/RichTextJitterEffect.csGFramework.Godot/Text/RichTextMarkup.csGFramework.Godot/Text/Effects/RichTextFadeInEffect.csGFramework.Godot/Text/RichTextEffectsController.csGFramework.Godot/Text/Effects/RichTextEffectBase.csGFramework.Godot/Text/GfRichTextLabel.cs
🧠 Learnings (2)
📚 Learning: 2026-04-06T12:45:43.921Z
Learnt from: GeWuYou
Repo: GeWuYou/GFramework PR: 190
File: GFramework.Game/Config/GameConfigBootstrap.cs:1-3
Timestamp: 2026-04-06T12:45:43.921Z
Learning: In the GeWuYou/GFramework repository, C# files may omit explicit `using System*` imports because the project-wide `GlobalUsings.cs` (referenced via manual global `using` directives) supplies common namespaces (e.g., `System`, `System.Threading`, `System.Threading.Tasks`). During code review, do not flag missing `using System...` directives in `.cs` files as long as `GlobalUsings.cs` is present/used to provide those namespaces.
Applied to files:
GFramework.Godot/Text/RichTextEffectEntry.csGFramework.Godot.Tests/Text/RichTextProfileTests.csGFramework.Godot/Text/Effects/RichTextRedEffect.csGFramework.Godot/Text/RichTextProfile.csGFramework.Godot/Text/Effects/RichTextGreenEffect.csGFramework.Godot/Text/Effects/RichTextBlueEffect.csGFramework.Godot.Tests/Text/RichTextMarkupTests.csGFramework.Godot/Text/IRichTextEffectRegistry.csGFramework.Godot/Text/Effects/RichTextGoldEffect.csGFramework.Godot/Text/Effects/RichTextSineEffect.csGFramework.Godot/Text/Effects/RichTextFlyInEffect.csGFramework.Godot/Text/DefaultRichTextEffectRegistry.csGFramework.Godot/Text/Effects/RichTextJitterEffect.csGFramework.Godot/Text/RichTextMarkup.csGFramework.Godot/Text/Effects/RichTextFadeInEffect.csGFramework.Godot/Text/RichTextEffectsController.csGFramework.Godot/Text/Effects/RichTextEffectBase.csGFramework.Godot/Text/GfRichTextLabel.cs
📚 Learning: 2026-04-18T02:29:44.423Z
Learnt from: CR
Repo: GeWuYou/GFramework PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-18T02:29:44.423Z
Learning: Applies to **/*.Tests.cs : Regression fixes should include a test that fails before the fix and passes after it
Applied to files:
GFramework.Godot.Tests/Text/RichTextProfileTests.csGFramework.Godot.Tests/Text/RichTextMarkupTests.cs
🔇 Additional comments (12)
GFramework.Godot/Text/Effects/RichTextBlueEffect.cs (1)
3-27: 实现简洁且行为明确,当前改动可接受。
TagName与_ProcessCustomFX的语义一致,颜色效果实现直接且可读性好。GFramework.Godot.Tests/Text/RichTextProfileTests.cs (1)
14-30: 测试覆盖点合理,断言粒度到位。该用例同时校验键集合与顺序,能有效保护默认内置配置不被无意改坏。
GFramework.Godot/Text/Effects/RichTextRedEffect.cs (1)
3-27: 实现一致性良好,改动可接受。标签名与颜色常量匹配,
_ProcessCustomFX行为明确。GFramework.Godot/Text/RichTextEffectEntry.cs (1)
3-22: 职责边界定义清晰,当前设计合理。配置项模型保持轻量,仅表达键与启用状态,便于与注册表职责解耦。
GFramework.Godot/Text/Effects/RichTextGoldEffect.cs (1)
3-27: 实现风格统一,行为正确。与同类颜色效果的结构一致,便于后续维护与扩展。
GFramework.Godot/Text/Effects/RichTextGreenEffect.cs (1)
3-27: 实现清晰且可读性好,当前改动通过。
TagName与颜色应用逻辑一致,符合该效果类职责。GFramework.Godot/Text/RichTextProfile.cs (1)
1-37: LGTM!代码结构清晰,XML 文档完整。
CreateBuiltInDefault()工厂方法提供了零配置可用的默认效果组合,与DefaultRichTextEffectRegistry中的效果键映射保持一致。GFramework.Godot/Text/Effects/RichTextFadeInEffect.cs (1)
1-47: LGTM!淡入效果实现正确,使用
charFx.ElapsedTime和charFx.RelativeIndex计算逐字符进度,alpha 值正确裁剪到[0,1]范围。GFramework.Godot/Text/Effects/RichTextSineEffect.cs (1)
1-47: LGTM!正弦波效果实现正确,相位计算考虑了时间和字符索引偏移,波形参数(amplitude、frequency、speed)可通过标签环境参数自定义。
GFramework.Godot/Text/Effects/RichTextFlyInEffect.cs (1)
1-64: LGTM!飞入效果实现完整,结合了位置偏移和透明度渐变。
EaseOutQuad缓动函数提供平滑的减速效果,提升视觉体验。GFramework.Godot/Text/DefaultRichTextEffectRegistry.cs (1)
1-65: LGTM!注册表实现清晰,效果键映射与
RichTextProfile.CreateBuiltInDefault()中定义的 8 个内置键完全对应。键名规范化处理(Trim().ToLowerInvariant())增强了容错性,区分颜色效果和动画效果的参数传递设计合理。GFramework.Godot/Text/RichTextEffectsController.cs (1)
52-69: 效果刷新流程清晰,回退路径明确。禁用开关时立即清空、启用时按配置重建
CustomEffects,行为一致且可维护。
- 创建 RichTextEffectBase 基类提供统一的标签命名和环境参数读取逻辑 - 实现 RichTextJitterEffect 抖动效果类,支持振幅和速度参数调节 - 添加 DefaultRichTextEffectRegistry 默认效果注册表管理内置效果映射 - 创建 GfRichTextLabel 组合式富文本标签宿主,集成效果装配逻辑 - 定义 IRichTextEffectRegistry 接口实现效果注册表抽象 - 开发 RichTextEffectsController 装配控制器负责效果集合管理 - 实现 RichTextMarkup 工具类提供语义化富文本标签构建辅助方法 - 添加相关单元测试验证效果控制器和标记工具的功能正确性
There was a problem hiding this comment.
🧹 Nitpick comments (1)
GFramework.Godot.Tests/Text/RichTextEffectsControllerTests.cs (1)
108-125: 建议:RecordingRegistry可记录每次调用的animatedEffectsEnabled值。当前
CapturedAnimatedEffectsEnabled仅保留最后一次调用的值(第 117 行)。若未来测试需验证多次调用时传入的不同animatedEffectsEnabled值,可考虑改为列表记录。♻️ 可选改进
private sealed class RecordingRegistry : IRichTextEffectRegistry { public List<RichTextProfile> CapturedProfiles { get; } = []; - public bool CapturedAnimatedEffectsEnabled { get; private set; } + public List<bool> CapturedAnimatedEffectsEnabled { get; } = []; public IReadOnlyList<RichTextEffect> CreateEffects(RichTextProfile profile, bool animatedEffectsEnabled) { CapturedProfiles.Add(profile); - CapturedAnimatedEffectsEnabled = animatedEffectsEnabled; + CapturedAnimatedEffectsEnabled.Add(animatedEffectsEnabled); return System.Array.Empty<RichTextEffect>(); }同时更新断言:
-Assert.That(registry.CapturedAnimatedEffectsEnabled, Is.False); +Assert.That(registry.CapturedAnimatedEffectsEnabled[0], Is.False);🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@GFramework.Godot.Tests/Text/RichTextEffectsControllerTests.cs` around lines 108 - 125, The RecordingRegistry currently only keeps the last animatedEffectsEnabled value; change CapturedAnimatedEffectsEnabled from a single bool to a collection (e.g., List<bool> CapturedAnimatedEffectsEnabled) and append the incoming animatedEffectsEnabled inside CreateEffects so every call is recorded; keep CapturedProfiles behavior (List<RichTextProfile> CapturedProfiles) and update tests to assert against CapturedAnimatedEffectsEnabled sequence instead of a single value.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@GFramework.Godot.Tests/Text/RichTextEffectsControllerTests.cs`:
- Around line 108-125: The RecordingRegistry currently only keeps the last
animatedEffectsEnabled value; change CapturedAnimatedEffectsEnabled from a
single bool to a collection (e.g., List<bool> CapturedAnimatedEffectsEnabled)
and append the incoming animatedEffectsEnabled inside CreateEffects so every
call is recorded; keep CapturedProfiles behavior (List<RichTextProfile>
CapturedProfiles) and update tests to assert against
CapturedAnimatedEffectsEnabled sequence instead of a single value.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 2f68f449-0e00-4958-ad08-667c14877e64
📒 Files selected for processing (10)
GFramework.Godot.Tests/Text/RichTextEffectsControllerTests.csGFramework.Godot.Tests/Text/RichTextMarkupTests.csGFramework.Godot/Text/DefaultRichTextEffectRegistry.csGFramework.Godot/Text/Effects/RichTextEffectBase.csGFramework.Godot/Text/Effects/RichTextJitterEffect.csGFramework.Godot/Text/GfRichTextLabel.csGFramework.Godot/Text/IRichTextEffectHost.csGFramework.Godot/Text/IRichTextEffectRegistry.csGFramework.Godot/Text/RichTextEffectsController.csGFramework.Godot/Text/RichTextMarkup.cs
✅ Files skipped from review due to trivial changes (4)
- GFramework.Godot/Text/IRichTextEffectHost.cs
- GFramework.Godot/Text/IRichTextEffectRegistry.cs
- GFramework.Godot/Text/Effects/RichTextEffectBase.cs
- GFramework.Godot/Text/RichTextMarkup.cs
📜 Review details
⏰ Context from checks skipped due to timeout of 900000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: Analyze (C#)
- GitHub Check: Code Quality & Security
🧰 Additional context used
📓 Path-based instructions (2)
**/*.cs
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.cs: Apply [Log] attribute for automatic logging field and logging helper method generation
Apply [Priority] attribute for automatic priority comparison implementation generation
Apply [GenerateEnumExtensions] attribute to generate enumeration extension capabilities
Apply [ContextAware] attribute to automatically implement IContextAware boilerplate logic
**/*.cs: All public, protected, and internal types and members MUST include XML documentation comments (///) with<summary>,<param>,<returns>,<exception>, and<remarks>where applicable
XML documentation comments must explain intent, contract, and usage constraints instead of restating syntax
If a member participates in lifecycle, threading, registration, or disposal behavior, document that behavior explicitly
Add inline comments for non-trivial logic, concurrency or threading behavior, performance-sensitive paths, workarounds, compatibility constraints or edge cases, and registration order or lifecycle sequencing
Avoid obvious comments such as// increment i
Core framework components such as Architecture, Module, System, Context, Registry, Service Module, and Lifecycle types MUST include high-level explanations of responsibilities, lifecycle, interaction with other components, why the abstraction exists, and when to use it instead of alternatives
Generated logic and generator pipelines MUST explain what is generated, why it is generated, the semantic assumptions the generator relies on, and any diagnostics or fallback behavior
Methods with non-trivial logic MUST document the core idea, key decisions, and edge case handling if any
Comments MUST NOT be trivial, redundant, or misleading; prefer explainingwhyandwhen, not justwhat
Prefer slightly more explanation over too little for framework code
Do not rely on implicit imports; declare every requiredusingexplicitly
Write null-safe code that respects nullable annotations instead of suppressing warnings by default
Use the namespac...
Files:
GFramework.Godot/Text/GfRichTextLabel.csGFramework.Godot.Tests/Text/RichTextMarkupTests.csGFramework.Godot/Text/RichTextEffectsController.csGFramework.Godot.Tests/Text/RichTextEffectsControllerTests.csGFramework.Godot/Text/DefaultRichTextEffectRegistry.csGFramework.Godot/Text/Effects/RichTextJitterEffect.cs
**/*.{cs,csproj,xml,yaml,json,md}
📄 CodeRabbit inference engine (AGENTS.md)
Use 4 spaces for indentation; do not use tabs
Files:
GFramework.Godot/Text/GfRichTextLabel.csGFramework.Godot.Tests/Text/RichTextMarkupTests.csGFramework.Godot/Text/RichTextEffectsController.csGFramework.Godot.Tests/Text/RichTextEffectsControllerTests.csGFramework.Godot/Text/DefaultRichTextEffectRegistry.csGFramework.Godot/Text/Effects/RichTextJitterEffect.cs
🧠 Learnings (7)
📚 Learning: 2026-04-18T02:29:44.423Z
Learnt from: CR
Repo: GeWuYou/GFramework PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-18T02:29:44.423Z
Learning: Applies to **/*.cs : Public API changes must be covered by unit or integration tests
Applied to files:
GFramework.Godot/Text/GfRichTextLabel.csGFramework.Godot.Tests/Text/RichTextMarkupTests.csGFramework.Godot.Tests/Text/RichTextEffectsControllerTests.cs
📚 Learning: 2026-04-18T02:29:44.423Z
Learnt from: CR
Repo: GeWuYou/GFramework PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-18T02:29:44.423Z
Learning: Applies to **/*.Tests.cs : Regression fixes should include a test that fails before the fix and passes after it
Applied to files:
GFramework.Godot/Text/GfRichTextLabel.csGFramework.Godot.Tests/Text/RichTextMarkupTests.csGFramework.Godot.Tests/Text/RichTextEffectsControllerTests.cs
📚 Learning: 2026-04-18T02:29:44.423Z
Learnt from: CR
Repo: GeWuYou/GFramework PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-18T02:29:44.423Z
Learning: Applies to **/*.Tests.cs : When a public API defines multiple contract branches, tests MUST cover the meaningful variants, including null, empty, default, and filtered inputs when those branches change behavior
Applied to files:
GFramework.Godot/Text/GfRichTextLabel.csGFramework.Godot.Tests/Text/RichTextEffectsControllerTests.cs
📚 Learning: 2026-04-18T02:29:44.423Z
Learnt from: CR
Repo: GeWuYou/GFramework PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-18T02:29:44.423Z
Learning: Before considering work complete, confirm: required comments and XML docs are present, code follows repository style and naming rules, relevant tests were added or updated, sensitive or unsafe behavior was not introduced, user-facing documentation is updated when needed, and feature adoption docs under `docs/zh-CN/` were added or updated when functionality was added, removed, or refactored
Applied to files:
GFramework.Godot/Text/GfRichTextLabel.cs
📚 Learning: 2026-04-18T02:29:44.423Z
Learnt from: CR
Repo: GeWuYou/GFramework PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-18T02:29:44.423Z
Learning: Every non-trivial feature, bug fix, or behavior change MUST include tests or an explicit justification for why a test is not practical
Applied to files:
GFramework.Godot/Text/GfRichTextLabel.cs
📚 Learning: 2026-04-06T12:45:43.921Z
Learnt from: GeWuYou
Repo: GeWuYou/GFramework PR: 190
File: GFramework.Game/Config/GameConfigBootstrap.cs:1-3
Timestamp: 2026-04-06T12:45:43.921Z
Learning: In the GeWuYou/GFramework repository, C# files may omit explicit `using System*` imports because the project-wide `GlobalUsings.cs` (referenced via manual global `using` directives) supplies common namespaces (e.g., `System`, `System.Threading`, `System.Threading.Tasks`). During code review, do not flag missing `using System...` directives in `.cs` files as long as `GlobalUsings.cs` is present/used to provide those namespaces.
Applied to files:
GFramework.Godot/Text/GfRichTextLabel.csGFramework.Godot.Tests/Text/RichTextMarkupTests.csGFramework.Godot/Text/RichTextEffectsController.csGFramework.Godot.Tests/Text/RichTextEffectsControllerTests.csGFramework.Godot/Text/DefaultRichTextEffectRegistry.csGFramework.Godot/Text/Effects/RichTextJitterEffect.cs
📚 Learning: 2026-04-18T02:29:44.423Z
Learnt from: CR
Repo: GeWuYou/GFramework PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-18T02:29:44.423Z
Learning: Applies to **/*.Tests.cs : Reuse existing architecture test infrastructure when relevant: `ArchitectureTestsBase<T>`, `SyncTestArchitecture`, `AsyncTestArchitecture`
Applied to files:
GFramework.Godot.Tests/Text/RichTextEffectsControllerTests.cs
🔇 Additional comments (6)
GFramework.Godot/Text/Effects/RichTextJitterEffect.cs (1)
1-62: LGTM!实现清晰,XML 文档完整且解释了线程安全假设。噪声种子基于
RelativeIndex的确定性重置策略保证了每个字符的抖动一致性。GFramework.Godot/Text/DefaultRichTextEffectRegistry.cs (1)
1-68: LGTM!注册表实现简洁,
CreateEffects方法正确处理空值和禁用项,CreateEffect使用 switch 表达式清晰地映射效果键到具体实例。GFramework.Godot.Tests/Text/RichTextMarkupTests.cs (1)
1-65: LGTM!测试覆盖了
RichTextMarkup的核心行为:颜色快捷方法、环境参数按键排序、以及非法标签/键的拒绝。实现层已通过CollectEnvironmentPairs确保参数排序确定性,测试断言正确。GFramework.Godot/Text/RichTextEffectsController.cs (1)
59-69: 设计确认:BbcodeEnabled状态管理符合文档语义。当前实现仅在启用框架效果时设置
BbcodeEnabled = true,禁用时不重置。这与GfRichTextLabel.EnableFrameworkEffects属性文档的约定一致:"关闭后只会停止框架效果安装,不会覆盖调用方手动维护的其他 BBCode 解析状态"。此设计避免了框架效果开关意外覆盖用户手动设置的 BBCode 状态。
GFramework.Godot/Text/GfRichTextLabel.cs (1)
68-76: LGTM!
EnsureController()使用闭包捕获EffectRegistry访问器而非实例,确保每次RefreshEffects()调用时读取最新的注册表。测试RefreshEffects_Should_Use_The_Current_Registry_From_Accessor已验证此行为。GFramework.Godot.Tests/Text/RichTextEffectsControllerTests.cs (1)
1-99: LGTM!测试覆盖了控制器的核心行为分支:启用时的 BBCode 开启与默认配置回退、禁用时的效果清空、以及注册表访问器的动态读取。测试替身设计简洁有效。
- 配置GitHub Actions工作流用于PR构建和测试 - 实现代码质量检查和安全扫描功能 - 添加.NET多版本SDK支持和依赖缓存 - 集成MegaLinter和TruffleHog安全工具 - 创建RichTextEffectsController的单元测试覆盖各种场景 - 实现测试报告生成和发布功能
- 将 RichTextEffectsControllerTests 中的 GFramework.Godot.Text 引用替换为 Godot 相关命名空间 - 使用 Godot.Collections.Array 替代系统数组类型 - 在 GlobalUsings 中添加 GFramework.Godot.Text 的全局引用 - 修复返回类型以使用新的 Array<RichTextEffect> 结构
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@GFramework.Godot.Tests/Text/RichTextEffectsControllerTests.cs`:
- Around line 1-3: The test file defines a conflicting alias "using Array =
Godot.Collections.Array;" which hides System.Array and causes
Array.Empty<RichTextEffect>() to resolve to the wrong type; fix by replacing
that call with System.Array.Empty<RichTextEffect>() (or remove/rename the alias)
where it's used in RichTextEffectsControllerTests so the generic Empty<T>()
resolves to System.Array; search for Array.Empty<RichTextEffect>() in the test
class and update it to System.Array.Empty<RichTextEffect>().
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 7eaeba7d-4c17-4990-b18b-c658d674aa00
📒 Files selected for processing (2)
.github/workflows/ci.ymlGFramework.Godot.Tests/Text/RichTextEffectsControllerTests.cs
📜 Review details
⏰ Context from checks skipped due to timeout of 900000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: Code Quality & Security
- GitHub Check: Analyze (C#)
🧰 Additional context used
📓 Path-based instructions (2)
**/*.cs
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.cs: Apply [Log] attribute for automatic logging field and logging helper method generation
Apply [Priority] attribute for automatic priority comparison implementation generation
Apply [GenerateEnumExtensions] attribute to generate enumeration extension capabilities
Apply [ContextAware] attribute to automatically implement IContextAware boilerplate logic
**/*.cs: All public, protected, and internal types and members MUST include XML documentation comments (///) with<summary>,<param>,<returns>,<exception>, and<remarks>where applicable
XML documentation comments must explain intent, contract, and usage constraints instead of restating syntax
If a member participates in lifecycle, threading, registration, or disposal behavior, document that behavior explicitly
Add inline comments for non-trivial logic, concurrency or threading behavior, performance-sensitive paths, workarounds, compatibility constraints or edge cases, and registration order or lifecycle sequencing
Avoid obvious comments such as// increment i
Core framework components such as Architecture, Module, System, Context, Registry, Service Module, and Lifecycle types MUST include high-level explanations of responsibilities, lifecycle, interaction with other components, why the abstraction exists, and when to use it instead of alternatives
Generated logic and generator pipelines MUST explain what is generated, why it is generated, the semantic assumptions the generator relies on, and any diagnostics or fallback behavior
Methods with non-trivial logic MUST document the core idea, key decisions, and edge case handling if any
Comments MUST NOT be trivial, redundant, or misleading; prefer explainingwhyandwhen, not justwhat
Prefer slightly more explanation over too little for framework code
Do not rely on implicit imports; declare every requiredusingexplicitly
Write null-safe code that respects nullable annotations instead of suppressing warnings by default
Use the namespac...
Files:
GFramework.Godot.Tests/Text/RichTextEffectsControllerTests.cs
**/*.{cs,csproj,xml,yaml,json,md}
📄 CodeRabbit inference engine (AGENTS.md)
Use 4 spaces for indentation; do not use tabs
Files:
GFramework.Godot.Tests/Text/RichTextEffectsControllerTests.cs
🧠 Learnings (2)
📚 Learning: 2026-04-18T02:29:44.423Z
Learnt from: CR
Repo: GeWuYou/GFramework PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-18T02:29:44.423Z
Learning: Applies to **/*.Tests.cs : Regression fixes should include a test that fails before the fix and passes after it
Applied to files:
.github/workflows/ci.ymlGFramework.Godot.Tests/Text/RichTextEffectsControllerTests.cs
📚 Learning: 2026-04-06T12:45:43.921Z
Learnt from: GeWuYou
Repo: GeWuYou/GFramework PR: 190
File: GFramework.Game/Config/GameConfigBootstrap.cs:1-3
Timestamp: 2026-04-06T12:45:43.921Z
Learning: In the GeWuYou/GFramework repository, C# files may omit explicit `using System*` imports because the project-wide `GlobalUsings.cs` (referenced via manual global `using` directives) supplies common namespaces (e.g., `System`, `System.Threading`, `System.Threading.Tasks`). During code review, do not flag missing `using System...` directives in `.cs` files as long as `GlobalUsings.cs` is present/used to provide those namespaces.
Applied to files:
GFramework.Godot.Tests/Text/RichTextEffectsControllerTests.cs
🪛 GitHub Check: Build and Test
GFramework.Godot.Tests/Text/RichTextEffectsControllerTests.cs
[failure] 108-108:
'RichTextEffectsControllerTests.RecordingRegistry' does not implement interface member 'IRichTextEffectRegistry.CreateEffect(string, bool)'. 'RichTextEffectsControllerTests.RecordingRegistry.CreateEffect(string, bool)' cannot implement 'IRichTextEffectRegistry.CreateEffect(string, bool)' because it does not have the matching return type of 'RichTextEffect'.
[failure] 108-108:
'RichTextEffectsControllerTests.RecordingRegistry' does not implement interface member 'IRichTextEffectRegistry.CreateEffects(RichTextProfile, bool)'. 'RichTextEffectsControllerTests.RecordingRegistry.CreateEffects(RichTextProfile, bool)' cannot implement 'IRichTextEffectRegistry.CreateEffects(RichTextProfile, bool)' because it does not have the matching return type of 'IReadOnlyList'.
[failure] 121-121:
The type or namespace name 'RichTextEffect' could not be found (are you missing a using directive or an assembly reference?)
[failure] 114-114:
The type or namespace name 'RichTextEffect' could not be found (are you missing a using directive or an assembly reference?)
[failure] 108-108:
'RichTextEffectsControllerTests.RecordingRegistry' does not implement interface member 'IRichTextEffectRegistry.CreateEffect(string, bool)'. 'RichTextEffectsControllerTests.RecordingRegistry.CreateEffect(string, bool)' cannot implement 'IRichTextEffectRegistry.CreateEffect(string, bool)' because it does not have the matching return type of 'RichTextEffect'.
[failure] 108-108:
'RichTextEffectsControllerTests.RecordingRegistry' does not implement interface member 'IRichTextEffectRegistry.CreateEffects(RichTextProfile, bool)'. 'RichTextEffectsControllerTests.RecordingRegistry.CreateEffects(RichTextProfile, bool)' cannot implement 'IRichTextEffectRegistry.CreateEffects(RichTextProfile, bool)' because it does not have the matching return type of 'IReadOnlyList'.
[failure] 121-121:
The type or namespace name 'RichTextEffect' could not be found (are you missing a using directive or an assembly reference?)
[failure] 114-114:
The type or namespace name 'RichTextEffect' could not be found (are you missing a using directive or an assembly reference?)
🔇 Additional comments (3)
.github/workflows/ci.yml (2)
148-153: 顺序执行测试并预创建结果目录的改动很稳妥。Line 148-153 将测试改为串行并提前创建
TestResults,能有效降低并发测试导致的“假红”概率。
165-190: 失败聚合与统一输出设计清晰。Line 165-190 使用
failed与failed_projects聚合失败项目,并在循环后统一输出,便于后续步骤做可靠失败判定。GFramework.Godot.Tests/Text/RichTextEffectsControllerTests.cs (1)
16-99: 测试场景覆盖完整,核心行为验证到位启用/禁用分支、内置 Profile 回退、以及“每次刷新重新读取注册表访问器”的行为都被覆盖,测试目标与控制器职责一致。
- 添加pull-requests写入权限以支持PR评论功能 - 修改pull-request-report条件避免跨仓库触发错误
Summary
Test ResultsDetails
Insights
build-and-test: Run #867
🎉 All tests passed!Slowest Tests
± Comparison with run #866 at b20c6c2 | 🎉 No failed tests detected across all runs. | 🍂 No flaky tests detected across all runs. | ⏱️ Measured over 4 runs. Github Test Reporter by CTRF 💚 |
✅
|
| Descriptor | Linter | Files | Fixed | Errors | Warnings | Elapsed time |
|---|---|---|---|---|---|---|
| dotnet-format | yes | 1 | no | 0.79s | ||
| ✅ REPOSITORY | gitleaks | yes | no | no | 3.44s | |
| ✅ REPOSITORY | trufflehog | yes | no | no | 3.87s |
Detailed Issues
⚠️ CSHARP / dotnet-format - 1 error
Welcome to .NET 9.0!
---------------------
SDK Version: 9.0.114
----------------
Installed an ASP.NET Core HTTPS development certificate.
To trust the certificate, run 'dotnet dev-certs https --trust'
Learn about HTTPS: https://aka.ms/dotnet-https
----------------
Write your first app: https://aka.ms/dotnet-hello-world
Find out what's new: https://aka.ms/dotnet-whats-new
Explore documentation: https://aka.ms/dotnet-docs
Report issues and find source on GitHub: https://github.com/dotnet/core
Use 'dotnet --help' to see available commands or visit: https://aka.ms/dotnet-cli
--------------------------------------------------------------------------------------
Unhandled exception: System.IO.FileNotFoundException: Both a MSBuild project file and solution file found in ''. Specify which to use with the <workspace> argument.
at Microsoft.CodeAnalysis.Tools.Workspaces.MSBuildWorkspaceFinder.FindWorkspace(String searchDirectory, String workspacePath)
at Microsoft.CodeAnalysis.Tools.Workspaces.MSBuildWorkspaceFinder.FindWorkspace(String searchDirectory, String workspacePath)
at Microsoft.CodeAnalysis.Tools.FormatCommandCommon.ParseWorkspaceOptions(ParseResult parseResult, FormatOptions formatOptions)
at Microsoft.CodeAnalysis.Tools.Commands.RootFormatCommand.FormatCommandDefaultHandler.InvokeAsync(ParseResult parseResult, CancellationToken cancellationToken)
at System.CommandLine.Invocation.InvocationPipeline.InvokeAsync(ParseResult parseResult, CancellationToken cancellationToken)
See detailed reports in MegaLinter artifacts
Set VALIDATE_ALL_CODEBASE: true in mega-linter.yml to validate all sources, not only the diff

Show us your support by starring ⭐ the repository
- 使用here document格式正确输出失败项目列表到GITHUB_OUTPUT - 添加EOF分隔符确保多行内容正确传递 - 在失败步骤中读取并显示具体的失败项目名称 - 保持原有的退出码设置确保工作流正确失败
Summary
Test ResultsDetails
Insights
build-and-test: Run #868
🎉 All tests passed!Slowest Tests
± Comparison with run #867 at f31bd60 | 🎉 No failed tests detected across all runs. | 🍂 No flaky tests detected across all runs. | ⏱️ Measured over 5 runs. Github Test Reporter by CTRF 💚 |
- 配置pull request触发的构建和测试流程 - 集成代码质量检查和安全扫描功能 - 设置.NET多版本SDK环境支持 - 配置NuGet包和dotnet工具缓存优化 - 实现Node.js和Bun运行时环境搭建 - 添加配置工具依赖安装和测试执行 - 配置项目构建和单元测试执行流程 - 集成测试报告生成和发布功能 - 实现失败测试项目的错误处理机制
Summary
Test ResultsDetails
Insights
build-and-test: Run #869
🎉 All tests passed!Slowest Tests
± Comparison with run #868 at 973aefb | 🎉 No failed tests detected across all runs. | 🍂 No flaky tests detected across all runs. | ⏱️ Measured over 6 runs. Github Test Reporter by CTRF 💚 |
- 新增 GfRichTextLabel 组件作为富文本标签宿主 - 实现 IRichTextEffectHost 接口用于效果控制器驱动 - 创建 RichTextEffectsController 处理效果装配逻辑 - 添加 RichTextProfile 配置资源类型 - 引入 RichTextEffectPlan 和 RichTextEffectPlanEntry 类型 - 在 CI 工作流中添加 GFramework.Godot.Tests 项目 - 优化 Godot 测试诊断条件判断逻辑 - 添加富文本效果控制器相关单元测试
Summary
Test ResultsDetails
Insights
build-and-test: Run #870
🎉 All tests passed!Slowest Tests
± Comparison with run #869 at 0b66484 | 🎉 No failed tests detected across all runs. | 🍂 No flaky tests detected across all runs. | ⏱️ Measured over 7 runs. Github Test Reporter by CTRF 💚 |
Summary by CodeRabbit
新功能
测试
运维
其他