scene.rs 16 KB

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