Use flexible object selectors in update and replace operations #2164
Labels
topic: core
Issues relating to core geometry, operations, algorithms
type: feature
New features and improvements to existing features
Current Situation
Currently, many of the methods that are part of update and replace operations act on specifically one object, identified by a
Handle
. How specifically they do that is a bit inconsistent: Some accept an argument for the updated/replaced object, others accept a closure that returns the updated/replaced object.Here are examples of that:
This approach is not very flexible, which leads to some cumbersome code. The inconsistency is also not great. A consistent design should be found, and followed where applicable.
It's possible to use methods of
ObjectSet
to acquire the handle of an object that is not yet known to the caller. Those are designed to be used in conjunction with methods like the ones presented above, for example to select the only object in a set (e.g.cycle.update_half_edge(cycle.half_edges().only(), ...)
), or select an object based on its index (e.g.cycle.update_half_edge(cycle.half_edges().nth(2), ...)
).This approach leads to a minor problem, where code isn't as compact as it could be, because the object needs to be kept in a variable to be used multiple times. For example:
Concept
Selection can be made more flexible, by accepting a selector argument that can select a specific object, or one or more objects based on query properties encoded into the selector. All applicable methods need to accept closures that return the updated/replaced object, as a closure can be called one or more times, depending on the selector.
Selector
We can define a
trait Selector
, which can then be accepted by all applicable methods asselector: impl Selector<SomeObject>
.Selector
would be implemented for multiple types:Handle<T>
, to select one specific object.Select
, and enum with variants for straight-forward selections. See below.I'm not totally clear on what the actual interface of
Selector
would be, but for a start, we should keep it simple. Maybe something likefn select(object_set: &ObjectSet) -> impl Iterator<&Handle>;
, roughly.Select
In addition to paving the way for more complex selectors, as described above, this issue would also include a simplification of the current system in the form of a
Select
enum.Select
would be used to replace the aforementionedObjectSet
methods, for example likeSelect::Only
orSelect::Nth(2)
.This would have the advantage of not requiring access to the object, allowing some minor simplifications. The example above could be written as this:
Next Steps
I believe this is pretty much ready for implementation (but of course, that implementation might provide some surprising problems and insights that could change the design). I don't have firm plans to work on this, so somebody could pick this up, if they wanted. Otherwise, I might do this in between other tasks at some point, as I don't believe it's that big of a job.
The text was updated successfully, but these errors were encountered: