Skip to content

Commit

Permalink
Queue when current paragraph is too long
Browse files Browse the repository at this point in the history
  • Loading branch information
ButterscotchV committed Jan 29, 2024
1 parent 6accf1f commit 0e2de41
Show file tree
Hide file tree
Showing 3 changed files with 138 additions and 39 deletions.
44 changes: 44 additions & 0 deletions ButterSTT.Tests/MessageSystem/MessageQueueTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -139,5 +139,49 @@ public void MaxDequeueTest()
output.WriteLine($"Second message: \"{curMessage}\"");
Assert.Equal($"queue system. {secondMessage}", curMessage);
}

[Fact()]
public void RealtimeAppendingTooLongTest()
{
var queue = new MessageQueue
{
MessageLength = 33,
WordTime = TimeSpan.Zero,
MaxWordsDequeued = int.MaxValue
};

// Initial message, fully completed
var firstMessage = "Testing the queue system.";
queue.CurParagraph = EnglishTextParser.ParseParagraph(firstMessage);
queue.FinishCurrentParagraph();

// Add a partial sentence to it
var secondMessage = "Second test ";
queue.CurParagraph = EnglishTextParser.ParseParagraph(secondMessage);
var curMessage = queue.GetCurrentMessage();
output.WriteLine($"Appended message: \"{curMessage}\"");
Assert.Equal($"{firstMessage} Second-", curMessage);
}

[Fact()]
public void RealtimeTooLongTest()
{
var queue = new MessageQueue
{
MessageLength = 18,
WordTime = TimeSpan.Zero,
MaxWordsDequeued = int.MaxValue
};

queue.CurParagraph = EnglishTextParser.ParseParagraph("Testing th");
var curMessage = queue.GetCurrentMessage();
output.WriteLine($"First message: \"{curMessage}\"");
Assert.Equal("Testing", curMessage);

queue.CurParagraph = EnglishTextParser.ParseParagraph("Testing the queue system.");
curMessage = queue.GetCurrentMessage();
output.WriteLine($"Second message: \"{curMessage}\"");
Assert.Equal("Testing the queue-", curMessage);
}
}
}
131 changes: 93 additions & 38 deletions ButterSTT/MessageSystem/MessageQueue.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,68 +34,76 @@ public void LimitParagraphIndex()
}
}

public void FinishCurrentParagraph()
public IEnumerable<string> ParagraphWordEnumerator()
{
// Limit the index if length has changed since last known
LimitParagraphIndex();

// Queue all words after the current displayed ones
for (var s = CurIndex.sentence; s < CurParagraph.Sentences.Length; s++)
{
var wordCount = CurParagraph.Sentences[s].Words.Length;
for (var w = CurIndex.word; w < wordCount; w++)
var sentence = CurParagraph.Sentences[s];
for (
var w = s <= CurIndex.sentence ? CurIndex.word : 0;
w < sentence.Words.Length;
w++
)
{
var word = CurParagraph.Sentences[s].Words[w];
WordQueue.Enqueue(
$"{word.Text}{(w + 1 >= wordCount && !word.Text.EndsWith(' ') ? " " : "")}"
);
yield return sentence.Words[w].Text;
}
// Reset word index to 0 for following sentences
CurIndex.word = 0;
}
}

public void FinishCurrentParagraph()
{
// Queue all words after the current displayed ones
foreach (var word in ParagraphWordEnumerator())
{
WordQueue.Enqueue(word);
}

// Reset states
CurParagraph = default;
CurIndex = default;
}

public string GetCurrentMessage()
public int ParagraphLengthFromIndex() => ParagraphWordEnumerator().Sum(w => w.Length);

public void QueueParagraphToFit(int padding = 0)
{
// Remove expired words if more space is needed
if (WordQueue.Count > 0 || CurParagraph.Length > 0)
// Limit the index if length has changed since last known
LimitParagraphIndex();

var paragraphLen = ParagraphLengthFromIndex();
// Queue as few words after the current displayed ones
for (var s = CurIndex.sentence; s < CurParagraph.Sentences.Length; s++)
{
var dequeueCount = 0;
while (
dequeueCount++ < MaxWordsDequeued
&& MessageWordQueue.TryPeek(out var expiredWord)
&& DateTime.UtcNow >= expiredWord.ExpiryTime
var sentence = CurParagraph.Sentences[s];
for (
var w = s <= CurIndex.sentence ? CurIndex.word : 0;
w < sentence.Words.Length;
w++
)
{
CurMessageLength -= MessageWordQueue.Dequeue().Text.Length;
}
}
if (paragraphLen <= MessageLength - padding)
{
CurIndex = (s, w);
return;
}

// If there's no queue and there's new words to display
if (WordQueue.Count <= 0 && CurParagraph.Length > 0)
{
// Fit the whole current paragraph in the message if possible
if (CurParagraph.Length <= MessageLength - CurMessageLength)
{
return string.Concat(
string.Concat(MessageWordQueue.Select(w => w.Text)),
string.Concat(
CurParagraph.Sentences.SelectMany(x => x.Words, (x, y) => y.Text)
)
)
.Trim();
var word = sentence.Words[w].Text;
WordQueue.Enqueue(word);
paragraphLen -= word.Length;
}
}
}

// Make sure there is enough room to fit a new word in the message and
// allow space for a dash after the current text if there is already more
private void ProgressWordQueue()
{
// Make sure there is enough room to fit a new word in the message
while (
WordQueue.TryPeek(out var newWord)
&& CurMessageLength + newWord.Length + (WordQueue.Count > 1 ? 1 : 0) < MessageLength
&& CurMessageLength + newWord.Length < MessageLength
)
{
var word = WordQueue.Dequeue();
Expand All @@ -109,9 +117,56 @@ public string GetCurrentMessage()
);
CurMessageLength += word.Length;
}
}

public string GetCurrentMessage()
{
// Remove expired words if more space is needed
if (WordQueue.Count > 0 || CurParagraph.Length > 0)
{
var dequeueCount = 0;
while (
dequeueCount++ < MaxWordsDequeued
&& MessageWordQueue.TryPeek(out var expiredWord)
&& DateTime.UtcNow >= expiredWord.ExpiryTime
)
{
CurMessageLength -= MessageWordQueue.Dequeue().Text.Length;
}
}

if (CurParagraph.Length >= MessageLength)
{
// Queue with a padding of the max words times the average word length
QueueParagraphToFit(MaxWordsDequeued * 6);
}

ProgressWordQueue();

var message = string.Concat(MessageWordQueue.Select(w => w.Text));

// If there's no queue and there's new words to display
if (WordQueue.Count <= 0 && CurParagraph.Length > 0)
{
var availableLength = MessageLength - CurMessageLength;
var totalTaken = 0;
var paragraph = string.Concat(
ParagraphWordEnumerator()
.TakeWhile(w =>
{
if (totalTaken + w.Length <= availableLength)
{
totalTaken += w.Length;
return true;
}
else
return false;
})
);
return (message + paragraph).Trim() + (CurParagraph.Length > totalTaken ? "-" : "");
}

var message = string.Concat(MessageWordQueue.Select(w => w.Text)).Trim();
return $"{message}{(WordQueue.Count > 0 ? "-" : "")}";
return message.Trim() + (WordQueue.Count > 0 ? "-" : "");
}
}
}
2 changes: 1 addition & 1 deletion ButterSTT/TextProcessing/EnglishTextParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public static Sentence ParseSentence(string text)
{
Word[] words = WordOnlyCompleteKeepUrl()
.Matches(text)
.Select(m => new Word(m.Value))
.Select(m => new Word(m.Value.EndsWith(' ') ? m.Value : m.Value + " "))
.ToArray();
return new Sentence(words);
}
Expand Down

0 comments on commit 0e2de41

Please sign in to comment.