scene.rs 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607
  1. /* This file is part of DarkFi (https://dark.fi)
  2. *
  3. * Copyright (C) 2020-2026 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. use async_channel::{Receiver, Sender};
  19. use async_trait::async_trait;
  20. use darkfi_serial::{FutAsyncWriteExt, SerialDecodable, SerialEncodable};
  21. use futures::{stream::FuturesUnordered, StreamExt};
  22. use parking_lot::Mutex as SyncMutex;
  23. use std::{
  24. collections::{HashMap, VecDeque},
  25. fmt,
  26. future::Future,
  27. str::FromStr,
  28. sync::{Arc, OnceLock, RwLock as SyncRwLock, Weak},
  29. };
  30. #[cfg(feature = "enable-plugins")]
  31. use crate::plugin;
  32. use crate::{
  33. error::{Error, Result},
  34. prop::{Property, PropertyAtomicGuard, PropertyPtr, Role},
  35. pubsub::{Publisher, PublisherPtr, Subscription},
  36. ui,
  37. };
  38. macro_rules! t { ($($arg:tt)*) => { trace!(target: "scene", $($arg)*); } }
  39. pub struct ScenePath(VecDeque<String>);
  40. impl<S: Into<String>> From<S> for ScenePath {
  41. fn from(path: S) -> Self {
  42. let path: String = path.into();
  43. (&path).parse().expect("invalid ScenePath &str")
  44. }
  45. }
  46. impl fmt::Display for ScenePath {
  47. fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
  48. write!(f, "/")?;
  49. for token in &self.0 {
  50. write!(f, "{}/", token)?;
  51. }
  52. Ok(())
  53. }
  54. }
  55. impl FromStr for ScenePath {
  56. type Err = Error;
  57. fn from_str(s: &str) -> Result<Self> {
  58. if s.is_empty() || s.chars().nth(0).unwrap() != '/' {
  59. return Err(Error::InvalidScenePath)
  60. }
  61. if s == "/" {
  62. return Ok(ScenePath(VecDeque::new()))
  63. }
  64. let mut tokens = s.split('/');
  65. // Should start with a /
  66. let initial = tokens.next().expect("should not be empty");
  67. if !initial.is_empty() {
  68. return Err(Error::InvalidScenePath)
  69. }
  70. let mut path = VecDeque::new();
  71. for token in tokens {
  72. // There should not be any double slashes //
  73. if token.is_empty() {
  74. return Err(Error::InvalidScenePath)
  75. }
  76. path.push_back(token.to_string());
  77. }
  78. Ok(ScenePath(path))
  79. }
  80. }
  81. pub type SceneNodePtr = Arc<SceneNode>;
  82. pub type SceneNodeWeak = Weak<SceneNode>;
  83. pub type SceneNodeId = u32;
  84. #[derive(Debug, Copy, Clone, PartialEq, SerialEncodable, SerialDecodable)]
  85. #[repr(u8)]
  86. pub enum SceneNodeType {
  87. Null = 0,
  88. Root = 1,
  89. Window = 2,
  90. WindowInput = 3,
  91. Keyboard = 4,
  92. Mouse = 5,
  93. Layer = 6,
  94. Object = 7,
  95. VectorArt = 8,
  96. Text = 9,
  97. Texture = 10,
  98. Fonts = 11,
  99. Font = 12,
  100. ChatView = 13,
  101. Edit = 14,
  102. Image = 15,
  103. Button = 16,
  104. Shortcut = 17,
  105. Gesture = 18,
  106. EmojiPicker = 19,
  107. SettingRoot = 20,
  108. Setting = 21,
  109. Menu = 22,
  110. TokenTable = 23,
  111. PluginRoot = 100,
  112. Plugin = 101,
  113. }
  114. pub struct SceneNode {
  115. pub name: String,
  116. pub id: SceneNodeId,
  117. pub typ: SceneNodeType,
  118. parent: SyncRwLock<Option<Weak<Self>>>,
  119. children: SyncRwLock<Vec<SceneNodePtr>>,
  120. pub props: Vec<PropertyPtr>,
  121. pub sigs: SyncRwLock<Vec<SignalPtr>>,
  122. pub methods: Vec<Method>,
  123. pub pimpl: OnceLock<Pimpl>,
  124. tasks: SyncMutex<Vec<smol::Task<()>>>,
  125. }
  126. impl SceneNode {
  127. pub fn root() -> SceneNodePtr {
  128. Arc::new(Self::new("", SceneNodeType::Root))
  129. }
  130. pub fn new<S: Into<String>>(name: S, typ: SceneNodeType) -> Self {
  131. Self {
  132. name: name.into(),
  133. id: rand::random(),
  134. typ,
  135. parent: SyncRwLock::new(None),
  136. children: SyncRwLock::new(vec![]),
  137. props: vec![],
  138. sigs: SyncRwLock::new(vec![]),
  139. methods: vec![],
  140. pimpl: OnceLock::new(),
  141. tasks: SyncMutex::new(vec![]),
  142. }
  143. }
  144. pub async fn setup<F, Fut>(self, pimpl_fn: F) -> Arc<Self>
  145. where
  146. F: FnOnce(SceneNodeWeak) -> Fut,
  147. Fut: Future<Output = Pimpl>,
  148. {
  149. let self_ = Arc::new(self);
  150. let weak_self = Arc::downgrade(&self_);
  151. // Initial props
  152. for prop in &self_.props {
  153. prop.set_parent(weak_self.clone());
  154. }
  155. let pimpl = pimpl_fn(weak_self).await;
  156. assert_eq!(Arc::strong_count(&self_), 1);
  157. self_.pimpl.set(pimpl).unwrap();
  158. self_
  159. }
  160. pub fn setup_null(self) -> Arc<Self> {
  161. let self_ = Arc::new(self);
  162. let weak_self = Arc::downgrade(&self_);
  163. // Initial props
  164. for prop in &self_.props {
  165. prop.set_parent(weak_self.clone());
  166. }
  167. assert_eq!(Arc::strong_count(&self_), 1);
  168. self_.pimpl.set(Pimpl::Null).unwrap();
  169. self_
  170. }
  171. pub fn pimpl<'a>(&'a self) -> &'a Pimpl {
  172. self.pimpl.get().unwrap()
  173. }
  174. pub fn link(self: &Arc<Self>, child: SceneNodePtr) {
  175. let mut childs_parent = child.parent.write().unwrap();
  176. assert!(childs_parent.is_none());
  177. *childs_parent = Some(Arc::downgrade(&self));
  178. drop(childs_parent);
  179. let mut children = self.children.write().unwrap();
  180. children.push(child);
  181. }
  182. pub fn unlink(&self) {
  183. // Try to read the parent
  184. let Some(parent_weak) = self.parent.read().unwrap().clone() else { return };
  185. // Try to upgrade to an Arc
  186. let Some(parent) = parent_weak.upgrade() else { return };
  187. // Delete ourself from the parent
  188. let mut children = parent.children.write().unwrap();
  189. for i in 0..children.len() {
  190. if children[i].id == self.id {
  191. children.remove(i);
  192. return
  193. }
  194. }
  195. panic!("child not found");
  196. }
  197. pub fn get_children(&self) -> Vec<SceneNodePtr> {
  198. self.children.read().unwrap().clone()
  199. }
  200. pub fn lookup_node<P: Into<ScenePath>>(self: &Arc<Self>, path: P) -> Option<SceneNodePtr> {
  201. let path: ScenePath = path.into();
  202. let mut path = path.0;
  203. if path.is_empty() {
  204. return Some(self.clone())
  205. }
  206. let child_name = path.pop_front().unwrap();
  207. for child in self.get_children() {
  208. if child.name == child_name {
  209. let path = ScenePath(path);
  210. return child.lookup_node(path)
  211. }
  212. }
  213. None
  214. }
  215. fn has_property(&self, name: &str) -> bool {
  216. self.props.iter().any(|prop| prop.name == name)
  217. }
  218. pub fn add_property(&mut self, prop: Property) -> Result<()> {
  219. if self.has_property(&prop.name) {
  220. return Err(Error::PropertyAlreadyExists)
  221. }
  222. self.props.push(Arc::new(prop));
  223. Ok(())
  224. }
  225. pub fn get_property(&self, name: &str) -> Option<PropertyPtr> {
  226. self.props.iter().find(|prop| prop.name == name).map(|prop| prop.clone())
  227. }
  228. // Convenience methods
  229. pub fn get_property_bool(&self, name: &str) -> Result<bool> {
  230. self.get_property(name).ok_or(Error::PropertyNotFound)?.get_bool(0)
  231. }
  232. pub fn get_property_u32(&self, name: &str) -> Result<u32> {
  233. self.get_property(name).ok_or(Error::PropertyNotFound)?.get_u32(0)
  234. }
  235. pub fn get_property_f32(&self, name: &str) -> Result<f32> {
  236. self.get_property(name).ok_or(Error::PropertyNotFound)?.get_f32(0)
  237. }
  238. pub fn get_property_str(&self, name: &str) -> Result<String> {
  239. self.get_property(name).ok_or(Error::PropertyNotFound)?.get_str(0)
  240. }
  241. pub fn get_property_enum(&self, name: &str) -> Result<String> {
  242. self.get_property(name).ok_or(Error::PropertyNotFound)?.get_enum(0)
  243. }
  244. pub fn get_property_node_id(&self, name: &str) -> Result<SceneNodeId> {
  245. self.get_property(name).ok_or(Error::PropertyNotFound)?.get_node_id(0)
  246. }
  247. // Setters
  248. pub fn set_property_bool(
  249. &self,
  250. atom: &mut PropertyAtomicGuard,
  251. role: Role,
  252. name: &str,
  253. val: bool,
  254. ) -> Result<()> {
  255. self.get_property(name).ok_or(Error::PropertyNotFound)?.set_bool(atom, role, 0, val)
  256. }
  257. pub fn set_property_u32(
  258. &self,
  259. atom: &mut PropertyAtomicGuard,
  260. role: Role,
  261. name: &str,
  262. val: u32,
  263. ) -> Result<()> {
  264. self.get_property(name).ok_or(Error::PropertyNotFound)?.set_u32(atom, role, 0, val)
  265. }
  266. pub fn set_property_f32(
  267. &self,
  268. atom: &mut PropertyAtomicGuard,
  269. role: Role,
  270. name: &str,
  271. val: f32,
  272. ) -> Result<()> {
  273. self.get_property(name).ok_or(Error::PropertyNotFound)?.set_f32(atom, role, 0, val)
  274. }
  275. pub fn set_property_str<S: Into<String>>(
  276. &self,
  277. atom: &mut PropertyAtomicGuard,
  278. role: Role,
  279. name: &str,
  280. val: S,
  281. ) -> Result<()> {
  282. self.get_property(name).ok_or(Error::PropertyNotFound)?.set_str(atom, role, 0, val)
  283. }
  284. pub fn set_property_enum<S: Into<String>>(
  285. &self,
  286. atom: &mut PropertyAtomicGuard,
  287. role: Role,
  288. name: &str,
  289. val: S,
  290. ) -> Result<()> {
  291. self.get_property(name).ok_or(Error::PropertyNotFound)?.set_enum(atom, role, 0, val)
  292. }
  293. pub fn set_property_node_id(
  294. &self,
  295. atom: &mut PropertyAtomicGuard,
  296. role: Role,
  297. name: &str,
  298. val: SceneNodeId,
  299. ) -> Result<()> {
  300. self.get_property(name).ok_or(Error::PropertyNotFound)?.set_node_id(atom, role, 0, val)
  301. }
  302. pub fn set_property_f32_vec(
  303. &self,
  304. atom: &mut PropertyAtomicGuard,
  305. role: Role,
  306. name: &str,
  307. val: Vec<f32>,
  308. ) -> Result<()> {
  309. self.get_property(name).ok_or(Error::PropertyNotFound)?.set_f32_vec(atom, role, val)
  310. }
  311. pub fn add_signal<S: Into<String>>(
  312. &mut self,
  313. name: S,
  314. desc: S,
  315. fmt: Vec<(S, S, CallArgType)>,
  316. ) -> Result<()> {
  317. let name = name.into();
  318. if self.has_signal(&name) {
  319. return Err(Error::SignalAlreadyExists)
  320. }
  321. let fmt = fmt
  322. .into_iter()
  323. .map(|(n, d, t)| CallArg { name: n.into(), desc: d.into(), typ: t })
  324. .collect();
  325. let mut sigs = self.sigs.write().unwrap();
  326. sigs.push(Arc::new(Signal {
  327. name: name.into(),
  328. desc: desc.into(),
  329. fmt,
  330. slots: SyncRwLock::new(HashMap::new()),
  331. }));
  332. Ok(())
  333. }
  334. fn has_signal(&self, name: &str) -> bool {
  335. let sigs = self.sigs.read().unwrap();
  336. sigs.iter().any(|sig| sig.name == name)
  337. }
  338. pub fn get_signal(&self, name: &str) -> Option<SignalPtr> {
  339. let sigs = self.sigs.read().unwrap();
  340. sigs.iter().find(|sig| sig.name == name).cloned()
  341. }
  342. pub fn register(&self, sig_name: &str, slot: Slot) -> Result<SlotId> {
  343. let slot_id = rand::random();
  344. let sig = self.get_signal(sig_name).ok_or(Error::SignalNotFound)?;
  345. let mut slots = sig.slots.write().unwrap();
  346. slots.insert(slot_id, slot);
  347. Ok(slot_id)
  348. }
  349. pub fn unregister(&self, sig_name: &str, slot_id: SlotId) -> Result<()> {
  350. let sig = self.get_signal(sig_name).ok_or(Error::SignalNotFound)?;
  351. let mut slots = sig.slots.write().unwrap();
  352. slots.remove(&slot_id).ok_or(Error::SlotNotFound)?;
  353. Ok(())
  354. }
  355. pub async fn trigger(&self, sig_name: &str, data: Vec<u8>) -> Result<()> {
  356. t!("trigger({sig_name}, {data:?}) [node={self:?}]");
  357. let sig = self.get_signal(sig_name).ok_or(Error::SignalNotFound)?;
  358. let futures = FuturesUnordered::new();
  359. let slots: Vec<_> = sig.slots.read().unwrap().values().cloned().collect();
  360. // TODO: autoremove failed slots
  361. for slot in slots {
  362. t!(" triggering {}", slot.name);
  363. // Trigger the slot
  364. let data = data.clone();
  365. futures.push(async move { slot.notify.send(data).await.is_ok() });
  366. }
  367. let success: Vec<_> = futures.collect().await;
  368. t!("trigger success: {success:?}");
  369. Ok(())
  370. }
  371. pub fn add_method<S: Into<String>>(
  372. &mut self,
  373. name: S,
  374. args: Vec<(S, S, CallArgType)>,
  375. result: Option<Vec<(S, S, CallArgType)>>,
  376. ) -> Result<()> {
  377. let name = name.into();
  378. if self.has_method(&name) {
  379. return Err(Error::MethodAlreadyExists)
  380. }
  381. let args = args
  382. .into_iter()
  383. .map(|(n, d, t)| CallArg { name: n.into(), desc: d.into(), typ: t })
  384. .collect();
  385. let result = match result {
  386. Some(result) => Some(
  387. result
  388. .into_iter()
  389. .map(|(n, d, t)| CallArg { name: n.into(), desc: d.into(), typ: t })
  390. .collect(),
  391. ),
  392. None => None,
  393. };
  394. self.methods.push(Method::new(name.into(), args, result));
  395. Ok(())
  396. }
  397. fn has_method(&self, name: &str) -> bool {
  398. self.methods.iter().any(|sig| sig.name == name)
  399. }
  400. pub fn get_method(&self, name: &str) -> Option<&Method> {
  401. self.methods.iter().find(|method| method.name == name)
  402. }
  403. pub async fn call_method(&self, name: &str, arg_data: CallData) -> Result<Option<CallData>> {
  404. let method = self.get_method(name).ok_or(Error::MethodNotFound)?;
  405. Ok(method.call(arg_data).await)
  406. }
  407. pub fn subscribe_method_call(&self, name: &str) -> Result<MethodCallSub> {
  408. let method = self.get_method(name).ok_or(Error::MethodNotFound)?;
  409. let method_sub = method.pubsub.clone().subscribe();
  410. Ok(method_sub)
  411. }
  412. pub fn get_full_path(&self) -> Option<String> {
  413. let subpath = "/".to_string() + &self.name;
  414. let Some(parent_weak) = self.parent.read().unwrap().clone() else { return Some(subpath) };
  415. let Some(parent) = parent_weak.upgrade() else { return None };
  416. // Handle root /
  417. if parent.typ == SceneNodeType::Root {
  418. return Some(subpath)
  419. }
  420. Some(parent.get_full_path()? + &subpath)
  421. }
  422. pub fn push_task(&self, task: smol::Task<()>) {
  423. self.tasks.lock().push(task);
  424. }
  425. pub fn clear_tasks(&self) {
  426. self.tasks.lock().clear();
  427. }
  428. }
  429. impl std::fmt::Debug for SceneNode {
  430. fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
  431. if let Some(path) = self.get_full_path() {
  432. write!(f, "{path}")
  433. } else {
  434. write!(f, "{}:{}", self.name, self.id)
  435. }
  436. }
  437. }
  438. impl Drop for SceneNode {
  439. fn drop(&mut self) {
  440. println!("Drop {}:{}", self.name, self.id);
  441. }
  442. }
  443. #[derive(Debug, Clone, SerialEncodable, SerialDecodable)]
  444. pub enum CallArgType {
  445. Uint32,
  446. Uint64,
  447. Float32,
  448. Bool,
  449. Str,
  450. Hash,
  451. }
  452. #[derive(Debug, Clone, SerialEncodable, SerialDecodable)]
  453. pub struct CallArg {
  454. pub name: String,
  455. pub desc: String,
  456. pub typ: CallArgType,
  457. }
  458. pub type CallData = Vec<u8>;
  459. pub type SlotId = u32;
  460. #[derive(Clone)]
  461. pub struct Slot {
  462. pub name: String,
  463. pub notify: Sender<CallData>,
  464. }
  465. impl Slot {
  466. pub fn new<S: Into<String>>(name: S) -> (Self, Receiver<CallData>) {
  467. let (notify, recvr) = async_channel::unbounded();
  468. let self_ = Self { name: name.into(), notify };
  469. (self_, recvr)
  470. }
  471. }
  472. type SignalPtr = Arc<Signal>;
  473. pub struct Signal {
  474. pub name: String,
  475. #[allow(dead_code)]
  476. pub desc: String,
  477. #[allow(dead_code)]
  478. pub fmt: Vec<CallArg>,
  479. slots: SyncRwLock<HashMap<SlotId, Slot>>,
  480. }
  481. #[derive(Clone, Debug)]
  482. pub struct MethodCall {
  483. pub data: CallData,
  484. pub send_res: Option<Sender<CallData>>,
  485. }
  486. impl MethodCall {
  487. fn new(data: CallData, send_res: Option<Sender<CallData>>) -> Self {
  488. Self { data, send_res }
  489. }
  490. }
  491. pub type MethodCallSub = Subscription<MethodCall>;
  492. pub struct Method {
  493. pub name: String,
  494. pub args: Vec<CallArg>,
  495. pub result: Option<Vec<CallArg>>,
  496. pub pubsub: PublisherPtr<MethodCall>,
  497. }
  498. impl Method {
  499. fn new(name: String, args: Vec<CallArg>, result: Option<Vec<CallArg>>) -> Self {
  500. Self { name, args, result, pubsub: Publisher::new() }
  501. }
  502. async fn call(&self, data: CallData) -> Option<CallData> {
  503. match &self.result {
  504. Some(_) => {
  505. let (send_res, recv_res) = async_channel::bounded(1);
  506. self.pubsub.notify(MethodCall::new(data, Some(send_res)));
  507. Some(recv_res.recv().await.unwrap())
  508. }
  509. None => {
  510. self.pubsub.notify(MethodCall::new(data, None));
  511. None
  512. }
  513. }
  514. }
  515. }
  516. pub enum Pimpl {
  517. Null,
  518. Window(ui::WindowPtr),
  519. Layer(ui::LayerPtr),
  520. ScrollLayer(ui::ScrollLayerPtr),
  521. VectorArt(ui::VectorArtPtr),
  522. Text(ui::TextPtr),
  523. Edit(ui::BaseEditPtr),
  524. ChatView(ui::ChatViewPtr),
  525. Image(ui::ImagePtr),
  526. Video(ui::VideoPtr),
  527. Button(ui::ButtonPtr),
  528. Shortcut(ui::ShortcutPtr),
  529. Gesture(ui::GesturePtr),
  530. EmojiPicker(ui::EmojiPickerPtr),
  531. Menu(ui::MenuPtr),
  532. TokenTable(ui::TokenTablePtr),
  533. #[cfg(feature = "enable-plugins")]
  534. DarkIrc(plugin::DarkIrcPtr),
  535. #[cfg(feature = "enable-plugins")]
  536. Fud(plugin::FudPtr),
  537. #[cfg(feature = "enable-plugins")]
  538. Drk(plugin::DrkPtr),
  539. }
  540. impl std::fmt::Debug for Pimpl {
  541. fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
  542. write!(f, "Pimpl")
  543. }
  544. }