Ticket #4045: fewercopy.patch

File fewercopy.patch, 6.2 KB (added by wraitii, 8 years ago)
  • components/CCmpRangeManager.cpp

     
    320320    EntityMap<EntityData> m_EntityData;
    321321
    322322    FastSpatialSubdivision m_Subdivision; // spatial index of m_EntityData
    323     std::vector<entity_id_t> m_SubdivisionResults;
     323    std::vector<std::pair<void*,size_t> > m_SubdivisionResults;
    324324
    325325    // LOS state:
    326326    static const player_id_t MAX_LOS_PLAYER_ID = 16;
     
    380380        // SetBounds is called)
    381381        ResetSubdivisions(entity_pos_t::FromInt(1024), entity_pos_t::FromInt(1024));
    382382
    383         m_SubdivisionResults.reserve(4096);
     383        m_SubdivisionResults.reserve(256);
    384384
    385385        // The whole map should be visible to Gaia by default, else e.g. animals
    386386        // will get confused when trying to run from enemies
     
    10721072
    10731073            for (size_t i = 0; i < m_SubdivisionResults.size(); ++i)
    10741074            {
    1075                 EntityMap<EntityData>::const_iterator it = m_EntityData.find(m_SubdivisionResults[i]);
    1076                 ENSURE(it != m_EntityData.end());
     1075                size_t size = m_SubdivisionResults[i].second;
     1076                auto start = (std::vector<entity_id_t>::const_pointer)(m_SubdivisionResults[i].first);
     1077                for (size_t j = 0; j < size; ++j)
     1078                {
     1079                    entity_id_t ent = (entity_id_t)*(start + j);
     1080                    EntityMap<EntityData>::const_iterator it = m_EntityData.find(ent);
     1081                    ENSURE(it != m_EntityData.end());
    10771082
    1078                 if (!TestEntityQuery(q, it->first, it->second))
    1079                     continue;
     1083                    if (!TestEntityQuery(q, it->first, it->second))
     1084                        continue;
    10801085
    1081                 CmpPtr<ICmpPosition> cmpSecondPosition(GetSimContext(), m_SubdivisionResults[i]);
    1082                 if (!cmpSecondPosition || !cmpSecondPosition->IsInWorld())
    1083                     continue;
    1084                 CFixedVector3D secondPosition = cmpSecondPosition->GetPosition();
     1086                    CmpPtr<ICmpPosition> cmpSecondPosition(GetSimContext(), ent);
     1087                    if (!cmpSecondPosition || !cmpSecondPosition->IsInWorld())
     1088                        continue;
     1089                    CFixedVector3D secondPosition = cmpSecondPosition->GetPosition();
    10851090
    1086                 // Restrict based on precise distance
    1087                 if (!InParabolicRange(
     1091                    // Restrict based on precise distance
     1092                    if (!InParabolicRange(
    10881093                        CFixedVector3D(it->second.x, secondPosition.Y, it->second.z)
    1089                             - pos3d,
     1094                        - pos3d,
    10901095                        q.maxRange))
    1091                     continue;
     1096                        continue;
    10921097
    1093                 if (!q.minRange.IsZero())
    1094                 {
    1095                     int distVsMin = (CFixedVector2D(it->second.x, it->second.z) - pos).CompareLength(q.minRange);
    1096                     if (distVsMin < 0)
    1097                         continue;
     1098                    if (!q.minRange.IsZero())
     1099                    {
     1100                        int distVsMin = (CFixedVector2D(it->second.x, it->second.z) - pos).CompareLength(q.minRange);
     1101                        if (distVsMin < 0)
     1102                            continue;
     1103                    }
     1104
     1105                    r.push_back(it->first);
    10981106                }
    1099 
    1100                 r.push_back(it->first);
    11011107            }
    11021108            std::sort(r.begin(), r.end());
    11031109        }
     
    11101116
    11111117            for (size_t i = 0; i < m_SubdivisionResults.size(); ++i)
    11121118            {
    1113                 EntityMap<EntityData>::const_iterator it = m_EntityData.find(m_SubdivisionResults[i]);
    1114                 ENSURE(it != m_EntityData.end());
     1119                size_t size = m_SubdivisionResults[i].second;
     1120                auto start = (std::vector<entity_id_t>::const_pointer)(m_SubdivisionResults[i].first);
     1121                for (size_t j = 0; j < size; ++j)
     1122                {
     1123                    entity_id_t ent = (entity_id_t)*(start + j);
     1124                    EntityMap<EntityData>::const_iterator it = m_EntityData.find(ent);
     1125                    ENSURE(it != m_EntityData.end());
    11151126
    1116                 if (!TestEntityQuery(q, it->first, it->second))
    1117                     continue;
     1127                    if (!TestEntityQuery(q, it->first, it->second))
     1128                        continue;
    11181129
    1119                 // Restrict based on precise distance
    1120                 int distVsMax = (CFixedVector2D(it->second.x, it->second.z) - pos).CompareLength(q.maxRange);
    1121                 if (distVsMax > 0)
    1122                     continue;
     1130                    // Restrict based on precise distance
     1131                    int distVsMax = (CFixedVector2D(it->second.x, it->second.z) - pos).CompareLength(q.maxRange);
     1132                    if (distVsMax > 0)
     1133                        continue;
    11231134
    1124                 if (!q.minRange.IsZero())
    1125                 {
    1126                     int distVsMin = (CFixedVector2D(it->second.x, it->second.z) - pos).CompareLength(q.minRange);
    1127                     if (distVsMin < 0)
    1128                         continue;
     1135                    if (!q.minRange.IsZero())
     1136                    {
     1137                        int distVsMin = (CFixedVector2D(it->second.x, it->second.z) - pos).CompareLength(q.minRange);
     1138                        if (distVsMin < 0)
     1139                            continue;
     1140                    }
     1141
     1142                    r.push_back(it->first);
    11291143                }
    1130 
    1131                 r.push_back(it->first);
    11321144            }
    11331145            std::sort(r.begin(), r.end());
    11341146        }
  • helpers/Spatial.h

     
    513513     * Returns a (non sorted) list of items that are either in the square or close to it.
    514514     * It's the responsibility of the querier to do proper distance checking and entity sorting.
    515515     */
    516     void GetInRange(std::vector<entity_id_t>& out, CFixedVector2D posMin, CFixedVector2D posMax) const
     516    void GetInRange(std::vector<std::pair<void*, size_t> >& out, CFixedVector2D posMin, CFixedVector2D posMax) const
    517517    {
    518518        size_t minX = Index(posMin.X);
    519519        size_t minY = Index(posMin.Y);
     
    530530        ENSURE(out.empty() && "GetInRange: out is not clean");
    531531
    532532        // Add oversized items, they can be anywhere
    533         out.insert(out.end(), m_OverSizedData.begin(), m_OverSizedData.end());
     533        if (!m_OverSizedData.empty())
     534            out.push_back(std::make_pair((void*)m_OverSizedData.data(), (size_t)m_OverSizedData.size()));
    534535
    535536        for (size_t Y = minY; Y < maxY; ++Y)
    536537        {
     
    538539            {
    539540                std::vector<entity_id_t>& subdivision = m_SpatialDivisionsData[X + Y*m_ArrayWidth];
    540541                if (!subdivision.empty())
    541                     out.insert(out.end(), subdivision.begin(), subdivision.end());
     542                    out.push_back(std::make_pair((void*)subdivision.data(), (size_t)subdivision.size()));
    542543            }
    543544        }
    544545    }
     
    547548     * Returns a (non sorted) list of items that are either in the circle or close to it.
    548549     * It's the responsibility of the querier to do proper distance checking and entity sorting.
    549550     */
    550     void GetNear(std::vector<entity_id_t>& out, CFixedVector2D pos, entity_pos_t range) const
     551    void GetNear(std::vector<std::pair<void*, size_t> >& out, CFixedVector2D pos, entity_pos_t range) const
    551552    {
    552553        // Because the subdivision size is rather big wrt typical ranges,
    553554        // this square over-approximation is hopefully not too bad.