diff --git a/.agent/rules/project-introduction.md b/.agent/rules/project-introduction.md index 70a5681b9..d4a413ed5 100644 --- a/.agent/rules/project-introduction.md +++ b/.agent/rules/project-introduction.md @@ -1,6 +1,7 @@ # Project Architecture: eepp & ecode -This repository contains two primary components: a core framework (`eepp`) and an application built on top of it (`ecode`). +This repository contains the core framework (`eepp`) and several applications and tools built on +top of it, including `ecode`, `eterm`, and `eeiv`. ## 1. eepp (Core Framework) @@ -12,6 +13,16 @@ This repository contains two primary components: a core framework (`eepp`) and a * **Relationship:** `ecode` is built *using* the `eepp` GUI framework. It acts as the primary real-world consumer of `eepp`. * **Goal:** Development on `ecode` is often used to test, improve, and drive new features in the underlying `eepp` library. +## 3. eterm (Terminal Emulator) + +`eterm` is the repository's terminal emulator. Its name is always written in lowercase: `eterm`, +not `eTerm`. Its implementation lives under `src/modules/eterm/`. + +## 4. eeiv (Image Viewer) + +`eeiv` is the repository's image viewer. Its application entry point is +`src/tools/eeiv/eeiv.cpp`. + ## Documentation & Code References When working on this project, rely on the following resources to understand existing implementations: diff --git a/src/modules/eterm/src/eterm/terminal/kittygraphicsprotocol.cpp b/src/modules/eterm/src/eterm/terminal/kittygraphicsprotocol.cpp index 1d32fdc82..c3d5b8612 100644 --- a/src/modules/eterm/src/eterm/terminal/kittygraphicsprotocol.cpp +++ b/src/modules/eterm/src/eterm/terminal/kittygraphicsprotocol.cpp @@ -663,11 +663,11 @@ KittyGraphicsHandleResult KittyGraphicsProtocol::finishTransfer( PendingTransfer std::shared_ptr> pixelStorage; if ( existing != mImages.end() && existing->second.pixels.use_count() == 1 ) { pixelStorage = existing->second.pixels; - pixelStorage->assign( pixels.begin(), pixels.end() ); - if ( format == 24 ) - recycleBuffer( pixels, mDecodedScratch ); - else if ( format == 32 ) - recycleBuffer( pixels, mDecodedScratch ); + // The existing image is no longer referenced by a queued UI update. Exchange its backing + // allocation with the freshly decoded frame instead of copying the complete image. The old + // image allocation becomes the next transfer's decode buffer. + pixelStorage->swap( pixels ); + recycleBuffer( pixels, mDecodedScratch ); } else { pixelStorage = std::make_shared>( std::move( pixels ) ); } diff --git a/src/tests/unit_tests/eterm_tests.cpp b/src/tests/unit_tests/eterm_tests.cpp index d92f82456..f9924522b 100644 --- a/src/tests/unit_tests/eterm_tests.cpp +++ b/src/tests/unit_tests/eterm_tests.cpp @@ -1064,12 +1064,24 @@ UTEST( eterm, kitty_graphics_reuses_unreferenced_replacement_pixel_storage ) { updates.clear(); const auto* storage = protocol.imagePixels( 91 ); ASSERT_TRUE( storage != nullptr ); + const auto* firstAllocation = storage->data(); ASSERT_EQ( KittyGraphicsError::None, protocol.handle( "a=t,f=24,s=2,v=1,i=91,q=2;BwgJCgsM" ).error ); EXPECT_TRUE( storage == protocol.imagePixels( 91 ) ); const std::vector expected{ 7, 8, 9, 10, 11, 12 }; EXPECT_TRUE( expected == *protocol.imagePixels( 91 ) ); + ASSERT_TRUE( firstAllocation != protocol.imagePixels( 91 )->data() ); + updates = protocol.takeUpdates(); + ASSERT_EQ( static_cast( 1 ), updates.size() ); + updates.clear(); + + ASSERT_EQ( KittyGraphicsError::None, + protocol.handle( "a=t,f=24,s=2,v=1,i=91,q=2;DQ4PEBES" ).error ); + EXPECT_TRUE( storage == protocol.imagePixels( 91 ) ); + const std::vector recycledExpected{ 13, 14, 15, 16, 17, 18 }; + EXPECT_TRUE( recycledExpected == *protocol.imagePixels( 91 ) ); + EXPECT_TRUE( firstAllocation == protocol.imagePixels( 91 )->data() ); } UTEST( eterm, kitty_graphics_rejects_shared_memory_transmission ) {