-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Silently ignore removal of nonexistent style layer or source #7962
Silently ignore removal of nonexistent style layer or source #7962
Conversation
@eimantas, thanks for your PR! By analyzing this pull request, we identified @jfirebaugh, @1ec5 and @incanus to be potential reviewers. |
src/mbgl/map/map.cpp
Outdated
impl->onUpdate(Update::Classes); | ||
return removedLayer; | ||
} catch (const std::runtime_error& err) { | ||
impl->styleMutated = false; |
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.
I believe this is incorrect. It always sets to false, even when the style was mutated before the call to remove a layer.
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.
Should I remove this statement? Since a couple of lines above there's impl->styleMutated = true;
assuming the layer will be removed. And since this is in a catch
block - the layer is not removed and the style is not mutated.
@eimantas Thank you for your contribution! Are you able to make the changes? |
@kkaefer - change implemented. |
Since this is "Core GL" fix, should I also add the entry to the Android SDK changelog? |
@eimantas The fix is to not mark the style as mutated until the change was completed successfully, so that a failure to remove still leaves the style in unmutated state |
Please see the change now. |
Noting that this addresses #7900 |
Would this change officially sanction a pattern of removing potentially nonexistent layers? That’s reasonable, but then why issue a warning? The developer might want to remove layers indiscriminately without spewing onto the console. On the other hand, if we still consider the removal of a nonexistent layer to be programmer error, we should continue to throw an assertion. However, |
So that a developer can fix his code the check whether the layer exists before removing it. However if you decide to transfer this into Cocoa/Android land with |
Sure, that's an intended use of There should be negligible performance impact to always checking for the existence of a layer before removing it. On the other hand, there should also be negligible performance impact to attempting to remove a nonexistent layer. So if that's the only programming mistake we're trying to head off with the warning, I'd lean towards silencing the warning. What do others here think? |
I think we should change the removal method in core and in SDK bindings to return a null pointer and not log any message. |
If everyone is fine with silently ignoring the removal of nonexistent layer, I can implement these changes. |
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.
Rather than throwing an exception which is caught by Map::removeLayer
, Style::removeLayer
itself should return nullptr
.
Updates are done. |
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.
Can you update the CHANGELOG entries now that it doesn't log a warning?
@ivovandongen Do you want to change the Android bindings to follow this behavior (no error, return null)?
@jfirebaugh Sure, but don't we want to make this consistent for sources than as well? Eg here |
On iOS/macOS, MGLBackgroundStyleLayer *fillLayer = [[MGLBackgroundStyleLayer alloc] initWithIdentifier:@"bg"];
[style removeLayer:fillLayer]; // no-op
// …
[style addLayer:fillLayer]; // MGLRedundantLayerException I think the correct behavior would be to ensure that /cc @boundsj |
I agree. Instead of setting this variable and property to I think we should do this in between the two early returns, resetting I can create an issue for this and make a separate PR. |
@jfirebaugh @kkaefer can this change be merged now? Once this core change lands and the behavior is changed, I'd like to add Darwin platform tests for the change in #8055. |
Yes, we should. The Android bindings also need to be adjusted (e.g. here), to either test for a nullptr result (if we want to keep the existing behavior), or to pass on a null pointer. |
In case of exception, silently ignore removal of nonexistent layer and return nullptr
This reverts a previous change that recreated the pending and raw layer pointers if an identifier match caused a layer to be removed but the removed layer was of a different type than the layer triggering the removal This refactors the pointer replacement to use a simpler solution that returns early if the layer does not have a raw pointer loaded in the mbgl map instance.
This refactors the source removal methods to make them consistent with the way layers are removed. This makes removal of nonexistent sources and removal of sources of a different type but same identifier as a previously added source a no-ops. As with layers, the check at the top of the method to ensure that the raw pointer is the same as the one in mbgl for the same identifier string should make it impossible to attempt to remove a source of a different type than the one in mbgl for the same identifier. However, for consistency with the layer implementation, the reinterpret_cast has been replaced with a dynamic_cast and check for nullptr.
@jfirebaugh @kkaefer @1ec5: @ivovandongen and I made the change to make nonexistent source and layer removal consistent and updated the platform implementations (including taking care of #8053). I think this is ready for re-review. |
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.
Darwin/iOS/macOS changes look good.
In case of exception:
nullptr
;