use crate::{NodeZoomLayerMap, TilePoint, Zoom};
use mlua::{Lua, Result as LuaResult, UserData};
use std::cell::RefCell;
use std::collections::HashMap;
use std::rc::Rc;
pub fn load_lua_script(lua: &Lua, lua_code: &str) -> LuaResult<mlua::Function> {
lua.load(lua_code).exec()?;
let globals = lua.globals();
let node_function: mlua::Function = globals.get("node_function")?;
Ok(node_function)
}
pub struct LuaState {
pub lua: Lua,
pub node_function: mlua::Function,
}
pub enum LuaProcess {
None,
Some(LuaState),
}
#[derive(Debug, Clone)]
pub struct OsmNode {
id: i64,
zoom: Zoom,
tile_point: TilePoint,
tags: std::collections::HashMap<String, String>,
}
impl OsmNode {
pub fn new(id: i64, zoom: Zoom, tile_point: TilePoint, tags: HashMap<String, String>) -> Self {
Self {
id,
zoom,
tile_point,
tags,
}
}
}
impl UserData for OsmNode {
fn add_methods<'lua, M: mlua::UserDataMethods<Self>>(methods: &mut M) {
methods.add_method("find", |_, node, key: String| {
Ok(node.tags.get(&key).cloned())
});
methods.add_method("get_id", |_, node, ()| Ok(node.id));
methods.add_method("get_lat", |_, node, ()| Ok(node.tile_point.x));
methods.add_method("get_lon", |_, node, ()| Ok(node.tile_point.y));
methods.add_method("find", |_, node, key: String| {
Ok(node.tags.get(&key).cloned())
});
}
}
pub fn call_node_function(
lua: &Lua,
node_function: &mlua::Function,
node: OsmNode,
layered_nodes: Rc<RefCell<NodeZoomLayerMap>>,
) -> LuaResult<()> {
let output = lua.create_function(|_, (node,): (mlua::Value,)| {
println!("Output node: {:?}", node);
Ok(())
})?;
let find_function = create_find_function(lua, node.clone())?;
lua.globals().set("Find", find_function)?;
let layer_function = create_layer_function(lua, layered_nodes.clone(), node.clone())?;
lua.globals().set("Layer", layer_function)?;
node_function.call((node, output))
}
fn create_find_function(lua: &Lua, node: OsmNode) -> LuaResult<mlua::Function> {
lua.create_function(move |_, key: String| Ok(node.tags.get(&key).cloned()))
}
fn create_layer_function(
lua: &Lua,
layered_nodes: Rc<RefCell<NodeZoomLayerMap>>,
node: OsmNode,
) -> LuaResult<mlua::Function> {
lua.create_function(move |_, layer_name: String| {
Ok(layered_nodes.clone().borrow_mut().insert(
node.zoom.clone(),
layer_name,
&node.tile_point,
))
})
}