-
-
Notifications
You must be signed in to change notification settings - Fork 200
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
OnReady<T>
for late-init fields
#534
Conversation
API docs are being generated and will be shortly available at: https://godot-rust.github.io/docs/gdext/pr-534 |
Alternative designs
|
Merging this for now, allowing for early feedback and follow-up improvements in separate PRs. |
OnReady
: Ergonomic late-initialization container withready()
supportWhile deferred initialization is generally seen as bad practice, it is often inevitable in game development. Godot in particular encourages initialization inside
ready()
, e.g. to access the scene tree after a node is inserted into it. The alternative to using this pattern isOption<T>
, which needs to be explicitly unwrapped withunwrap()
orexpect()
each time, and can be accidentally overridden.OnReady<T>
should always be used as a field. There are two modes to use it:new()
.Before
ready()
is called, allOnReady
fields constructed withnew()
are automatically initialized, in the order ofdeclaration. This means that you can safely access them in
ready()
.manual()
.These fields are left uninitialized until you call
init()
on them. This is useful if you need more complexinitialization scenarios than a closure allows. If you forget initialization, a panic will occur on first access.
Conceptually,
OnReady<T>
is very close to once_cell'sLazy<T>
, with additional hooks into the Godot lifecycle.The absence of methods to check initialization state is deliberate: you don't need them if you follow the above two patterns.
This container is not designed as a general late-initialization solution, but tailored to the
ready()
semantics of Godot.This type is not thread-safe.
ready()
runs on the main thread and you are expected to access its value on the main thread, as well.Example