main.rs 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  1. /* This file is part of DarkFi (https://dark.fi)
  2. *
  3. * Copyright (C) 2020-2024 Dyne.org foundation
  4. *
  5. * This program is free software: you can redistribute it and/or modify
  6. * it under the terms of the GNU Affero General Public License as
  7. * published by the Free Software Foundation, either version 3 of the
  8. * License, or (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU Affero General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU Affero General Public License
  16. * along with this program. If not, see <https://www.gnu.org/licenses/>.
  17. */
  18. // channel wait until deadline
  19. #![feature(deadline_api)]
  20. // Adds remainder() fn for String::split() result
  21. #![feature(str_split_whitespace_remainder)]
  22. // instant.elapsed().as_millis_f32()
  23. #![feature(duration_millis_float)]
  24. // Allow attributes on statements and code blocks
  25. #![feature(stmt_expr_attributes)]
  26. // if let Some(is_foo) = is_foo && is_foo { ... }
  27. #![feature(let_chains)]
  28. // consume a box
  29. #![feature(box_into_inner)]
  30. // we need Arc::get_mut_unchecked() to workaround the lack of Arc::new_cyclic() which
  31. // accepts async fns.
  32. // See https://github.com/rust-lang/rust/issues/112566
  33. #![feature(get_mut_unchecked)]
  34. // Use these to incrementally fix warnings with cargo fix
  35. //#![allow(warnings, unused)]
  36. //#![deny(unused_imports)]
  37. use async_lock::{Mutex as AsyncMutex, RwLock as AsyncRwLock};
  38. use std::sync::{mpsc, Arc};
  39. #[macro_use]
  40. extern crate log;
  41. #[allow(unused_imports)]
  42. use log::LevelFilter;
  43. mod app;
  44. mod build_info;
  45. //mod darkirc;
  46. mod darkirc2;
  47. mod error;
  48. mod expr;
  49. mod gfx;
  50. mod mesh;
  51. mod net;
  52. //mod plugin;
  53. mod prop;
  54. mod pubsub;
  55. //mod py;
  56. mod ringbuf;
  57. mod scene;
  58. use scene::SceneNode as SceneNode3;
  59. mod text;
  60. mod ui;
  61. mod util;
  62. use crate::{net::ZeroMQAdapter, text::TextShaper};
  63. pub type ExecutorPtr = Arc<smol::Executor<'static>>;
  64. fn panic_hook(panic_info: &std::panic::PanicInfo) {
  65. error!("panic occurred: {panic_info}");
  66. //error!("panic: {}", std::backtrace::Backtrace::force_capture().to_string());
  67. std::process::exit(1);
  68. }
  69. fn main() {
  70. // Exit the application on panic right away
  71. std::panic::set_hook(Box::new(panic_hook));
  72. #[cfg(target_os = "android")]
  73. {
  74. android_logger::init_once(
  75. android_logger::Config::default().with_max_level(LevelFilter::Debug).with_tag("darkfi"),
  76. );
  77. let paths = std::fs::read_dir("/data/data/darkfi.darkwallet/").unwrap();
  78. for path in paths {
  79. debug!("{}", path.unwrap().path().display())
  80. }
  81. }
  82. #[cfg(target_os = "linux")]
  83. {
  84. // For ANSI colors in the terminal
  85. colored::control::set_override(true);
  86. let term_logger = simplelog::TermLogger::new(
  87. simplelog::LevelFilter::Debug,
  88. simplelog::Config::default(),
  89. simplelog::TerminalMode::Mixed,
  90. simplelog::ColorChoice::Auto,
  91. );
  92. simplelog::CombinedLogger::init(vec![term_logger]).expect("logger");
  93. }
  94. info!("Target OS: {}", build_info::TARGET_OS);
  95. info!("Target arch: {}", build_info::TARGET_ARCH);
  96. let ex = Arc::new(smol::Executor::new());
  97. let sg_root = SceneNode3::root();
  98. let async_runtime = app::AsyncRuntime::new(ex.clone());
  99. async_runtime.start();
  100. let sg_root2 = sg_root.clone();
  101. let ex2 = ex.clone();
  102. let zmq_task = ex.spawn(async {
  103. let zmq_rpc = ZeroMQAdapter::new(sg_root2, ex2).await;
  104. zmq_rpc.run().await;
  105. });
  106. async_runtime.push_task(zmq_task);
  107. let (method_req, method_rep) = mpsc::channel();
  108. // The UI actually needs to be running for this to reply back.
  109. // Otherwise calls will just hang.
  110. let render_api = gfx::RenderApi::new(method_req);
  111. let event_pub = gfx::GraphicsEventPublisher::new();
  112. let text_shaper = TextShaper::new();
  113. //let darkirc_backend = DarkIrcBackend::new();
  114. let app = app::App::new(
  115. sg_root,
  116. render_api,
  117. event_pub.clone(),
  118. text_shaper,
  119. //darkirc_backend,
  120. ex.clone(),
  121. );
  122. let app_task = ex.spawn(app.clone().start());
  123. async_runtime.push_task(app_task);
  124. let cv_started = app.is_started.clone();
  125. let sg_root = app.sg_root.clone();
  126. let ex2 = ex.clone();
  127. let darkirc_task = ex.spawn(async move {
  128. cv_started.wait().await;
  129. if let Err(e) = darkirc2::receive_msgs(sg_root, ex2).await {
  130. error!("DarkIRC error: {e}")
  131. }
  132. });
  133. async_runtime.push_task(darkirc_task);
  134. /*
  135. // Nice to see which events exist
  136. let ev_sub = event_pub.subscribe_key_down();
  137. let ev_relay_task = ex.spawn(async move {
  138. debug!(target: "main", "event relayer started");
  139. loop {
  140. let Ok((key, mods, repeat)) = ev_sub.receive().await else {
  141. debug!(target: "main", "Event relayer closed");
  142. break
  143. };
  144. // Ignore keys which get stuck repeating when switching windows
  145. match key {
  146. miniquad::KeyCode::LeftShift | miniquad::KeyCode::LeftSuper => continue,
  147. _ => {}
  148. }
  149. if !repeat {
  150. debug!(target: "main", "key_down event: {:?} {:?} {}", key, mods, repeat);
  151. }
  152. }
  153. });
  154. async_runtime.push_task(ev_relay_task);
  155. let ev_sub = event_pub.subscribe_key_up();
  156. let ev_relay_task = ex.spawn(async move {
  157. debug!(target: "main", "event relayer started");
  158. loop {
  159. let Ok((key, mods)) = ev_sub.receive().await else {
  160. debug!(target: "main", "Event relayer closed");
  161. break
  162. };
  163. // Ignore keys which get stuck repeating when switching windows
  164. match key {
  165. miniquad::KeyCode::LeftShift | miniquad::KeyCode::LeftSuper => continue,
  166. _ => {}
  167. }
  168. debug!(target: "main", "key_up event: {:?} {:?}", key, mods);
  169. }
  170. });
  171. async_runtime.push_task(ev_relay_task);
  172. let ev_sub = event_pub.subscribe_char();
  173. let ev_relay_task = ex.spawn(async move {
  174. debug!(target: "main", "event relayer started");
  175. loop {
  176. let Ok((key, mods, repeat)) = ev_sub.receive().await else {
  177. debug!(target: "main", "Event relayer closed");
  178. break
  179. };
  180. debug!(target: "main", "char event: {:?} {:?} {}", key, mods, repeat);
  181. }
  182. });
  183. async_runtime.push_task(ev_relay_task);
  184. */
  185. //let stage = gfx::Stage::new(method_rep, event_pub);
  186. gfx::run_gui(app, async_runtime, method_rep, event_pub);
  187. debug!(target: "main", "Started GFX backend");
  188. }
  189. /*
  190. use rustpython_vm::{self as pyvm, convert::ToPyObject};
  191. fn main() {
  192. let module = pyvm::Interpreter::without_stdlib(Default::default()).enter(|vm| {
  193. let source = r#"
  194. def foo():
  195. open("hihi", "w")
  196. return 110
  197. #max(1 + lw/3, 4*10) + foo(2, True)
  198. "#;
  199. //let code_obj = vm
  200. // .compile(source, pyvm::compiler::Mode::Exec, "<embedded>".to_owned())
  201. // .map_err(|err| vm.new_syntax_error(&err, Some(source))).unwrap();
  202. //code_obj
  203. pyvm::import::import_source(vm, "lain", source).unwrap()
  204. });
  205. fn foo(x: u32, y: bool) -> u32 {
  206. if y {
  207. 2 * x
  208. } else {
  209. x
  210. }
  211. }
  212. let res = pyvm::Interpreter::without_stdlib(Default::default()).enter(|vm| {
  213. let globals = vm.ctx.new_dict();
  214. globals.set_item("lw", vm.ctx.new_int(110).to_pyobject(vm), vm).unwrap();
  215. globals.set_item("lh", vm.ctx.new_int(4).to_pyobject(vm), vm).unwrap();
  216. globals.set_item("foo", vm.new_function("foo", foo).into(), vm).unwrap();
  217. let scope = pyvm::scope::Scope::new(None, globals);
  218. let foo_fn = module.get_attr("foo", vm).unwrap();
  219. foo_fn.call((), vm).unwrap()
  220. //vm.run_code_obj(code_obj, scope).unwrap()
  221. });
  222. println!("{:?}", res);
  223. }
  224. */