Skip to content

Commit

Permalink
[pal] Modernise memory management
Browse files Browse the repository at this point in the history
  • Loading branch information
nyalldawson committed Dec 30, 2019
1 parent 578f32a commit 10bda51
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 42 deletions.
53 changes: 23 additions & 30 deletions src/core/pal/feature.cpp
Expand Up @@ -1081,7 +1081,7 @@ std::size_t FeaturePart::createCandidatesAlongLineNearMidpoint( std::vector< std
}


LabelPosition *FeaturePart::curvedPlacementAtOffset( PointSet *path_positions, double *path_distances, int &orientation, const double offsetAlongLine, bool &reversed, bool &flip )
std::unique_ptr< LabelPosition > FeaturePart::curvedPlacementAtOffset( PointSet *path_positions, double *path_distances, int &orientation, const double offsetAlongLine, bool &reversed, bool &flip )
{
double offsetAlongSegment = offsetAlongLine;
int index = 1;
Expand Down Expand Up @@ -1153,7 +1153,7 @@ LabelPosition *FeaturePart::curvedPlacementAtOffset( PointSet *path_positions, d
}
}

LabelPosition *slp = nullptr;
std::unique_ptr< LabelPosition > slp;
LabelPosition *slp_tmp = nullptr;

double old_x = path_positions->x[index - 1];
Expand All @@ -1180,7 +1180,6 @@ LabelPosition *FeaturePart::curvedPlacementAtOffset( PointSet *path_positions, d
double start_x, start_y, end_x, end_y;
if ( !nextCharPosition( ci.width, path_distances[index], path_positions, index, offsetAlongSegment, start_x, start_y, end_x, end_y ) )
{
delete slp;
return nullptr;
}

Expand All @@ -1199,7 +1198,6 @@ LabelPosition *FeaturePart::curvedPlacementAtOffset( PointSet *path_positions, d
|| ( li->max_char_angle_outside < 0 && angle_delta < 0
&& angle_delta < li->max_char_angle_outside * ( M_PI / 180 ) ) )
{
delete slp;
return nullptr;
}

Expand Down Expand Up @@ -1231,13 +1229,14 @@ LabelPosition *FeaturePart::curvedPlacementAtOffset( PointSet *path_positions, d
render_angle += M_PI;
}

LabelPosition *tmp = new LabelPosition( 0, render_x /*- xBase*/, render_y /*- yBase*/, ci.width, string_height, -render_angle, 0.0001, this );
std::unique_ptr< LabelPosition > tmp = qgis::make_unique< LabelPosition >( 0, render_x /*- xBase*/, render_y /*- yBase*/, ci.width, string_height, -render_angle, 0.0001, this );
tmp->setPartId( orientation > 0 ? i : li->char_num - i - 1 );
LabelPosition *next = tmp.get();
if ( !slp )
slp = tmp;
slp = std::move( tmp );
else
slp_tmp->setNextPart( tmp );
slp_tmp = tmp;
slp_tmp->setNextPart( std::move( tmp ) );
slp_tmp = next;

// Normalise to 0 <= angle < 2PI
while ( render_angle >= 2 * M_PI ) render_angle -= 2 * M_PI;
Expand All @@ -1250,9 +1249,9 @@ LabelPosition *FeaturePart::curvedPlacementAtOffset( PointSet *path_positions, d
return slp;
}

static LabelPosition *_createCurvedCandidate( LabelPosition *lp, double angle, double dist )
static std::unique_ptr< LabelPosition > _createCurvedCandidate( LabelPosition *lp, double angle, double dist )
{
LabelPosition *newLp = new LabelPosition( *lp );
std::unique_ptr< LabelPosition > newLp = qgis::make_unique< LabelPosition >( *lp );
newLp->offsetPosition( dist * std::cos( angle + M_PI_2 ), dist * std::sin( angle + M_PI_2 ) );
return newLp;
}
Expand Down Expand Up @@ -1324,7 +1323,7 @@ std::size_t FeaturePart::createCurvedCandidatesAlongLine( std::vector< std::uniq
if ( pal->isCanceled() )
return 0;

QLinkedList<LabelPosition *> positions;
std::vector< std::unique_ptr< LabelPosition >> positions;
const std::size_t candidateTargetCount = maximumLineCandidates();
double delta = std::max( li->label_height / 6, total_distance / candidateTargetCount );

Expand All @@ -1351,7 +1350,7 @@ std::size_t FeaturePart::createCurvedCandidatesAlongLine( std::vector< std::uniq
orientation = 1;
}

LabelPosition *slp = curvedPlacementAtOffset( mapShape, path_distances.get(), orientation, distanceAlongLineToStartCandidate, reversed, flip );
std::unique_ptr< LabelPosition > slp = curvedPlacementAtOffset( mapShape, path_distances.get(), orientation, distanceAlongLineToStartCandidate, reversed, flip );
if ( !slp )
continue;

Expand All @@ -1361,7 +1360,6 @@ std::size_t FeaturePart::createCurvedCandidatesAlongLine( std::vector< std::uniq
// if labels should be shown upright then retry with the opposite orientation
if ( ( showUprightLabels() && !flip ) )
{
delete slp;
orientation = -orientation;
slp = curvedPlacementAtOffset( mapShape, path_distances.get(), orientation, distanceAlongLineToStartCandidate, reversed, flip );
}
Expand All @@ -1371,11 +1369,11 @@ std::size_t FeaturePart::createCurvedCandidatesAlongLine( std::vector< std::uniq

// evaluate cost
double angle_diff = 0.0, angle_last = 0.0, diff;
LabelPosition *tmp = slp;
LabelPosition *tmp = slp.get();
double sin_avg = 0, cos_avg = 0;
while ( tmp )
{
if ( tmp != slp ) // not first?
if ( tmp != slp.get() ) // not first?
{
diff = std::fabs( tmp->getAlpha() - angle_last );
if ( diff > 2 * M_PI ) diff -= 2 * M_PI;
Expand Down Expand Up @@ -1405,51 +1403,46 @@ std::size_t FeaturePart::createCurvedCandidatesAlongLine( std::vector< std::uniq
// displacement - we loop through 3 times, generating above, online then below line placements successively
for ( int i = 0; i <= 2; ++i )
{
LabelPosition *p = nullptr;
std::unique_ptr< LabelPosition > p;
if ( i == 0 && ( ( !localreversed && ( flags & FLAG_ABOVE_LINE ) ) || ( localreversed && ( flags & FLAG_BELOW_LINE ) ) ) )
p = _createCurvedCandidate( slp, angle_avg, mLF->distLabel() + li->label_height / 2 );
p = _createCurvedCandidate( slp.get(), angle_avg, mLF->distLabel() + li->label_height / 2 );
if ( i == 1 && flags & FLAG_ON_LINE )
{
p = _createCurvedCandidate( slp, angle_avg, 0 );
p = _createCurvedCandidate( slp.get(), angle_avg, 0 );
p->setCost( p->cost() + 0.002 );
}
if ( i == 2 && ( ( !localreversed && ( flags & FLAG_BELOW_LINE ) ) || ( localreversed && ( flags & FLAG_ABOVE_LINE ) ) ) )
{
p = _createCurvedCandidate( slp, angle_avg, -li->label_height / 2 - mLF->distLabel() );
p = _createCurvedCandidate( slp.get(), angle_avg, -li->label_height / 2 - mLF->distLabel() );
p->setCost( p->cost() + 0.001 );
}

if ( p && mLF->permissibleZonePrepared() )
{
bool within = true;
LabelPosition *currentPos = p;
LabelPosition *currentPos = p.get();
while ( within && currentPos )
{
within = GeomFunction::containsCandidate( mLF->permissibleZonePrepared(), currentPos->getX(), currentPos->getY(), currentPos->getWidth(), currentPos->getHeight(), currentPos->getAlpha() );
currentPos = currentPos->getNextPart();
}
if ( !within )
{
delete p;
p = nullptr;
p.reset();
}
}

if ( p )
positions.append( p );
positions.emplace_back( std::move( p ) );
}

// delete original candidate
delete slp;
}

std::size_t nbp = positions.size();
for ( std::size_t i = 0; i < nbp; i++ )
for ( std::unique_ptr< LabelPosition > &pos : positions )
{
lPos.emplace_back( std::unique_ptr< LabelPosition >( positions.takeFirst() ) );
lPos.emplace_back( std::move( pos ) );
}

return nbp;
return positions.size();
}

/*
Expand Down
4 changes: 2 additions & 2 deletions src/core/pal/feature.h
Expand Up @@ -226,8 +226,8 @@ namespace pal
* \param flip if TRUE label is placed on the other side of the line
* \returns calculated label position
*/
LabelPosition *curvedPlacementAtOffset( PointSet *path_positions, double *path_distances,
int &orientation, double distance, bool &reversed, bool &flip );
std::unique_ptr< LabelPosition > curvedPlacementAtOffset( PointSet *path_positions, double *path_distances,
int &orientation, double distance, bool &reversed, bool &flip );

/**
* Generate curved candidates for line features.
Expand Down
9 changes: 4 additions & 5 deletions src/core/pal/labelposition.cpp
Expand Up @@ -153,9 +153,8 @@ LabelPosition::LabelPosition( const LabelPosition &other )
h = other.h;

if ( other.nextPart )
nextPart = new LabelPosition( *other.nextPart );
else
nextPart = nullptr;
nextPart = qgis::make_unique< LabelPosition >( *other.nextPart );

partId = other.partId;
upsideDown = other.upsideDown;
reversed = other.reversed;
Expand Down Expand Up @@ -315,10 +314,10 @@ bool LabelPosition::isInConflictMultiPart( const LabelPosition *lp ) const
{
if ( tmp1->isInConflictSinglePart( tmp2 ) )
return true;
tmp2 = tmp2->nextPart;
tmp2 = tmp2->getNextPart();
}

tmp1 = tmp1->nextPart;
tmp1 = tmp1->getNextPart();
}
return false; // no conflict found
}
Expand Down
10 changes: 5 additions & 5 deletions src/core/pal/labelposition.h
Expand Up @@ -100,8 +100,6 @@ namespace pal
//! Copy constructor
LabelPosition( const LabelPosition &other );

~LabelPosition() override { delete nextPart; }

/**
* \brief Is the labelposition in the bounding-box ? (intersect or inside????)
*
Expand Down Expand Up @@ -272,8 +270,8 @@ namespace pal
bool getUpsideDown() const { return upsideDown; }

Quadrant getQuadrant() const { return quadrant; }
LabelPosition *getNextPart() const { return nextPart; }
void setNextPart( LabelPosition *next ) { nextPart = next; }
LabelPosition *getNextPart() const { return nextPart.get(); }
void setNextPart( std::unique_ptr< LabelPosition > next ) { nextPart = std::move( next ); }

// -1 if not multi-part
int getPartId() const { return partId; }
Expand Down Expand Up @@ -324,7 +322,6 @@ namespace pal
double w;
double h;

LabelPosition *nextPart = nullptr;
int partId;

//True if label direction is the same as line / polygon ring direction.
Expand All @@ -337,6 +334,9 @@ namespace pal
LabelPosition::Quadrant quadrant;

private:

std::unique_ptr< LabelPosition > nextPart;

double mCost;
bool mHasObstacleConflict;
bool mHasHardConflict = false;
Expand Down

0 comments on commit 10bda51

Please sign in to comment.