Skip to content
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

Render A/B Street's lanes and traffic simulation on top of Mapbox GL #788

Merged
merged 24 commits into from
Oct 31, 2021

Conversation

dabreegster
Copy link
Collaborator

See piggyback/README.md for an overview and goals. Demo:
screencast

Main open question

I am totally overwhelmed by the web dev ecosystem. I found a nice plugin to switch Mapbox styles (https://github.com/el/style-switcher), but for the life of me, I can't figure out the "right" way to include it as a dependency.

  1. I tried adding a <script> pointing to a copy on cdnjs, but hit problems where the .js didn't seem to export any symbols. This isn't a "hermetic" way of depending on it anyway; what if that CDN disappears?
  2. I started an NPM package and switched to using Mapbox and this plugin as dependencies. Except... I can't seem to find anywhere that describes how to actually use all of the JS dependencies in the .html. I think the answer is to use webpack, browserify, gulp, or something else to consolidate into one minified .js file. But I lack the context to decide the most reasonable way to wire this all up, and I'm having trouble finding an authoritative-sounding voice on which framework or ecosystem to buy into.

Some next steps

  • If the long-term intention of this demo is just to render roads and intersections and let Mapbox handle buildings and other stuff, we could get some dramatic speedups in DrawMap by excluding most objects. I don't want to add a bunch of branching logic there, though. Ideally the huge World refactor could make it easy for us to express that we just want a few "layers" from the A/B Street side.
  • We're in JS land now, so maybe there's some nice easy way to add a progress bar around things like loading the map file?
  • Figure out a deployment story and publish an initial version of this WASM package on NPM or something else. I want people to be encouraged to build web apps that use bits and pieces of A/B Street, and based on feedback, expand what's in the PiggybackDemo API.

Copy link
Collaborator Author

@dabreegster dabreegster left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hopefully needless to say, just view the full diff, not each commit. Unless you want to watch me really flailing around in the beginning...

@@ -87,9 +87,11 @@ impl AgentCache {
pub fn calculate_unzoomed_agents<P: AsRef<Prerender>>(
&mut self,
prerender: &mut P,
app: &dyn AppLike,
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Split up the arguments here to avoid borrow checker annoyingness in the new piggyback crate

directory to contain some maps.

Quick development:
`wasm-pack build --dev --target web -- --features wasm && ./serve_locally.py`
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In my branch where I switched to npm, the python script gets replaced with https://www.npmjs.com/package/http-server

`;
}

var lastTime = performance.now();
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is all so unorganized and weird. I'm not used to the typical ways of organizing state like this. Advice / good example projects welcome.


traffic_controls_inactive();

// Let the onclick handlers reach into this scope. Alternatively, grab the buttons here and set onclick handlers.
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here's an example where I'm not sure what the best practice is. Should we just define the bare buttons in HTML, grab the by ID here, and install the onclick?

#[cfg(target_arch = "wasm32")]
pub use piggyback::*;

#[cfg(not(target_arch = "wasm32"))]
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I want to just mark the entire piggyback crate as wasm-only and get rid of the feature flags and everything. But there doesn't seem to be a way to encode that in Cargo.toml. So then if you're building stuff for native and you run cargo check in the workspace, it tries to build things here and blows up.

}
None
}
}
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The idea is that we could add much, much more to the API. In the extreme case, open up all of Map and Sim. But those public APIs are currently a mess. Based on what we want to make out of this, we could be much more targeted and/or clean up internal APIs as we go.

@@ -260,7 +260,7 @@ type WindowAdapter = crate::backend_glow_native::WindowAdapter;

pub struct PrerenderInnards {
gl: Rc<glow::Context>,
window_adapter: WindowAdapter,
window_adapter: Option<WindowAdapter>,
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In piggyback mode, there's no window (that widgetry manages). Doesn't affect existing code.

})
.unwrap();

debug!("built WebGL context");

fn webgl2_program_context(
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I split up these methods into getting the context, then building the shaders for each webgl version

webgl1_program(glow::Context::from_webgl1_context(raw_gl), &mut timer).unwrap();
let prerender_innards = PrerenderInnards::new(gl, program, None);

let style = Style::light_bg();
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could certainly be more configurable here

@ilyabo
Copy link

ilyabo commented Oct 25, 2021

I think the answer is to use webpack, browserify, gulp, or something else to consolidate into one minified .js

If you want to avoid the pain of configuring webpack etc, I'd recommend going with either Create React App or the more advanced Next.js. React is likely the most popular JS UI library nowadays, but even if you don't use React these frameworks can help to bootstrap a JS app with all the tools for dependency management and building and save a lot of time on the configuration. If you are interested, maybe I could help you with that.

We're in JS land now, so maybe there's some nice easy way to add a progress bar around things like loading the map file?

There are dozens of React UI kits out there now. My personal favorite is Chakra. Here you can find progress bars: https://chakra-ui.com/docs/feedback/progress

@dabreegster
Copy link
Collaborator Author

If you want to avoid the pain of configuring webpack etc, I'd recommend going with either Create React App or the more advanced Next.js.

Thank you for the pointers! I might dive into these options myself, but more than likely, hand it off to somebody else starting out on the project and more familiar with web dev. I think for existing as example code, a "vanilla JS" mapbox example without any frameworks could be useful. But I'd also like to see a variation using React and other things. My goals with this were partly to learn a bit of mapbox myself, but also to start fostering more of an ecosystem where people can play around with gluing abst to "normal" web apps.

(And for my own learning, I think I'll try out create-react-app but dig into the config it autogenerates, because I want to understand a bit of how bundling works in practice.)

@dabreegster
Copy link
Collaborator Author

@dabreegster
Copy link
Collaborator Author

Going to merge this now. Deployment is still messy and manual, but it's at least a start.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants