From bfa9b6ab603f053f20bf2560030c01720723da4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=ADn=20Lucas=20Golini?= Date: Mon, 31 Aug 2026 01:15:28 -0300 Subject: [PATCH] Rename TerminalController to TerminalSession. --- .../eterm/terminal/terminaldisplay.hpp | 8 +- ...inalcontroller.hpp => terminalsession.hpp} | 32 ++-- .../src/eterm/terminal/terminaldisplay.cpp | 174 ++++++++--------- ...inalcontroller.cpp => terminalsession.cpp} | 123 ++++++------ src/tests/unit_tests/eterm_tests.cpp | 176 +++++++++--------- src/tools/eterm_tabs/eterm_tabs.cpp | 4 +- 6 files changed, 255 insertions(+), 262 deletions(-) rename src/modules/eterm/include/eterm/terminal/{terminalcontroller.hpp => terminalsession.hpp} (88%) rename src/modules/eterm/src/eterm/terminal/{terminalcontroller.cpp => terminalsession.cpp} (80%) diff --git a/src/modules/eterm/include/eterm/terminal/terminaldisplay.hpp b/src/modules/eterm/include/eterm/terminal/terminaldisplay.hpp index f5a64041a..76904182d 100644 --- a/src/modules/eterm/include/eterm/terminal/terminaldisplay.hpp +++ b/src/modules/eterm/include/eterm/terminal/terminaldisplay.hpp @@ -12,7 +12,7 @@ #include #include #include -#include +#include #include #include @@ -242,7 +242,7 @@ class TerminalDisplay { void setPadding( const Rectf& padding ); - const std::shared_ptr& getController() const; + const std::shared_ptr& getSession() const; std::string getSelection(); @@ -313,7 +313,7 @@ class TerminalDisplay { protected: EE::Window::Window* mWindow; std::vector mColors; - std::shared_ptr mController; + std::shared_ptr mSession; std::shared_ptr mSnapshot; mutable std::string mClipboardUtf8; Uint32 mNumCallBacks{ 0 }; @@ -382,7 +382,7 @@ class TerminalDisplay { void consumeSnapshot(); - void drainControllerEvents(); + void drainSessionEvents(); TerminalColorPalette makeColorPalette() const; diff --git a/src/modules/eterm/include/eterm/terminal/terminalcontroller.hpp b/src/modules/eterm/include/eterm/terminal/terminalsession.hpp similarity index 88% rename from src/modules/eterm/include/eterm/terminal/terminalcontroller.hpp rename to src/modules/eterm/include/eterm/terminal/terminalsession.hpp index 2f7d1bd57..59be5bef2 100644 --- a/src/modules/eterm/include/eterm/terminal/terminalcontroller.hpp +++ b/src/modules/eterm/include/eterm/terminal/terminalsession.hpp @@ -1,5 +1,5 @@ -#ifndef ETERM_TERMINALCONTROLLER_HPP -#define ETERM_TERMINALCONTROLLER_HPP +#ifndef ETERM_TERMINALSESSION_HPP +#define ETERM_TERMINALSESSION_HPP #include #include @@ -69,13 +69,13 @@ struct TerminalColorPalette { }; /** - * Per-terminal worker/controller. + * Per-terminal worker/session. * * After create() returns, the worker thread exclusively owns the emulator, PTY, process, parser, * history, selection, and cursor. UI code may only enqueue commands, drain events, or retain an - * immutable snapshot returned by snapshot(). No controller callback is invoked by the worker. + * immutable snapshot returned by snapshot(). No session callback is invoked by the worker. */ -class TerminalController final : public std::enable_shared_from_this { +class TerminalSession final : public std::enable_shared_from_this { public: using PtyPtr = std::unique_ptr; using ProcPtr = std::unique_ptr; @@ -104,16 +104,16 @@ class TerminalController final : public std::enable_shared_from_this create( PtyPtr&& pty, ProcPtr&& process, - size_t historySize, - TerminalColorPalette palette = {} ); + static std::shared_ptr create( PtyPtr&& pty, ProcPtr&& process, + size_t historySize, + TerminalColorPalette palette = {} ); - ~TerminalController(); + ~TerminalSession(); - TerminalController( const TerminalController& ) = delete; - TerminalController( TerminalController&& ) = delete; - TerminalController& operator=( const TerminalController& ) = delete; - TerminalController& operator=( TerminalController&& ) = delete; + TerminalSession( const TerminalSession& ) = delete; + TerminalSession( TerminalSession&& ) = delete; + TerminalSession& operator=( const TerminalSession& ) = delete; + TerminalSession& operator=( TerminalSession&& ) = delete; void write( std::string data, bool mayEcho = true ); void writeRaw( std::string data ); @@ -218,8 +218,8 @@ class TerminalController final : public std::enable_shared_from_this; - TerminalController( PtyPtr&& pty, ProcPtr&& process, size_t historySize, - TerminalColorPalette palette ); + TerminalSession( PtyPtr&& pty, ProcPtr&& process, size_t historySize, + TerminalColorPalette palette ); void start(); bool enqueue( Command&& command ); @@ -246,4 +246,4 @@ class TerminalController final : public std::enable_shared_from_this TerminalDisplay::create( std::shared_ptr terminal = std::shared_ptr( new TerminalDisplay( window, font, fontSize, pixelsSize, useFrameBuffer ) ); - terminal->mController = - TerminalController::create( std::move( pseudoTerminal ), std::move( process ), historySize, - terminal->makeColorPalette() ); - if ( !terminal->mController ) { + terminal->mSession = + TerminalSession::create( std::move( pseudoTerminal ), std::move( process ), historySize, + terminal->makeColorPalette() ); + if ( !terminal->mSession ) { if ( freeProcessFactory ) eeSAFE_DELETE( processFactory ); return nullptr; } - terminal->mController->setPresentationRate( presentationRateForWindow( window ) ); + terminal->mSession->setPresentationRate( presentationRateForWindow( window ) ); terminal->mProgram = program; terminal->mArgs = args; terminal->mEnv = env; @@ -473,8 +473,8 @@ std::shared_ptr TerminalDisplay::create( } TerminalDisplay::~TerminalDisplay() { - if ( mController ) - mController->shutdown(); + if ( mSession ) + mSession->shutdown(); } TerminalDisplay::TerminalDisplay( EE::Window::Window* window, Font* font, const Float& fontSize, @@ -621,8 +621,8 @@ void TerminalDisplay::setPadding( const Rectf& padding ) { } } -const std::shared_ptr& TerminalDisplay::getController() const { - return mController; +const std::shared_ptr& TerminalDisplay::getSession() const { + return mSession; } int TerminalDisplay::scrollSize() const { @@ -638,7 +638,7 @@ int TerminalDisplay::scrollPosition() const { } Uint64 TerminalDisplay::scrollTo( int position ) { - return mController ? mController->scrollTo( position ) : 0; + return mSession ? mSession->scrollTo( position ) : 0; } Uint64 TerminalDisplay::lastAppliedScrollCommand() const { @@ -679,13 +679,13 @@ const TerminalColorScheme& TerminalDisplay::getColorScheme() const { void TerminalDisplay::setColorScheme( const TerminalColorScheme& colorScheme ) { mColorScheme = colorScheme; resetColors(); - if ( mController ) - mController->setColorPalette( makeColorPalette() ); + if ( mSession ) + mSession->setColorPalette( makeColorPalette() ); invalidateLines(); } bool TerminalDisplay::isAppCapturingMouse() const { - return mController && + return mSession && ( mMode & ( MODE_MOUSEX10 | MODE_MOUSEBTN | MODE_MOUSEMOTION | MODE_MOUSEMANY ) ); } @@ -711,7 +711,7 @@ void TerminalDisplay::setKeepAlive( bool keepAlive ) { bool TerminalDisplay::update( bool isMouseOverMe ) { consumeSnapshot(); - drainControllerEvents(); + drainSessionEvents(); if ( mFocus && isBlinkingCursor() && mClock.getElapsedTime().asSeconds() > 0.7 ) { mMode ^= MODE_BLINK; mClock.restart(); @@ -730,9 +730,9 @@ bool TerminalDisplay::update( bool isMouseOverMe ) { } void TerminalDisplay::consumeSnapshot() { - if ( !mController ) + if ( !mSession ) return; - auto snapshot = mController->snapshot(); + auto snapshot = mSession->snapshot(); if ( !snapshot || snapshot->generation == mSnapshotGeneration ) return; @@ -781,56 +781,56 @@ void TerminalDisplay::consumeSnapshot() { mDirty = true; } -void TerminalDisplay::drainControllerEvents() { - if ( !mController ) +void TerminalDisplay::drainSessionEvents() { + if ( !mSession ) return; - for ( auto& event : mController->drainEvents() ) { + for ( auto& event : mSession->drainEvents() ) { switch ( event.type ) { - case TerminalController::EventType::Title: + case TerminalSession::EventType::Title: sendEvent( { EventType::TITLE, std::move( event.data ) } ); break; - case TerminalController::EventType::IconTitle: + case TerminalSession::EventType::IconTitle: sendEvent( { EventType::ICON_TITLE, std::move( event.data ) } ); break; - case TerminalController::EventType::ScrollPosition: + case TerminalSession::EventType::ScrollPosition: sendEvent( { EventType::SCROLL_HISTORY } ); break; - case TerminalController::EventType::Bell: + case TerminalSession::EventType::Bell: sendEvent( { EventType::BELL } ); break; - case TerminalController::EventType::Clipboard: + case TerminalSession::EventType::Clipboard: setClipboard( event.data.c_str() ); sendEvent( { EventType::CLIPBOARD } ); break; - case TerminalController::EventType::ProcessExit: + case TerminalSession::EventType::ProcessExit: onProcessExit( event.value ); break; - case TerminalController::EventType::RestartFailure: + case TerminalSession::EventType::RestartFailure: sendEvent( { EventType::RESTART_FAILURE, std::move( event.data ) } ); break; - case TerminalController::EventType::Data: + case TerminalSession::EventType::Data: if ( mDataCallback ) mDataCallback( event.data.data(), event.data.size() ); break; - case TerminalController::EventType::PromptState: + case TerminalSession::EventType::PromptState: if ( mPromptStateChangedCallback ) mPromptStateChangedCallback( event.promptState, event.data ); break; - case TerminalController::EventType::Color: + case TerminalSession::EventType::Color: if ( event.value < 0 ) resetColors(); else resetColor( event.value, event.data.empty() ? nullptr : event.data.c_str() ); invalidateLines(); break; - case TerminalController::EventType::Error: + case TerminalSession::EventType::Error: Log::error( "Terminal worker error: %s", event.data.c_str() ); sendEvent( { EventType::WORKER_ERROR, std::move( event.data ) } ); break; - case TerminalController::EventType::HistoryLength: + case TerminalSession::EventType::HistoryLength: sendEvent( { EventType::HISTORY_LENGTH_CHANGE } ); break; - case TerminalController::EventType::SnapshotReady: + case TerminalSession::EventType::SnapshotReady: break; } } @@ -848,8 +848,8 @@ TerminalColorPalette TerminalDisplay::makeColorPalette() const { } std::string TerminalDisplay::getSelection() { - if ( mController ) { - if ( auto selection = mController->requestSelection() ) + if ( mSession ) { + if ( auto selection = mSession->requestSelection() ) return std::move( *selection ); } return mSnapshot ? mSnapshot->selection : std::string{}; @@ -872,33 +872,33 @@ int TerminalDisplay::getExitCode() const { } void TerminalDisplay::terminate() { - if ( mController ) - mController->terminate(); + if ( mSession ) + mSession->terminate(); } void TerminalDisplay::setAllowMemoryTrimming( bool allow ) { - if ( mController ) - mController->setAllowMemoryTrimming( allow ); + if ( mSession ) + mSession->setAllowMemoryTrimming( allow ); } void TerminalDisplay::setDataCallback( DataFunc callback ) { mDataCallback = std::move( callback ); - if ( mController ) - mController->setDataEventsEnabled( static_cast( mDataCallback ) ); + if ( mSession ) + mSession->setDataEventsEnabled( static_cast( mDataCallback ) ); } void TerminalDisplay::setPromptStateChangedCallback( PromptStateChangedFunc callback ) { mPromptStateChangedCallback = std::move( callback ); - if ( mController ) - mController->setPromptEventsEnabled( static_cast( mPromptStateChangedCallback ) ); + if ( mSession ) + mSession->setPromptEventsEnabled( static_cast( mPromptStateChangedCallback ) ); } void TerminalDisplay::setCursorMode( TerminalCursorMode mode ) { if ( mCursorMode == mode ) return; mCursorMode = mode; - if ( mController ) - mController->setCursorMode( mode ); + if ( mSession ) + mSession->setCursorMode( mode ); invalidateCursor(); } @@ -907,29 +907,29 @@ TerminalCursorMode TerminalDisplay::getCursorMode() const { } void TerminalDisplay::executeFile( const std::string& cmd ) { - if ( mController ) { + if ( mSession ) { std::string rcmd; #if EE_PLATFORM != EE_PLATFORM_WIN rcmd.push_back( 0x15 ); #endif rcmd.append( cmd ).push_back( '\r' ); - mController->write( std::move( rcmd ) ); + mSession->write( std::move( rcmd ) ); } } void TerminalDisplay::executeBinary( const std::string& binaryPath, const std::string& args ) { - if ( mController ) { + if ( mSession ) { std::string rcmd; #if EE_PLATFORM != EE_PLATFORM_WIN rcmd.push_back( 0x15 ); #endif rcmd.append( "\"" ).append( binaryPath ).append( "\" " ).append( args ).push_back( '\r' ); - mController->write( std::move( rcmd ) ); + mSession->write( std::move( rcmd ) ); } } void TerminalDisplay::action( TerminalShortcutAction action ) { - if ( !mController && action != TerminalShortcutAction::FONTSIZE_GROW && + if ( !mSession && action != TerminalShortcutAction::FONTSIZE_GROW && action != TerminalShortcutAction::FONTSIZE_SHRINK ) return; switch ( action ) { @@ -937,11 +937,11 @@ void TerminalDisplay::action( TerminalShortcutAction action ) { getClipboard(); if ( !mClipboardUtf8.empty() ) { if ( mMode & MODE_BRCKTPASTE ) { - mController->writeRaw( "\033[200~" ); - mController->writeRaw( std::move( mClipboardUtf8 ) ); - mController->writeRaw( "\033[201~" ); + mSession->writeRaw( "\033[200~" ); + mSession->writeRaw( std::move( mClipboardUtf8 ) ); + mSession->writeRaw( "\033[201~" ); } else { - mController->writeRaw( std::move( mClipboardUtf8 ) ); + mSession->writeRaw( std::move( mClipboardUtf8 ) ); } } break; @@ -955,11 +955,11 @@ void TerminalDisplay::action( TerminalShortcutAction action ) { sanitizeInput( selection ); if ( !selection.empty() ) { if ( mMode & MODE_BRCKTPASTE ) { - mController->writeRaw( "\033[200~" ); - mController->writeRaw( std::move( selection ) ); - mController->writeRaw( "\033[201~" ); + mSession->writeRaw( "\033[200~" ); + mSession->writeRaw( std::move( selection ) ); + mSession->writeRaw( "\033[201~" ); } else { - mController->writeRaw( std::move( selection ) ); + mSession->writeRaw( std::move( selection ) ); } } break; @@ -971,27 +971,27 @@ void TerminalDisplay::action( TerminalShortcutAction action ) { break; } case TerminalShortcutAction::SCROLLUP_SCREEN: { - mController->scrollUp( -(int)mClickStep ); + mSession->scrollUp( -(int)mClickStep ); break; } case TerminalShortcutAction::SCROLLDOWN_SCREEN: { - mController->scrollDown( -(int)mClickStep ); + mSession->scrollDown( -(int)mClickStep ); break; } case TerminalShortcutAction::SCROLLUP_ROW: { - mController->scrollUp( mClickStep ); + mSession->scrollUp( mClickStep ); break; } case TerminalShortcutAction::SCROLLDOWN_ROW: { - mController->scrollDown( mClickStep ); + mSession->scrollDown( mClickStep ); break; } case TerminalShortcutAction::SCROLLUP_HISTORY: { - mController->scrollUp( INT_MAX ); + mSession->scrollUp( INT_MAX ); break; } case TerminalShortcutAction::SCROLLDOWN_HISTORY: { - mController->scrollDown( INT_MAX ); + mSession->scrollDown( INT_MAX ); break; } case TerminalShortcutAction::FONTSIZE_GROW: { @@ -1055,7 +1055,7 @@ void TerminalDisplay::onMouseDoubleClick( const Vector2i& pos, const Uint32& fla if ( !isAppCapturingMouse() && ( flags & EE_BUTTON_LMASK ) && ( getSelectionMode() == SEL_EMPTY || getSelectionMode() == SEL_IDLE ) ) { auto gridPos{ positionToGrid( pos ) }; - mController->selectionStart( gridPos.x, gridPos.y, SNAP_WORD ); + mSession->selectionStart( gridPos.x, gridPos.y, SNAP_WORD ); } } @@ -1083,13 +1083,13 @@ void TerminalDisplay::onMouseMove( const Vector2i& pos, const Uint32& flags ) { if ( !isCapturingMouse && ( flags & EE_BUTTON_LMASK ) && ( mDraggingSel || getSelectionMode() == SEL_EMPTY || getSelectionMode() == SEL_READY ) ) { auto gridPos{ positionToGrid( pos ) }; - mController->selectionExtend( + mSession->selectionExtend( gridPos.x, gridPos.y, mWindow->getInput()->getModState() & KEYMOD_SHIFT ? SEL_RECTANGULAR : SEL_REGULAR, false ); } - mController->mouseReport( TerminalMouseEventType::MouseMotion, positionToGrid( pos ), flags, - mWindow->getInput()->getModState() ); + mSession->mouseReport( TerminalMouseEventType::MouseMotion, positionToGrid( pos ), flags, + mWindow->getInput()->getModState() ); } void TerminalDisplay::onMouseDown( const Vector2i& pos, const Uint32& flags ) { @@ -1103,10 +1103,10 @@ void TerminalDisplay::onMouseDown( const Vector2i& pos, const Uint32& flags ) { if ( !isCapturingMouse && ( flags & EE_BUTTON_LMASK ) && mLastDoubleClick.getElapsedTime() < Milliseconds( 300.f ) ) { - mController->selectionStart( gridPos.x, gridPos.y, SNAP_LINE ); + mSession->selectionStart( gridPos.x, gridPos.y, SNAP_LINE ); } else if ( !isCapturingMouse && ( flags & EE_BUTTON_LMASK ) ) { if ( !mDraggingSel ) { - mController->selectionStart( gridPos.x, gridPos.y, 0 ); + mSession->selectionStart( gridPos.x, gridPos.y, 0 ); mDraggingSel = true; invalidateLines(); mWindow->getInput()->captureMouse( true ); @@ -1129,8 +1129,8 @@ void TerminalDisplay::onMouseDown( const Vector2i& pos, const Uint32& flags ) { } } - mController->mouseReport( TerminalMouseEventType::MouseButtonDown, positionToGrid( pos ), flags, - mWindow->getInput()->getModState() ); + mSession->mouseReport( TerminalMouseEventType::MouseButtonDown, positionToGrid( pos ), flags, + mWindow->getInput()->getModState() ); } void TerminalDisplay::onMouseUp( const Vector2i& pos, const Uint32& flags ) { @@ -1176,8 +1176,8 @@ void TerminalDisplay::onMouseUp( const Vector2i& pos, const Uint32& flags ) { } } - mController->mouseReport( TerminalMouseEventType::MouseButtonRelease, positionToGrid( pos ), - flags, mWindow->getInput()->getModState() ); + mSession->mouseReport( TerminalMouseEventType::MouseButtonRelease, positionToGrid( pos ), flags, + mWindow->getInput()->getModState() ); } static inline Color termColor( unsigned int terminalColor, const std::vector& colors ) { @@ -1713,7 +1713,7 @@ void TerminalDisplay::drawBg( bool toFBO ) { } void TerminalDisplay::draw( const Vector2f& pos ) { - if ( !mController || !mSnapshot ) + if ( !mSession || !mSnapshot ) return; mDrawing = true; @@ -1777,9 +1777,9 @@ void TerminalDisplay::onSizeChange() { mFont, mFontSize, mSize - Vector2f( mPadding.Left + mPadding.Right, mPadding.Top + mPadding.Bottom ) ) ); - if ( mController && ( !mSnapshot || gridSize.getWidth() != mSnapshot->columns || - gridSize.getHeight() != mSnapshot->rows ) ) { - mController->resize( gridSize.getWidth(), gridSize.getHeight() ); + if ( mSession && ( !mSnapshot || gridSize.getWidth() != mSnapshot->columns || + gridSize.getHeight() != mSnapshot->rows ) ) { + mSession->resize( gridSize.getWidth(), gridSize.getHeight() ); mDirtyLines.resize( gridSize.getHeight(), 1 ); } @@ -1798,7 +1798,7 @@ void TerminalDisplay::onSizeChange() { void TerminalDisplay::onProcessExit( int exitCode ) { sendEvent( { EventType::PROCESS_EXIT, String::toString( exitCode ) } ); - if ( !mController || mProgram.empty() || exitCode != 0 || !mKeepAlive ) + if ( !mSession || mProgram.empty() || exitCode != 0 || !mKeepAlive ) return; auto processFactory = eeNew( ProcessFactory, () ); @@ -1824,23 +1824,23 @@ void TerminalDisplay::onProcessExit( int exitCode ) { return; } - mController->restart( std::move( pseudoTerminal ), std::move( process ) ); + mSession->restart( std::move( pseudoTerminal ), std::move( process ) ); eeSAFE_DELETE( processFactory ); } void TerminalDisplay::onTextInput( const Uint32& chr ) { - if ( !mController ) + if ( !mSession ) return; String input; input.push_back( chr ); std::string utf8Input( input.toUtf8() ); - mController->write( std::move( utf8Input ) ); + mSession->write( std::move( utf8Input ) ); mDirty = true; } void TerminalDisplay::onTextEditing( const String&, const Int32&, const Int32& ) { - if ( !mController ) + if ( !mSession ) return; invalidateCursor(); updateIMELocation(); @@ -1910,7 +1910,7 @@ void TerminalDisplay::onKeyDown( const Keycode& keyCode, const Uint32& /*chr*/, } } - mController->write( std::string( 1, tmp ) ); + mSession->write( std::string( 1, tmp ) ); return; } } @@ -1929,7 +1929,7 @@ void TerminalDisplay::onKeyDown( const Keycode& keyCode, const Uint32& /*chr*/, continue; if ( k.string.size() > 0 ) { - mController->write( k.string ); + mSession->write( k.string ); return; } break; @@ -1951,7 +1951,7 @@ void TerminalDisplay::onKeyDown( const Keycode& keyCode, const Uint32& /*chr*/, continue; if ( k.string.size() > 0 ) { - mController->write( k.string ); + mSession->write( k.string ); return; } break; @@ -2069,8 +2069,8 @@ void TerminalDisplay::setFocus( bool focus ) { } else { mMode &= ~MODE_FOCUSED; } - if ( mController ) - mController->setFocus( focus ); + if ( mSession ) + mSession->setFocus( focus ); invalidateCursor(); } diff --git a/src/modules/eterm/src/eterm/terminal/terminalcontroller.cpp b/src/modules/eterm/src/eterm/terminal/terminalsession.cpp similarity index 80% rename from src/modules/eterm/src/eterm/terminal/terminalcontroller.cpp rename to src/modules/eterm/src/eterm/terminal/terminalsession.cpp index 616616228..d09c8e97c 100644 --- a/src/modules/eterm/src/eterm/terminal/terminalcontroller.cpp +++ b/src/modules/eterm/src/eterm/terminal/terminalsession.cpp @@ -1,4 +1,4 @@ -#include +#include #include #include @@ -10,19 +10,17 @@ using namespace EE::System; namespace eterm { namespace Terminal { -struct TerminalController::SelectionResponse { +struct TerminalSession::SelectionResponse { std::mutex mutex; std::condition_variable condition; std::string selection; bool ready{ false }; }; -class TerminalController::WorkerDisplay final : public ITerminalDisplay { +class TerminalSession::WorkerDisplay final : public ITerminalDisplay { public: - WorkerDisplay( TerminalController& controller, TerminalColorPalette palette ) : - mController( controller ), - mInitialPalette( std::move( palette ) ), - mPalette( mInitialPalette ) { + WorkerDisplay( TerminalSession& session, TerminalColorPalette palette ) : + mSession( session ), mInitialPalette( std::move( palette ) ), mPalette( mInitialPalette ) { mMode |= MODE_FOCUSED; } @@ -96,18 +94,18 @@ class TerminalController::WorkerDisplay final : public ITerminalDisplay { mLastHistoryLength = snapshot->historyLength; Event event{ EventType::HistoryLength }; event.value = mLastHistoryLength; - mController.enqueueEvent( std::move( event ), true ); + mSession.enqueueEvent( std::move( event ), true ); } - mController.publishSnapshot( std::move( snapshot ) ); + mSession.publishSnapshot( std::move( snapshot ) ); } - void bell() { mController.enqueueEvent( { EventType::Bell }, false ); } + void bell() { mSession.enqueueEvent( { EventType::Bell }, false ); } void resetColors() { mPalette = mInitialPalette; Event event{ EventType::Color }; event.value = -1; - mController.enqueueEvent( std::move( event ), false ); + mSession.enqueueEvent( std::move( event ), false ); } int resetColor( const Uint32& index, const char* name ) { @@ -149,7 +147,7 @@ class TerminalController::WorkerDisplay final : public ITerminalDisplay { Event event{ EventType::Color }; event.data = name ? name : ""; event.value = static_cast( index ); - mController.enqueueEvent( std::move( event ), false ); + mSession.enqueueEvent( std::move( event ), false ); return 0; } @@ -174,27 +172,25 @@ class TerminalController::WorkerDisplay final : public ITerminalDisplay { void setTitle( const char* title ) { mTitle = title ? title : ""; - mController.enqueueEvent( { EventType::Title, mTitle }, true ); + mSession.enqueueEvent( { EventType::Title, mTitle }, true ); } void setIconTitle( const char* title ) { - mController.enqueueEvent( { EventType::IconTitle, title ? title : "" }, true ); + mSession.enqueueEvent( { EventType::IconTitle, title ? title : "" }, true ); } void setClipboard( const char* text ) { if ( text ) - mController.enqueueEvent( { EventType::Clipboard, text }, false ); + mSession.enqueueEvent( { EventType::Clipboard, text }, false ); } void onProcessExit( int exitCode ) { Event event{ EventType::ProcessExit }; event.value = exitCode; - mController.enqueueEvent( std::move( event ), false ); + mSession.enqueueEvent( std::move( event ), false ); } - void onScrollPositionChange() { - mController.enqueueEvent( { EventType::ScrollPosition }, true ); - } + void onScrollPositionChange() { mSession.enqueueEvent( { EventType::ScrollPosition }, true ); } void setPalette( TerminalColorPalette palette ) { mInitialPalette = palette; @@ -224,7 +220,7 @@ class TerminalController::WorkerDisplay final : public ITerminalDisplay { mPalette.background = color; } - TerminalController& mController; + TerminalSession& mSession; TerminalColorPalette mInitialPalette; TerminalColorPalette mPalette; std::vector mCells; @@ -241,35 +237,35 @@ class TerminalController::WorkerDisplay final : public ITerminalDisplay { bool mCursorVisible{ false }; }; -std::shared_ptr TerminalController::create( PtyPtr&& pty, ProcPtr&& process, - size_t historySize, - TerminalColorPalette palette ) { +std::shared_ptr TerminalSession::create( PtyPtr&& pty, ProcPtr&& process, + size_t historySize, + TerminalColorPalette palette ) { if ( !pty || !process ) return nullptr; - auto controller = std::shared_ptr( new TerminalController( + auto session = std::shared_ptr( new TerminalSession( std::move( pty ), std::move( process ), historySize, std::move( palette ) ) ); - controller->start(); - return controller; + session->start(); + return session; } -TerminalController::TerminalController( PtyPtr&& pty, ProcPtr&& process, size_t historySize, - TerminalColorPalette palette ) { +TerminalSession::TerminalSession( PtyPtr&& pty, ProcPtr&& process, size_t historySize, + TerminalColorPalette palette ) { mWorkerDisplay = std::make_shared( *this, std::move( palette ) ); mEmulator = TerminalEmulator::create( std::move( pty ), std::move( process ), mWorkerDisplay, historySize ); - // Establish a complete generation before the controller becomes concurrently visible. + // Establish a complete generation before the session becomes concurrently visible. mEmulator->redraw(); } -TerminalController::~TerminalController() { +TerminalSession::~TerminalSession() { shutdown(); } -void TerminalController::start() { +void TerminalSession::start() { mWorker = std::thread( [this] { workerLoop(); } ); } -void TerminalController::shutdown() { +void TerminalSession::shutdown() { std::lock_guard shutdownLock( mShutdownMutex ); if ( !mShutdownRequested.exchange( true, std::memory_order_acq_rel ) ) mCommandCondition.notify_all(); @@ -277,7 +273,7 @@ void TerminalController::shutdown() { mWorker.join(); } -bool TerminalController::enqueue( Command&& command ) { +bool TerminalSession::enqueue( Command&& command ) { { std::lock_guard lock( mCommandMutex ); @@ -291,27 +287,27 @@ bool TerminalController::enqueue( Command&& command ) { return true; } -void TerminalController::write( std::string data, bool mayEcho ) { +void TerminalSession::write( std::string data, bool mayEcho ) { enqueue( WriteCommand{ std::move( data ), mayEcho } ); } -void TerminalController::writeRaw( std::string data ) { +void TerminalSession::writeRaw( std::string data ) { enqueue( WriteRawCommand{ std::move( data ) } ); } -void TerminalController::resize( int columns, int rows ) { +void TerminalSession::resize( int columns, int rows ) { enqueue( ResizeCommand{ columns, rows } ); } -void TerminalController::scrollUp( int amount ) { +void TerminalSession::scrollUp( int amount ) { enqueue( ScrollCommand{ amount, -1 } ); } -void TerminalController::scrollDown( int amount ) { +void TerminalSession::scrollDown( int amount ) { enqueue( ScrollCommand{ amount, 1 } ); } -Uint64 TerminalController::scrollTo( int position ) { +Uint64 TerminalSession::scrollTo( int position ) { const Uint64 commandId = mNextScrollCommand.fetch_add( 1, std::memory_order_relaxed ) + 1; if ( !enqueue( ScrollCommand{ position, 0, commandId } ) ) @@ -320,60 +316,60 @@ Uint64 TerminalController::scrollTo( int position ) { return commandId; } -void TerminalController::selectionStart( int column, int row, int snap ) { +void TerminalSession::selectionStart( int column, int row, int snap ) { enqueue( SelectionStartCommand{ column, row, snap } ); } -void TerminalController::selectionExtend( int column, int row, int type, bool done ) { +void TerminalSession::selectionExtend( int column, int row, int type, bool done ) { enqueue( SelectionExtendCommand{ column, row, type, done } ); } -void TerminalController::selectionClear() { +void TerminalSession::selectionClear() { enqueue( SelectionClearCommand{} ); } -void TerminalController::mouseReport( TerminalMouseEventType type, Vector2i position, Uint32 flags, - Uint32 modifiers ) { +void TerminalSession::mouseReport( TerminalMouseEventType type, Vector2i position, Uint32 flags, + Uint32 modifiers ) { enqueue( MouseCommand{ type, position, flags, modifiers } ); } -void TerminalController::setFocus( bool focus ) { +void TerminalSession::setFocus( bool focus ) { enqueue( FocusCommand{ { focus } } ); } -void TerminalController::setCursorMode( TerminalCursorMode mode ) { +void TerminalSession::setCursorMode( TerminalCursorMode mode ) { enqueue( CursorModeCommand{ mode } ); } -void TerminalController::setColorPalette( TerminalColorPalette palette ) { +void TerminalSession::setColorPalette( TerminalColorPalette palette ) { enqueue( PaletteCommand{ std::move( palette ) } ); } -void TerminalController::setAllowMemoryTrimming( bool allow ) { +void TerminalSession::setAllowMemoryTrimming( bool allow ) { enqueue( AllowTrimCommand{ { allow } } ); } -void TerminalController::setPresentationRate( Uint32 framesPerSecond ) { +void TerminalSession::setPresentationRate( Uint32 framesPerSecond ) { enqueue( PresentationRateCommand{ framesPerSecond } ); } -void TerminalController::setDataEventsEnabled( bool enabled ) { +void TerminalSession::setDataEventsEnabled( bool enabled ) { enqueue( DataEventsCommand{ { enabled } } ); } -void TerminalController::setPromptEventsEnabled( bool enabled ) { +void TerminalSession::setPromptEventsEnabled( bool enabled ) { enqueue( PromptEventsCommand{ { enabled } } ); } -void TerminalController::reset() { +void TerminalSession::reset() { enqueue( ResetCommand{} ); } -void TerminalController::terminate() { +void TerminalSession::terminate() { enqueue( TerminateCommand{} ); } -void TerminalController::restart( PtyPtr&& pty, ProcPtr&& process ) { +void TerminalSession::restart( PtyPtr&& pty, ProcPtr&& process ) { if ( !pty || !process ) { enqueueEvent( { EventType::RestartFailure, "Invalid PTY or process" }, false ); return; @@ -381,13 +377,12 @@ void TerminalController::restart( PtyPtr&& pty, ProcPtr&& process ) { enqueue( RestartCommand{ std::move( pty ), std::move( process ) } ); } -std::shared_ptr TerminalController::snapshot() const { +std::shared_ptr TerminalSession::snapshot() const { std::lock_guard lock( mPublishedSnapshotMutex ); return mPublishedSnapshot; } -std::optional -TerminalController::requestSelection( std::chrono::milliseconds timeout ) { +std::optional TerminalSession::requestSelection( std::chrono::milliseconds timeout ) { if ( mShutdownRequested.load( std::memory_order_acquire ) ) return std::nullopt; auto response = std::make_shared(); @@ -398,7 +393,7 @@ TerminalController::requestSelection( std::chrono::milliseconds timeout ) { return std::move( response->selection ); } -std::vector TerminalController::drainEvents() { +std::vector TerminalSession::drainEvents() { std::vector events; std::lock_guard lock( mEventMutex ); events.reserve( mEvents.size() ); @@ -409,7 +404,7 @@ std::vector TerminalController::drainEvents() { return events; } -void TerminalController::enqueueEvent( Event event, bool coalescable ) { +void TerminalSession::enqueueEvent( Event event, bool coalescable ) { std::lock_guard lock( mEventMutex ); if ( coalescable ) { for ( auto it = mEvents.rbegin(); it != mEvents.rend(); ++it ) { @@ -428,7 +423,7 @@ void TerminalController::enqueueEvent( Event event, bool coalescable ) { mEvents.emplace_back( std::move( event ) ); } -void TerminalController::publishSnapshot( std::shared_ptr snapshot ) { +void TerminalSession::publishSnapshot( std::shared_ptr snapshot ) { const Uint64 generation = snapshot->generation; { std::lock_guard lock( mPublishedSnapshotMutex ); @@ -439,7 +434,7 @@ void TerminalController::publishSnapshot( std::shared_ptr commands; { std::lock_guard lock( mCommandMutex ); @@ -470,7 +465,7 @@ void TerminalController::processCommands() { } } -void TerminalController::processCommand( Command&& command ) { +void TerminalSession::processCommand( Command&& command ) { std::visit( [this]( auto&& value ) { using T = std::decay_t; @@ -559,4 +554,4 @@ void TerminalController::processCommand( Command&& command ) { std::move( command ) ); } -}} // namespace eterm::Terminal +}} // namespace eterm::Terminal \ No newline at end of file diff --git a/src/tests/unit_tests/eterm_tests.cpp b/src/tests/unit_tests/eterm_tests.cpp index f76099bc0..270134ef4 100644 --- a/src/tests/unit_tests/eterm_tests.cpp +++ b/src/tests/unit_tests/eterm_tests.cpp @@ -4,8 +4,8 @@ #include #include #include -#include #include +#include #include #include @@ -59,12 +59,12 @@ class MockProcess : public IProcess { }; static std::shared_ptr -waitForSnapshot( const std::shared_ptr& controller, +waitForSnapshot( const std::shared_ptr& session, const std::function& predicate, std::chrono::milliseconds timeout = std::chrono::milliseconds( 1000 ) ) { const auto deadline = std::chrono::steady_clock::now() + timeout; while ( std::chrono::steady_clock::now() < deadline ) { - auto snapshot = controller->snapshot(); + auto snapshot = session->snapshot(); if ( snapshot && predicate( *snapshot ) ) return snapshot; std::this_thread::sleep_for( std::chrono::milliseconds( 1 ) ); @@ -72,60 +72,59 @@ waitForSnapshot( const std::shared_ptr& controller, return nullptr; } -UTEST( eterm_controller, command_wakeup_and_snapshot_immutability ) { +UTEST( eterm_session, command_wakeup_and_snapshot_immutability ) { auto pty = std::make_unique(); auto process = std::make_unique(); - auto controller = TerminalController::create( std::move( pty ), std::move( process ), 100 ); - ASSERT_TRUE( controller != nullptr ); + auto session = TerminalSession::create( std::move( pty ), std::move( process ), 100 ); + ASSERT_TRUE( session != nullptr ); - controller->writeRaw( "ABC" ); - auto first = waitForSnapshot( controller, []( const TerminalSnapshot& snapshot ) { + session->writeRaw( "ABC" ); + auto first = waitForSnapshot( session, []( const TerminalSnapshot& snapshot ) { return snapshot.cells.size() >= 3 && snapshot.cells[0].u == 'A' && snapshot.cells[1].u == 'B' && snapshot.cells[2].u == 'C'; } ); ASSERT_TRUE( first != nullptr ); const Uint64 firstGeneration = first->generation; - controller->writeRaw( "\rXYZ" ); - auto second = - waitForSnapshot( controller, [firstGeneration]( const TerminalSnapshot& snapshot ) { - return snapshot.generation > firstGeneration && snapshot.cells[0].u == 'X'; - } ); + session->writeRaw( "\rXYZ" ); + auto second = waitForSnapshot( session, [firstGeneration]( const TerminalSnapshot& snapshot ) { + return snapshot.generation > firstGeneration && snapshot.cells[0].u == 'X'; + } ); ASSERT_TRUE( second != nullptr ); EXPECT_EQ( static_cast( 'A' ), first->cells[0].u ); EXPECT_TRUE( second->generation > first->generation ); } -UTEST( eterm_controller, skipped_snapshot_generation_requires_full_redraw ) { +UTEST( eterm_session, skipped_snapshot_generation_requires_full_redraw ) { TerminalSnapshot snapshot; snapshot.generation = 42; EXPECT_TRUE( snapshot.dirtyRowsFollow( 41 ) ); EXPECT_FALSE( snapshot.dirtyRowsFollow( 40 ) ); } -UTEST( eterm_controller, ordered_selection_request ) { +UTEST( eterm_session, ordered_selection_request ) { auto pty = std::make_unique(); pty->mBuffer = "ordered selection"; auto process = std::make_unique(); - auto controller = TerminalController::create( std::move( pty ), std::move( process ), 100 ); - ASSERT_TRUE( waitForSnapshot( controller, []( const TerminalSnapshot& snapshot ) { + auto session = TerminalSession::create( std::move( pty ), std::move( process ), 100 ); + ASSERT_TRUE( waitForSnapshot( session, []( const TerminalSnapshot& snapshot ) { return !snapshot.cells.empty() && snapshot.cells[0].u == 'o'; } ) != nullptr ); - controller->selectionStart( 0, 0, 0 ); - controller->selectionExtend( 6, 0, SEL_REGULAR, false ); - auto selection = controller->requestSelection(); + session->selectionStart( 0, 0, 0 ); + session->selectionExtend( 6, 0, SEL_REGULAR, false ); + auto selection = session->requestSelection(); ASSERT_TRUE( selection.has_value() ); EXPECT_STDSTREQ( "ordered", *selection ); } -UTEST( eterm_controller, loaded_command_latency_stays_bounded ) { +UTEST( eterm_session, loaded_command_latency_stays_bounded ) { auto pty = std::make_unique(); pty->mBuffer.assign( 32 * 1024 * 1024, 'L' ); pty->mMaxRead = 64; MockPty* ptyPtr = pty.get(); auto process = std::make_unique(); - auto controller = TerminalController::create( std::move( pty ), std::move( process ), 100 ); + auto session = TerminalSession::create( std::move( pty ), std::move( process ), 100 ); const auto readDeadline = std::chrono::steady_clock::now() + std::chrono::milliseconds( 100 ); while ( ptyPtr->mBytesRead.load( std::memory_order_relaxed ) == 0 && std::chrono::steady_clock::now() < readDeadline ) @@ -133,19 +132,19 @@ UTEST( eterm_controller, loaded_command_latency_stays_bounded ) { ASSERT_TRUE( ptyPtr->mBytesRead.load( std::memory_order_relaxed ) > 0 ); const auto start = std::chrono::steady_clock::now(); - auto selection = controller->requestSelection(); + auto selection = session->requestSelection(); const auto latency = std::chrono::steady_clock::now() - start; EXPECT_TRUE( selection.has_value() ); EXPECT_TRUE( latency < std::chrono::milliseconds( 50 ) ); } -UTEST( eterm_controller, resize_and_output_are_serialized ) { +UTEST( eterm_session, resize_and_output_are_serialized ) { auto pty = std::make_unique(); auto process = std::make_unique(); - auto controller = TerminalController::create( std::move( pty ), std::move( process ), 100 ); - controller->resize( 40, 12 ); - controller->writeRaw( "after resize" ); - auto snapshot = waitForSnapshot( controller, []( const TerminalSnapshot& value ) { + auto session = TerminalSession::create( std::move( pty ), std::move( process ), 100 ); + session->resize( 40, 12 ); + session->writeRaw( "after resize" ); + auto snapshot = waitForSnapshot( session, []( const TerminalSnapshot& value ) { return value.columns == 40 && value.rows == 12 && !value.cells.empty() && value.cells[0].u == 'a'; } ); @@ -153,59 +152,59 @@ UTEST( eterm_controller, resize_and_output_are_serialized ) { EXPECT_EQ( static_cast( 40 * 12 ), snapshot->cells.size() ); } -UTEST( eterm_controller, scroll_snapshots_acknowledge_the_latest_ordered_command ) { +UTEST( eterm_session, scroll_snapshots_acknowledge_the_latest_ordered_command ) { auto pty = std::make_unique(); for ( int line = 0; line < 80; ++line ) pty->mBuffer += "history " + std::to_string( line ) + "\r\n"; auto process = std::make_unique(); - auto controller = TerminalController::create( std::move( pty ), std::move( process ), 100 ); - ASSERT_TRUE( waitForSnapshot( controller, []( const TerminalSnapshot& snapshot ) { + auto session = TerminalSession::create( std::move( pty ), std::move( process ), 100 ); + ASSERT_TRUE( waitForSnapshot( session, []( const TerminalSnapshot& snapshot ) { return snapshot.historyLength >= 25; } ) != nullptr ); - const Uint64 firstCommand = controller->scrollTo( 10 ); - const Uint64 secondCommand = controller->scrollTo( 25 ); + const Uint64 firstCommand = session->scrollTo( 10 ); + const Uint64 secondCommand = session->scrollTo( 25 ); EXPECT_EQ( firstCommand + 1, secondCommand ); auto acknowledged = - waitForSnapshot( controller, [secondCommand]( const TerminalSnapshot& snapshot ) { + waitForSnapshot( session, [secondCommand]( const TerminalSnapshot& snapshot ) { return snapshot.lastAppliedScrollCommand == secondCommand; } ); ASSERT_TRUE( acknowledged != nullptr ); EXPECT_EQ( 25, acknowledged->scrollPosition ); } -UTEST( eterm_controller, presentation_rate_is_applied_on_the_worker ) { +UTEST( eterm_session, presentation_rate_is_applied_on_the_worker ) { auto pty = std::make_unique(); auto process = std::make_unique(); - auto controller = TerminalController::create( std::move( pty ), std::move( process ), 100 ); - controller->setPresentationRate( 120 ); - ASSERT_TRUE( waitForSnapshot( controller, []( const TerminalSnapshot& snapshot ) { + auto session = TerminalSession::create( std::move( pty ), std::move( process ), 100 ); + session->setPresentationRate( 120 ); + ASSERT_TRUE( waitForSnapshot( session, []( const TerminalSnapshot& snapshot ) { return snapshot.presentationRate == 120; } ) != nullptr ); } -UTEST( eterm_controller, focus_reporting_is_ordered_on_worker ) { +UTEST( eterm_session, focus_reporting_is_ordered_on_worker ) { auto pty = std::make_unique(); pty->mBuffer = "\033[?1004h"; pty->mLoopWrites = false; MockPty* ptyPtr = pty.get(); auto process = std::make_unique(); - auto controller = TerminalController::create( std::move( pty ), std::move( process ), 100 ); - auto enabled = waitForSnapshot( controller, []( const TerminalSnapshot& snapshot ) { + auto session = TerminalSession::create( std::move( pty ), std::move( process ), 100 ); + auto enabled = waitForSnapshot( session, []( const TerminalSnapshot& snapshot ) { return snapshot.windowMode & MODE_FOCUS; } ); ASSERT_TRUE( enabled != nullptr ); - controller->setFocus( false ); - auto unfocused = waitForSnapshot( controller, [enabled]( const TerminalSnapshot& snapshot ) { + session->setFocus( false ); + auto unfocused = waitForSnapshot( session, [enabled]( const TerminalSnapshot& snapshot ) { return snapshot.generation > enabled->generation && !( snapshot.windowMode & MODE_FOCUSED ); } ); ASSERT_TRUE( unfocused != nullptr ); ASSERT_TRUE( ptyPtr->mWrites.size() >= 3 ); EXPECT_STDSTREQ( "\033[O", ptyPtr->mWrites.substr( ptyPtr->mWrites.size() - 3 ) ); - controller->setFocus( true ); - ASSERT_TRUE( waitForSnapshot( controller, [unfocused]( const TerminalSnapshot& snapshot ) { + session->setFocus( true ); + ASSERT_TRUE( waitForSnapshot( session, [unfocused]( const TerminalSnapshot& snapshot ) { return snapshot.generation > unfocused->generation && snapshot.windowMode & MODE_FOCUSED; } ) != nullptr ); @@ -213,20 +212,20 @@ UTEST( eterm_controller, focus_reporting_is_ordered_on_worker ) { EXPECT_STDSTREQ( "\033[I", ptyPtr->mWrites.substr( ptyPtr->mWrites.size() - 3 ) ); } -UTEST( eterm_controller, replaceable_events_coalesce_without_losing_ordered_events ) { +UTEST( eterm_session, replaceable_events_coalesce_without_losing_ordered_events ) { auto pty = std::make_unique(); auto process = std::make_unique(); - auto controller = TerminalController::create( std::move( pty ), std::move( process ), 100 ); - controller->drainEvents(); - controller->writeRaw( "\033]0;first\a\033]0;second\a" ); - ASSERT_TRUE( waitForSnapshot( controller, []( const TerminalSnapshot& snapshot ) { + auto session = TerminalSession::create( std::move( pty ), std::move( process ), 100 ); + session->drainEvents(); + session->writeRaw( "\033]0;first\a\033]0;second\a" ); + ASSERT_TRUE( waitForSnapshot( session, []( const TerminalSnapshot& snapshot ) { return snapshot.title == "second"; } ) != nullptr ); int titleEvents = 0; std::string title; - for ( auto& event : controller->drainEvents() ) { - if ( event.type == TerminalController::EventType::Title ) { + for ( auto& event : session->drainEvents() ) { + if ( event.type == TerminalSession::EventType::Title ) { ++titleEvents; title = std::move( event.data ); } @@ -235,54 +234,54 @@ UTEST( eterm_controller, replaceable_events_coalesce_without_losing_ordered_even EXPECT_STDSTREQ( "second", title ); } -UTEST( eterm_controller, ordered_events_are_coalescing_barriers ) { +UTEST( eterm_session, ordered_events_are_coalescing_barriers ) { auto pty = std::make_unique(); auto process = std::make_unique(); - auto controller = TerminalController::create( std::move( pty ), std::move( process ), 100 ); - controller->drainEvents(); - controller->writeRaw( "\033]0;before\a\a\033]0;after\a" ); - ASSERT_TRUE( waitForSnapshot( controller, []( const TerminalSnapshot& snapshot ) { + auto session = TerminalSession::create( std::move( pty ), std::move( process ), 100 ); + session->drainEvents(); + session->writeRaw( "\033]0;before\a\a\033]0;after\a" ); + ASSERT_TRUE( waitForSnapshot( session, []( const TerminalSnapshot& snapshot ) { return snapshot.title == "after"; } ) != nullptr ); - std::vector semanticEvents; - for ( const auto& event : controller->drainEvents() ) { - if ( event.type == TerminalController::EventType::Title || - event.type == TerminalController::EventType::Bell ) + std::vector semanticEvents; + for ( const auto& event : session->drainEvents() ) { + if ( event.type == TerminalSession::EventType::Title || + event.type == TerminalSession::EventType::Bell ) semanticEvents.emplace_back( event.type ); } ASSERT_EQ( static_cast( 3 ), semanticEvents.size() ); - EXPECT_EQ( TerminalController::EventType::Title, semanticEvents[0] ); - EXPECT_EQ( TerminalController::EventType::Bell, semanticEvents[1] ); - EXPECT_EQ( TerminalController::EventType::Title, semanticEvents[2] ); + EXPECT_EQ( TerminalSession::EventType::Title, semanticEvents[0] ); + EXPECT_EQ( TerminalSession::EventType::Bell, semanticEvents[1] ); + EXPECT_EQ( TerminalSession::EventType::Title, semanticEvents[2] ); } -UTEST( eterm_controller, reset_is_ordered_and_publishes_immediately ) { +UTEST( eterm_session, reset_is_ordered_and_publishes_immediately ) { auto pty = std::make_unique(); pty->mBuffer = "content"; auto process = std::make_unique(); - auto controller = TerminalController::create( std::move( pty ), std::move( process ), 100 ); - auto populated = waitForSnapshot( controller, []( const TerminalSnapshot& snapshot ) { + auto session = TerminalSession::create( std::move( pty ), std::move( process ), 100 ); + auto populated = waitForSnapshot( session, []( const TerminalSnapshot& snapshot ) { return !snapshot.cells.empty() && snapshot.cells[0].u == 'c'; } ); ASSERT_TRUE( populated != nullptr ); - controller->reset(); - auto reset = waitForSnapshot( controller, [populated]( const TerminalSnapshot& snapshot ) { + session->reset(); + auto reset = waitForSnapshot( session, [populated]( const TerminalSnapshot& snapshot ) { return snapshot.generation > populated->generation && !snapshot.cells.empty() && snapshot.cells[0].u == ' '; } ); ASSERT_TRUE( reset != nullptr ); } -UTEST( eterm_controller, process_exit_follows_buffered_output_and_final_snapshot ) { +UTEST( eterm_session, process_exit_follows_buffered_output_and_final_snapshot ) { auto pty = std::make_unique(); pty->mMaxRead = 1; MockPty* ptyPtr = pty.get(); auto process = std::make_unique(); MockProcess* processPtr = process.get(); - auto controller = TerminalController::create( std::move( pty ), std::move( process ), 100 ); - controller->setDataEventsEnabled( true ); - controller->writeRaw( std::string( 3 * 1024, 'Q' ) ); + auto session = TerminalSession::create( std::move( pty ), std::move( process ), 100 ); + session->setDataEventsEnabled( true ); + session->writeRaw( std::string( 3 * 1024, 'Q' ) ); const auto readDeadline = std::chrono::steady_clock::now() + std::chrono::milliseconds( 100 ); while ( ptyPtr->mBytesRead.load( std::memory_order_relaxed ) == 0 && std::chrono::steady_clock::now() < readDeadline ) @@ -291,51 +290,50 @@ UTEST( eterm_controller, process_exit_follows_buffered_output_and_final_snapshot processPtr->mExited.store( true ); auto finalSnapshot = waitForSnapshot( - controller, []( const TerminalSnapshot& snapshot ) { return snapshot.processExited; } ); + session, []( const TerminalSnapshot& snapshot ) { return snapshot.processExited; } ); ASSERT_TRUE( finalSnapshot != nullptr ); EXPECT_EQ( 0, finalSnapshot->exitCode ); size_t bytesRead = 0; bool sawExit = false; - for ( auto& event : controller->drainEvents() ) { - if ( event.type == TerminalController::EventType::Data ) + for ( auto& event : session->drainEvents() ) { + if ( event.type == TerminalSession::EventType::Data ) bytesRead += event.data.size(); - else if ( event.type == TerminalController::EventType::ProcessExit ) + else if ( event.type == TerminalSession::EventType::ProcessExit ) sawExit = true; } EXPECT_EQ( static_cast( 3 * 1024 ), bytesRead ); EXPECT_TRUE( sawExit ); } -UTEST( eterm_controller, repeated_create_destroy_and_concurrent_workers ) { +UTEST( eterm_session, repeated_create_destroy_and_concurrent_workers ) { for ( int iteration = 0; iteration < 16; ++iteration ) { - std::vector> controllers; + std::vector> sessions; for ( int terminal = 0; terminal < 4; ++terminal ) { auto pty = std::make_unique(); auto process = std::make_unique(); - auto controller = - TerminalController::create( std::move( pty ), std::move( process ), 100 ); - controller->writeRaw( "worker" + std::to_string( terminal ) ); - controllers.emplace_back( std::move( controller ) ); + auto session = TerminalSession::create( std::move( pty ), std::move( process ), 100 ); + session->writeRaw( "worker" + std::to_string( terminal ) ); + sessions.emplace_back( std::move( session ) ); } - for ( const auto& controller : controllers ) { - EXPECT_TRUE( waitForSnapshot( controller, []( const TerminalSnapshot& snapshot ) { + for ( const auto& session : sessions ) { + EXPECT_TRUE( waitForSnapshot( session, []( const TerminalSnapshot& snapshot ) { return !snapshot.cells.empty() && snapshot.cells[0].u == 'w'; } ) != nullptr ); } } } -UTEST( eterm_controller, concurrent_shutdown_is_idempotent ) { +UTEST( eterm_session, concurrent_shutdown_is_idempotent ) { auto pty = std::make_unique(); auto process = std::make_unique(); - auto controller = TerminalController::create( std::move( pty ), std::move( process ), 100 ); + auto session = TerminalSession::create( std::move( pty ), std::move( process ), 100 ); std::vector shutdownThreads; for ( int thread = 0; thread < 4; ++thread ) - shutdownThreads.emplace_back( [controller] { controller->shutdown(); } ); + shutdownThreads.emplace_back( [session] { session->shutdown(); } ); for ( auto& thread : shutdownThreads ) thread.join(); - controller->shutdown(); + session->shutdown(); } class MockDisplay : public ITerminalDisplay { diff --git a/src/tools/eterm_tabs/eterm_tabs.cpp b/src/tools/eterm_tabs/eterm_tabs.cpp index 78b264a41..a30aeb9fb 100644 --- a/src/tools/eterm_tabs/eterm_tabs.cpp +++ b/src/tools/eterm_tabs/eterm_tabs.cpp @@ -145,8 +145,8 @@ void queueExitedTabs() { auto* terminal = terminalFromTab( tab ); if ( !terminal || !terminal->getTerm() ) return; - const auto& controller = terminal->getTerm()->getController(); - auto snapshot = controller ? controller->snapshot() : nullptr; + const auto& session = terminal->getTerm()->getSession(); + auto snapshot = session ? session->snapshot() : nullptr; if ( snapshot && snapshot->processExited ) queueExitCloseTab( tab ); } );