Replace DataTemplateManager simulation component with a globalscript, refs #4868.

Removes the serialization of JSON files, shrinking savegame files and
rejoin states sent across the network, refs #3834, #4239, #3909,
f24523dc8f.
Removes the AI C++ code to read JSON files from e33d4a52e9 since the AI
can now use the globalscript.
Allows the AI to read Aura templates and removal of GUIInterface code to
improve performance.
Serialization of the JSON objects in other simulation components was
removed in 9c0e37f2c0 / D1109, a6f14f5631 / D1130.

Serialization removal planned by sanderd17
AI part proofread by mimo
Simulation part proofread by bb
Discussed with Itms on irc

Differential Revision: https://code.wildfiregames.com/D1108
This was SVN commit r20737.
This commit is contained in:
elexis 2017-12-31 01:02:21 +00:00
parent 1162eefdc2
commit c90d72deb5
21 changed files with 144 additions and 310 deletions

View file

@ -0,0 +1,45 @@
/**
* @file This provides a cache for Aura and Technology templates.
* They may not be serialized, otherwise rejoined clients would refer
* to different objects, triggering an Out-of-sync error.
*/
function ModificationTemplates(path)
{
let suffix = ".json";
this.names = deepfreeze(listFiles(path, suffix, true));
this.templates = {};
for (let name of this.names)
this.templates[name] = Engine.ReadJSONFile(path + name + suffix);
deepfreeze(this.templates);
}
ModificationTemplates.prototype.GetNames = function()
{
return this.names;
};
ModificationTemplates.prototype.Has = function(name)
{
return this.names.indexOf(name) != -1;
};
ModificationTemplates.prototype.Get = function(name)
{
return this.templates[name];
};
ModificationTemplates.prototype.GetAll = function()
{
return this.templates;
};
function LoadModificationTemplates()
{
global.AuraTemplates = new ModificationTemplates("simulation/data/auras/");
global.TechnologyTemplates = new ModificationTemplates("simulation/data/technologies/");
}

View file

@ -347,7 +347,7 @@ m.Template = m.Class({
if (tech.indexOf("{civ}") == -1)
continue;
let civTech = tech.replace("{civ}", civ);
techs[i] = gameState.techTemplates[civTech] ?
techs[i] = TechnologyTemplates.Has(civTech) ?
civTech : tech.replace("{civ}", "generic");
}
return techs;

View file

@ -9,13 +9,13 @@ m.GameState = function() {
this.ai = null; // must be updated by the AIs.
};
m.GameState.prototype.init = function(SharedScript, state, player) {
m.GameState.prototype.init = function(SharedScript, state, player)
{
this.sharedScript = SharedScript;
this.EntCollecNames = SharedScript._entityCollectionsName;
this.timeElapsed = SharedScript.timeElapsed;
this.circularMap = SharedScript.circularMap;
this.templates = SharedScript._templates;
this.techTemplates = SharedScript._techTemplates;
this.entities = SharedScript.entities;
this.player = player;
this.playerData = SharedScript.playersData[this.player];
@ -150,8 +150,8 @@ m.GameState.prototype.isCeasefireActive = function()
m.GameState.prototype.getTemplate = function(type)
{
if (this.techTemplates[type] !== undefined)
return new m.Technology(this.techTemplates, type);
if (TechnologyTemplates.Has(type))
return new m.Technology(type);
if (this.templates[type] === undefined)
this.sharedScript.GetTemplate(type);

View file

@ -9,7 +9,6 @@ m.SharedScript = function(settings)
this._players = Object.keys(settings.players).map(key => settings.players[key]); // TODO SM55 Object.values(settings.players)
this._templates = settings.templates;
this._techTemplates = settings.techTemplates;
this._entityMetadata = {};
for (let player of this._players)
@ -30,7 +29,6 @@ m.SharedScript.prototype.Serialize = function()
{
return {
"players": this._players,
"techTemplates": this._techTemplates,
"templatesModifications": this._templatesModifications,
"entitiesModifications": this._entitiesModifications,
"metadata": this._entityMetadata
@ -44,7 +42,6 @@ m.SharedScript.prototype.Serialize = function()
m.SharedScript.prototype.Deserialize = function(data)
{
this._players = data.players;
this._techTemplates = data.techTemplates;
this._templatesModifications = data.templatesModifications;
this._entitiesModifications = data.entitiesModifications;
this._entityMetadata = data.metadata;

View file

@ -1,26 +1,26 @@
LoadModificationTemplates();
var API3 = function(m)
{
/** Wrapper around a technology template */
m.Technology = function(allTemplates, templateName)
m.Technology = function(templateName)
{
this._templateName = templateName;
let template = allTemplates[templateName];
let template = TechnologyTemplates.Get(templateName);
// check if this is one of two paired technologies.
this._isPair = template.pair !== undefined;
if (this._isPair)
{
if (allTemplates[template.pair].top == templateName)
this._pairedWith = allTemplates[template.pair].bottom;
else
this._pairedWith = allTemplates[template.pair].top;
let pairTech = TechnologyTemplates.Get(template.pair);
this._pairedWith = pairTech.top == templateName ? pairTech.bottom : pairTech.top;
}
// check if it only defines a pair:
this._definesPair = template.top !== undefined;
this._template = template;
this._techTemplates = allTemplates;
};
/** returns generic, or specific if civ provided. */
@ -45,10 +45,10 @@ m.Technology.prototype.getPairedTechs = function()
if (!this._definesPair)
return undefined;
let techOne = new m.Technology(this._techTemplates, this._template.top);
let techTwo = new m.Technology(this._techTemplates, this._template.bottom);
return [techOne,techTwo];
return [
new m.Technology(this._template.top),
new m.Technology(this._template.bottom)
];
};
m.Technology.prototype.pair = function()

View file

@ -8,14 +8,11 @@ Auras.prototype.Schema =
Auras.prototype.Init = function()
{
let cmpDataTemplateManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_DataTemplateManager);
this.auras = {};
this.affectedPlayers = {};
for (let name of this.GetAuraNames())
{
this.affectedPlayers[name] = [];
this.auras[name] = cmpDataTemplateManager.GetAuraTemplate(name);
}
// In case of autogarrisoning, this component can be called before ownership is set.
// So it needs to be completely initialised from the start.
this.Clean();
@ -24,7 +21,7 @@ Auras.prototype.Init = function()
// We can modify identifier if we want stackable auras in some case.
Auras.prototype.GetModifierIdentifier = function(name)
{
if (this.auras[name].stackable)
if (AuraTemplates.Get(name).stackable)
return name + this.entity;
return name;
};
@ -34,7 +31,7 @@ Auras.prototype.GetDescriptions = function()
var ret = {};
for (let auraID of this.GetAuraNames())
{
let aura = this.auras[auraID];
let aura = AuraTemplates.Get(auraID);
ret[auraID] = {
"name": aura.auraName,
"description": aura.auraDescription || null,
@ -51,7 +48,7 @@ Auras.prototype.GetAuraNames = function()
Auras.prototype.GetOverlayIcon = function(name)
{
return this.auras[name].overlayIcon || "";
return AuraTemplates.Get(name).overlayIcon || "";
};
Auras.prototype.GetAffectedEntities = function(name)
@ -62,18 +59,18 @@ Auras.prototype.GetAffectedEntities = function(name)
Auras.prototype.GetRange = function(name)
{
if (this.IsRangeAura(name))
return +this.auras[name].radius;
return +AuraTemplates.Get(name).radius;
return undefined;
};
Auras.prototype.GetClasses = function(name)
{
return this.auras[name].affects;
return AuraTemplates.Get(name).affects;
};
Auras.prototype.GetModifications = function(name)
{
return this.auras[name].modifications;
return AuraTemplates.Get(name).modifications;
};
Auras.prototype.GetAffectedPlayers = function(name)
@ -90,13 +87,15 @@ Auras.prototype.GetRangeOverlays = function()
if (!this.IsRangeAura(name) || !this[name].isApplied)
continue;
let rangeOverlay = AuraTemplates.Get(name).rangeOverlay;
rangeOverlays.push(
this.auras[name].rangeOverlay ?
rangeOverlay ?
{
"radius": this.GetRange(name),
"texture": this.auras[name].rangeOverlay.lineTexture,
"textureMask": this.auras[name].rangeOverlay.lineTextureMask,
"thickness": this.auras[name].rangeOverlay.lineThickness
"texture": rangeOverlay.lineTexture,
"textureMask": rangeOverlay.lineTextureMask,
"thickness": rangeOverlay.lineThickness
} :
// Specify default in order not to specify it in about 40 auras
{
@ -112,7 +111,7 @@ Auras.prototype.GetRangeOverlays = function()
Auras.prototype.CalculateAffectedPlayers = function(name)
{
var affectedPlayers = this.auras[name].affectedPlayers || ["Player"];
var affectedPlayers = AuraTemplates.Get(name).affectedPlayers || ["Player"];
this.affectedPlayers[name] = [];
var cmpPlayer = Engine.QueryInterface(this.entity, IID_Player);
@ -137,12 +136,14 @@ Auras.prototype.CalculateAffectedPlayers = function(name)
Auras.prototype.CanApply = function(name)
{
if (!this.auras[name].requiredTechnology)
if (!AuraTemplates.Get(name).requiredTechnology)
return true;
let cmpTechnologyManager = QueryOwnerInterface(this.entity, IID_TechnologyManager);
if (!cmpTechnologyManager)
return false;
return cmpTechnologyManager.IsTechnologyResearched(this.auras[name].requiredTechnology);
return cmpTechnologyManager.IsTechnologyResearched(AuraTemplates.Get(name).requiredTechnology);
};
Auras.prototype.HasFormationAura = function()
@ -162,7 +163,7 @@ Auras.prototype.HasGarrisonedUnitsAura = function()
Auras.prototype.GetType = function(name)
{
return this.auras[name].type;
return AuraTemplates.Get(name).type;
};
Auras.prototype.IsFormationAura = function(name)
@ -470,7 +471,7 @@ Auras.prototype.OnGlobalResearchFinished = function(msg)
return;
for (let name of this.GetAuraNames())
{
let requiredTech = this.auras[name].requiredTechnology;
let requiredTech = AuraTemplates.Get(name).requiredTechnology;
if (requiredTech && requiredTech == msg.tech)
{
this.Clean();

View file

@ -1,71 +0,0 @@
/**
* System component which loads the technology and the aura data files
*/
function DataTemplateManager() {}
DataTemplateManager.prototype.Schema =
"<a:component type='system'/><empty/>";
DataTemplateManager.prototype.Init = function()
{
this.technologiesPath = "simulation/data/technologies/";
this.aurasPath = "simulation/data/auras/";
this.allTechs = {};
this.allAuras = {};
for (let techName of this.ListAllTechs())
this.GetTechnologyTemplate(techName);
for (let auraName of this.ListAllAuras())
this.GetAuraTemplate(auraName);
deepfreeze(this.allTechs);
deepfreeze(this.allAuras);
};
DataTemplateManager.prototype.GetTechnologyTemplate = function(template)
{
if (!this.allTechs[template])
{
this.allTechs[template] = Engine.ReadJSONFile(this.technologiesPath + template + ".json");
if (!this.allTechs[template])
error("Failed to load technology \"" + template + "\"");
}
return this.allTechs[template];
};
DataTemplateManager.prototype.GetAuraTemplate = function(template)
{
if (!this.allAuras[template])
{
this.allAuras[template] = Engine.ReadJSONFile(this.aurasPath + template + ".json");
if (!this.allAuras[template])
error("Failed to load aura \"" + template + "\"");
}
return this.allAuras[template];
};
DataTemplateManager.prototype.ListAllTechs = function()
{
return listFiles(this.technologiesPath, ".json", true);
};
DataTemplateManager.prototype.ListAllAuras = function()
{
return listFiles(this.aurasPath, ".json", true);
};
DataTemplateManager.prototype.GetAllTechs = function()
{
return this.allTechs;
};
DataTemplateManager.prototype.TechnologyExists = function(template)
{
return !!this.allTechs[template];
};
Engine.RegisterSystemComponentType(IID_DataTemplateManager, "DataTemplateManager", DataTemplateManager);

View file

@ -643,26 +643,17 @@ GuiInterface.prototype.GetTemplateData = function(player, name)
if (!template.Auras)
return GetTemplateDataHelper(template, player, aurasTemplate, Resources, DamageTypes);
// Add aura name and description loaded from JSON file
let auraNames = template.Auras._string.split(/\s+/);
let cmpDataTemplateManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_DataTemplateManager);
for (let name of auraNames)
aurasTemplate[name] = cmpDataTemplateManager.GetAuraTemplate(name);
aurasTemplate[name] = AuraTemplates.Get(name);
return GetTemplateDataHelper(template, player, aurasTemplate, Resources, DamageTypes);
};
GuiInterface.prototype.GetTechnologyData = function(player, data)
{
let cmpDataTemplateManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_DataTemplateManager);
let template = cmpDataTemplateManager.GetTechnologyTemplate(data.name);
if (!template)
{
warn("Tried to get data for invalid technology: " + data.name);
return null;
}
return GetTechnologyDataHelper(template, data.civ, Resources);
return GetTechnologyDataHelper(TechnologyTemplates.Get(data.name), data.civ, Resources);
};
GuiInterface.prototype.IsTechnologyResearched = function(player, data)

View file

@ -163,22 +163,20 @@ ProductionQueue.prototype.GetTechnologiesList = function()
var techs = string.split(/\s+/);
// Replace the civ specific technologies
let cmpDataTemplateManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_DataTemplateManager);
for (let i = 0; i < techs.length; ++i)
{
let tech = techs[i];
if (tech.indexOf("{civ}") == -1)
continue;
let civTech = tech.replace("{civ}", cmpPlayer.GetCiv());
techs[i] = cmpDataTemplateManager.TechnologyExists(civTech) ?
civTech : tech.replace("{civ}", "generic");
techs[i] = TechnologyTemplates.Has(civTech) ? civTech : tech.replace("{civ}", "generic");
}
// Remove any technologies that can't be researched by this civ
techs = techs.filter(tech => {
let reqs = DeriveTechnologyRequirements(cmpTechnologyManager.GetTechnologyTemplate(tech), cmpPlayer.GetCiv());
return cmpTechnologyManager.CheckTechnologyRequirements(reqs, true);
});
techs = techs.filter(tech =>
cmpTechnologyManager.CheckTechnologyRequirements(
DeriveTechnologyRequirements(TechnologyTemplates.Get(tech), cmpPlayer.GetCiv()),
true));
var techList = [];
var superseded = {}; // Stores the tech which supersedes the key
@ -192,7 +190,8 @@ ProductionQueue.prototype.GetTechnologiesList = function()
var tech = techs[i];
if (disabledTechnologies && disabledTechnologies[tech])
continue;
var template = cmpTechnologyManager.GetTechnologyTemplate(tech);
let template = TechnologyTemplates.Get(tech);
if (!template.supersedes || techs.indexOf(template.supersedes) === -1)
techList.push(tech);
else
@ -223,7 +222,7 @@ ProductionQueue.prototype.GetTechnologiesList = function()
continue;
}
var template = cmpTechnologyManager.GetTechnologyTemplate(tech);
let template = TechnologyTemplates.Get(tech);
if (template.top)
ret[i] = {"pair": true, "top": template.top, "bottom": template.bottom};
else
@ -248,7 +247,7 @@ ProductionQueue.prototype.IsTechnologyResearchedOrInProgress = function(tech)
var cmpTechnologyManager = QueryOwnerInterface(this.entity, IID_TechnologyManager);
var template = cmpTechnologyManager.GetTechnologyTemplate(tech);
let template = TechnologyTemplates.Get(tech);
if (template.top)
{
return (cmpTechnologyManager.IsTechnologyResearched(template.top) || cmpTechnologyManager.IsInProgress(template.top)
@ -346,10 +345,7 @@ ProductionQueue.prototype.AddBatch = function(templateName, type, count, metadat
}
else if (type == "technology")
{
// Load the technology template
var cmpDataTemplateManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_DataTemplateManager);
var template = cmpDataTemplateManager.GetTechnologyTemplate(templateName);
if (!template)
if (!TechnologyTemplates.Has(templateName))
return;
if (!this.GetTechnologiesList().some(tech =>
@ -362,6 +358,7 @@ ProductionQueue.prototype.AddBatch = function(templateName, type, count, metadat
return;
}
let template = TechnologyTemplates.Get(templateName);
let techCostMultiplier = this.GetTechCostMultiplier();
let time = techCostMultiplier.time * template.researchTime * cmpPlayer.GetCheatTimeMultiplier();
@ -811,7 +808,7 @@ ProductionQueue.prototype.ProgressTimeout = function(data)
var cmpTechnologyManager = QueryOwnerInterface(this.entity, IID_TechnologyManager);
cmpTechnologyManager.ResearchTechnology(item.technologyTemplate);
var template = cmpTechnologyManager.GetTechnologyTemplate(item.technologyTemplate);
let template = TechnologyTemplates.Get(item.technologyTemplate);
if (template && template.soundComplete)
{

View file

@ -46,8 +46,8 @@ TechnologyManager.prototype.Init = function()
// Some technologies are automatically researched when their conditions are met. They have no cost and are
// researched instantly. This allows civ bonuses and more complicated technologies.
this.unresearchedAutoResearchTechs = new Set();
var allTechs = Engine.QueryInterface(SYSTEM_ENTITY, IID_DataTemplateManager).GetAllTechs();
for (var key in allTechs)
let allTechs = TechnologyTemplates.GetAll();
for (let key in allTechs)
if (allTechs[key].autoResearch || allTechs[key].top)
this.unresearchedAutoResearchTechs.add(key);
};
@ -61,10 +61,9 @@ TechnologyManager.prototype.OnUpdate = function()
// This function checks if the requirements of any autoresearch techs are met and if they are it researches them
TechnologyManager.prototype.UpdateAutoResearch = function()
{
var cmpDataTempMan = Engine.QueryInterface(SYSTEM_ENTITY, IID_DataTemplateManager);
for (let key of this.unresearchedAutoResearchTechs)
{
var tech = cmpDataTempMan.GetTechnologyTemplate(key);
let tech = TechnologyTemplates.Get(key);
if ((tech.autoResearch && this.CanResearch(key))
|| (tech.top && (this.IsTechnologyResearched(tech.top) || this.IsTechnologyResearched(tech.bottom))))
{
@ -75,11 +74,6 @@ TechnologyManager.prototype.UpdateAutoResearch = function()
}
};
TechnologyManager.prototype.GetTechnologyTemplate = function(tech)
{
return Engine.QueryInterface(SYSTEM_ENTITY, IID_DataTemplateManager).GetTechnologyTemplate(tech);
};
// Checks an entity template to see if its technology requirements have been met
TechnologyManager.prototype.CanProduce = function (templateName)
{
@ -110,7 +104,7 @@ TechnologyManager.prototype.IsTechnologyStarted = function(tech)
// Checks the requirements for a technology to see if it can be researched at the current time
TechnologyManager.prototype.CanResearch = function(tech)
{
let template = this.GetTechnologyTemplate(tech);
let template = TechnologyTemplates.Get(tech);
if (!template)
{
@ -270,17 +264,10 @@ TechnologyManager.prototype.ResearchTechnology = function(tech)
{
this.StoppedResearch(tech, false);
var template = this.GetTechnologyTemplate(tech);
if (!template)
{
error("Tried to research invalid technology: " + uneval(tech));
return;
}
var modifiedComponents = {};
this.researchedTechs.add(tech);
// store the modifications in an easy to access structure
let template = TechnologyTemplates.Get(tech);
if (template.modifications)
{
let derivedModifiers = DeriveModificationsFromTech(template);

View file

@ -7,6 +7,22 @@ Engine.LoadComponentScript("interfaces/TechnologyManager.js");
Engine.LoadComponentScript("Auras.js");
Engine.LoadComponentScript("AuraManager.js");
global.AuraTemplates = {
"Get": name => {
let template = {
"type": name,
"affectedPlayers": ["Ally"],
"affects": ["CorrectClass"],
"modifications": [{ "value": "Component/Value", "add": 10 }],
"auraName": "name",
"auraDescription": "description"
};
if (name == "range")
template.radius = auraRange;
return template;
}
};
let playerID = [0, 1, 2];
let playerEnt = [10, 11, 12];
let playerState = "active";
@ -34,22 +50,6 @@ function testAuras(name, test_function)
"GetEntitiesByPlayer": id => [30, 31, 32]
});
AddMock(SYSTEM_ENTITY, IID_DataTemplateManager, {
"GetAuraTemplate": (name) => {
let template = {
"type": name,
"affectedPlayers": ["Ally"],
"affects": ["CorrectClass"],
"modifications": [{ "value": "Component/Value", "add": 10 }],
"auraName": "name",
"auraDescription": "description"
};
if (name == "range")
template.radius = auraRange;
return template;
}
});
AddMock(playerEnt[1], IID_Player, {
"IsAlly": id => id == playerID[1] || id == playerID[2],
"IsEnemy": id => id != playerID[1] || id != playerID[2],

View file

@ -7,6 +7,11 @@ Engine.LoadComponentScript("interfaces/TechnologyManager.js");
Engine.LoadComponentScript("interfaces/ProductionQueue.js");
Engine.LoadComponentScript("ProductionQueue.js");
global.TechnologyTemplates = {
"Has": name => name == "phase_town_athen" || name == "phase_city_athen",
"Get": () => ({})
};
const productionQueueId = 6;
const playerId = 1;
const playerEntityID = 2;
@ -32,10 +37,6 @@ AddMock(SYSTEM_ENTITY, IID_PlayerManager, {
"GetPlayerByID": id => playerEntityID
});
AddMock(SYSTEM_ENTITY, IID_DataTemplateManager, {
"TechnologyExists": name => name == "phase_town_athen" || name == "phase_city_athen"
});
AddMock(playerEntityID, IID_Player, {
"GetCiv": () => "iber",
"GetDisabledTechnologies": () => ({}),
@ -45,7 +46,6 @@ AddMock(playerEntityID, IID_Player, {
AddMock(playerEntityID, IID_TechnologyManager, {
"CheckTechnologyRequirements": () => true,
"GetTechnologyTemplate": tech => tech,
"IsInProgress": () => false,
"IsTechnologyResearched": () => false
});
@ -125,7 +125,6 @@ TS_ASSERT_UNEVAL_EQUALS(cmpProductionQueue.GetTechnologiesList(), ["phase_town_a
AddMock(playerEntityID, IID_TechnologyManager, {
"CheckTechnologyRequirements": () => true,
"GetTechnologyTemplate": tech => tech,
"IsInProgress": () => false,
"IsTechnologyResearched": tech => tech == "phase_town_athen"
});

View file

@ -1,9 +1,9 @@
Engine.LoadComponentScript("interfaces/TechnologyManager.js");
Engine.LoadComponentScript("TechnologyManager.js");
AddMock(SYSTEM_ENTITY, IID_DataTemplateManager, {
"GetAllTechs": () => {}
});
global.TechnologyTemplates = {
"GetAll": () => []
};
let cmpTechnologyManager = ConstructComponent(SYSTEM_ENTITY, "TechnologyManager", {});

View file

@ -88,9 +88,7 @@ function Cheat(input)
else
return;
// check if specialised tech exists (like phase_town_athen)
var cmpDataTemplateManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_DataTemplateManager);
if (cmpDataTemplateManager.ListAllTechs().indexOf(parameter + "_" + cmpPlayer.civ) > -1)
if (TechnologyTemplates.Has(parameter + "_" + cmpPlayer.civ))
parameter += "_" + cmpPlayer.civ;
else
parameter += "_generic";
@ -140,13 +138,8 @@ function Cheat(input)
}
}
// check, if technology exists
var template = cmpTechnologyManager.GetTechnologyTemplate(techname);
if (!template)
return;
// check, if technology is already researched
if (!cmpTechnologyManager.IsTechnologyResearched(techname))
if (TechnologyTemplates.Has(techname) &&
!cmpTechnologyManager.IsTechnologyResearched(techname))
cmpTechnologyManager.ResearchTechnology(techname);
return;
case "metaCheat":

View file

@ -0,0 +1,2 @@
// Loads the Aura and Technology JSON files
LoadModificationTemplates();

View file

@ -97,7 +97,6 @@ bool CMapGeneratorWorker::Run()
// Replace RNG with a seeded deterministic function
m_ScriptInterface->ReplaceNondeterministicRNG(m_MapGenRNG);
m_ScriptInterface->LoadGlobalScripts();
// Functions for RMS
JSI_VFS::RegisterScriptFunctions_Maps(*m_ScriptInterface);
@ -110,6 +109,9 @@ bool CMapGeneratorWorker::Run()
m_ScriptInterface->RegisterFunction<std::vector<std::string>, std::string, bool, CMapGeneratorWorker::FindActorTemplates>("FindActorTemplates");
m_ScriptInterface->RegisterFunction<int, CMapGeneratorWorker::GetTerrainTileSize>("GetTerrainTileSize");
// Globalscripts may use VFS script functions
m_ScriptInterface->LoadGlobalScripts();
// Parse settings
JS::RootedValue settingsVal(cx);
if (!m_ScriptInterface->ParseJSON(m_Settings, &settingsVal) && settingsVal.isUndefined())

View file

@ -165,9 +165,6 @@ COMPONENT(SoundManager)
INTERFACE(ValueModificationManager)
COMPONENT(ValueModificationManagerScripted)
INTERFACE(DataTemplateManager)
COMPONENT(DataTemplateManagerScripted)
INTERFACE(Terrain)
COMPONENT(Terrain)

View file

@ -37,7 +37,6 @@
#include "simulation2/components/ICmpObstructionManager.h"
#include "simulation2/components/ICmpRangeManager.h"
#include "simulation2/components/ICmpTemplateManager.h"
#include "simulation2/components/ICmpDataTemplateManager.h"
#include "simulation2/components/ICmpTerritoryManager.h"
#include "simulation2/helpers/LongPathfinder.h"
#include "simulation2/serialization/DebugSerializer.h"
@ -216,14 +215,12 @@ public:
m_HasSharedComponent(false),
m_SerializablePrototypes(new ObjectIdCache<std::wstring>(g_ScriptRuntime)),
m_EntityTemplates(g_ScriptRuntime->m_rt),
m_TechTemplates(g_ScriptRuntime->m_rt),
m_SharedAIObj(g_ScriptRuntime->m_rt),
m_PassabilityMapVal(g_ScriptRuntime->m_rt),
m_TerritoryMapVal(g_ScriptRuntime->m_rt)
{
m_ScriptInterface->ReplaceNondeterministicRNG(m_RNG);
m_ScriptInterface->LoadGlobalScripts();
m_ScriptInterface->SetCallbackData(static_cast<void*> (this));
@ -240,6 +237,9 @@ public:
m_ScriptInterface->RegisterFunction<CParamNode, std::string, CAIWorker::GetTemplate>("GetTemplate");
JSI_VFS::RegisterScriptFunctions_Simulation(*(m_ScriptInterface.get()));
// Globalscripts may use VFS script functions
m_ScriptInterface->LoadGlobalScripts();
}
~CAIWorker()
@ -400,7 +400,7 @@ public:
m_RNG.seed(seed);
}
bool TryLoadSharedComponent(bool hasTechs)
bool TryLoadSharedComponent()
{
JSContext* cx = m_ScriptInterface->GetContext();
JSAutoRequest rq(cx);
@ -455,18 +455,6 @@ public:
ENSURE(m_HasLoadedEntityTemplates);
m_ScriptInterface->SetProperty(settings, "templates", m_EntityTemplates, false);
if (hasTechs)
{
m_ScriptInterface->SetProperty(settings, "techTemplates", m_TechTemplates, false);
}
else
{
// won't get the tech templates directly.
JS::RootedValue fakeTech(cx);
m_ScriptInterface->Eval("({})", &fakeTech);
m_ScriptInterface->SetProperty(settings, "techTemplates", fakeTech, false);
}
JS::AutoValueVector argv(cx);
argv.append(settings);
m_ScriptInterface->CallConstructor(ctor, argv, &m_SharedAIObj);
@ -627,11 +615,6 @@ public:
}
}
void RegisterTechTemplates(const shared_ptr<ScriptInterface::StructuredClone>& techTemplates)
{
m_ScriptInterface->ReadStructuredClone(techTemplates, &m_TechTemplates);
}
void LoadEntityTemplates(const std::vector<std::pair<std::string, const CParamNode*> >& templates)
{
JSContext* cx = m_ScriptInterface->GetContext();
@ -754,8 +737,7 @@ public:
deserializer.Bool("useSharedScript", m_HasSharedComponent);
if (m_HasSharedComponent)
{
TryLoadSharedComponent(false);
TryLoadSharedComponent();
JS::RootedValue sharedData(cx);
deserializer.ScriptVal("sharedData", &sharedData);
if (!m_ScriptInterface->CallFunctionVoid(m_SharedAIObj, "Deserialize", sharedData))
@ -922,7 +904,6 @@ private:
JS::PersistentRootedValue m_EntityTemplates;
bool m_HasLoadedEntityTemplates;
JS::PersistentRootedValue m_TechTemplates;
std::map<VfsPath, JS::Heap<JS::Value> > m_PlayerMetadata;
std::vector<shared_ptr<CAIPlayer> > m_Players; // use shared_ptr just to avoid copying
@ -1026,19 +1007,7 @@ public:
virtual void TryLoadSharedComponent()
{
const ScriptInterface& scriptInterface = GetSimContext().GetScriptInterface();
JSContext* cx = scriptInterface.GetContext();
JSAutoRequest rq(cx);
// load the technology templates
CmpPtr<ICmpDataTemplateManager> cmpDataTemplateManager(GetSystemEntity());
ENSURE(cmpDataTemplateManager);
JS::RootedValue techTemplates(cx);
cmpDataTemplateManager->GetAllTechs(&techTemplates);
m_Worker.RegisterTechTemplates(scriptInterface.WriteStructuredClone(techTemplates));
m_Worker.TryLoadSharedComponent(true);
m_Worker.TryLoadSharedComponent();
}
virtual void RunGamestateInit()

View file

@ -1,39 +0,0 @@
/* Copyright (C) 2017 Wildfire Games.
* This file is part of 0 A.D.
*
* 0 A.D. is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* 0 A.D. is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
*/
#include "precompiled.h"
#include "ICmpDataTemplateManager.h"
#include "simulation2/system/InterfaceScripted.h"
#include "simulation2/scripting/ScriptComponent.h"
BEGIN_INTERFACE_WRAPPER(DataTemplateManager)
END_INTERFACE_WRAPPER(DataTemplateManager)
class CCmpDataTemplateManagerScripted : public ICmpDataTemplateManager
{
public:
DEFAULT_SCRIPT_WRAPPER(DataTemplateManagerScripted)
virtual void GetAllTechs(JS::MutableHandleValue ret)
{
m_Script.CallRef("GetAllTechs", ret);
}
};
REGISTER_COMPONENT_SCRIPT_WRAPPER(DataTemplateManagerScripted)

View file

@ -1,38 +0,0 @@
/* Copyright (C) 2012 Wildfire Games.
* This file is part of 0 A.D.
*
* 0 A.D. is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* 0 A.D. is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef INCLUDED_ICMPDATATEMPLATEMANAGER
#define INCLUDED_ICMPDATATEMPLATEMANAGER
#include "simulation2/system/Interface.h"
#include "maths/Fixed.h"
/**
* Data template manager interface.
* (This interface only includes the functions needed by native code for accessing
* json template data, the associated logic is handled in scripts)
*/
class ICmpDataTemplateManager : public IComponent
{
public:
virtual void GetAllTechs(JS::MutableHandleValue ret) = 0;
DECLARE_INTERFACE_TYPE(DataTemplateManager)
};
#endif // INCLUDED_ICMPDATATEMPLATEMANAGER

View file

@ -63,7 +63,6 @@ CComponentManager::CComponentManager(CSimContext& context, shared_ptr<ScriptRunt
m_ScriptInterface.SetCallbackData(static_cast<void*> (this));
m_ScriptInterface.ReplaceNondeterministicRNG(m_RNG);
m_ScriptInterface.LoadGlobalScripts();
// For component script tests, the test system sets up its own scripted implementation of
// these functions, so we skip registering them here in those cases
@ -87,6 +86,9 @@ CComponentManager::CComponentManager(CSimContext& context, shared_ptr<ScriptRunt
m_ScriptInterface.RegisterFunction<void, CComponentManager::Script_FlushDestroyedEntities> ("FlushDestroyedEntities");
}
// Globalscripts may use VFS script functions
m_ScriptInterface.LoadGlobalScripts();
// Define MT_*, IID_* as script globals, and store their names
#define MESSAGE(name) m_ScriptInterface.SetGlobal("MT_" #name, (int)MT_##name);
#define INTERFACE(name) \