Merge pull request #344 from Xelio/patch-fix-portal-flicker

Fix flicker portal in portal render limit handler
This commit is contained in:
Stefan Breunig 2013-03-02 07:22:45 -08:00
commit bc089cd5c8
4 changed files with 130 additions and 24 deletions

View File

@ -49,21 +49,28 @@ window.requestData = function() {
$.each(tiles, function(ind, tls) {
data = { minLevelOfDetail: -1 };
data.boundsParamsList = tls;
window.requests.add(window.postAjax('getThinnedEntitiesV2', data, window.handleDataResponse));
window.requests.add(window.postAjax('getThinnedEntitiesV2', data, window.handleDataResponse, window.handleFailedRequest));
});
}
// Handle failed map data request
window.handleFailedRequest = function() {
if(requests.isLastRequest('getThinnedEntitiesV2')) {
var leftOverPortals = portalRenderLimit.mergeLowLevelPortals(null);
handlePortalsRender(leftOverPortals);
}
}
// works on map data response and ensures entities are drawn/updated.
window.handleDataResponse = function(data, textStatus, jqXHR) {
// remove from active ajax queries list
if(!data || !data.result) {
window.failedRequestCount++;
console.warn(data);
handleFailedRequest();
return;
}
var portalUpdateAvailable = false;
var portalInUrlAvailable = false;
var m = data.result.map;
// defer rendering of portals because there is no z-index in SVG.
// this means that whats rendered last ends up on top. While the
@ -72,8 +79,6 @@ window.handleDataResponse = function(data, textStatus, jqXHR) {
// https://github.com/Leaflet/Leaflet/issues/185
var ppp = [];
var p2f = {};
// Reset new portals count of Portal Render Limit handler
portalRenderLimit.resetCounting();
$.each(m, function(qk, val) {
$.each(val.deletedGameEntityGuids, function(ind, guid) {
if(getTypeByGuid(guid) === TYPE_FIELD && window.fields[guid] !== undefined) {
@ -92,8 +97,6 @@ window.handleDataResponse = function(data, textStatus, jqXHR) {
// format for portals: { controllingTeam, turret }
if(ent[2].turret !== undefined) {
if(selectedPortal === ent[0]) portalUpdateAvailable = true;
if(urlPortal && ent[0] == urlPortal) portalInUrlAvailable = true;
var latlng = [ent[2].locationE6.latE6/1E6, ent[2].locationE6.lngE6/1E6];
if(!window.getPaddedBounds().contains(latlng)
@ -102,7 +105,7 @@ window.handleDataResponse = function(data, textStatus, jqXHR) {
) return;
portalRenderLimit.pushPortal(ent);
ppp.push(ent); // delay portal render
} else if(ent[2].edge !== undefined) {
renderLink(ent);
@ -129,11 +132,28 @@ window.handleDataResponse = function(data, textStatus, jqXHR) {
}
});
// Process the portals with portal render limit handler first
// Low level portal will hold until last request
var newPpp = portalRenderLimit.splitOrMergeLowLevelPortals(ppp);
handlePortalsRender(newPpp);
resolvePlayerNames();
renderUpdateStatus();
}
window.handlePortalsRender = function(portals) {
var portalUpdateAvailable = false;
var portalInUrlAvailable = false;
// Preserve and restore "selectedPortal" between portal re-render
if(portalUpdateAvailable) var oldSelectedPortal = selectedPortal;
runHooks('portalDataLoaded', {portals : ppp});
$.each(ppp, function(ind, portal) { renderPortal(portal); });
runHooks('portalDataLoaded', {portals : portals});
$.each(portals, function(ind, portal) {
if(selectedPortal === portal[0]) portalUpdateAvailable = true;
if(urlPortal && portal[0] == urlPortal) portalInUrlAvailable = true;
renderPortal(portal);
});
var selectedPortalLayer = portals[oldSelectedPortal];
if(portalUpdateAvailable && selectedPortalLayer) selectedPortal = oldSelectedPortal;
@ -150,8 +170,6 @@ window.handleDataResponse = function(data, textStatus, jqXHR) {
}
if(portalUpdateAvailable) renderPortalDetails(selectedPortal);
resolvePlayerNames();
renderUpdateStatus();
}
// removes entities that are still handled by Leaflet, although they

View File

@ -3,9 +3,22 @@
// Functions to handle hiding low level portal when portal render
// limit is reached.
//
// After initialized and reset in window.requestData(), portals in
// response data will pass to function "pushPortal". Each new portal
// not on the map will add 1 to newPortalsPerLevel[portal level].
// On initialization, previous minLevel will preserve to previousMinLevel
// with zoom level difference.
//
// After initialized and reset in window.requestData(), "processPortals"
// intercept all portals data in "handleDataResponse". Put the count of
// new portals to newPortalsPerLevel[portal level]. And split portals
// into two parts base on previousMinLevel. Portals with level >=
// previousMinLevel will return as result and continue to render.
// Others will save to portalsPreviousMinLevel. If there is no more
// active request of map data, portals will not split and
// portalsPreviousMinLevel will add back to result and render base on
// current minLevel.
//
// "handleFailRequest" is added to handle the case when the last request
// failed and "processPortals" didn't get called. It will get
// portalsPreviousMinLevel base on current minLevel and render them.
//
// "getMinLevel" will be called by "getMinPortalLevel" in utils_misc.js
// to determine min portal level to draw on map.
@ -28,12 +41,28 @@ window.portalRenderLimit = function() {}
window.portalRenderLimit.initialized = false;
window.portalRenderLimit.minLevelSet = false;
window.portalRenderLimit.minLevel = -1;
window.portalRenderLimit.previousMinLevel = -1;
window.portalRenderLimit.previousZoomLevel;
window.portalRenderLimit.newPortalsPerLevel = new Array(MAX_PORTAL_LEVEL + 1);
window.portalRenderLimit.portalsPreviousMinLevel = new Array(MAX_PORTAL_LEVEL + 1);
window.portalRenderLimit.init = function () {
var currentZoomLevel = map.getZoom();
portalRenderLimit.previousZoomLevel = portalRenderLimit.previousZoomLevel || currentZoomLevel;
// If there is a minLevel set in previous run, calculate previousMinLevel with it.
if(portalRenderLimit.minLevelSet) {
var zoomDiff = currentZoomLevel - portalRenderLimit.previousZoomLevel;
portalRenderLimit.previousMinLevel = Math.max(portalRenderLimit.minLevel - zoomDiff, -1);
portalRenderLimit.previousMinLevel = Math.min(portalRenderLimit.previousMinLevel, MAX_PORTAL_LEVEL);
}
portalRenderLimit.previousZoomLevel = currentZoomLevel;
portalRenderLimit.initialized = true;
portalRenderLimit.minLevel = -1;
portalRenderLimit.resetCounting();
portalRenderLimit.resetPortalsPreviousMinLevel();
}
window.portalRenderLimit.resetCounting = function() {
@ -43,13 +72,59 @@ window.portalRenderLimit.resetCounting = function() {
}
}
window.portalRenderLimit.pushPortal = function(ent) {
var portalGuid = ent[0];
var portalLevel = parseInt(getPortalLevel(ent[2]));
window.portalRenderLimit.resetPortalsPreviousMinLevel = function() {
for(var i = 0; i <= MAX_PORTAL_LEVEL; i++) {
portalRenderLimit.portalsPreviousMinLevel[i] = new Array();
}
}
window.portalRenderLimit.splitOrMergeLowLevelPortals = function(originPortals) {
portalRenderLimit.resetCounting();
portalRenderLimit.countingPortals(originPortals);
var resultPortals = requests.isLastRequest('getThinnedEntitiesV2')
? portalRenderLimit.mergeLowLevelPortals(originPortals)
: portalRenderLimit.splitLowLevelPortals(originPortals);
return resultPortals;
}
window.portalRenderLimit.countingPortals = function(portals) {
$.each(portals, function(ind, portal) {
var portalGuid = portal[0];
var portalLevel = parseInt(getPortalLevel(portal[2]));
var layerGroup = portalsLayers[portalLevel];
if(findEntityInLeaflet(layerGroup, window.portals, ent[0])) return;
if(findEntityInLeaflet(layerGroup, window.portals, portalGuid)) return true;
portalRenderLimit.newPortalsPerLevel[portalLevel]++;
});
}
window.portalRenderLimit.splitLowLevelPortals = function(portals) {
var resultPortals = new Array();
$.each(portals, function(ind, portal) {
var portalLevel = parseInt(getPortalLevel(portal[2]));
if(portalLevel < portalRenderLimit.previousMinLevel) {
portalRenderLimit.portalsPreviousMinLevel[portalLevel].push(portal);
}else{
resultPortals.push(portal);
}
});
return resultPortals;
}
window.portalRenderLimit.mergeLowLevelPortals = function(appendTo) {
var resultPortals = appendTo ? appendTo : new Array();
for(var i = portalRenderLimit.getMinLevel();
i < portalRenderLimit.previousMinLevel;
i++) {
$.merge(resultPortals, portalRenderLimit.portalsPreviousMinLevel[i]);
}
// Reset portalsPreviousMinLevel, ensure they return only once
portalRenderLimit.resetPortalsPreviousMinLevel();
return resultPortals;
}
window.portalRenderLimit.getMinLevel = function() {

View File

@ -111,3 +111,14 @@ window.requests._callOnRefreshFunctions = function() {
window.requests.addRefreshFunction = function(f) {
window.requests._onRefreshFunctions.push(f);
}
window.requests.isLastRequest = function(action) {
var result = true;
$.each(window.activeRequests, function(ind, req) {
if(req.action === action) {
result = false;
return false;
}
});
return result;
}

View File

@ -58,7 +58,7 @@ window.postAjax = function(action, data, success, error) {
data = JSON.stringify($.extend({method: 'dashboard.'+action}, data));
var remove = function(data, textStatus, jqXHR) { window.requests.remove(jqXHR); };
var errCnt = function(jqXHR) { window.failedRequestCount++; window.requests.remove(jqXHR); };
return $.ajax({
var result = $.ajax({
// use full URL to avoid issues depending on how people set their
// slash. See:
// https://github.com/breunigs/ingress-intel-total-conversion/issues/56
@ -73,6 +73,8 @@ window.postAjax = function(action, data, success, error) {
req.setRequestHeader('X-CSRFToken', readCookie('csrftoken'));
}
});
result.action = action;
return result;
}
// converts unix timestamps to HH:mm:ss format if it was today;