Skip to content

Cache singleton pointers #1577

@Bromeon

Description

@Bromeon

GDExtension API to fetch singletons

There is an FFI function to fetch a singleton:

typedef GDExtensionObjectPtr (*GDExtensionInterfaceGlobalGetSingleton)(GDExtensionConstStringNamePtr p_name);

Notably, this returns null if the singleton is not yet initialized (before a certain init stage).
What we need to test is whether it also returns null after a certain deinit stage.


Caching

Fetching these pointers via FFI + Godot lookup every time a singleton API is called shouldn't be necessary. Thoughts:

  • One way is to cache by singleton name / class ID / type ID, in a Rust-side global HashMap.
  • As singletons tend to be accessed from multiple threads, we'd need a locking strategy.
  • We can optimize this, so that during "fully initialized" (after MainLoop init), we assume the hashmap doesn't change. It would need an AtomicBool (for the "fully initialized" flag accessed from different threads), after that a raw hashmap access. Or a Mutex if that's faster.
  • We'd also need to see what key to use. GodotClass::class_id() retrieves the ID from a static OnceLock<ClassId> which should be pretty fast. It's a bit a shame that there's no good compile time solution (const_type_id is nightly, and even crates emulating it will need the hash computation).
  • Blazingly fast would be to do it directly via trait, not needing hashmaps at all. Since all singletons are statically known via Singleton trait, we can override the singleton() method (or add another one) to store a static OnceLock<Something<Gd<T>>>. We'd somehow need to get the thread safety sorted, and make sure to have an extra check whether the singletons is initialized (already + still).
  • I would not cache any dynamic singletons registered via Engine::register_singleton, or registered in GDScript.

Metadata

Metadata

Assignees

No one assigned

    Labels

    c: engineGodot classes (nodes, resources, ...)performancePerformance problems and optimizations

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions