Slightly improve fogging performance by avoiding the constant deletion/re-creation of mirages.

This makes the simulation update faster per entity but also makes the
number of entities greater at a given moment. The performance gain is
positive.

This was SVN commit r15956.
This commit is contained in:
Itms 2014-11-12 15:56:45 +00:00
parent 7130997df9
commit 9ad2fc9fac
5 changed files with 40 additions and 43 deletions

View file

@ -251,7 +251,9 @@ EntitySelection.prototype.update = function()
}
// Remove non-visible units (e.g. moved back into fog-of-war)
if (entState.visibility == "hidden")
// At the next update, mirages will be renamed to the real
// entity they replace, so just ignore them now
if (entState.visibility == "hidden" && !entState.mirage)
{
// Disable any highlighting of the disappeared unit
_setHighlight([ent], 0, false);

View file

@ -11,31 +11,30 @@ Fogging.prototype.Schema =
Fogging.prototype.Init = function()
{
this.mirages = [];
this.miraged = [];
this.seen = [];
var cmpPlayerManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_PlayerManager);
for (var player = 0; player < cmpPlayerManager.GetNumPlayers(); ++player)
{
this.mirages.push(INVALID_ENTITY);
this.miraged.push(false);
this.seen.push(false);
}
};
Fogging.prototype.LoadMirage = function(player)
{
var cmpTemplateManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_TemplateManager);
var templateName = "mirage|" + cmpTemplateManager.GetCurrentTemplateName(this.entity);
// If this is an entity without visibility (e.g. a foundation), it should be
// marked as seen for its owner
var cmpParentOwnership = Engine.QueryInterface(this.entity, IID_Ownership);
if (cmpParentOwnership && cmpParentOwnership.GetOwner() == player)
this.seen[player] = true;
this.miraged[player] = true;
if (!this.seen[player] || this.mirages[player] != INVALID_ENTITY)
return;
if (this.mirages[player] == INVALID_ENTITY)
{
var cmpTemplateManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_TemplateManager);
var templateName = "mirage|" + cmpTemplateManager.GetCurrentTemplateName(this.entity);
this.mirages[player] = Engine.AddEntity(templateName);
}
this.mirages[player] = Engine.AddEntity(templateName);
var cmpMirage = Engine.QueryInterface(this.mirages[player], IID_Mirage);
if (!cmpMirage)
{
@ -44,15 +43,16 @@ Fogging.prototype.LoadMirage = function(player)
return;
}
// Setup basic mirage properties
// Copy basic mirage properties
cmpMirage.SetPlayer(player);
cmpMirage.SetParent(this.entity);
// Copy cmpOwnership data
var cmpParentOwnership = Engine.QueryInterface(this.entity, IID_Ownership);
var cmpMirageOwnership = Engine.QueryInterface(this.mirages[player], IID_Ownership);
if (!cmpParentOwnership || !cmpMirageOwnership)
{
error("Failed to setup the ownership data of the fogged entity " + templateName);
error("Failed to copy the ownership data of the fogged entity " + templateName);
return;
}
cmpMirageOwnership.SetOwner(cmpParentOwnership.GetOwner());
@ -62,7 +62,7 @@ Fogging.prototype.LoadMirage = function(player)
var cmpMiragePosition = Engine.QueryInterface(this.mirages[player], IID_Position);
if (!cmpParentPosition || !cmpMiragePosition)
{
error("Failed to setup the position data of the fogged entity " + templateName);
error("Failed to copy the position data of the fogged entity " + templateName);
return;
}
if (!cmpParentPosition.IsInWorld())
@ -78,7 +78,7 @@ Fogging.prototype.LoadMirage = function(player)
var cmpMirageVisualActor = Engine.QueryInterface(this.mirages[player], IID_Visual);
if (!cmpParentVisualActor || !cmpMirageVisualActor)
{
error("Failed to setup the visual data of the fogged entity " + templateName);
error("Failed to copy the visual data of the fogged entity " + templateName);
return;
}
cmpMirageVisualActor.SetActorSeed(cmpParentVisualActor.GetActorSeed());
@ -86,11 +86,11 @@ Fogging.prototype.LoadMirage = function(player)
// Store valuable information into the mirage component (especially for the GUI)
var cmpFoundation = Engine.QueryInterface(this.entity, IID_Foundation);
if (cmpFoundation)
cmpMirage.AddFoundation(cmpFoundation.GetBuildPercentage());
cmpMirage.CopyFoundation(cmpFoundation.GetBuildPercentage());
var cmpHealth = Engine.QueryInterface(this.entity, IID_Health);
if (cmpHealth)
cmpMirage.AddHealth(
cmpMirage.CopyHealth(
cmpHealth.GetMaxHitpoints(),
cmpHealth.GetHitpoints(),
cmpHealth.IsRepairable() && (cmpHealth.GetHitpoints() < cmpHealth.GetMaxHitpoints())
@ -98,7 +98,7 @@ Fogging.prototype.LoadMirage = function(player)
var cmpResourceSupply = Engine.QueryInterface(this.entity, IID_ResourceSupply);
if (cmpResourceSupply)
cmpMirage.AddResourceSupply(
cmpMirage.CopyResourceSupply(
cmpResourceSupply.GetMaxAmount(),
cmpResourceSupply.GetCurrentAmount(),
cmpResourceSupply.GetType(),
@ -121,7 +121,7 @@ Fogging.prototype.IsMiraged = function(player)
if (player >= this.mirages.length)
return false;
return this.mirages[player] != INVALID_ENTITY;
return this.miraged[player];
};
Fogging.prototype.GetMirage = function(player)
@ -147,17 +147,10 @@ Fogging.prototype.OnVisibilityChanged = function(msg)
if (msg.newVisibility == VIS_VISIBLE)
{
this.miraged[msg.player] = false;
this.seen[msg.player] = true;
// Destroy mirages when we get back into LoS
if (this.mirages[msg.player] != INVALID_ENTITY)
{
Engine.DestroyEntity(this.mirages[msg.player]);
this.mirages[msg.player] = INVALID_ENTITY;
}
}
// Intermediate LoS state, meaning we must create a mirage
if (msg.newVisibility == VIS_FOGGED)
this.LoadMirage(msg.player);
};

View file

@ -194,6 +194,7 @@ GuiInterface.prototype.GetEntityState = function(player, ent)
"garrisonHolder": null,
"gate": null,
"guard": null,
"mirage": null,
"pack": null,
"player": -1,
"position": null,
@ -206,8 +207,9 @@ GuiInterface.prototype.GetEntityState = function(player, ent)
"visibility": null,
};
// Used for several components
var cmpMirage = Engine.QueryInterface(ent, IID_Mirage);
if (cmpMirage)
ret.mirage = true;
var cmpIdentity = Engine.QueryInterface(ent, IID_Identity);
if (cmpIdentity)
@ -386,7 +388,6 @@ GuiInterface.prototype.GetExtendedEntityState = function(player, ent)
"barterMarket": null,
"buildingAI": null,
"healer": null,
"mirage": null,
"obstruction": null,
"turretParent":null,
"promotion": null,
@ -396,8 +397,6 @@ GuiInterface.prototype.GetExtendedEntityState = function(player, ent)
};
var cmpMirage = Engine.QueryInterface(ent, IID_Mirage);
if (cmpMirage)
ret.mirage = true;
var cmpIdentity = Engine.QueryInterface(ent, IID_Identity);

View file

@ -48,7 +48,7 @@ Mirage.prototype.SetPlayer = function(player)
// Foundation data
Mirage.prototype.AddFoundation = function(buildPercentage)
Mirage.prototype.CopyFoundation = function(buildPercentage)
{
this.foundation = true;
this.buildPercentage = buildPercentage;
@ -66,7 +66,7 @@ Mirage.prototype.GetBuildPercentage = function()
// Health data
Mirage.prototype.AddHealth = function(maxHitpoints, hitpoints, needsRepair)
Mirage.prototype.CopyHealth = function(maxHitpoints, hitpoints, needsRepair)
{
this.health = true;
this.maxHitpoints = maxHitpoints;
@ -96,7 +96,7 @@ Mirage.prototype.NeedsRepair = function()
// ResourceSupply data
Mirage.prototype.AddResourceSupply = function(maxAmount, amount, type, isInfinite)
Mirage.prototype.CopyResourceSupply = function(maxAmount, amount, type, isInfinite)
{
this.resourceSupply = true;
this.maxAmount = maxAmount;
@ -134,16 +134,13 @@ Mirage.prototype.IsInfinite = function()
Mirage.prototype.OnVisibilityChanged = function(msg)
{
if (msg.player == this.player && msg.newVisibility == VIS_VISIBLE && this.parent == INVALID_ENTITY)
Engine.DestroyEntity(this.entity);
};
Mirage.prototype.OnDestroy = function(msg)
{
if (this.parent == INVALID_ENTITY)
if (msg.player != this.player || msg.newVisibility != VIS_HIDDEN)
return;
Engine.BroadcastMessage(MT_EntityRenamed, { entity: this.entity, newentity: this.parent });
if (this.parent == INVALID_ENTITY)
Engine.DestroyEntity(this.entity);
else
Engine.BroadcastMessage(MT_EntityRenamed, { entity: this.entity, newentity: this.parent });
};
Engine.RegisterComponentType(IID_Mirage, "Mirage", Mirage);

View file

@ -20,7 +20,13 @@ Visibility.prototype.Init = function()
Visibility.prototype.GetLosVisibility = function(player, isOutsideFog, forceRetainInFog)
{
if (isOutsideFog)
{
var cmpMirage = Engine.QueryInterface(this.entity, IID_Mirage);
if (cmpMirage)
return VIS_HIDDEN;
return VIS_VISIBLE;
}
// Fogged if the 'retain in fog' flag is set, and in a non-visible explored region
var cmpVision = Engine.QueryInterface(this.entity, IID_Vision);