mod.rs 25 KB

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