mirror of https://github.com/axmolengine/axmol.git
closed #4106: Object which isn't in Vector would also be released when invoking Vector::eraseObject.
Also refactored 'Vector::eraseObject': 1) Removed 'toRelease' parameter, Vector class should manage reference count. 2) Added 'removeAll' parameter to decide wether to remove all elements with the same value or just the first occurrence . 3) Added relevant UnitTest for 'Vector::eraseObject'.
This commit is contained in:
parent
2eb1c1bb73
commit
c6b2b86fe5
|
@ -309,18 +309,38 @@ public:
|
|||
last->release();
|
||||
}
|
||||
|
||||
/** @brief Remove a certain object.
|
||||
/** @brief Remove a certain object in Vector.
|
||||
* @param object The object to be removed.
|
||||
* @param toRelease Whether to decrease the referece count of the deleted object.
|
||||
* @param removeAll Whether to remove all elements with the same value.
|
||||
*/
|
||||
void eraseObject(T object, bool toRelease = true)
|
||||
void eraseObject(T object, bool removeAll = false)
|
||||
{
|
||||
CCASSERT(object != nullptr, "The object should not be nullptr");
|
||||
auto iter = std::find(_data.begin(), _data.end(), object);
|
||||
if (iter != _data.end())
|
||||
_data.erase(iter);
|
||||
if (toRelease)
|
||||
object->release();
|
||||
|
||||
if (removeAll)
|
||||
{
|
||||
for (auto iter = _data.begin(); iter != _data.end();)
|
||||
{
|
||||
if ((*iter) == object)
|
||||
{
|
||||
iter = _data.erase(iter);
|
||||
object->release();
|
||||
}
|
||||
else
|
||||
{
|
||||
++iter;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
auto iter = std::find(_data.begin(), _data.end(), object);
|
||||
if (iter != _data.end())
|
||||
{
|
||||
_data.erase(iter);
|
||||
object->release();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** @brief Removes from the vector with an iterator.
|
||||
|
|
|
@ -186,7 +186,7 @@ void Control::removeTargetWithActionForControlEvent(Ref* target, Handler action,
|
|||
|
||||
//remove all invocations if the target and action are null
|
||||
//TODO: should the invocations be deleted, or just removed from the array? Won't that cause issues if you add a single invocation for multiple events?
|
||||
bool bDeleteObjects=true;
|
||||
|
||||
if (!target && !action)
|
||||
{
|
||||
//remove objects
|
||||
|
@ -215,7 +215,7 @@ void Control::removeTargetWithActionForControlEvent(Ref* target, Handler action,
|
|||
}
|
||||
|
||||
for(const auto &invocation : tobeRemovedInvocations) {
|
||||
eventInvocationList.eraseObject(invocation, bDeleteObjects);
|
||||
eventInvocationList.eraseObject(invocation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -233,6 +233,47 @@ void TemplateVectorTest::onEnter()
|
|||
vec6.eraseObject(vec6.at(2));
|
||||
CCASSERT(vec6.at(2)->getTag() == 1013, "");
|
||||
vec6.clear();
|
||||
|
||||
auto objA = Node::create(); // retain count is 1
|
||||
auto objB = Node::create();
|
||||
auto objC = Node::create();
|
||||
{
|
||||
Vector<Node*> array1;
|
||||
Vector<Node*> array2;
|
||||
|
||||
// push back objA 3 times
|
||||
array1.pushBack(objA); // retain count is 2
|
||||
array1.pushBack(objA); // retain count is 3
|
||||
array1.pushBack(objA); // retain count is 4
|
||||
|
||||
array2.pushBack(objA); // retain count is 5
|
||||
array2.pushBack(objB);
|
||||
array2.pushBack(objC);
|
||||
|
||||
for (auto obj : array1) {
|
||||
array2.eraseObject(obj);
|
||||
}
|
||||
CCASSERT(objA->getReferenceCount() == 4, "");
|
||||
}
|
||||
CCASSERT(objA->getReferenceCount() == 1, "");
|
||||
|
||||
{
|
||||
Vector<Node*> array1;
|
||||
// push back objA 3 times
|
||||
array1.pushBack(objA); // retain count is 2
|
||||
array1.pushBack(objA); // retain count is 3
|
||||
array1.pushBack(objA); // retain count is 4
|
||||
CCASSERT(objA->getReferenceCount() == 4, "");
|
||||
array1.eraseObject(objA, true); // Remove all occurrences in the Vector.
|
||||
CCASSERT(objA->getReferenceCount() == 1, "");
|
||||
|
||||
array1.pushBack(objA); // retain count is 2
|
||||
array1.pushBack(objA); // retain count is 3
|
||||
array1.pushBack(objA); // retain count is 4
|
||||
|
||||
array1.eraseObject(objA, false);
|
||||
CCASSERT(objA->getReferenceCount() == 3, ""); // Only remove the first occurrence in the Vector.
|
||||
}
|
||||
|
||||
// Check the retain count in vec7
|
||||
CCASSERT(vec7.size() == 20, "");
|
||||
|
|
Loading…
Reference in New Issue