mirror of
https://github.com/moonlight-stream/moonlight-chrome.git
synced 2025-08-17 16:46:31 +00:00
Rewrite box art loading to load directly from chrome.storage for a huge speed improvement
This commit is contained in:
parent
4284394607
commit
6c457fe56d
@ -117,7 +117,6 @@ function restoreUiAfterNaClLoad() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function beginBackgroundPollingOfHost(host) {
|
function beginBackgroundPollingOfHost(host) {
|
||||||
host.warmBoxArtCache();
|
|
||||||
if (host.online) {
|
if (host.online) {
|
||||||
$("#hostgrid-" + host.serverUid).removeClass('host-cell-inactive');
|
$("#hostgrid-" + host.serverUid).removeClass('host-cell-inactive');
|
||||||
// The host was already online. Just start polling in the background now.
|
// The host was already online. Just start polling in the background now.
|
||||||
@ -459,14 +458,11 @@ function showApps(host) {
|
|||||||
// double clicking the button will cause multiple box arts to appear.
|
// double clicking the button will cause multiple box arts to appear.
|
||||||
// to mitigate this we ensure we don't add a duplicate.
|
// to mitigate this we ensure we don't add a duplicate.
|
||||||
// This isn't perfect: there's lots of RTTs before the logic prevents anything
|
// This isn't perfect: there's lots of RTTs before the logic prevents anything
|
||||||
var imageBlob = new Blob([resolvedPromise], {type: "image/png"});
|
var outerDiv = $("<div>", {class: 'game-container mdl-card mdl-shadow--4dp', id: 'game-'+app.id, backgroundImage: resolvedPromise, role: 'link', tabindex: 0, title: app.title, 'aria-label': app.title });
|
||||||
var outerDiv = $("<div>", {class: 'game-container mdl-card mdl-shadow--4dp', id: 'game-'+app.id, backgroundImage: URL.createObjectURL(imageBlob), role: 'link', tabindex: 0, title: app.title, 'aria-label': app.title });
|
$(outerDiv).append($("<img \>", {src: resolvedPromise, id: 'game-'+app.id, name: app.title }));
|
||||||
$(outerDiv).append($("<img \>", {src: URL.createObjectURL(imageBlob), id: 'game-'+app.id, name: app.title }));
|
|
||||||
$(outerDiv).append($("<div>", {class: "game-title", html: $("<span>", {html: app.title} )}));
|
$(outerDiv).append($("<div>", {class: "game-title", html: $("<span>", {html: app.title} )}));
|
||||||
$("#game-grid").append(outerDiv);
|
$("#game-grid").append(outerDiv);
|
||||||
|
|
||||||
|
|
||||||
// $("#gameList").append($("<div>", {html:$("<img \>", {src: URL.createObjectURL(imageBlob), id: 'game-'+app.id, name: app.title }), class: 'box-art mdl-cell mdl-cell--3-col'}).append($("<span>", {html: app.title, class:"game-title"})));
|
|
||||||
$('#game-'+app.id).on('click', function () {
|
$('#game-'+app.id).on('click', function () {
|
||||||
startGame(host, app.id);
|
startGame(host, app.id);
|
||||||
});
|
});
|
||||||
|
@ -71,7 +71,6 @@ function NvHTTP(address, clientUid, userEnteredAddress = '') {
|
|||||||
this.serverMajorVersion = 0;
|
this.serverMajorVersion = 0;
|
||||||
this.appVersion = '';
|
this.appVersion = '';
|
||||||
this.clientUid = clientUid;
|
this.clientUid = clientUid;
|
||||||
this._memCachedBoxArtArray = {};
|
|
||||||
this._pollCount = 0;
|
this._pollCount = 0;
|
||||||
this._consecutivePollFailures = 0;
|
this._consecutivePollFailures = 0;
|
||||||
this.online = false;
|
this.online = false;
|
||||||
@ -223,10 +222,6 @@ NvHTTP.prototype = {
|
|||||||
return string;
|
return string;
|
||||||
},
|
},
|
||||||
|
|
||||||
_prepareForStorage: function() {
|
|
||||||
this._memCachedBoxArtArray = {};
|
|
||||||
},
|
|
||||||
|
|
||||||
_parseServerInfo: function(xmlStr) {
|
_parseServerInfo: function(xmlStr) {
|
||||||
$xml = this._parseXML(xmlStr);
|
$xml = this._parseXML(xmlStr);
|
||||||
$root = $xml.find('root');
|
$root = $xml.find('root');
|
||||||
@ -354,77 +349,17 @@ NvHTTP.prototype = {
|
|||||||
return this.getAppListWithCacheFlush();
|
return this.getAppListWithCacheFlush();
|
||||||
},
|
},
|
||||||
|
|
||||||
// warms `this` _memCachedBoxArtArray with ALL box art from ALL servers
|
|
||||||
// this is inefficient, but works well.
|
|
||||||
warmBoxArtCache: function () {
|
|
||||||
if (!this.paired) {
|
|
||||||
console.log('%c[utils.js, warmBoxArtCache]', 'color: grey;', 'Not warming box art cache for unpaired host');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (Object.keys(this._memCachedBoxArtArray).length != 0) {
|
|
||||||
console.log('%c[utils.js, warmBoxArtCache]', 'color: grey;', 'Box art cache already warmed');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (chrome.storage) {
|
|
||||||
chrome.storage.local.get('boxArtCache', function(JSONCachedBoxArtArray) {
|
|
||||||
|
|
||||||
var storedBoxArtArray; // load cached data if it exists
|
|
||||||
if (JSONCachedBoxArtArray.boxArtCache != undefined) {
|
|
||||||
storedBoxArtArray = JSONCachedBoxArtArray.boxArtCache;
|
|
||||||
for (var key in storedBoxArtArray) {
|
|
||||||
this._memCachedBoxArtArray[key] = _base64ToArrayBuffer(storedBoxArtArray[key]);
|
|
||||||
}
|
|
||||||
console.log('%c[utils.js, warmBoxArtCache]', 'color: grey;', 'Box art cache warmed');
|
|
||||||
} else {
|
|
||||||
console.warn('%c[utils.js, warmBoxArtCache]', 'color: grey;', 'No box art found in storage. Cannot warm cache!');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}.bind(this));
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
// returns the box art of the given appID.
|
// returns the box art of the given appID.
|
||||||
// three layers of response time are possible: memory cached (in javascript), storage cached (in chrome.storage.local), and streamed (host sends binary over the network)
|
// three layers of response time are possible: memory cached (in javascript), storage cached (in chrome.storage.local), and streamed (host sends binary over the network)
|
||||||
getBoxArt: function (appId) {
|
getBoxArt: function (appId) {
|
||||||
|
|
||||||
// TODO: unfortunately we do N lookups from storage cache, each of them filling up the memory cache.
|
|
||||||
// once the first round of calls are all made, each subsequent request hits this and returns from memory cache
|
|
||||||
if (this._memCachedBoxArtArray[appId] === null) {
|
|
||||||
// This means a previous box art request failed, don't try again
|
|
||||||
return new Promise(function (resolve, reject) {
|
|
||||||
console.error('%c[utils.js, utils.js, getBoxArt]', 'color: gray;', 'Returning cached box-art failure result')
|
|
||||||
reject(null);
|
|
||||||
return;
|
|
||||||
}.bind(this));
|
|
||||||
} else if (this._memCachedBoxArtArray[appId] !== undefined) {
|
|
||||||
return new Promise(function (resolve, reject) {
|
|
||||||
console.log('%c[utils.js, utils.js, getBoxArt]', 'color: gray;', 'Returning memory-cached box-art');
|
|
||||||
resolve(this._memCachedBoxArtArray[appId]);
|
|
||||||
return;
|
|
||||||
}.bind(this));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (chrome.storage) {
|
if (chrome.storage) {
|
||||||
// This may be bad practice to push/pull this much data through local storage?
|
// This may be bad practice to push/pull this much data through local storage?
|
||||||
|
|
||||||
return new Promise(function (resolve, reject) {
|
return new Promise(function (resolve, reject) {
|
||||||
chrome.storage.local.get('boxArtCache', function(JSONCachedBoxArtArray) {
|
chrome.storage.local.get('boxart-'+appId, function(storageData) {
|
||||||
|
|
||||||
var storedBoxArtArray; // load cached data if it exists
|
|
||||||
if (JSONCachedBoxArtArray.boxArtCache != undefined && JSONCachedBoxArtArray.boxArtCache[appId] != undefined) {
|
|
||||||
storedBoxArtArray = JSONCachedBoxArtArray.boxArtCache;
|
|
||||||
|
|
||||||
storedBoxArtArray[appId] = _base64ToArrayBuffer(storedBoxArtArray[appId]);
|
|
||||||
this._memCachedBoxArtArray[appId] = storedBoxArtArray[appId];
|
|
||||||
|
|
||||||
} else {
|
|
||||||
storedBoxArtArray = {};
|
|
||||||
}
|
|
||||||
|
|
||||||
// if we already have it, load it.
|
// if we already have it, load it.
|
||||||
if (storedBoxArtArray[appId] !== undefined && Object.keys(storedBoxArtArray).length !== 0 && storedBoxArtArray[appId].constructor !== Object) {
|
if (storageData !== undefined && Object.keys(storageData).length !== 0 && storageData['boxart-'+appId].constructor !== Object) {
|
||||||
console.log('%c[utils.js, getBoxArt]', 'color: gray;', 'Returning strage-cached box art for app: ', appId);
|
console.log('%c[utils.js, getBoxArt]', 'color: gray;', 'Returning storage-cached box art for app: ', appId);
|
||||||
resolve(storedBoxArtArray[appId]);
|
resolve(storageData['boxart-'+appId]);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -435,24 +370,17 @@ NvHTTP.prototype = {
|
|||||||
'&appid=' + appId +
|
'&appid=' + appId +
|
||||||
'&AssetType=2&AssetIdx=0',
|
'&AssetType=2&AssetIdx=0',
|
||||||
true
|
true
|
||||||
]).then(function(streamedBoxArt) {
|
]).then(function(boxArtBuffer) {
|
||||||
// the memcached data is global to all the async calls we're doing. This way there's only one array that holds everything properly.
|
var reader = new FileReader();
|
||||||
this._memCachedBoxArtArray[appId] = streamedBoxArt;
|
reader.onloadend = function() {
|
||||||
var obj = {};
|
var obj = {};
|
||||||
var arrayToStore = {}
|
obj['boxart-'+appId] = this.result;
|
||||||
|
chrome.storage.local.set(obj, function(onSuccess) {});
|
||||||
for (key in this._memCachedBoxArtArray) { // convert the arraybuffer into a string
|
console.log('%c[utils.js, utils.js, getBoxArt]', 'color: gray;', 'Returning network-fetched box art');
|
||||||
arrayToStore[key] = _arrayBufferToBase64(this._memCachedBoxArtArray[key]);
|
resolve(this.result);
|
||||||
}
|
}
|
||||||
|
reader.readAsDataURL(new Blob([boxArtBuffer], {type: "image/png"}));
|
||||||
obj['boxArtCache'] = arrayToStore; // storage is in JSON format. JSON does not support binary data.
|
|
||||||
chrome.storage.local.set(obj, function(onSuccess) {});
|
|
||||||
console.log('%c[utils.js, utils.js, getBoxArt]', 'color: gray;', 'Returning streamed box art');
|
|
||||||
resolve(streamedBoxArt);
|
|
||||||
return;
|
|
||||||
}.bind(this), function(error) {
|
}.bind(this), function(error) {
|
||||||
// Cache the failure but not persistently
|
|
||||||
this._memCachedBoxArtArray[appId] = null;
|
|
||||||
console.error('%c[utils.js, utils.js, getBoxArt]', 'color: gray;', 'Box-art request failed!', error);
|
console.error('%c[utils.js, utils.js, getBoxArt]', 'color: gray;', 'Box-art request failed!', error);
|
||||||
reject(error);
|
reject(error);
|
||||||
return;
|
return;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user