Merge branch 'main' into new-logging
This commit is contained in:
		
						commit
						1c74b23700
					
				@ -71,7 +71,7 @@ export default class PIXIApp extends PIXI.Application {
 | 
				
			|||||||
     * @param {HTMLElement} [opts.view] - The canvas HTML element. If not set, a render-element is added inside the body.
 | 
					     * @param {HTMLElement} [opts.view] - The canvas HTML element. If not set, a render-element is added inside the body.
 | 
				
			||||||
     * @param {boolean} [opts.transparent=true] - Should the render view be transparent?
 | 
					     * @param {boolean} [opts.transparent=true] - Should the render view be transparent?
 | 
				
			||||||
     * @param {boolean} [opts.antialias=true] - Sets antialias (only applicable in chrome at the moment).
 | 
					     * @param {boolean} [opts.antialias=true] - Sets antialias (only applicable in chrome at the moment).
 | 
				
			||||||
     * @param {number} [opts.resolution=window.devicePixelRatio | 1] - The resolution / device pixel ratio of the renderer, retina would be 2.
 | 
					     * @param {number} [opts.resolution=window.devicePixelRatio || 1] - The resolution / device pixel ratio of the renderer, retina would be 2.
 | 
				
			||||||
     * @param {boolean} [opts.autoResize=true] - Should the canvas-element be resized automatically if the resolution was set?
 | 
					     * @param {boolean} [opts.autoResize=true] - Should the canvas-element be resized automatically if the resolution was set?
 | 
				
			||||||
     * @param {number} [opts.backgroundColor=0x282828] - The color of the background.
 | 
					     * @param {number} [opts.backgroundColor=0x282828] - The color of the background.
 | 
				
			||||||
     * @param {string|Theme} [opts.theme=dark] - The name of the theme (dark, light, red) or a Theme object to use for styling.
 | 
					     * @param {string|Theme} [opts.theme=dark] - The name of the theme (dark, light, red) or a Theme object to use for styling.
 | 
				
			||||||
@ -81,6 +81,7 @@ export default class PIXIApp extends PIXI.Application {
 | 
				
			|||||||
     * @param {boolean} [opts.roundPixels=true] - Align PIXI.DisplayObject coordinates to screen resolution.
 | 
					     * @param {boolean} [opts.roundPixels=true] - Align PIXI.DisplayObject coordinates to screen resolution.
 | 
				
			||||||
     * @param {boolean} [opts.monkeyPatchMapping=true] - Monkey patch for canvas fullscreen support on large displays.
 | 
					     * @param {boolean} [opts.monkeyPatchMapping=true] - Monkey patch for canvas fullscreen support on large displays.
 | 
				
			||||||
     * @param {boolean} [opts.adaptive=true] - Adds Graphics adaptive calculation of quadratic curve and arc subdivision.
 | 
					     * @param {boolean} [opts.adaptive=true] - Adds Graphics adaptive calculation of quadratic curve and arc subdivision.
 | 
				
			||||||
 | 
					     * @param {boolean} [opts.autoDensity=true] - Automatically adapts width to devicePixelRation
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    constructor({
 | 
					    constructor({
 | 
				
			||||||
        width = null,
 | 
					        width = null,
 | 
				
			||||||
@ -90,7 +91,7 @@ export default class PIXIApp extends PIXI.Application {
 | 
				
			|||||||
        backgroundColor = 0x282828,
 | 
					        backgroundColor = 0x282828,
 | 
				
			||||||
        theme = 'dark',
 | 
					        theme = 'dark',
 | 
				
			||||||
        antialias = true,
 | 
					        antialias = true,
 | 
				
			||||||
        resolution = 1,
 | 
					        resolution = window.devicePixelRatio || 1, //  Needed for text resolution https://www.html5gamedevs.com/topic/46418-text-and-resolution/
 | 
				
			||||||
        autoResize = true,
 | 
					        autoResize = true,
 | 
				
			||||||
        fpsLogging = false,
 | 
					        fpsLogging = false,
 | 
				
			||||||
        progress = {},
 | 
					        progress = {},
 | 
				
			||||||
@ -99,6 +100,7 @@ export default class PIXIApp extends PIXI.Application {
 | 
				
			|||||||
        monkeyPatchMapping = true,
 | 
					        monkeyPatchMapping = true,
 | 
				
			||||||
        adaptive = true,
 | 
					        adaptive = true,
 | 
				
			||||||
        graphql = false,
 | 
					        graphql = false,
 | 
				
			||||||
 | 
					        autoDensity = true // Needed for text resolution https://www.html5gamedevs.com/topic/46418-text-and-resolution/
 | 
				
			||||||
    }) {
 | 
					    }) {
 | 
				
			||||||
        const fullScreen = !width || !height
 | 
					        const fullScreen = !width || !height
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -117,6 +119,7 @@ export default class PIXIApp extends PIXI.Application {
 | 
				
			|||||||
            autoResize,
 | 
					            autoResize,
 | 
				
			||||||
            backgroundColor,
 | 
					            backgroundColor,
 | 
				
			||||||
            forceCanvas,
 | 
					            forceCanvas,
 | 
				
			||||||
 | 
					            autoDensity
 | 
				
			||||||
        })
 | 
					        })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        this.width = width
 | 
					        this.width = width
 | 
				
			||||||
@ -137,7 +140,7 @@ export default class PIXIApp extends PIXI.Application {
 | 
				
			|||||||
        this.graphql = graphql
 | 
					        this.graphql = graphql
 | 
				
			||||||
        if (fullScreen || autoResize) {
 | 
					        if (fullScreen || autoResize) {
 | 
				
			||||||
            console.log('App is in fullScreen mode or autoResize mode')
 | 
					            console.log('App is in fullScreen mode or autoResize mode')
 | 
				
			||||||
            const resizeDebounced = debounce((event) => this.resizeApp(event), 50)
 | 
					            const resizeDebounced = debounce(event => this.resizeApp(event), 50)
 | 
				
			||||||
            window.addEventListener('resize', resizeDebounced)
 | 
					            window.addEventListener('resize', resizeDebounced)
 | 
				
			||||||
            document.body.addEventListener('orientationchange', this.checkOrientation.bind(this))
 | 
					            document.body.addEventListener('orientationchange', this.checkOrientation.bind(this))
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@ -167,25 +170,25 @@ export default class PIXIApp extends PIXI.Application {
 | 
				
			|||||||
        // GraphQL
 | 
					        // GraphQL
 | 
				
			||||||
        if (this.graphql && typeof apollo !== 'undefined') {
 | 
					        if (this.graphql && typeof apollo !== 'undefined') {
 | 
				
			||||||
            const networkInterface = apollo.createNetworkInterface({
 | 
					            const networkInterface = apollo.createNetworkInterface({
 | 
				
			||||||
                uri: '/graphql',
 | 
					                uri: '/graphql'
 | 
				
			||||||
            })
 | 
					            })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            const wsClient = new subscriptions.SubscriptionClient(`wss://${location.hostname}/subscriptions`, {
 | 
					            const wsClient = new subscriptions.SubscriptionClient(`wss://${location.hostname}/subscriptions`, {
 | 
				
			||||||
                reconnect: true,
 | 
					                reconnect: true,
 | 
				
			||||||
                connectionParams: {},
 | 
					                connectionParams: {}
 | 
				
			||||||
            })
 | 
					            })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            const networkInterfaceWithSubscriptions = subscriptions.addGraphQLSubscriptions(networkInterface, wsClient)
 | 
					            const networkInterfaceWithSubscriptions = subscriptions.addGraphQLSubscriptions(networkInterface, wsClient)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            this.apolloClient = new apollo.ApolloClient({
 | 
					            this.apolloClient = new apollo.ApolloClient({
 | 
				
			||||||
                networkInterface: networkInterfaceWithSubscriptions,
 | 
					                networkInterface: networkInterfaceWithSubscriptions
 | 
				
			||||||
            })
 | 
					            })
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // progress
 | 
					        // progress
 | 
				
			||||||
        this._progress = new Progress(
 | 
					        this._progress = new Progress(
 | 
				
			||||||
            Object.assign({ theme: this.theme }, this.progressOpts, {
 | 
					            Object.assign({ theme: this.theme }, this.progressOpts, {
 | 
				
			||||||
                app: this,
 | 
					                app: this
 | 
				
			||||||
            })
 | 
					            })
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
        this._progress.visible = false
 | 
					        this._progress.visible = false
 | 
				
			||||||
@ -214,7 +217,7 @@ export default class PIXIApp extends PIXI.Application {
 | 
				
			|||||||
        if (value != this.orient) {
 | 
					        if (value != this.orient) {
 | 
				
			||||||
            setTimeout(
 | 
					            setTimeout(
 | 
				
			||||||
                100,
 | 
					                100,
 | 
				
			||||||
                function () {
 | 
					                function() {
 | 
				
			||||||
                    this.orientationChanged(true)
 | 
					                    this.orientationChanged(true)
 | 
				
			||||||
                }.bind(this)
 | 
					                }.bind(this)
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
@ -469,7 +472,7 @@ export default class PIXIApp extends PIXI.Application {
 | 
				
			|||||||
    loadSprites(resources, loaded = null, { resolutionDependent = true, progress = false } = {}) {
 | 
					    loadSprites(resources, loaded = null, { resolutionDependent = true, progress = false } = {}) {
 | 
				
			||||||
        this.loadTextures(
 | 
					        this.loadTextures(
 | 
				
			||||||
            resources,
 | 
					            resources,
 | 
				
			||||||
            (textures) => {
 | 
					            textures => {
 | 
				
			||||||
                let sprites = new Map()
 | 
					                let sprites = new Map()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                for (let [key, texture] of textures) {
 | 
					                for (let [key, texture] of textures) {
 | 
				
			||||||
@ -528,7 +531,7 @@ export default class PIXIApp extends PIXI.Application {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (progress) {
 | 
					        if (progress) {
 | 
				
			||||||
            loader.on('progress', (e) => {
 | 
					            loader.on('progress', e => {
 | 
				
			||||||
                this.progress(e.progress)
 | 
					                this.progress(e.progress)
 | 
				
			||||||
            })
 | 
					            })
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@ -719,7 +722,7 @@ class FpsDisplay extends PIXI.Graphics {
 | 
				
			|||||||
                fontWeight: 'bold',
 | 
					                fontWeight: 'bold',
 | 
				
			||||||
                fill: '#f6f6f6',
 | 
					                fill: '#f6f6f6',
 | 
				
			||||||
                stroke: '#434f4f',
 | 
					                stroke: '#434f4f',
 | 
				
			||||||
                strokeThickness: 3,
 | 
					                strokeThickness: 3
 | 
				
			||||||
            })
 | 
					            })
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
        this.text.position.set(6, 6)
 | 
					        this.text.position.set(6, 6)
 | 
				
			||||||
 | 
				
			|||||||
@ -155,7 +155,7 @@ export class DeepZoomInfo {
 | 
				
			|||||||
            this.baseURL = this.urlForTile(this.baseLevel, 0, 0, false)
 | 
					            this.baseURL = this.urlForTile(this.baseLevel, 0, 0, false)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (loadBaseImage) {
 | 
					            if (loadBaseImage) {
 | 
				
			||||||
                this.imageForURL(this.baseURL, (e) => {
 | 
					                this.imageForURL(this.baseURL, e => {
 | 
				
			||||||
                    this.size = [e.target.naturalWidth, e.target.naturalHeight]
 | 
					                    this.size = [e.target.naturalWidth, e.target.naturalHeight]
 | 
				
			||||||
                    this.baseImage = e.target
 | 
					                    this.baseImage = e.target
 | 
				
			||||||
                })
 | 
					                })
 | 
				
			||||||
@ -332,7 +332,7 @@ export class DeepZoomImage extends PIXI.Container {
 | 
				
			|||||||
            useWorker = '',
 | 
					            useWorker = '',
 | 
				
			||||||
            minimumLevel = 0,
 | 
					            minimumLevel = 0,
 | 
				
			||||||
            alpha = 1,
 | 
					            alpha = 1,
 | 
				
			||||||
            app = window.app,
 | 
					            app = window.app
 | 
				
			||||||
        } = {}
 | 
					        } = {}
 | 
				
			||||||
    ) {
 | 
					    ) {
 | 
				
			||||||
        super()
 | 
					        super()
 | 
				
			||||||
@ -708,7 +708,7 @@ export class DeepZoomImage extends PIXI.Container {
 | 
				
			|||||||
        let changed = { added: [], removed: [] }
 | 
					        let changed = { added: [], removed: [] }
 | 
				
			||||||
        let newNeeded = new Map()
 | 
					        let newNeeded = new Map()
 | 
				
			||||||
        let { centerCol, centerRow, needed } = this.neededTiles(tiles, level)
 | 
					        let { centerCol, centerRow, needed } = this.neededTiles(tiles, level)
 | 
				
			||||||
        needed.forEach((d) => {
 | 
					        needed.forEach(d => {
 | 
				
			||||||
            let [url, col, row] = d
 | 
					            let [url, col, row] = d
 | 
				
			||||||
            newNeeded.set(url, [col, row])
 | 
					            newNeeded.set(url, [col, row])
 | 
				
			||||||
            if (!tiles.requested.has(url)) {
 | 
					            if (!tiles.requested.has(url)) {
 | 
				
			||||||
@ -856,7 +856,7 @@ export class DeepZoomImage extends PIXI.Container {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    hideTilesAboveLevel(level) {
 | 
					    hideTilesAboveLevel(level) {
 | 
				
			||||||
        Object.keys(this.tileLayers).forEach((key) => {
 | 
					        Object.keys(this.tileLayers).forEach(key => {
 | 
				
			||||||
            let tiles = this.tileLayers[key]
 | 
					            let tiles = this.tileLayers[key]
 | 
				
			||||||
            if (tiles.level > level) {
 | 
					            if (tiles.level > level) {
 | 
				
			||||||
                tiles.visible = false
 | 
					                tiles.visible = false
 | 
				
			||||||
@ -869,7 +869,7 @@ export class DeepZoomImage extends PIXI.Container {
 | 
				
			|||||||
     * @param {number} level - The zoom level of the grid
 | 
					     * @param {number} level - The zoom level of the grid
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    destroyTilesAboveLevel(level) {
 | 
					    destroyTilesAboveLevel(level) {
 | 
				
			||||||
        Object.keys(this.tileLayers).forEach((key) => {
 | 
					        Object.keys(this.tileLayers).forEach(key => {
 | 
				
			||||||
            let tiles = this.tileLayers[key]
 | 
					            let tiles = this.tileLayers[key]
 | 
				
			||||||
            if (tiles.level > level && !tiles.keep) {
 | 
					            if (tiles.level > level && !tiles.keep) {
 | 
				
			||||||
                for (let url of tiles.available.keys()) {
 | 
					                for (let url of tiles.available.keys()) {
 | 
				
			||||||
@ -882,18 +882,38 @@ export class DeepZoomImage extends PIXI.Container {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    destroyAllTiles() {
 | 
					    destroyAllTiles() {
 | 
				
			||||||
        Object.keys(this.tileLayers).forEach((key) => {
 | 
					        Object.keys(this.tileLayers).forEach(key => {
 | 
				
			||||||
            this.destroyTiles(key)
 | 
					            this.destroyTiles(key)
 | 
				
			||||||
        })
 | 
					        })
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /** Destroys all tiles and laywer above the current level to ensure that the memory can
 | 
				
			||||||
 | 
					     * be reused. This must be called from time to time to free load worker which otherwise would
 | 
				
			||||||
 | 
					     * consume memory and threads permanentely.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    destroyUnusedTilesAndLayers() {
 | 
				
			||||||
 | 
					        this.destroyTilesAboveLevel(this.currentLevel)
 | 
				
			||||||
 | 
					        let candidates = []
 | 
				
			||||||
 | 
					        Object.keys(this.tileLayers).forEach(key => {
 | 
				
			||||||
 | 
					            let tiles = this.tileLayers[key]
 | 
				
			||||||
 | 
					            if (tiles.level > this.currentLevel) {
 | 
				
			||||||
 | 
					                candidates.push(key)
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        })
 | 
				
			||||||
 | 
					        for (let key of candidates) {
 | 
				
			||||||
 | 
					            let tiles = this.tileLayers[key]
 | 
				
			||||||
 | 
					            tiles.destroy()
 | 
				
			||||||
 | 
					            delete this.tileLayers[key]
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Tint tiles in all layers that are no longer needed
 | 
					     * Tint tiles in all layers that are no longer needed
 | 
				
			||||||
     *
 | 
					     *
 | 
				
			||||||
     * @memberof DeepZoomImage
 | 
					     * @memberof DeepZoomImage
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    tintObsoleteTiles() {
 | 
					    tintObsoleteTiles() {
 | 
				
			||||||
        Object.keys(this.tileLayers).forEach((key) => {
 | 
					        Object.keys(this.tileLayers).forEach(key => {
 | 
				
			||||||
            let tiles = this.tileLayers[key]
 | 
					            let tiles = this.tileLayers[key]
 | 
				
			||||||
            tiles.untintTiles()
 | 
					            tiles.untintTiles()
 | 
				
			||||||
            if (!tiles.keep) {
 | 
					            if (!tiles.keep) {
 | 
				
			||||||
@ -908,7 +928,7 @@ export class DeepZoomImage extends PIXI.Container {
 | 
				
			|||||||
     * @memberof DeepZoomImage
 | 
					     * @memberof DeepZoomImage
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    destroyUnneededTiles() {
 | 
					    destroyUnneededTiles() {
 | 
				
			||||||
        Object.keys(this.tileLayers).forEach((key) => {
 | 
					        Object.keys(this.tileLayers).forEach(key => {
 | 
				
			||||||
            let tiles = this.tileLayers[key]
 | 
					            let tiles = this.tileLayers[key]
 | 
				
			||||||
            if (!tiles.keep) {
 | 
					            if (!tiles.keep) {
 | 
				
			||||||
                tiles.destroyUnneededTiles()
 | 
					                tiles.destroyUnneededTiles()
 | 
				
			||||||
@ -922,7 +942,7 @@ export class DeepZoomImage extends PIXI.Container {
 | 
				
			|||||||
     * @memberof DeepZoomImage
 | 
					     * @memberof DeepZoomImage
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    destroyObsoleteTiles() {
 | 
					    destroyObsoleteTiles() {
 | 
				
			||||||
        Object.keys(this.tileLayers).forEach((key) => {
 | 
					        Object.keys(this.tileLayers).forEach(key => {
 | 
				
			||||||
            let tiles = this.tileLayers[key]
 | 
					            let tiles = this.tileLayers[key]
 | 
				
			||||||
            if (!tiles.keep) {
 | 
					            if (!tiles.keep) {
 | 
				
			||||||
                tiles.destroyObsoleteTiles()
 | 
					                tiles.destroyObsoleteTiles()
 | 
				
			||||||
@ -937,7 +957,7 @@ export class DeepZoomImage extends PIXI.Container {
 | 
				
			|||||||
     * @memberof DeepZoomImage
 | 
					     * @memberof DeepZoomImage
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    destroyTiles() {
 | 
					    destroyTiles() {
 | 
				
			||||||
        Object.keys(this.tileLayers).forEach((key) => {
 | 
					        Object.keys(this.tileLayers).forEach(key => {
 | 
				
			||||||
            let tiles = this.tileLayers[key]
 | 
					            let tiles = this.tileLayers[key]
 | 
				
			||||||
            if (!tiles.keep) {
 | 
					            if (!tiles.keep) {
 | 
				
			||||||
                tiles.destroyTiles(this.quadTrees)
 | 
					                tiles.destroyTiles(this.quadTrees)
 | 
				
			||||||
@ -949,7 +969,7 @@ export class DeepZoomImage extends PIXI.Container {
 | 
				
			|||||||
     * @param {number} level - The zoom level of the grid
 | 
					     * @param {number} level - The zoom level of the grid
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    tintTilesBelowLevel(level) {
 | 
					    tintTilesBelowLevel(level) {
 | 
				
			||||||
        Object.keys(this.tileLayers).forEach((key) => {
 | 
					        Object.keys(this.tileLayers).forEach(key => {
 | 
				
			||||||
            let tiles = this.tileLayers[key]
 | 
					            let tiles = this.tileLayers[key]
 | 
				
			||||||
            if (tiles.level < level) {
 | 
					            if (tiles.level < level) {
 | 
				
			||||||
                tiles.tintTiles(this.quadTrees)
 | 
					                tiles.tintTiles(this.quadTrees)
 | 
				
			||||||
@ -989,7 +1009,7 @@ export class DeepZoomImage extends PIXI.Container {
 | 
				
			|||||||
            this.fastLoads += 1
 | 
					            this.fastLoads += 1
 | 
				
			||||||
            this.populateTiles(currentTiles, this.currentLevel, {
 | 
					            this.populateTiles(currentTiles, this.currentLevel, {
 | 
				
			||||||
                onlyone: false,
 | 
					                onlyone: false,
 | 
				
			||||||
                about: event.about,
 | 
					                about: event.about
 | 
				
			||||||
            })
 | 
					            })
 | 
				
			||||||
            if (this.fastLoads == 3) {
 | 
					            if (this.fastLoads == 3) {
 | 
				
			||||||
                this.fastLoads = 0
 | 
					                this.fastLoads = 0
 | 
				
			||||||
 | 
				
			|||||||
@ -40,7 +40,7 @@ export class TileLoader {
 | 
				
			|||||||
        if (this.loaded.has(url)) this.loaded.delete(url)
 | 
					        if (this.loaded.has(url)) this.loaded.delete(url)
 | 
				
			||||||
        if (this.loading.has(url)) this.loading.delete(url)
 | 
					        if (this.loading.has(url)) this.loading.delete(url)
 | 
				
			||||||
        //Tile.unschedule(url)
 | 
					        //Tile.unschedule(url)
 | 
				
			||||||
        this.loadQueue = this.loadQueue.filter((item) => item != url)
 | 
					        this.loadQueue = this.loadQueue.filter(item => item != url)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /** Cancels loading by clearing the load queue **/
 | 
					    /** Cancels loading by clearing the load queue **/
 | 
				
			||||||
@ -246,7 +246,7 @@ export class RequestTileLoader extends TileLoader {
 | 
				
			|||||||
            let xhr = new XMLHttpRequest()
 | 
					            let xhr = new XMLHttpRequest()
 | 
				
			||||||
            xhr.open('GET', url, false)
 | 
					            xhr.open('GET', url, false)
 | 
				
			||||||
            xhr.responseType = 'arraybuffer'
 | 
					            xhr.responseType = 'arraybuffer'
 | 
				
			||||||
            xhr.onload = (e) => {
 | 
					            xhr.onload = e => {
 | 
				
			||||||
                let CompressedImage = PIXI.compressedTextures.CompressedImage
 | 
					                let CompressedImage = PIXI.compressedTextures.CompressedImage
 | 
				
			||||||
                let compressed = CompressedImage.loadFromArrayBuffer(xhr.response, url)
 | 
					                let compressed = CompressedImage.loadFromArrayBuffer(xhr.response, url)
 | 
				
			||||||
                let base = new PIXI.BaseTexture(compressed)
 | 
					                let base = new PIXI.BaseTexture(compressed)
 | 
				
			||||||
@ -317,10 +317,10 @@ export class RequestTileLoader extends TileLoader {
 | 
				
			|||||||
export class WorkerTileLoader extends TileLoader {
 | 
					export class WorkerTileLoader extends TileLoader {
 | 
				
			||||||
    constructor(tiles, workerPath) {
 | 
					    constructor(tiles, workerPath) {
 | 
				
			||||||
        super(tiles)
 | 
					        super(tiles)
 | 
				
			||||||
 | 
					        this.debug = false
 | 
				
			||||||
        let worker = (this.worker = new Worker(workerPath))
 | 
					        let worker = (this.worker = new Worker(workerPath))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        worker.onmessage = (event) => {
 | 
					        worker.onmessage = event => {
 | 
				
			||||||
            if (event.data.success) {
 | 
					            if (event.data.success) {
 | 
				
			||||||
                let { url, col, row, buffer } = event.data
 | 
					                let { url, col, row, buffer } = event.data
 | 
				
			||||||
                //console.log("WorkerTileLoader.loaded", url, buffer)
 | 
					                //console.log("WorkerTileLoader.loaded", url, buffer)
 | 
				
			||||||
@ -353,11 +353,13 @@ export class WorkerTileLoader extends TileLoader {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    cancel() {
 | 
					    cancel() {
 | 
				
			||||||
 | 
					        if (this.debug) console.log('canceling worker')
 | 
				
			||||||
        super.cancel()
 | 
					        super.cancel()
 | 
				
			||||||
        this.worker.postMessage({ command: 'abort' })
 | 
					        this.worker.postMessage({ command: 'abort' })
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    destroy() {
 | 
					    destroy() {
 | 
				
			||||||
 | 
					        if (this.debug) console.log('destroying worker')
 | 
				
			||||||
        this.worker.postMessage({ command: 'abort' })
 | 
					        this.worker.postMessage({ command: 'abort' })
 | 
				
			||||||
        this.worker.terminate()
 | 
					        this.worker.terminate()
 | 
				
			||||||
        this.worker = null
 | 
					        this.worker = null
 | 
				
			||||||
 | 
				
			|||||||
@ -1,35 +1,58 @@
 | 
				
			|||||||
let loadQueue = []
 | 
					let loadQueue = []
 | 
				
			||||||
 | 
					let requestPool = []
 | 
				
			||||||
let pendingRequests = new Map()
 | 
					let pendingRequests = new Map()
 | 
				
			||||||
 | 
					let requestCount = 0
 | 
				
			||||||
const batchSize = 8
 | 
					const batchSize = 8
 | 
				
			||||||
const debug = false
 | 
					const debug = false
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function recycledXMLHttpRequest() {
 | 
				
			||||||
 | 
					    // https://nullprogram.com/blog/2013/02/08/
 | 
				
			||||||
 | 
					    if (requestPool.length > 0) {
 | 
				
			||||||
 | 
					        return requestPool.pop()
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    requestCount += 1
 | 
				
			||||||
 | 
					    if (debug) console.log('create XMLHttpRequest', requestCount)
 | 
				
			||||||
 | 
					    let xhr = new XMLHttpRequest()
 | 
				
			||||||
 | 
					    return xhr
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function load() {
 | 
					function load() {
 | 
				
			||||||
    while (loadQueue.length > 0 && pendingRequests.size < batchSize) {
 | 
					    while (loadQueue.length > 0 && pendingRequests.size < batchSize) {
 | 
				
			||||||
        let tile = loadQueue.shift()
 | 
					        let tile = loadQueue.shift()
 | 
				
			||||||
        let [col, row, url] = tile
 | 
					        let [col, row, url] = tile
 | 
				
			||||||
        let xhr = new XMLHttpRequest()
 | 
					        let xhr = recycledXMLHttpRequest()
 | 
				
			||||||
        xhr.responseType = 'arraybuffer'
 | 
					        xhr.onload = event => {
 | 
				
			||||||
        xhr.onload = (event) => {
 | 
					 | 
				
			||||||
            pendingRequests.delete(url)
 | 
					 | 
				
			||||||
            let buffer = xhr.response
 | 
					            let buffer = xhr.response
 | 
				
			||||||
            postMessage({ success: true, url, col, row, buffer }, [buffer])
 | 
					            postMessage({ success: true, url, col, row, buffer }, [buffer])
 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        xhr.onerror = (event) => {
 | 
					 | 
				
			||||||
            pendingRequests.delete(url)
 | 
					            pendingRequests.delete(url)
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        xhr.onerror = event => {
 | 
				
			||||||
            let buffer = null
 | 
					            let buffer = null
 | 
				
			||||||
            postMessage({ success: false, url, col, row, buffer })
 | 
					            postMessage({ success: false, url, col, row, buffer })
 | 
				
			||||||
 | 
					            pendingRequests.delete(url)
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					        xhr.onreadystatechange = () => {
 | 
				
			||||||
 | 
					            // In local files, status is 0 upon success in Mozilla Firefox
 | 
				
			||||||
 | 
					            if (xhr.readyState === XMLHttpRequest.DONE) {
 | 
				
			||||||
 | 
					                pendingRequests.delete(url)
 | 
				
			||||||
 | 
					                requestPool.push(xhr)
 | 
				
			||||||
 | 
					                if (debug) console.log('resuse XMLHttpRequest')
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if (debug) console.log('open XMLHttpRequest')
 | 
				
			||||||
        xhr.open('GET', url, true)
 | 
					        xhr.open('GET', url, true)
 | 
				
			||||||
 | 
					        xhr.responseType = 'arraybuffer'
 | 
				
			||||||
 | 
					        if (debug) console.log('send XMLHttpRequest')
 | 
				
			||||||
        xhr.send()
 | 
					        xhr.send()
 | 
				
			||||||
        pendingRequests.set(url, xhr)
 | 
					        pendingRequests.set(url, xhr)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    if (loadQueue.length > 0) setTimeout(load, 1000 / 120)
 | 
					    if (loadQueue.length > 0) setTimeout(load, 1000 / 120)
 | 
				
			||||||
    else {
 | 
					    else {
 | 
				
			||||||
        if (debug) console.log('Ready')
 | 
					        if (debug) console.log('tileloader ready')
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
self.onmessage = (event) => {
 | 
					self.onmessage = event => {
 | 
				
			||||||
    let msg = event.data
 | 
					    let msg = event.data
 | 
				
			||||||
    switch (msg.command) {
 | 
					    switch (msg.command) {
 | 
				
			||||||
        case 'load':
 | 
					        case 'load':
 | 
				
			||||||
@ -40,10 +63,12 @@ self.onmessage = (event) => {
 | 
				
			|||||||
            break
 | 
					            break
 | 
				
			||||||
        case 'abort':
 | 
					        case 'abort':
 | 
				
			||||||
            loadQueue = []
 | 
					            loadQueue = []
 | 
				
			||||||
 | 
					            requestPool = []
 | 
				
			||||||
            for (let xhr of pendingRequests.values()) {
 | 
					            for (let xhr of pendingRequests.values()) {
 | 
				
			||||||
                xhr.abort()
 | 
					                xhr.abort()
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            if (debug) console.log('Abort')
 | 
					            pendingRequests.clear()
 | 
				
			||||||
 | 
					            if (debug) console.log('tileloader aborted')
 | 
				
			||||||
            break
 | 
					            break
 | 
				
			||||||
        default:
 | 
					        default:
 | 
				
			||||||
            console.warn('Unknown worker command: ' + msg.command)
 | 
					            console.warn('Unknown worker command: ' + msg.command)
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user