scene.rs 16 KB

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