ingress-intel-total-conversion/code/portal_render_limit.js
Xelio c75caa91dd Fix flicker portal in portal render limit handler
Change:
Extract portal handle process from "handleDataResponse" to "handlePortalData"
Add "action" property to object returned by $.ajax() to identity type of request
Delay low level portal render until no active request of map data.
2013-02-28 15:10:13 +08:00

166 lines
5.9 KiB
JavaScript

// PORTAL RENDER LIMIT HANDLER ///////////////////////////////////////
// Functions to handle hiding low level portal when portal render
// limit is reached.
//
// 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.
//
// "getMinLevel" will return minLevel and call "setMinLevel" if
// minLevel hasn't set yet.
//
// In "setMinLevel", it will loop through all portal level from
// high to low, and sum total portal count (old + new) to check
// minLevel.
//
// In each call of window.handleDataResponse(), it will call
// "resetCounting" to reset previous response data. But minLevel
// is preserved and only replaced when render limit reached in
// higher level, until next window.requestData() called and reset.
//
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();
if(!portalRenderLimit.previousZoomLevel) portalRenderLimit.previousZoomLevel = currentZoomLevel;
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() {
portalRenderLimit.minLevelSet = false;
for(var i = 0; i <= MAX_PORTAL_LEVEL; i++) {
portalRenderLimit.newPortalsPerLevel[i] = 0;
}
}
window.portalRenderLimit.resetPortalsPreviousMinLevel = function() {
for(var i = 0; i <= MAX_PORTAL_LEVEL; i++) {
portalRenderLimit.portalsPreviousMinLevel[i] = new Array();
}
}
window.portalRenderLimit.processPortals = function(ppp) {
portalRenderLimit.resetCounting();
var resultPortals = new Array();
$.each(ppp, function(ind, portal) {
portalRenderLimit.countPortal(portal);
if(!portalRenderLimit.isLastRequest()) {
var portalLevel = parseInt(getPortalLevel(portal[2]));
if(portalLevel < portalRenderLimit.previousMinLevel) {
portalRenderLimit.portalsPreviousMinLevel[portalLevel].push(portal);
}else{
resultPortals.push(portal);
}
}
});
if(portalRenderLimit.isLastRequest()) {
resultPortals = portalRenderLimit.getLowLevelPortals(ppp);
portalRenderLimit.resetPortalsPreviousMinLevel();
}
return resultPortals;
}
window.portalRenderLimit.handleFailRequest = function() {
if(portalRenderLimit.isLastRequest()) {
var ppp = portalRenderLimit.getLowLevelPortals(null);
portalRenderLimit.resetPortalsPreviousMinLevel();
handlePortalData(ppp);
}
}
window.portalRenderLimit.countPortal = function(ent) {
var portalGuid = ent[0];
var portalLevel = parseInt(getPortalLevel(ent[2]));
var layerGroup = portalsLayers[portalLevel];
if(findEntityInLeaflet(layerGroup, window.portals, ent[0])) return;
portalRenderLimit.newPortalsPerLevel[portalLevel]++;
}
window.portalRenderLimit.getLowLevelPortals = function(appendTo) {
var resultPortals = appendTo ? appendTo : new Array();
for(var i = portalRenderLimit.getMinLevel();
i < portalRenderLimit.previousMinLevel;
i++) {
$.merge(resultPortals, portalRenderLimit.portalsPreviousMinLevel[i]);
}
return resultPortals;
}
window.portalRenderLimit.isLastRequest = function() {
var result = true;
$.each(window.activeRequests, function(ind, req) {
if(req.action === 'getThinnedEntitiesV2') {
result = false;
return false;
}
});
return result;
}
window.portalRenderLimit.getMinLevel = function() {
if(!portalRenderLimit.initialized) return -1;
if(!portalRenderLimit.minLevelSet) portalRenderLimit.setMinLevel();
return portalRenderLimit.minLevel;
}
window.portalRenderLimit.setMinLevel = function() {
var totalPortalsCount = 0;
var newMinLevel = MAX_PORTAL_LEVEL + 1;
// Find the min portal level under render limit
while(newMinLevel > 0) {
var oldPortalCount = layerGroupLength(portalsLayers[newMinLevel - 1]);
var newPortalCount = portalRenderLimit.newPortalsPerLevel[newMinLevel - 1];
totalPortalsCount += oldPortalCount + newPortalCount;
if(totalPortalsCount >= MAX_DRAWN_PORTALS)
break;
newMinLevel--;
}
// If render limit reached at max portal level, still let portal at max level render
newMinLevel = Math.min(newMinLevel, MAX_PORTAL_LEVEL);
portalRenderLimit.minLevel = Math.max(newMinLevel, portalRenderLimit.minLevel);
portalRenderLimit.minLevelSet = true;
}