diff --git a/src/object_pool/mod.rs b/src/object_pool/mod.rs index aab41de..2f2bae0 100644 --- a/src/object_pool/mod.rs +++ b/src/object_pool/mod.rs @@ -7,7 +7,7 @@ pub mod object_attributes; mod object_id; mod object_pool; mod object_type; -mod vt_version; +pub mod vt_version; use crate::network_management::name::NAME; diff --git a/src/object_pool/object.rs b/src/object_pool/object.rs index eb4acb0..bf0e4ec 100644 --- a/src/object_pool/object.rs +++ b/src/object_pool/object.rs @@ -11,9 +11,10 @@ use crate::object_pool::object_attributes::{ use crate::object_pool::object_id::ObjectId; use crate::object_pool::{Colour, ObjectType}; +use super::object_attributes::{DataCodeType, PictureGraphicFormat}; use super::object_id::NullableObjectId; -#[derive(Debug)] +#[derive(Debug, Clone)] pub enum Object { WorkingSet(WorkingSet), DataMask(DataMask), @@ -341,12 +342,41 @@ impl Object { refs } + + pub fn as_sized_object(&self) -> Option<&dyn SizedObject> { + match self { + Object::Container(o) => Some(o), + Object::Button(o) => Some(o), + Object::InputBoolean(o) => Some(o), + Object::InputString(o) => Some(o), + Object::InputNumber(o) => Some(o), + Object::InputList(o) => Some(o), + Object::OutputString(o) => Some(o), + Object::OutputNumber(o) => Some(o), + Object::OutputList(o) => Some(o), + Object::OutputLine(o) => Some(o), + Object::OutputRectangle(o) => Some(o), + Object::OutputEllipse(o) => Some(o), + Object::OutputPolygon(o) => Some(o), + Object::OutputMeter(o) => Some(o), + Object::OutputLinearBarGraph(o) => Some(o), + Object::OutputArchedBarGraph(o) => Some(o), + Object::PictureGraphic(o) => Some(o), + Object::ScaledGraphic(o) => Some(o), + _ => None, + } + } } -#[derive(Debug, PartialEq)] +pub trait SizedObject { + fn width(&self) -> u16; + fn height(&self) -> u16; +} + +#[derive(Debug, PartialEq, Clone)] pub struct WorkingSet { pub id: ObjectId, - pub background_colour: Colour, + pub background_colour: u8, pub selectable: bool, pub active_mask: ObjectId, pub object_refs: Vec, @@ -354,7 +384,7 @@ pub struct WorkingSet { pub language_codes: Vec, } -#[derive(Debug, PartialEq)] +#[derive(Debug, PartialEq, Clone)] pub struct DataMask { pub id: ObjectId, pub background_colour: u8, @@ -363,7 +393,7 @@ pub struct DataMask { pub macro_refs: Vec, } -#[derive(Debug, PartialEq)] +#[derive(Debug, PartialEq, Clone)] pub struct AlarmMask { pub id: ObjectId, pub background_colour: u8, @@ -374,7 +404,7 @@ pub struct AlarmMask { pub macro_refs: Vec, } -#[derive(Debug, PartialEq)] +#[derive(Debug, PartialEq, Clone)] pub struct Container { pub id: ObjectId, pub width: u16, @@ -384,7 +414,17 @@ pub struct Container { pub macro_refs: Vec, } -#[derive(Debug, PartialEq)] +impl SizedObject for Container { + fn width(&self) -> u16 { + self.width + } + + fn height(&self) -> u16 { + self.height + } +} + +#[derive(Debug, PartialEq, Clone)] pub struct SoftKeyMask { pub id: ObjectId, pub background_colour: u8, @@ -392,7 +432,7 @@ pub struct SoftKeyMask { pub macro_refs: Vec, } -#[derive(Debug, PartialEq)] +#[derive(Debug, PartialEq, Clone)] pub struct Key { pub id: ObjectId, pub background_colour: u8, @@ -401,7 +441,7 @@ pub struct Key { pub macro_refs: Vec, } -#[derive(Debug, PartialEq)] +#[derive(Debug, PartialEq, Clone)] pub struct Button { pub id: ObjectId, pub width: u16, @@ -414,7 +454,17 @@ pub struct Button { pub macro_refs: Vec, } -#[derive(Debug, PartialEq)] +impl SizedObject for Button { + fn width(&self) -> u16 { + self.width + } + + fn height(&self) -> u16 { + self.height + } +} + +#[derive(Debug, PartialEq, Clone)] pub struct InputBoolean { pub id: ObjectId, pub background_colour: u8, @@ -426,7 +476,17 @@ pub struct InputBoolean { pub macro_refs: Vec, } -#[derive(Debug, PartialEq)] +impl SizedObject for InputBoolean { + fn width(&self) -> u16 { + self.width + } + + fn height(&self) -> u16 { + self.width + } +} + +#[derive(Debug, PartialEq, Clone)] pub struct InputString { pub id: ObjectId, pub width: u16, @@ -442,6 +502,16 @@ pub struct InputString { pub macro_refs: Vec, } +impl SizedObject for InputString { + fn width(&self) -> u16 { + self.width + } + + fn height(&self) -> u16 { + self.height + } +} + #[derive(Debug, Clone, PartialEq)] pub struct InputNumber { pub id: ObjectId, @@ -463,6 +533,16 @@ pub struct InputNumber { pub macro_refs: Vec, } +impl SizedObject for InputNumber { + fn width(&self) -> u16 { + self.width + } + + fn height(&self) -> u16 { + self.height + } +} + #[derive(Debug, PartialEq, Clone)] pub struct InputList { pub id: ObjectId, @@ -475,6 +555,16 @@ pub struct InputList { pub macro_refs: Vec, } +impl SizedObject for InputList { + fn width(&self) -> u16 { + self.width + } + + fn height(&self) -> u16 { + self.height + } +} + #[derive(Debug, PartialEq, Clone)] pub struct OutputString { pub id: ObjectId, @@ -489,7 +579,17 @@ pub struct OutputString { pub macro_refs: Vec, } -#[derive(Debug, PartialEq)] +impl SizedObject for OutputString { + fn width(&self) -> u16 { + self.width + } + + fn height(&self) -> u16 { + self.height + } +} + +#[derive(Debug, PartialEq, Clone)] pub struct OutputNumber { pub id: ObjectId, pub width: u16, @@ -507,6 +607,16 @@ pub struct OutputNumber { pub macro_refs: Vec, } +impl SizedObject for OutputNumber { + fn width(&self) -> u16 { + self.width + } + + fn height(&self) -> u16 { + self.height + } +} + #[derive(Debug, PartialEq, Clone)] pub struct OutputList { pub id: ObjectId, @@ -518,6 +628,16 @@ pub struct OutputList { pub macro_refs: Vec, } +impl SizedObject for OutputList { + fn width(&self) -> u16 { + self.width + } + + fn height(&self) -> u16 { + self.height + } +} + #[derive(Debug, PartialEq, Clone)] pub struct OutputLine { pub id: ObjectId, @@ -528,7 +648,17 @@ pub struct OutputLine { pub macro_refs: Vec, } -#[derive(Debug)] +impl SizedObject for OutputLine { + fn width(&self) -> u16 { + self.width + } + + fn height(&self) -> u16 { + self.height + } +} + +#[derive(Debug, Clone)] pub struct OutputRectangle { pub id: ObjectId, pub line_attributes: ObjectId, @@ -539,7 +669,17 @@ pub struct OutputRectangle { pub macro_refs: Vec, } -#[derive(Debug)] +impl SizedObject for OutputRectangle { + fn width(&self) -> u16 { + self.width + } + + fn height(&self) -> u16 { + self.height + } +} + +#[derive(Debug, Clone)] pub struct OutputEllipse { pub id: ObjectId, pub line_attributes: ObjectId, @@ -552,7 +692,17 @@ pub struct OutputEllipse { pub macro_refs: Vec, } -#[derive(Debug)] +impl SizedObject for OutputEllipse { + fn width(&self) -> u16 { + self.width + } + + fn height(&self) -> u16 { + self.height + } +} + +#[derive(Debug, Clone)] pub struct OutputPolygon { pub id: ObjectId, pub width: u16, @@ -564,7 +714,17 @@ pub struct OutputPolygon { pub macro_refs: Vec, } -#[derive(Debug)] +impl SizedObject for OutputPolygon { + fn width(&self) -> u16 { + self.width + } + + fn height(&self) -> u16 { + self.height + } +} + +#[derive(Debug, Clone)] pub struct OutputMeter { pub id: ObjectId, pub width: u16, @@ -582,7 +742,17 @@ pub struct OutputMeter { pub macro_refs: Vec, } -#[derive(Debug, Clone, PartialEq, Eq)] +impl SizedObject for OutputMeter { + fn width(&self) -> u16 { + self.width + } + + fn height(&self) -> u16 { + self.width + } +} + +#[derive(Debug, Clone, PartialEq)] pub struct OutputLinearBarGraph { pub id: ObjectId, pub width: u16, @@ -600,7 +770,17 @@ pub struct OutputLinearBarGraph { pub macro_refs: Vec, } -#[derive(Debug)] +impl SizedObject for OutputLinearBarGraph { + fn width(&self) -> u16 { + self.width + } + + fn height(&self) -> u16 { + self.height + } +} + +#[derive(Debug, Clone)] pub struct OutputArchedBarGraph { pub id: ObjectId, pub width: u16, @@ -620,32 +800,89 @@ pub struct OutputArchedBarGraph { pub macro_refs: Vec, } -#[derive(Debug)] +impl SizedObject for OutputArchedBarGraph { + fn width(&self) -> u16 { + self.width + } + + fn height(&self) -> u16 { + self.height + } +} + +#[derive(Debug, Clone)] pub struct PictureGraphic { pub id: ObjectId, pub width: u16, pub actual_width: u16, pub actual_height: u16, - pub format: u8, + pub format: PictureGraphicFormat, pub options: PictureGraphicOptions, pub transparency_colour: u8, pub data: Vec, pub macro_refs: Vec, } -#[derive(Debug)] +impl PictureGraphic { + pub fn data_as_raw_encoded(&self) -> Vec { + match self.options.data_code_type { + DataCodeType::Raw => self.data.clone(), + DataCodeType::RunLength => { + let mut raw_data = vec![]; + let mut i = 0; + while i < self.data.len() { + let count = self.data[i] as usize; + let value = self.data[i + 1]; + raw_data.extend(vec![value; count]); + i += 2; + } + raw_data + } + } + } + + pub fn data_as_run_length_encoded(&self) -> Vec { + match self.options.data_code_type { + DataCodeType::Raw => { + let mut run_length_data = vec![]; + let mut i = 0; + while i < self.data.len() { + let value = self.data[i]; + let count = self.data[i..].iter().take_while(|&&x| x == value).count(); + run_length_data.push(count as u8); + run_length_data.push(value); + i += count; + } + run_length_data + } + DataCodeType::RunLength => self.data.clone(), + } + } +} + +impl SizedObject for PictureGraphic { + fn width(&self) -> u16 { + self.width + } + + fn height(&self) -> u16 { + self.actual_height * (self.width / self.actual_width) + } +} + +#[derive(Debug, Clone)] pub struct NumberVariable { pub id: ObjectId, pub value: u32, } -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct StringVariable { pub id: ObjectId, pub value: String, } -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct FontAttributes { pub id: ObjectId, pub font_colour: u8, @@ -655,7 +892,7 @@ pub struct FontAttributes { pub macro_refs: Vec, } -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct LineAttributes { pub id: ObjectId, pub line_colour: u8, @@ -664,7 +901,7 @@ pub struct LineAttributes { pub macro_refs: Vec, } -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct FillAttributes { pub id: ObjectId, pub fill_type: u8, @@ -673,7 +910,7 @@ pub struct FillAttributes { pub macro_refs: Vec, } -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct InputAttributes { pub id: ObjectId, pub validation_type: u8, @@ -706,38 +943,38 @@ impl From for ValidationType { } } -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct CharacterRange { pub first_character: u16, pub last_character: u16, } -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct CodePlane { pub number: u8, pub character_ranges: Vec, } -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct ExtendedInputAttributes { pub id: ObjectId, pub validation_type: ValidationType, pub code_planes: Vec, } -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct ObjectPointer { pub id: ObjectId, pub value: NullableObjectId, } -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct Macro { pub id: ObjectId, pub commands: Vec, } -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct AuxiliaryFunctionType1 { pub id: ObjectId, pub background_colour: u8, @@ -745,7 +982,7 @@ pub struct AuxiliaryFunctionType1 { pub object_refs: Vec, } -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct AuxiliaryInputType1 { pub id: ObjectId, pub background_colour: u8, @@ -754,7 +991,7 @@ pub struct AuxiliaryInputType1 { pub object_refs: Vec, } -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct AuxiliaryFunctionType2 { pub id: ObjectId, pub background_colour: u8, @@ -762,7 +999,7 @@ pub struct AuxiliaryFunctionType2 { pub object_refs: Vec, } -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct AuxiliaryInputType2 { pub id: ObjectId, pub background_colour: u8, @@ -770,14 +1007,14 @@ pub struct AuxiliaryInputType2 { pub object_refs: Vec, } -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct AuxiliaryControlDesignatorType2 { pub id: ObjectId, pub pointer_type: u8, pub auxiliary_object_id: ObjectId, } -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct ColourMap { pub id: ObjectId, pub colour_map: Vec, @@ -805,6 +1042,16 @@ pub struct GraphicsContext { pub transparency_colour: u8, } +impl SizedObject for GraphicsContext { + fn width(&self) -> u16 { + self.viewport_width + } + + fn height(&self) -> u16 { + self.viewport_height + } +} + #[derive(Debug, Clone, PartialEq)] pub struct WindowMask { pub id: ObjectId, @@ -820,7 +1067,7 @@ pub struct WindowMask { pub macro_refs: Vec, } -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq)] pub struct KeyGroup { pub id: ObjectId, pub options: KeyGroupOptions, @@ -830,7 +1077,7 @@ pub struct KeyGroup { pub macro_refs: Vec, } -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct ObjectLabelReferenceList { pub id: ObjectId, pub object_labels: Vec, @@ -844,14 +1091,14 @@ pub struct ExternalObjectDefinition { pub objects: Vec, } -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct ExternalReferenceName { pub id: ObjectId, pub options: ExternalReferenceNameOptions, pub name: NAME, } -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct ExternalObjectPointer { pub id: ObjectId, pub default_object_id: NullableObjectId, @@ -859,7 +1106,7 @@ pub struct ExternalObjectPointer { pub external_object_id: NullableObjectId, } -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct Animation { pub id: ObjectId, pub width: u16, @@ -875,21 +1122,31 @@ pub struct Animation { pub macro_refs: Vec, } -#[derive(Debug)] +impl SizedObject for Animation { + fn width(&self) -> u16 { + self.width + } + + fn height(&self) -> u16 { + self.height + } +} + +#[derive(Debug, Clone)] pub struct ColourPalette { pub id: ObjectId, pub options: ColourPaletteOptions, pub colours: Vec, } -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct GraphicData { pub id: ObjectId, pub format: u8, pub data: Vec, } -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct ScaledGraphic { pub id: ObjectId, pub width: u16, @@ -900,7 +1157,17 @@ pub struct ScaledGraphic { pub macro_refs: Vec, } -#[derive(Debug)] +impl SizedObject for ScaledGraphic { + fn width(&self) -> u16 { + self.width + } + + fn height(&self) -> u16 { + self.height + } +} + +#[derive(Debug, Clone)] pub struct WorkingSetSpecialControls { pub id: ObjectId, pub id_of_colour_map: NullableObjectId, diff --git a/src/object_pool/object_attributes.rs b/src/object_pool/object_attributes.rs index ce42ed0..d12b7a9 100644 --- a/src/object_pool/object_attributes.rs +++ b/src/object_pool/object_attributes.rs @@ -39,7 +39,7 @@ impl From for WindowType { impl From for u8 { fn from(value: WindowType) -> Self { - value.into() + value as u8 } } @@ -131,11 +131,81 @@ impl From for u8 { let mut bit_data: BitVec = BitVec::new(); bit_data.push(value.available); bit_data.push(value.transparent); - bit_data.extend([0; 6]); + bit_data.extend([false; 6]); bit_data.load::() } } +#[derive(FromRepr, Debug, PartialEq, Clone, Copy)] +#[repr(u8)] +pub enum Event { + Reserved = 0, + OnActivate = 1, + OnDeactivate = 2, + OnShow = 3, + OnHide = 4, + // OnRefresh = N/A + OnEnable = 5, + OnDisable = 6, + OnChangeActiveMask = 7, + OnChangeSoftKeyMask = 8, + OnChangeAttribute = 9, + OnChangeBackgroundColour = 10, + OnChangeFontAttributes = 11, + OnChangeLineAttributes = 12, + OnChangeFillAttributes = 13, + OnChangeChildLocation = 14, + OnChangeSize = 15, + OnChangeValue = 16, + OnChangePriority = 17, + OnChangeEndPoint = 18, + OnInputFieldSelection = 19, + OnInputFieldDeselection = 20, + OnESC = 21, + OnEntryOfValue = 22, + OnEntryOfNewValue = 23, + OnKeyPress = 24, + OnKeyRelease = 25, + OnChangeChildPosition = 26, + OnPointingEventPress = 27, + OnPointingEventRelease = 28, + // Reserved 29-239 + ProprietaryEvent1 = 240, + ProprietaryEvent2 = 241, + ProprietaryEvent3 = 242, + ProprietaryEvent4 = 243, + ProprietaryEvent5 = 244, + ProprietaryEvent6 = 245, + ProprietaryEvent7 = 246, + ProprietaryEvent8 = 247, + ProprietaryEvent9 = 248, + ProprietaryEvent10 = 249, + ProprietaryEvent11 = 250, + ProprietaryEvent12 = 251, + ProprietaryEvent13 = 252, + ProprietaryEvent14 = 253, + ProprietaryEvent15 = 254, + UseExtendedMacro = 255, +} + +impl Event { + pub fn iter() -> impl Iterator { + (0..=255).map(Event::from).filter(|e| *e != Event::Reserved) + } +} + +impl From for Event { + fn from(value: u8) -> Self { + Event::from_repr(value).unwrap_or(Event::Reserved) + } +} + +impl From for u8 { + fn from(value: Event) -> Self { + value as u8 + } +} + #[derive(Debug, PartialEq, Clone)] pub struct ObjectRef { pub id: ObjectId, @@ -144,10 +214,10 @@ pub struct ObjectRef { // pub y: i16, } -#[derive(Debug, PartialEq, Eq, Clone)] +#[derive(Debug, PartialEq, Clone)] pub struct MacroRef { pub macro_id: u8, - pub event_id: u8, + pub event_id: Event, } #[derive(Debug, Default, Clone, Copy, PartialEq)] @@ -167,7 +237,7 @@ impl core::ops::Add> for Point { } } -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct ObjectLabel { pub id: ObjectId, pub string_variable_reference: NullableObjectId, @@ -208,7 +278,7 @@ impl From for u8 { bit_data.push(value.transparent_background); bit_data.push(value.disabled); bit_data.push(value.no_border); - bit_data.extend([0; 3]); + bit_data.extend([false; 2]); bit_data.load::() } } @@ -261,7 +331,7 @@ impl From for u8 { bit_data.push(value.transparent); bit_data.push(value.auto_wrap); bit_data.push(value.wrap_on_hyphen); - bit_data.extend([0; 5]); + bit_data.extend([false; 5]); bit_data.load::() } } @@ -274,7 +344,7 @@ pub struct Alignment { impl From for Alignment { fn from(value: u8) -> Self { - let mut bit_data = value.view_bits::().to_bitvec(); + let mut bit_data = value.view_bits::().to_bitvec(); Alignment { horizontal: HorizontalAlignment::from([ bit_data.pop().unwrap(), @@ -390,7 +460,7 @@ impl From for u8 { let mut bit_data: BitVec = BitVec::new(); bit_data.push(value.enabled); bit_data.push(value.real_time_editing); - bit_data.extend([0; 6]); + bit_data.extend([false; 6]); bit_data.load::() } } @@ -440,7 +510,7 @@ impl From for u8 { let mut bit_data: BitVec = BitVec::new(); bit_data.push(value.enabled); bit_data.push(value.real_time_editing); - bit_data.extend([0; 6]); + bit_data.extend([false; 6]); bit_data.load::() } } @@ -515,7 +585,7 @@ impl From for u8 { bit_data.push(value.display_leading_zeros); bit_data.push(value.display_zero_as_blank); bit_data.push(value.truncate); - bit_data.extend([0; 4]); + bit_data.extend([false; 4]); bit_data.load::() } } @@ -526,7 +596,7 @@ impl From for u8 { bit_data.push(value.transparent); bit_data.push(value.auto_wrap); bit_data.push(value.wrap_on_hyphen); - bit_data.extend([0; 5]); + bit_data.extend([false; 5]); bit_data.load::() } } @@ -591,7 +661,7 @@ pub struct GraphicsContextOptions { impl From for GraphicsContextOptions { fn from(value: u8) -> Self { - let mut bit_data = value.view_bits::().to_bitvec(); + let mut bit_data = value.view_bits::().to_bitvec(); GraphicsContextOptions { transparent: bit_data.pop().unwrap(), color: bit_data.pop().unwrap().into(), @@ -604,7 +674,7 @@ impl From for u8 { let mut bit_data: BitVec = BitVec::new(); bit_data.push(value.transparent); bit_data.push(value.color.into()); - bit_data.extend([0; 6]); + bit_data.extend([false; 6]); bit_data.load::() } } @@ -617,7 +687,7 @@ pub struct KeyGroupOptions { impl From for KeyGroupOptions { fn from(value: u8) -> Self { - let mut bit_data = value.view_bits::().to_bitvec(); + let mut bit_data = value.view_bits::().to_bitvec(); KeyGroupOptions { available: bit_data.pop().unwrap(), transparent: bit_data.pop().unwrap(), @@ -630,7 +700,7 @@ impl From for u8 { let mut bit_data: BitVec = BitVec::new(); bit_data.push(value.available); bit_data.push(value.transparent); - bit_data.extend([0; 6]); + bit_data.extend([false; 6]); bit_data.load::() } } @@ -669,7 +739,7 @@ pub struct OutputMeterOptions { impl From for OutputMeterOptions { fn from(value: u8) -> Self { - let mut bit_data = value.view_bits::().to_bitvec(); + let mut bit_data = value.view_bits::().to_bitvec(); OutputMeterOptions { draw_arc: bit_data.pop().unwrap(), draw_border: bit_data.pop().unwrap(), @@ -686,7 +756,7 @@ impl From for u8 { bit_data.push(value.draw_border); bit_data.push(value.draw_ticks); bit_data.push(value.deflection_direction.into()); - bit_data.extend([0; 4]); + bit_data.extend([false; 4]); bit_data.load::() } } @@ -775,7 +845,7 @@ pub struct OutputLinearBarGraphOptions { impl From for OutputLinearBarGraphOptions { fn from(value: u8) -> Self { - let mut bit_data = value.view_bits::().to_bitvec(); + let mut bit_data = value.view_bits::().to_bitvec(); OutputLinearBarGraphOptions { draw_border: bit_data.pop().unwrap(), draw_target_line: bit_data.pop().unwrap(), @@ -796,7 +866,7 @@ impl From for u8 { bit_data.push(value.bar_graph_type.into()); bit_data.push(value.axis_orientation.into()); bit_data.push(value.grow_direction.into()); - bit_data.extend([0; 2]); + bit_data.extend([false; 2]); bit_data.load::() } } @@ -813,7 +883,7 @@ pub struct OutputArchedBarGraphOptions { impl From for OutputArchedBarGraphOptions { fn from(value: u8) -> Self { - let mut bit_data = value.view_bits::().to_bitvec(); + let mut bit_data = value.view_bits::().to_bitvec(); let draw_border = bit_data.pop().unwrap(); let draw_target_line = bit_data.pop().unwrap(); bit_data.pop(); //undefined bit @@ -839,7 +909,7 @@ impl From for u8 { bit_data.push(value.axis_orientation.into()); bit_data.push(value.grow_direction.into()); bit_data.push(value.deflection_direction.into()); - bit_data.extend([0; 1]); + bit_data.extend([false; 1]); bit_data.load::() } } @@ -868,6 +938,26 @@ impl From for bool { } } +#[derive(FromRepr, Debug, PartialEq, Clone, Copy)] +#[repr(u8)] +pub enum PictureGraphicFormat { + Monochrome = 0, + FourBit = 1, + EightBit = 2, +} + +impl From for PictureGraphicFormat { + fn from(value: u8) -> Self { + PictureGraphicFormat::from_repr(value).unwrap() + } +} + +impl From for u8 { + fn from(value: PictureGraphicFormat) -> Self { + value as u8 + } +} + #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct PictureGraphicOptions { pub transparent: bool, @@ -877,7 +967,7 @@ pub struct PictureGraphicOptions { impl From for PictureGraphicOptions { fn from(value: u8) -> Self { - let mut bit_data = value.view_bits::().to_bitvec(); + let mut bit_data = value.view_bits::().to_bitvec(); PictureGraphicOptions { transparent: bit_data.pop().unwrap(), flashing: bit_data.pop().unwrap(), @@ -892,7 +982,7 @@ impl From for u8 { bit_data.push(value.transparent); bit_data.push(value.flashing); bit_data.push(value.data_code_type.into()); - bit_data.extend([0; 5]); + bit_data.extend([false; 5]); bit_data.load::() } } @@ -904,7 +994,7 @@ pub struct ExternalObjectDefinitionOptions { impl From for ExternalObjectDefinitionOptions { fn from(value: u8) -> Self { - let mut bit_data = value.view_bits::().to_bitvec(); + let mut bit_data = value.view_bits::().to_bitvec(); ExternalObjectDefinitionOptions { enabled: bit_data.pop().unwrap(), } @@ -915,7 +1005,7 @@ impl From for u8 { fn from(value: ExternalObjectDefinitionOptions) -> u8 { let mut bit_data: BitVec = BitVec::new(); bit_data.push(value.enabled); - bit_data.extend([0; 7]); + bit_data.extend([false; 7]); bit_data.load::() } } @@ -927,7 +1017,7 @@ pub struct ExternalReferenceNameOptions { impl From for ExternalReferenceNameOptions { fn from(value: u8) -> Self { - let mut bit_data = value.view_bits::().to_bitvec(); + let mut bit_data = value.view_bits::().to_bitvec(); ExternalReferenceNameOptions { enabled: bit_data.pop().unwrap(), } @@ -938,7 +1028,7 @@ impl From for u8 { fn from(value: ExternalReferenceNameOptions) -> u8 { let mut bit_data: BitVec = BitVec::new(); bit_data.push(value.enabled); - bit_data.extend([0; 7]); + bit_data.extend([false; 7]); bit_data.load::() } } @@ -1023,7 +1113,7 @@ impl From for u8 { let disabled_behaviour: [bool; 2] = value.disabled_behaviour.into(); bit_data.push(disabled_behaviour[0]); bit_data.push(disabled_behaviour[1]); - bit_data.extend([0; 5]); + bit_data.extend([false; 5]); bit_data.load::() } } @@ -1041,7 +1131,7 @@ impl From for ColourPaletteOptions { impl From for u8 { fn from(_value: ColourPaletteOptions) -> u8 { let mut bit_data: BitVec = BitVec::new(); - bit_data.extend([0; 8]); + bit_data.extend([false; 8]); bit_data.load::() } } @@ -1064,7 +1154,7 @@ impl From for u8 { fn from(value: ScaledGraphicOptions) -> u8 { let mut bit_data: BitVec = BitVec::new(); bit_data.push(value.flashing); - bit_data.extend([0; 7]); + bit_data.extend([false; 7]); bit_data.load::() } } diff --git a/src/object_pool/object_id.rs b/src/object_pool/object_id.rs index fd42461..ee304e9 100644 --- a/src/object_pool/object_id.rs +++ b/src/object_pool/object_id.rs @@ -15,6 +15,10 @@ impl ObjectId { Ok(ObjectId { id }) } } + + pub fn value(&self) -> u16 { + self.id + } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] diff --git a/src/object_pool/object_pool.rs b/src/object_pool/object_pool.rs index 952315b..75df2ad 100644 --- a/src/object_pool/object_pool.rs +++ b/src/object_pool/object_pool.rs @@ -7,16 +7,13 @@ use crate::object_pool::object::{ use crate::object_pool::object_id::ObjectId; use crate::object_pool::vt_version::VtVersion; use crate::object_pool::ObjectType; -use core::cell::Cell; -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct ObjectPool { objects: Vec, colour_map: [u8; 256], colour_palette: [Colour; 256], _supported_vt_version: VtVersion, - - size_cache: Cell>, } impl ObjectPool { @@ -32,16 +29,11 @@ impl ObjectPool { colour_map, colour_palette: Colour::COLOUR_PALETTE, _supported_vt_version: VtVersion::default(), - - size_cache: Cell::new(None), } } pub fn size(&self) -> usize { - if self.size_cache.get().is_none() { - self.size_cache.set(Some(self.as_iop().len())); - } - self.size_cache.get().unwrap_or_default() + self.objects.len() } /// @@ -112,10 +104,18 @@ impl ObjectPool { self.objects.push(obj); } + pub fn remove(&mut self, id: ObjectId) { + self.objects.retain(|x| x.id() != id); + } + pub fn object_by_id(&self, id: ObjectId) -> Option<&Object> { self.objects.iter().find(|&o| o.id() == id) } + pub fn object_mut_by_id(&mut self, id: ObjectId) -> Option<&mut Object> { + self.objects.iter_mut().find(|o| o.id() == id) + } + pub fn objects_by_type(&self, object_type: ObjectType) -> Vec<&Object> { self.objects .iter() @@ -123,6 +123,13 @@ impl ObjectPool { .collect() } + pub fn objects_by_types(&self, object_types: &[ObjectType]) -> Vec<&Object> { + self.objects + .iter() + .filter(|&o| object_types.contains(&o.object_type())) + .collect() + } + // Get objects by type pub fn working_set_object(&self) -> Option<&WorkingSet> { diff --git a/src/object_pool/reader.rs b/src/object_pool/reader.rs index df58023..75965d0 100644 --- a/src/object_pool/reader.rs +++ b/src/object_pool/reader.rs @@ -77,7 +77,7 @@ impl Object { ) -> Result, ParseError> { let mut objs = Vec::new(); for _ in 0..nr_of_objects { - objs.push(Self::read_u16(data)?.try_into()?); + objs.push(Self::read_u16(data)?.clamp(0, u16::MAX - 1).try_into()?); } Ok(objs) } @@ -116,7 +116,7 @@ impl Object { let mut refs = Vec::new(); for _ in 0..nr_of_macros { refs.push(MacroRef { - event_id: Self::read_u8(data)?, + event_id: Self::read_u8(data)?.into(), macro_id: Self::read_u8(data)?, }) } @@ -375,7 +375,7 @@ impl Object { ) -> Result { let mut o = DataMask { id, - background_colour: Self::read_u8(data)?, + background_colour: Self::read_u8(data)?.into(), soft_key_mask: Self::read_u16(data)?.into(), object_refs: Vec::with_capacity(Self::read_u8(data)?.into()), macro_refs: Vec::with_capacity(Self::read_u8(data)?.into()), @@ -395,7 +395,7 @@ impl Object { ) -> Result { let mut o = AlarmMask { id, - background_colour: Self::read_u8(data)?, + background_colour: Self::read_u8(data)?.into(), soft_key_mask: Self::read_u16(data)?.into(), priority: Self::read_u8(data)?, acoustic_signal: Self::read_u8(data)?, @@ -438,7 +438,7 @@ impl Object { ) -> Result { let mut o = SoftKeyMask { id, - background_colour: Self::read_u8(data)?, + background_colour: Self::read_u8(data)?.into(), objects: Vec::with_capacity(Self::read_u8(data)?.into()), macro_refs: Vec::with_capacity(Self::read_u8(data)?.into()), }; @@ -454,7 +454,7 @@ impl Object { fn read_key(id: ObjectId, data: &mut dyn Iterator) -> Result { let mut o = Key { id, - background_colour: Self::read_u8(data)?, + background_colour: Self::read_u8(data)?.into(), key_code: Self::read_u8(data)?, object_refs: Vec::with_capacity(Self::read_u8(data)?.into()), macro_refs: Vec::with_capacity(Self::read_u8(data)?.into()), @@ -473,8 +473,8 @@ impl Object { id, width: Self::read_u16(data)?, height: Self::read_u16(data)?, - background_colour: Self::read_u8(data)?, - border_colour: Self::read_u8(data)?, + background_colour: Self::read_u8(data)?.into(), + border_colour: Self::read_u8(data)?.into(), key_code: Self::read_u8(data)?, options: Self::read_u8(data)?.into(), object_refs: Vec::with_capacity(Self::read_u8(data)?.into()), @@ -495,7 +495,7 @@ impl Object { ) -> Result { let mut o = InputBoolean { id, - background_colour: Self::read_u8(data)?, + background_colour: Self::read_u8(data)?.into(), width: Self::read_u16(data)?, foreground_colour: Self::read_u16(data)?.try_into()?, variable_reference: Self::read_u16(data)?.into(), @@ -518,7 +518,7 @@ impl Object { id, width: Self::read_u16(data)?, height: Self::read_u16(data)?, - background_colour: Self::read_u8(data)?, + background_colour: Self::read_u8(data)?.into(), font_attributes: Self::read_u16(data)?.try_into()?, input_attributes: Self::read_u16(data)?.into(), options: Self::read_u8(data)?.into(), @@ -543,7 +543,7 @@ impl Object { id, width: Self::read_u16(data)?, height: Self::read_u16(data)?, - background_colour: Self::read_u8(data)?, + background_colour: Self::read_u8(data)?.into(), font_attributes: Self::read_u16(data)?.try_into()?, options: Self::read_u8(data)?.into(), variable_reference: Self::read_u16(data)?.into(), @@ -598,7 +598,7 @@ impl Object { id, width: Self::read_u16(data)?, height: Self::read_u16(data)?, - background_colour: Self::read_u8(data)?, + background_colour: Self::read_u8(data)?.into(), font_attributes: Self::read_u16(data)?.try_into()?, options: Self::read_u8(data)?.into(), variable_reference: Self::read_u16(data)?.into(), @@ -621,7 +621,7 @@ impl Object { id, width: Self::read_u16(data)?, height: Self::read_u16(data)?, - background_colour: Self::read_u8(data)?, + background_colour: Self::read_u8(data)?.into(), font_attributes: Self::read_u16(data)?.try_into()?, options: Self::read_u8(data)?.into(), variable_reference: Self::read_u16(data)?.into(), @@ -731,9 +731,9 @@ impl Object { let mut o = OutputMeter { id, width: Self::read_u16(data)?, - needle_colour: Self::read_u8(data)?, - border_colour: Self::read_u8(data)?, - arc_and_tick_colour: Self::read_u8(data)?, + needle_colour: Self::read_u8(data)?.into(), + border_colour: Self::read_u8(data)?.into(), + arc_and_tick_colour: Self::read_u8(data)?.into(), options: Self::read_u8(data)?.into(), nr_of_ticks: Self::read_u8(data)?, start_angle: Self::read_u8(data)?, @@ -759,8 +759,8 @@ impl Object { id, width: Self::read_u16(data)?, height: Self::read_u16(data)?, - colour: Self::read_u8(data)?, - target_line_colour: Self::read_u8(data)?, + colour: Self::read_u8(data)?.into(), + target_line_colour: Self::read_u8(data)?.into(), options: Self::read_u8(data)?.into(), nr_of_ticks: Self::read_u8(data)?, min_value: Self::read_u16(data)?, @@ -786,8 +786,8 @@ impl Object { id, width: Self::read_u16(data)?, height: Self::read_u16(data)?, - colour: Self::read_u8(data)?, - target_line_colour: Self::read_u8(data)?, + colour: Self::read_u8(data)?.into(), + target_line_colour: Self::read_u8(data)?.into(), options: Self::read_u8(data)?.into(), start_angle: Self::read_u8(data)?, end_angle: Self::read_u8(data)?, @@ -816,16 +816,19 @@ impl Object { width: Self::read_u16(data)?, actual_width: Self::read_u16(data)?, actual_height: Self::read_u16(data)?, - format: Self::read_u8(data)?, + format: Self::read_u8(data)?.into(), options: Self::read_u8(data)?.into(), - transparency_colour: Self::read_u8(data)?, - data: Vec::with_capacity(Self::read_u32(data)? as usize), - macro_refs: Vec::with_capacity(Self::read_u8(data)?.into()), + transparency_colour: Self::read_u8(data)?.into(), + data: Vec::new(), + macro_refs: Vec::new(), }; - o.data.extend(Self::read_bytes(data, o.data.capacity())?); + let data_len = Self::read_u32(data)? as usize; + let macro_refs_len = Self::read_u8(data)? as usize; + + o.data.extend(Self::read_bytes(data, data_len)?); o.macro_refs - .extend(Self::read_macro_refs(data, o.macro_refs.capacity())?); + .extend(Self::read_macro_refs(data, macro_refs_len)?); Ok(Object::PictureGraphic(o)) } @@ -860,7 +863,7 @@ impl Object { ) -> Result { let mut o = FontAttributes { id, - font_colour: Self::read_u8(data)?, + font_colour: Self::read_u8(data)?.into(), font_size: Self::read_u8(data)?, font_type: Self::read_u8(data)?, font_style: Self::read_u8(data)?, @@ -879,7 +882,7 @@ impl Object { ) -> Result { let mut o = LineAttributes { id, - line_colour: Self::read_u8(data)?, + line_colour: Self::read_u8(data)?.into(), line_width: Self::read_u8(data)?, line_art: Self::read_u16(data)?, macro_refs: Vec::with_capacity(Self::read_u8(data)?.into()), @@ -898,7 +901,7 @@ impl Object { let mut o = FillAttributes { id, fill_type: Self::read_u8(data)?, - fill_colour: Self::read_u8(data)?, + fill_colour: Self::read_u8(data)?.into(), fill_pattern: Self::read_u16(data)?.into(), macro_refs: Vec::with_capacity(Self::read_u8(data)?.into()), }; @@ -956,7 +959,7 @@ impl Object { ) -> Result { let mut o = AuxiliaryFunctionType1 { id, - background_colour: Self::read_u8(data)?, + background_colour: Self::read_u8(data)?.into(), function_type: Self::read_u8(data)?, object_refs: Vec::with_capacity(Self::read_u8(data)?.into()), }; @@ -973,7 +976,7 @@ impl Object { ) -> Result { let mut o = AuxiliaryInputType1 { id, - background_colour: Self::read_u8(data)?, + background_colour: Self::read_u8(data)?.into(), function_type: Self::read_u8(data)?, input_id: Self::read_u8(data)?, object_refs: Vec::with_capacity(Self::read_u8(data)?.into()), @@ -991,7 +994,7 @@ impl Object { ) -> Result { let mut o = AuxiliaryFunctionType2 { id, - background_colour: Self::read_u8(data)?, + background_colour: Self::read_u8(data)?.into(), function_attributes: Self::read_u8(data)?, object_refs: Vec::with_capacity(Self::read_u8(data)?.into()), }; @@ -1008,7 +1011,7 @@ impl Object { ) -> Result { let mut o = AuxiliaryInputType2 { id, - background_colour: Self::read_u8(data)?, + background_colour: Self::read_u8(data)?.into(), function_attributes: Self::read_u8(data)?, object_refs: Vec::with_capacity(Self::read_u8(data)?.into()), }; @@ -1040,7 +1043,7 @@ impl Object { id, cell_format: Self::read_u16(data)?.into(), window_type: Self::read_u8(data)?.into(), - background_colour: Self::read_u8(data)?, + background_colour: Self::read_u8(data)?.into(), options: Self::read_u8(data)?.into(), name: Self::read_u16(data)?.try_into()?, window_title: Self::read_u16(data)?.into(), @@ -1096,14 +1099,14 @@ impl Object { viewport_zoom: Self::read_f32(data)?, graphics_cursor_x: Self::read_i16(data)?, graphics_cursor_y: Self::read_i16(data)?, - foreground_colour: Self::read_u8(data)?, - background_colour: Self::read_u8(data)?, + foreground_colour: Self::read_u8(data)?.into(), + background_colour: Self::read_u8(data)?.into(), font_attributes_object: Self::read_u16(data)?.into(), line_attributes_object: Self::read_u16(data)?.into(), fill_attributes_object: Self::read_u16(data)?.into(), format: Self::read_u8(data)?.into(), options: Self::read_u8(data)?.into(), - transparency_colour: Self::read_u8(data)?, + transparency_colour: Self::read_u8(data)?.into(), }; Ok(Object::GraphicsContext(o)) } diff --git a/src/object_pool/vt_version.rs b/src/object_pool/vt_version.rs index da1f63a..cfc7d3e 100644 --- a/src/object_pool/vt_version.rs +++ b/src/object_pool/vt_version.rs @@ -1,7 +1,7 @@ use crate::object_pool::ParseError; use crate::object_pool::ParseError::UnsupportedVtVersion; -#[derive(Debug, Default)] +#[derive(Debug, Default, Clone, PartialEq, PartialOrd)] pub enum VtVersion { Version0, Version1, diff --git a/src/object_pool/writer.rs b/src/object_pool/writer.rs index 91a8edb..a77c373 100644 --- a/src/object_pool/writer.rs +++ b/src/object_pool/writer.rs @@ -308,6 +308,7 @@ impl Object { Self::write_u8(data, o.options); Self::write_u16(data, o.variable_reference); Self::write_u8(data, o.justification); + Self::write_u8(data, o.value.len() as u8); Self::write_string(data, &o.value); Self::write_u8(data, o.enabled); Self::write_u8(data, o.macro_refs.len() as u8); @@ -518,6 +519,7 @@ impl Object { fn write_string_variable(data: &mut Vec, o: &StringVariable) { Self::write_u16(data, o.id); Self::write_u8(data, ObjectType::StringVariable); + Self::write_u16(data, o.value.len() as u16); Self::write_string(data, &o.value); } fn write_font_attributes(data: &mut Vec, o: &FontAttributes) { @@ -555,6 +557,7 @@ impl Object { Self::write_u16(data, o.id); Self::write_u8(data, ObjectType::InputAttributes); Self::write_u8(data, o.validation_type); + Self::write_u8(data, o.validation_string.len() as u8); Self::write_string(data, &o.validation_string); Self::write_u8(data, o.macro_refs.len() as u8);