1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-06-25 18:30:07 +00:00

Severs the DiskImage implementation from its public header file.

This commit is contained in:
Thomas Harte 2017-09-22 22:46:31 -04:00
parent 698e4fe550
commit d72dad2d1a
3 changed files with 59 additions and 50 deletions

View File

@ -612,6 +612,7 @@
4B45189C1F75FD1C00926311 /* SingleTrackDisk.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SingleTrackDisk.cpp; sourceTree = "<group>"; };
4B45189D1F75FD1C00926311 /* SingleTrackDisk.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = SingleTrackDisk.hpp; sourceTree = "<group>"; };
4B4518A71F76004200926311 /* TapeParser.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = TapeParser.hpp; path = Parsers/TapeParser.hpp; sourceTree = "<group>"; };
4B4518A81F76022000926311 /* DiskImageImplementation.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = DiskImageImplementation.hpp; sourceTree = "<group>"; };
4B4A762E1DB1A3FA007AAE2E /* AY38910.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = AY38910.cpp; path = AY38910/AY38910.cpp; sourceTree = "<group>"; };
4B4A762F1DB1A3FA007AAE2E /* AY38910.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = AY38910.hpp; path = AY38910/AY38910.hpp; sourceTree = "<group>"; };
4B4DC81F1D2C2425003C5BF8 /* Vic20.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Vic20.cpp; sourceTree = "<group>"; };
@ -1443,6 +1444,7 @@
children = (
4B45188A1F75FD1B00926311 /* DiskImage.cpp */,
4B45188B1F75FD1B00926311 /* DiskImage.hpp */,
4B4518A81F76022000926311 /* DiskImageImplementation.hpp */,
4B45188C1F75FD1B00926311 /* Formats */,
);
path = DiskImage;

View File

@ -19,16 +19,11 @@ namespace Storage {
namespace Disk {
/*!
Models a disk as a collection of tracks, providing a range of possible track positions and allowing
a point sampling of the track beneath any of those positions (if any).
Models a disk image as a collection of tracks, plus a range of possible track positions.
The intention is not that tracks necessarily be evenly spaced; a head_position_count of 3 wih track
A appearing in positions 0 and 1, and track B appearing in position 2 is an appropriate use of this API
if it matches the media.
The track returned is point sampled only; if a particular disk drive has a sufficiently large head to
pick up multiple tracks at once then the drive responsible for asking for multiple tracks and for
merging the results.
*/
class DiskImage {
public:
@ -70,10 +65,14 @@ class DiskImageHolderBase: public Disk {
protected:
int get_id_for_track_at_position(unsigned int head, unsigned int position);
std::map<int, std::shared_ptr<Track>> cached_tracks_;
std::unique_ptr<Concurrency::AsyncTaskQueue> update_queue_;
};
/*!
Provides a wrapper that wraps a DiskImage to make it into a Disk, providing caching and,
thereby, an intermediate store for modified tracks so that mutable disk images can either
update on the fly or perform a block update on closure, as appropriate.
*/
template <typename T> class DiskImageHolder: public DiskImageHolderBase {
public:
template <typename... Ts> DiskImageHolder(Ts&&... args) :
@ -90,49 +89,7 @@ template <typename T> class DiskImageHolder: public DiskImageHolderBase {
T disk_image_;
};
template <typename T> unsigned int DiskImageHolder<T>::get_head_position_count() {
return disk_image_.get_head_position_count();
}
template <typename T> unsigned int DiskImageHolder<T>::get_head_count() {
return disk_image_.get_head_count();
}
template <typename T> bool DiskImageHolder<T>::get_is_read_only() {
return disk_image_.get_is_read_only();
}
template <typename T> void DiskImageHolder<T>::set_track_at_position(unsigned int head, unsigned int position, const std::shared_ptr<Track> &track) {
if(disk_image_.get_is_read_only()) return;
int address = get_id_for_track_at_position(head, position);
cached_tracks_[address] = track;
if(!update_queue_) update_queue_.reset(new Concurrency::AsyncTaskQueue);
std::shared_ptr<Track> track_copy(track->clone());
update_queue_->enqueue([this, head, position, track_copy] {
disk_image_.set_track_at_position(head, position, track_copy);
});
}
template <typename T> std::shared_ptr<Track> DiskImageHolder<T>::get_track_at_position(unsigned int head, unsigned int position) {
if(head >= get_head_count()) return nullptr;
if(position >= get_head_position_count()) return nullptr;
int address = get_id_for_track_at_position(head, position);
std::map<int, std::shared_ptr<Track>>::iterator cached_track = cached_tracks_.find(address);
if(cached_track != cached_tracks_.end()) return cached_track->second;
std::shared_ptr<Track> track = disk_image_.get_track_at_position(head, position);
if(!track) return nullptr;
cached_tracks_[address] = track;
return track;
}
template <typename T> DiskImageHolder<T>::~DiskImageHolder() {
if(update_queue_) update_queue_->flush();
}
#include "DiskImageImplementation.hpp"
}
}

View File

@ -0,0 +1,50 @@
//
// DiskImageImplementation.hpp
// Clock Signal
//
// Created by Thomas Harte on 22/09/2017.
// Copyright © 2017 Thomas Harte. All rights reserved.
//
template <typename T> unsigned int DiskImageHolder<T>::get_head_position_count() {
return disk_image_.get_head_position_count();
}
template <typename T> unsigned int DiskImageHolder<T>::get_head_count() {
return disk_image_.get_head_count();
}
template <typename T> bool DiskImageHolder<T>::get_is_read_only() {
return disk_image_.get_is_read_only();
}
template <typename T> void DiskImageHolder<T>::set_track_at_position(unsigned int head, unsigned int position, const std::shared_ptr<Track> &track) {
if(disk_image_.get_is_read_only()) return;
int address = get_id_for_track_at_position(head, position);
cached_tracks_[address] = track;
if(!update_queue_) update_queue_.reset(new Concurrency::AsyncTaskQueue);
std::shared_ptr<Track> track_copy(track->clone());
update_queue_->enqueue([this, head, position, track_copy] {
disk_image_.set_track_at_position(head, position, track_copy);
});
}
template <typename T> std::shared_ptr<Track> DiskImageHolder<T>::get_track_at_position(unsigned int head, unsigned int position) {
if(head >= get_head_count()) return nullptr;
if(position >= get_head_position_count()) return nullptr;
int address = get_id_for_track_at_position(head, position);
std::map<int, std::shared_ptr<Track>>::iterator cached_track = cached_tracks_.find(address);
if(cached_track != cached_tracks_.end()) return cached_track->second;
std::shared_ptr<Track> track = disk_image_.get_track_at_position(head, position);
if(!track) return nullptr;
cached_tracks_[address] = track;
return track;
}
template <typename T> DiskImageHolder<T>::~DiskImageHolder() {
if(update_queue_) update_queue_->flush();
}