Ticket #4191: 0003-Make-AI-map-updates-more-clever.patch

File 0003-Make-AI-map-updates-more-clever.patch, 3.1 KB (added by Itms, 8 years ago)
  • source/simulation2/components/CCmpAIManager.cpp

     
    520520        ENSURE(m_CommandsComputed);
    521521
    522522        m_GameState = gameState;
    523         JSContext* cx = m_ScriptInterface->GetContext();
    524523
    525524        if (dirtinessInformations.dirty)
    526525        {
     526            bool dimensionChange = m_PassabilityMap.m_W != passabilityMap.m_W || m_PassabilityMap.m_H != passabilityMap.m_H;
     527
    527528            m_PassabilityMap = passabilityMap;
    528529            if (dirtinessInformations.globallyDirty)
    529530                m_LongPathfinder.Reload(&m_PassabilityMap, nonPathfindingPassClassMasks, pathfindingPassClassMasks);
    530531            else
    531532                m_LongPathfinder.Update(&m_PassabilityMap, dirtinessInformations.dirtinessGrid);
    532             ScriptInterface::ToJSVal(cx, &m_PassabilityMapVal, m_PassabilityMap);
     533
     534            if (dimensionChange)
     535            {
     536                JSContext* cx = m_ScriptInterface->GetContext();
     537                ScriptInterface::ToJSVal(cx, &m_PassabilityMapVal, m_PassabilityMap);
     538            }
     539            else
     540                UpdatePassabilityMapVal();
    533541        }
    534542
    535543        if (territoryMapDirty)
    536544        {
     545            bool dimensionChange = m_TerritoryMap.m_W != territoryMap.m_W || m_TerritoryMap.m_H != territoryMap.m_H;
     546
    537547            m_TerritoryMap = territoryMap;
    538             ScriptInterface::ToJSVal(cx, &m_TerritoryMapVal, m_TerritoryMap);
     548
     549            if (dimensionChange)
     550            {
     551                JSContext* cx = m_ScriptInterface->GetContext();
     552                ScriptInterface::ToJSVal(cx, &m_TerritoryMapVal, m_TerritoryMap);
     553            }
     554            else
     555                UpdateTerritoryMapVal();
    539556        }
    540557
    541558        m_CommandsComputed = false;
    542559    }
    543560
     561    // Those functions are used to avoid an useless memory reallocation followed by a garbage collection on each turn.
     562    // Warning: They assume the maps do not change dimensions. Only the raw data of the maps will be updated.
     563    // Additionally, a segmentation fault would happen if the map dimensions are reduced.
     564
     565    void UpdatePassabilityMapVal()
     566    {
     567        JSContext* cx = m_ScriptInterface->GetContext();
     568        JSAutoRequest rq(cx);
     569
     570        JS::RootedObject mapObj(cx, &m_PassabilityMapVal.toObject());
     571        JS::RootedValue mapData(cx);
     572        ENSURE(JS_GetProperty(cx, mapObj, "data", &mapData));
     573        JS::RootedObject dataObj(cx, &mapData.toObject());
     574
     575        u32 length = 0;
     576        ENSURE(JS_GetArrayLength(cx, dataObj, &length));
     577        u32 nbytes = (u32)(length * sizeof(NavcellData));
     578
     579        JS::AutoCheckCannotGC nogc;
     580        memcpy((void*)JS_GetUint16ArrayData(dataObj, nogc), m_PassabilityMap.m_Data, nbytes);
     581    }
     582    void UpdateTerritoryMapVal()
     583    {
     584        JSContext* cx = m_ScriptInterface->GetContext();
     585        JSAutoRequest rq(cx);
     586
     587        JS::RootedObject mapObj(cx, &m_TerritoryMapVal.toObject());
     588        JS::RootedValue mapData(cx);
     589        ENSURE(JS_GetProperty(cx, mapObj, "data", &mapData));
     590        JS::RootedObject dataObj(cx, &mapData.toObject());
     591
     592        u32 length = 0;
     593        ENSURE(JS_GetArrayLength(cx, dataObj, &length));
     594        u32 nbytes = (u32)(length * sizeof(u8));
     595
     596        JS::AutoCheckCannotGC nogc;
     597        memcpy((void*)JS_GetUint8ArrayData(dataObj, nogc), m_TerritoryMap.m_Data, nbytes);
     598    }
     599
    544600    void WaitToFinishComputation()
    545601    {
    546602        if (!m_CommandsComputed)