app.rs 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388
  1. use async_recursion::async_recursion;
  2. use futures::{stream::FuturesUnordered, StreamExt};
  3. use std::{sync::Arc, thread};
  4. use crate::{
  5. expr::Op,
  6. gfx2::{GraphicsEventPublisherPtr, RenderApiPtr, Vertex},
  7. prop::{Property, PropertySubType, PropertyType},
  8. scene::{Pimpl, SceneGraph, SceneGraphPtr2, SceneNodeId, SceneNodeType},
  9. text2::TextShaperPtr,
  10. ui::{Mesh, RenderLayer, Stoppable, Text, Window},
  11. };
  12. //fn print_type_of<T>(_: &T) {
  13. // println!("{}", std::any::type_name::<T>())
  14. //}
  15. pub struct AsyncRuntime {
  16. signal: smol::channel::Sender<()>,
  17. shutdown: smol::channel::Receiver<()>,
  18. exec_threadpool: std::sync::Mutex<Option<thread::JoinHandle<()>>>,
  19. ex: Arc<smol::Executor<'static>>,
  20. tasks: std::sync::Mutex<Vec<smol::Task<()>>>,
  21. }
  22. impl AsyncRuntime {
  23. pub fn new(ex: Arc<smol::Executor<'static>>) -> Self {
  24. let (signal, shutdown) = smol::channel::unbounded::<()>();
  25. Self {
  26. signal,
  27. shutdown,
  28. exec_threadpool: std::sync::Mutex::new(None),
  29. ex,
  30. tasks: std::sync::Mutex::new(vec![]),
  31. }
  32. }
  33. pub fn start(&self) {
  34. let n_threads = std::thread::available_parallelism().unwrap().get();
  35. let shutdown = self.shutdown.clone();
  36. let ex = self.ex.clone();
  37. let exec_threadpool = thread::spawn(move || {
  38. easy_parallel::Parallel::new()
  39. // N executor threads
  40. .each(0..n_threads, |_| smol::future::block_on(ex.run(shutdown.recv())))
  41. .run();
  42. });
  43. *self.exec_threadpool.lock().unwrap() = Some(exec_threadpool);
  44. debug!(target: "async_runtime", "Started runtime");
  45. }
  46. pub fn push_task(&self, task: smol::Task<()>) {
  47. self.tasks.lock().unwrap().push(task);
  48. }
  49. pub fn stop(&self) {
  50. // Go through event graph and call stop on everything
  51. // Depth first
  52. debug!(target: "app", "Stopping app...");
  53. let tasks = std::mem::take(&mut *self.tasks.lock().unwrap());
  54. // Close all tasks
  55. smol::future::block_on(async {
  56. // Perform cleanup code
  57. // If not finished in certain amount of time, then just exit
  58. let futures = FuturesUnordered::new();
  59. for task in tasks {
  60. futures.push(task.cancel());
  61. }
  62. let _: Vec<_> = futures.collect().await;
  63. });
  64. if !self.signal.close() {
  65. error!(target: "app", "exec threadpool was already shutdown");
  66. }
  67. let exec_threadpool = std::mem::replace(&mut *self.exec_threadpool.lock().unwrap(), None);
  68. let exec_threadpool = exec_threadpool.expect("threadpool wasnt started");
  69. exec_threadpool.join().unwrap();
  70. debug!(target: "app", "Stopped app");
  71. }
  72. }
  73. pub struct App {
  74. sg: SceneGraphPtr2,
  75. ex: Arc<smol::Executor<'static>>,
  76. render_api: RenderApiPtr,
  77. event_pub: GraphicsEventPublisherPtr,
  78. text_shaper: TextShaperPtr,
  79. }
  80. impl App {
  81. pub fn new(
  82. sg: SceneGraphPtr2,
  83. ex: Arc<smol::Executor<'static>>,
  84. render_api: RenderApiPtr,
  85. event_pub: GraphicsEventPublisherPtr,
  86. text_shaper: TextShaperPtr,
  87. ) -> Arc<Self> {
  88. Arc::new(Self { sg, ex, render_api, event_pub, text_shaper })
  89. }
  90. pub async fn start(self: Arc<Self>) {
  91. debug!(target: "app", "App::start()");
  92. // Setup UI
  93. let mut sg = self.sg.lock().await;
  94. let window = sg.add_node("window", SceneNodeType::Window);
  95. let mut prop = Property::new("screen_size", PropertyType::Float32, PropertySubType::Pixel);
  96. prop.set_array_len(2);
  97. // Window not yet initialized so we can't set these.
  98. //prop.set_f32(0, screen_width);
  99. //prop.set_f32(1, screen_height);
  100. window.add_property(prop).unwrap();
  101. let mut prop = Property::new("scale", PropertyType::Float32, PropertySubType::Pixel);
  102. prop.set_defaults_f32(vec![1.]).unwrap();
  103. window.add_property(prop).unwrap();
  104. let window_id = window.id;
  105. // Create Window
  106. // Window::new(window, weak sg)
  107. drop(sg);
  108. let pimpl = Window::new(
  109. self.ex.clone(),
  110. self.sg.clone(),
  111. window_id,
  112. self.render_api.clone(),
  113. self.event_pub.clone(),
  114. )
  115. .await;
  116. // -> reads any props it needs
  117. // -> starts procs
  118. let mut sg = self.sg.lock().await;
  119. let node = sg.get_node_mut(window_id).unwrap();
  120. node.pimpl = pimpl;
  121. sg.link(window_id, SceneGraph::ROOT_ID).unwrap();
  122. // Testing
  123. let node = sg.get_node(window_id).unwrap();
  124. node.set_property_f32("scale", 2.).unwrap();
  125. drop(sg);
  126. self.make_me_a_schema_plox().await;
  127. // Access drawable in window node and call draw()
  128. self.trigger_redraw().await;
  129. }
  130. pub async fn stop(&self) {
  131. let sg = self.sg.lock().await;
  132. let window_id = sg.lookup_node("/window").unwrap().id;
  133. self.stop_node(&sg, window_id).await;
  134. }
  135. #[async_recursion]
  136. async fn stop_node(&self, sg: &SceneGraph, node_id: SceneNodeId) {
  137. let node = sg.get_node(node_id).unwrap();
  138. for child_inf in node.get_children2() {
  139. self.stop_node(sg, child_inf.id).await;
  140. }
  141. match &node.pimpl {
  142. Pimpl::Window(win) => win.stop().await,
  143. Pimpl::RenderLayer(layer) => layer.stop().await,
  144. Pimpl::Mesh(mesh) => mesh.stop().await,
  145. _ => panic!("unhandled pimpl type"),
  146. };
  147. }
  148. async fn make_me_a_schema_plox(&self) {
  149. // Create a layer called view
  150. let mut sg = self.sg.lock().await;
  151. let layer_node_id = create_layer(&mut sg, "view");
  152. // Customize our layer
  153. let node = sg.get_node(layer_node_id).unwrap();
  154. let prop = node.get_property("rect").unwrap();
  155. prop.set_f32(0, 0.).unwrap();
  156. prop.set_f32(1, 0.).unwrap();
  157. let code = vec![Op::LoadVar("w".to_string())];
  158. prop.set_expr(2, code).unwrap();
  159. let code = vec![Op::LoadVar("h".to_string())];
  160. prop.set_expr(3, code).unwrap();
  161. node.set_property_bool("is_visible", true).unwrap();
  162. // Setup the pimpl
  163. let node_id = node.id;
  164. drop(sg);
  165. let pimpl =
  166. RenderLayer::new(self.ex.clone(), self.sg.clone(), node_id, self.render_api.clone())
  167. .await;
  168. let mut sg = self.sg.lock().await;
  169. let node = sg.get_node_mut(node_id).unwrap();
  170. node.pimpl = pimpl;
  171. let window_id = sg.lookup_node("/window").unwrap().id;
  172. sg.link(node_id, window_id).unwrap();
  173. // Create a bg mesh
  174. let node_id = create_mesh(&mut sg, "bg");
  175. let node = sg.get_node_mut(node_id).unwrap();
  176. let prop = node.get_property("rect").unwrap();
  177. prop.set_f32(0, 0.).unwrap();
  178. prop.set_f32(1, 0.).unwrap();
  179. let code = vec![Op::LoadVar("w".to_string())];
  180. prop.set_expr(2, code).unwrap();
  181. let code = vec![Op::LoadVar("h".to_string())];
  182. prop.set_expr(3, code).unwrap();
  183. // Setup the pimpl
  184. let node_id = node.id;
  185. let (x1, y1) = (0., 0.);
  186. let (x2, y2) = (1., 1.);
  187. let verts = vec![
  188. // top left
  189. Vertex { pos: [x1, y1], color: [0.3, 0., 0., 1.], uv: [0., 0.] },
  190. // top right
  191. Vertex { pos: [x2, y1], color: [0., 0., 0., 1.], uv: [1., 0.] },
  192. // bottom left
  193. Vertex { pos: [x1, y2], color: [0., 0., 0., 1.], uv: [0., 1.] },
  194. // bottom right
  195. Vertex { pos: [x2, y2], color: [0., 0., 0., 1.], uv: [1., 1.] },
  196. ];
  197. let indices = vec![0, 2, 1, 1, 2, 3];
  198. drop(sg);
  199. let pimpl = Mesh::new(
  200. self.ex.clone(),
  201. self.sg.clone(),
  202. node_id,
  203. self.render_api.clone(),
  204. verts,
  205. indices,
  206. )
  207. .await;
  208. let mut sg = self.sg.lock().await;
  209. let node = sg.get_node_mut(node_id).unwrap();
  210. node.pimpl = pimpl;
  211. sg.link(node_id, layer_node_id).unwrap();
  212. // Create another mesh
  213. let node_id = create_mesh(&mut sg, "box");
  214. let node = sg.get_node_mut(node_id).unwrap();
  215. let prop = node.get_property("rect").unwrap();
  216. prop.set_f32(0, 10.).unwrap();
  217. prop.set_f32(1, 10.).unwrap();
  218. prop.set_f32(2, 60.).unwrap();
  219. prop.set_f32(3, 60.).unwrap();
  220. // Setup the pimpl
  221. let (x1, y1) = (0., 0.);
  222. let (x2, y2) = (1., 1.);
  223. let verts = vec![
  224. // top left
  225. Vertex { pos: [x1, y1], color: [1., 0., 0., 1.], uv: [0., 0.] },
  226. // top right
  227. Vertex { pos: [x2, y1], color: [1., 0., 1., 1.], uv: [1., 0.] },
  228. // bottom left
  229. Vertex { pos: [x1, y2], color: [0., 0., 1., 1.], uv: [0., 1.] },
  230. // bottom right
  231. Vertex { pos: [x2, y2], color: [1., 1., 0., 1.], uv: [1., 1.] },
  232. ];
  233. let indices = vec![0, 2, 1, 1, 2, 3];
  234. drop(sg);
  235. let pimpl = Mesh::new(
  236. self.ex.clone(),
  237. self.sg.clone(),
  238. node_id,
  239. self.render_api.clone(),
  240. verts,
  241. indices,
  242. )
  243. .await;
  244. let mut sg = self.sg.lock().await;
  245. let node = sg.get_node_mut(node_id).unwrap();
  246. node.pimpl = pimpl;
  247. sg.link(node_id, layer_node_id).unwrap();
  248. // Create some text
  249. let node_id = create_text(&mut sg, "label");
  250. let node = sg.get_node_mut(node_id).unwrap();
  251. let prop = node.get_property("rect").unwrap();
  252. prop.set_f32(0, 100.).unwrap();
  253. prop.set_f32(1, 100.).unwrap();
  254. prop.set_f32(2, 800.).unwrap();
  255. prop.set_f32(3, 200.).unwrap();
  256. node.set_property_f32("baseline", 40.).unwrap();
  257. node.set_property_f32("font_size", 60.).unwrap();
  258. node.set_property_str("text", "anon1🍆").unwrap();
  259. //node.set_property_str("text", "anon1").unwrap();
  260. let prop = node.get_property("color").unwrap();
  261. prop.set_f32(0, 0.).unwrap();
  262. prop.set_f32(1, 1.).unwrap();
  263. prop.set_f32(2, 0.).unwrap();
  264. prop.set_f32(3, 1.).unwrap();
  265. drop(sg);
  266. let pimpl = Text::new(
  267. self.ex.clone(),
  268. self.sg.clone(),
  269. node_id,
  270. self.render_api.clone(),
  271. self.text_shaper.clone(),
  272. )
  273. .await;
  274. let mut sg = self.sg.lock().await;
  275. let node = sg.get_node_mut(node_id).unwrap();
  276. node.pimpl = pimpl;
  277. sg.link(node_id, layer_node_id).unwrap();
  278. }
  279. async fn trigger_redraw(&self) {
  280. let sg = self.sg.lock().await;
  281. let window_node = sg.lookup_node("/window").expect("no window attached!");
  282. match &window_node.pimpl {
  283. Pimpl::Window(win) => win.draw(&sg).await,
  284. _ => panic!("wrong pimpl"),
  285. }
  286. }
  287. }
  288. pub fn create_layer(sg: &mut SceneGraph, name: &str) -> SceneNodeId {
  289. let node = sg.add_node(name, SceneNodeType::RenderLayer);
  290. let prop = Property::new("is_visible", PropertyType::Bool, PropertySubType::Null);
  291. node.add_property(prop).unwrap();
  292. let mut prop = Property::new("rect", PropertyType::Float32, PropertySubType::Pixel);
  293. prop.set_array_len(4);
  294. prop.allow_exprs();
  295. node.add_property(prop).unwrap();
  296. node.id
  297. }
  298. pub fn create_mesh(sg: &mut SceneGraph, name: &str) -> SceneNodeId {
  299. let node = sg.add_node(name, SceneNodeType::RenderMesh);
  300. let mut prop = Property::new("rect", PropertyType::Float32, PropertySubType::Pixel);
  301. prop.set_array_len(4);
  302. prop.allow_exprs();
  303. node.add_property(prop).unwrap();
  304. let prop = Property::new("z_index", PropertyType::Uint32, PropertySubType::Null);
  305. node.add_property(prop).unwrap();
  306. node.id
  307. }
  308. fn create_text(sg: &mut SceneGraph, name: &str) -> SceneNodeId {
  309. let node = sg.add_node(name, SceneNodeType::RenderText);
  310. let mut prop = Property::new("rect", PropertyType::Float32, PropertySubType::Pixel);
  311. prop.set_array_len(4);
  312. prop.allow_exprs();
  313. node.add_property(prop).unwrap();
  314. let prop = Property::new("baseline", PropertyType::Float32, PropertySubType::Pixel);
  315. node.add_property(prop).unwrap();
  316. let prop = Property::new("font_size", PropertyType::Float32, PropertySubType::Pixel);
  317. node.add_property(prop).unwrap();
  318. let prop = Property::new("text", PropertyType::Str, PropertySubType::Null);
  319. node.add_property(prop).unwrap();
  320. let mut prop = Property::new("color", PropertyType::Float32, PropertySubType::Color);
  321. prop.set_array_len(4);
  322. prop.set_range_f32(0., 1.);
  323. node.add_property(prop).unwrap();
  324. let prop = Property::new("z_index", PropertyType::Uint32, PropertySubType::Null);
  325. node.add_property(prop).unwrap();
  326. let prop = Property::new("debug", PropertyType::Bool, PropertySubType::Null);
  327. node.add_property(prop).unwrap();
  328. node.id
  329. }