Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Referenced objects and extendable object pool #41

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/object_pool/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ mod vt_version;
use crate::network_management::name::NAME;

pub use colour::Colour;
pub use object_attributes::ObjectRef;
pub use object_id::NullableObjectId;
pub use object_id::ObjectId;
pub use object_pool::ObjectPool;
pub use object_type::ObjectType;

Expand Down
171 changes: 168 additions & 3 deletions src/object_pool/object.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
InputList(InputList),
OutputString(OutputString),
OutputNumber(OutputNumber),
OutputList(OutputList),
OutputLine(OutputLine),
OutputRectangle(OutputRectangle),
OutputEllipse(OutputEllipse),
Expand All @@ -52,7 +53,6 @@
WindowMask(WindowMask),
KeyGroup(KeyGroup),
GraphicsContext(GraphicsContext),
OutputList(OutputList),
ExtendedInputAttributes(ExtendedInputAttributes),
ColourMap(ColourMap),
ObjectLabelReferenceList(ObjectLabelReferenceList),
Expand Down Expand Up @@ -82,6 +82,7 @@
Object::InputList(o) => o.id,
Object::OutputString(o) => o.id,
Object::OutputNumber(o) => o.id,
Object::OutputList(o) => o.id,

Check warning on line 85 in src/object_pool/object.rs

View check run for this annotation

Codecov / codecov/patch

src/object_pool/object.rs#L85

Added line #L85 was not covered by tests
Object::OutputLine(o) => o.id,
Object::OutputRectangle(o) => o.id,
Object::OutputEllipse(o) => o.id,
Expand All @@ -106,7 +107,6 @@
Object::WindowMask(o) => o.id,
Object::KeyGroup(o) => o.id,
Object::GraphicsContext(o) => o.id,
Object::OutputList(o) => o.id,
Object::ExtendedInputAttributes(o) => o.id,
Object::ColourMap(o) => o.id,
Object::ObjectLabelReferenceList(o) => o.id,
Expand Down Expand Up @@ -136,6 +136,7 @@
Object::InputList(_) => ObjectType::InputList,
Object::OutputString(_) => ObjectType::OutputString,
Object::OutputNumber(_) => ObjectType::OutputNumber,
Object::OutputList(_) => ObjectType::OutputList,

Check warning on line 139 in src/object_pool/object.rs

View check run for this annotation

Codecov / codecov/patch

src/object_pool/object.rs#L139

Added line #L139 was not covered by tests
Object::OutputLine(_) => ObjectType::OutputLine,
Object::OutputRectangle(_) => ObjectType::OutputRectangle,
Object::OutputEllipse(_) => ObjectType::OutputEllipse,
Expand All @@ -162,7 +163,6 @@
Object::WindowMask(_) => ObjectType::WindowMask,
Object::KeyGroup(_) => ObjectType::KeyGroup,
Object::GraphicsContext(_) => ObjectType::GraphicsContext,
Object::OutputList(_) => ObjectType::OutputList,
Object::ExtendedInputAttributes(_) => ObjectType::ExtendedInputAttributes,
Object::ColourMap(_) => ObjectType::ColourMap,
Object::ObjectLabelReferenceList(_) => ObjectType::ObjectLabelReferenceList,
Expand All @@ -176,6 +176,171 @@
Object::ScaledGraphic(_) => ObjectType::ScaledGraphic,
}
}

///
/// Returns a list of object IDs referenced by this object in the order they are listed
/// as attributes in the object specification.
///
/// # Examples
/// We can use this method recursively to process objects in a "depth-first" manner
/// as required by the ISO 11783-6 (ch. 4.6.1.3) standard:
/// ```
/// use ag_iso_stack::object_pool::ObjectId;
/// use ag_iso_stack::object_pool::ObjectPool;
///
/// fn process_object(object_pool: &ObjectPool, object_id: ObjectId) {
/// let object = object_pool.object_by_id(object_id).unwrap();
/// for referenced_object_id in object.referenced_objects() {
/// process_object(object_pool, referenced_object_id);
/// }
/// // Process the object here
/// }
///
/// let working_set = object_pool.working_set_object().unwrap();
/// process_object(&object_pool, working_set.id);
///
pub fn referenced_objects(&self) -> Vec<ObjectId> {
let mut refs: Vec<ObjectId> = vec![];

Check warning on line 203 in src/object_pool/object.rs

View check run for this annotation

Codecov / codecov/patch

src/object_pool/object.rs#L202-L203

Added lines #L202 - L203 were not covered by tests

fn extend_object_refs(refs: &mut Vec<ObjectId>, object_refs: &[ObjectRef]) {
refs.extend(object_refs.iter().map(|x| x.id));

Check warning on line 206 in src/object_pool/object.rs

View check run for this annotation

Codecov / codecov/patch

src/object_pool/object.rs#L205-L206

Added lines #L205 - L206 were not covered by tests
}

fn push_nullable_id(refs: &mut Vec<ObjectId>, nullable_id: &NullableObjectId) {
if let Some(id) = nullable_id.0 {
refs.push(id);

Check warning on line 211 in src/object_pool/object.rs

View check run for this annotation

Codecov / codecov/patch

src/object_pool/object.rs#L209-L211

Added lines #L209 - L211 were not covered by tests
}
}

fn extend_nullable_ids(refs: &mut Vec<ObjectId>, nullable_ids: &[NullableObjectId]) {
refs.extend(nullable_ids.iter().filter_map(|x| x.0));

Check warning on line 216 in src/object_pool/object.rs

View check run for this annotation

Codecov / codecov/patch

src/object_pool/object.rs#L215-L216

Added lines #L215 - L216 were not covered by tests
}

match self {
Object::WorkingSet(o) => {
refs.push(o.active_mask);
extend_object_refs(&mut refs, &o.object_refs);

Check warning on line 222 in src/object_pool/object.rs

View check run for this annotation

Codecov / codecov/patch

src/object_pool/object.rs#L219-L222

Added lines #L219 - L222 were not covered by tests
}
Object::DataMask(o) => {
push_nullable_id(&mut refs, &o.soft_key_mask);
extend_object_refs(&mut refs, &o.object_refs);

Check warning on line 226 in src/object_pool/object.rs

View check run for this annotation

Codecov / codecov/patch

src/object_pool/object.rs#L224-L226

Added lines #L224 - L226 were not covered by tests
}
Object::AlarmMask(o) => {
push_nullable_id(&mut refs, &o.soft_key_mask);
extend_object_refs(&mut refs, &o.object_refs);

Check warning on line 230 in src/object_pool/object.rs

View check run for this annotation

Codecov / codecov/patch

src/object_pool/object.rs#L228-L230

Added lines #L228 - L230 were not covered by tests
}
Object::Container(o) => extend_object_refs(&mut refs, &o.object_refs),
Object::SoftKeyMask(o) => refs.extend(&o.objects),
Object::Key(o) => extend_object_refs(&mut refs, &o.object_refs),
Object::Button(o) => extend_object_refs(&mut refs, &o.object_refs),
Object::InputBoolean(o) => {
refs.push(o.foreground_colour);
push_nullable_id(&mut refs, &o.variable_reference);

Check warning on line 238 in src/object_pool/object.rs

View check run for this annotation

Codecov / codecov/patch

src/object_pool/object.rs#L232-L238

Added lines #L232 - L238 were not covered by tests
}
Object::InputString(o) => {
refs.push(o.font_attributes);
push_nullable_id(&mut refs, &o.input_attributes);
push_nullable_id(&mut refs, &o.variable_reference);

Check warning on line 243 in src/object_pool/object.rs

View check run for this annotation

Codecov / codecov/patch

src/object_pool/object.rs#L240-L243

Added lines #L240 - L243 were not covered by tests
}
Object::InputNumber(o) => {
refs.push(o.font_attributes);
push_nullable_id(&mut refs, &o.variable_reference);

Check warning on line 247 in src/object_pool/object.rs

View check run for this annotation

Codecov / codecov/patch

src/object_pool/object.rs#L245-L247

Added lines #L245 - L247 were not covered by tests
}
Object::InputList(o) => {
push_nullable_id(&mut refs, &o.variable_reference);
extend_nullable_ids(&mut refs, &o.list_items);

Check warning on line 251 in src/object_pool/object.rs

View check run for this annotation

Codecov / codecov/patch

src/object_pool/object.rs#L249-L251

Added lines #L249 - L251 were not covered by tests
}
Object::OutputString(o) => {
refs.push(o.font_attributes);
push_nullable_id(&mut refs, &o.variable_reference);

Check warning on line 255 in src/object_pool/object.rs

View check run for this annotation

Codecov / codecov/patch

src/object_pool/object.rs#L253-L255

Added lines #L253 - L255 were not covered by tests
}
Object::OutputNumber(o) => {
refs.push(o.font_attributes);
push_nullable_id(&mut refs, &o.variable_reference);

Check warning on line 259 in src/object_pool/object.rs

View check run for this annotation

Codecov / codecov/patch

src/object_pool/object.rs#L257-L259

Added lines #L257 - L259 were not covered by tests
}
Object::OutputList(o) => {
push_nullable_id(&mut refs, &o.variable_reference);
extend_nullable_ids(&mut refs, &o.list_items);

Check warning on line 263 in src/object_pool/object.rs

View check run for this annotation

Codecov / codecov/patch

src/object_pool/object.rs#L261-L263

Added lines #L261 - L263 were not covered by tests
}
Object::OutputLine(o) => refs.push(o.line_attributes),
Object::OutputRectangle(o) => {
refs.push(o.line_attributes);
push_nullable_id(&mut refs, &o.fill_attributes);

Check warning on line 268 in src/object_pool/object.rs

View check run for this annotation

Codecov / codecov/patch

src/object_pool/object.rs#L265-L268

Added lines #L265 - L268 were not covered by tests
}
Object::OutputEllipse(o) => {
refs.push(o.line_attributes);
push_nullable_id(&mut refs, &o.fill_attributes);

Check warning on line 272 in src/object_pool/object.rs

View check run for this annotation

Codecov / codecov/patch

src/object_pool/object.rs#L270-L272

Added lines #L270 - L272 were not covered by tests
}
Object::OutputPolygon(o) => {
refs.push(o.line_attributes);
push_nullable_id(&mut refs, &o.fill_attributes);

Check warning on line 276 in src/object_pool/object.rs

View check run for this annotation

Codecov / codecov/patch

src/object_pool/object.rs#L274-L276

Added lines #L274 - L276 were not covered by tests
}
Object::OutputMeter(o) => push_nullable_id(&mut refs, &o.variable_reference),
Object::OutputLinearBarGraph(o) => {
push_nullable_id(&mut refs, &o.variable_reference);
push_nullable_id(&mut refs, &o.target_value_variable_reference);

Check warning on line 281 in src/object_pool/object.rs

View check run for this annotation

Codecov / codecov/patch

src/object_pool/object.rs#L278-L281

Added lines #L278 - L281 were not covered by tests
}
Object::OutputArchedBarGraph(o) => {
push_nullable_id(&mut refs, &o.variable_reference);
push_nullable_id(&mut refs, &o.target_value_variable_reference);

Check warning on line 285 in src/object_pool/object.rs

View check run for this annotation

Codecov / codecov/patch

src/object_pool/object.rs#L283-L285

Added lines #L283 - L285 were not covered by tests
}
Object::PictureGraphic(_)
| Object::NumberVariable(_)
| Object::StringVariable(_)
| Object::FontAttributes(_)
| Object::LineAttributes(_) => (), // No references
Object::FillAttributes(o) => push_nullable_id(&mut refs, &o.fill_pattern),
Object::InputAttributes(_) => (), // No references
Object::ObjectPointer(o) => push_nullable_id(&mut refs, &o.value),

Check warning on line 294 in src/object_pool/object.rs

View check run for this annotation

Codecov / codecov/patch

src/object_pool/object.rs#L291-L294

Added lines #L291 - L294 were not covered by tests
Object::Macro(_)
| Object::AuxiliaryFunctionType1(_)
| Object::AuxiliaryInputType1(_)
| Object::AuxiliaryFunctionType2(_)
| Object::AuxiliaryInputType2(_) => (), // No references
Object::AuxiliaryControlDesignatorType2(o) => refs.push(o.auxiliary_object_id),
Object::WindowMask(o) => {
push_nullable_id(&mut refs, &o.window_title);
push_nullable_id(&mut refs, &o.window_icon);
extend_nullable_ids(&mut refs, &o.objects);
extend_object_refs(&mut refs, &o.object_refs);

Check warning on line 305 in src/object_pool/object.rs

View check run for this annotation

Codecov / codecov/patch

src/object_pool/object.rs#L299-L305

Added lines #L299 - L305 were not covered by tests
}
Object::KeyGroup(o) => {
refs.push(o.name);
push_nullable_id(&mut refs, &o.key_group_icon);
refs.extend(&o.objects);

Check warning on line 310 in src/object_pool/object.rs

View check run for this annotation

Codecov / codecov/patch

src/object_pool/object.rs#L307-L310

Added lines #L307 - L310 were not covered by tests
}
Object::GraphicsContext(o) => {
push_nullable_id(&mut refs, &o.font_attributes_object);
push_nullable_id(&mut refs, &o.line_attributes_object);
push_nullable_id(&mut refs, &o.fill_attributes_object);

Check warning on line 315 in src/object_pool/object.rs

View check run for this annotation

Codecov / codecov/patch

src/object_pool/object.rs#L312-L315

Added lines #L312 - L315 were not covered by tests
}
Object::ExtendedInputAttributes(_) | Object::ColourMap(_) => (), // No references
Object::ObjectLabelReferenceList(o) => {
for label in o.object_labels.as_slice() {
refs.push(label.id);
push_nullable_id(&mut refs, &label.string_variable_reference);
push_nullable_id(&mut refs, &label.graphic_representation);

Check warning on line 322 in src/object_pool/object.rs

View check run for this annotation

Codecov / codecov/patch

src/object_pool/object.rs#L317-L322

Added lines #L317 - L322 were not covered by tests
}
}
Object::ExternalObjectDefinition(o) => extend_nullable_ids(&mut refs, &o.objects),
Object::ExternalReferenceName(_) => (), // No references
Object::ExternalObjectPointer(o) => {
push_nullable_id(&mut refs, &o.default_object_id);
push_nullable_id(&mut refs, &o.external_reference_name_id);
push_nullable_id(&mut refs, &o.external_object_id);

Check warning on line 330 in src/object_pool/object.rs

View check run for this annotation

Codecov / codecov/patch

src/object_pool/object.rs#L325-L330

Added lines #L325 - L330 were not covered by tests
}
Object::Animation(o) => extend_object_refs(&mut refs, &o.object_refs),

Check warning on line 332 in src/object_pool/object.rs

View check run for this annotation

Codecov / codecov/patch

src/object_pool/object.rs#L332

Added line #L332 was not covered by tests

Object::ColourPalette(_) | Object::GraphicData(_) => (), // No references
Object::WorkingSetSpecialControls(o) => {
push_nullable_id(&mut refs, &o.id_of_colour_map);
push_nullable_id(&mut refs, &o.id_of_colour_palette);

Check warning on line 337 in src/object_pool/object.rs

View check run for this annotation

Codecov / codecov/patch

src/object_pool/object.rs#L334-L337

Added lines #L334 - L337 were not covered by tests
}
Object::ScaledGraphic(o) => push_nullable_id(&mut refs, &o.value),

Check warning on line 339 in src/object_pool/object.rs

View check run for this annotation

Codecov / codecov/patch

src/object_pool/object.rs#L339

Added line #L339 was not covered by tests
};

refs

Check warning on line 342 in src/object_pool/object.rs

View check run for this annotation

Codecov / codecov/patch

src/object_pool/object.rs#L342

Added line #L342 was not covered by tests
}
}

#[derive(Debug, PartialEq)]
Expand Down
18 changes: 13 additions & 5 deletions src/object_pool/object_pool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,15 +79,23 @@
where
I: IntoIterator<Item = u8>,
{
let mut data = data.into_iter();

let mut op = Self::new();
op.extend_with_iop(data);
op

Check warning on line 84 in src/object_pool/object_pool.rs

View check run for this annotation

Codecov / codecov/patch

src/object_pool/object_pool.rs#L83-L84

Added lines #L83 - L84 were not covered by tests
}

pub fn extend_with_iop<I>(&mut self, data: I)

Check warning on line 87 in src/object_pool/object_pool.rs

View check run for this annotation

Codecov / codecov/patch

src/object_pool/object_pool.rs#L87

Added line #L87 was not covered by tests
where
I: IntoIterator<Item = u8>,
{
let mut data = data.into_iter();

Check warning on line 91 in src/object_pool/object_pool.rs

View check run for this annotation

Codecov / codecov/patch

src/object_pool/object_pool.rs#L91

Added line #L91 was not covered by tests

while let Ok(o) = Object::read(&mut data) {
op.objects.push(o);
// By the standard, if there already is an object with the same ID, the new object
// replaces the old one
self.objects.retain(|x| x.id() != o.id());
self.objects.push(o);

Check warning on line 97 in src/object_pool/object_pool.rs

View check run for this annotation

Codecov / codecov/patch

src/object_pool/object_pool.rs#L96-L97

Added lines #L96 - L97 were not covered by tests
}

op
}

pub fn as_iop(&self) -> Vec<u8> {
Expand Down
Loading