refactor the data buffer functionality

This commit is contained in:
sawka 2023-02-06 12:08:07 -08:00
parent 62b9503387
commit 4429607eb5
3 changed files with 68 additions and 42 deletions

View File

@ -2,41 +2,28 @@ import * as mobx from "mobx";
import {WindowSize, RendererContext, TermOptsType} from "./types";
import {getPtyData, termWidthFromCols, termHeightFromRows} from "./model";
import {incObs} from "./util";
const InitialSize = 10*1024;
const IncreaseFactor = 1.5;
import {PtyDataBuffer} from "./ptydata";
class ImageRendererModel {
context : RendererContext;
dataSize : number;
imageData : Uint8Array;
brokenData : boolean;
isDone : mobx.IObservableValue<boolean>;
reloading : boolean = false;
dataVersion : mobx.IObservableValue<number>;
htmlImgDivElem : any;
htmlImg : any;
termOpts : TermOptsType;
dataBuf : PtyDataBuffer;
constructor(imgDivElem : any, context : RendererContext, termOpts : TermOptsType, isDone : boolean) {
this.dataBuf = new PtyDataBuffer();
this.htmlImgDivElem = imgDivElem;
this.termOpts = termOpts;
this.context = context;
this._resetData();
this.isDone = mobx.observable.box(isDone, {name: "isDone"});
this.dataVersion = mobx.observable.box(0, {name: "dataVersion"});
this.reload(0);
console.log("image", this.termOpts);
}
_resetData() {
this.dataSize = 0;
this.imageData = new Uint8Array(InitialSize);
this.brokenData = false;
}
dispose() : void {
this._resetData();
this.dataBuf.reset();
this.removeImage();
}
@ -49,7 +36,7 @@ class ImageRendererModel {
if (!this.isDone.get()) {
return;
}
let blob = new Blob([this.imageData.slice(0, this.dataSize)], {type: "image/jpeg"});
let blob = new Blob([this.dataBuf.getData()], {type: "image/jpeg"});
this.htmlImg = new Image();
this.htmlImg.src = URL.createObjectURL(blob);
this.htmlImg.style.maxHeight = termHeightFromRows(this.termOpts.rows) + "px";
@ -61,43 +48,24 @@ class ImageRendererModel {
if (this.reloading) {
return;
}
this._resetData();
this.dataBuf.reset();
this.reloading = true;
let rtnp = getPtyData(this.context.sessionId, this.context.cmdId);
rtnp.then((ptydata) => {
setTimeout(() => {
this.reloading = false;
this.receiveData(ptydata.pos, ptydata.data, "reload");
this.dataBuf.receiveData(ptydata.pos, ptydata.data, "reload");
this.renderImage();
}, delayMs);
}).catch((e) => {
this.brokenData = true;
this.dataBuf.brokenData = true;
this.reloading = false;
console.log("error reloading image data", e);
});
}
_growArray(minSize : number) : void {
let newSize = Math.round(this.imageData.length * IncreaseFactor);
if (newSize < minSize) {
newSize = minSize;
}
let newData = new Uint8Array(newSize);
newData.set(this.imageData);
this.imageData = newData;
}
receiveData(pos : number, data : Uint8Array, reason? : string) : void {
if (pos != this.dataSize) {
this.brokenData = true;
return;
}
if (this.dataSize + data.length > this.imageData.length) {
this._growArray(this.dataSize + data.length);
}
this.imageData.set(data, pos);
this.dataSize += data.length;
incObs(this.dataVersion);
this.dataBuf.receiveData(pos, data, reason);
}
cmdDone() : void {

View File

@ -314,7 +314,7 @@ class ImageRenderer extends React.Component<{sw : ScreenWindow, line : LineType,
let isLoaded = this.imageLoaded.get();
let isDone = (imageModel != null && imageModel.isDone.get());
if (imageModel != null) {
let dataVersion = imageModel.dataVersion.get();
let dataVersion = imageModel.dataBuf.dataVersion.get();
}
return (
<div ref={this.elemRef} className={"image-wrapper"}>

58
src/ptydata.ts Normal file
View File

@ -0,0 +1,58 @@
import * as mobx from "mobx";
import {incObs} from "./util";
const InitialSize = 10*1024;
const IncreaseFactor = 1.5;
class PtyDataBuffer {
ptyPos : number;
dataVersion : mobx.IObservableValue<number>;
brokenData : boolean;
rawData : Uint8Array;
dataSize : number;
constructor() {
this.ptyPos = 0;
this.dataVersion = mobx.observable.box(0, {name: "dataVersion"});
this._resetData();
}
_resetData() {
this.dataSize = 0;
this.rawData = new Uint8Array(InitialSize);
this.brokenData = false;
}
reset() : void {
this._resetData();
}
getData() : Uint8Array {
return this.rawData.slice(0, this.dataSize);
}
_growArray(minSize : number) : void {
let newSize = Math.round(this.rawData.length * IncreaseFactor);
if (newSize < minSize) {
newSize = minSize;
}
let newData = new Uint8Array(newSize);
newData.set(this.rawData);
this.rawData = newData;
}
receiveData(pos : number, data : Uint8Array, reason? : string) : void {
if (pos != this.dataSize) {
this.brokenData = true;
return;
}
if (this.dataSize + data.length > this.rawData.length) {
this._growArray(this.dataSize + data.length);
}
this.rawData.set(data, pos);
this.dataSize += data.length;
incObs(this.dataVersion);
}
}
export {PtyDataBuffer};