module TextViewport.Render.RenderBuffer where import Data.Hashable (Hashable) import Data.Sequence qualified as Seq import Data.Sequences (Index, Textual) import TextViewport.Buffer.Buffer (Buffer(..)) import TextViewport.Render.CachedRender import TextViewport.Render.RenderCache import TextViewport.Render.RenderItem (renderItem) import TextViewport.Render.RenderedBuffer import TextViewport.Render.Segmentation (Segmenter) renderBuffer :: (Segmenter seg a, Hashable a, Textual a, Index a ~ Int) => Int -> Buffer a seg -> RenderCache a seg -> (RenderCache a seg, RenderedBuffer a) renderBuffer width (Buffer items) (RenderCache cache) = let n = Seq.length items go i (cAcc, rAcc) | i >= n = (RenderCache cAcc, RenderedBuffer rAcc) | otherwise = let item = Seq.index items i mOld = Seq.index cache i newEntry = renderItem width i item mOld cAcc' = Seq.update i (Just newEntry) cAcc rAcc' = rAcc Seq.|> crRendered newEntry in go (i + 1) (cAcc', rAcc') in go 0 (cache, Seq.empty) updateRenderedItem :: (Segmenter seg a, Hashable a, Textual a, Index a ~ Int) => Int -> Int -> Buffer a seg -> RenderCache a seg -> RenderedBuffer a -> (RenderCache a seg, RenderedBuffer a) updateRenderedItem width itemIx (Buffer items) (RenderCache cache) (RenderedBuffer rb) = let item = Seq.index items itemIx mOld = Seq.index cache itemIx newEntry = renderItem width itemIx item mOld newCache = Seq.update itemIx (Just newEntry) cache newRB = Seq.update itemIx (crRendered newEntry) rb in (RenderCache newCache, RenderedBuffer newRB)