Ticket #4405: dynamic_noaiProxy.patch

File dynamic_noaiProxy.patch, 7.7 KB (added by wraitii, 7 years ago)

better patch for Itms

  • 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..9106446 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.SkipComponent("AIProxy");
    7983}
    8084
    8185Engine.RegisterGlobal("PreInitGame", PreInitGame);
  • 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..e6d45d5 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_SkipComponent> ("SkipComponent");
    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_SkipComponent(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 skip invalid component " + cname);
     371        componentManager->m_ScriptInterface.ReportError(msg.c_str());
     372        return;
     373    }
     374    componentManager->SkipComponent(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::SkipComponent(const ComponentTypeId& ID)
     562{
     563    // unsubscribe the component from all messages, effectively this is similar to removing it altogether.
     564    for (auto& messageType : m_LocalMessageSubscriptions)
     565    {
     566        std::vector<ComponentTypeId>::iterator component = std::find(messageType.second.begin(),messageType.second.end(), ID);
     567        if (component != messageType.second.end())
     568        {
     569            // pop and swap, I do not believe we actually care about the order here.
     570            std::swap(*component, messageType.second.back());
     571            messageType.second.pop_back();
     572        }
     573    }
     574}
     575
     576
    546577void CComponentManager::RegisterComponentType(InterfaceId iid, ComponentTypeId cid, AllocFunc alloc, DeallocFunc dealloc,
    547578        const char* name, const std::string& schema)
    548579{
    entity_id_t CComponentManager::AddEntity(const std::wstring& templateName, entit  
    874905            continue;
    875906
    876907        CComponentManager::ComponentTypeId cid = LookupCID(it->first);
     908
    877909        if (cid == CID__Invalid)
    878910        {
    879911            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..16499ab 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 SkipComponent(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_SkipComponent(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:  
    385394
    386395    boost::rand48 m_RNG;
    387396
     397    bool m_SkipAiProxy = false;
     398
    388399    friend class TestComponentManager;
    389400};
    390401