this patch fixes several issues:

fix #103 by always re-rendering resonator details.
  A follow-up patch could also avoid re-rendering resos if they did not
  change. Given that there are only a few on these high zoom levels, perf
  improvement might be negligible though.
- fix #91. This avoids drawing portals/links/fields again if they are
  hidden. The patch looks for those hidden entities and either removes
  them before re-drawing (portals) or skips re-drawing altogether:
- Fields and Links are assumed to never change as long as their GUID is
  the same. This avoids deleting and re-creating links/fields all the
  time and might improve speed. Haven’t tested though.
This commit is contained in:
Stefan Breunig
2013-02-11 11:30:56 +01:00
parent 05ca824897
commit 64bf9e1f70

View File

@ -216,9 +216,17 @@ window.renderPortal = function(ent) {
var team = getTeam(ent[2]); var team = getTeam(ent[2]);
// do nothing if portal did not change // do nothing if portal did not change
var old = window.portals[ent[0]]; var layerGroup = portalsLayers[parseInt(portalLevel)];
if(old && old.options.level === portalLevel && old.options.team === team) var old = findEntityInLeaflet(layerGroup, window.portals, ent[0]);
return; if(old) {
var oo = old.options;
var u = oo.team !== team;
u = u || oo.level !== portalLevel;
// nothing for the portal changed, so dont update. Let resonators
// manage themselves if they want to be updated.
if(!u) return renderResonators(ent);
removeByGuid(ent[0]);
}
// there were changes, remove old portal // there were changes, remove old portal
removeByGuid(ent[0]); removeByGuid(ent[0]);
@ -245,7 +253,7 @@ window.renderPortal = function(ent) {
details: ent[2], details: ent[2],
guid: ent[0]}); guid: ent[0]});
p.on('remove', function() { p.on('remove', function() {
var portalGuid = this.options.guid var portalGuid = this.options.guid
// remove attached resonators, skip if // remove attached resonators, skip if
@ -261,13 +269,17 @@ window.renderPortal = function(ent) {
window.portalAccessIndicator = null; window.portalAccessIndicator = null;
} }
}); });
p.on('add', function() {
p.on('add', function() {
// enable for debugging
if(window.portals[this.options.guid]) throw('duplicate portal detected');
window.portals[this.options.guid] = this; window.portals[this.options.guid] = this;
// handles the case where a selected portal gets removed from the // handles the case where a selected portal gets removed from the
// map by hiding all portals with said level // map by hiding all portals with said level
if(window.selectedPortal != this.options.guid) if(window.selectedPortal != this.options.guid)
window.portalResetColor(this); window.portalResetColor(this);
}); });
p.on('click', function() { window.renderPortalDetails(ent[0]); }); p.on('click', function() { window.renderPortalDetails(ent[0]); });
p.on('dblclick', function() { p.on('dblclick', function() {
window.renderPortalDetails(ent[0]); window.renderPortalDetails(ent[0]);
@ -279,11 +291,10 @@ window.renderPortal = function(ent) {
window.runHooks('portalAdded', {portal: p}); window.runHooks('portalAdded', {portal: p});
// portalLevel contains a float, need to round down // portalLevel contains a float, need to round down
p.addTo(portalsLayers[parseInt(portalLevel)]); p.addTo(layerGroup);
} }
window.renderResonators = function(ent) { window.renderResonators = function(ent) {
var portalLevel = getPortalLevel(ent[2]); var portalLevel = getPortalLevel(ent[2]);
if(portalLevel < getMinPortalLevel() && ent[0] != selectedPortal) return; if(portalLevel < getMinPortalLevel() && ent[0] != selectedPortal) return;
@ -344,8 +355,12 @@ window.portalResetColor = function(portal) {
// renders a link on the map from the given entity // renders a link on the map from the given entity
window.renderLink = function(ent) { window.renderLink = function(ent) {
removeByGuid(ent[0]); if(Object.keys(links).length >= MAX_DRAWN_LINKS)
if(Object.keys(links).length >= MAX_DRAWN_LINKS) return; return removeByGuid(ent[0]);
// assume that links never change. If they do, they will have a
// different ID.
if(findEntityInLeaflet(linksLayer, links, ent[0])) return;
var team = getTeam(ent[2]); var team = getTeam(ent[2]);
var edge = ent[2].edge; var edge = ent[2].edge;
@ -366,6 +381,8 @@ window.renderLink = function(ent) {
poly.on('remove', function() { delete window.links[this.options.guid]; }); poly.on('remove', function() { delete window.links[this.options.guid]; });
poly.on('add', function() { poly.on('add', function() {
// enable for debugging
if(window.links[this.options.guid]) throw('duplicate link detected');
window.links[this.options.guid] = this; window.links[this.options.guid] = this;
this.bringToBack(); this.bringToBack();
}); });
@ -374,8 +391,12 @@ window.renderLink = function(ent) {
// renders a field on the map from a given entity // renders a field on the map from a given entity
window.renderField = function(ent) { window.renderField = function(ent) {
window.removeByGuid(ent[0]); if(Object.keys(fields).length >= MAX_DRAWN_FIELDS)
if(Object.keys(fields).length >= MAX_DRAWN_FIELDS) return; return window.removeByGuid(ent[0]);
// assume that fields never change. If they do, they will have a
// different ID.
if(findEntityInLeaflet(fieldsLayer, fields, ent[0])) return;
var team = getTeam(ent[2]); var team = getTeam(ent[2]);
var reg = ent[2].capturedRegion; var reg = ent[2].capturedRegion;
@ -391,14 +412,37 @@ window.renderField = function(ent) {
clickable: false, clickable: false,
smoothFactor: 10, smoothFactor: 10,
vertices: ent[2].capturedRegion, vertices: ent[2].capturedRegion,
lastUpdate: ent[1],
guid: ent[0]}); guid: ent[0]});
if(!getPaddedBounds().intersects(poly.getBounds())) return; if(!getPaddedBounds().intersects(poly.getBounds())) return;
poly.on('remove', function() { delete window.fields[this.options.guid]; }); poly.on('remove', function() { delete window.fields[this.options.guid]; });
poly.on('add', function() { poly.on('add', function() {
// enable for debugging
if(window.fields[this.options.guid]) console.warn('duplicate field detected');
window.fields[this.options.guid] = this; window.fields[this.options.guid] = this;
this.bringToBack(); this.bringToBack();
}); });
poly.addTo(fieldsLayer); poly.addTo(fieldsLayer);
} }
// looks for the GUID in either the layerGroup or entityHash, depending
// on which is faster. Will either return the Leaflet entity or null, if
// it does not exist.
// For example, to find a field use the function like this:
// field = findEntityInLeaflet(fieldsLayer, fields, 'asdasdasd');
window.findEntityInLeaflet = function(layerGroup, entityHash, guid) {
// fast way
if(map.hasLayer(layerGroup)) return entityHash[guid] || null;
// slow way in case the layer is currently hidden
var ent = null;
layerGroup.eachLayer(function(entity) {
if(entity.options.guid !== guid) return true;
ent = entity;
return false;
});
return ent;
}