scene.rs 14 KB

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