mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-12-24 15:02:59 +03:00
Add a /map/set-edits API call
This commit is contained in:
parent
a17ef9cc43
commit
e1de43b75c
@ -24,12 +24,14 @@ For now, the API is JSON over HTTP. The exact format is unspecified, error codes
|
||||
are missing, etc. A summary of the commands available so far:
|
||||
|
||||
- **/sim**
|
||||
- **GET /sim/reset**: Reset all map edits and the simulation state. The trips
|
||||
that will run don't change; they're determined by the scenario file you
|
||||
initially pass to `headless`.
|
||||
- **GET /sim/reset**: Reset all temporary map edits and the simulation state.
|
||||
The trips that will run don't change; they're determined by the scenario
|
||||
file you initially pass to `headless`. If you made live map edits using
|
||||
things like `/traffic-signals/set`, they'll be reset. If you specified
|
||||
`--edits` or used `/map/set-edits`, these will remain in effect.
|
||||
- **POST /sim/load**: Switch the scenario being simulated. Takes a
|
||||
[SimFlags](https://dabreegster.github.io/abstreet/rustdoc/sim/struct.SimFlags.html)
|
||||
as a JSON POST body.
|
||||
as a JSON POST body. Resets all map edits.
|
||||
- **GET /sim/get-time**: Returns the current simulation time.
|
||||
- **GET /sim/goto-time?t=06:30:00**: Simulate until 6:30 AM. If the time you
|
||||
specify is before the current time, you have to call **/sim/reset** first.
|
||||
@ -61,6 +63,10 @@ are missing, etc. A summary of the commands available so far:
|
||||
this to a file in `data/player/edits/map_name/` and later use it in-game
|
||||
normally. You can also later run the `headless` server with
|
||||
`--edits=name_of_edits`.
|
||||
- **POST /map/set-edits**: The POST body must be
|
||||
[PermanentMapEdits](https://dabreegster.github.io/abstreet/rustdoc/map_model/struct.PermanentMapEdits.html)
|
||||
in JSON format. This is the same as the files in `data/player/edits/`. The
|
||||
edits will remain as you call `/sim/reset`, but get reset with `/sim/load`.
|
||||
|
||||
## Working with the map model
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
// This runs a simulation without any graphics and serves a very basic API to control things. The
|
||||
// API is not documented yet. To run this:
|
||||
// This runs a simulation without any graphics and serves a very basic API to control things. See
|
||||
// https://dabreegster.github.io/abstreet/dev/api.html for documentation. To run this:
|
||||
//
|
||||
// > cd headless; cargo run -- --port=1234 ../data/system/scenarios/montlake/weekday.bin
|
||||
// > curl http://localhost:1234/get-time
|
||||
@ -30,18 +30,24 @@ lazy_static::lazy_static! {
|
||||
static ref MAP: RwLock<Map> = RwLock::new(Map::blank());
|
||||
static ref SIM: RwLock<Sim> = RwLock::new(Sim::new(&Map::blank(), SimOptions::new("tmp"), &mut Timer::throwaway()));
|
||||
static ref FLAGS: RwLock<SimFlags> = RwLock::new(SimFlags::for_test("tmp"));
|
||||
static ref EDITS: RwLock<Option<String>> = RwLock::new(None);
|
||||
static ref EDITS: RwLock<Option<MapEdits>> = RwLock::new(None);
|
||||
}
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
let mut args = CmdArgs::new();
|
||||
let mut timer = Timer::new("setup headless");
|
||||
let sim_flags = SimFlags::from_args(&mut args);
|
||||
let port = args.required("--port").parse::<u16>().unwrap();
|
||||
*EDITS.write().unwrap() = args.optional("--edits");
|
||||
let load_edits = args.optional("--edits");
|
||||
args.done();
|
||||
|
||||
let (mut map, sim, _) = sim_flags.load(&mut Timer::new("setup headless"));
|
||||
let (mut map, sim, _) = sim_flags.load(&mut timer);
|
||||
if let Some(path) = load_edits {
|
||||
let edits = MapEdits::load(&map, path, &mut timer).unwrap();
|
||||
*EDITS.write().unwrap() = Some(edits);
|
||||
}
|
||||
|
||||
apply_edits(&mut map);
|
||||
*MAP.write().unwrap() = map;
|
||||
*SIM.write().unwrap() = sim;
|
||||
@ -243,7 +249,7 @@ fn handle_command(
|
||||
})
|
||||
.collect(),
|
||||
})),
|
||||
// Querying the map
|
||||
// Controlling the map
|
||||
"/map/get-edits" => {
|
||||
let mut edits = map.get_edits().clone();
|
||||
edits.commands.clear();
|
||||
@ -252,16 +258,21 @@ fn handle_command(
|
||||
&edits, map,
|
||||
)))
|
||||
}
|
||||
"/map/set-edits" => {
|
||||
let perma: PermanentMapEdits = abstutil::from_json(body)?;
|
||||
let edits = PermanentMapEdits::from_permanent(perma, map)?;
|
||||
*EDITS.write().unwrap() = Some(edits);
|
||||
apply_edits(map);
|
||||
Ok(format!("loaded edits"))
|
||||
}
|
||||
_ => Err("Unknown command".into()),
|
||||
}
|
||||
}
|
||||
|
||||
fn apply_edits(map: &mut Map) {
|
||||
if let Some(name) = EDITS.read().unwrap().as_ref() {
|
||||
let mut timer = Timer::new(format!("apply edits {}", name));
|
||||
let edits =
|
||||
MapEdits::load(map, abstutil::path_edits(map.get_name(), name), &mut timer).unwrap();
|
||||
map.must_apply_edits(edits, &mut timer);
|
||||
if let Some(edits) = EDITS.read().unwrap().as_ref() {
|
||||
let mut timer = Timer::new(format!("apply edits {}", edits.edits_name));
|
||||
map.must_apply_edits(edits.clone(), &mut timer);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -20,7 +20,7 @@ pub struct Assets {
|
||||
}
|
||||
|
||||
impl Assets {
|
||||
pub fn new(font_dir: String) -> Assets {
|
||||
pub fn new() -> Assets {
|
||||
let mut a = Assets {
|
||||
default_line_height: RefCell::new(0.0),
|
||||
text_cache: RefCell::new(LruCache::new(500)),
|
||||
@ -29,6 +29,9 @@ impl Assets {
|
||||
font_to_id: HashMap::new(),
|
||||
text_opts: Options::default(),
|
||||
};
|
||||
// TODO These paths are now hardcoded for WASM. This is reasonable, since the fonts
|
||||
// available are currently fixed anyway. For widgetry to become a library, need to figure
|
||||
// out how to override these.
|
||||
a.text_opts.fontdb = fontdb::Database::new();
|
||||
a.text_opts.fontdb.load_font_data(
|
||||
include_bytes!("../../data/system/fonts/BungeeInline-Regular.ttf").to_vec(),
|
||||
|
@ -216,7 +216,7 @@ pub fn run<G: 'static + GUI, F: FnOnce(&mut EventCtx) -> G>(settings: Settings,
|
||||
|
||||
let monitor_scale_factor = prerender_innards.monitor_scale_factor();
|
||||
let prerender = Prerender {
|
||||
assets: Assets::new(abstutil::path("system/fonts")),
|
||||
assets: Assets::new(),
|
||||
num_uploads: Cell::new(0),
|
||||
inner: prerender_innards,
|
||||
scale_factor: RefCell::new(settings.scale_factor.unwrap_or(monitor_scale_factor)),
|
||||
|
Loading…
Reference in New Issue
Block a user