Keep the engine fed instead of feeding it a character at a time
The pump handed the engine one character and then waited a character time
before the next, on purpose, so it stayed behind the engine rather than ahead.
That leaves the engine with an empty buffer between every two characters of a
message, and an engine with an empty buffer transmits idle rather than waiting.
The idle is added to how long the message takes, which in a contest is time
paid for nothing.
The pump now keeps two characters in the engine: one being transmitted and one
behind it, so the engine never runs dry. The clock at the baud rate says when
the engine has room for the next one, and the engine reporting that it has
stopped transmitting sets the estimate back to an empty buffer.
The last two characters are now beyond reach rather than the last one. Everything
before them can still be rewritten, which is what the pane is for.
A message is finished when the buffer is empty and the engine is estimated to
have transmitted what it holds, so {END} and {RX} no longer run while the engine
still has the last characters of the message.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RtspmWmS7f8kUvcyaHpRWZ
This commit is contained in:
@@ -3,8 +3,9 @@ using Nonemm.Digital;
|
||||
|
||||
namespace Nonemm.Digital.Tests;
|
||||
|
||||
/// The text waiting to go out, fed to the engine a character at a time. The
|
||||
/// pump is run at a baud rate no radio uses so the tests do not wait for RTTY.
|
||||
/// The text waiting to go out, fed to the engine a few characters at a time.
|
||||
/// The pump is run at a baud rate no radio uses so the tests do not wait for
|
||||
/// RTTY.
|
||||
public class TypeAheadTests
|
||||
{
|
||||
private static readonly TimeSpan Patience = TimeSpan.FromSeconds(5);
|
||||
@@ -13,6 +14,10 @@ public class TypeAheadTests
|
||||
/// test can still catch the pump partway through.
|
||||
private const double Fast = 7500;
|
||||
|
||||
/// A character time of 100 ms, so a test can tell the characters sent ahead
|
||||
/// from the ones that wait for the engine.
|
||||
private const double Slow = 75;
|
||||
|
||||
private readonly StringBuilder went = new();
|
||||
|
||||
private string Sent
|
||||
@@ -48,7 +53,7 @@ public class TypeAheadTests
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task AMessageGoesOutOneCharacterAtATime()
|
||||
public async Task AMessageGoesOut()
|
||||
{
|
||||
using TypeAhead buffer = Buffer();
|
||||
|
||||
@@ -178,6 +183,52 @@ public class TypeAheadTests
|
||||
Assert.Equal("", buffer.Sent);
|
||||
}
|
||||
|
||||
/// The engine is given the second character before it has transmitted the
|
||||
/// first, so it has one in hand when the first is done. An engine left with
|
||||
/// an empty buffer transmits idle instead, and that idle is added to how
|
||||
/// long the message takes.
|
||||
[Fact]
|
||||
public async Task TheEngineIsKeptOneCharacterAhead()
|
||||
{
|
||||
using TypeAhead buffer = Buffer(baud: Slow);
|
||||
|
||||
buffer.Append("CQ TEST");
|
||||
|
||||
await WaitForAsync(() => Sent.Length >= 2);
|
||||
Assert.Equal("CQ", Sent);
|
||||
}
|
||||
|
||||
/// Only the lead goes out ahead. The rest waits, which is what leaves it
|
||||
/// where the operator can still change it.
|
||||
[Fact]
|
||||
public async Task NoMoreThanTheLeadGoesToTheEngineAtOnce()
|
||||
{
|
||||
using TypeAhead buffer = Buffer(baud: Slow);
|
||||
|
||||
buffer.Append("CQ TEST");
|
||||
|
||||
await WaitForAsync(() => Sent.Length >= 2);
|
||||
await Task.Delay(20);
|
||||
Assert.Equal(2, Sent.Length);
|
||||
}
|
||||
|
||||
/// The estimate of what the engine still holds is only an estimate. An
|
||||
/// engine that says it has stopped transmitting has an empty buffer, and
|
||||
/// the next character goes to it at once rather than a character time
|
||||
/// later.
|
||||
[Fact]
|
||||
public async Task AnIdleEngineIsFedWithoutWaiting()
|
||||
{
|
||||
using TypeAhead buffer = Buffer(baud: Slow);
|
||||
buffer.Append("CQ TEST");
|
||||
await WaitForAsync(() => Sent.Length >= 2);
|
||||
|
||||
buffer.EngineIdle();
|
||||
|
||||
await WaitForAsync(() => Sent.Length >= 4);
|
||||
Assert.Equal("CQ T", Sent);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ACharacterTakesAsLongAsTheBaudRateSays()
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user