From 4ea49f374a6b167036efe09e4a42b7ac86683214 Mon Sep 17 00:00:00 2001 From: sanderd17 Date: Mon, 2 May 2016 09:26:07 +0000 Subject: [PATCH] Disable serialization of the AI when no AI players are present. Disable serialization of cached AI templates overall. Improve serialization of repetitive vectors and templatenames. Refs #3834 This was SVN commit r18121. --- .../simulation/components/AIInterface.js | 2 + .../simulation2/components/CCmpAIManager.cpp | 12 +++-- .../components/CCmpRangeManager.cpp | 4 +- .../components/CCmpTemplateManager.cpp | 44 +++++------------ .../serialization/SerializeTemplates.h | 49 ++++++++++++++++++- 5 files changed, 74 insertions(+), 37 deletions(-) diff --git a/binaries/data/mods/public/simulation/components/AIInterface.js b/binaries/data/mods/public/simulation/components/AIInterface.js index c45316ba22..14cbdd0d54 100644 --- a/binaries/data/mods/public/simulation/components/AIInterface.js +++ b/binaries/data/mods/public/simulation/components/AIInterface.js @@ -48,6 +48,8 @@ AIInterface.prototype.Serialize = function() continue; if (typeof this[key] == "function") continue; + if (key == "templates") + continue; state[key] = this[key]; } return state; diff --git a/source/simulation2/components/CCmpAIManager.cpp b/source/simulation2/components/CCmpAIManager.cpp index 69e0f7a43c..24b1a1ff87 100644 --- a/source/simulation2/components/CCmpAIManager.cpp +++ b/source/simulation2/components/CCmpAIManager.cpp @@ -609,6 +609,9 @@ public: void SerializeState(ISerializer& serializer) { + if (m_Players.empty()) + return; + JSContext* cx = m_ScriptInterface->GetContext(); JSAutoRequest rq(cx); @@ -665,6 +668,12 @@ public: void Deserialize(std::istream& stream, u32 numAis) { + m_PlayerMetadata.clear(); + m_Players.clear(); + + if (numAis == 0) + return; + JSContext* cx = m_ScriptInterface->GetContext(); JSAutoRequest rq(cx); @@ -672,9 +681,6 @@ public: CStdDeserializer deserializer(*m_ScriptInterface, stream); - m_PlayerMetadata.clear(); - m_Players.clear(); - std::string rngString; std::stringstream rngStream; deserializer.StringASCII("rng", rngString, 0, 32); diff --git a/source/simulation2/components/CCmpRangeManager.cpp b/source/simulation2/components/CCmpRangeManager.cpp index 60487371d9..f6d8106e66 100644 --- a/source/simulation2/components/CCmpRangeManager.cpp +++ b/source/simulation2/components/CCmpRangeManager.cpp @@ -415,14 +415,14 @@ public: serialize.Bool("global visibility update", m_GlobalVisibilityUpdate); SerializeVector()(serialize, "global player visibility update", m_GlobalPlayerVisibilityUpdate); - SerializeVector()(serialize, "dirty visibility", m_DirtyVisibility); + SerializeRepetitiveVector()(serialize, "dirty visibility", m_DirtyVisibility); SerializeVector()(serialize, "modified entities", m_ModifiedEntities); // We don't serialize m_Subdivision, m_LosPlayerCounts or m_LosTiles // since they can be recomputed from the entity data when deserializing; // m_LosState must be serialized since it depends on the history of exploration - SerializeVector()(serialize, "los state", m_LosState); + SerializeRepetitiveVector()(serialize, "los state", m_LosState); SerializeVector()(serialize, "shared los masks", m_SharedLosMasks); SerializeVector()(serialize, "shared dirty visibility masks", m_SharedDirtyVisibilityMasks); } diff --git a/source/simulation2/components/CCmpTemplateManager.cpp b/source/simulation2/components/CCmpTemplateManager.cpp index 5eef615737..3d86f8efcf 100644 --- a/source/simulation2/components/CCmpTemplateManager.cpp +++ b/source/simulation2/components/CCmpTemplateManager.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2015 Wildfire Games. +/* Copyright (C) 2016 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -21,6 +21,7 @@ #include "ICmpTemplateManager.h" #include "simulation2/MessageTypes.h" +#include "simulation2/serialization/SerializeTemplates.h" #include "ps/TemplateLoader.h" @@ -58,43 +59,24 @@ public: virtual void Serialize(ISerializer& serialize) { - size_t count = 0; + std::map> templateMap; + + for (std::pair templateEnt : m_LatestTemplates) + if (!ENTITY_IS_LOCAL(templateEnt.first)) + templateMap[templateEnt.second].push_back(templateEnt.first); - for (std::map::const_iterator it = m_LatestTemplates.begin(); it != m_LatestTemplates.end(); ++it) - { - if (ENTITY_IS_LOCAL(it->first)) - continue; - ++count; - } - serialize.NumberU32_Unbounded("num entities", (u32)count); - - for (std::map::const_iterator it = m_LatestTemplates.begin(); it != m_LatestTemplates.end(); ++it) - { - if (ENTITY_IS_LOCAL(it->first)) - continue; - serialize.NumberU32_Unbounded("id", it->first); - serialize.StringASCII("template", it->second, 0, 256); - } - // TODO: maybe we should do some kind of interning thing instead of printing so many strings? - - // TODO: will need to serialize techs too, because we need to be giving out - // template data before other components (like the tech components) have been deserialized + SerializeMap>()(serialize, "templates", templateMap); } virtual void Deserialize(const CParamNode& paramNode, IDeserializer& deserialize) { Init(paramNode); - u32 numEntities; - deserialize.NumberU32_Unbounded("num entities", numEntities); - for (u32 i = 0; i < numEntities; ++i) - { - entity_id_t ent; - std::string templateName; - deserialize.NumberU32_Unbounded("id", ent); - deserialize.StringASCII("template", templateName, 0, 256); - m_LatestTemplates[ent] = templateName; - } + std::map> templateMap; + SerializeMap>()(deserialize, "templates", templateMap); + for (std::pair> mapEl : templateMap) + for (entity_id_t id : mapEl.second) + m_LatestTemplates[id] = mapEl.first; } virtual void HandleMessage(const CMessage& msg, bool UNUSED(global)) diff --git a/source/simulation2/serialization/SerializeTemplates.h b/source/simulation2/serialization/SerializeTemplates.h index 1b338c5c78..df4593f27d 100644 --- a/source/simulation2/serialization/SerializeTemplates.h +++ b/source/simulation2/serialization/SerializeTemplates.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2015 Wildfire Games. +/* Copyright (C) 2016 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -53,6 +53,53 @@ struct SerializeVector } }; +template +struct SerializeRepetitiveVector +{ + template + void operator()(ISerializer& serialize, const char* name, std::vector& value) + { + size_t len = value.size(); + serialize.NumberU32_Unbounded("length", (u32)len); + if (len == 0) + return; + u32 count = 1; + T prevVal = value[0]; + for (size_t i = 1; i < len; ++i) + { + if (prevVal == value[i]) + { + count++; + continue; + } + serialize.NumberU32_Unbounded("#", count); + ELEM()(serialize, name, prevVal); + count = 1; + prevVal = value[i]; + } + serialize.NumberU32_Unbounded("#", count); + ELEM()(serialize, name, prevVal); + } + + template + void operator()(IDeserializer& deserialize, const char* name, std::vector& value) + { + value.clear(); + u32 len; + deserialize.NumberU32_Unbounded("length", len); + value.reserve(len); // TODO: watch out for out-of-memory + for (size_t i = 0; i < len;) + { + u32 count; + deserialize.NumberU32_Unbounded("#", count); + T el; + ELEM()(deserialize, name, el); + i += count; + value.insert(value.end(), count, el); + } + } +}; + template struct SerializeMap {