Skip to content

Conversation

@Joy-less
Copy link
Contributor

@Joy-less Joy-less commented Jan 25, 2026

Cherry-picked from my pull request in godotengine/godot at the request of @Arctis-Fireblight.

Summary by CodeRabbit

  • New Features

    • Added string comparison methods to NodePath and StringName, enabling direct equality checks with string values.
  • Refactor

    • Optimized string conversion performance for NodePath and StringName objects through improved internal handling.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link

coderabbitai bot commented Jan 25, 2026

Walkthrough

Both NodePath and StringName classes are enhanced with static ConcurrentDictionary-based caching to store weak references, enabling reuse of instances for identical input strings. Changes include: readonly modification to _weakReferenceToSelf, new input/output string tracking fields, cache removal logic in Dispose(), nullable implicit operators with caching logic, and ToString() now returning cached strings instead of marshaling from native values. New Equals(string?) overload added for string comparison.

Changes

Cohort / File(s) Summary
NodePath Caching Implementation
modules/mono/glue/GodotSharp/GodotSharp/Core/NodePath.cs
Added static _nodePathCache (ConcurrentDictionary) and input/output string tracking fields (_inputString, _outputString). Constructor logic updated to populate cached state; implicit operator NodePath(string?) now checks cache before creating instances. Dispose() removes entries from cache. ToString() returns cached _outputString instead of marshaling. New Equals(string?) overload compares against string by native conversion. _weakReferenceToSelf made readonly.
StringName Caching Implementation
modules/mono/glue/GodotSharp/GodotSharp/Core/StringName.cs
Parallel caching architecture: static _stringNameCache (ConcurrentDictionary) stores weak references. Input/output string tracking fields (_inputString, _outputString) added. Constructor initialization updated; implicit operator StringName?(string?) implements cache lookup and storage. Dispose() cleans up cache entries. ToString() returns cached _outputString. New Equals(string?) overload added. _weakReferenceToSelf marked readonly.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 40.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Cache StringNames & NodePaths' is clear, concise, and directly summarizes the main change: introducing caching mechanisms for both StringName and NodePath classes.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In `@modules/mono/glue/GodotSharp/GodotSharp/Core/NodePath.cs`:
- Around line 177-192: Cached weak references in _nodePathCache for NodePath can
become dead and remain in the dictionary, causing repeated cache misses; modify
the lookup in the NodePath creation code: when _nodePathCache.TryGetValue(from,
out var cachedWeak) returns true but cachedWeak.TryGetTarget(out _) returns
false, remove the stale entry (e.g., _nodePathCache.TryRemove(from, out _))
before creating a new NodePath, and then add the new
nodePath._weakReferenceToSelf via _nodePathCache.TryAdd(from,
nodePath._weakReferenceToSelf); update the code paths that reference
TryGetValue, TryGetTarget, TryRemove/TryAdd, and _weakReferenceToSelf
accordingly to ensure thread-safe replacement of dead weak refs.

In `@modules/mono/glue/GodotSharp/GodotSharp/Core/StringName.cs`:
- Around line 118-134: The cache path in StringName.Create (where
_stringNameCache.TryGetValue is used) leaves dead WeakReference entries in
_stringNameCache when cachedStringNameWeakReference.TryGetTarget returns false;
before creating and TryAdd'ing the new StringName(from) instance, remove the
stale entry from _stringNameCache (e.g., call _stringNameCache.TryRemove(from,
out _)) so the subsequent TryAdd using stringName._weakReferenceToSelf can
succeed; ensure this change touches the block around
_stringNameCache.TryGetValue, TryGetTarget, the creation of new StringName, and
the TryAdd call.

Copy link
Contributor

@Arctis-Fireblight Arctis-Fireblight left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for your work on this!
I have gone ahead and marked this as approved for merge.

I'll be cutting our 26.1-stable this week, and this will be merged shortly afterwards for inclusion in 26.2.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants