From e0b046d1b7b8916ad02e3f9c74c25be0d7ef7658 Mon Sep 17 00:00:00 2001 From: kovacsv Date: Sat, 2 Jul 2022 09:16:45 +0200 Subject: [PATCH] Add callbacks for file loading progress. --- source/engine/import/importer.js | 29 ++++++++++++------ source/engine/import/importerfiles.js | 26 +++++++++------- source/engine/io/fileutils.js | 37 ++++++++++------------- source/engine/threejs/threemodelloader.js | 12 ++++++-- source/engine/viewer/embeddedviewer.js | 4 +++ source/website/threemodelloaderui.js | 5 +++ test/tests/exportimport_test.js | 9 +++++- test/tests/importer_test.js | 18 +++++++++-- 8 files changed, 93 insertions(+), 47 deletions(-) diff --git a/source/engine/import/importer.js b/source/engine/import/importer.js index 37abeaf..65da4fa 100644 --- a/source/engine/import/importer.js +++ b/source/engine/import/importer.js @@ -109,15 +109,20 @@ export class Importer ImportFiles (inputFiles, settings, callbacks) { - this.LoadFiles (inputFiles, () => { - callbacks.onFilesLoaded (); - RunTaskAsync (() => { - this.ImportLoadedFiles (settings, callbacks); - }); + callbacks.onLoadStart (); + this.LoadFiles (inputFiles, { + onReady : () => { + callbacks.onImportStart (); + RunTaskAsync (() => { + this.ImportLoadedFiles (settings, callbacks); + }); + }, + onFileProgress : callbacks.onFileProgress, + onFileLoadProgress : callbacks.onFileLoadProgress }); } - LoadFiles (inputFiles, onReady) + LoadFiles (inputFiles, callbacks) { let newFileList = new ImporterFileList (); newFileList.FillFromInputFiles (inputFiles); @@ -143,10 +148,14 @@ export class Importer if (reset) { this.fileList = newFileList; } - this.fileList.GetContent (() => { - this.DecompressArchives (this.fileList, () => { - onReady (); - }); + this.fileList.GetContent ({ + onReady : () => { + this.DecompressArchives (this.fileList, () => { + callbacks.onReady (); + }); + }, + onFileProgress : callbacks.onFileProgress, + onFileLoadProgress : callbacks.onFileLoadProgress }); } diff --git a/source/engine/import/importerfiles.js b/source/engine/import/importerfiles.js index 1c4525a..e507db1 100644 --- a/source/engine/import/importerfiles.js +++ b/source/engine/import/importerfiles.js @@ -1,5 +1,5 @@ import { RunTasks } from '../core/taskrunner.js'; -import { FileFormat, FileSource, GetFileExtension, GetFileName, ReadFile, RequestUrl } from '../io/fileutils.js'; +import { FileSource, GetFileExtension, GetFileName, ReadFile, RequestUrl } from '../io/fileutils.js'; export class InputFile { @@ -80,13 +80,17 @@ export class ImporterFileList return this.files; } - GetContent (onReady) + GetContent (callbacks) { RunTasks (this.files.length, { - runTask : (index, complete) => { - this.GetFileContent (this.files[index], complete); + runTask : (index, onTaskComplete) => { + callbacks.onFileProgress (index, this.files.length); + this.GetFileContent (this.files[index], { + onReady : onTaskComplete, + onProgress : callbacks.onFileLoadProgress + }); }, - onReady : onReady + onReady : callbacks.onReady }); } @@ -126,26 +130,26 @@ export class ImporterFileList this.files.push (file); } - GetFileContent (file, complete) + GetFileContent (file, callbacks) { if (file.content !== null) { - complete (); + callbacks.onReady (); return; } let loaderPromise = null; if (file.source === FileSource.Url) { - loaderPromise = RequestUrl (file.data, FileFormat.Binary); + loaderPromise = RequestUrl (file.data, callbacks.onProgress); } else if (file.source === FileSource.File) { - loaderPromise = ReadFile (file.data, FileFormat.Binary); + loaderPromise = ReadFile (file.data, callbacks.onProgress); } else { - complete (); + callbacks.onReady (); return; } loaderPromise.then ((content) => { file.SetContent (content); }).catch (() => { }).finally (() => { - complete (); + callbacks.onReady (); }); } } diff --git a/source/engine/io/fileutils.js b/source/engine/io/fileutils.js index 5391a0d..076609a 100644 --- a/source/engine/io/fileutils.js +++ b/source/engine/io/fileutils.js @@ -39,21 +39,17 @@ export function GetFileExtension (filePath) return extension.toLowerCase (); } -export function RequestUrl (url, format) +export function RequestUrl (url, onProgress) { return new Promise ((resolve, reject) => { let request = new XMLHttpRequest (); request.open ('GET', url, true); - if (format === FileFormat.Text) { - request.responseType = 'text'; - } else if (format === FileFormat.Binary) { - request.responseType = 'arraybuffer'; - } else { - reject (); - return; - } - request.onload = function () { + request.onprogress = (event) => { + onProgress (event.loaded, event.total); + }; + + request.onload = () => { if (request.status === 200) { resolve (request.response); } else { @@ -61,36 +57,35 @@ export function RequestUrl (url, format) } }; - request.onerror = function () { + request.onerror = () => { reject (); }; + request.responseType = 'arraybuffer'; request.send (null); }); } -export function ReadFile (file, format) +export function ReadFile (file, onProgress) { return new Promise ((resolve, reject) => { let reader = new FileReader (); - reader.onloadend = function (event) { + reader.onprogress = (event) => { + onProgress (event.loaded, event.total); + }; + + reader.onloadend = (event) => { if (event.target.readyState === FileReader.DONE) { resolve (event.target.result); } }; - reader.onerror = function () { + reader.onerror = () => { reject (); }; - if (format === FileFormat.Text) { - reader.readAsText (file); - } else if (format === FileFormat.Binary) { - reader.readAsArrayBuffer (file); - } else { - reject (); - } + reader.readAsArrayBuffer (file); }); } diff --git a/source/engine/threejs/threemodelloader.js b/source/engine/threejs/threemodelloader.js index 75a7d0a..02dd1a3 100644 --- a/source/engine/threejs/threemodelloader.js +++ b/source/engine/threejs/threemodelloader.js @@ -29,10 +29,18 @@ export class ThreeModelLoader } this.inProgress = true; - callbacks.onLoadStart (); this.RevokeObjectUrls (); this.importer.ImportFiles (inputFiles, settings, { - onFilesLoaded : () => { + onLoadStart : () => { + callbacks.onLoadStart (); + }, + onFileProgress : (current, total) => { + callbacks.onFileProgress (current, total); + }, + onFileLoadProgress : (current, total) => { + callbacks.onFileLoadProgress (current, total); + }, + onImportStart : () => { callbacks.onImportStart (); }, onSelectMainFile : (fileNames, selectFile) => { diff --git a/source/engine/viewer/embeddedviewer.js b/source/engine/viewer/embeddedviewer.js index f0de5cb..892b31a 100644 --- a/source/engine/viewer/embeddedviewer.js +++ b/source/engine/viewer/embeddedviewer.js @@ -87,6 +87,10 @@ export class EmbeddedViewer progressDiv.innerHTML = 'Loading model...'; this.parentElement.appendChild (progressDiv); }, + onFileProgress : (current, total) => { + }, + onFileLoadProgress : (current, total) => { + }, onImportStart : () => { progressDiv.innerHTML = 'Importing model...'; }, diff --git a/source/website/threemodelloaderui.js b/source/website/threemodelloaderui.js index b960e61..42fb46f 100644 --- a/source/website/threemodelloaderui.js +++ b/source/website/threemodelloaderui.js @@ -28,6 +28,11 @@ export class ThreeModelLoaderUI progressDialog.Init ('Loading Model'); progressDialog.Open (); }, + onFileProgress : (current, total) => { + progressDialog.SetText ('Loading File ' + (current + 1).toString () + '/' + total.toString ()); + }, + onFileLoadProgress : (current, total) => { + }, onSelectMainFile : (fileNames, selectFile) => { progressDialog.Close (); this.modalDialog = this.ShowFileSelectorDialog (fileNames, (index) => { diff --git a/test/tests/exportimport_test.js b/test/tests/exportimport_test.js index 486cd1e..90a2872 100644 --- a/test/tests/exportimport_test.js +++ b/test/tests/exportimport_test.js @@ -118,7 +118,14 @@ function ExportImport (model, format, extension, onReady) let settings = new OV.ImportSettings (); let fileObjects = exportedFiles.map (file => new OV.InputFile (file.name, OV.FileSource.File, new FileObject ('', file.name, file.content))); importer.ImportFiles (fileObjects, settings, { - onFilesLoaded : function () { + onLoadStart : function () { + + }, + onFileProgress : (current, total) => { + }, + onFileLoadProgress : (current, total) => { + }, + onImportStart : function () { }, onImportSuccess : function (importResult) { diff --git a/test/tests/importer_test.js b/test/tests/importer_test.js index 4a611fc..a2176b3 100644 --- a/test/tests/importer_test.js +++ b/test/tests/importer_test.js @@ -9,7 +9,14 @@ function ImportFilesWithImporter (importer, files, callbacks) let settings = new OV.ImportSettings (); let inputFiles = OV.InputFilesFromFileObjects (files); importer.ImportFiles (inputFiles, settings, { - onFilesLoaded : function () { + onLoadStart : function () { + + }, + onFileProgress : (current, total) => { + }, + onFileLoadProgress : (current, total) => { + }, + onImportStart : function () { }, onImportSuccess : function (importResult) { @@ -262,7 +269,14 @@ describe ('Importer Test', function () { settings.defaultColor = new OV.RGBColor (200, 0, 0); let inputFiles = OV.InputFilesFromFileObjects (files); theImporter.ImportFiles (inputFiles, settings, { - onFilesLoaded : function () { + onLoadStart : function () { + + }, + onFileProgress : (current, total) => { + }, + onFileLoadProgress : (current, total) => { + }, + onImportStart : function () { }, onImportSuccess : function (importResult) {