-
-
Notifications
You must be signed in to change notification settings - Fork 111
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[vtbackend] Refactor Sequencer into SequenceBuilder to increase code …
…share. Also, SequenceBuilder is the way better and more intuitive name than Sequencer :) Signed-off-by: Christian Parpart <[email protected]>
- Loading branch information
1 parent
8c6d981
commit 7d52144
Showing
11 changed files
with
389 additions
and
653 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,197 @@ | ||
// SPDX-License-Identifier: Apache-2.0 | ||
#pragma once | ||
|
||
#include <vtbackend/Sequence.h> | ||
#include <vtbackend/SixelParser.h> | ||
#include <vtbackend/logging.h> | ||
|
||
#include <vtparser/Parser.h> | ||
#include <vtparser/ParserExtension.h> | ||
|
||
#include <concepts> | ||
#include <memory> | ||
#include <string_view> | ||
|
||
namespace vtbackend | ||
{ | ||
|
||
template <typename T> | ||
concept InstructionCounterConcept = requires(T t, size_t n) { | ||
{ t() } -> std::same_as<void>; | ||
{ t(n) } -> std::same_as<void>; | ||
}; | ||
|
||
struct NoOpInstructionCounter | ||
{ | ||
void operator()(size_t /*increment*/ = 1) const noexcept {} | ||
}; | ||
|
||
/// SequenceBuilder - The semantic VT analyzer layer. | ||
/// | ||
/// SequenceBuilder implements the translation from VT parser events, forming a higher level Sequence, | ||
/// that can be matched against FunctionDefinition objects and then handled on the currently active Screen. | ||
template <SequenceHandlerConcept Handler, InstructionCounterConcept IncrementInstructionCounter> | ||
class SequenceBuilder | ||
{ | ||
public: | ||
explicit SequenceBuilder(Handler handler, IncrementInstructionCounter incrementInstructionCounter): | ||
Check warning on line 37 in src/vtbackend/SequenceBuilder.h GitHub Actions / clang-tidy-reviewclang-tidy
|
||
_sequence {}, | ||
_parameterBuilder { _sequence.parameters() }, | ||
_incrementInstructionCounter { std::move(incrementInstructionCounter) }, | ||
_handler { std::move(handler) } | ||
{ | ||
} | ||
|
||
// {{{ ParserEvents interface | ||
void error(std::string_view errorString) | ||
{ | ||
if (vtParserLog) | ||
vtParserLog()("Parser error: {}", errorString); | ||
Check warning on line 49 in src/vtbackend/SequenceBuilder.h GitHub Actions / clang-tidy-reviewclang-tidy
|
||
} | ||
void print(char32_t codepoint) | ||
{ | ||
_incrementInstructionCounter(); | ||
_handler.writeText(codepoint); | ||
} | ||
|
||
size_t print(std::string_view chars, size_t cellCount) | ||
{ | ||
assert(!chars.empty()); | ||
|
||
_incrementInstructionCounter(cellCount); | ||
_handler.writeText(chars, cellCount); | ||
return _handler.maxBulkTextSequenceWidth(); | ||
} | ||
|
||
void printEnd() { _handler.writeTextEnd(); } | ||
|
||
void execute(char controlCode) { _handler.executeControlCode(controlCode); } | ||
|
||
void clear() noexcept | ||
{ | ||
_sequence.clearExceptParameters(); | ||
_parameterBuilder.reset(); | ||
} | ||
|
||
void collect(char ch) { _sequence.intermediateCharacters().push_back(ch); } | ||
Check warning on line 76 in src/vtbackend/SequenceBuilder.h GitHub Actions / clang-tidy-reviewclang-tidy
|
||
|
||
void collectLeader(char leader) noexcept { _sequence.setLeader(leader); } | ||
|
||
void param(char ch) noexcept | ||
{ | ||
switch (ch) | ||
{ | ||
case ';': paramSeparator(); break; | ||
case ':': paramSubSeparator(); break; | ||
case '0': | ||
case '1': | ||
case '2': | ||
case '3': | ||
case '4': | ||
case '5': | ||
case '6': | ||
case '7': | ||
case '8': | ||
case '9': paramDigit(ch); break; | ||
default: crispy::unreachable(); | ||
} | ||
} | ||
|
||
void paramDigit(char ch) noexcept | ||
{ | ||
_parameterBuilder.multiplyBy10AndAdd(static_cast<uint8_t>(ch - '0')); | ||
} | ||
|
||
void paramSeparator() noexcept { _parameterBuilder.nextParameter(); } | ||
void paramSubSeparator() noexcept { _parameterBuilder.nextSubParameter(); } | ||
|
||
void dispatchESC(char finalChar) | ||
{ | ||
_sequence.setCategory(FunctionCategory::ESC); | ||
_sequence.setFinalChar(finalChar); | ||
handleSequence(); | ||
} | ||
|
||
void dispatchCSI(char finalChar) | ||
{ | ||
_sequence.setCategory(FunctionCategory::CSI); | ||
_sequence.setFinalChar(finalChar); | ||
handleSequence(); | ||
} | ||
|
||
void startOSC() { _sequence.setCategory(FunctionCategory::OSC); } | ||
|
||
void putOSC(char ch) | ||
{ | ||
if (_sequence.intermediateCharacters().size() + 1 < Sequence::MaxOscLength) | ||
_sequence.intermediateCharacters().push_back(ch); | ||
} | ||
|
||
void dispatchOSC() | ||
{ | ||
auto const [code, skipCount] = vtparser::extractCodePrefix(_sequence.intermediateCharacters()); | ||
_parameterBuilder.set(static_cast<Sequence::Parameter>(code)); | ||
_sequence.intermediateCharacters().erase(0, skipCount); | ||
handleSequence(); | ||
clear(); | ||
} | ||
|
||
void hook(char finalChar) | ||
{ | ||
_incrementInstructionCounter(); | ||
_sequence.setCategory(FunctionCategory::DCS); | ||
_sequence.setFinalChar(finalChar); | ||
|
||
handleSequence(); | ||
} | ||
void put(char ch) | ||
{ | ||
if (_hookedParser) | ||
_hookedParser->pass(ch); | ||
} | ||
void unhook() | ||
{ | ||
if (_hookedParser) | ||
{ | ||
_hookedParser->finalize(); | ||
_hookedParser.reset(); | ||
} | ||
} | ||
void startAPC() {} | ||
void putAPC(char) {} | ||
void dispatchAPC() {} | ||
void startPM() {} | ||
void putPM(char) {} | ||
void dispatchPM() {} | ||
|
||
void hookParser(std::unique_ptr<ParserExtension> parserExtension) noexcept | ||
{ | ||
_hookedParser = std::move(parserExtension); | ||
} | ||
|
||
[[nodiscard]] size_t maxBulkTextSequenceWidth() const noexcept | ||
{ | ||
return _handler.maxBulkTextSequenceWidth(); | ||
} | ||
// }}} | ||
|
||
private: | ||
void handleSequence() | ||
{ | ||
_parameterBuilder.fixiate(); | ||
_handler.processSequence(_sequence); | ||
} | ||
|
||
Sequence _sequence {}; | ||
SequenceParameterBuilder _parameterBuilder; | ||
IncrementInstructionCounter _incrementInstructionCounter; | ||
Handler _handler; | ||
|
||
std::unique_ptr<ParserExtension> _hookedParser {}; | ||
}; | ||
|
||
template <SequenceHandlerConcept Handler, InstructionCounterConcept IncrementInstructionCounter> | ||
SequenceBuilder(Handler&, | ||
IncrementInstructionCounter) -> SequenceBuilder<Handler, IncrementInstructionCounter>; | ||
|
||
} // namespace vtbackend |
Oops, something went wrong.