Ticket #2022: cleanedupTerr.patch

File cleanedupTerr.patch, 11.4 KB (added by wraitii, 10 years ago)
  • components/CCmpTerritoryManager.cpp

     
    8888    // connected flag in bit 6 (TERRITORY_CONNECTED_MASK);
    8989    // processed flag in bit 7 (TERRITORY_PROCESSED_MASK)
    9090    Grid<u8>* m_Territories;
     91    Grid<u8>* m_InfluenceGrid;
     92
     93    // wraitii: Defining these as part of the object allows to avoid a few temporaries
     94    // wraitii: at least Kuranes says so.
     95    std::vector<std::pair<player_id_t, Grid<u32>* > > playerGrids;
     96
     97    std::map<player_id_t, std::vector<entity_id_t> > influenceEntities;
     98    std::vector<entity_id_t> rootInfluenceEntities;
     99
     100    std::vector<std::pair<u16, u16> > tileStack;
     101
     102    // this is regularly used as a gridu32
     103    std::deque<Grid<u32>* > grid32Pool;
    91104
    92105    // Set to true when territories change; will send a TerritoriesChanged message
    93106    // during the Update phase
     
    113126    virtual void Init(const CParamNode& UNUSED(paramNode))
    114127    {
    115128        m_Territories = NULL;
     129        m_InfluenceGrid = NULL;
    116130        m_DebugOverlay = NULL;
    117131//      m_DebugOverlay = new TerritoryOverlay(*this);
    118132        m_BoundaryLinesDirty = true;
     
    135149    virtual void Deinit()
    136150    {
    137151        SAFE_DELETE(m_Territories);
     152        SAFE_DELETE(m_InfluenceGrid);
    138153        SAFE_DELETE(m_DebugOverlay);
     154        for(std::deque<Grid<u32>* >::iterator it = grid32Pool.begin(); it != grid32Pool.end(); ++it )
     155            delete *it;
    139156    }
    140157
    141158    virtual void Serialize(ISerializer& UNUSED(serialize))
     
    345362
    346363    u16 tilesW = cmpTerrain->GetTilesPerSide();
    347364    u16 tilesH = cmpTerrain->GetTilesPerSide();
    348 
    349     m_Territories = new Grid<u8>(tilesW, tilesH);
     365   
     366    if (!m_Territories)
     367        m_Territories = new Grid<u8>(tilesW, tilesH);
     368    else
     369        m_Territories->reset();
    350370
    351371    // Compute terrain-passability-dependent costs per tile
    352     Grid<u8> influenceGrid(tilesW, tilesH);
     372    if (!m_InfluenceGrid)
     373        m_InfluenceGrid = new Grid<u8>(tilesW, tilesH);
     374    else
     375        m_InfluenceGrid->reset();
    353376
    354377    CmpPtr<ICmpPathfinder> cmpPathfinder(GetSystemEntity());
    355378    ICmpPathfinder::pass_class_t passClassDefault = cmpPathfinder->GetPassabilityClass("default");
    356379    ICmpPathfinder::pass_class_t passClassUnrestricted = cmpPathfinder->GetPassabilityClass("unrestricted");
    357380
     381
    358382    const Grid<u16>& passGrid = cmpPathfinder->GetPassabilityGrid();
     383
     384    // wraitii: locality changes, perhaps unecessary
     385    u16* passGridData = passGrid.m_Data;
     386    u8* influenceGridData = m_InfluenceGrid->m_Data;
     387    u32 gridSize = tilesH * tilesW;
     388
    359389    for (u16 j = 0; j < tilesH; ++j)
    360390    {
    361391        for (u16 i = 0; i < tilesW; ++i)
     
    368398                cost = m_ImpassableCost;
    369399            else
    370400                cost = 1;
    371             influenceGrid.set(i, j, cost);
     401            m_InfluenceGrid->set(i, j, cost);
    372402        }
    373403    }
    374404
     
    376406    CComponentManager::InterfaceList influences = GetSimContext().GetComponentManager().GetEntitiesWithInterface(IID_TerritoryInfluence);
    377407
    378408    // Allow influence entities to override the terrain costs
    379     RasteriseInfluences(influences, influenceGrid);
     409    RasteriseInfluences(influences, *m_InfluenceGrid);
    380410
    381411    // Split influence entities into per-player lists, ignoring any with invalid properties
    382     std::map<player_id_t, std::vector<entity_id_t> > influenceEntities;
    383     std::vector<entity_id_t> rootInfluenceEntities;
    384     for (CComponentManager::InterfaceList::iterator it = influences.begin(); it != influences.end(); ++it)
     412    influenceEntities.clear();
     413    rootInfluenceEntities.clear();
     414    const CComponentManager::InterfaceList::const_iterator itiEnd = influences.end();
     415    for (CComponentManager::InterfaceList::const_iterator it = influences.begin(); it != itiEnd; ++it)
    385416    {
    386417        // Ignore any with no weight or radius (to avoid divide-by-zero later)
    387418        ICmpTerritoryInfluence* cmpTerritoryInfluence = static_cast<ICmpTerritoryInfluence*>(it->second);
     
    413444    }
    414445
    415446    // For each player, store the sum of influences on each tile
    416     std::vector<std::pair<player_id_t, Grid<u32> > > playerGrids;
     447    playerGrids.clear();    // start by resetting.
     448
    417449    // TODO: this is a large waste of memory; we don't really need to store
    418450    // all the intermediate grids
    419451
    420     for (std::map<player_id_t, std::vector<entity_id_t> >::iterator it = influenceEntities.begin(); it != influenceEntities.end(); ++it)
     452    OpenQueue openTiles;
     453    Grid<u32>* entityGrid = new Grid<u32>(tilesW, tilesH);
     454   
     455    const std::map<player_id_t, std::vector<entity_id_t> >::iterator itieEnd = influenceEntities.end();
     456    for (std::map<player_id_t, std::vector<entity_id_t> >::iterator it = influenceEntities.begin(); it != itieEnd; ++it)
    421457    {
    422         Grid<u32> playerGrid(tilesW, tilesH);
     458        Grid<u32>* playerGrid = new Grid<u32>(tilesW, tilesH);
    423459
    424         std::vector<entity_id_t>& ents = it->second;
    425         for (std::vector<entity_id_t>::iterator eit = ents.begin(); eit != ents.end(); ++eit)
     460        std::vector<entity_id_t> &ents = it->second;
     461        std::vector<entity_id_t>::const_iterator eitEnd = ents.end();       
     462        for (std::vector<entity_id_t>::const_iterator eit = ents.begin(); eit != eitEnd; ++eit)
    426463        {
    427464            // Compute the influence map of the current entity, then add it to the player grid
    428 
    429             Grid<u32> entityGrid(tilesW, tilesH);
     465            entityGrid->reset();
    430466
    431467            CmpPtr<ICmpPosition> cmpPosition(GetSimContext(), *eit);
    432468            CFixedVector2D pos = cmpPosition->GetPosition2D();
     
    442478            // when doing all the sums
    443479
    444480            // Initialise the tile under the entity
    445             entityGrid.set(i, j, weight);
    446             OpenQueue openTiles;
    447             OpenQueue::Item tile = { std::make_pair((u16)i, (i16)j), weight };
     481            entityGrid->set(i, j, weight);
     482            OpenQueue::Item tile = { std::make_pair(i, j), weight };
    448483            openTiles.push(tile);
    449484
    450485            // Expand influences outwards
    451             FloodFill(entityGrid, influenceGrid, openTiles, falloff);
     486            FloodFill(*entityGrid, *m_InfluenceGrid, openTiles, falloff);
    452487
    453488            // TODO: we should do a sparse grid and only add the non-zero regions, for performance
    454             for (u16 j = 0; j < entityGrid.m_H; ++j)
    455                 for (u16 i = 0; i < entityGrid.m_W; ++i)
    456                     playerGrid.set(i, j, playerGrid.get(i, j) + entityGrid.get(i, j));
     489            for (u16 j = 0; j < entityGrid->m_H; ++j)
     490                for (u16 i = 0; i < entityGrid->m_W; ++i)
     491                    playerGrid->set(i, j, playerGrid->get(i, j) + entityGrid->get(i, j));
    457492        }
    458493
    459494        playerGrids.push_back(std::make_pair(it->first, playerGrid));
     
    467502            u32 bestWeight = 0;
    468503            for (size_t k = 0; k < playerGrids.size(); ++k)
    469504            {
    470                 u32 w = playerGrids[k].second.get(i, j);
     505                u32 w = playerGrids[k].second->get(i, j);
    471506                if (w > bestWeight)
    472507                {
    473508                    player_id_t id = playerGrids[k].first;
     
    479514    }
    480515
    481516    // Detect territories connected to a 'root' influence (typically a civ center)
    482     // belonging to their player, and mark them with the connected flag
    483     for (std::vector<entity_id_t>::iterator it = rootInfluenceEntities.begin(); it != rootInfluenceEntities.end(); ++it)
     517    // belonging to their player, and mark them with the connected flag,
     518
     519    // wraitii: those two things moved ouy of the loop.
     520    // probably useless obfuscation if the vector is small enough.
     521    Grid<u8>& grid = *m_Territories;
     522    u16 maxi = (u16)(grid.m_W-1);
     523    u16 maxj = (u16)(grid.m_H-1);
     524    std::vector<entity_id_t>::const_iterator itrEnd = rootInfluenceEntities.end();
     525    for (std::vector<entity_id_t>::const_iterator it = rootInfluenceEntities.begin(); it != itrEnd; ++it)
    484526    {
    485527        // (These components must be valid else the entities wouldn't be added to this list)
    486528        CmpPtr<ICmpOwnership> cmpOwnership(GetSimContext(), *it);
     
    492534
    493535        u8 owner = (u8)cmpOwnership->GetOwner();
    494536
    495         if (m_Territories->get(i, j) != owner)
     537        if (grid.get(i, j) != owner)
    496538            continue;
    497539
    498540        // TODO: would be nice to refactor some of the many flood fill
    499541        // algorithms in this component
    500 
    501         Grid<u8>& grid = *m_Territories;
    502 
    503         u16 maxi = (u16)(grid.m_W-1);
    504         u16 maxj = (u16)(grid.m_H-1);
    505 
    506         std::vector<std::pair<u16, u16> > tileStack;
    507 
    508542#define MARK_AND_PUSH(i, j) STMT(grid.set(i, j, owner | TERRITORY_CONNECTED_MASK); tileStack.push_back(std::make_pair(i, j)); )
    509543
    510544        MARK_AND_PUSH(i, j);
     
    560594
    561595void CCmpTerritoryManager::RasteriseInfluences(CComponentManager::InterfaceList& infls, Grid<u8>& grid)
    562596{
    563     for (CComponentManager::InterfaceList::iterator it = infls.begin(); it != infls.end(); ++it)
     597   
     598    CComponentManager::InterfaceList::const_iterator itEnd = infls.end();
     599    for (CComponentManager::InterfaceList::const_iterator it = infls.begin(); it != itEnd; ++it)
    564600    {
    565601        ICmpTerritoryInfluence* cmpTerritoryInfluence = static_cast<ICmpTerritoryInfluence*>(it->second);
    566602
     
    691727        m_BoundaryLinesDirty = false;
    692728    }
    693729
     730    // wraitii: this has been moved out of the loop, probably with reason.
     731    float alpha = 0.2f + 0.8f * fabsf((float)cos(m_AnimTime * M_PI));// TODO: should let artists tweak this
    694732    for (size_t i = 0; i < m_BoundaryLines.size(); ++i)
    695733    {
    696734        if (!m_BoundaryLines[i].connected)
    697735        {
    698736            CColor c = m_BoundaryLines[i].color;
    699             c.a *= 0.2f + 0.8f * fabsf((float)cos(m_AnimTime * M_PI)); // TODO: should let artists tweak this
     737            c.a *= alpha;
    700738            m_BoundaryLines[i].overlay.m_Color = c;
    701739        }
    702740    }
     
    714752
    715753player_id_t CCmpTerritoryManager::GetOwner(entity_pos_t x, entity_pos_t z)
    716754{
    717     u16 i, j;
    718755    CalculateTerritories();
    719756    if (!m_Territories)
    720757        return 0;
    721758
     759    // wraitii: this was moved to be closer to where it's used. OK.
     760    u16 i, j;
    722761    NearestTile(x, z, i, j, m_Territories->m_W, m_Territories->m_H);
    723762    return m_Territories->get(i, j) & TERRITORY_PLAYER_MASK;
    724763}
    725764
    726765bool CCmpTerritoryManager::IsConnected(entity_pos_t x, entity_pos_t z)
    727766{
    728     u16 i, j;
    729767    CalculateTerritories();
    730768    if (!m_Territories)
    731769        return false;
    732770
     771    // wraitii: this was moved to be closer to where it's used. OK.
     772    u16 i, j;
    733773    NearestTile(x, z, i, j, m_Territories->m_W, m_Territories->m_H);
    734774    return (m_Territories->get(i, j) & TERRITORY_CONNECTED_MASK) != 0;
    735775}
     
    762802    case 6:  RenderTile(CColor(1, 0, 1, a), false); break;
    763803    default: RenderTile(CColor(1, 1, 1, a), false); break;
    764804    }
    765 }
     805}
     806 No newline at end of file
  • helpers/Grid.h

     
    7676        delete[] m_Data;
    7777    }
    7878
    79     void reset()
     79    inline void reset()
    8080    {
    8181        if (m_Data)
    8282            memset(m_Data, 0, m_W*m_H*sizeof(T));
    8383    }
    8484
    85     void set(int i, int j, const T& value)
     85    inline void set(int i, int j, const T& value)
    8686    {
    8787#if GRID_BOUNDS_DEBUG
    8888        ENSURE(0 <= i && i < m_W && 0 <= j && j < m_H);
    8989#endif
    9090        m_Data[j*m_W + i] = value;
    9191    }
     92   
     93    inline void add(int i, int j, T val)
     94    {
     95#if GRID_BOUNDS_DEBUG
     96        ENSURE(0 <= i && i < m_W && 0 <= j && j < m_H);
     97#endif
     98        m_Data[j*m_W + i] += val;
     99    }
     100    inline void getPtr(int i, int j)
     101    {
     102#if GRID_BOUNDS_DEBUG
     103        ENSURE(0 <= i && i < m_W && 0 <= j && j < m_H);
     104#endif
     105        return m_Data[j*m_W + i];
     106    }
    92107
    93     T& get(int i, int j) const
     108    inline T& get(int i, int j) const
    94109    {
    95110#if GRID_BOUNDS_DEBUG
    96111        ENSURE(0 <= i && i < m_W && 0 <= j && j < m_H);
     
    144159        delete[] m_Data;
    145160    }
    146161
    147     void reset()
     162    inline void reset()
    148163    {
    149164        for (size_t i = 0; i < (size_t)(m_BW*m_BH); ++i)
    150165            delete[] m_Data[i];
     
    152167        memset(m_Data, 0, m_BW*m_BH*sizeof(T*));
    153168    }
    154169
    155     void set(int i, int j, const T& value)
     170    inline void set(int i, int j, const T& value)
    156171    {
    157172#if GRID_BOUNDS_DEBUG
    158173        ENSURE(0 <= i && i < m_W && 0 <= j && j < m_H);
     
    160175        GetBucket(i, j)[(j % BucketSize)*BucketSize + (i % BucketSize)] = value;
    161176    }
    162177
    163     T& get(int i, int j)
     178    inline T& get(int i, int j)
    164179    {
    165180#if GRID_BOUNDS_DEBUG
    166181        ENSURE(0 <= i && i < m_W && 0 <= j && j < m_H);