mod.rs 26 KB

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