1
0
forked from 0ad/0ad

Modified caching behavior to work similarly to how k776 suggested. Also added modification level affects as also suggested by k776.

This was SVN commit r11604.
This commit is contained in:
Jonathan Waller 2012-04-21 16:37:35 +00:00
parent 9488ca42f6
commit 96549e0418
4 changed files with 87 additions and 152 deletions

View File

@ -49,45 +49,21 @@ Armour.prototype.TakeDamage = function(hack, pierce, crush)
Armour.prototype.GetArmourStrengths = function()
{
if (!this.armourCache)
// Work out the armour values with technology effects
var self = this;
var cmpTechMan = QueryOwnerInterface(this.entity, IID_TechnologyManager);
var applyTechs = function(type)
{
// Work out the armour values with technology effects
var self = this;
var cmpTechMan = QueryOwnerInterface(this.entity, IID_TechnologyManager);
var applyTechs = function(type)
{
var allComponent = cmpTechMan.ApplyModifications("Armour/All", +self.template[type], self.entity) - self.template[type];
return allComponent + cmpTechMan.ApplyModifications("Armour/" + type, +self.template[type], self.entity);
};
this.armourCache = {
hack: applyTechs("Hack"),
pierce: applyTechs("Pierce"),
crush: applyTechs("Crush")
};
}
var allComponent = cmpTechMan.ApplyModifications("Armour/All", +self.template[type], self.entity) - self.template[type];
return allComponent + cmpTechMan.ApplyModifications("Armour/" + type, +self.template[type], self.entity);
};
return this.armourCache;
};
// Remove any cached template data which is based on technology data
Armour.prototype.OnTechnologyModificationChange = function(msg)
{
var cmpOwnership = Engine.QueryInterface(this.entity, IID_Ownership);
if (!cmpOwnership)
return;
var player = cmpOwnership.GetOwner();
if (msg.component === "Armour" && msg.player === player)
delete this.armourCache;
};
// Remove any cached template data which is based on technology data
Armour.prototype.OnOwnershipChanged = function(msg)
{
delete this.armourCache;
return {
hack: applyTechs("Hack"),
pierce: applyTechs("Pierce"),
crush: applyTechs("Crush")
};
};
Engine.RegisterComponentType(IID_DamageReceiver, "Armour", Armour);

View File

@ -136,91 +136,41 @@ Attack.prototype.GetBestAttack = function()
Attack.prototype.GetTimers = function(type)
{
if (!this.attackCache)
this.attackCache = {};
if (!this.attackCache.Timers)
this.attackCache.Timers = {};
var cmpTechMan = QueryOwnerInterface(this.entity, IID_TechnologyManager);
if (!this.attackCache.Timers[type]){
var cmpTechMan = QueryOwnerInterface(this.entity, IID_TechnologyManager);
var prepare = cmpTechMan.ApplyModifications("Attack/" + type + "/PrepareTime", +(this.template[type].PrepareTime||0), this.entity);
var repeat = cmpTechMan.ApplyModifications("Attack/" + type + "/RepeatTime", +(this.template[type].RepeatTime||1000), this.entity);
this.attackCache.Timers[type] = { "prepare": prepare, "repeat": repeat, "recharge": repeat - prepare };
}
var prepare = cmpTechMan.ApplyModifications("Attack/" + type + "/PrepareTime", +(this.template[type].PrepareTime||0), this.entity);
var repeat = cmpTechMan.ApplyModifications("Attack/" + type + "/RepeatTime", +(this.template[type].RepeatTime||1000), this.entity);
return this.attackCache.Timers[type];
return { "prepare": prepare, "repeat": repeat, "recharge": repeat - prepare };
};
Attack.prototype.GetAttackStrengths = function(type)
{
if (!this.attackCache)
this.attackCache = {};
// Work out the attack values with technology effects
var self = this;
if (!this.attackCache.Strengths)
this.attackCache.Strengths = {};
if (!this.attackCache.Strengths[type])
var cmpTechMan = QueryOwnerInterface(this.entity, IID_TechnologyManager);
var applyTechs = function(damageType)
{
// Work out the attack values with technology effects
var self = this;
var cmpTechMan = QueryOwnerInterface(this.entity, IID_TechnologyManager);
var applyTechs = function(damageType)
{
var allComponent = cmpTechMan.ApplyModifications("Attack/" + type + "/All", (+self.template[type][damageType] || 0), self.entity) - self.template[type][damageType];
return allComponent + cmpTechMan.ApplyModifications("Attack/" + type + "/" + damageType, (+self.template[type][damageType] || 0), self.entity);
};
this.attackCache.Strengths[type] = {
hack: applyTechs("Hack"),
pierce: applyTechs("Pierce"),
crush: applyTechs("Crush")
};
}
var allComponent = cmpTechMan.ApplyModifications("Attack/" + type + "/All", (+self.template[type][damageType] || 0), self.entity) - self.template[type][damageType];
return allComponent + cmpTechMan.ApplyModifications("Attack/" + type + "/" + damageType, (+self.template[type][damageType] || 0), self.entity);
};
return this.attackCache.Strengths[type];
return {
hack: applyTechs("Hack"),
pierce: applyTechs("Pierce"),
crush: applyTechs("Crush")
};
};
Attack.prototype.GetRange = function(type)
{
if (!this.attackCache)
this.attackCache = {};
if (!this.attackCache.Range)
this.attackCache.Range = {};
var cmpTechMan = QueryOwnerInterface(this.entity, IID_TechnologyManager);
if (!this.attackCache.Range[type]){
var cmpTechMan = QueryOwnerInterface(this.entity, IID_TechnologyManager);
var max = cmpTechMan.ApplyModifications("Attack/" + type + "/MaxRange", +this.template[type].MaxRange, this.entity);
var min = cmpTechMan.ApplyModifications("Attack/" + type + "/MinRange", +(this.template[type].MinRange || 0), this.entity);
this.attackCache.Range[type] = { "max": max, "min": min };
}
var max = cmpTechMan.ApplyModifications("Attack/" + type + "/MaxRange", +this.template[type].MaxRange, this.entity);
var min = cmpTechMan.ApplyModifications("Attack/" + type + "/MinRange", +(this.template[type].MinRange || 0), this.entity);
return this.attackCache.Range[type];
};
// Remove any cached template data which is based on technology data
Attack.prototype.OnTechnologyModificationChange = function(msg)
{
var cmpOwnership = Engine.QueryInterface(this.entity, IID_Ownership);
if (!cmpOwnership)
return;
var player = cmpOwnership.GetOwner();
if (msg.component === "Attack" && msg.player === player)
delete this.attackCache;
};
// Remove any cached template data which is based on technology data
Attack.prototype.OnOwnershipChanged = function(msg)
{
delete this.attackCache;
return { "max": max, "min": min };
};
// Calculate the attack damage multiplier against a target

View File

@ -125,60 +125,34 @@ ResourceGatherer.prototype.GetLastCarriedType = function()
return undefined;
};
// Remove any cached template data which is based on technology data
ResourceGatherer.prototype.OnTechnologyModificationChange = function(msg)
{
var cmpOwnership = Engine.QueryInterface(this.entity, IID_Ownership);
if (!cmpOwnership)
return;
var player = cmpOwnership.GetOwner();
if (msg.component === "ResourceGatherer" && msg.player === player)
{
delete this.gatherRatesCache;
delete this.capacitiesCache;
}
};
// Remove any cached template data which is based on technology data
ResourceGatherer.prototype.OnOwnershipChanged = function(msg)
{
delete this.gatherRatesCache;
delete this.capacitiesCache;
};
ResourceGatherer.prototype.GetGatherRates = function()
{
if (!this.gatherRatesCache)
var ret = {};
var cmpTechMan = QueryOwnerInterface(this.entity, IID_TechnologyManager);
var baseSpeed = cmpTechMan.ApplyModifications("ResourceGatherer/BaseSpeed", this.template.BaseSpeed, this.entity);
for (var r in this.template.Rates)
{
this.gatherRatesCache = {};
var cmpTechMan = QueryOwnerInterface(this.entity, IID_TechnologyManager);
var baseSpeed = cmpTechMan.ApplyModifications("ResourceGatherer/BaseSpeed", this.template.BaseSpeed, this.entity);
for (var r in this.template.Rates)
{
var rate = cmpTechMan.ApplyModifications("ResourceGatherer/Rates/" + r, this.template.Rates[r], this.entity);
this.gatherRatesCache[r] = rate * baseSpeed;
}
var rate = cmpTechMan.ApplyModifications("ResourceGatherer/Rates/" + r, this.template.Rates[r], this.entity);
ret[r] = rate * baseSpeed;
}
return this.gatherRatesCache;
return ret;
};
ResourceGatherer.prototype.GetCapacities = function()
{
if (!this.capacitiesCache)
var ret = {};
var cmpTechMan = QueryOwnerInterface(this.entity, IID_TechnologyManager);
for (var r in this.template.Capacities)
{
this.capacitiesCache = {};
var cmpTechMan = QueryOwnerInterface(this.entity, IID_TechnologyManager);
for (var r in this.template.Capacities)
{
this.capacitiesCache[r] = cmpTechMan.ApplyModifications("ResourceGatherer/Capacities/" + r, this.template.Capacities[r], this.entity);
}
ret[r] = cmpTechMan.ApplyModifications("ResourceGatherer/Capacities/" + r, this.template.Capacities[r], this.entity);
}
return this.capacitiesCache;
return ret;
};
ResourceGatherer.prototype.GetRange = function()

View File

@ -16,6 +16,9 @@ TechnologyManager.prototype.Init = function ()
// {"add": 2}
// ]}
this.modifications = {};
this.modificationCache = {}; // Caches the values after technologies have been applied
// e.g. { "Attack/Melee/Hack" : {5: 10, 7: 12, ...}, ...}
// where 5 and 7 are entity id's
this.typeCounts = {}; // stores the number of entities of each type
this.classCounts = {}; // stores the number of entities of each Class
@ -190,6 +193,8 @@ TechnologyManager.prototype.OnGlobalOwnershipChanged = function (msg)
delete this.typeCountsByClass[classes[i]][template];
}
}
this.clearModificationCache(msg.entity);
}
};
@ -232,14 +237,23 @@ TechnologyManager.prototype.ResearchTechnology = function (tech)
if (!this.modifications[modification.value])
this.modifications[modification.value] = [];
var mod = {"affects": affects};
var modAffects = [];
if (modification.affects)
{
for (var j in modification.affects)
modAffects.push(modification.affects[j].split(/\s+/));
}
var mod = {"affects": affects.concat(modAffects)};
// copy the modification data into our new data structure
for (var j in modification)
if (j !== "value")
if (j !== "value" && j !== "affects")
mod[j] = modification[j];
this.modifications[modification.value].push(mod);
modifiedComponents[modification.value.split("/")[0]] = true;
this.modificationCache[modification.value] = {};
}
}
@ -252,8 +266,29 @@ TechnologyManager.prototype.ResearchTechnology = function (tech)
this.UpdateAutoResearch();
};
// Clears the cached data for an entity from the modifications cache
TechnologyManager.prototype.clearModificationCache = function(ent)
{
for (var valueName in this.modificationCache)
delete this.modificationCache[valueName][ent];
};
// Caching layer in front of ApplyModificationsWorker
TechnologyManager.prototype.ApplyModifications = function(valueName, curValue, ent)
{
{
if (!this.modificationCache[valueName])
this.modificationCache[valueName] = {};
if (!this.modificationCache[valueName][ent])
this.modificationCache[valueName][ent] = this.ApplyModificationsWorker(valueName, curValue, ent);
return this.modificationCache[valueName][ent];
}
// The code to actually apply the modification
TechnologyManager.prototype.ApplyModificationsWorker = function(valueName, curValue, ent)
{
// Get all modifications to this value
var modifications = this.modifications[valueName];
if (!modifications) // no modifications so return the original value