@@ -43,6 +43,10 @@ impl Position {
4343 } )
4444 }
4545
46+ pub ( super ) fn json ( self ) -> serde_json:: Value {
47+ serde_json:: json!( { "x" : self . x, "y" : self . y, "z" : self . z } )
48+ }
49+
4650 fn from_fields ( model : & PropertiesModel , field : & str ) -> Self {
4751 Self {
4852 x : model. number ( & component_name ( field, "x" ) ) ,
@@ -66,10 +70,6 @@ impl Position {
6670 z : self . z - other. z ,
6771 }
6872 }
69-
70- pub ( super ) fn json ( self ) -> serde_json:: Value {
71- serde_json:: json!( { "x" : self . x, "y" : self . y, "z" : self . z } )
72- }
7373}
7474
7575#[ derive( Clone ) ]
@@ -84,15 +84,28 @@ pub(super) fn is_angle(field: &str) -> bool {
8484 field == "rot"
8585}
8686
87+ pub ( super ) fn sub_parts ( name : & str ) -> Option < ( & str , & str ) > {
88+ name. split_once ( '.' )
89+ }
90+
91+ pub ( super ) fn number_f ( value : & serde_json:: Value ) -> f32 {
92+ value. as_f64 ( ) . unwrap_or ( 0.0 ) as f32
93+ }
94+
95+ pub ( super ) fn component_name ( field : & str , axis : & str ) -> String {
96+ format ! ( "{field}_{axis}" )
97+ }
98+
99+ pub ( super ) fn component ( name : & str ) -> Option < ( & str , & str ) > {
100+ let ( field, axis) = name. rsplit_once ( '_' ) ?;
101+ matches ! ( axis, "x" | "y" | "z" ) . then_some ( ( field, axis) )
102+ }
103+
87104/// A sub-object's field, named `parent.key` (Lua's `name .. tkey`).
88105fn sub_name ( parent : & str , key : & str ) -> String {
89106 format ! ( "{parent}.{key}" )
90107}
91108
92- pub ( super ) fn sub_parts ( name : & str ) -> Option < ( & str , & str ) > {
93- name. split_once ( '.' )
94- }
95-
96109/// Lua sends only the changed key for these, rather than the whole table: the
97110/// setters apply the keys they are given, and resending the rest would fight
98111/// with the engine's own bookkeeping.
@@ -143,27 +156,12 @@ impl PropertiesModel {
143156 }
144157 }
145158
146- fn value ( & self , name : & str ) -> FieldValue {
147- self . fields
148- . iter ( )
149- . find ( |field| field. name ( ) == name)
150- . map ( |field| field. value ( ) )
151- . unwrap_or ( FieldValue :: Text ( String :: new ( ) ) )
152- }
153-
154159 pub ( super ) fn set ( & mut self , name : & str , value : FieldValue ) {
155160 if let Some ( field) = self . fields . iter_mut ( ) . find ( |field| field. name ( ) == name) {
156161 field. set_value ( & value) ;
157162 }
158163 }
159164
160- fn number ( & self , name : & str ) -> f32 {
161- match self . value ( name) {
162- FieldValue :: Number ( n) => n,
163- _ => 0.0 ,
164- }
165- }
166-
167165 /// Build the fields for one object.
168166 ///
169167 /// Generic sub-objects (`states`, `resources`, ...) and the rules map have
@@ -370,6 +368,55 @@ impl PropertiesModel {
370368 . collect ( )
371369 }
372370
371+ pub ( super ) fn set_json_field ( & mut self , name : & str , value : & serde_json:: Value ) {
372+ // The team choice shows names, so the stored id has to be mapped back.
373+ if name == "team" {
374+ if let Some ( team) = value. as_i64 ( ) . and_then ( |id| self . team_name ( id as i32 ) ) {
375+ self . set ( name, FieldValue :: Text ( team) ) ;
376+ }
377+ return ;
378+ }
379+ if let Some ( value) = value. as_bool ( ) {
380+ self . set ( name, FieldValue :: Bool ( value) ) ;
381+ } else if let Some ( value) = value. as_str ( ) {
382+ self . set ( name, FieldValue :: Text ( value. to_string ( ) ) ) ;
383+ } else if value. is_number ( ) {
384+ self . set ( name, number ( value) ) ;
385+ }
386+ }
387+
388+ /// The reverse of `sub_value`: put a sub-object key into its field.
389+ pub ( super ) fn set_sub_field ( & mut self , name : & str , key : & str , value : & serde_json:: Value ) {
390+ let captions = match key {
391+ "fireState" => Some ( FIRE_STATES ) ,
392+ "moveState" => Some ( MOVE_STATES ) ,
393+ _ => None ,
394+ } ;
395+ if let Some ( captions) = captions {
396+ let index = value. as_i64 ( ) . unwrap_or ( 0 ) as usize ;
397+ if let Some ( caption) = captions. get ( index) {
398+ self . set ( name, FieldValue :: Text ( ( * caption) . to_string ( ) ) ) ;
399+ }
400+ return ;
401+ }
402+ self . set_json_field ( name, value) ;
403+ }
404+
405+ fn value ( & self , name : & str ) -> FieldValue {
406+ self . fields
407+ . iter ( )
408+ . find ( |field| field. name ( ) == name)
409+ . map ( |field| field. value ( ) )
410+ . unwrap_or ( FieldValue :: Text ( String :: new ( ) ) )
411+ }
412+
413+ fn number ( & self , name : & str ) -> f32 {
414+ match self . value ( name) {
415+ FieldValue :: Number ( n) => n,
416+ _ => 0.0 ,
417+ }
418+ }
419+
373420 fn sub_fields_of ( & self , parent : & str ) -> Vec < String > {
374421 self . layout
375422 . iter ( )
@@ -413,40 +460,6 @@ impl PropertiesModel {
413460 . find ( |( team_id, _) | * team_id == id)
414461 . map ( |( _, name) | name. clone ( ) )
415462 }
416-
417- pub ( super ) fn set_json_field ( & mut self , name : & str , value : & serde_json:: Value ) {
418- // The team choice shows names, so the stored id has to be mapped back.
419- if name == "team" {
420- if let Some ( team) = value. as_i64 ( ) . and_then ( |id| self . team_name ( id as i32 ) ) {
421- self . set ( name, FieldValue :: Text ( team) ) ;
422- }
423- return ;
424- }
425- if let Some ( value) = value. as_bool ( ) {
426- self . set ( name, FieldValue :: Bool ( value) ) ;
427- } else if let Some ( value) = value. as_str ( ) {
428- self . set ( name, FieldValue :: Text ( value. to_string ( ) ) ) ;
429- } else if value. is_number ( ) {
430- self . set ( name, number ( value) ) ;
431- }
432- }
433-
434- /// The reverse of `sub_value`: put a sub-object key into its field.
435- pub ( super ) fn set_sub_field ( & mut self , name : & str , key : & str , value : & serde_json:: Value ) {
436- let captions = match key {
437- "fireState" => Some ( FIRE_STATES ) ,
438- "moveState" => Some ( MOVE_STATES ) ,
439- _ => None ,
440- } ;
441- if let Some ( captions) = captions {
442- let index = value. as_i64 ( ) . unwrap_or ( 0 ) as usize ;
443- if let Some ( caption) = captions. get ( index) {
444- self . set ( name, FieldValue :: Text ( ( * caption) . to_string ( ) ) ) ;
445- }
446- return ;
447- }
448- self . set_json_field ( name, value) ;
449- }
450463}
451464
452465impl EditorModel for PropertiesModel {
@@ -488,10 +501,6 @@ fn number(value: &serde_json::Value) -> FieldValue {
488501 FieldValue :: Number ( number_f ( value) )
489502}
490503
491- pub ( super ) fn number_f ( value : & serde_json:: Value ) -> f32 {
492- value. as_f64 ( ) . unwrap_or ( 0.0 ) as f32
493- }
494-
495504fn index_of ( captions : & [ & str ] , value : & str ) -> i32 {
496505 captions
497506 . iter ( )
@@ -552,15 +561,6 @@ fn sub_field(name: &str, key: &str, value: &serde_json::Value) -> Option<Box<dyn
552561 None
553562}
554563
555- pub ( super ) fn component_name ( field : & str , axis : & str ) -> String {
556- format ! ( "{field}_{axis}" )
557- }
558-
559- pub ( super ) fn component ( name : & str ) -> Option < ( & str , & str ) > {
560- let ( field, axis) = name. rsplit_once ( '_' ) ?;
561- matches ! ( axis, "x" | "y" | "z" ) . then_some ( ( field, axis) )
562- }
563-
564564fn title ( name : & str ) -> String {
565565 let mut out = String :: new ( ) ;
566566 for ( i, ch) in name. chars ( ) . enumerate ( ) {
0 commit comments