Skip to content
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 Root::push() and Index::push() to assist with glTF construction. #404

Merged
merged 2 commits into from
Dec 29, 2023

Conversation

kpreid
Copy link
Contributor

@kpreid kpreid commented Dec 18, 2023

These methods reduce the amount of boilerplate and possible mistakes involved in constructing a glTF asset from scratch.

Most use cases are served by Root::push(); Index::push() is useful for cases like animation samplers where the vector of objects is not in the Root, or in algorithmically complex situations such as pushing both within and outside closures, which would produce borrow conflicts if &mut Root was required for everything.

This requires some expansion of the Get trait to support writing. By keeping the old Get::get(), this is not a breaking change unless some dependent implements Get, but if we choose to make general breaking changes, it would probably make sense to rename the trait, and perhaps even declare it an implementation detail, seal it, and hide its methods. (This PR no longer modifies Get and instead adds AsMut<Vec<T>> implementations.)

This is based on a helper function I wrote and used extensively in my own code, and I've also verified that these methods work well in the same situations.

@alteous
Copy link
Member

alteous commented Dec 20, 2023

In spirit, I like it. I must admit I have written similar functions. I'm hesitant on the naming/repurposing of Get though.

Do you think we even need the Get trait with this your change anymore? Perhaps AsRef<[T]>/AsMut<Vec<T>> would serve the same purpose?

@kpreid
Copy link
Contributor Author

kpreid commented Dec 20, 2023

I'm hesitant on the naming/repurposing of Get though.

Indeed, that's the part of this change I'm most unsure about.

Do you think we even need the Get trait with this your change anymore? Perhaps AsRef<[T]>/AsMut<Vec<T>> would serve the same purpose?

That seems like a reasonable approach, and I like it a little better than the two methods read_by_type() / write_by_type() I made up on the spot. I'm generally a little skeptical of making use of very general traits to provide rather application-specific semantics, because there in future cases there might be semantic conflict between what the trait means in general and how it has to be implemented to provide this feature, that even if not really breaking might mean the type can be used generically in a nonsensical way, but I can't think of a reason why this particular case would be risky. And an upside would be that this PR could then be purely additive / non-breaking, since Get could be left exactly as-is.

Would you like me to rewrite this PR in terms of AsRef + AsMut?

@alteous
Copy link
Member

alteous commented Dec 24, 2023

Yeah I think we should try AsRef and AsMut.

These methods reduce the amount of boilerplate and possible mistakes
involved in constructing a glTF asset from scratch.

Most use cases are served by `Root::push()`; `Index::push()` is useful
for cases like animation samplers where the vector of objects is not in
the `Root`, or in algorithmically complex situations such as pushing
both within and outside closures, which would produce borrow conflicts
if `&mut Root` was required for everything.

This introduces a new paradigm for child object access: implementing
`AsMut<Vec<T>>`. This could also replace the `Get` trait's function via
`AsRef<[T]>` implementations, but that would be a breaking change, so if
that is to be done, let's do it separately. This commit includes those
`AsRef` implementations, though, since they're harmless and parallel to
the `AsMut` implementations.
This way, all `Index`es are guaranteed valid and the dependencies
between the glTF objects are reflected in the program's variables.

I have manually tested that the output of the example is valid glTF.
@kpreid
Copy link
Contributor Author

kpreid commented Dec 24, 2023

Yeah I think we should try AsRef and AsMut.

Done. It turned out that this could be a totally non-breaking change, leaving Get alone, so I did that, but I still have the code for replacing Get, so it can become a separate refactor/API-change PR later.

@alteous
Copy link
Member

alteous commented Dec 29, 2023

Thanks! 😄

@alteous alteous merged commit d5b04fc into gltf-rs:main Dec 29, 2023
1 check passed
@kpreid kpreid deleted the push branch December 31, 2023 23:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants