-
-
Notifications
You must be signed in to change notification settings - Fork 211
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
save
and try_save
functions and IO-utilites refactor in godot_core::engine refactor
#535
Conversation
API docs are being generated and will be shortly available at: https://godot-rust.github.io/docs/gdext/pr-535 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks! 🙂
In general, I'd appreciate separation of refactorings and business logic changes/additions, at least on a per-commit basis. Otherwise it's very hard to see what has changed -- especially now where a lot of content is moved across files.
If you do change anything during a refactor (e.g. improve docs), please highlight it with comments. It's impossible for me to see diffs across different files that are not recognized by Git, at least without going through significant effort.
As mentioned in #473 (review), the NotUniqueError
might see some use outside I/O contexts, so I wonder if we should rather move it somewhere else, maybe godot::obj
or so? We do have godot::builtin::meta::ConvertError
already elsewhere, but that's not really fitting for a Gd
specific error.
My main question would be about
GdIoError
- thematically it seems fitting to gather all errors stemming fromtry_load
,try_save
andGFile::try_from_unique
under one enum (as in this draft). Functionally I have some doubts, as it could be limiting if we would like in future to extend the errors:GdIoError::ResourceSave
would be a prime candidate, as we could potentially try to match Godot'sError
to help user distinguish between the cases without requiring them to match it themselves.On the other hand I don't know if introducing three new error types regarding each of these functionalities:
GdLoadError
,GdSaveError
andGFileError
wouldn't be considered a bloat.
For previously introduced error types (#467), we followed an approach of not providing too much detailed API. Such an enum can make sense internally, but if you make it public, there are some caveats:
- It needs to be
#[non_exhaustive]
for forward compatibility, which limits matching. - It adds a lot of API surface for a niche use case.
GFile
and save/load are important parts, but they are a handful of symbols -- while the error API would likely add twice as much symbols, just for handling errors. - Game developers are typically more interested in the fact that there is an error, rather than knowing all the inner details.
I would thus only provide a surface-level error type, implementing the std::error::Error
trait but not offering specific insights. We can expose those when there is concrete demand.
Will do! Then the creation of
Ok, in that case a generic |
I think it's enough to have 2 commits:
|
39dd9fb
to
7b79b58
Compare
I've added |
It's fine. Also, consider my previous statement:
Do we really need By implementing the |
Per rename to
Public
I think that noone would need to do a non-exhaustive I can revert implementing |
Good call, yes you can remove that. You could include
Yes, please do. I generally think |
The problem is that the current API is misleading. pub enum ErrorKind {
ResourceCantLoad,
ResourceCantCast,
ResourceCantSave,
FileAccessNotOpen,
FileAccessNotUnique,
Custom,
} This enum is the union of all possible error types, but each operation can only expose some of the errors. Let's look at I don't want you to answer these questions, but my point is: these are not just questions I ask myself when not knowing the implementation, but questions that every user asks. So you end up with:
I'm not convinced this is what users want. In practice, the only thing that's typically relevant is to differentiate logic errors (bugs that must be fixed) from runtime errors (file not found). Sometimes they overlap, e.g. if the file is provided by the developer themselves. But throwing all the possible error types at the user is not necessarily a great abstraction. As mentioned, we had this exact discussion for the I'm not generally opposed to having this discussion, but there are 2 main principles I try to follow:
Sorry for insisting on bureaucracy here, but it's important to me that we build APIs with a good, consistent user experience 🙂 |
If you are interested in discussing how to model error APIs, we can gladly take it to a separate issue. There are also a few other APIs that might need consideration:
I'm still not sure what the best approach would be -- domain-specific We can discuss this in #536. |
I would suggest we do not wait until the error discussion is resolved, this can take months. For now I would make the error API absolutely minimal (no overlaps as above), then I can merge a first version. We can then individually look at the different cases in future PRs. Sounds good? |
@Bromeon Yeah, I think it will be for the best - will just keep the Additionally: By default, the I was wondering if we should change the If someone is just updating the resource and saving it back, they could get its |
7b79b58
to
4e2e331
Compare
If we only go for public
even make sense? They are basically a "flat" representation of an enum, which seems strictly worse: the user needs to understand which properties are set under which circumstances, but there is no type-level support (enum) to indicate this. Maybe better to just keep the enum with the strongest type representation internally, and expose just There are also some merge conflicts. |
16ad31b
to
972045e
Compare
@Bromeon Should be good to go. Underlying
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the update! There are currently merge conflicts, but it looks mostly good 🙂
972045e
to
736698c
Compare
736698c
to
b118232
Compare
Thanks a lot! Error APIs will definitely still evolve, anyone interested can participate in #536 🙂 |
Initially addressing only #532, but after checking out TODOs and general structure some more proposed changes requiring opinions from maintainers:
godot_core::engine::io
module, containing all utility functions and structs regarding general I-O: loading, saving and file read/write,try_load
returningResult
instead ofOption
, allowing for distinguishing between load failure and casting failure (for the second possible recover, as theGd<Resource>
is encapsulated,GFile::try_from_unique
returningError
if built fromGd<FileAccess>
not in open state.My main question would be about
GdIoError
- thematically it seems fitting to gather all errors stemming fromtry_load
,try_save
andGFile::try_from_unique
under one enum (as in this draft). Functionally I have some doubts, as it could be limiting if we would like in future to extend the errors:GdIoError::ResourceSave
would be a prime candidate, as we could potentially try to match Godot'sError
to help user distinguish between the cases without requiring them to match it themselves.On the other hand I don't know if introducing three new error types regarding each of these functionalities:
GdLoadError
,GdSaveError
andGFileError
wouldn't be considered a bloat.Additionally, the currently used
IoResult
inGFile
operations could be also put intoGdIoError
/GFileError
, passing additional information about underlying Godot'sError
.