mod.rs 44 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501
  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::{BatchGuardPtr, PropertyAtomicGuard};
  31. mod wrap;
  32. pub use wrap::{
  33. PropertyBool, PropertyColor, PropertyDimension, PropertyEnum, PropertyFloat32, PropertyRect,
  34. PropertyStr, 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. Flag = 5,
  72. }
  73. #[derive(Debug, Copy, Clone, PartialEq)]
  74. pub enum Role {
  75. User = 0,
  76. App = 1,
  77. Internal = 2,
  78. Ignored = 3,
  79. }
  80. #[derive(Debug, Clone, PartialEq)]
  81. pub enum PropertyValue {
  82. Unset,
  83. Null,
  84. Bool(bool),
  85. Uint32(u32),
  86. Float32(f32),
  87. Str(String),
  88. Enum(String),
  89. SceneNodeId(SceneNodeId),
  90. SExpr(Arc<SExprCode>),
  91. }
  92. impl PropertyValue {
  93. fn as_type(&self) -> PropertyType {
  94. match self {
  95. Self::Unset => todo!("not sure"),
  96. Self::Null => PropertyType::Null,
  97. Self::Bool(_) => PropertyType::Bool,
  98. Self::Uint32(_) => PropertyType::Uint32,
  99. Self::Float32(_) => PropertyType::Float32,
  100. Self::Str(_) => PropertyType::Str,
  101. Self::Enum(_) => PropertyType::Enum,
  102. Self::SceneNodeId(_) => PropertyType::SceneNodeId,
  103. Self::SExpr(_) => PropertyType::SExpr,
  104. }
  105. }
  106. pub fn is_unset(&self) -> bool {
  107. match self {
  108. Self::Unset => true,
  109. _ => false,
  110. }
  111. }
  112. pub fn is_null(&self) -> bool {
  113. match self {
  114. Self::Null => true,
  115. _ => false,
  116. }
  117. }
  118. pub fn is_expr(&self) -> bool {
  119. match self {
  120. Self::SExpr(_) => true,
  121. _ => false,
  122. }
  123. }
  124. pub fn as_bool(&self) -> Result<bool> {
  125. match self {
  126. Self::Bool(v) => Ok(*v),
  127. _ => Err(Error::PropertyWrongType),
  128. }
  129. }
  130. pub fn as_u32(&self) -> Result<u32> {
  131. match self {
  132. Self::Uint32(v) => Ok(*v),
  133. _ => Err(Error::PropertyWrongType),
  134. }
  135. }
  136. pub fn as_f32(&self) -> Result<f32> {
  137. match self {
  138. Self::Float32(v) => Ok(*v),
  139. _ => Err(Error::PropertyWrongType),
  140. }
  141. }
  142. pub fn as_str(&self) -> Result<String> {
  143. match self {
  144. Self::Str(v) => Ok(v.clone()),
  145. _ => Err(Error::PropertyWrongType),
  146. }
  147. }
  148. pub fn as_enum(&self) -> Result<String> {
  149. match self {
  150. Self::Enum(v) => Ok(v.clone()),
  151. _ => Err(Error::PropertyWrongType),
  152. }
  153. }
  154. pub fn as_node_id(&self) -> Result<SceneNodeId> {
  155. match self {
  156. Self::SceneNodeId(v) => Ok(*v),
  157. _ => Err(Error::PropertyWrongType),
  158. }
  159. }
  160. pub fn as_sexpr(&self) -> Result<Arc<SExprCode>> {
  161. match self {
  162. Self::SExpr(v) => Ok(v.clone()),
  163. _ => Err(Error::PropertyWrongType),
  164. }
  165. }
  166. }
  167. impl Encodable for PropertyValue {
  168. fn encode<S: Write>(&self, s: &mut S) -> std::result::Result<usize, std::io::Error> {
  169. match self {
  170. Self::Unset | Self::Null => {
  171. // do nothing
  172. Ok(0)
  173. }
  174. Self::Bool(v) => v.encode(s),
  175. Self::Uint32(v) => v.encode(s),
  176. Self::Float32(v) => v.encode(s),
  177. Self::Str(v) => v.encode(s),
  178. Self::Enum(v) => v.encode(s),
  179. Self::SceneNodeId(v) => v.encode(s),
  180. Self::SExpr(v) => v.encode(s),
  181. }
  182. }
  183. }
  184. #[derive(Debug, Clone)]
  185. pub enum ModifyAction {
  186. Clear,
  187. Set(usize),
  188. SetVec,
  189. SetCache(Vec<usize>),
  190. Unset(usize),
  191. Push(usize),
  192. Insert(usize),
  193. Remove(usize, PropertyValue),
  194. }
  195. type ModifyPublisher = PublisherPtr<(Role, ModifyAction, BatchGuardPtr)>;
  196. pub type PropertyPtr = Arc<Property>;
  197. pub type PropertyWeak = Weak<Property>;
  198. #[derive(Debug, Clone)]
  199. pub struct PropertyDepend {
  200. pub prop: PropertyWeak,
  201. pub i: usize,
  202. pub local_name: String,
  203. }
  204. pub struct Property {
  205. pub name: String,
  206. pub node: SyncMutex<Option<SceneNodeWeak>>,
  207. pub typ: PropertyType,
  208. pub subtype: PropertySubType,
  209. pub defaults: Vec<PropertyValue>,
  210. // either a value or an expr must be set
  211. pub vals: SyncMutex<Vec<PropertyValue>>,
  212. // only used valid when PropertyValue is an expr
  213. // caches the last calculated value
  214. pub cache: SyncMutex<Vec<PropertyValue>>,
  215. pub ui_name: String,
  216. pub desc: String,
  217. pub is_null_allowed: bool,
  218. pub is_expr_allowed: bool,
  219. // Use 0 for unbounded length
  220. pub array_len: usize,
  221. pub min_val: Option<PropertyValue>,
  222. pub max_val: Option<PropertyValue>,
  223. // PropertyType must be Enum
  224. pub enum_items: Option<Vec<String>>,
  225. on_modify: ModifyPublisher,
  226. depends: SyncMutex<Vec<PropertyDepend>>,
  227. }
  228. impl Property {
  229. pub fn new<S: Into<String>>(name: S, typ: PropertyType, subtype: PropertySubType) -> Self {
  230. Self {
  231. name: name.into(),
  232. node: SyncMutex::new(None),
  233. typ,
  234. subtype,
  235. defaults: vec![typ.default_value()],
  236. vals: SyncMutex::new(vec![PropertyValue::Unset]),
  237. cache: SyncMutex::new(vec![PropertyValue::Null]),
  238. ui_name: String::new(),
  239. desc: String::new(),
  240. is_null_allowed: false,
  241. is_expr_allowed: false,
  242. array_len: 1,
  243. min_val: None,
  244. max_val: None,
  245. enum_items: None,
  246. on_modify: Publisher::new(),
  247. depends: SyncMutex::new(vec![]),
  248. }
  249. }
  250. /// Just used for debugging
  251. pub fn set_parent(&self, node: SceneNodeWeak) {
  252. *self.node.lock().unwrap() = Some(node);
  253. }
  254. pub fn set_ui_text<S: Into<String>>(&mut self, ui_name: S, desc: S) {
  255. self.ui_name = ui_name.into();
  256. self.desc = desc.into();
  257. }
  258. pub fn set_array_len(&mut self, len: usize) {
  259. self.array_len = len;
  260. self.defaults.resize(len, self.typ.default_value());
  261. self.defaults.shrink_to_fit();
  262. let vals = &mut *self.vals.lock().unwrap();
  263. vals.resize(len, PropertyValue::Unset);
  264. vals.shrink_to_fit();
  265. let cache = &mut *self.cache.lock().unwrap();
  266. cache.resize(len, PropertyValue::Null);
  267. cache.shrink_to_fit();
  268. }
  269. pub fn set_unbounded(&mut self) {
  270. self.set_array_len(0);
  271. }
  272. pub fn set_range_u32(&mut self, min: u32, max: u32) {
  273. self.min_val = Some(PropertyValue::Uint32(min));
  274. self.max_val = Some(PropertyValue::Uint32(max));
  275. }
  276. pub fn set_range_f32(&mut self, min: f32, max: f32) {
  277. self.min_val = Some(PropertyValue::Float32(min));
  278. self.max_val = Some(PropertyValue::Float32(max));
  279. }
  280. pub fn set_enum_items<S: Into<String>>(&mut self, enum_items: Vec<S>) -> Result<()> {
  281. if self.typ != PropertyType::Enum {
  282. return Err(Error::PropertyWrongType)
  283. }
  284. self.enum_items = Some(enum_items.into_iter().map(|item| item.into()).collect());
  285. Ok(())
  286. }
  287. pub fn allow_null_values(&mut self) {
  288. self.is_null_allowed = true;
  289. }
  290. pub fn allow_exprs(&mut self) {
  291. self.is_expr_allowed = true;
  292. }
  293. fn check_defaults_len(&self, defaults_len: usize) -> Result<()> {
  294. if !self.is_bounded() || defaults_len != self.array_len {
  295. return Err(Error::PropertyWrongLen)
  296. }
  297. Ok(())
  298. }
  299. pub fn set_defaults_bool(&mut self, defaults: Vec<bool>) -> Result<()> {
  300. self.check_defaults_len(defaults.len())?;
  301. self.defaults = defaults.into_iter().map(|v| PropertyValue::Bool(v)).collect();
  302. Ok(())
  303. }
  304. pub fn set_defaults_u32(&mut self, defaults: Vec<u32>) -> Result<()> {
  305. self.check_defaults_len(defaults.len())?;
  306. self.defaults = defaults.into_iter().map(|v| PropertyValue::Uint32(v)).collect();
  307. Ok(())
  308. }
  309. pub fn set_defaults_f32(&mut self, defaults: Vec<f32>) -> Result<()> {
  310. self.check_defaults_len(defaults.len())?;
  311. self.defaults = defaults.into_iter().map(|v| PropertyValue::Float32(v)).collect();
  312. Ok(())
  313. }
  314. pub fn set_defaults_str(&mut self, defaults: Vec<String>) -> Result<()> {
  315. self.check_defaults_len(defaults.len())?;
  316. self.defaults = defaults.into_iter().map(|v| PropertyValue::Str(v)).collect();
  317. Ok(())
  318. }
  319. pub fn set_defaults_null(&mut self) -> Result<()> {
  320. if !self.is_null_allowed {
  321. return Err(Error::PropertyNullNotAllowed)
  322. }
  323. if !self.is_bounded() {
  324. return Err(Error::PropertyWrongLen)
  325. }
  326. self.defaults = (0..self.array_len).map(|_| PropertyValue::Null).collect();
  327. Ok(())
  328. }
  329. // Set
  330. /// This will clear all values, resetting them to the default
  331. pub fn clear_values(self: &Arc<Self>, atom: &mut PropertyAtomicGuard, role: Role) {
  332. {
  333. let vals = &mut self.vals.lock().unwrap();
  334. vals.clear();
  335. vals.resize(self.array_len, PropertyValue::Unset);
  336. }
  337. atom.add(self.clone(), role, ModifyAction::Clear);
  338. }
  339. fn set_raw_value(&self, i: usize, val: PropertyValue) -> Result<()> {
  340. if self.typ != val.as_type() {
  341. return Err(Error::PropertyWrongType)
  342. }
  343. let vals = &mut self.vals.lock().unwrap();
  344. if i >= vals.len() {
  345. return Err(Error::PropertyWrongIndex)
  346. }
  347. vals[i] = val;
  348. Ok(())
  349. }
  350. pub fn unset(
  351. self: &Arc<Self>,
  352. atom: &mut PropertyAtomicGuard,
  353. role: Role,
  354. i: usize,
  355. ) -> Result<()> {
  356. {
  357. let vals = &mut self.vals.lock().unwrap();
  358. if i >= vals.len() {
  359. return Err(Error::PropertyWrongIndex)
  360. }
  361. vals[i] = PropertyValue::Unset;
  362. }
  363. atom.add(self.clone(), role, ModifyAction::Unset(i));
  364. Ok(())
  365. }
  366. pub fn set_null(
  367. self: &Arc<Self>,
  368. atom: &mut PropertyAtomicGuard,
  369. role: Role,
  370. i: usize,
  371. ) -> Result<()> {
  372. if !self.is_null_allowed {
  373. return Err(Error::PropertyNullNotAllowed)
  374. }
  375. let mut vals = self.vals.lock().unwrap();
  376. if i >= vals.len() {
  377. return Err(Error::PropertyWrongIndex)
  378. }
  379. vals[i] = PropertyValue::Null;
  380. drop(vals);
  381. atom.add(self.clone(), role, ModifyAction::Set(i));
  382. Ok(())
  383. }
  384. pub fn set_bool(
  385. self: &Arc<Self>,
  386. atom: &mut PropertyAtomicGuard,
  387. role: Role,
  388. i: usize,
  389. val: bool,
  390. ) -> Result<()> {
  391. self.set_raw_value(i, PropertyValue::Bool(val))?;
  392. atom.add(self.clone(), role, ModifyAction::Set(i));
  393. Ok(())
  394. }
  395. pub fn set_u32(
  396. self: &Arc<Self>,
  397. atom: &mut PropertyAtomicGuard,
  398. role: Role,
  399. i: usize,
  400. val: u32,
  401. ) -> Result<()> {
  402. if self.min_val.is_some() {
  403. let min = self.min_val.as_ref().unwrap().as_u32()?;
  404. if val < min {
  405. return Err(Error::PropertyOutOfRange)
  406. }
  407. }
  408. if self.max_val.is_some() {
  409. let max = self.max_val.as_ref().unwrap().as_u32()?;
  410. if val > max {
  411. return Err(Error::PropertyOutOfRange)
  412. }
  413. }
  414. self.set_raw_value(i, PropertyValue::Uint32(val))?;
  415. atom.add(self.clone(), role, ModifyAction::Set(i));
  416. Ok(())
  417. }
  418. pub fn set_f32(
  419. self: &Arc<Self>,
  420. atom: &mut PropertyAtomicGuard,
  421. role: Role,
  422. i: usize,
  423. val: f32,
  424. ) -> Result<()> {
  425. if self.min_val.is_some() {
  426. let min = self.min_val.as_ref().unwrap().as_f32()?;
  427. if val < min {
  428. return Err(Error::PropertyOutOfRange)
  429. }
  430. }
  431. if self.max_val.is_some() {
  432. let max = self.max_val.as_ref().unwrap().as_f32()?;
  433. if val > max {
  434. return Err(Error::PropertyOutOfRange)
  435. }
  436. }
  437. self.set_raw_value(i, PropertyValue::Float32(val))?;
  438. atom.add(self.clone(), role, ModifyAction::Set(i));
  439. Ok(())
  440. }
  441. pub fn set_str<S: Into<String>>(
  442. self: &Arc<Self>,
  443. atom: &mut PropertyAtomicGuard,
  444. role: Role,
  445. i: usize,
  446. val: S,
  447. ) -> Result<()> {
  448. self.set_raw_value(i, PropertyValue::Str(val.into()))?;
  449. atom.add(self.clone(), role, ModifyAction::Set(i));
  450. Ok(())
  451. }
  452. pub fn set_enum<S: Into<String>>(
  453. self: &Arc<Self>,
  454. atom: &mut PropertyAtomicGuard,
  455. role: Role,
  456. i: usize,
  457. val: S,
  458. ) -> Result<()> {
  459. if self.typ != PropertyType::Enum {
  460. return Err(Error::PropertyWrongType)
  461. }
  462. let val = val.into();
  463. if !self.enum_items.as_ref().unwrap().contains(&val) {
  464. return Err(Error::PropertyWrongEnumItem)
  465. }
  466. self.set_raw_value(i, PropertyValue::Enum(val.into()))?;
  467. atom.add(self.clone(), role, ModifyAction::Set(i));
  468. Ok(())
  469. }
  470. pub fn set_node_id(
  471. self: &Arc<Self>,
  472. atom: &mut PropertyAtomicGuard,
  473. role: Role,
  474. i: usize,
  475. val: SceneNodeId,
  476. ) -> Result<()> {
  477. self.set_raw_value(i, PropertyValue::SceneNodeId(val))?;
  478. atom.add(self.clone(), role, ModifyAction::Set(i));
  479. Ok(())
  480. }
  481. pub fn set_expr(
  482. self: &Arc<Self>,
  483. atom: &mut PropertyAtomicGuard,
  484. role: Role,
  485. i: usize,
  486. val: SExprCode,
  487. ) -> Result<()> {
  488. {
  489. if !self.is_expr_allowed {
  490. return Err(Error::PropertySExprNotAllowed)
  491. }
  492. let vals = &mut self.vals.lock().unwrap();
  493. if i >= vals.len() {
  494. return Err(Error::PropertyWrongIndex)
  495. }
  496. vals[i] = PropertyValue::SExpr(Arc::new(val));
  497. }
  498. atom.add(self.clone(), role, ModifyAction::Set(i));
  499. Ok(())
  500. }
  501. fn set_value_vec<T, F>(
  502. self: &Arc<Self>,
  503. atom: &mut PropertyAtomicGuard,
  504. role: Role,
  505. val: Vec<T>,
  506. f: F,
  507. ) -> Result<()>
  508. where
  509. F: Fn(T) -> PropertyValue,
  510. {
  511. if self.is_bounded() {
  512. return Err(Error::PropertyIsBounded)
  513. }
  514. {
  515. let mut vals = self.vals.lock().unwrap();
  516. vals.clear();
  517. vals.extend(val.into_iter().map(f));
  518. }
  519. atom.add(self.clone(), role, ModifyAction::SetVec);
  520. Ok(())
  521. }
  522. pub fn set_bool_vec(
  523. self: &Arc<Self>,
  524. atom: &mut PropertyAtomicGuard,
  525. role: Role,
  526. val: Vec<bool>,
  527. ) -> Result<()> {
  528. self.set_value_vec(atom, role, val, PropertyValue::Bool)
  529. }
  530. pub fn set_u32_vec(
  531. self: &Arc<Self>,
  532. atom: &mut PropertyAtomicGuard,
  533. role: Role,
  534. val: Vec<u32>,
  535. ) -> Result<()> {
  536. self.set_value_vec(atom, role, val, PropertyValue::Uint32)
  537. }
  538. pub fn set_f32_vec(
  539. self: &Arc<Self>,
  540. atom: &mut PropertyAtomicGuard,
  541. role: Role,
  542. val: Vec<f32>,
  543. ) -> Result<()> {
  544. self.set_value_vec(atom, role, val, PropertyValue::Float32)
  545. }
  546. pub fn set_str_vec<S: Into<String>>(
  547. self: &Arc<Self>,
  548. atom: &mut PropertyAtomicGuard,
  549. role: Role,
  550. val: Vec<S>,
  551. ) -> Result<()> {
  552. self.set_value_vec(atom, role, val, |v| PropertyValue::Str(v.into()))
  553. }
  554. pub fn set_enum_vec<S: Into<String>>(
  555. self: &Arc<Self>,
  556. atom: &mut PropertyAtomicGuard,
  557. role: Role,
  558. val: Vec<S>,
  559. ) -> Result<()> {
  560. if self.typ != PropertyType::Enum {
  561. return Err(Error::PropertyWrongType)
  562. }
  563. self.set_value_vec(atom, role, val, |v| PropertyValue::Enum(v.into()))
  564. }
  565. pub fn set_node_id_vec(
  566. self: &Arc<Self>,
  567. atom: &mut PropertyAtomicGuard,
  568. role: Role,
  569. val: Vec<SceneNodeId>,
  570. ) -> Result<()> {
  571. self.set_value_vec(atom, role, val, PropertyValue::SceneNodeId)
  572. }
  573. fn set_cache(&self, i: usize, val: PropertyValue) -> Result<()> {
  574. if self.typ != val.as_type() {
  575. return Err(Error::PropertyWrongType)
  576. }
  577. let cache = &mut self.cache.lock().unwrap();
  578. if i >= cache.len() {
  579. return Err(Error::PropertyWrongIndex)
  580. }
  581. cache[i] = val;
  582. Ok(())
  583. }
  584. pub fn set_cache_f32(
  585. self: &Arc<Self>,
  586. atom: &mut PropertyAtomicGuard,
  587. role: Role,
  588. i: usize,
  589. val: f32,
  590. ) -> Result<()> {
  591. self.set_cache(i, PropertyValue::Float32(val))?;
  592. atom.add(self.clone(), role, ModifyAction::SetCache(vec![i]));
  593. Ok(())
  594. }
  595. pub fn set_cache_u32(
  596. self: &Arc<Self>,
  597. atom: &mut PropertyAtomicGuard,
  598. role: Role,
  599. i: usize,
  600. val: u32,
  601. ) -> Result<()> {
  602. self.set_cache(i, PropertyValue::Uint32(val))?;
  603. atom.add(self.clone(), role, ModifyAction::SetCache(vec![i]));
  604. Ok(())
  605. }
  606. pub fn set_cache_f32_multi(
  607. self: &Arc<Self>,
  608. atom: &mut PropertyAtomicGuard,
  609. role: Role,
  610. changes: Vec<(usize, f32)>,
  611. ) -> Result<()> {
  612. let mut idxs = vec![];
  613. for (idx, val) in changes {
  614. self.set_cache(idx, PropertyValue::Float32(val))?;
  615. idxs.push(idx);
  616. }
  617. atom.add(self.clone(), role, ModifyAction::SetCache(idxs));
  618. Ok(())
  619. }
  620. pub fn set_cache_u32_range(
  621. self: &Arc<Self>,
  622. atom: &mut PropertyAtomicGuard,
  623. role: Role,
  624. changes: Vec<(usize, u32)>,
  625. ) -> Result<()> {
  626. let mut idxs = vec![];
  627. for (idx, val) in changes {
  628. self.set_cache(idx, PropertyValue::Uint32(val))?;
  629. idxs.push(idx);
  630. }
  631. atom.add(self.clone(), role, ModifyAction::SetCache(idxs));
  632. Ok(())
  633. }
  634. // Push
  635. fn push_value(
  636. self: &Arc<Self>,
  637. atom: &mut PropertyAtomicGuard,
  638. role: Role,
  639. value: PropertyValue,
  640. ) -> Result<usize> {
  641. if self.is_bounded() {
  642. return Err(Error::PropertyIsBounded)
  643. }
  644. let mut vals = self.vals.lock().unwrap();
  645. let i = vals.len();
  646. vals.push(value);
  647. drop(vals);
  648. atom.add(self.clone(), role, ModifyAction::Push(i));
  649. Ok(i)
  650. }
  651. pub fn push_null(
  652. self: &Arc<Self>,
  653. atom: &mut PropertyAtomicGuard,
  654. role: Role,
  655. ) -> Result<usize> {
  656. self.push_value(atom, role, PropertyValue::Null)
  657. }
  658. pub fn push_bool(
  659. self: &Arc<Self>,
  660. atom: &mut PropertyAtomicGuard,
  661. role: Role,
  662. val: bool,
  663. ) -> Result<usize> {
  664. self.push_value(atom, role, PropertyValue::Bool(val))
  665. }
  666. pub fn push_u32(
  667. self: &Arc<Self>,
  668. atom: &mut PropertyAtomicGuard,
  669. role: Role,
  670. val: u32,
  671. ) -> Result<usize> {
  672. // TODO: none of these push calls are enforcing constraints that are required
  673. // see the set_XX calls.
  674. self.push_value(atom, role, PropertyValue::Uint32(val))
  675. }
  676. pub fn push_f32(
  677. self: &Arc<Self>,
  678. atom: &mut PropertyAtomicGuard,
  679. role: Role,
  680. val: f32,
  681. ) -> Result<usize> {
  682. self.push_value(atom, role, PropertyValue::Float32(val))
  683. }
  684. pub fn push_str<S: Into<String>>(
  685. self: &Arc<Self>,
  686. atom: &mut PropertyAtomicGuard,
  687. role: Role,
  688. val: S,
  689. ) -> Result<usize> {
  690. self.push_value(atom, role, PropertyValue::Str(val.into()))
  691. }
  692. pub fn push_enum<S: Into<String>>(
  693. self: &Arc<Self>,
  694. atom: &mut PropertyAtomicGuard,
  695. role: Role,
  696. val: S,
  697. ) -> Result<usize> {
  698. self.push_value(atom, role, PropertyValue::Enum(val.into()))
  699. }
  700. pub fn push_node_id(
  701. self: &Arc<Self>,
  702. atom: &mut PropertyAtomicGuard,
  703. role: Role,
  704. val: SceneNodeId,
  705. ) -> Result<usize> {
  706. self.push_value(atom, role, PropertyValue::SceneNodeId(val))
  707. }
  708. // Insert
  709. fn insert_value(
  710. self: &Arc<Self>,
  711. atom: &mut PropertyAtomicGuard,
  712. role: Role,
  713. index: usize,
  714. value: PropertyValue,
  715. ) -> Result<usize> {
  716. if self.is_bounded() {
  717. return Err(Error::PropertyIsBounded)
  718. }
  719. if index > self.get_len() {
  720. return Err(Error::PropertyWrongIndex)
  721. }
  722. let mut vals = self.vals.lock().unwrap();
  723. vals.insert(index, value);
  724. drop(vals);
  725. atom.add(self.clone(), role, ModifyAction::Insert(index));
  726. Ok(index)
  727. }
  728. pub fn insert_null(
  729. self: &Arc<Self>,
  730. atom: &mut PropertyAtomicGuard,
  731. role: Role,
  732. index: usize,
  733. ) -> Result<usize> {
  734. self.insert_value(atom, role, index, PropertyValue::Null)
  735. }
  736. pub fn insert_bool(
  737. self: &Arc<Self>,
  738. atom: &mut PropertyAtomicGuard,
  739. role: Role,
  740. index: usize,
  741. val: bool,
  742. ) -> Result<usize> {
  743. self.insert_value(atom, role, index, PropertyValue::Bool(val))
  744. }
  745. pub fn insert_u32(
  746. self: &Arc<Self>,
  747. atom: &mut PropertyAtomicGuard,
  748. role: Role,
  749. index: usize,
  750. val: u32,
  751. ) -> Result<usize> {
  752. self.insert_value(atom, role, index, PropertyValue::Uint32(val))
  753. }
  754. pub fn insert_f32(
  755. self: &Arc<Self>,
  756. atom: &mut PropertyAtomicGuard,
  757. role: Role,
  758. index: usize,
  759. val: f32,
  760. ) -> Result<usize> {
  761. self.insert_value(atom, role, index, PropertyValue::Float32(val))
  762. }
  763. pub fn insert_str<S: Into<String>>(
  764. self: &Arc<Self>,
  765. atom: &mut PropertyAtomicGuard,
  766. role: Role,
  767. index: usize,
  768. val: S,
  769. ) -> Result<usize> {
  770. self.insert_value(atom, role, index, PropertyValue::Str(val.into()))
  771. }
  772. pub fn insert_enum<S: Into<String>>(
  773. self: &Arc<Self>,
  774. atom: &mut PropertyAtomicGuard,
  775. role: Role,
  776. index: usize,
  777. val: S,
  778. ) -> Result<usize> {
  779. self.insert_value(atom, role, index, PropertyValue::Enum(val.into()))
  780. }
  781. pub fn insert_node_id(
  782. self: &Arc<Self>,
  783. atom: &mut PropertyAtomicGuard,
  784. role: Role,
  785. index: usize,
  786. val: SceneNodeId,
  787. ) -> Result<usize> {
  788. self.insert_value(atom, role, index, PropertyValue::SceneNodeId(val))
  789. }
  790. // Remove
  791. fn remove_value(
  792. self: &Arc<Self>,
  793. atom: &mut PropertyAtomicGuard,
  794. role: Role,
  795. index: usize,
  796. ) -> Result<PropertyValue> {
  797. if self.is_bounded() {
  798. return Err(Error::PropertyIsBounded)
  799. }
  800. if index >= self.get_len() {
  801. return Err(Error::PropertyWrongIndex)
  802. }
  803. let mut vals = self.vals.lock().unwrap();
  804. let value = vals.remove(index);
  805. drop(vals);
  806. atom.add(self.clone(), role, ModifyAction::Remove(index, value.clone()));
  807. Ok(value)
  808. }
  809. pub fn remove_null(
  810. self: &Arc<Self>,
  811. atom: &mut PropertyAtomicGuard,
  812. role: Role,
  813. index: usize,
  814. ) -> Result<()> {
  815. self.remove_value(atom, role, index)?;
  816. Ok(())
  817. }
  818. pub fn remove_bool(
  819. self: &Arc<Self>,
  820. atom: &mut PropertyAtomicGuard,
  821. role: Role,
  822. index: usize,
  823. ) -> Result<bool> {
  824. match self.remove_value(atom, role, index)? {
  825. PropertyValue::Bool(v) => Ok(v),
  826. _ => Err(Error::PropertyWrongType),
  827. }
  828. }
  829. pub fn remove_u32(
  830. self: &Arc<Self>,
  831. atom: &mut PropertyAtomicGuard,
  832. role: Role,
  833. index: usize,
  834. ) -> Result<u32> {
  835. match self.remove_value(atom, role, index)? {
  836. PropertyValue::Uint32(v) => Ok(v),
  837. _ => Err(Error::PropertyWrongType),
  838. }
  839. }
  840. pub fn remove_f32(
  841. self: &Arc<Self>,
  842. atom: &mut PropertyAtomicGuard,
  843. role: Role,
  844. index: usize,
  845. ) -> Result<f32> {
  846. match self.remove_value(atom, role, index)? {
  847. PropertyValue::Float32(v) => Ok(v),
  848. _ => Err(Error::PropertyWrongType),
  849. }
  850. }
  851. pub fn remove_str(
  852. self: &Arc<Self>,
  853. atom: &mut PropertyAtomicGuard,
  854. role: Role,
  855. index: usize,
  856. ) -> Result<String> {
  857. match self.remove_value(atom, role, index)? {
  858. PropertyValue::Str(v) => Ok(v),
  859. _ => Err(Error::PropertyWrongType),
  860. }
  861. }
  862. pub fn remove_enum(
  863. self: &Arc<Self>,
  864. atom: &mut PropertyAtomicGuard,
  865. role: Role,
  866. index: usize,
  867. ) -> Result<String> {
  868. match self.remove_value(atom, role, index)? {
  869. PropertyValue::Enum(v) => Ok(v),
  870. _ => Err(Error::PropertyWrongType),
  871. }
  872. }
  873. pub fn remove_node_id(
  874. self: &Arc<Self>,
  875. atom: &mut PropertyAtomicGuard,
  876. role: Role,
  877. index: usize,
  878. ) -> Result<SceneNodeId> {
  879. match self.remove_value(atom, role, index)? {
  880. PropertyValue::SceneNodeId(v) => Ok(v),
  881. _ => Err(Error::PropertyWrongType),
  882. }
  883. }
  884. // Remove by item
  885. pub fn remove_str_item(
  886. self: &Arc<Self>,
  887. atom: &mut PropertyAtomicGuard,
  888. role: Role,
  889. item: &str,
  890. ) -> Option<usize> {
  891. for i in 0..self.get_len() {
  892. if self.get_str(i).unwrap() == item {
  893. self.remove_str(atom, role, i).unwrap();
  894. return Some(i)
  895. }
  896. }
  897. None
  898. }
  899. // Get
  900. pub fn is_bounded(&self) -> bool {
  901. self.array_len != 0
  902. }
  903. pub fn get_len(&self) -> usize {
  904. // Avoid locking unless we need to
  905. // If array len is nonzero, then vals len should be the same.
  906. if !self.is_bounded() {
  907. return self.vals.lock().unwrap().len()
  908. }
  909. self.array_len
  910. }
  911. pub fn is_unset(&self, i: usize) -> Result<bool> {
  912. let val = self.get_raw_value(i)?;
  913. Ok(val.is_unset())
  914. }
  915. pub fn is_null(&self, i: usize) -> Result<bool> {
  916. let val = self.get_value(i)?;
  917. if val.is_unset() {
  918. return Ok(self.defaults[i].is_null())
  919. }
  920. Ok(val.is_null())
  921. }
  922. pub fn is_expr(&self, i: usize) -> Result<bool> {
  923. if !self.is_expr_allowed {
  924. return Ok(false)
  925. }
  926. let val = self.get_raw_value(i)?;
  927. Ok(val.is_expr())
  928. }
  929. pub fn get_raw_value(&self, i: usize) -> Result<PropertyValue> {
  930. let vals = &self.vals.lock().unwrap();
  931. if self.is_bounded() {
  932. assert_eq!(vals.len(), self.array_len);
  933. }
  934. if i >= vals.len() {
  935. return Err(Error::PropertyWrongIndex)
  936. }
  937. let val = vals[i].clone();
  938. Ok(val)
  939. }
  940. pub fn get_value(&self, i: usize) -> Result<PropertyValue> {
  941. let val = self.get_raw_value(i)?;
  942. if val.is_expr() {
  943. let cached = self.get_cached(i)?;
  944. if cached.is_null() {
  945. return Ok(self.defaults[i].clone())
  946. }
  947. return Ok(cached)
  948. }
  949. if val.is_unset() {
  950. return Ok(self.defaults[i].clone())
  951. }
  952. Ok(val)
  953. }
  954. pub fn get_bool(&self, i: usize) -> Result<bool> {
  955. self.get_value(i)?.as_bool()
  956. }
  957. pub fn get_bool_opt(&self, i: usize) -> Result<Option<bool>> {
  958. let val = self.get_value(i)?;
  959. if val.is_null() {
  960. return Ok(None)
  961. }
  962. Ok(Some(val.as_bool()?))
  963. }
  964. pub fn get_u32(&self, i: usize) -> Result<u32> {
  965. self.get_value(i)?.as_u32()
  966. }
  967. pub fn get_u32_opt(&self, i: usize) -> Result<Option<u32>> {
  968. let val = self.get_value(i)?;
  969. if val.is_null() {
  970. return Ok(None)
  971. }
  972. Ok(Some(val.as_u32()?))
  973. }
  974. pub fn get_f32(&self, i: usize) -> Result<f32> {
  975. self.get_value(i)?.as_f32()
  976. }
  977. pub fn get_f32_opt(&self, i: usize) -> Result<Option<f32>> {
  978. let val = self.get_value(i)?;
  979. if val.is_null() {
  980. return Ok(None)
  981. }
  982. Ok(Some(val.as_f32()?))
  983. }
  984. pub fn get_str(&self, i: usize) -> Result<String> {
  985. self.get_value(i)?.as_str()
  986. }
  987. pub fn get_str_opt(&self, i: usize) -> Result<Option<String>> {
  988. let val = self.get_value(i)?;
  989. if val.is_null() {
  990. return Ok(None)
  991. }
  992. Ok(Some(val.as_str()?))
  993. }
  994. pub fn get_enum(&self, i: usize) -> Result<String> {
  995. self.get_value(i)?.as_enum()
  996. }
  997. pub fn get_enum_opt(&self, i: usize) -> Result<Option<String>> {
  998. let val = self.get_value(i)?;
  999. if val.is_null() {
  1000. return Ok(None)
  1001. }
  1002. Ok(Some(val.as_enum()?))
  1003. }
  1004. pub fn get_node_id(&self, i: usize) -> Result<SceneNodeId> {
  1005. self.get_value(i)?.as_node_id()
  1006. }
  1007. pub fn get_node_id_opt(&self, i: usize) -> Result<Option<SceneNodeId>> {
  1008. let val = self.get_value(i)?;
  1009. if val.is_null() {
  1010. return Ok(None)
  1011. }
  1012. Ok(Some(val.as_node_id()?))
  1013. }
  1014. pub fn get_expr(&self, i: usize) -> Result<Arc<SExprCode>> {
  1015. self.get_raw_value(i)?.as_sexpr()
  1016. }
  1017. pub fn get_cached(&self, i: usize) -> Result<PropertyValue> {
  1018. let cache = &self.cache.lock().unwrap();
  1019. if self.is_bounded() {
  1020. assert_eq!(cache.len(), self.array_len);
  1021. }
  1022. if i >= cache.len() {
  1023. return Err(Error::PropertyWrongIndex)
  1024. }
  1025. Ok(cache[i].clone())
  1026. }
  1027. fn get_value_vec<T, F>(&self, f: F) -> Result<Vec<T>>
  1028. where
  1029. F: Fn(&PropertyValue) -> Option<T>,
  1030. {
  1031. if self.is_bounded() {
  1032. return Err(Error::PropertyIsBounded)
  1033. }
  1034. let vals = self.vals.lock().unwrap();
  1035. let mut result = Vec::with_capacity(vals.len());
  1036. for val in vals.iter() {
  1037. match f(val) {
  1038. Some(v) => result.push(v),
  1039. None => return Err(Error::PropertyWrongType),
  1040. }
  1041. }
  1042. Ok(result)
  1043. }
  1044. pub fn get_bool_vec(&self) -> Result<Vec<bool>> {
  1045. self.get_value_vec(|val| match val {
  1046. PropertyValue::Bool(v) => Some(*v),
  1047. _ => None,
  1048. })
  1049. }
  1050. pub fn get_u32_vec(&self) -> Result<Vec<u32>> {
  1051. self.get_value_vec(|val| match val {
  1052. PropertyValue::Uint32(v) => Some(*v),
  1053. _ => None,
  1054. })
  1055. }
  1056. pub fn get_f32_vec(&self) -> Result<Vec<f32>> {
  1057. self.get_value_vec(|val| match val {
  1058. PropertyValue::Float32(v) => Some(*v),
  1059. _ => None,
  1060. })
  1061. }
  1062. pub fn get_str_vec(&self) -> Result<Vec<String>> {
  1063. self.get_value_vec(|val| match val {
  1064. PropertyValue::Str(v) => Some(v.clone()),
  1065. _ => None,
  1066. })
  1067. }
  1068. pub fn get_enum_vec(&self) -> Result<Vec<String>> {
  1069. self.get_value_vec(|val| match val {
  1070. PropertyValue::Enum(v) => Some(v.clone()),
  1071. _ => None,
  1072. })
  1073. }
  1074. pub fn get_node_id_vec(&self) -> Result<Vec<SceneNodeId>> {
  1075. self.get_value_vec(|val| match val {
  1076. PropertyValue::SceneNodeId(v) => Some(*v),
  1077. _ => None,
  1078. })
  1079. }
  1080. // Contains
  1081. pub fn contains_str(&self, s: &str) -> bool {
  1082. for i in 0..self.get_len() {
  1083. if let Ok(item) = self.get_str(i) {
  1084. if item == s {
  1085. return true
  1086. }
  1087. }
  1088. }
  1089. false
  1090. }
  1091. // Subs
  1092. pub fn subscribe_modify(&self) -> Subscription<(Role, ModifyAction, BatchGuardPtr)> {
  1093. self.on_modify.clone().subscribe()
  1094. }
  1095. // Dependencies
  1096. pub fn add_depend<S: Into<String>>(&self, prop: &PropertyPtr, i: usize, local_name: S) {
  1097. self.depends.lock().unwrap().push(PropertyDepend {
  1098. prop: Arc::downgrade(prop),
  1099. i,
  1100. local_name: local_name.into(),
  1101. });
  1102. }
  1103. pub fn get_depends(&self) -> Vec<PropertyDepend> {
  1104. self.depends.lock().unwrap().clone()
  1105. }
  1106. }
  1107. impl std::fmt::Debug for Property {
  1108. fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
  1109. let node = {
  1110. let mut null_name = || write!(f, "<null>:{}", self.name);
  1111. let Ok(node) = self.node.lock() else { return null_name() };
  1112. let Some(node) = node.clone() else { return null_name() };
  1113. let Some(node) = node.upgrade() else { return null_name() };
  1114. node
  1115. };
  1116. write!(f, "{:?}:{}", node, self.name)
  1117. }
  1118. }
  1119. #[cfg(test)]
  1120. mod tests {
  1121. use super::*;
  1122. use crate::expr::Op;
  1123. #[test]
  1124. fn test_getset() {
  1125. let prop = Arc::new(Property::new("foo", PropertyType::Float32, PropertySubType::Null));
  1126. let atom = &mut PropertyAtomicGuard::none();
  1127. assert!(prop.set_f32(atom, Role::App, 1, 4.).is_err());
  1128. assert!(prop.is_unset(0).unwrap());
  1129. assert!(prop.set_f32(atom, Role::App, 0, 4.).is_ok());
  1130. assert_eq!(prop.get_f32(0).unwrap(), 4.);
  1131. assert!(!prop.is_unset(0).unwrap());
  1132. prop.unset(atom, Role::App, 0).unwrap();
  1133. assert!(prop.is_unset(0).unwrap());
  1134. assert_eq!(prop.get_f32(0).unwrap(), 0.);
  1135. }
  1136. #[test]
  1137. fn test_nullable() {
  1138. // default len is 1
  1139. let mut prop_temp = Property::new("foo", PropertyType::Float32, PropertySubType::Null);
  1140. assert!(prop_temp.set_defaults_f32(vec![1.0, 0.0]).is_err());
  1141. assert!(prop_temp.set_defaults_f32(vec![2.0]).is_ok());
  1142. prop_temp.allow_null_values();
  1143. let prop = Arc::new(prop_temp);
  1144. let atom = &mut PropertyAtomicGuard::none();
  1145. prop.set_null(atom, Role::App, 0).unwrap();
  1146. assert!(prop.get_f32_opt(1).is_err());
  1147. assert!(prop.get_f32_opt(0).is_ok());
  1148. assert!(prop.get_f32_opt(0).unwrap().is_none());
  1149. prop.clear_values(atom, Role::App);
  1150. assert!(prop.get_f32(0).is_ok());
  1151. assert!(prop.get_f32_opt(0).unwrap().is_some());
  1152. assert_eq!(prop.get_f32(0).unwrap(), 2.0);
  1153. }
  1154. #[test]
  1155. fn test_nonnullable() {
  1156. let prop = Arc::new(Property::new("foo", PropertyType::Float32, PropertySubType::Null));
  1157. let atom = &mut PropertyAtomicGuard::none();
  1158. assert!(prop.set_null(atom, Role::App, 0).is_err());
  1159. assert!(prop.is_unset(0).unwrap());
  1160. }
  1161. #[test]
  1162. fn test_unbounded() {
  1163. let mut prop_temp = Property::new("foo", PropertyType::Float32, PropertySubType::Null);
  1164. prop_temp.set_unbounded();
  1165. prop_temp.allow_null_values();
  1166. let prop = Arc::new(prop_temp);
  1167. let atom = &mut PropertyAtomicGuard::none();
  1168. assert_eq!(prop.get_len(), 0);
  1169. prop.push_f32(atom, Role::App, 2.0).unwrap();
  1170. prop.push_f32(atom, Role::App, 3.0).unwrap();
  1171. assert_eq!(prop.get_len(), 2);
  1172. prop.clear_values(atom, Role::App);
  1173. assert_eq!(prop.get_len(), 0);
  1174. prop.push_null(atom, Role::App).unwrap();
  1175. prop.push_f32(atom, Role::App, 4.0).unwrap();
  1176. prop.push_f32(atom, Role::App, 5.0).unwrap();
  1177. assert_eq!(prop.get_len(), 3);
  1178. assert!(prop.get_f32_opt(0).unwrap().is_none());
  1179. assert!(prop.get_f32_opt(1).unwrap().is_some());
  1180. assert!(prop.get_f32_opt(2).unwrap().is_some());
  1181. assert!(prop.get_f32_opt(3).is_err());
  1182. let prop2 = Arc::new(Property::new("foo", PropertyType::Float32, PropertySubType::Null));
  1183. let atom2 = &mut PropertyAtomicGuard::none();
  1184. assert!(prop2.push_f32(atom2, Role::App, 4.0).is_err());
  1185. }
  1186. #[test]
  1187. fn test_range() {
  1188. let mut prop_temp = Property::new("foo", PropertyType::Float32, PropertySubType::Null);
  1189. let half_pi = 3.1415926535 / 2.;
  1190. prop_temp.set_range_f32(-half_pi, half_pi);
  1191. let prop = Arc::new(prop_temp);
  1192. let atom = &mut PropertyAtomicGuard::none();
  1193. assert!(prop.set_f32(atom, Role::App, 0, 6.).is_err());
  1194. assert!(prop.set_f32(atom, Role::App, 0, 1.).is_ok());
  1195. }
  1196. #[test]
  1197. fn test_enum() {
  1198. let mut prop_temp = Property::new("foo", PropertyType::Enum, PropertySubType::Null);
  1199. prop_temp.set_enum_items(vec!["ABC", "XYZ", "FOO"]).unwrap();
  1200. let prop = Arc::new(prop_temp);
  1201. let atom = &mut PropertyAtomicGuard::none();
  1202. assert!(prop.set_enum(atom, Role::App, 0, "ABC").is_ok());
  1203. assert!(prop.set_enum(atom, Role::App, 0, "BAR").is_err());
  1204. }
  1205. #[test]
  1206. fn test_expr() {
  1207. let mut prop_temp = Property::new("foo", PropertyType::Float32, PropertySubType::Null);
  1208. prop_temp.allow_exprs();
  1209. let prop = Arc::new(prop_temp);
  1210. let atom = &mut PropertyAtomicGuard::none();
  1211. assert_eq!(prop.get_f32(0).unwrap(), 0.);
  1212. let code = vec![Op::ConstFloat32(4.)];
  1213. prop.set_expr(atom, Role::App, 0, code).unwrap();
  1214. let val = prop.get_cached(0).unwrap();
  1215. assert!(val.is_null());
  1216. prop.set_cache_f32(atom, Role::App, 0, 4.).unwrap();
  1217. let val = prop.get_cached(0).unwrap();
  1218. assert_eq!(val.as_f32().unwrap(), 4.);
  1219. }
  1220. fn setup_test_property() -> Arc<Property> {
  1221. let mut prop_temp = Property::new("test", PropertyType::Str, PropertySubType::Null);
  1222. prop_temp.set_unbounded();
  1223. let prop = Arc::new(prop_temp);
  1224. let atom = &mut PropertyAtomicGuard::none();
  1225. prop.push_str(atom, Role::Internal, "Item 1").unwrap();
  1226. prop.push_str(atom, Role::Internal, "Item 2").unwrap();
  1227. prop.push_str(atom, Role::Internal, "Item 3").unwrap();
  1228. prop
  1229. }
  1230. #[test]
  1231. fn test_insert_at_beginning() {
  1232. let prop = setup_test_property();
  1233. let atom = &mut PropertyAtomicGuard::none();
  1234. prop.insert_str(atom, Role::App, 0, "NEW").unwrap();
  1235. assert_eq!(prop.get_len(), 4);
  1236. assert_eq!(prop.get_str(0).unwrap(), "NEW");
  1237. assert_eq!(prop.get_str(1).unwrap(), "Item 1");
  1238. assert_eq!(prop.get_str(2).unwrap(), "Item 2");
  1239. assert_eq!(prop.get_str(3).unwrap(), "Item 3");
  1240. }
  1241. #[test]
  1242. fn test_insert_at_end() {
  1243. let prop = setup_test_property();
  1244. let atom = &mut PropertyAtomicGuard::none();
  1245. prop.insert_str(atom, Role::App, 3, "NEW").unwrap();
  1246. assert_eq!(prop.get_len(), 4);
  1247. assert_eq!(prop.get_str(0).unwrap(), "Item 1");
  1248. assert_eq!(prop.get_str(1).unwrap(), "Item 2");
  1249. assert_eq!(prop.get_str(2).unwrap(), "Item 3");
  1250. assert_eq!(prop.get_str(3).unwrap(), "NEW");
  1251. }
  1252. #[test]
  1253. fn test_insert_in_middle() {
  1254. let prop = setup_test_property();
  1255. let atom = &mut PropertyAtomicGuard::none();
  1256. prop.insert_str(atom, Role::App, 1, "NEW").unwrap();
  1257. assert_eq!(prop.get_len(), 4);
  1258. assert_eq!(prop.get_str(0).unwrap(), "Item 1");
  1259. assert_eq!(prop.get_str(1).unwrap(), "NEW");
  1260. assert_eq!(prop.get_str(2).unwrap(), "Item 2");
  1261. assert_eq!(prop.get_str(3).unwrap(), "Item 3");
  1262. }
  1263. #[test]
  1264. fn test_insert_bounded_fails() {
  1265. let mut prop_temp = Property::new("test", PropertyType::Str, PropertySubType::Null);
  1266. prop_temp.set_array_len(3);
  1267. let prop = Arc::new(prop_temp);
  1268. let atom = &mut PropertyAtomicGuard::none();
  1269. let result = prop.insert_str(atom, Role::App, 0, "NEW");
  1270. assert!(matches!(result, Err(Error::PropertyIsBounded)));
  1271. }
  1272. #[test]
  1273. fn test_insert_out_of_bounds_fails() {
  1274. let prop = setup_test_property();
  1275. let atom = &mut PropertyAtomicGuard::none();
  1276. let result = prop.insert_str(atom, Role::App, 10, "NEW");
  1277. assert!(matches!(result, Err(Error::PropertyWrongIndex)));
  1278. }
  1279. #[test]
  1280. fn test_remove_from_beginning() {
  1281. let prop = setup_test_property();
  1282. let atom = &mut PropertyAtomicGuard::none();
  1283. let removed = prop.remove_str(atom, Role::App, 0).unwrap();
  1284. assert_eq!(removed, "Item 1");
  1285. assert_eq!(prop.get_len(), 2);
  1286. assert_eq!(prop.get_str(0).unwrap(), "Item 2");
  1287. assert_eq!(prop.get_str(1).unwrap(), "Item 3");
  1288. }
  1289. #[test]
  1290. fn test_remove_from_end() {
  1291. let prop = setup_test_property();
  1292. let atom = &mut PropertyAtomicGuard::none();
  1293. let removed = prop.remove_str(atom, Role::App, 2).unwrap();
  1294. assert_eq!(removed, "Item 3");
  1295. assert_eq!(prop.get_len(), 2);
  1296. assert_eq!(prop.get_str(0).unwrap(), "Item 1");
  1297. assert_eq!(prop.get_str(1).unwrap(), "Item 2");
  1298. }
  1299. #[test]
  1300. fn test_remove_from_middle() {
  1301. let prop = setup_test_property();
  1302. let atom = &mut PropertyAtomicGuard::none();
  1303. let removed = prop.remove_str(atom, Role::App, 1).unwrap();
  1304. assert_eq!(removed, "Item 2");
  1305. assert_eq!(prop.get_len(), 2);
  1306. assert_eq!(prop.get_str(0).unwrap(), "Item 1");
  1307. assert_eq!(prop.get_str(1).unwrap(), "Item 3");
  1308. }
  1309. #[test]
  1310. fn test_remove_bounded_fails() {
  1311. let mut prop_temp = Property::new("test", PropertyType::Str, PropertySubType::Null);
  1312. prop_temp.set_array_len(3);
  1313. let prop = Arc::new(prop_temp);
  1314. let atom = &mut PropertyAtomicGuard::none();
  1315. let result = prop.remove_str(atom, Role::App, 0);
  1316. assert!(matches!(result, Err(Error::PropertyIsBounded)));
  1317. }
  1318. #[test]
  1319. fn test_remove_out_of_bounds_fails() {
  1320. let prop = setup_test_property();
  1321. let atom = &mut PropertyAtomicGuard::none();
  1322. let result = prop.remove_str(atom, Role::App, 10);
  1323. assert!(matches!(result, Err(Error::PropertyWrongIndex)));
  1324. }
  1325. #[test]
  1326. fn test_insert_remove_mixed_types() {
  1327. let mut prop_temp = Property::new("test", PropertyType::Float32, PropertySubType::Null);
  1328. prop_temp.set_unbounded();
  1329. let prop = Arc::new(prop_temp);
  1330. let atom = &mut PropertyAtomicGuard::none();
  1331. prop.push_f32(atom, Role::App, 1.0).unwrap();
  1332. prop.push_f32(atom, Role::App, 3.0).unwrap();
  1333. prop.insert_f32(atom, Role::App, 1, 2.0).unwrap();
  1334. assert_eq!(prop.get_f32(0).unwrap(), 1.0);
  1335. assert_eq!(prop.get_f32(1).unwrap(), 2.0);
  1336. assert_eq!(prop.get_f32(2).unwrap(), 3.0);
  1337. let removed = prop.remove_f32(atom, Role::App, 1).unwrap();
  1338. assert_eq!(removed, 2.0);
  1339. assert_eq!(prop.get_len(), 2);
  1340. assert_eq!(prop.get_f32(0).unwrap(), 1.0);
  1341. assert_eq!(prop.get_f32(1).unwrap(), 3.0);
  1342. }
  1343. }