Remove unnecessary dynamic allocation (#18014)

* don't dynamically allocate PointArray's internal vector. take advantage of move semantics where possible.

* don't dynamically allocate RichText's _elementRenders vectors
This commit is contained in:
kepler-5 2017-07-03 23:31:29 -07:00 committed by minggo
parent fec74ac549
commit bbe84f8d7a
4 changed files with 42 additions and 75 deletions

View File

@ -33,6 +33,8 @@
#include "2d/CCActionCatmullRom.h" #include "2d/CCActionCatmullRom.h"
#include "2d/CCNode.h" #include "2d/CCNode.h"
#include <iterator>
using namespace std; using namespace std;
NS_CC_BEGIN; NS_CC_BEGIN;
@ -56,25 +58,18 @@ PointArray* PointArray::create(ssize_t capacity)
bool PointArray::initWithCapacity(ssize_t capacity) bool PointArray::initWithCapacity(ssize_t capacity)
{ {
_controlPoints = new (std::nothrow) vector<Vec2*>(); _controlPoints.reserve(capacity);
if (capacity > 0) {
_controlPoints->reserve(capacity);
}
return true; return true;
} }
PointArray* PointArray::clone() const PointArray* PointArray::clone() const
{ {
vector<Vec2*> *newArray = new (std::nothrow) vector<Vec2*>(); vector<Vec2> newArray = _controlPoints;
for (auto& controlPoint : *_controlPoints)
{
newArray->push_back(new Vec2(controlPoint->x, controlPoint->y));
}
PointArray *points = new (std::nothrow) PointArray(); PointArray *points = new (std::nothrow) PointArray();
points->initWithCapacity(10); points->initWithCapacity(10);
points->setControlPoints(newArray); points->setControlPoints(std::move(newArray));
points->autorelease(); points->autorelease();
return points; return points;
@ -83,98 +78,76 @@ PointArray* PointArray::clone() const
PointArray::~PointArray() PointArray::~PointArray()
{ {
CCLOGINFO("deallocing PointArray: %p", this); CCLOGINFO("deallocing PointArray: %p", this);
for (auto& controlPoint : *_controlPoints)
{
delete controlPoint;
}
delete _controlPoints;
} }
PointArray::PointArray() :_controlPoints(nullptr){} PointArray::PointArray() {}
const std::vector<Vec2*>* PointArray::getControlPoints() const const std::vector<Vec2>& PointArray::getControlPoints() const
{ {
return _controlPoints; return _controlPoints;
} }
void PointArray::setControlPoints(vector<Vec2*> *controlPoints) void PointArray::setControlPoints(vector<Vec2> controlPoints)
{ {
CCASSERT(controlPoints != nullptr, "control points should not be nullptr"); _controlPoints = std::move(controlPoints);
// delete old points
vector<Vec2*>::iterator iter;
for (auto& controlPoint : *_controlPoints)
{
delete controlPoint;
}
delete _controlPoints;
_controlPoints = controlPoints;
} }
void PointArray::addControlPoint(const Vec2& controlPoint) void PointArray::addControlPoint(const Vec2& controlPoint)
{ {
_controlPoints->push_back(new Vec2(controlPoint.x, controlPoint.y)); _controlPoints.push_back(controlPoint);
} }
void PointArray::insertControlPoint(const Vec2 &controlPoint, ssize_t index) void PointArray::insertControlPoint(const Vec2& controlPoint, ssize_t index)
{ {
Vec2 *temp = new (std::nothrow) Vec2(controlPoint.x, controlPoint.y); _controlPoints.insert(std::next(_controlPoints.begin(), index), controlPoint);
_controlPoints->insert(_controlPoints->begin() + index, temp);
} }
Vec2 PointArray::getControlPointAtIndex(ssize_t index) const Vec2& PointArray::getControlPointAtIndex(ssize_t index) const
{ {
index = MIN(static_cast<ssize_t>(_controlPoints->size())-1, MAX(index, 0)); index = MIN(static_cast<ssize_t>(_controlPoints.size())-1, MAX(index, 0));
return *(_controlPoints->at(index)); return _controlPoints.at(index);
} }
void PointArray::replaceControlPoint(const Vec2 &controlPoint, ssize_t index) void PointArray::replaceControlPoint(const Vec2& controlPoint, ssize_t index)
{ {
Vec2 *temp = _controlPoints->at(index); _controlPoints.at(index) = controlPoint;
temp->x = controlPoint.x;
temp->y = controlPoint.y;
} }
void PointArray::removeControlPointAtIndex(ssize_t index) void PointArray::removeControlPointAtIndex(ssize_t index)
{ {
vector<Vec2*>::iterator iter = _controlPoints->begin() + index; vector<Vec2>::iterator iter = std::next(_controlPoints.begin(), index);
Vec2* removedPoint = *iter; _controlPoints.erase(iter);
_controlPoints->erase(iter);
delete removedPoint;
} }
ssize_t PointArray::count() const ssize_t PointArray::count() const
{ {
return _controlPoints->size(); return _controlPoints.size();
} }
PointArray* PointArray::reverse() const PointArray* PointArray::reverse() const
{ {
vector<Vec2*> *newArray = new (std::nothrow) vector<Vec2*>(); vector<Vec2> newArray;
Vec2 *point = nullptr; newArray.reserve(_controlPoints.size());
for (auto iter = _controlPoints->rbegin(), iterRend = _controlPoints->rend(); iter != iterRend; ++iter) for (auto iter = _controlPoints.rbegin(), iterRend = _controlPoints.rend(); iter != iterRend; ++iter)
{ {
point = *iter; newArray.push_back(*iter);
newArray->push_back(new Vec2(point->x, point->y));
} }
PointArray *config = PointArray::create(0); PointArray *config = PointArray::create(0);
config->setControlPoints(newArray); config->setControlPoints(std::move(newArray));
return config; return config;
} }
void PointArray::reverseInline() void PointArray::reverseInline()
{ {
size_t l = _controlPoints->size(); const size_t l = _controlPoints.size();
Vec2 *p1 = nullptr; Vec2 *p1 = nullptr;
Vec2 *p2 = nullptr; Vec2 *p2 = nullptr;
float x, y; float x, y;
for (size_t i = 0; i < l/2; ++i) for (size_t i = 0; i < l/2; ++i)
{ {
p1 = _controlPoints->at(i); p1 = &_controlPoints.at(i);
p2 = _controlPoints->at(l-i-1); p2 = &_controlPoints.at(l-i-1);
x = p1->x; x = p1->x;
y = p1->y; y = p1->y;

View File

@ -96,7 +96,7 @@ public:
* @param controlPoint A control point. * @param controlPoint A control point.
* @param index Insert the point to array in index. * @param index Insert the point to array in index.
*/ */
void insertControlPoint(const Vec2 &controlPoint, ssize_t index); void insertControlPoint(const Vec2& controlPoint, ssize_t index);
/** Replaces an existing controlPoint at index. /** Replaces an existing controlPoint at index.
* *
@ -104,7 +104,7 @@ public:
* @param controlPoint A control point. * @param controlPoint A control point.
* @param index Replace the point to array in index. * @param index Replace the point to array in index.
*/ */
void replaceControlPoint(const Vec2 &controlPoint, ssize_t index); void replaceControlPoint(const Vec2& controlPoint, ssize_t index);
/** Get the value of a controlPoint at a given index. /** Get the value of a controlPoint at a given index.
* *
@ -112,7 +112,7 @@ public:
* @param index Get the point in index. * @param index Get the point in index.
* @return A Vec2. * @return A Vec2.
*/ */
Vec2 getControlPointAtIndex(ssize_t index); const Vec2& getControlPointAtIndex(ssize_t index) const;
/** Deletes a control point at a given index /** Deletes a control point at a given index
* *
@ -147,14 +147,14 @@ public:
/** /**
* @js NA * @js NA
*/ */
const std::vector<Vec2*>* getControlPoints() const; const std::vector<Vec2>& getControlPoints() const;
/** /**
* @js NA * @js NA
*/ */
void setControlPoints(std::vector<Vec2*> *controlPoints); void setControlPoints(std::vector<Vec2> controlPoints);
private: private:
/** Array that contains the control points. */ /** Array that contains the control points. */
std::vector<Vec2*> *_controlPoints; std::vector<Vec2> _controlPoints;
}; };
/** @class CardinalSplineTo /** @class CardinalSplineTo

View File

@ -1719,7 +1719,7 @@ void RichText::handleCustomRenderer(cocos2d::Node *renderer)
void RichText::addNewLine() void RichText::addNewLine()
{ {
_leftSpaceWidth = _customSize.width; _leftSpaceWidth = _customSize.width;
_elementRenders.push_back(new Vector<Node*>()); _elementRenders.emplace_back();
} }
void RichText::formarRenderers() void RichText::formarRenderers()
@ -1730,10 +1730,9 @@ void RichText::formarRenderers()
float nextPosY = 0.0f; float nextPosY = 0.0f;
for (auto& element: _elementRenders) for (auto& element: _elementRenders)
{ {
Vector<Node*>* row = element;
float nextPosX = 0.0f; float nextPosX = 0.0f;
float maxY = 0.0f; float maxY = 0.0f;
for (auto& iter : *row) for (auto& iter : element)
{ {
iter->setAnchorPoint(Vec2::ZERO); iter->setAnchorPoint(Vec2::ZERO);
iter->setPosition(nextPosX, nextPosY); iter->setPosition(nextPosX, nextPosY);
@ -1754,9 +1753,9 @@ void RichText::formarRenderers()
for (size_t i=0, size = _elementRenders.size(); i<size; i++) for (size_t i=0, size = _elementRenders.size(); i<size; i++)
{ {
Vector<Node*>* row = (_elementRenders[i]); Vector<Node*>& row = _elementRenders[i];
float maxHeight = 0.0f; float maxHeight = 0.0f;
for (auto& iter : *row) for (auto& iter : row)
{ {
maxHeight = MAX(iter->getContentSize().height, maxHeight); maxHeight = MAX(iter->getContentSize().height, maxHeight);
} }
@ -1767,11 +1766,11 @@ void RichText::formarRenderers()
float nextPosY = _customSize.height; float nextPosY = _customSize.height;
for (size_t i=0, size = _elementRenders.size(); i<size; i++) for (size_t i=0, size = _elementRenders.size(); i<size; i++)
{ {
Vector<Node*>* row = (_elementRenders[i]); Vector<Node*>& row = _elementRenders[i];
float nextPosX = 0.0f; float nextPosX = 0.0f;
nextPosY -= (maxHeights[i] + _defaults.at(KEY_VERTICAL_SPACE).asFloat()); nextPosY -= (maxHeights[i] + _defaults.at(KEY_VERTICAL_SPACE).asFloat());
for (auto& iter : *row) for (auto& iter : row)
{ {
iter->setAnchorPoint(Vec2::ZERO); iter->setAnchorPoint(Vec2::ZERO);
iter->setPosition(nextPosX, nextPosY); iter->setPosition(nextPosX, nextPosY);
@ -1782,11 +1781,6 @@ void RichText::formarRenderers()
delete [] maxHeights; delete [] maxHeights;
} }
for (auto& iter : _elementRenders)
{
iter->clear();
delete iter;
}
_elementRenders.clear(); _elementRenders.clear();
if (_ignoreSize) if (_ignoreSize)
@ -1812,7 +1806,7 @@ void RichText::pushToContainer(cocos2d::Node *renderer)
{ {
return; return;
} }
_elementRenders[_elementRenders.size()-1]->pushBack(renderer); _elementRenders[_elementRenders.size()-1].pushBack(renderer);
} }
void RichText::setVerticalSpace(float space) void RichText::setVerticalSpace(float space)

View File

@ -562,7 +562,7 @@ protected:
bool _formatTextDirty; bool _formatTextDirty;
Vector<RichElement*> _richElements; Vector<RichElement*> _richElements;
std::vector<Vector<Node*>*> _elementRenders; std::vector<Vector<Node*>> _elementRenders;
float _leftSpaceWidth; float _leftSpaceWidth;
ValueMap _defaults; /*!< default values */ ValueMap _defaults; /*!< default values */