[core] Immutable style Impls#8929
Conversation
| == std::tie(rhs->id, lhs->type); | ||
| }; | ||
|
|
||
| longest_common_subsequence(a.begin(), a.end(), b.begin(), b.end(), std::back_inserter(lcs), eq); |
There was a problem hiding this comment.
This LCS implementation is the unrefined O(ND) space algorithm from the classic paper. I'm not sure if we need a full LCS, versus a more basic unordered set difference -- it probably depends if we want to implement a "move layer" operation rather than the current "remove and re-add" implementation (see mapbox/mapbox-gl-js#4142).
If we do end up keeping LCS, we should probably implement the O(N) space refinement presented in the paper. I haven't yet invested the time to understand it or write a high-quality implementation.
|
Starting to look good! One thing I'm wondering about is wether we should add the option to mutate multiple properties at once (in layers for example) to avoid unnecessary copies of the implementations. |
|
|
||
| float dist = length(v_pos - gl_FragCoord.xy); | ||
| float alpha = smoothstep(1.0, 0.0, dist); | ||
| float alpha = 1.0 - smoothstep(0.0, 1.0, dist); |
There was a problem hiding this comment.
Did these snuck in by accident?
a696800 to
bac2476
Compare
|
This is ready for review. I checked for conflicts with #8937; they are minimal (added a header file in the same place). |
There was a problem hiding this comment.
zoomChanged is missing here, and none of our regression tests caught it. Will investigate.
ivovandongen
left a comment
There was a problem hiding this comment.
Looks good!
- Ran the Android integration tests as well, no regressions. Although the run time (locally) increased from ~5:30min to ~8:00min. No immediately obvious cause for this, it is spread fairly evenly over the style tests.
- Ran through all the Android test app activities manually, no regressions I could spot.
| // Private implementation | ||
| const std::unique_ptr<Impl> baseImpl; | ||
| class Impl; | ||
| Immutable<Impl> baseImpl; |
There was a problem hiding this comment.
I realize this has been public before, but is there a way we can make it private now?
There was a problem hiding this comment.
Style at a minimum would need to be friended. GeometryTile also uses it; it's possible that use could be eliminated. I'd like to leave this for a followup change though.
|
|
||
| <% } -%> | ||
| // Visibility | ||
| void setVisibility(VisibilityType) final; |
There was a problem hiding this comment.
Nit: Can we add override to be consistent with the rest of the codebase?
There was a problem hiding this comment.
You want to write override final or final override? Neither of those appear elsewhere in the codebase.
There was a problem hiding this comment.
I'm specifically interested in override (final override reads better), to make it fully clear that this is a virtual function override.
There was a problem hiding this comment.
Let's discuss making that style change separately. We already have quite a few uses of final without override.
| <%- camelize(type) %>Layer(const <%- camelize(type) %>Layer&) = delete; | ||
| Mutable<Impl> mutableImpl() const; | ||
| <%- camelize(type) %>Layer(Immutable<Impl>); | ||
| std::unique_ptr<Layer> cloneRef(const std::string& id) const final; |
There was a problem hiding this comment.
Same note about privatization here. I know they've been public before, so this may be a follow-up change.
| } | ||
|
|
||
| LayerType getType() const; | ||
| const std::string& getID() const; |
There was a problem hiding this comment.
This returns a reference to a string, which is stored in the immutable implementation. Now that we're switching this frequently, it means that the reference can become invalid when you do something like this:
auto& id = layer->getID();
layer->setMaxZoom(2);
std::cout << id;Instead of returning a reference to objects inside the frequently-changing Immutable, we should return the ID as a value.
|
|
||
| template <class S> friend class Immutable; | ||
| template <class S, class... Args> friend Mutable<S> makeMutable(Args&&...); | ||
| }; |
There was a problem hiding this comment.
Mutable/Immutable is vulnerable to the following scenario: Contained type inherits from std::enable_shared_from_this. It's now possible to obtain a shared_ptr from the Mutable object, convert that to an Immutable, and continue to mutate the object with the previously obtained shared_ptr handle. The same goes for EnableImmutableFromThis. It seems like a promise that it can't keep...
There was a problem hiding this comment.
Well, sure. But you could also just hold onto the raw pointer from Mutable::get(), a reference from Mutable::operator*, const_cast, .... There's no way to 100% prevent misuse in C++; that would require language support in the style of Rust borrow checking.
There was a problem hiding this comment.
Yup, but shared_ptr indicates shared ownership, whereas the others don't.
| * Members that are private in `FooLayer::Impl` are internal to "foo" layers. | ||
| */ | ||
| class Layer::Impl { | ||
| class Layer::Impl : public EnableImmutableFromThis<Layer::Impl> { |
There was a problem hiding this comment.
This allows converting an existing object to an Immutable, but this object has many mutable fields that cut be mutated from the original handle.
There was a problem hiding this comment.
EnableImmutableFromThis is required only for Source::Impl::createRenderSource and Layer::Impl::createRenderLayer. It's probably a good idea to change how those operations are performed so that EnableImmutableFromThis isn't necessary. I see two options:
- Require passing an
Immutable<Impl>self reference to those methods (3e7ce6ba27b31a73a9242e4e14e8eaacefe42a5e). I'm not crazy about this because it allows the possibility of passing some other reference that doesn't matchthis. - Replace the virtual dispatch with a static dispatch -- switch statement or
Layer::accept.
| return longest_common_subsequence(a, endA, b, endB, outIt, std::equal_to<>()); | ||
| } | ||
|
|
||
| } |
There was a problem hiding this comment.
This file could use a lot more documentation
3db6ac8 to
38d1677
Compare
|
Bizarre link error on linux builds: Seems totally unrelated to any of the changes in cebc5f11cd834a6cf478b267df5f436ab5fd7362. |
Avoid dangling references in the following sequence:
auto& id = layer->getID();
layer->setMaxZoom(2);
std::cout << id;
The reference would be dangling because mutating the layer allocates a new Immutable impl, and there may be no references to the prior impl, which held the id.
…create
* Eliminates the need for EnableImmutableFromThis
* Eliminates the dependency of {Source,Layer}::Impl on corresponding Render class (circular dependency)
9fffcd3 to
e859904
Compare
Implements immutability for:
Light::ImplSource::Impland subclassesLayer::Impland subclassesRefs #8820