Ticket #4405: noAiProxy-serialized.patch

File noAiProxy-serialized.patch, 10.3 KB (added by wraitii, 7 years ago)
  • binaries/data/mods/public/simulation/helpers/InitGame.js

    diff --git a/binaries/data/mods/public/simulation/helpers/InitGame.js b/binaries/data/mods/public/simulation/helpers/InitGame.js
    index 0da8fa9..9c70942 100644
    a b function InitGame(settings)  
    7676    cmpAIManager.SetRNGSeed(seed);
    7777    cmpAIManager.TryLoadSharedComponent();
    7878    cmpAIManager.RunGamestateInit();
     79
     80    // If there are no AIs in the game, don't bother sending message to AIProxy, which takes a few ms per turn in MP games sometimes.
     81    if (!cmpAIManager.HasActiveAIs())
     82        Engine.DeafenComponent("AIProxy");
    7983}
    8084
    8185Engine.RegisterGlobal("PreInitGame", PreInitGame);
  • binaries/data/mods/public/simulation/helpers/Player.js

    diff --git a/binaries/data/mods/public/simulation/helpers/Player.js b/binaries/data/mods/public/simulation/helpers/Player.js
    index ea10491..14f46ba 100644
    a b function LoadPlayerSettings(settings, newPlayers)  
    168168        }
    169169
    170170    // Disable the AIIinterface when no AI players are present
    171     if (playerData && !playerData.some(v => v && !!v.AI))
     171    if (!Engine.HasActiveAIs())
    172172        Engine.QueryInterface(SYSTEM_ENTITY, IID_AIInterface).Disable();
    173173}
    174174
  • source/simulation2/components/CCmpAIManager.cpp

    diff --git a/source/simulation2/components/CCmpAIManager.cpp b/source/simulation2/components/CCmpAIManager.cpp
    index dd210c6..4981595 100644
    a b public:  
    11591159        }
    11601160    }
    11611161
     1162    virtual bool HasActiveAIs()
     1163    {
     1164        return m_Worker.getPlayerSize() > 0;
     1165    }
     1166
    11621167private:
    11631168    std::vector<std::string> m_TemplateNames;
    11641169    size_t m_TemplateLoadedIdx;
  • source/simulation2/components/ICmpAIManager.cpp

    diff --git a/source/simulation2/components/ICmpAIManager.cpp b/source/simulation2/components/ICmpAIManager.cpp
    index 316618f..5b63213 100644
    a b DEFINE_INTERFACE_METHOD_3("AddPlayer", void, ICmpAIManager, AddPlayer, std::wstr  
    2929DEFINE_INTERFACE_METHOD_1("SetRNGSeed", void, ICmpAIManager, SetRNGSeed, uint32_t)
    3030DEFINE_INTERFACE_METHOD_0("TryLoadSharedComponent", void, ICmpAIManager, TryLoadSharedComponent)
    3131DEFINE_INTERFACE_METHOD_0("RunGamestateInit", void, ICmpAIManager, RunGamestateInit)
     32DEFINE_INTERFACE_METHOD_0("HasActiveAIs", bool, ICmpAIManager, HasActiveAIs)
    3233END_INTERFACE_WRAPPER(AIManager)
    3334
    3435// Implement the static method that finds all AI scripts
  • source/simulation2/components/ICmpAIManager.h

    diff --git a/source/simulation2/components/ICmpAIManager.h b/source/simulation2/components/ICmpAIManager.h
    index 97d46f7..5f97912 100644
    a b public:  
    4848    virtual void PushCommands() = 0;
    4949
    5050    /**
     51     * Returns true if there are currently any AI registered with the AiManager
     52     */
     53    virtual bool HasActiveAIs() = 0;
     54
     55    /**
    5156     * Returns a vector of {"id":"value-for-AddPlayer", "name":"Human readable name"}
    5257     * objects, based on all the available AI scripts.
    5358     */
  • source/simulation2/system/ComponentManager.cpp

    diff --git a/source/simulation2/system/ComponentManager.cpp b/source/simulation2/system/ComponentManager.cpp
    index 005b82b..6902992 100644
    a b  
    2626
    2727#include "simulation2/MessageTypes.h"
    2828#include "simulation2/components/ICmpTemplateManager.h"
     29#include "simulation2/components/ICmpAiManager.h"
    2930
    3031#include "lib/utf8.h"
    3132#include "ps/CLogger.h"
    CComponentManager::CComponentManager(CSimContext& context, shared_ptr<ScriptRunt  
    7475        m_ScriptInterface.RegisterFunction<void, std::string, CComponentManager::Script_RegisterInterface> ("RegisterInterface");
    7576        m_ScriptInterface.RegisterFunction<void, std::string, CComponentManager::Script_RegisterMessageType> ("RegisterMessageType");
    7677        m_ScriptInterface.RegisterFunction<void, std::string, JS::HandleValue, CComponentManager::Script_RegisterGlobal> ("RegisterGlobal");
     78        m_ScriptInterface.RegisterFunction<void, std::string, CComponentManager::Script_DeafenComponent> ("DeafenComponent");
    7779        m_ScriptInterface.RegisterFunction<IComponent*, int, int, CComponentManager::Script_QueryInterface> ("QueryInterface");
    7880        m_ScriptInterface.RegisterFunction<std::vector<int>, int, CComponentManager::Script_GetEntitiesWithInterface> ("GetEntitiesWithInterface");
    7981        m_ScriptInterface.RegisterFunction<std::vector<IComponent*>, int, CComponentManager::Script_GetComponentsWithInterface> ("GetComponentsWithInterface");
    void CComponentManager::Script_RegisterInterface(ScriptInterface::CxPrivate* pCx  
    359361    componentManager->m_ScriptInterface.SetGlobal(("IID_" + name).c_str(), (int)id);
    360362}
    361363
     364void CComponentManager::Script_DeafenComponent(ScriptInterface::CxPrivate* pCxPrivate, const std::string& cname)
     365{
     366    CComponentManager* componentManager = static_cast<CComponentManager*> (pCxPrivate->pCBData);
     367    ComponentTypeId cid = componentManager->LookupCID(cname);
     368    if (cid == CID__Invalid)
     369    {
     370        std::string msg("Trying to deafen invalid component " + cname);
     371        componentManager->m_ScriptInterface.ReportError(msg.c_str());
     372        return;
     373    }
     374    componentManager->DeafenComponent(cid);
     375}
     376
    362377void CComponentManager::Script_RegisterMessageType(ScriptInterface::CxPrivate* pCxPrivate, const std::string& name)
    363378{
    364379    CComponentManager* componentManager = static_cast<CComponentManager*> (pCxPrivate->pCBData);
    void CComponentManager::SetRNGSeed(u32 seed)  
    543558    m_RNG.seed(seed);
    544559}
    545560
     561void CComponentManager::DeafenComponent(const ComponentTypeId& ID)
     562{
     563    m_DeafenedComponents.insert(ID);
     564   
     565    // unsubscribe the component from all messages, effectively this is similar to removing it altogether.
     566    for (auto& messageType : m_LocalMessageSubscriptions)
     567    {
     568        std::vector<ComponentTypeId>::iterator component = std::find(messageType.second.begin(),messageType.second.end(), ID);
     569        if (component != messageType.second.end())
     570        {
     571            // pop and swap, I do not believe we actually care about the order here.
     572            std::swap(*component, messageType.second.back());
     573            messageType.second.pop_back();
     574        }
     575    }
     576}
     577
     578
    546579void CComponentManager::RegisterComponentType(InterfaceId iid, ComponentTypeId cid, AllocFunc alloc, DeallocFunc dealloc,
    547580        const char* name, const std::string& schema)
    548581{
    entity_id_t CComponentManager::AddEntity(const std::wstring& templateName, entit  
    874907            continue;
    875908
    876909        CComponentManager::ComponentTypeId cid = LookupCID(it->first);
     910
    877911        if (cid == CID__Invalid)
    878912        {
    879913            LOGERROR("Unrecognised component type name '%s' in entity template '%s'", it->first, utf8_from_wstring(templateName));
  • source/simulation2/system/ComponentManager.h

    diff --git a/source/simulation2/system/ComponentManager.h b/source/simulation2/system/ComponentManager.h
    index 8176dc5..2247e71 100644
    a b public:  
    301301     */
    302302    void SetRNGSeed(u32 seed);
    303303
     304    /**
     305     * Tells the Component Manager to remove all subscriptions of a given component type,
     306     * effectively making it similar to altogether removing that component (but in a less intrusive way).
     307     * This is called in public mod for AIProxy in player-only games.
     308     * Since AIProxy can end up taking several ms (>3/4) per turn doing nothing useful otherwise
     309     */
     310    void DeafenComponent(const ComponentTypeId& ID);
     311
    304312    // Various state serialization functions:
    305313    bool ComputeStateHash(std::string& outHash, bool quick);
    306314    bool DumpDebugState(std::ostream& stream, bool includeDebugInfo);
    private:  
    322330    static void Script_RegisterInterface(ScriptInterface::CxPrivate* pCxPrivate, const std::string& name);
    323331    static void Script_RegisterMessageType(ScriptInterface::CxPrivate* pCxPrivate, const std::string& name);
    324332    static void Script_RegisterGlobal(ScriptInterface::CxPrivate* pCxPrivate, const std::string& name, JS::HandleValue value);
     333    static void Script_DeafenComponent(ScriptInterface::CxPrivate* pCxPrivate, const std::string& cname);
    325334    static IComponent* Script_QueryInterface(ScriptInterface::CxPrivate* pCxPrivate, int ent, int iid);
    326335    static std::vector<int> Script_GetEntitiesWithInterface(ScriptInterface::CxPrivate* pCxPrivate, int iid);
    327336    static std::vector<IComponent*> Script_GetComponentsWithInterface(ScriptInterface::CxPrivate* pCxPrivate, int iid);
    private:  
    374383
    375384    std::map<entity_id_t, SEntityComponentCache*> m_ComponentCaches;
    376385
     386    std::set<ComponentTypeId> m_DeafenedComponents;
     387
    377388    // TODO: maintaining both ComponentsBy* is nasty; can we get rid of one,
    378389    // while keeping QueryInterface and PostMessage sufficiently efficient?
    379390
  • source/simulation2/system/ComponentManagerSerialization.cpp

    diff --git a/source/simulation2/system/ComponentManagerSerialization.cpp b/source/simulation2/system/ComponentManagerSerialization.cpp
    index c9de4b2..3b430a0 100644
    a b  
    2727#include "simulation2/serialization/HashSerializer.h"
    2828#include "simulation2/serialization/StdSerializer.h"
    2929#include "simulation2/serialization/StdDeserializer.h"
     30#include "simulation2/serialization/StdDeserializer.h"
     31#include "simulation2/serialization/SerializeTemplates.h"
    3032
    3133#include "simulation2/components/ICmpTemplateManager.h"
    3234
    bool CComponentManager::ComputeStateHash(std::string& outHash, bool quick)  
    167169 *   For each entity:
    168170 *     Entity id.
    169171 *     Component state.
     172 * Deafened components (by cid)
    170173 *
    171174 * Rationale:
    172175 * Saved games should be valid across patches, which might change component
    bool CComponentManager::SerializeState(std::ostream& stream)  
    289292        }
    290293    }
    291294
     295    // deafened components
     296    serializer.NumberU32_Unbounded("num deafened components", (uint32_t)m_DeafenedComponents.size());
     297    for (ComponentTypeId cid : m_DeafenedComponents)
     298        serializer.NumberU32_Unbounded("cid", cid);
     299
    292300    // TODO: catch exceptions
    293301    return true;
    294302}
    bool CComponentManager::DeserializeState(std::istream& stream)  
    377385            }
    378386        }
    379387
     388        // deafened components
     389        m_DeafenedComponents.clear();
     390        uint32_t numDeafenedComponents;
     391        deserializer.NumberU32_Unbounded("num deafened components", numDeafenedComponents);
     392        for (size_t j = 0; j < numDeafenedComponents; ++j)
     393        {
     394            uint32_t cid;
     395            deserializer.NumberU32_Unbounded("cid", cid);
     396            DeafenComponent((ComponentTypeId)cid);
     397        }
     398
    380399        if (stream.peek() != EOF)
    381400        {
    382401            LOGERROR("Deserialization didn't reach EOF");