mod.rs 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971
  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 crate::error::{Error, Result};
  19. use darkfi_serial::{async_trait, Encodable, FutAsyncWriteExt, SerialDecodable, SerialEncodable};
  20. use std::{
  21. io::Write,
  22. sync::{Arc, Mutex as SyncMutex, Weak},
  23. };
  24. use crate::{
  25. expr::SExprCode,
  26. pubsub::{Publisher, PublisherPtr, Subscription},
  27. scene::{SceneNodeId, SceneNodeWeak},
  28. };
  29. mod guard;
  30. pub use guard::{BatchGuardId, BatchGuardPtr, PropertyAtomicGuard};
  31. mod wrap;
  32. pub use wrap::{
  33. PropertyBool, PropertyColor, PropertyDimension, PropertyFloat32, PropertyRect, PropertyStr,
  34. PropertyUint32,
  35. };
  36. #[derive(Debug, Copy, Clone, PartialEq, SerialEncodable, SerialDecodable)]
  37. #[repr(u8)]
  38. pub enum PropertyType {
  39. Null = 0,
  40. Bool = 1,
  41. Uint32 = 2,
  42. Float32 = 3,
  43. Str = 4,
  44. Enum = 5,
  45. SceneNodeId = 7,
  46. SExpr = 8,
  47. }
  48. impl PropertyType {
  49. fn default_value(&self) -> PropertyValue {
  50. match self {
  51. Self::Null => PropertyValue::Null,
  52. Self::Bool => PropertyValue::Bool(false),
  53. Self::Uint32 => PropertyValue::Uint32(0),
  54. Self::Float32 => PropertyValue::Float32(0.),
  55. Self::Str => PropertyValue::Str(String::new()),
  56. Self::Enum => PropertyValue::Enum(String::new()),
  57. Self::SceneNodeId => PropertyValue::SceneNodeId(0),
  58. Self::SExpr => PropertyValue::SExpr(Arc::new(vec![])),
  59. }
  60. }
  61. }
  62. #[derive(Debug, Copy, Clone, PartialEq, SerialEncodable, SerialDecodable)]
  63. #[repr(u8)]
  64. pub enum PropertySubType {
  65. Null = 0,
  66. Color = 1,
  67. // Size of something in pixels
  68. Pixel = 2,
  69. ResourceId = 3,
  70. Locale = 4,
  71. }
  72. #[derive(Debug, Copy, Clone, PartialEq)]
  73. pub enum Role {
  74. User = 0,
  75. App = 1,
  76. Internal = 2,
  77. Ignored = 3,
  78. }
  79. #[derive(Debug, Clone, PartialEq)]
  80. pub enum PropertyValue {
  81. Unset,
  82. Null,
  83. Bool(bool),
  84. Uint32(u32),
  85. Float32(f32),
  86. Str(String),
  87. Enum(String),
  88. SceneNodeId(SceneNodeId),
  89. SExpr(Arc<SExprCode>),
  90. }
  91. impl PropertyValue {
  92. fn as_type(&self) -> PropertyType {
  93. match self {
  94. Self::Unset => todo!("not sure"),
  95. Self::Null => PropertyType::Null,
  96. Self::Bool(_) => PropertyType::Bool,
  97. Self::Uint32(_) => PropertyType::Uint32,
  98. Self::Float32(_) => PropertyType::Float32,
  99. Self::Str(_) => PropertyType::Str,
  100. Self::Enum(_) => PropertyType::Enum,
  101. Self::SceneNodeId(_) => PropertyType::SceneNodeId,
  102. Self::SExpr(_) => PropertyType::SExpr,
  103. }
  104. }
  105. pub fn is_unset(&self) -> bool {
  106. match self {
  107. Self::Unset => true,
  108. _ => false,
  109. }
  110. }
  111. pub fn is_null(&self) -> bool {
  112. match self {
  113. Self::Null => true,
  114. _ => false,
  115. }
  116. }
  117. pub fn is_expr(&self) -> bool {
  118. match self {
  119. Self::SExpr(_) => true,
  120. _ => false,
  121. }
  122. }
  123. pub fn as_bool(&self) -> Result<bool> {
  124. match self {
  125. Self::Bool(v) => Ok(*v),
  126. _ => Err(Error::PropertyWrongType),
  127. }
  128. }
  129. pub fn as_u32(&self) -> Result<u32> {
  130. match self {
  131. Self::Uint32(v) => Ok(*v),
  132. _ => Err(Error::PropertyWrongType),
  133. }
  134. }
  135. pub fn as_f32(&self) -> Result<f32> {
  136. match self {
  137. Self::Float32(v) => Ok(*v),
  138. _ => Err(Error::PropertyWrongType),
  139. }
  140. }
  141. pub fn as_str(&self) -> Result<String> {
  142. match self {
  143. Self::Str(v) => Ok(v.clone()),
  144. _ => Err(Error::PropertyWrongType),
  145. }
  146. }
  147. pub fn as_enum(&self) -> Result<String> {
  148. match self {
  149. Self::Enum(v) => Ok(v.clone()),
  150. _ => Err(Error::PropertyWrongType),
  151. }
  152. }
  153. pub fn as_node_id(&self) -> Result<SceneNodeId> {
  154. match self {
  155. Self::SceneNodeId(v) => Ok(*v),
  156. _ => Err(Error::PropertyWrongType),
  157. }
  158. }
  159. pub fn as_sexpr(&self) -> Result<Arc<SExprCode>> {
  160. match self {
  161. Self::SExpr(v) => Ok(v.clone()),
  162. _ => Err(Error::PropertyWrongType),
  163. }
  164. }
  165. }
  166. impl Encodable for PropertyValue {
  167. fn encode<S: Write>(&self, s: &mut S) -> std::result::Result<usize, std::io::Error> {
  168. match self {
  169. Self::Unset | Self::Null => {
  170. // do nothing
  171. Ok(0)
  172. }
  173. Self::Bool(v) => v.encode(s),
  174. Self::Uint32(v) => v.encode(s),
  175. Self::Float32(v) => v.encode(s),
  176. Self::Str(v) => v.encode(s),
  177. Self::Enum(v) => v.encode(s),
  178. Self::SceneNodeId(v) => v.encode(s),
  179. Self::SExpr(v) => v.encode(s),
  180. }
  181. }
  182. }
  183. #[derive(Debug, Clone)]
  184. pub enum ModifyAction {
  185. Clear,
  186. Set(usize),
  187. SetCache(Vec<usize>),
  188. Push(usize),
  189. }
  190. type ModifyPublisher = PublisherPtr<(Role, ModifyAction, BatchGuardPtr)>;
  191. pub type PropertyPtr = Arc<Property>;
  192. pub type PropertyWeak = Weak<Property>;
  193. #[derive(Debug, Clone)]
  194. pub struct PropertyDepend {
  195. pub prop: PropertyWeak,
  196. pub i: usize,
  197. pub local_name: String,
  198. }
  199. pub struct Property {
  200. pub name: String,
  201. pub node: SyncMutex<Option<SceneNodeWeak>>,
  202. pub typ: PropertyType,
  203. pub subtype: PropertySubType,
  204. pub defaults: Vec<PropertyValue>,
  205. // either a value or an expr must be set
  206. pub vals: SyncMutex<Vec<PropertyValue>>,
  207. // only used valid when PropertyValue is an expr
  208. // caches the last calculated value
  209. pub cache: SyncMutex<Vec<PropertyValue>>,
  210. pub ui_name: String,
  211. pub desc: String,
  212. pub is_null_allowed: bool,
  213. pub is_expr_allowed: bool,
  214. // Use 0 for unbounded length
  215. pub array_len: usize,
  216. pub min_val: Option<PropertyValue>,
  217. pub max_val: Option<PropertyValue>,
  218. // PropertyType must be Enum
  219. pub enum_items: Option<Vec<String>>,
  220. on_modify: ModifyPublisher,
  221. depends: SyncMutex<Vec<PropertyDepend>>,
  222. }
  223. impl Property {
  224. pub fn new<S: Into<String>>(name: S, typ: PropertyType, subtype: PropertySubType) -> Self {
  225. Self {
  226. name: name.into(),
  227. node: SyncMutex::new(None),
  228. typ,
  229. subtype,
  230. defaults: vec![typ.default_value()],
  231. vals: SyncMutex::new(vec![PropertyValue::Unset]),
  232. cache: SyncMutex::new(vec![PropertyValue::Null]),
  233. ui_name: String::new(),
  234. desc: String::new(),
  235. is_null_allowed: false,
  236. is_expr_allowed: false,
  237. array_len: 1,
  238. min_val: None,
  239. max_val: None,
  240. enum_items: None,
  241. on_modify: Publisher::new(),
  242. depends: SyncMutex::new(vec![]),
  243. }
  244. }
  245. /// Just used for debugging
  246. pub fn set_parent(&self, node: SceneNodeWeak) {
  247. *self.node.lock().unwrap() = Some(node);
  248. }
  249. pub fn set_ui_text<S: Into<String>>(&mut self, ui_name: S, desc: S) {
  250. self.ui_name = ui_name.into();
  251. self.desc = desc.into();
  252. }
  253. pub fn set_array_len(&mut self, len: usize) {
  254. self.array_len = len;
  255. self.defaults.resize(len, self.typ.default_value());
  256. self.defaults.shrink_to_fit();
  257. let vals = &mut *self.vals.lock().unwrap();
  258. vals.resize(len, PropertyValue::Unset);
  259. vals.shrink_to_fit();
  260. let cache = &mut *self.cache.lock().unwrap();
  261. cache.resize(len, PropertyValue::Null);
  262. cache.shrink_to_fit();
  263. }
  264. pub fn set_unbounded(&mut self) {
  265. self.set_array_len(0);
  266. }
  267. pub fn set_range_u32(&mut self, min: u32, max: u32) {
  268. self.min_val = Some(PropertyValue::Uint32(min));
  269. self.max_val = Some(PropertyValue::Uint32(max));
  270. }
  271. pub fn set_range_f32(&mut self, min: f32, max: f32) {
  272. self.min_val = Some(PropertyValue::Float32(min));
  273. self.max_val = Some(PropertyValue::Float32(max));
  274. }
  275. pub fn set_enum_items<S: Into<String>>(&mut self, enum_items: Vec<S>) -> Result<()> {
  276. if self.typ != PropertyType::Enum {
  277. return Err(Error::PropertyWrongType)
  278. }
  279. self.enum_items = Some(enum_items.into_iter().map(|item| item.into()).collect());
  280. Ok(())
  281. }
  282. pub fn allow_null_values(&mut self) {
  283. self.is_null_allowed = true;
  284. }
  285. pub fn allow_exprs(&mut self) {
  286. self.is_expr_allowed = true;
  287. }
  288. fn check_defaults_len(&self, defaults_len: usize) -> Result<()> {
  289. if !self.is_bounded() || defaults_len != self.array_len {
  290. return Err(Error::PropertyWrongLen)
  291. }
  292. Ok(())
  293. }
  294. pub fn set_defaults_bool(&mut self, defaults: Vec<bool>) -> Result<()> {
  295. self.check_defaults_len(defaults.len())?;
  296. self.defaults = defaults.into_iter().map(|v| PropertyValue::Bool(v)).collect();
  297. Ok(())
  298. }
  299. pub fn set_defaults_u32(&mut self, defaults: Vec<u32>) -> Result<()> {
  300. self.check_defaults_len(defaults.len())?;
  301. self.defaults = defaults.into_iter().map(|v| PropertyValue::Uint32(v)).collect();
  302. Ok(())
  303. }
  304. pub fn set_defaults_f32(&mut self, defaults: Vec<f32>) -> Result<()> {
  305. self.check_defaults_len(defaults.len())?;
  306. self.defaults = defaults.into_iter().map(|v| PropertyValue::Float32(v)).collect();
  307. Ok(())
  308. }
  309. pub fn set_defaults_str(&mut self, defaults: Vec<String>) -> Result<()> {
  310. self.check_defaults_len(defaults.len())?;
  311. self.defaults = defaults.into_iter().map(|v| PropertyValue::Str(v)).collect();
  312. Ok(())
  313. }
  314. pub fn set_defaults_null(&mut self) -> Result<()> {
  315. if !self.is_null_allowed {
  316. return Err(Error::PropertyNullNotAllowed)
  317. }
  318. if !self.is_bounded() {
  319. return Err(Error::PropertyWrongLen)
  320. }
  321. self.defaults = (0..self.array_len).map(|_| PropertyValue::Null).collect();
  322. Ok(())
  323. }
  324. // Set
  325. /// This will clear all values, resetting them to the default
  326. pub fn clear_values(self: &Arc<Self>, atom: &mut PropertyAtomicGuard, role: Role) {
  327. {
  328. let vals = &mut self.vals.lock().unwrap();
  329. vals.clear();
  330. vals.resize(self.array_len, PropertyValue::Unset);
  331. }
  332. atom.add(self.clone(), role, ModifyAction::Clear);
  333. }
  334. fn set_raw_value(&self, i: usize, val: PropertyValue) -> Result<()> {
  335. if self.typ != val.as_type() {
  336. return Err(Error::PropertyWrongType)
  337. }
  338. let vals = &mut self.vals.lock().unwrap();
  339. if i >= vals.len() {
  340. return Err(Error::PropertyWrongIndex)
  341. }
  342. vals[i] = val;
  343. Ok(())
  344. }
  345. pub fn unset(
  346. self: &Arc<Self>,
  347. atom: &mut PropertyAtomicGuard,
  348. role: Role,
  349. i: usize,
  350. ) -> Result<()> {
  351. {
  352. let vals = &mut self.vals.lock().unwrap();
  353. if i >= vals.len() {
  354. return Err(Error::PropertyWrongIndex)
  355. }
  356. vals[i] = PropertyValue::Unset;
  357. }
  358. atom.add(self.clone(), role, ModifyAction::Set(i));
  359. Ok(())
  360. }
  361. pub fn set_null(
  362. self: &Arc<Self>,
  363. atom: &mut PropertyAtomicGuard,
  364. role: Role,
  365. i: usize,
  366. ) -> Result<()> {
  367. if !self.is_null_allowed {
  368. return Err(Error::PropertyNullNotAllowed)
  369. }
  370. let mut vals = self.vals.lock().unwrap();
  371. if i >= vals.len() {
  372. return Err(Error::PropertyWrongIndex)
  373. }
  374. vals[i] = PropertyValue::Null;
  375. drop(vals);
  376. atom.add(self.clone(), role, ModifyAction::Set(i));
  377. Ok(())
  378. }
  379. pub fn set_bool(
  380. self: &Arc<Self>,
  381. atom: &mut PropertyAtomicGuard,
  382. role: Role,
  383. i: usize,
  384. val: bool,
  385. ) -> Result<()> {
  386. self.set_raw_value(i, PropertyValue::Bool(val))?;
  387. atom.add(self.clone(), role, ModifyAction::Set(i));
  388. Ok(())
  389. }
  390. pub fn set_u32(
  391. self: &Arc<Self>,
  392. atom: &mut PropertyAtomicGuard,
  393. role: Role,
  394. i: usize,
  395. val: u32,
  396. ) -> Result<()> {
  397. if self.min_val.is_some() {
  398. let min = self.min_val.as_ref().unwrap().as_u32()?;
  399. if val < min {
  400. return Err(Error::PropertyOutOfRange)
  401. }
  402. }
  403. if self.max_val.is_some() {
  404. let max = self.max_val.as_ref().unwrap().as_u32()?;
  405. if val > max {
  406. return Err(Error::PropertyOutOfRange)
  407. }
  408. }
  409. self.set_raw_value(i, PropertyValue::Uint32(val))?;
  410. atom.add(self.clone(), role, ModifyAction::Set(i));
  411. Ok(())
  412. }
  413. pub fn set_f32(
  414. self: &Arc<Self>,
  415. atom: &mut PropertyAtomicGuard,
  416. role: Role,
  417. i: usize,
  418. val: f32,
  419. ) -> Result<()> {
  420. if self.min_val.is_some() {
  421. let min = self.min_val.as_ref().unwrap().as_f32()?;
  422. if val < min {
  423. return Err(Error::PropertyOutOfRange)
  424. }
  425. }
  426. if self.max_val.is_some() {
  427. let max = self.max_val.as_ref().unwrap().as_f32()?;
  428. if val > max {
  429. return Err(Error::PropertyOutOfRange)
  430. }
  431. }
  432. self.set_raw_value(i, PropertyValue::Float32(val))?;
  433. atom.add(self.clone(), role, ModifyAction::Set(i));
  434. Ok(())
  435. }
  436. pub fn set_str<S: Into<String>>(
  437. self: &Arc<Self>,
  438. atom: &mut PropertyAtomicGuard,
  439. role: Role,
  440. i: usize,
  441. val: S,
  442. ) -> Result<()> {
  443. self.set_raw_value(i, PropertyValue::Str(val.into()))?;
  444. atom.add(self.clone(), role, ModifyAction::Set(i));
  445. Ok(())
  446. }
  447. pub fn set_enum<S: Into<String>>(
  448. self: &Arc<Self>,
  449. atom: &mut PropertyAtomicGuard,
  450. role: Role,
  451. i: usize,
  452. val: S,
  453. ) -> Result<()> {
  454. if self.typ != PropertyType::Enum {
  455. return Err(Error::PropertyWrongType)
  456. }
  457. let val = val.into();
  458. if !self.enum_items.as_ref().unwrap().contains(&val) {
  459. return Err(Error::PropertyWrongEnumItem)
  460. }
  461. self.set_raw_value(i, PropertyValue::Enum(val.into()))?;
  462. atom.add(self.clone(), role, ModifyAction::Set(i));
  463. Ok(())
  464. }
  465. pub fn set_node_id(
  466. self: &Arc<Self>,
  467. atom: &mut PropertyAtomicGuard,
  468. role: Role,
  469. i: usize,
  470. val: SceneNodeId,
  471. ) -> Result<()> {
  472. self.set_raw_value(i, PropertyValue::SceneNodeId(val))?;
  473. atom.add(self.clone(), role, ModifyAction::Set(i));
  474. Ok(())
  475. }
  476. pub fn set_expr(
  477. self: &Arc<Self>,
  478. atom: &mut PropertyAtomicGuard,
  479. role: Role,
  480. i: usize,
  481. val: SExprCode,
  482. ) -> Result<()> {
  483. {
  484. if !self.is_expr_allowed {
  485. return Err(Error::PropertySExprNotAllowed)
  486. }
  487. let vals = &mut self.vals.lock().unwrap();
  488. if i >= vals.len() {
  489. return Err(Error::PropertyWrongIndex)
  490. }
  491. vals[i] = PropertyValue::SExpr(Arc::new(val));
  492. }
  493. atom.add(self.clone(), role, ModifyAction::Set(i));
  494. Ok(())
  495. }
  496. pub fn set_f32_vec(
  497. self: &Arc<Self>,
  498. atom: &mut PropertyAtomicGuard,
  499. role: Role,
  500. val: Vec<f32>,
  501. ) -> Result<()> {
  502. for (i, &val) in val.iter().enumerate() {
  503. self.clone().set_f32(atom, role, i, val)?;
  504. }
  505. Ok(())
  506. }
  507. fn set_cache(&self, i: usize, val: PropertyValue) -> Result<()> {
  508. if self.typ != val.as_type() {
  509. return Err(Error::PropertyWrongType)
  510. }
  511. let cache = &mut self.cache.lock().unwrap();
  512. if i >= cache.len() {
  513. return Err(Error::PropertyWrongIndex)
  514. }
  515. cache[i] = val;
  516. Ok(())
  517. }
  518. pub fn set_cache_f32(
  519. self: &Arc<Self>,
  520. atom: &mut PropertyAtomicGuard,
  521. role: Role,
  522. i: usize,
  523. val: f32,
  524. ) -> Result<()> {
  525. self.set_cache(i, PropertyValue::Float32(val))?;
  526. atom.add(self.clone(), role, ModifyAction::SetCache(vec![i]));
  527. Ok(())
  528. }
  529. pub fn set_cache_u32(
  530. self: &Arc<Self>,
  531. atom: &mut PropertyAtomicGuard,
  532. role: Role,
  533. i: usize,
  534. val: u32,
  535. ) -> Result<()> {
  536. self.set_cache(i, PropertyValue::Uint32(val))?;
  537. atom.add(self.clone(), role, ModifyAction::SetCache(vec![i]));
  538. Ok(())
  539. }
  540. pub fn set_cache_f32_multi(
  541. self: &Arc<Self>,
  542. atom: &mut PropertyAtomicGuard,
  543. role: Role,
  544. changes: Vec<(usize, f32)>,
  545. ) -> Result<()> {
  546. let mut idxs = vec![];
  547. for (idx, val) in changes {
  548. self.set_cache(idx, PropertyValue::Float32(val))?;
  549. idxs.push(idx);
  550. }
  551. atom.add(self.clone(), role, ModifyAction::SetCache(idxs));
  552. Ok(())
  553. }
  554. pub fn set_cache_u32_range(
  555. self: &Arc<Self>,
  556. atom: &mut PropertyAtomicGuard,
  557. role: Role,
  558. changes: Vec<(usize, u32)>,
  559. ) -> Result<()> {
  560. let mut idxs = vec![];
  561. for (idx, val) in changes {
  562. self.set_cache(idx, PropertyValue::Uint32(val))?;
  563. idxs.push(idx);
  564. }
  565. atom.add(self.clone(), role, ModifyAction::SetCache(idxs));
  566. Ok(())
  567. }
  568. // Push
  569. fn push_value(
  570. self: &Arc<Self>,
  571. atom: &mut PropertyAtomicGuard,
  572. role: Role,
  573. value: PropertyValue,
  574. ) -> Result<usize> {
  575. if self.is_bounded() {
  576. return Err(Error::PropertyIsBounded)
  577. }
  578. let mut vals = self.vals.lock().unwrap();
  579. let i = vals.len();
  580. vals.push(value);
  581. drop(vals);
  582. atom.add(self.clone(), role, ModifyAction::Push(i));
  583. Ok(i)
  584. }
  585. pub fn push_null(
  586. self: &Arc<Self>,
  587. atom: &mut PropertyAtomicGuard,
  588. role: Role,
  589. ) -> Result<usize> {
  590. self.push_value(atom, role, PropertyValue::Null)
  591. }
  592. pub fn push_bool(
  593. self: &Arc<Self>,
  594. atom: &mut PropertyAtomicGuard,
  595. role: Role,
  596. val: bool,
  597. ) -> Result<usize> {
  598. self.push_value(atom, role, PropertyValue::Bool(val))
  599. }
  600. pub fn push_u32(
  601. self: &Arc<Self>,
  602. atom: &mut PropertyAtomicGuard,
  603. role: Role,
  604. val: u32,
  605. ) -> Result<usize> {
  606. // TODO: none of these push calls are enforcing constraints that are required
  607. // see the set_XX calls.
  608. self.push_value(atom, role, PropertyValue::Uint32(val))
  609. }
  610. pub fn push_f32(
  611. self: &Arc<Self>,
  612. atom: &mut PropertyAtomicGuard,
  613. role: Role,
  614. val: f32,
  615. ) -> Result<usize> {
  616. self.push_value(atom, role, PropertyValue::Float32(val))
  617. }
  618. pub fn push_str<S: Into<String>>(
  619. self: &Arc<Self>,
  620. atom: &mut PropertyAtomicGuard,
  621. role: Role,
  622. val: S,
  623. ) -> Result<usize> {
  624. self.push_value(atom, role, PropertyValue::Str(val.into()))
  625. }
  626. pub fn push_enum<S: Into<String>>(
  627. self: &Arc<Self>,
  628. atom: &mut PropertyAtomicGuard,
  629. role: Role,
  630. val: S,
  631. ) -> Result<usize> {
  632. self.push_value(atom, role, PropertyValue::Enum(val.into()))
  633. }
  634. pub fn push_node_id(
  635. self: &Arc<Self>,
  636. atom: &mut PropertyAtomicGuard,
  637. role: Role,
  638. val: SceneNodeId,
  639. ) -> Result<usize> {
  640. self.push_value(atom, role, PropertyValue::SceneNodeId(val))
  641. }
  642. // Get
  643. pub fn is_bounded(&self) -> bool {
  644. self.array_len != 0
  645. }
  646. pub fn get_len(&self) -> usize {
  647. // Avoid locking unless we need to
  648. // If array len is nonzero, then vals len should be the same.
  649. if !self.is_bounded() {
  650. return self.vals.lock().unwrap().len()
  651. }
  652. self.array_len
  653. }
  654. pub fn is_unset(&self, i: usize) -> Result<bool> {
  655. let val = self.get_raw_value(i)?;
  656. Ok(val.is_unset())
  657. }
  658. pub fn is_null(&self, i: usize) -> Result<bool> {
  659. let val = self.get_value(i)?;
  660. if val.is_unset() {
  661. return Ok(self.defaults[i].is_null())
  662. }
  663. Ok(val.is_null())
  664. }
  665. pub fn is_expr(&self, i: usize) -> Result<bool> {
  666. if !self.is_expr_allowed {
  667. return Ok(false)
  668. }
  669. let val = self.get_raw_value(i)?;
  670. Ok(val.is_expr())
  671. }
  672. pub fn get_raw_value(&self, i: usize) -> Result<PropertyValue> {
  673. let vals = &self.vals.lock().unwrap();
  674. if self.is_bounded() {
  675. assert_eq!(vals.len(), self.array_len);
  676. }
  677. if i >= vals.len() {
  678. return Err(Error::PropertyWrongIndex)
  679. }
  680. let val = vals[i].clone();
  681. Ok(val)
  682. }
  683. pub fn get_value(&self, i: usize) -> Result<PropertyValue> {
  684. let val = self.get_raw_value(i)?;
  685. if val.is_expr() {
  686. let cached = self.get_cached(i)?;
  687. if cached.is_null() {
  688. return Ok(self.defaults[i].clone())
  689. }
  690. return Ok(cached)
  691. }
  692. if val.is_unset() {
  693. return Ok(self.defaults[i].clone())
  694. }
  695. Ok(val)
  696. }
  697. pub fn get_bool(&self, i: usize) -> Result<bool> {
  698. self.get_value(i)?.as_bool()
  699. }
  700. pub fn get_bool_opt(&self, i: usize) -> Result<Option<bool>> {
  701. let val = self.get_value(i)?;
  702. if val.is_null() {
  703. return Ok(None)
  704. }
  705. Ok(Some(val.as_bool()?))
  706. }
  707. pub fn get_u32(&self, i: usize) -> Result<u32> {
  708. self.get_value(i)?.as_u32()
  709. }
  710. pub fn get_u32_opt(&self, i: usize) -> Result<Option<u32>> {
  711. let val = self.get_value(i)?;
  712. if val.is_null() {
  713. return Ok(None)
  714. }
  715. Ok(Some(val.as_u32()?))
  716. }
  717. pub fn get_f32(&self, i: usize) -> Result<f32> {
  718. self.get_value(i)?.as_f32()
  719. }
  720. pub fn get_f32_opt(&self, i: usize) -> Result<Option<f32>> {
  721. let val = self.get_value(i)?;
  722. if val.is_null() {
  723. return Ok(None)
  724. }
  725. Ok(Some(val.as_f32()?))
  726. }
  727. pub fn get_str(&self, i: usize) -> Result<String> {
  728. self.get_value(i)?.as_str()
  729. }
  730. pub fn get_str_opt(&self, i: usize) -> Result<Option<String>> {
  731. let val = self.get_value(i)?;
  732. if val.is_null() {
  733. return Ok(None)
  734. }
  735. Ok(Some(val.as_str()?))
  736. }
  737. pub fn get_enum(&self, i: usize) -> Result<String> {
  738. self.get_value(i)?.as_enum()
  739. }
  740. pub fn get_enum_opt(&self, i: usize) -> Result<Option<String>> {
  741. let val = self.get_value(i)?;
  742. if val.is_null() {
  743. return Ok(None)
  744. }
  745. Ok(Some(val.as_enum()?))
  746. }
  747. pub fn get_node_id(&self, i: usize) -> Result<SceneNodeId> {
  748. self.get_value(i)?.as_node_id()
  749. }
  750. pub fn get_node_id_opt(&self, i: usize) -> Result<Option<SceneNodeId>> {
  751. let val = self.get_value(i)?;
  752. if val.is_null() {
  753. return Ok(None)
  754. }
  755. Ok(Some(val.as_node_id()?))
  756. }
  757. pub fn get_expr(&self, i: usize) -> Result<Arc<SExprCode>> {
  758. self.get_raw_value(i)?.as_sexpr()
  759. }
  760. pub fn get_cached(&self, i: usize) -> Result<PropertyValue> {
  761. let cache = &self.cache.lock().unwrap();
  762. if self.is_bounded() {
  763. assert_eq!(cache.len(), self.array_len);
  764. }
  765. if i >= cache.len() {
  766. return Err(Error::PropertyWrongIndex)
  767. }
  768. Ok(cache[i].clone())
  769. }
  770. // Subs
  771. pub fn subscribe_modify(&self) -> Subscription<(Role, ModifyAction, BatchGuardPtr)> {
  772. self.on_modify.clone().subscribe()
  773. }
  774. // Dependencies
  775. pub fn add_depend<S: Into<String>>(&self, prop: &PropertyPtr, i: usize, local_name: S) {
  776. self.depends.lock().unwrap().push(PropertyDepend {
  777. prop: Arc::downgrade(prop),
  778. i,
  779. local_name: local_name.into(),
  780. });
  781. }
  782. pub fn get_depends(&self) -> Vec<PropertyDepend> {
  783. self.depends.lock().unwrap().clone()
  784. }
  785. }
  786. impl std::fmt::Debug for Property {
  787. fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
  788. let node = {
  789. let mut null_name = || write!(f, "<null>:{}", self.name);
  790. let Ok(node) = self.node.lock() else { return null_name() };
  791. let Some(node) = node.clone() else { return null_name() };
  792. let Some(node) = node.upgrade() else { return null_name() };
  793. node
  794. };
  795. write!(f, "{:?}:{}", node, self.name)
  796. }
  797. }
  798. #[cfg(test)]
  799. mod tests {
  800. use super::*;
  801. use crate::expr::Op;
  802. #[test]
  803. fn test_getset() {
  804. let prop = Property::new("foo", PropertyType::Float32, PropertySubType::Null);
  805. assert!(prop.set_f32(Role::App, 1, 4.).is_err());
  806. assert!(prop.is_unset(0).unwrap());
  807. assert!(prop.set_f32(Role::App, 0, 4.).is_ok());
  808. assert_eq!(prop.get_f32(0).unwrap(), 4.);
  809. assert!(!prop.is_unset(0).unwrap());
  810. prop.unset(Role::App, 0).unwrap();
  811. assert!(prop.is_unset(0).unwrap());
  812. assert_eq!(prop.get_f32(0).unwrap(), 0.);
  813. }
  814. #[test]
  815. fn test_nullable() {
  816. // default len is 1
  817. let mut prop = Property::new("foo", PropertyType::Float32, PropertySubType::Null);
  818. assert!(prop.set_defaults_f32(vec![1.0, 0.0]).is_err());
  819. assert!(prop.set_defaults_f32(vec![2.0]).is_ok());
  820. prop.allow_null_values();
  821. prop.set_null(Role::App, 0).unwrap();
  822. assert!(prop.get_f32_opt(1).is_err());
  823. assert!(prop.get_f32_opt(0).is_ok());
  824. assert!(prop.get_f32_opt(0).unwrap().is_none());
  825. prop.clear_values(Role::App);
  826. assert!(prop.get_f32(0).is_ok());
  827. assert!(prop.get_f32_opt(0).unwrap().is_some());
  828. assert_eq!(prop.get_f32(0).unwrap(), 2.0);
  829. }
  830. #[test]
  831. fn test_nonnullable() {
  832. let prop = Property::new("foo", PropertyType::Float32, PropertySubType::Null);
  833. assert!(prop.set_null(Role::App, 0).is_err());
  834. assert!(prop.is_unset(0).unwrap());
  835. }
  836. #[test]
  837. fn test_unbounded() {
  838. let mut prop = Property::new("foo", PropertyType::Float32, PropertySubType::Null);
  839. prop.set_unbounded();
  840. assert_eq!(prop.get_len(), 0);
  841. prop.push_f32(Role::App, 2.0).unwrap();
  842. prop.push_f32(Role::App, 3.0).unwrap();
  843. assert_eq!(prop.get_len(), 2);
  844. prop.clear_values(Role::App);
  845. assert_eq!(prop.get_len(), 0);
  846. prop.allow_null_values();
  847. prop.push_null(Role::App).unwrap();
  848. prop.push_f32(Role::App, 4.0).unwrap();
  849. prop.push_f32(Role::App, 5.0).unwrap();
  850. assert_eq!(prop.get_len(), 3);
  851. assert!(prop.get_f32_opt(0).unwrap().is_none());
  852. assert!(prop.get_f32_opt(1).unwrap().is_some());
  853. assert!(prop.get_f32_opt(2).unwrap().is_some());
  854. assert!(prop.get_f32_opt(3).is_err());
  855. let prop2 = Property::new("foo", PropertyType::Float32, PropertySubType::Null);
  856. assert!(prop2.push_f32(Role::App, 4.0).is_err());
  857. }
  858. #[test]
  859. fn test_range() {
  860. let mut prop = Property::new("foo", PropertyType::Float32, PropertySubType::Null);
  861. let half_pi = 3.1415926535 / 2.;
  862. prop.set_range_f32(-half_pi, half_pi);
  863. assert!(prop.set_f32(Role::App, 0, 6.).is_err());
  864. assert!(prop.set_f32(Role::App, 0, 1.).is_ok());
  865. }
  866. #[test]
  867. fn test_enum() {
  868. let mut prop = Property::new("foo", PropertyType::Enum, PropertySubType::Null);
  869. prop.set_enum_items(vec!["ABC", "XYZ", "FOO"]).unwrap();
  870. assert!(prop.set_enum(Role::App, 0, "ABC").is_ok());
  871. assert!(prop.set_enum(Role::App, 0, "BAR").is_err());
  872. }
  873. #[test]
  874. fn test_expr() {
  875. let mut prop = Property::new("foo", PropertyType::Float32, PropertySubType::Null);
  876. prop.allow_exprs();
  877. assert_eq!(prop.get_f32(0).unwrap(), 0.);
  878. let code = vec![Op::ConstFloat32(4.)];
  879. prop.set_expr(Role::App, 0, code).unwrap();
  880. let val = prop.get_cached(0).unwrap();
  881. assert!(val.is_null());
  882. prop.set_cache_f32(Role::App, 0, 4.).unwrap();
  883. let val = prop.get_cached(0).unwrap();
  884. assert_eq!(val.as_f32().unwrap(), 4.);
  885. }
  886. }