diff --git a/Storage/Disk/Disk.hpp b/Storage/Disk/Disk.hpp index b85db192b..46dac2db8 100644 --- a/Storage/Disk/Disk.hpp +++ b/Storage/Disk/Disk.hpp @@ -61,6 +61,12 @@ class Disk { @returns whether the disk image is read only. Defaults to @c true if not overridden. */ virtual bool get_is_read_only() = 0; + + /*! + @returns @c true if the tracks at the two addresses are different. @c false if they are the same track. + This can avoid some degree of work when disk images offer sub-head-position precision. + */ + virtual bool tracks_differ(Track::Address, Track::Address) = 0; }; } diff --git a/Storage/Disk/DiskImage/DiskImage.hpp b/Storage/Disk/DiskImage/DiskImage.hpp index 32c535761..a1a230f54 100644 --- a/Storage/Disk/DiskImage/DiskImage.hpp +++ b/Storage/Disk/DiskImage/DiskImage.hpp @@ -67,6 +67,12 @@ class DiskImage { @returns whether the disk image is read only. Defaults to @c true if not overridden. */ virtual bool get_is_read_only() { return true; } + + /*! + @returns @c true if the tracks at the two addresses are different. @c false if they are the same track. + This can avoid some degree of work when disk images offer sub-head-position precision. + */ + virtual bool tracks_differ(Track::Address lhs, Track::Address rhs) { return lhs == rhs; } }; class DiskImageHolderBase: public Disk { @@ -93,6 +99,7 @@ template class DiskImageHolder: public DiskImageHolderBase { void set_track_at_position(Track::Address address, const std::shared_ptr &track); void flush_tracks(); bool get_is_read_only(); + bool tracks_differ(Track::Address lhs, Track::Address rhs); private: T disk_image_; diff --git a/Storage/Disk/DiskImage/DiskImageImplementation.hpp b/Storage/Disk/DiskImage/DiskImageImplementation.hpp index 6812cc20d..799687419 100644 --- a/Storage/Disk/DiskImage/DiskImageImplementation.hpp +++ b/Storage/Disk/DiskImage/DiskImageImplementation.hpp @@ -58,3 +58,7 @@ template std::shared_ptr DiskImageHolder::get_track_at_po template DiskImageHolder::~DiskImageHolder() { if(update_queue_) update_queue_->flush(); } + +template bool DiskImageHolder::tracks_differ(Track::Address lhs, Track::Address rhs) { + return disk_image_.tracks_differ(lhs, rhs); +} diff --git a/Storage/Disk/Track/Track.hpp b/Storage/Disk/Track/Track.hpp index 7debed708..bb4ae83e1 100644 --- a/Storage/Disk/Track/Track.hpp +++ b/Storage/Disk/Track/Track.hpp @@ -84,6 +84,13 @@ class Track { int rhs_largest_position = rhs.position.as_largest(); return std::tie(head, largest_position) < std::tie(rhs.head, rhs_largest_position); } + constexpr bool operator == (const Address &rhs) const { + return head == rhs.head && position == rhs.position; + } + constexpr bool operator != (const Address &rhs) const { + return head != rhs.head || position != rhs.position; + } + constexpr Address(int head, HeadPosition position) : head(head), position(position) {} }; @@ -107,11 +114,11 @@ class Track { virtual Event get_next_event() = 0; /*! - Jumps to the event latest offset that is less than or equal to the input time. + Jumps to the start of the fist event that will occur after @c time_since_index_hole. @returns the time jumped to. */ - virtual Time seek_to(const Time &time_since_index_hole) = 0; + virtual float seek_to(float time_since_index_hole) = 0; /*! The virtual copy constructor pattern; returns a copy of the Track.