-
Notifications
You must be signed in to change notification settings - Fork 43
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
Add small chapter for registering ResourceFormatLoaders/Savers. #65
base: master
Are you sure you want to change the base?
Conversation
Thanks a lot for this nice addition, and sorry for the late review! I cleaned up some parts, some feedback for next time:
I think it's mostly OK, but I'd still split at least the different classes and give a short introductory text to each. So you'd have 4 code blocks:
They could still be copy-pasted individually, but then it's not a massive wall of code hitting the reader. Some comments about the code and contents: 1. Unregistering singletonpub fn unregister_input_output() {
Engine::singleton().unregister_singleton("AssetSingleton");
} This is still a memory leak. You unregister the singleton but don't free the instance. See Singleton chapter... You also mention
Are you sure that's true? Godot will hint at some leaks as a best-effort, but I'm not sure if it's guaranteed. And it's borderline "bad practice" so I would not even suggest that, as it encourages not cleaning up properly. 2. Resource detection// The stringified name of your resource should be returned.
fn get_resource_type(&self, path: GString) -> GString {
// This is a slight hack to check if the file has the right extension.
// You can change this to your heart's content.
if path.to_string().ends_with(".myextension") {
"MyResourceType".into()
} else {
// In case of not handling the given resource, it must return an empty string.
GString::new()
}
} Can you elaborate why this is a hack and how one would do it properly? Thanks for mentioning the empty string behavior, that's very helpful 👍 3. Saving and loading logic
I would rather mention It would also be nice if the tutorial/page about saving loading would quickly touch on the semantics of the fn save(
&mut self,
resource: Option<Gd<Resource>>,
path: GString,
flags: u32,
) -> godot::global::Error
fn load(
&self,
path: GString,
original_path: GString,
use_sub_threads: bool,
cache_mode: i32,
) -> Variant ...I have some questions as a reader:
After filling in those gaps, it would be a very comprehensible page! Let me know if you need help completing these parts. Thanks a lot! |
Co-authored-by: Jan Haller <[email protected]>
Thanks for the review and the suggenstions/feedback! No problem that it took so long i understand its just not a big priority ;) Ye fair points was originally intended as a draft as i was certain that some things needed improvement since your very thourough from what i've seen ^^ (good thing imo). Splitting the blocks up is so obvious and i completly agree havent thought of that possibility. will do 1. Unregistering singletonYour right i completly forgot that Singletons are manually managed. will fix I was contemplating myself whether to include the last statement regarding the necessity when i wrote it. Now i think we should delete it since if your looking for a guide it should be a bit opinionated and following good/the best practices. If you really want to you can f around yourself and find out eventually that its not necessary. But as written it doesnt add any value. From the angle of are you sure if this is true? No. I actually arent 🥴 i'm certain that the operating system will clean up and it is worded misleading and badly on my side mb. Was writing it because i thought its easier to grasp but ... well that doesnt help anybody. In turn it could be worded with something along the lines of: The downside of this approach is that the destructor does not run which entails that if you depend on the destructor it is possible to have bad side effects if not the operating system will take care of reclaiming the memory. 2. Resource detectionRight i failed again to do proper reasoning lol. String el = p_path.get_extension().to_lower();
if (el == "gd" || el == "gdc") {
return "GDScript";
} I didnt use this feature because it was not available at the time of writing but you added the methods recently sooo it's not necessary anymore and we can just mirror godot with 3. Saving and loading logicI actually wasn't familiar with the GFile class probably glossed over it woops. The signatures are indeed a bit confusing but i thought because they are virtual methods a user would just look up the godot docs but maybe we just copy the documentation above since the Godot docs also just offer the bare minimum.
Consider the following information your fault since you made me look: If this gets a special case anyway because of the SaverFlags mentioned above and it's trivial to implement you could consider changing this to a Result.
I've sadly run out of time for this one ^^ I've written more for this today than for my bachelors thesis xD maybe im sneaking the investigation in there haha. Thanks for your continuus effort and a great evening! |
As promised the little overhaul :) I actually did some more reaserch as well as a little bug adventure since the Saver was actually not working as intended. On the topic of special casing those functions/classes it would probably also be good if you special case to remove the Would be great if you could apply your last bit of feedback if any and squash the commits for me if its not too much to ask ^^ Have a great evening! |
Hey as I said on discord the small "guide" for the ResourceFormatLoader and Savers.
I've taken a slightly different approach on the writing style and instead tried to provide a pretty all boilerplate included example which you can easily copy and paste to just get it working in your projects.
If this is not desired and a more tutorial like approch is preffered i can also rewrite it in that style.
I also wasnt entirly sure because this is by no means the most minial example because in theory you can just directly register the Saver/Loader in the gdextension trait impl but idk feels wrong since you "leak" on exit.
Lemme know any formulation or clarity problems :)
You can also freely edit it to your desire if you want to.
Thanks in advance :>