1
0
mirror of https://github.com/TomHarte/CLK.git synced 2025-02-22 11:29:20 +00:00

Merge pull request #1431 from TomHarte/UniqueSectors

Eliminate use of std::shared_ptr for tracks on both sides of DiskImageHolder.
This commit is contained in:
Thomas Harte 2024-12-09 22:23:01 -05:00 committed by GitHub
commit 5a3e4dd47b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
44 changed files with 136 additions and 122 deletions

View File

@ -67,7 +67,7 @@ Analyser::Static::TargetList Analyser::Static::DiskII::GetTargets(
// Grab track 0, sector 0: the boot sector.
const auto track_zero =
disk->get_track_at_position(Storage::Disk::Track::Address(0, Storage::Disk::HeadPosition(0)));
disk->track_at_position(Storage::Disk::Track::Address(0, Storage::Disk::HeadPosition(0)));
const auto sector_map = Storage::Encodings::AppleGCR::sectors_from_segment(
Storage::Disk::track_serialisation(*track_zero, Storage::Time(1, 50000)));

View File

@ -44,7 +44,7 @@ Analyser::Static::TargetList Analyser::Static::FAT12::GetTargets(
// Attempt to grab MFM track 0, sector 1: the boot sector.
const auto track_zero =
disk->get_track_at_position(Storage::Disk::Track::Address(0, Storage::Disk::HeadPosition(0)));
disk->track_at_position(Storage::Disk::Track::Address(0, Storage::Disk::HeadPosition(0)));
const auto sector_map = Storage::Encodings::MFM::sectors_from_segment(
Storage::Disk::track_serialisation(
*track_zero,

View File

@ -43,12 +43,12 @@ public:
@returns the @c Track at @c position underneath @c head if there are any detectable events there;
returns @c nullptr otherwise.
*/
virtual std::shared_ptr<Track> get_track_at_position(Track::Address address) = 0;
virtual Track *track_at_position(Track::Address) = 0;
/*!
Replaces the Track at position @c position underneath @c head with @c track. Ignored if this disk is read-only.
*/
virtual void set_track_at_position(Track::Address address, const std::shared_ptr<Track> &track) = 0;
virtual void set_track_at_position(Track::Address, const std::shared_ptr<Track> &) = 0;
/*!
Provides a hint that no further tracks are likely to be written for a while.

View File

@ -50,12 +50,12 @@ public:
@returns the @c Track at @c position underneath @c head if there are any detectable events there;
returns @c nullptr otherwise.
*/
virtual std::shared_ptr<Track> get_track_at_position(Track::Address address) = 0;
virtual std::unique_ptr<Track> track_at_position(Track::Address address) = 0;
/*!
Replaces the Tracks indicated by the map, that maps from physical address to track content.
*/
virtual void set_tracks(const std::map<Track::Address, std::shared_ptr<Track>> &) {}
virtual void set_tracks(const std::map<Track::Address, std::unique_ptr<Track>> &) {}
/*!
Communicates that it is likely to be a while before any more tracks are written.
@ -72,6 +72,12 @@ public:
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; }
/*!
Maps from an address to its canonical form; this provides a means for images that duplicate the same
track at different addresses to declare as much.
*/
virtual Track::Address canonical_address(Track::Address address) { return address; }
};
class DiskImageHolderBase: public Disk {
@ -97,7 +103,7 @@ public:
HeadPosition get_maximum_head_position();
int get_head_count();
std::shared_ptr<Track> get_track_at_position(Track::Address address);
Track *track_at_position(Track::Address address);
void set_track_at_position(Track::Address address, const std::shared_ptr<Track> &track);
void flush_tracks();
bool get_is_read_only();

View File

@ -22,10 +22,10 @@ template <typename T> void DiskImageHolder<T>::flush_tracks() {
if(!unwritten_tracks_.empty()) {
if(!update_queue_) update_queue_ = std::make_unique<Concurrency::AsyncTaskQueue<true>>();
using TrackMap = std::map<Track::Address, std::shared_ptr<Track>>;
std::shared_ptr<TrackMap> track_copies(new TrackMap);
using TrackMap = std::map<Track::Address, std::unique_ptr<Track>>;
auto track_copies = std::make_shared<TrackMap>();
for(const auto &address : unwritten_tracks_) {
track_copies->insert({address, std::shared_ptr<Track>(cached_tracks_[address]->clone())});
track_copies->insert({address, std::unique_ptr<Track>(cached_tracks_[address]->clone())});
}
unwritten_tracks_.clear();
@ -42,17 +42,18 @@ template <typename T> void DiskImageHolder<T>::set_track_at_position(Track::Addr
cached_tracks_[address] = track;
}
template <typename T> std::shared_ptr<Track> DiskImageHolder<T>::get_track_at_position(Track::Address address) {
template <typename T> Track *DiskImageHolder<T>::track_at_position(Track::Address address) {
if(address.head >= get_head_count()) return nullptr;
if(address.position >= get_maximum_head_position()) return nullptr;
auto cached_track = cached_tracks_.find(address);
if(cached_track != cached_tracks_.end()) return cached_track->second;
const auto canonical_address = disk_image_.canonical_address(address);
auto cached_track = cached_tracks_.find(canonical_address);
if(cached_track != cached_tracks_.end()) return cached_track->second.get();
std::shared_ptr<Track> track = disk_image_.get_track_at_position(address);
std::shared_ptr<Track> track = disk_image_.track_at_position(canonical_address);
if(!track) return nullptr;
cached_tracks_[address] = track;
return track;
cached_tracks_[canonical_address] = track;
return track.get();
}
template <typename T> DiskImageHolder<T>::~DiskImageHolder() {

View File

@ -124,7 +124,7 @@ int AmigaADF::get_head_count() {
return 2;
}
std::shared_ptr<Track> AmigaADF::get_track_at_position(Track::Address address) {
std::unique_ptr<Track> AmigaADF::track_at_position(Track::Address address) {
using namespace Storage::Encodings;
// Create an MFM encoder.
@ -179,7 +179,7 @@ std::shared_ptr<Track> AmigaADF::get_track_at_position(Track::Address address) {
encoder->add_byte(0xff);
}
return std::make_shared<Storage::Disk::PCMTrack>(std::move(encoded_segment));
return std::make_unique<Storage::Disk::PCMTrack>(std::move(encoded_segment));
}
long AmigaADF::get_file_offset_for_position(Track::Address address) {

View File

@ -31,7 +31,7 @@ public:
// implemented to satisfy @c Disk
HeadPosition get_maximum_head_position() final;
int get_head_count() final;
std::shared_ptr<Track> get_track_at_position(Track::Address) final;
std::unique_ptr<Track> track_at_position(Track::Address) final;
private:
Storage::FileHolder file_;

View File

@ -61,7 +61,7 @@ size_t AppleDSK::logical_sector_for_physical_sector(size_t physical) {
return (physical * (is_prodos_ ? 8 : 7)) % 15;
}
std::shared_ptr<Track> AppleDSK::get_track_at_position(Track::Address address) {
std::unique_ptr<Track> AppleDSK::track_at_position(Track::Address address) {
std::vector<uint8_t> track_data;
{
std::lock_guard lock_guard(file_.get_file_access_mutex());
@ -93,10 +93,10 @@ std::shared_ptr<Track> AppleDSK::get_track_at_position(Track::Address address) {
const size_t offset_in_fifths = size_t(address.position.as_int() % 5);
segment.rotate_right(offset_in_fifths * segment.data.size() / 5);
return std::make_shared<PCMTrack>(segment);
return std::make_unique<PCMTrack>(segment);
}
void AppleDSK::set_tracks(const std::map<Track::Address, std::shared_ptr<Track>> &tracks) {
void AppleDSK::set_tracks(const std::map<Track::Address, std::unique_ptr<Track>> &tracks) {
std::map<Track::Address, std::vector<uint8_t>> tracks_by_address;
for(const auto &pair: tracks) {
// Decode the track.

View File

@ -31,8 +31,8 @@ public:
// Implemented to satisfy @c DiskImage.
HeadPosition get_maximum_head_position() final;
std::shared_ptr<Track> get_track_at_position(Track::Address) final;
void set_tracks(const std::map<Track::Address, std::shared_ptr<Track>> &) final;
std::unique_ptr<Track> track_at_position(Track::Address) final;
void set_tracks(const std::map<Track::Address, std::unique_ptr<Track>> &) final;
bool get_is_read_only() final;
private:

View File

@ -198,7 +198,7 @@ std::size_t CPCDSK::index_for_track(::Storage::Disk::Track::Address address) {
return size_t((address.position.as_int() * head_count_) + address.head);
}
std::shared_ptr<Track> CPCDSK::get_track_at_position(::Storage::Disk::Track::Address address) {
std::unique_ptr<Track> CPCDSK::track_at_position(::Storage::Disk::Track::Address address) {
// Given that thesea are interleaved images, determine which track, chronologically, is being requested.
const std::size_t chronological_track = index_for_track(address);
@ -221,7 +221,7 @@ std::shared_ptr<Track> CPCDSK::get_track_at_position(::Storage::Disk::Track::Add
track->filler_byte);
}
void CPCDSK::set_tracks(const std::map<::Storage::Disk::Track::Address, std::shared_ptr<::Storage::Disk::Track>> &tracks) {
void CPCDSK::set_tracks(const std::map<::Storage::Disk::Track::Address, std::unique_ptr<::Storage::Disk::Track>> &tracks) {
// Patch changed tracks into the disk image.
for(auto &pair: tracks) {
// Assume MFM for now; with extensions DSK can contain FM tracks.

View File

@ -34,8 +34,8 @@ public:
HeadPosition get_maximum_head_position() final;
int get_head_count() final;
bool get_is_read_only() final;
void set_tracks(const std::map<::Storage::Disk::Track::Address, std::shared_ptr<::Storage::Disk::Track>> &tracks) final;
std::shared_ptr<::Storage::Disk::Track> get_track_at_position(::Storage::Disk::Track::Address address) final;
void set_tracks(const std::map<Track::Address, std::unique_ptr<Track>> &) final;
std::unique_ptr<::Storage::Disk::Track> track_at_position(::Storage::Disk::Track::Address) final;
private:
struct Track {

View File

@ -38,7 +38,7 @@ HeadPosition D64::get_maximum_head_position() {
return HeadPosition(number_of_tracks_);
}
std::shared_ptr<Track> D64::get_track_at_position(const Track::Address address) {
std::unique_ptr<Track> D64::track_at_position(const Track::Address address) {
// Figure out where this track starts on the disk.
int offset_to_track = 0;
int tracks_to_traverse = address.position.as_int();
@ -135,5 +135,5 @@ std::shared_ptr<Track> D64::get_track_at_position(const Track::Address address)
Encodings::CommodoreGCR::encode_block(&sector_data[target_data_offset], end_of_data);
}
return std::make_shared<PCMTrack>(PCMSegment(data));
return std::make_unique<PCMTrack>(PCMSegment(data));
}

View File

@ -27,7 +27,7 @@ public:
D64(const std::string &file_name);
HeadPosition get_maximum_head_position() final;
std::shared_ptr<Track> get_track_at_position(Track::Address address) final;
std::unique_ptr<Track> track_at_position(Track::Address) final;
private:
Storage::FileHolder file_;

View File

@ -79,7 +79,7 @@ long DMK::get_file_offset_for_position(Track::Address address) {
return (address.head*head_count_ + address.position.as_int()) * track_length_ + 16;
}
std::shared_ptr<::Storage::Disk::Track> DMK::get_track_at_position(::Storage::Disk::Track::Address address) {
std::unique_ptr<::Storage::Disk::Track> DMK::track_at_position(::Storage::Disk::Track::Address address) {
file_.seek(get_file_offset_for_position(address), SEEK_SET);
// Read the IDAM table.
@ -179,5 +179,5 @@ std::shared_ptr<::Storage::Disk::Track> DMK::get_track_at_position(::Storage::Di
idam_pointer++;
}
return std::make_shared<PCMTrack>(segments);
return std::make_unique<PCMTrack>(segments);
}

View File

@ -33,7 +33,7 @@ public:
int get_head_count() final;
bool get_is_read_only() final;
std::shared_ptr<::Storage::Disk::Track> get_track_at_position(::Storage::Disk::Track::Address address) final;
std::unique_ptr<Track> track_at_position(Track::Address) final;
private:
FileHolder file_;

View File

@ -36,9 +36,7 @@ HeadPosition G64::get_maximum_head_position() {
return HeadPosition(number_of_tracks_ > 84 ? number_of_tracks_ : 84, 2);
}
std::shared_ptr<Track> G64::get_track_at_position(Track::Address address) {
std::shared_ptr<Track> resulting_track;
std::unique_ptr<Track> G64::track_at_position(Track::Address address) {
// seek to this track's entry in the track table
file_.seek(long((address.position.as_half() * 4) + 0xc), SEEK_SET);
@ -93,7 +91,7 @@ std::shared_ptr<Track> G64::get_track_at_position(Track::Address address) {
}
}
resulting_track = std::make_shared<PCMTrack>(std::move(segments));
return std::make_unique<PCMTrack>(std::move(segments));
} else {
PCMSegment segment(
Encodings::CommodoreGCR::length_of_a_bit_in_time_zone(unsigned(speed_zone_offset)),
@ -101,11 +99,9 @@ std::shared_ptr<Track> G64::get_track_at_position(Track::Address address) {
track_contents
);
resulting_track = std::make_shared<PCMTrack>(std::move(segment));
return std::make_unique<PCMTrack>(std::move(segment));
}
// TODO: find out whether it's possible for a G64 to supply only a partial track. I don't think it is, which would make the
// above correct but supposing I'm wrong, the above would produce some incorrectly clocked tracks
return resulting_track;
// TODO: find out whether it's possible for a G64 to supply only a partial track. I don't think it is, which
// would make the above correct but supposing I'm wrong, the above would produce some incorrectly clocked tracks.
}

View File

@ -31,7 +31,7 @@ public:
// implemented to satisfy @c Disk
HeadPosition get_maximum_head_position() final;
std::shared_ptr<Track> get_track_at_position(Track::Address address) final;
std::unique_ptr<Track> track_at_position(Track::Address) final;
using DiskImage::get_is_read_only;
private:

View File

@ -54,7 +54,7 @@ uint16_t HFE::seek_track(Track::Address address) {
return track_length / 2; // Divide by two to give the track length for a single side.
}
std::shared_ptr<Track> HFE::get_track_at_position(Track::Address address) {
std::unique_ptr<Track> HFE::track_at_position(Track::Address address) {
PCMSegment segment;
{
std::lock_guard lock_guard(file_.get_file_access_mutex());
@ -96,10 +96,10 @@ std::shared_ptr<Track> HFE::get_track_at_position(Track::Address address) {
}
}
return std::make_shared<PCMTrack>(segment);
return std::make_unique<PCMTrack>(segment);
}
void HFE::set_tracks(const std::map<Track::Address, std::shared_ptr<Track>> &tracks) {
void HFE::set_tracks(const std::map<Track::Address, std::unique_ptr<Track>> &tracks) {
for(auto &track : tracks) {
std::unique_lock lock_guard(file_.get_file_access_mutex());
uint16_t track_length = seek_track(track.first);

View File

@ -33,8 +33,8 @@ public:
HeadPosition get_maximum_head_position() final;
int get_head_count() final;
bool get_is_read_only() final;
void set_tracks(const std::map<Track::Address, std::shared_ptr<Track>> &tracks) final;
std::shared_ptr<Track> get_track_at_position(Track::Address address) final;
void set_tracks(const std::map<Track::Address, std::unique_ptr<Track>> &tracks) final;
std::unique_ptr<Track> track_at_position(Track::Address) final;
private:
Storage::FileHolder file_;

View File

@ -98,7 +98,7 @@ int IMD::get_head_count() {
return heads_ + 1;
}
std::shared_ptr<::Storage::Disk::Track> IMD::get_track_at_position(::Storage::Disk::Track::Address address) {
std::unique_ptr<Track> IMD::track_at_position(Track::Address address) {
auto location = track_locations_.find(address);
if(location == track_locations_.end()) {
return nullptr;

View File

@ -31,7 +31,7 @@ public:
// DiskImage interface.
HeadPosition get_maximum_head_position() final;
int get_head_count() final;
std::shared_ptr<::Storage::Disk::Track> get_track_at_position(::Storage::Disk::Track::Address address) final;
std::unique_ptr<Track> track_at_position(Track::Address) final;
private:
FileHolder file_;

View File

@ -186,7 +186,7 @@ int IPF::get_head_count() {
return head_count_;
}
std::shared_ptr<Track> IPF::get_track_at_position([[maybe_unused]] Track::Address address) {
std::unique_ptr<Track> IPF::track_at_position([[maybe_unused]] Track::Address address) {
// Get the track description, if it exists, and check either that the file has contents for the track.
auto pair = tracks_.find(address);
if(pair == tracks_.end()) {
@ -313,7 +313,7 @@ std::shared_ptr<Track> IPF::get_track_at_position([[maybe_unused]] Track::Addres
++block_count;
}
return std::make_shared<Storage::Disk::PCMTrack>(segments);
return std::make_unique<Storage::Disk::PCMTrack>(segments);
}
/// @returns The correct bit length for @c block on a track of @c density.

View File

@ -38,7 +38,7 @@ public:
// implemented to satisfy @c Disk
HeadPosition get_maximum_head_position() final;
int get_head_count() final;
std::shared_ptr<Track> get_track_at_position(Track::Address address) final;
std::unique_ptr<Track> track_at_position(Track::Address) final;
private:
Storage::FileHolder file_;

View File

@ -21,7 +21,7 @@ void MFMSectorDump::set_geometry(int sectors_per_track, uint8_t sector_size, uin
first_sector_ = first_sector;
}
std::shared_ptr<Track> MFMSectorDump::get_track_at_position(Track::Address address) {
std::unique_ptr<Track> MFMSectorDump::track_at_position(Track::Address address) {
if(address.head >= get_head_count()) return nullptr;
if(address.position.as_largest() >= get_maximum_head_position().as_largest()) return nullptr;
@ -44,7 +44,7 @@ std::shared_ptr<Track> MFMSectorDump::get_track_at_position(Track::Address addre
density_);
}
void MFMSectorDump::set_tracks(const std::map<Track::Address, std::shared_ptr<Track>> &tracks) {
void MFMSectorDump::set_tracks(const std::map<Track::Address, std::unique_ptr<Track>> &tracks) {
uint8_t parsed_track[(128 << sector_size_)*sectors_per_track_];
// TODO: it would be more efficient from a file access and locking point of view to parse the sectors

View File

@ -24,8 +24,8 @@ public:
MFMSectorDump(const std::string &file_name);
bool get_is_read_only() final;
void set_tracks(const std::map<Track::Address, std::shared_ptr<Track>> &tracks) final;
std::shared_ptr<Track> get_track_at_position(Track::Address address) final;
void set_tracks(const std::map<Track::Address, std::unique_ptr<Track>> &tracks) final;
std::unique_ptr<Track> track_at_position(Track::Address) final;
protected:
Storage::FileHolder file_;

View File

@ -75,7 +75,7 @@ MSA::MSA(const std::string &file_name) :
throw Error::InvalidFormat;
}
std::shared_ptr<::Storage::Disk::Track> MSA::get_track_at_position(::Storage::Disk::Track::Address address) {
std::unique_ptr<Track> MSA::track_at_position(Track::Address address) {
if(address.head >= sides_) return nullptr;
const auto position = address.position.as_int();

View File

@ -26,7 +26,7 @@ public:
// Implemented to satisfy @c DiskImage.
HeadPosition get_maximum_head_position() final;
int get_head_count() final;
std::shared_ptr<::Storage::Disk::Track> get_track_at_position(::Storage::Disk::Track::Address address) final;
std::unique_ptr<Track> track_at_position(Track::Address) final;
bool get_is_read_only() final { return false; }
private:

View File

@ -171,7 +171,7 @@ bool MacintoshIMG::get_is_read_only() {
return file_.get_is_known_read_only();
}
std::shared_ptr<::Storage::Disk::Track> MacintoshIMG::get_track_at_position(::Storage::Disk::Track::Address address) {
std::unique_ptr<Track> MacintoshIMG::track_at_position(Track::Address address) {
/*
The format_ byte has the following meanings:
@ -246,13 +246,13 @@ std::shared_ptr<::Storage::Disk::Track> MacintoshIMG::get_track_at_position(::St
// TODO: it seems some tracks are skewed respective to others; investigate further.
// segment.rotate_right(3000); // Just a test, yo.
return std::make_shared<PCMTrack>(segment);
return std::make_unique<PCMTrack>(segment);
}
return nullptr;
}
void MacintoshIMG::set_tracks(const std::map<Track::Address, std::shared_ptr<Track>> &tracks) {
void MacintoshIMG::set_tracks(const std::map<Track::Address, std::unique_ptr<Track>> &tracks) {
std::map<Track::Address, std::vector<uint8_t>> tracks_by_address;
for(const auto &pair: tracks) {
// Determine a data rate for the track.

View File

@ -47,8 +47,8 @@ public:
int get_head_count() final;
bool get_is_read_only() final;
std::shared_ptr<::Storage::Disk::Track> get_track_at_position(::Storage::Disk::Track::Address address) final;
void set_tracks(const std::map<Track::Address, std::shared_ptr<Track>> &tracks) final;
std::unique_ptr<Track> track_at_position(Track::Address) final;
void set_tracks(const std::map<Track::Address, std::unique_ptr<Track>> &tracks) final;
private:
Storage::FileHolder file_;

View File

@ -54,7 +54,14 @@ long NIB::file_offset(Track::Address address) {
return long(address.position.as_int()) * track_length;
}
std::shared_ptr<::Storage::Disk::Track> NIB::get_track_at_position(::Storage::Disk::Track::Address address) {
Track::Address NIB::canonical_address(Track::Address address) {
return Track::Address(
address.head,
HeadPosition(address.position.as_int())
);
}
std::unique_ptr<Track> NIB::track_at_position(Track::Address address) {
static constexpr size_t MinimumSyncByteCount = 4;
// NIBs contain data for a fixed quantity of integer-position tracks underneath a single head only.
@ -71,9 +78,6 @@ std::shared_ptr<::Storage::Disk::Track> NIB::get_track_at_position(::Storage::Di
std::vector<uint8_t> track_data;
{
std::lock_guard lock_guard(file_.get_file_access_mutex());
if(cached_offset_ == offset && cached_track_) {
return cached_track_;
}
file_.seek(offset, SEEK_SET);
track_data = file_.read(track_length);
}
@ -133,12 +137,10 @@ std::shared_ptr<::Storage::Disk::Track> NIB::get_track_at_position(::Storage::Di
}
std::lock_guard lock_guard(file_.get_file_access_mutex());
cached_offset_ = offset;
cached_track_ = std::make_shared<PCMTrack>(segment);
return cached_track_;
return std::make_unique<PCMTrack>(segment);
}
void NIB::set_tracks(const std::map<Track::Address, std::shared_ptr<Track>> &tracks) {
void NIB::set_tracks(const std::map<Track::Address, std::unique_ptr<Track>> &tracks) {
std::map<Track::Address, std::vector<uint8_t>> tracks_by_address;
// Convert to a map from address to a vector of data that contains the NIB representation
@ -186,5 +188,4 @@ void NIB::set_tracks(const std::map<Track::Address, std::shared_ptr<Track>> &tra
file_.seek(file_offset(track.first), SEEK_SET);
file_.write(track.second);
}
cached_track_ = nullptr; // Conservative, but safe.
}

View File

@ -27,20 +27,15 @@ public:
// Implemented to satisfy @c DiskImage.
HeadPosition get_maximum_head_position() final;
std::shared_ptr<::Storage::Disk::Track> get_track_at_position(::Storage::Disk::Track::Address address) final;
void set_tracks(const std::map<Track::Address, std::shared_ptr<Track>> &tracks) final;
Track::Address canonical_address(Track::Address) final;
std::unique_ptr<Track> track_at_position(Track::Address) final;
void set_tracks(const std::map<Track::Address, std::unique_ptr<Track>> &tracks) final;
bool get_is_read_only() final;
private:
FileHolder file_;
long get_file_offset_for_position(Track::Address address);
long file_offset(Track::Address address);
// Cache for the last-generated track, given that head steps on an Apple II
// occur in quarter-track increments, so there'll routinely be four gets in
// a row for the same data.
long cached_offset_ = 0;
std::shared_ptr<Storage::Disk::PCMTrack> cached_track_;
};
}

View File

@ -50,7 +50,7 @@ long OricMFMDSK::get_file_offset_for_position(Track::Address address) {
return long(seek_offset) * 6400 + 256;
}
std::shared_ptr<Track> OricMFMDSK::get_track_at_position(Track::Address address) {
std::unique_ptr<Track> OricMFMDSK::track_at_position(Track::Address address) {
PCMSegment segment;
{
std::lock_guard lock_guard(file_.get_file_access_mutex());
@ -112,10 +112,10 @@ std::shared_ptr<Track> OricMFMDSK::get_track_at_position(Track::Address address)
}
}
return std::make_shared<PCMTrack>(segment);
return std::make_unique<PCMTrack>(segment);
}
void OricMFMDSK::set_tracks(const std::map<Track::Address, std::shared_ptr<Track>> &tracks) {
void OricMFMDSK::set_tracks(const std::map<Track::Address, std::unique_ptr<Track>> &tracks) {
for(const auto &track : tracks) {
PCMSegment segment = Storage::Disk::track_serialisation(*track.second, Storage::Encodings::MFM::MFMBitLength);
Storage::Encodings::MFM::Shifter shifter;

View File

@ -32,8 +32,8 @@ public:
int get_head_count() final;
bool get_is_read_only() final;
void set_tracks(const std::map<Track::Address, std::shared_ptr<Track>> &tracks) final;
std::shared_ptr<Track> get_track_at_position(Track::Address address) final;
void set_tracks(const std::map<Track::Address, std::unique_ptr<Track>> &tracks) final;
std::unique_ptr<Track> track_at_position(Track::Address) final;
private:
Storage::FileHolder file_;

View File

@ -182,7 +182,7 @@ public:
(void)first_sync_;
}
std::shared_ptr<PCMTrack> get_track() {
std::unique_ptr<PCMTrack> get_track() {
// If no contents are supplied, return an unformatted track.
if(sectors_.empty() && track_data_.empty()) {
return nullptr;
@ -192,11 +192,11 @@ public:
// changes and fuzzy bits in sectors only.
if(sectors_.empty()) {
PCMSegment segment;
std::unique_ptr<Storage::Encodings::MFM::Encoder> encoder = Storage::Encodings::MFM::GetMFMEncoder(segment.data);
auto encoder = Storage::Encodings::MFM::GetMFMEncoder(segment.data);
for(auto c: track_data_) {
encoder->add_byte(c);
}
return std::make_shared<PCMTrack>(segment);
return std::make_unique<PCMTrack>(segment);
}
// Otherwise, seek to encode the sectors, using the track data to
@ -377,7 +377,7 @@ public:
track_size += 16;
}
return std::make_shared<PCMTrack>(segments);
return std::make_unique<PCMTrack>(segments);
}
private:
@ -448,7 +448,7 @@ int STX::get_head_count() {
return head_count_;
}
std::shared_ptr<::Storage::Disk::Track> STX::get_track_at_position(::Storage::Disk::Track::Address address) {
std::unique_ptr<Track> STX::track_at_position(Track::Address address) {
// These images have two sides, at most.
if(address.head > 1) return nullptr;

View File

@ -30,7 +30,7 @@ public:
HeadPosition get_maximum_head_position() final;
int get_head_count() final;
std::shared_ptr<::Storage::Disk::Track> get_track_at_position(::Storage::Disk::Track::Address address) final;
std::unique_ptr<Track> track_at_position(Track::Address) final;
private:
FileHolder file_;

View File

@ -18,7 +18,7 @@
using namespace Storage::Disk;
std::shared_ptr<Track> Storage::Disk::track_for_sectors(
std::unique_ptr<Track> Storage::Disk::track_for_sectors(
const uint8_t *const source,
int number_of_sectors,
uint8_t track,

View File

@ -17,7 +17,22 @@
namespace Storage::Disk {
std::shared_ptr<Track> track_for_sectors(const uint8_t *source, int number_of_sectors, uint8_t track, uint8_t side, uint8_t first_sector, uint8_t size, Storage::Encodings::MFM::Density density);
void decode_sectors(const Track &track, uint8_t *destination, uint8_t first_sector, uint8_t last_sector, uint8_t sector_size, Storage::Encodings::MFM::Density density);
std::unique_ptr<Track> track_for_sectors(
const uint8_t *source,
int number_of_sectors,
uint8_t track,
uint8_t side,
uint8_t first_sector,
uint8_t size,
Storage::Encodings::MFM::Density density
);
void decode_sectors(
const Track &track,
uint8_t *destination,
uint8_t first_sector,
uint8_t last_sector,
uint8_t sector_size,
Storage::Encodings::MFM::Density density
);
}

View File

@ -147,7 +147,7 @@ bool WOZ::tracks_differ(Track::Address lhs, Track::Address rhs) {
return offset1 != offset2;
}
std::shared_ptr<Track> WOZ::get_track_at_position(Track::Address address) {
std::unique_ptr<Track> WOZ::track_at_position(Track::Address address) {
const long offset = file_offset(address);
if(offset == NoSuchTrack) {
return nullptr;
@ -183,10 +183,10 @@ std::shared_ptr<Track> WOZ::get_track_at_position(Track::Address address) {
}
}
return std::make_shared<PCMTrack>(PCMSegment(number_of_bits, track_contents));
return std::make_unique<PCMTrack>(PCMSegment(number_of_bits, track_contents));
}
void WOZ::set_tracks(const std::map<Track::Address, std::shared_ptr<Track>> &tracks) {
void WOZ::set_tracks(const std::map<Track::Address, std::unique_ptr<Track>> &tracks) {
if(type_ == Type::WOZ2) return;
for(const auto &pair: tracks) {

View File

@ -26,8 +26,8 @@ public:
// Implemented to satisfy @c DiskImage.
HeadPosition get_maximum_head_position() final;
int get_head_count() final;
std::shared_ptr<Track> get_track_at_position(Track::Address address) final;
void set_tracks(const std::map<Track::Address, std::shared_ptr<Track>> &tracks) final;
std::unique_ptr<Track> track_at_position(Track::Address) final;
void set_tracks(const std::map<Track::Address, std::unique_ptr<Track>> &tracks) final;
bool get_is_read_only() final;
bool tracks_differ(Track::Address, Track::Address) final;

View File

@ -8,8 +8,6 @@
#include "Drive.hpp"
#include "Track/UnformattedTrack.hpp"
#include <algorithm>
#include <cassert>
#include <cmath>
@ -107,7 +105,7 @@ void Drive::step(HeadPosition offset) {
did_step(head_position_);
}
std::shared_ptr<Track> Drive::step_to(HeadPosition offset) {
Track *Drive::step_to(HeadPosition offset) {
HeadPosition old_head_position = head_position_;
head_position_ = std::max(offset, HeadPosition(0));
@ -343,8 +341,8 @@ void Drive::process_next_event() {
// MARK: - Track management
std::shared_ptr<Track> Drive::get_track() {
if(disk_) return disk_->get_track_at_position(Track::Address(head_, head_position_));
Track *Drive::get_track() {
if(disk_) return disk_->track_at_position(Track::Address(head_, head_position_));
return nullptr;
}
@ -355,7 +353,7 @@ void Drive::set_track(const std::shared_ptr<Track> &track) {
void Drive::setup_track() {
track_ = get_track();
if(!track_) {
track_ = std::make_shared<UnformattedTrack>();
track_ = &unformatted_track_;
}
float offset = 0.0f;
@ -426,11 +424,11 @@ void Drive::end_writing() {
if(!patched_track_) {
// Avoid creating a new patched track if this one is already patched
patched_track_ = std::dynamic_pointer_cast<PCMTrack>(track_);
if(!patched_track_ || !patched_track_->is_resampled_clone()) {
Track *const tr = track_.get();
// patched_track_ = dynamic_cast<PCMTrack *>(track_);
// if(!patched_track_ || !patched_track_->is_resampled_clone()) {
Track *const tr = track_;
patched_track_.reset(PCMTrack::resampled_clone(tr, high_resolution_track_rate));
}
// }
}
patched_track_->add_segment(write_start_time_, write_segment_, clamp_writing_to_index_hole_);
cycles_since_index_hole_ %= cycles_per_revolution_;

View File

@ -11,6 +11,7 @@
#include "Disk.hpp"
#include "Track/PCMSegment.hpp"
#include "Track/PCMTrack.hpp"
#include "Track/UnformattedTrack.hpp"
#include "../TimedEventLoop.hpp"
#include "../../Activity/Observer.hpp"
@ -174,7 +175,7 @@ public:
It's for the benefit of user-optional fast-loading mechanisms **ONLY**.
*/
std::shared_ptr<Track> step_to(HeadPosition offset);
Track *step_to(HeadPosition offset);
/*!
Alters the rotational velocity of this drive.
@ -209,7 +210,8 @@ private:
// Drives contain an entire disk; from that a certain track
// will be currently under the head.
std::shared_ptr<Disk> disk_;
std::shared_ptr<Track> track_;
UnformattedTrack unformatted_track_;
Track *track_ = nullptr;
bool has_disk_ = false;
// Contains the multiplier that converts between track-relative lengths
@ -274,7 +276,7 @@ private:
/*!
@returns the track underneath the current head at the location now stepped to.
*/
std::shared_ptr<Track> get_track();
Track *get_track();
/*!
Attempts to set @c track as the track underneath the current head at the location now stepped to.

View File

@ -179,7 +179,7 @@ public:
}
};
template<class T> std::shared_ptr<Storage::Disk::Track>
template<class T> std::unique_ptr<Storage::Disk::Track>
GTrackWithSectors(
const std::vector<const Sector *> &sectors,
std::size_t post_index_address_mark_bytes, uint8_t post_index_address_mark_value,
@ -300,7 +300,7 @@ template<class T> std::shared_ptr<Storage::Disk::Track>
// Allow the amount of data written to be up to 10% more than the expected size. Which is generous.
if(segment.data.size() > max_size) segment.data.resize(max_size);
return std::make_shared<Storage::Disk::PCMTrack>(std::move(segment));
return std::make_unique<Storage::Disk::PCMTrack>(std::move(segment));
}
Encoder::Encoder(std::vector<bool> &target, std::vector<bool> *fuzzy_target) :
@ -339,7 +339,7 @@ void Encoder::add_crc(bool incorrectly) {
namespace {
template <Density density>
std::shared_ptr<Storage::Disk::Track> TTrackWithSectors(
std::unique_ptr<Storage::Disk::Track> TTrackWithSectors(
const std::vector<const Sector *> &sectors,
std::optional<std::size_t> sector_gap_length,
std::optional<uint8_t> sector_gap_filler_byte
@ -361,7 +361,7 @@ std::shared_ptr<Storage::Disk::Track> TTrackWithSectors(
}
std::shared_ptr<Storage::Disk::Track> Storage::Encodings::MFM::TrackWithSectors(
std::unique_ptr<Storage::Disk::Track> Storage::Encodings::MFM::TrackWithSectors(
Density density,
const std::vector<Sector> &sectors,
std::optional<std::size_t> sector_gap_length,
@ -375,7 +375,7 @@ std::shared_ptr<Storage::Disk::Track> Storage::Encodings::MFM::TrackWithSectors(
);
}
std::shared_ptr<Storage::Disk::Track> Storage::Encodings::MFM::TrackWithSectors(
std::unique_ptr<Storage::Disk::Track> Storage::Encodings::MFM::TrackWithSectors(
Density density,
const std::vector<const Sector *> &sectors,
std::optional<std::size_t> sector_gap_length,

View File

@ -27,13 +27,13 @@ namespace Storage::Encodings::MFM {
@param sector_gap_length If specified, sets the distance in whole bytes between each ID and its data.
@param sector_gap_filler_byte If specified, sets the value (unencoded) that is used to populate the gap between each ID and its data.
*/
std::shared_ptr<Storage::Disk::Track> TrackWithSectors(
std::unique_ptr<Storage::Disk::Track> TrackWithSectors(
Density density,
const std::vector<Sector> &sectors,
std::optional<std::size_t> sector_gap_length = std::nullopt,
std::optional<uint8_t> sector_gap_filler_byte = std::nullopt);
std::shared_ptr<Storage::Disk::Track> TrackWithSectors(
std::unique_ptr<Storage::Disk::Track> TrackWithSectors(
Density density,
const std::vector<const Sector *> &sectors,
std::optional<std::size_t> sector_gap_length = std::nullopt,

View File

@ -25,7 +25,7 @@ void Parser::install_track(const Storage::Disk::Track::Address &address) {
return;
}
const auto track = disk_->get_track_at_position(address);
const auto track = disk_->track_at_position(address);
if(!track) {
return;
}