-
Notifications
You must be signed in to change notification settings - Fork 14
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement PartialEq for Map or MapFactory #11
Comments
This is an issue I am happy to take on, but I will need to familiarize myself with how to implement PartialEq on JSValues. |
Hi @thebearjew I am not an expert on this area so please correct me if this doesn't make any sense. I think That said, implementing
impl PartialEq for Handle {
fn eq(&self, other: &Self) -> bool {
js_sys::Object::is(self.on_data.as_ref(), other.on_data.as_ref()) &&
js_sys::Object::is(self.on_styledata.as_ref(), other.on_styledata.as_ref()) &&
...
}
}
#[derive(PartialEq)]
pub struct MapFactory {
pub map: Arc<Map>,
handle: Option<Handle>,
}
pub struct Map {
pub(crate) inner: crate::js::Map,
}
impl PartialEq for Map {
fn eq(&self, other: &Self) -> bool {
js_sys::Object::is(&self.inner, &other.inner)
}
} NOTE: Above code compiles but wasn't tested at all. |
I agree that using JavaScript referential equality ( I am working on a PR for this, but I think it's possible to make passing around a // Get Clone for free because Arc<crate::js::Map>
#[derive(Clone)]
pub struct Map {
pub(crate) inner: Arc<crate::js::Map>,
}
pub struct MapFactory {
map: Map,
handle: Handle
}
impl MapFactory {
pub fn set_listener<F: MapEventListener + 'static>(&mut self, f: F) {
// Arc<Map> here
// I don't think the Arc will be dropped because calling Handle::new()
// will move it into a Closure and that should maintain a reference.
// I am not certain if this will work, please correct me!
let map = Arc::new(self.map.clone());
self.handle = Some(Handle::new(Arc::downgrade(&map), f));
let handle = self.handle.as_ref().unwrap();
// ...
}
} Here's a concrete example of the scenario I am trying to implement: I would like to control the behavior of the map via Yew hooks and lifecycle events, rather than respond to Mapbox events like Example: #[function_component(LoadRemoteGeoJson)]
fn load_remote_geojson(props: Props) -> Html {
let geojson = use_fetch::<MyGeoJsonData>(props.url);
// Accesses the same object from `use_map`
// This is helpful because it means we can fetch GeoJson outside of the root component `<App>`
// Can also update or change the map based on button clicks.
// Currently this is not possible without Map or MapFactory implementing `Clone` and `PartialEq`.
let map = use_context::<Map>();
map.add_geojeon_source("walking", geojson);
map.add_layer("walking", ...);
// renders props.children
html! { ... }
}
fn switch(route: Route) -> Html {
match route {
Route::User { id } => html {
//
<LoadRemoteGeoJson url={format!("https://example.com/{id}.geojson")}>
<UserProfile {id} />
</LoadRemoteGeoJson>
},
}
}
#[function_component(App)]
fn app() -> Html {
// Initialize the map. copied mapbox-gl-rs example.
let map = use_map();
html! {
// Make the `MapFactory` or `Map` available to any component in the application.
// This requires `Clone` and `PartialEq` on `Map` or `MapFactory`
<ContextProvider<Map> context={map.clone}>
<BrowserRouter>
// Load different GeoJson based on route
<Switch<Route> render={switch} />
</BrowserRouter>
</ContextProvider<Map>>
}
} I should mention that I am not a Rust expert and could use some guidance and help if I make some basic Rust mistakes. I am more knowledgeable about React / Yew / Frontend concepts. ありがとうございます |
Hi @thebearjew
Or perhaps service worker is in mind? |
When using
mapboxgl
inside of a Yew app, it would be helpful to pass aroundMapFactory
orMap
as props to other components so they can manipulate the map in different ways. Yew requires that props implementProperties
andPartialEq
.Additionally, in order to take a map instance and pass it into a Yew context provider like
use_context
, the type must implementParitalEq
(docs for use_context).Global state management crates for Yew like bounce also require that the shared value be
ParitalEq
.This will allow the mapbox gl instance to be used outside of the context where it was initialized.
The text was updated successfully, but these errors were encountered: