-
Notifications
You must be signed in to change notification settings - Fork 1.3k
[core] Replace mbgl::MapChange with mbgl::MapObserver #8377
Conversation
@brunoabinader, thanks for your PR! By analyzing this pull request, we identified @1ec5, @tmpsantos and @friedbunny to be potential reviewers. |
b3a3780
to
de9c074
Compare
include/mbgl/map/map_observer.hpp
Outdated
return mapObserver; | ||
} | ||
|
||
virtual void onRegionWillChange() {} |
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.
Suggest s/Region/Camera/g
.
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.
Ack. For now I'm abstaining from renaming the public APIs for Qt & Android. For iOS & macOS I'm adding entries to CHANGELOG.md
about the renaming.
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.
Renaming the public API for iOS and macOS would be a backwards-incompatible change that would require a major version bump. Fortunately, this PR doesn’t touch the public API (MGLMapView.h) at all, only the internal implementation of MGLMapView (MGLMapView.mm), so no changelog entry is required.
include/mbgl/map/map_observer.hpp
Outdated
} | ||
|
||
virtual void onRegionWillChange() {} | ||
virtual void onRegionWillChangeAnimated() {} |
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.
Would it make sense to provide a boolean (or two-valued-enum) parameter to on*Change
, rather than having separate on*Change
and on*ChangeAnimated
methods? Similarly with on*Rendering{Frame,Map}
/on*Rendering{Frame,Map}FullyRendered
.
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 think so - I'm adding two enums to MapObserver
: CameraChangeMode
and RenderMode
.
include/mbgl/map/map_observer.hpp
Outdated
virtual void onWillStartRenderingFrame() {} | ||
virtual void onDidFinishRenderingFrame() {} | ||
virtual void onDidFinishRenderingFrameFullyRendered() {} | ||
virtual void onWillStartRenderingMap() {} |
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.
Is there a useful difference between on*RenderingFrame
and on*RenderingMap
?
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.
onWillStartRenderingMap()
and onDidFinishRenderingMap()
are based on MapKit’s -[MKMapViewDelegate mapViewWillStartRenderingMap:]
(“when one or more tiles are revealed and require rendering”) and -[MKMapViewDelegate mapViewDidFinishRenderingMap:fullyRendered:]
(“finishes rendering all of the currently visible tiles to the best of its ability”), which have analogues in our iOS and macOS SDKs.
If our iOS documentation is to be believed, on*RenderingFrame()
would be called on each frame of a camera animation or property transition, even where no additional tiles need to be fetched and displayed. However, I don’t know for sure if that’s how we’ve implemented these notifications, given #2775.
/cc @friedbunny
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.
In terms of usefulness, we’ve found the “rendering frame” notifications to be useful in situations where the developer wants to synchronize a view atop the map or override some annotation view behavior that we apply on every frame. But the “rendering map” notifications remain more generally useful for knowing when it’s safe to snapshot a map view or have the UI change once the map is quiescent.
platform/ios/src/MGLMapView.mm
Outdated
- (void)notifyMapChange:(mbgl::MapChange)change | ||
{ | ||
// Ignore map updates when the Map object isn't set. | ||
- (void)onRegionWillChange:(bool)animated { |
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.
In Objective-C, use BOOL
(YES
/NO
) instead of bool
(true
/false
).
platform/ios/src/MGLMapView.mm
Outdated
- (void)notifyMapChange:(mbgl::MapChange)change | ||
{ | ||
// Ignore map updates when the Map object isn't set. | ||
- (void)onRegionWillChange:(bool)animated { |
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.
Remove “on” from the names of this method and others like it. Also, ensure that there’s a word before the parameter that describes the parameter, so that the meaning of the YES
or NO
is apparent at the call site: -regionWillChangeAnimated:
.
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.
-cameraWillChangeAnimated:
would also be acceptable.
The macOS SDK implementation of MGLMapViewDelegate already uses the term “camera” instead of “region”. The iOS SDK implementation blindly copied MapKit’s use of “region” without bringing over MapKit’s MKRegion
struct.
We’ll want to fix the public interface when we’re ready for backwards-incompatible changes, but for now, either name works for this internal method.
platform/ios/src/MGLMapView.mm
Outdated
break; | ||
} | ||
case mbgl::MapChangeSourceDidChange: | ||
- (void)onRegionIsChanging { |
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.
-regionIsChanging:
platform/ios/src/MGLMapView.mm
Outdated
} | ||
} | ||
|
||
- (void)onRegionDidChange:(bool)animated { |
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.
-regionDidChangeAnimated:
platform/ios/src/MGLMapView.mm
Outdated
} | ||
} | ||
|
||
- (void)onWillStartLoadingMap { |
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.
-mapViewWillStartLoadingMap
platform/ios/src/MGLMapView.mm
Outdated
} | ||
} | ||
|
||
- (void)onDidFinishRenderingMap:(bool)fullyRendered { |
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.
-mapViewDidFinishRenderingMapFullyRendered:
platform/ios/src/MGLMapView.mm
Outdated
} | ||
} | ||
|
||
- (void)onDidFinishLoadingStyle { |
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.
-mapViewDidFinishLoadingStyle
platform/ios/src/MGLMapView.mm
Outdated
} | ||
} | ||
|
||
- (void)onSourceDidChange { |
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.
iOS doesn’t need to do anything in response to source changes, since attribution is displayed on-demand. You can safely remove this method and make its caller a no-op.
platform/macos/src/MGLMapView.mm
Outdated
} | ||
} | ||
|
||
- (void)onSourceDidChange { |
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.
Pass in the mbgl::style::Source
and rename this method to -sourceDidChange:
.
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.
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.
→ #8397
} | ||
|
||
void Map::Impl::onStyleError() { | ||
backend.notifyMapChange(MapChangeDidFailLoadingMap); | ||
observer.onDidFailLoadingMap(); |
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.
We should plumb res.error
through to here or implement onResourceError()
instead to allow the SDKs to provide more information about the failure. Currently, in order to fudge parity with MapKit, the iOS and macOS SDKs have to synthesize an uninformative NSError, but res.error
’s message
field would be perfect for this purpose.
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.
Same as above, I'd prefer if we could move this to a platform-specific refactor.
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.
This suggestion isn’t platform-specific but rather an improvement on the code being added in this PR. Tracking in #8398.
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 see - thanks for the clarification. Let's handle this in #8398 👍
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.
Android side of things is 👍 , ticketed follow up ticket to migrate the android code base to this system in #8389.
de9c074
to
81b0a2b
Compare
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.
platform/ios/src/MGLMapView.mm
Outdated
@@ -1167,7 +1167,8 @@ - (void)touchesBegan:(__unused NS_SET_OF(UITouch *) *)touches withEvent:(__unuse | |||
} | |||
|
|||
- (void)notifyGestureDidBegin { | |||
[self notifyMapChange:mbgl::MapChangeRegionWillChange]; | |||
bool animated = 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.
s/bool/BOOL/ and s/false/NO/ (×2)
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'm a bit confused - I've seen bool
usage when the code is a glue between C++ and Objective-C, and BOOL
on Objective-C code along this source file - should we open an issue then to fix this for all remaining bool
s?
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.
Ok, I think I got it now - this function is not part of the C++ glue and thus should use the Objective-C notation - got it :) Fixing now.
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.
👍 As a rule of thumb, in Objective-C++ code, if you’re inside an Objective-C class or category (look for @implementation
and @end
), use Objective-C types; if you’re inside a C++ class
or struct
, use C++ types. There are some exceptions: for example, I find it useful to use static_cast
over C-style casts throughout Objective-C++ code. And std::vector
can often be faster than NSMutableArray. This article suggests some more ways C++ can improve Objective-C code, but a lot of it is a matter of preference.
81b0a2b
to
71eee82
Compare
71eee82
to
ff2be9f
Compare
Qt public API refactor handled in #8419. |
Implements
mbgl::MapObserver
, replacingmbgl::MapChange
enumerator andmbgl::Backend::notifyMapChange
. Nowmbgl::Backend
inherits frommbgl::MapObserver
, which provides non-pure virtual equivalents for the enumerator items.Caveats:
QMapboxGL::MapChange
enumerator from the public API.mbgl::MapChange
- this is not necessary but finishing up this platform refactor can happen on a separate PR. Once we finish cleaning up the Android platform, then we can safely removembgl::MapChange
source code entirely.Added suggested reviewers for platform-specific patches as well as core changes - please replace yourself with someone else from the mobile team otherwise.
Fixes #6383.