Skip to content
This repository has been archived by the owner on Aug 8, 2023. It is now read-only.

MGLSource should not maintain parallel state #7375

Closed
1ec5 opened this issue Dec 11, 2016 · 13 comments
Closed

MGLSource should not maintain parallel state #7375

1ec5 opened this issue Dec 11, 2016 · 13 comments
Labels
archived Archived because of inactivity gl-ios iOS Mapbox Maps SDK for iOS macOS Mapbox Maps SDK for macOS refactor runtime styling

Comments

@1ec5
Copy link
Contributor

1ec5 commented Dec 11, 2016

MGLSource and its subclasses, particularly MGLShapeSource, currently hang onto objects passed into their initializers in order to return them in their properties’ getters. This is a workaround for #6584, but it’s problematic because MGLSource objects don’t necessarily know the canonical value of these properties. For example, if you get a source via -[MGLStyle sourceWithIdentifier:], the properties are all unset because the source was initialized via -[MGLSource initWithRawSource:]. You can then proceed to modify the source’s contents behind the backs of any other MGLShapeSource instances that wrap that source:

let one = MGLShapeSource(identifier: "one", shape: MGLPointFeature(), options: nil)
mapView.style.addSource(one)
// a short while later…
let uno = mapView.style.source(withIdentifier: "one")
uno.shape = someOtherFeature
// finally…
assert(one.shape is MGLPointFeature)
// 💣💥

/cc @boundsj

@1ec5
Copy link
Contributor Author

1ec5 commented Dec 11, 2016

This is essentially blocked by #7376, because otherwise we can continue to expose an -[MGLShapeSource setShape:] but we’d have to eliminate -[MGLShapeSource shape]. A write-only property is theoretically possible but unheard of in Objective-C and Swift. (The closest thing I can think of is -[NSView setNeedsDisplay:], which isn’t a property and which no one thinks is a good design.)

@1ec5
Copy link
Contributor Author

1ec5 commented Dec 12, 2016

#7377 will eliminate MGLShapeSource.geoJSONData and make MGLShapeSource.URL’s getter computed. It will also eliminate all the parallel state in MGLRasterSource and MGLVectorSource. However, MGLShapeSource.shape remains.

@boundsj
Copy link
Contributor

boundsj commented Dec 12, 2016

I updated the example in the original description above:
s/let uno = mapView.style.layer(withIdentifier: "one")/let uno = mapView.style.source(withIdentifier: "one")

@boundsj
Copy link
Contributor

boundsj commented Dec 12, 2016

This gets into #7376 and the memory concerns noted there but would it make sense for MGLStyle to keep references to the source and layer objects in use? Then, asking the style for a source would/could always return the same source instance.

@1ec5
Copy link
Contributor Author

1ec5 commented Dec 13, 2016

It's definitely possible and it'd solve several problems associated with these wrappers. We already do that for MGLOpenGLStyleLayers, which are entirely managed by the style. I wanted to avoid doing that for sources and layers in general, since there may be ways for the style to change behind MGLStyle's back, whereas a custom layer can only come from application code.

@jfirebaugh
Copy link
Contributor

I'm open to adding a void* peer member to mbgl::Style::Source, mbgl::Style::Layer, etc., as a place where SDKs could stash a pointer to the SDK-level object, so that they can ensure that methods like getLayer() always returns the same object for a given identifier. Would that help?

@1ec5
Copy link
Contributor Author

1ec5 commented Dec 14, 2016

The more I think about this, the more attractive @boundsj’s idea in #7375 (comment) looks. The only catch is that we have to be absolutely certain MGLStyle knows exactly when a source or layer goes away, such as due to polyline/polygon annotation removals.

A void* peer member on Source and Layer wouldn’t be a complete solution, because ARC doesn’t track ownership in void* pointers – the pointer would immediately become stale without some other Objective-C object hanging onto the object. However, a general-purpose void* context member would probably be useful for associating (non-object) data with any mbgl object that the SDK might need to wrap.

@jfirebaugh
Copy link
Contributor

What does ARC do if you use a type-erasure-based any type instead of void*? http://www.artima.com/cppsource/type_erasure2.html

@1ec5
Copy link
Contributor Author

1ec5 commented Dec 2, 2018

Type erasure via any would also potentially eliminate the edge cases caused by application code and mbgl effectively maintaining separate registries of sources (or layers).

/ref #13492

@stale stale bot removed the archived Archived because of inactivity label Dec 2, 2018
@stale stale bot added the archived Archived because of inactivity label May 31, 2019
@stale
Copy link

stale bot commented May 31, 2019

This issue has been automatically detected as stale because it has not had recent activity and will be archived. Thank you for your contributions.

@stale stale bot closed this as completed May 31, 2019
@1ec5
Copy link
Contributor Author

1ec5 commented Aug 6, 2019

Still the biggest pain point with runtime styling in Objective-C and Swift.

@1ec5 1ec5 reopened this Aug 6, 2019
@stale stale bot removed the archived Archived because of inactivity label Aug 6, 2019
@1ec5
Copy link
Contributor Author

1ec5 commented Aug 6, 2019

A void* peer member on Source and Layer wouldn’t be a complete solution, because ARC doesn’t track ownership in void* pointers – the pointer would immediately become stale without some other Objective-C object hanging onto the object.

This might not be a problem anymore if ARC can track ownership of Objective-C objects within C/C++ structs. The only unknown, then, is whether that also extends to void * or any pointers.

@jmkiley jmkiley added the gl-ios label Nov 21, 2019
@stale stale bot added the archived Archived because of inactivity label May 20, 2020
@stale
Copy link

stale bot commented May 22, 2020

This issue has been automatically detected as stale because it has not had recent activity and will be archived. Thank you for your contributions.

@stale stale bot closed this as completed May 22, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
archived Archived because of inactivity gl-ios iOS Mapbox Maps SDK for iOS macOS Mapbox Maps SDK for macOS refactor runtime styling
Projects
None yet
Development

No branches or pull requests

5 participants