// // DiskImageImplementation.hpp // Clock Signal // // Created by Thomas Harte on 22/09/2017. // Copyright 2017 Thomas Harte. All rights reserved. // template HeadPosition DiskImageHolder::maximum_head_position() const { return disk_image_.maximum_head_position(); } template int DiskImageHolder::head_count() const { return disk_image_.head_count(); } template bool DiskImageHolder::is_read_only() const { return disk_image_.is_read_only(); } template bool DiskImageHolder::represents(const std::string &file) const { return disk_image_.represents(file); } template bool DiskImageHolder::has_written() const { return has_written_; } template void DiskImageHolder::flush_tracks() { if(!unwritten_tracks_.empty()) { if(!update_queue_) update_queue_ = std::make_unique>(); using TrackMap = std::map>; auto track_copies = std::make_shared(); for(const auto &address : unwritten_tracks_) { track_copies->insert({address, std::unique_ptr(cached_tracks_[address]->clone())}); } unwritten_tracks_.clear(); update_queue_->enqueue([this, track_copies]() { disk_image_.set_tracks(*track_copies); }); } } template void DiskImageHolder::set_track_at_position(Track::Address address, const std::shared_ptr &track) { if(disk_image_.is_read_only()) return; has_written_ = true; unwritten_tracks_.insert(address); cached_tracks_[address] = track; } template Track *DiskImageHolder::track_at_position(Track::Address address) const { if(address.head >= head_count()) return nullptr; if(address.position >= maximum_head_position()) return nullptr; 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 = disk_image_.track_at_position(canonical_address); if(!track) return nullptr; cached_tracks_[canonical_address] = track; return track.get(); } template DiskImageHolder::~DiskImageHolder() { if(update_queue_) update_queue_->flush(); } template bool DiskImageHolder::tracks_differ(Track::Address lhs, Track::Address rhs) const { return disk_image_.tracks_differ(lhs, rhs); }