diff --git a/code/map_data.js b/code/map_data.js index 363240c4..300be338 100644 --- a/code/map_data.js +++ b/code/map_data.js @@ -49,7 +49,7 @@ 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, portalRenderLimit.handleFailRequest)); }); } @@ -59,11 +59,10 @@ window.handleDataResponse = function(data, textStatus, jqXHR) { if(!data || !data.result) { window.failedRequestCount++; console.warn(data); + portalRenderLimit.handleFailRequest(); 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 what’s rendered last ends up on top. While the @@ -72,8 +71,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 +89,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 +97,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); @@ -118,7 +113,7 @@ window.handleDataResponse = function(data, textStatus, jqXHR) { } }); }); - + $.each(ppp, function(ind, portal) { if(portal[2].portalV2['linkedFields'] === undefined) { portal[2].portalV2['linkedFields'] = []; @@ -128,12 +123,28 @@ window.handleDataResponse = function(data, textStatus, jqXHR) { portal[2].portalV2['linkedFields'] = uniqueArray(p2f[portal[0]]); } }); + + // Process the portals with portal render limit handler first + ppp = portalRenderLimit.processPortals(ppp); + handlePortalData(ppp); + + resolvePlayerNames(); + renderUpdateStatus(); +} + +window.handlePortalData = function(ppp) { + 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); }); + $.each(ppp, 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 +161,6 @@ window.handleDataResponse = function(data, textStatus, jqXHR) { } if(portalUpdateAvailable) renderPortalDetails(selectedPortal); - resolvePlayerNames(); - renderUpdateStatus(); } // removes entities that are still handled by Leaflet, although they diff --git a/code/portal_render_limit.js b/code/portal_render_limit.js index 58961023..f80bd7b9 100644 --- a/code/portal_render_limit.js +++ b/code/portal_render_limit.js @@ -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,25 @@ 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() { @@ -43,7 +69,45 @@ window.portalRenderLimit.resetCounting = function() { } } -window.portalRenderLimit.pushPortal = function(ent) { +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]; @@ -52,6 +116,27 @@ window.portalRenderLimit.pushPortal = function(ent) { 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(); diff --git a/code/utils_misc.js b/code/utils_misc.js index 1e5e0a87..451d565e 100644 --- a/code/utils_misc.js +++ b/code/utils_misc.js @@ -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;