1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-07-05 10:28:58 +00:00

Get code up on feet, fix most obvious transgressions.

This commit is contained in:
Thomas Harte 2023-06-12 16:09:02 -04:00
parent 1aa953dd4d
commit d028555361
3 changed files with 78 additions and 16 deletions

View File

@ -1,15 +1,17 @@
//
// Serialiser.hpp
// RangeDispatcher.hpp
// Clock Signal
//
// Created by Thomas Harte on 29/05/2023.
// Copyright © 2023 Thomas Harte. All rights reserved.
//
#ifndef Dispatcher_hpp
#define Dispatcherr_hpp
#ifndef RangeDispatcher_hpp
#define RangeDispatcher_hpp
namespace Dispatcher {
#include <algorithm>
namespace Reflection {
/// Provides glue for a run of calls like:
///
@ -20,11 +22,11 @@ namespace Dispatcher {
///
/// Allowing the caller to execute any subrange of the calls.
template <typename SequencerT>
struct Dispatcher {
struct RangeDispatcher {
/// Perform @c target.perform<n>() for the input range `start <= n < end`.
template <typename... Args>
void dispatch(SequencerT &target, int start, int end, Args&&... args) {
static void dispatch(SequencerT &target, int start, int end, Args&&... args) {
// Minor optimisation: do a comparison with end once outside the loop and if it implies so
// then do no further comparisons within the loop. This is somewhat targetted at expected
@ -37,7 +39,7 @@ struct Dispatcher {
}
private:
template <bool use_end, typename... Args> void dispatch(SequencerT &target, int start, int end, Args&&... args) {
template <bool use_end, typename... Args> static void dispatch(SequencerT &target, int start, int end, Args&&... args) {
static_assert(SequencerT::max < 2048);
// Yes, macros, yuck. But I want an actual switch statement for the dispatch to start
@ -90,16 +92,16 @@ private:
};
/// An optional target for a Dispatcher which uses a classifier to divide the input region into typed ranges, issuing calls to the target
/// An optional target for a RangeDispatcher which uses a classifier to divide the input region into typed ranges, issuing calls to the target
/// only to begin and end each subrange, and for the number of cycles spent within.
template <typename ClassifierT, TargetT>
struct RangeDispatcher {
template <typename ClassifierT, typename TargetT>
struct SubrangeDispatcher {
static constexpr int max = ClassifierT::max;
template <int n, typename... Args>
void perform(int begin, int end, Arg&&... args) {
template <int n>
void perform(int begin, int end) {
constexpr auto region = ClassifierT::region(n);
const auto clipped_start = std::max(start, find_begin(n));
const auto clipped_start = std::max(begin, find_begin(n));
const auto clipped_end = std::min(end, find_end(n));
if constexpr (n == find_begin(n)) {
@ -125,8 +127,10 @@ struct RangeDispatcher {
while(n < ClassifierT::max && ClassifierT::region(n) == type) ++n;
return n;
}
TargetT &target;
};
}
#endif /* Dispatcher_hpp */
#endif /* RangeDispatcher_hpp */

View File

@ -7,6 +7,7 @@
objects = {
/* Begin PBXBuildFile section */
4281683A2A37AFB4008ECD27 /* DispatcherTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 428168392A37AFB4008ECD27 /* DispatcherTests.mm */; };
4B018B89211930DE002A3937 /* 65C02_extended_opcodes_test.bin in Resources */ = {isa = PBXBuildFile; fileRef = 4B018B88211930DE002A3937 /* 65C02_extended_opcodes_test.bin */; };
4B01A6881F22F0DB001FD6E3 /* Z80MemptrTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B01A6871F22F0DB001FD6E3 /* Z80MemptrTests.swift */; };
4B0333AF2094081A0050B93D /* AppleDSK.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B0333AD2094081A0050B93D /* AppleDSK.cpp */; };
@ -1101,7 +1102,8 @@
/* Begin PBXFileReference section */
428168372A16C25C008ECD27 /* LineLayout.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = LineLayout.hpp; sourceTree = "<group>"; };
428168382A254FBE008ECD27 /* Dispatcher.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Dispatcher.hpp; sourceTree = "<group>"; };
428168382A254FBE008ECD27 /* RangeDispatcher.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = RangeDispatcher.hpp; sourceTree = "<group>"; };
428168392A37AFB4008ECD27 /* DispatcherTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = DispatcherTests.mm; sourceTree = "<group>"; };
42AD552E2A0C4D5000ACE410 /* 68000.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = 68000.hpp; sourceTree = "<group>"; };
42AD55302A0C4D5000ACE410 /* 68000Storage.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = 68000Storage.hpp; sourceTree = "<group>"; };
42AD55312A0C4D5000ACE410 /* 68000Implementation.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = 68000Implementation.hpp; sourceTree = "<group>"; };
@ -4287,6 +4289,7 @@
4BE34437238389E10058E78F /* AtariSTVideoTests.mm */,
4BB2A9AE1E13367E001A5C23 /* CRCTests.mm */,
4BB0CAA627E51B6300672A88 /* DingusdevPowerPCTests.mm */,
428168392A37AFB4008ECD27 /* DispatcherTests.mm */,
4BFF1D3C2235C3C100838EA1 /* EmuTOSTests.mm */,
4B47770C26900685005C2340 /* EnterpriseDaveTests.mm */,
4B051CB2267D3FF800CA44E8 /* EnterpriseNickTests.mm */,
@ -4972,7 +4975,7 @@
4BB06B211F316A3F00600C7A /* ForceInline.hpp */,
4B80214322EE7C3E00068002 /* JustInTime.hpp */,
4B644ED023F0FB55006C0CC5 /* ScanSynchroniser.hpp */,
428168382A254FBE008ECD27 /* Dispatcher.hpp */,
428168382A254FBE008ECD27 /* RangeDispatcher.hpp */,
4B449C942063389900A095C8 /* TimeTypes.hpp */,
4B996B2D2496DAC2001660EF /* VSyncPredictor.hpp */,
);
@ -6155,6 +6158,7 @@
4B3BA0D01D318B44005DD7A7 /* MOS6532Bridge.mm in Sources */,
4B778F3823A5F11C0000D260 /* SegmentParser.cpp in Sources */,
4B778F0723A5EC150000D260 /* CommodoreTAP.cpp in Sources */,
4281683A2A37AFB4008ECD27 /* DispatcherTests.mm in Sources */,
4B778F4123A5F19A0000D260 /* MemoryPacker.cpp in Sources */,
4B778F4423A5F1BE0000D260 /* CommodoreGCR.cpp in Sources */,
4B778EF923A5EB740000D260 /* MSA.cpp in Sources */,

View File

@ -0,0 +1,54 @@
//
// DispatcherTests.m
// Clock SignalTests
//
// Created by Thomas Harte on 12/06/2023.
// Copyright © 2023 Thomas Harte. All rights reserved.
//
#import <XCTest/XCTest.h>
#include "RangeDispatcher.hpp"
#include <array>
#include <cassert>
@interface DispatcherTests : XCTestCase
@end
@implementation DispatcherTests {
}
- (void)setUp {
}
- (void)tearDown {
}
struct DoStep {
static constexpr int max = 100;
template <int n> void perform(int, int) {
assert(n < max);
performed[n] = true;
}
std::array<bool, max> performed{};
};
- (void)testPoints {
DoStep stepper;
Reflection::RangeDispatcher<DoStep>::dispatch(stepper, 0, 10);
for(size_t c = 0; c < stepper.performed.size(); c++) {
XCTAssert(stepper.performed[c] == (c < 10));
}
Reflection::RangeDispatcher<DoStep>::dispatch(stepper, 29, 100000);
for(size_t c = 0; c < stepper.performed.size(); c++) {
XCTAssert(stepper.performed[c] == (c < 10) || (c >= 29));
}
}
- (void)testRanges {
}
@end