This is an automated email from the ASF dual-hosted git repository.

rstrickland pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/daffodil-vscode.git


The following commit(s) were added to refs/heads/main by this push:
     new 25d9f1f  Fix File/Viewport Navigation Issue
25d9f1f is described below

commit 25d9f1f37531f5491e53ca7ea3c867851dee58ed
Author: Davin Shearer <[email protected]>
AuthorDate: Thu Aug 17 13:44:58 2023 -0400

    Fix File/Viewport Navigation Issue
    
    - Fixes issue where the UI would send viewport data requests w/ invalid
      offsets if the filesize was less than the viewport capacity.
    - Reworked `getLogger` functionality of data editor extension.
    
    Closes #819
---
 src/dataEditor/dataEditorClient.ts                 |  44 ++++++---
 .../DataDisplays/CustomByteDisplay/BinaryData.ts   |   2 -
 .../CustomByteDisplay/DataLineFeed.svelte          | 106 +++++++++++++--------
 .../components/DataDisplays/DataViewports.svelte   |   3 +-
 src/svelte/src/components/dataEditor.svelte        |  28 ++++--
 src/svelte/src/stores/configuration.ts             |   3 +
 6 files changed, 120 insertions(+), 66 deletions(-)

diff --git a/src/dataEditor/dataEditorClient.ts 
b/src/dataEditor/dataEditorClient.ts
index ae6bec1..467eeb6 100644
--- a/src/dataEditor/dataEditorClient.ts
+++ b/src/dataEditor/dataEditorClient.ts
@@ -245,9 +245,14 @@ export class DataEditorClient implements vscode.Disposable 
{
         ? (createSessionResponse.getFileSize() as number)
         : 0
     } catch {
-      vscode.window.showErrorMessage(
-        `Failed to create session for ${this.fileToEdit}`
-      )
+      const msg = `Failed to create session for ${this.fileToEdit}`
+      getLogger().error({
+        err: {
+          msg: msg,
+          stack: new Error().stack,
+        },
+      })
+      vscode.window.showErrorMessage(msg)
     }
 
     // create the viewport
@@ -264,9 +269,14 @@ export class DataEditorClient implements vscode.Disposable 
{
       await viewportSubscribe(this.panel, this.currentViewportId)
       await sendViewportRefresh(this.panel, viewportDataResponse)
     } catch {
-      vscode.window.showErrorMessage(
-        `Failed to create viewport for ${this.fileToEdit}`
-      )
+      const msg = `Failed to create viewport for ${this.fileToEdit}`
+      getLogger().error({
+        err: {
+          msg: msg,
+          stack: new Error().stack,
+        },
+      })
+      vscode.window.showErrorMessage(msg)
     }
 
     // send the initial file info to the webview
@@ -602,17 +612,22 @@ export class DataEditorClient implements 
vscode.Disposable {
     offset: number,
     bytesPerRow: number
   ) {
-    // start of the row containing the offset
-    const startOffset = offset - (offset % bytesPerRow)
+    // start of the row containing the offset, making sure the offset is never 
negative
+    const startOffset = Math.max(0, offset - (offset % bytesPerRow))
     try {
       await sendViewportRefresh(
         panel,
         await modifyViewport(viewportId, startOffset, VIEWPORT_CAPACITY_MAX)
       )
     } catch {
-      vscode.window.showErrorMessage(
-        `Failed to scroll viewport ${viewportId} to offset ${startOffset}`
-      )
+      const msg = `Failed to scroll viewport ${viewportId} to offset 
${startOffset}`
+      getLogger().error({
+        err: {
+          msg: msg,
+          stack: new Error().stack,
+        },
+      })
+      vscode.window.showErrorMessage(msg)
     }
   }
 }
@@ -816,9 +831,10 @@ async function viewportSubscribe(
         .setInterest(ALL_EVENTS & ~ViewportEventKind.VIEWPORT_EVT_MODIFY)
     )
     .on('data', async (event: ViewportEvent) => {
-      getLogger().debug(
-        `viewport '${event.getViewportId()}' received event: 
${event.getViewportEventKind()}`
-      )
+      getLogger().debug({
+        viewportId: event.getViewportId(),
+        event: event.getViewportEventKind(),
+      })
       await sendViewportRefresh(panel, await getViewportData(viewportId))
     })
     .on('error', (err) => {
diff --git 
a/src/svelte/src/components/DataDisplays/CustomByteDisplay/BinaryData.ts 
b/src/svelte/src/components/DataDisplays/CustomByteDisplay/BinaryData.ts
index e3f9e31..dec18d0 100644
--- a/src/svelte/src/components/DataDisplays/CustomByteDisplay/BinaryData.ts
+++ b/src/svelte/src/components/DataDisplays/CustomByteDisplay/BinaryData.ts
@@ -21,8 +21,6 @@ import { radixBytePad } from '../../../utilities/display'
 
 export const BYTE_ACTION_DIV_OFFSET: number = 24
 
-export const VIEWPORT_SCROLL_INCREMENT: number = 512
-
 export type EditAction =
   | 'insert-before'
   | 'insert-after'
diff --git 
a/src/svelte/src/components/DataDisplays/CustomByteDisplay/DataLineFeed.svelte 
b/src/svelte/src/components/DataDisplays/CustomByteDisplay/DataLineFeed.svelte
index f7d75cf..7051354 100644
--- 
a/src/svelte/src/components/DataDisplays/CustomByteDisplay/DataLineFeed.svelte
+++ 
b/src/svelte/src/components/DataDisplays/CustomByteDisplay/DataLineFeed.svelte
@@ -21,21 +21,21 @@ limitations under the License.
     editMode,
     editorEncoding,
     focusedViewportId,
-    seekOffsetInput,
     selectionDataStore,
     selectionSize,
     selectedByte,
     fileMetrics,
     searchQuery,
     editorActionsAllowed,
+    dataFeedLineTop,
   } from '../../../stores'
   import {
     EditByteModes,
     NUM_LINES_DISPLAYED,
-    VIEWPORT_CAPACITY_MAX,
     type BytesPerRow,
     type RadixValues,
     EditActionRestrictions,
+    VIEWPORT_SCROLL_INCREMENT,
   } from '../../../stores/configuration'
   import { MessageCommand } from '../../../utilities/message'
   import { vscode } from '../../../utilities/vscode'
@@ -65,8 +65,8 @@ limitations under the License.
     updateSearchResultsHighlights,
   } from '../../../utilities/highlights'
 
-  export let lineTop: number
-  export let awaitViewportScroll: boolean
+  // export let $dataFeedLineTop: number
+  export let awaitViewportSeek: boolean
   export let bytesPerRow: BytesPerRow = 16
   export let dataRadix: RadixValues = 16
   export let addressRadix: RadixValues = 16
@@ -76,43 +76,53 @@ limitations under the License.
   const CONTAINER_ID = 'viewportData-container'
   const eventDispatcher = createEventDispatcher()
 
-  function OFFSET_FETCH_ADJUSTMENT(direction: ViewportScrollDirection) {
+  function OFFSET_FETCH_ADJUSTMENT(
+    direction: ViewportScrollDirection,
+    numLinesToScroll: number
+  ) {
+    const newLineTopOffset =
+      numLinesToScroll * bytesPerRow + $dataFeedLineTop * bytesPerRow
+    let scroll_count = Math.floor(newLineTopOffset / VIEWPORT_SCROLL_INCREMENT)
+
     if (direction === ViewportScrollDirection.INCREMENT) {
-      const fetchBound = viewportData.fileOffset + VIEWPORT_CAPACITY_MAX / 2
+      const fetchBound =
+        viewportData.fileOffset + scroll_count * VIEWPORT_SCROLL_INCREMENT
       if (fetchBound > $fileMetrics.computedSize)
         return (
-          (fetchBound - $fileMetrics.computedSize / bytesPerRow) * bytesPerRow
+          ($fileMetrics.computedSize / bytesPerRow) * bytesPerRow -
+          NUM_LINES_DISPLAYED * bytesPerRow
         )
+
       return fetchBound
     } else {
       const validBytesRemaining =
-        viewportData.fileOffset - VIEWPORT_CAPACITY_MAX / 2 > 0
+        viewportData.fileOffset + scroll_count * VIEWPORT_SCROLL_INCREMENT > 0
       if (!validBytesRemaining) return 0
       else {
-        return viewportData.fileOffset - VIEWPORT_CAPACITY_MAX / 2
+        return (
+          viewportData.fileOffset + scroll_count * VIEWPORT_SCROLL_INCREMENT
+        )
       }
     }
   }
 
   const INCREMENT_LINE = () => {
-    handle_navigation(ViewportScrollDirection.INCREMENT)
+    handle_navigation(1)
   }
   const DECREMENT_LINE = () => {
-    handle_navigation(ViewportScrollDirection.DECREMENT)
+    handle_navigation(-1)
   }
   const INCREMENT_SEGMENT = () => {
-    handle_navigation(ViewportScrollDirection.INCREMENT, NUM_LINES_DISPLAYED)
+    handle_navigation(NUM_LINES_DISPLAYED)
   }
   const DECREMENT_SEGMENT = () => {
-    handle_navigation(ViewportScrollDirection.DECREMENT, -NUM_LINES_DISPLAYED)
+    handle_navigation(-NUM_LINES_DISPLAYED)
   }
   const SCROLL_TO_END = () => {
-    $seekOffsetInput = $fileMetrics.computedSize.toString(addressRadix)
-    eventDispatcher('seek')
+    handle_navigation(lineTopMaxFile)
   }
   const SCROLL_TO_TOP = () => {
-    $seekOffsetInput = '0'
-    eventDispatcher('seek')
+    handle_navigation(-lineTopMaxFile)
   }
 
   let totalLinesPerFilesize = 0
@@ -139,6 +149,7 @@ limitations under the License.
 
   enum ViewportScrollDirection {
     DECREMENT = -1,
+    NONE = 0,
     INCREMENT = 1,
   }
 
@@ -168,8 +179,8 @@ limitations under the License.
       0
     )
 
-    atViewportHead = lineTop === 0
-    atViewportTail = lineTop === lineTopMaxViewport
+    atViewportHead = $dataFeedLineTop === 0
+    atViewportTail = $dataFeedLineTop === lineTopMaxViewport
     atFileHead = viewportData.fileOffset === 0
     atFileTail = viewportData.bytesLeft === 0
 
@@ -177,16 +188,20 @@ limitations under the License.
       $selectionDataStore.active || (atViewportHead && atFileHead)
     disableIncrement =
       $selectionDataStore.active || (atViewportTail && atFileTail)
-    lineTopFileOffset = lineTop * bytesPerRow
+    lineTopFileOffset = $dataFeedLineTop * bytesPerRow
   }
 
   $: {
-    if (viewportData.fileOffset >= 0 && !awaitViewportScroll && lineTop >= 0) {
+    if (
+      viewportData.fileOffset >= 0 &&
+      !awaitViewportSeek &&
+      $dataFeedLineTop >= 0
+    ) {
       if (
         viewportLines.length !== 0 &&
         bytesPerRow !== viewportLines[0].bytes.length
       ) {
-        lineTop = viewport_offset_to_line_num(
+        $dataFeedLineTop = viewport_offset_to_line_num(
           parseInt(viewportLines[0].offset, addressRadix),
           viewportData.fileOffset,
           bytesPerRow
@@ -194,7 +209,7 @@ limitations under the License.
       }
 
       viewportLines = generate_line_data(
-        lineTop,
+        $dataFeedLineTop,
         dataRadix,
         addressRadix,
         bytesPerRow
@@ -273,29 +288,37 @@ limitations under the License.
       : atViewportTail && atFileTail
   }
 
-  function handle_navigation(
-    direction: ViewportScrollDirection,
-    linesToMove: number = direction
-  ) {
-    if (at_scroll_boundary(direction)) return
+  function direction_of_scroll(
+    numLinesToScroll: number
+  ): ViewportScrollDirection {
+    return Math.sign(numLinesToScroll) as ViewportScrollDirection
+  }
+
+  function handle_navigation(numLinesToScroll: number) {
+    const navDirection = direction_of_scroll(numLinesToScroll)
 
-    if (at_fetch_boundary(direction, linesToMove)) {
+    if (at_scroll_boundary(navDirection)) return
+
+    if (at_fetch_boundary(navDirection, numLinesToScroll)) {
       const viewportOffset = viewportData.fileOffset
       const lineTopOffset = viewportLines[0].bytes[0].offset
-      const nextViewportOffset = OFFSET_FETCH_ADJUSTMENT(direction)
+      const nextViewportOffset = OFFSET_FETCH_ADJUSTMENT(
+        navDirection,
+        numLinesToScroll
+      )
 
       eventDispatcher('traverse-file', {
         nextViewportOffset: nextViewportOffset,
         lineTopOnRefresh:
           Math.floor(
             (viewportOffset + lineTopOffset - nextViewportOffset) / bytesPerRow
-          ) + linesToMove,
+          ) + numLinesToScroll,
       })
       return
     }
 
-    const newLine = lineTop + linesToMove
-    lineTop = Math.max(0, Math.min(newLine, lineTopMaxViewport))
+    const newLine = $dataFeedLineTop + numLinesToScroll
+    $dataFeedLineTop = Math.max(0, Math.min(newLine, lineTopMaxViewport))
   }
 
   function at_fetch_boundary(
@@ -304,8 +327,8 @@ limitations under the License.
   ): boolean {
     if (linesToMove != direction)
       return direction === ViewportScrollDirection.INCREMENT
-        ? lineTop + linesToMove >= lineTopMaxViewport && !atFileTail
-        : lineTop + linesToMove <= 0 && !atFileHead
+        ? $dataFeedLineTop + linesToMove >= lineTopMaxViewport && !atFileTail
+        : $dataFeedLineTop + linesToMove <= 0 && !atFileHead
 
     return direction === ViewportScrollDirection.INCREMENT
       ? atViewportTail && !atFileTail
@@ -410,7 +433,7 @@ limitations under the License.
         },
       })
       lineTopOnRefresh = lineTopMaxViewport
-      awaitViewportScroll = true
+      awaitViewportSeek = true
     }
   }
 
@@ -433,9 +456,12 @@ limitations under the License.
   window.addEventListener('message', (msg) => {
     switch (msg.data.command) {
       case MessageCommand.viewportRefresh:
-        if (awaitViewportScroll) {
-          awaitViewportScroll = false
-          lineTop = Math.max(0, Math.min(lineTopMaxViewport, lineTop))
+        if (awaitViewportSeek) {
+          awaitViewportSeek = false
+          $dataFeedLineTop = Math.max(
+            0,
+            Math.min(lineTopMaxViewport, $dataFeedLineTop)
+          )
           if ($selectionDataStore.active)
             selectedByteElement = document.getElementById(
               $selectedByte.offset.toString()
@@ -520,7 +546,7 @@ limitations under the License.
     <FileTraversalIndicator
       totalLines={totalLinesPerFilesize}
       selectionActive={$selectionDataStore.active}
-      currentLine={lineTop}
+      currentLine={$dataFeedLineTop}
       fileOffset={viewportData.fileOffset}
       maxDisplayLines={NUM_LINES_DISPLAYED}
       bind:percentageTraversed
diff --git a/src/svelte/src/components/DataDisplays/DataViewports.svelte 
b/src/svelte/src/components/DataDisplays/DataViewports.svelte
index b031f25..2c0cafe 100644
--- a/src/svelte/src/components/DataDisplays/DataViewports.svelte
+++ b/src/svelte/src/components/DataDisplays/DataViewports.svelte
@@ -32,11 +32,10 @@ limitations under the License.
   on:applyChanges
   on:handleEditorEvent
   viewportData={$viewport}
-  lineTop={$dataFeedLineTop}
   bytesPerRow={$bytesPerRow}
   dataRadix={$displayRadix}
   addressRadix={$addressRadix}
-  bind:awaitViewportScroll={$dataFeedAwaitRefresh}
+  bind:awaitViewportSeek={$dataFeedAwaitRefresh}
 />
 
 <style lang="scss">
diff --git a/src/svelte/src/components/dataEditor.svelte 
b/src/svelte/src/components/dataEditor.svelte
index 8af8309..a64acfe 100644
--- a/src/svelte/src/components/dataEditor.svelte
+++ b/src/svelte/src/components/dataEditor.svelte
@@ -46,7 +46,12 @@ limitations under the License.
   import { vscode } from '../utilities/vscode'
   import Header from './Header/Header.svelte'
   import Main from './Main.svelte'
-  import { EditByteModes, NUM_LINES_DISPLAYED } from '../stores/configuration'
+  import {
+    EditByteModes,
+    NUM_LINES_DISPLAYED,
+    VIEWPORT_CAPACITY_MAX,
+    VIEWPORT_SCROLL_INCREMENT,
+  } from '../stores/configuration'
   import ServerMetrics from './ServerMetrics/ServerMetrics.svelte'
   import {
     elementKeypressEventMap,
@@ -86,7 +91,9 @@ limitations under the License.
 
     const fileSize = $fileMetrics.computedSize
     const viewportBoundary =
-      $viewport.length + $viewport.fileOffset - 20 * $bytesPerRow
+      $viewport.length +
+      $viewport.fileOffset -
+      NUM_LINES_DISPLAYED * $bytesPerRow
     const offset =
       offsetArg > 0 &&
       offsetArg < viewport.offsetMax &&
@@ -96,21 +103,26 @@ limitations under the License.
 
     const relativeFileLine = Math.floor(offset / $bytesPerRow)
     const relativeFileOffset = relativeFileLine * $bytesPerRow
-    const lineTopBoundary = Math.floor($viewport.length / $bytesPerRow) - 20
+    const lineTopBoundary =
+      Math.floor($viewport.length / $bytesPerRow) - NUM_LINES_DISPLAYED
     let relativeTargetLine = relativeFileLine
     let viewportStartOffset = $viewport.fileOffset
-
+    $dataFeedAwaitRefresh = true
     // make sure that the offset is within the loaded viewport
     if (
       offset < $viewport.fileOffset ||
       offset > viewportBoundary ||
       relativeTargetLine > lineTopBoundary
     ) {
-      let adjustedFileOffset = Math.max(0, relativeFileOffset - 512)
-      const fetchPastFileBoundary = fileSize - adjustedFileOffset < 1024
+      let adjustedFileOffset = Math.max(
+        0,
+        relativeFileOffset - VIEWPORT_SCROLL_INCREMENT
+      )
+      const fetchPastFileBoundary =
+        fileSize - adjustedFileOffset < VIEWPORT_CAPACITY_MAX
       if (fetchPastFileBoundary)
         adjustedFileOffset = byte_count_divisible_offset(
-          fileSize - 1024,
+          fileSize - VIEWPORT_CAPACITY_MAX,
           $bytesPerRow,
           1
         )
@@ -124,7 +136,6 @@ limitations under the License.
           ) -
           (NUM_LINES_DISPLAYED - 1)
         : viewport_offset_to_line_num(offset, viewportStartOffset, 
$bytesPerRow)
-      $dataFeedAwaitRefresh = true
 
       // NOTE: Scrolling the viewport will make the display bounce until it 
goes to the correct offset
       vscode.postMessage({
@@ -139,6 +150,7 @@ limitations under the License.
     }
 
     $dataFeedLineTop = relativeTargetLine
+    $dataFeedAwaitRefresh = false
     clearDataDisplays()
   }
 
diff --git a/src/svelte/src/stores/configuration.ts 
b/src/svelte/src/stores/configuration.ts
index 8b681a1..37e3595 100644
--- a/src/svelte/src/stores/configuration.ts
+++ b/src/svelte/src/stores/configuration.ts
@@ -109,6 +109,9 @@ export const UNPRINTABLE_CHAR_STAND_IN = 
String.fromCharCode(9617)
 // Number of bytes to for the viewport to populate
 export const VIEWPORT_CAPACITY_MAX = 16 * 64 // 1024, Ωedit maximum viewport 
size is 1048576 (1024 * 1024)
 
+// Offset shift amount on viewport data fetch
+export const VIEWPORT_SCROLL_INCREMENT = VIEWPORT_CAPACITY_MAX / 2
+
 // Number of bytes to display in the viewport
 export const NUM_LINES_DISPLAYED = 20
 

Reply via email to