Commit 353d2496ceb630e2f574474c80ce75de7ba85ac7

Authored by Charles Otto
1 parent a5768458

Rework smartCopy

If we are doing nonsense like composing algorithms in memory, checking for
a NULL parent is not a viable way to detect when smartCopy has returned a
loose transform. This is because root transforms created through
algorithmCore or whatever also have NULL parents, but actually they will
be deleted via QSharedPointers, so adding them to a parent chain is
dangerous, and they can show up as child transforms if we say attach them
as children of a stream or distribute transform as part of a
parallelization scheme.

So, instead we add an output parameter to smartCopy indicating if the
returned pointer is a newly allocated transform, that is not already set
up to be deleted.
openbr/openbr_plugin.h
... ... @@ -1209,7 +1209,9 @@ public:
1209 1209 * and copy enough of their state that projectUpdate can safely be called on the original
1210 1210 * instance, and the copy concurrently.
1211 1211 */
1212   - virtual Transform * smartCopy() { return this;}
  1212 + virtual Transform * smartCopy(bool & newTransform) { newTransform=false; return this;}
  1213 +
  1214 + virtual Transform * smartCopy() {bool junk; return smartCopy(junk);}
1213 1215  
1214 1216 /*!
1215 1217 * \brief Recursively retrieve a named event, returns NULL if an event is not found.
... ...
openbr/plugins/meta.cpp
... ... @@ -614,13 +614,20 @@ class DistributeTemplateTransform : public MetaTransform
614 614  
615 615 public:
616 616  
617   - Transform * smartCopy()
  617 + Transform * smartCopy(bool & newTransform)
618 618 {
619   - if (!transform->timeVarying())
  619 + if (!transform->timeVarying()) {
  620 + newTransform = false;
620 621 return this;
  622 + }
  623 + newTransform = true;
621 624  
622 625 DistributeTemplateTransform * output = new DistributeTemplateTransform;
623   - output->transform = transform->smartCopy();
  626 + bool newChild = false;
  627 + output->transform = transform->smartCopy(newChild);
  628 + if (newChild)
  629 + output->transform->setParent(output);
  630 +
624 631 return output;
625 632 }
626 633  
... ...
openbr/plugins/openbr_internal.h
... ... @@ -139,8 +139,9 @@ public:
139 139 *\brief For transforms that don't do any training, this default implementation
140 140 * which creates a new copy of the Transform from its description string is sufficient.
141 141 */
142   - virtual Transform * smartCopy()
  142 + virtual Transform * smartCopy(bool & newTransform)
143 143 {
  144 + newTransform = true;
144 145 return this->clone();
145 146 }
146 147  
... ... @@ -250,10 +251,13 @@ public:
250 251 * it creates a new copy of its own class, and gives that copy the child transforms
251 252 * returned by calling smartCopy on this transforms children
252 253 */
253   - Transform * smartCopy()
  254 + Transform * smartCopy(bool & newTransform)
254 255 {
255   - if (!timeVarying())
  256 + if (!timeVarying()) {
  257 + newTransform = false;
256 258 return this;
  259 + }
  260 + newTransform = true;
257 261  
258 262 QString name = metaObject()->className();
259 263 name.replace("Transform","");
... ... @@ -266,8 +270,9 @@ public:
266 270  
267 271 foreach(Transform* t, transforms )
268 272 {
269   - Transform * maybe_copy = t->smartCopy();
270   - if (maybe_copy->parent() == NULL)
  273 + bool newItem = false;
  274 + Transform * maybe_copy = t->smartCopy(newItem);
  275 + if (newItem)
271 276 maybe_copy->setParent(output);
272 277 output->transforms.append(maybe_copy);
273 278 }
... ...
openbr/plugins/stream.cpp
... ... @@ -1092,10 +1092,6 @@ public:
1092 1092  
1093 1093 // dst is set to all output received by the final stage, along
1094 1094 // with anything output via the calls to finalize.
1095   - //dst = collectionStage->getOutput();
1096   -
1097   - // dst is set to all output received by the final stage, along
1098   - // with anything output via the calls to finalize.
1099 1095 foreach(const TemplateList & list, collector->sets) {
1100 1096 dst.append(list);
1101 1097 }
... ... @@ -1378,10 +1374,10 @@ public:
1378 1374 basis.init();
1379 1375 }
1380 1376  
1381   - Transform * smartCopy()
  1377 + Transform * smartCopy(bool & newTransform)
1382 1378 {
1383 1379 // We just want the DirectStream to begin with, so just return a copy of that.
1384   - DirectStreamTransform * res = (DirectStreamTransform *) basis.smartCopy();
  1380 + DirectStreamTransform * res = (DirectStreamTransform *) basis.smartCopy(newTransform);
1385 1381 res->activeFrames = this->activeFrames;
1386 1382 return res;
1387 1383 }
... ...