Explorar o código

BUG: ctkWorkflow / ctkWorkflowStep - Fix memory leak

Delete Workflow setter in WorkflowStep as long as we don't want the user to create unassociated steps.
It avoids having trouble when cleaning between WorflowStep & WotkflowStepWidget.
Create a list of registered worflowStep in workflow_p to manage the cleaning.
Every time a workflowStep (but not workflowStepWidget) is created, it registrates in the workflow.
The workflow manages then the destruction of the steps when he calls his dtor.
Michael.jeulinl %!s(int64=13) %!d(string=hai) anos
pai
achega
f0609f790a

+ 1 - 0
Libs/Core/Testing/Cpp/ctkWorkflowTest2.cpp

@@ -126,6 +126,7 @@ int ctkWorkflowTest2(int argc, char * argv [] )
   ctkWorkflow *workflow = new ctkWorkflow();
   ctkWorkflowStep *step1 = new ctkWorkflowStep(workflow, "Step 1");
   step1->setName("Step 1");
+  step1->setId("FirstStep");
   step1->setDescription("Description for step 1");
   ctkWorkflowStep *step2 = new ctkWorkflowStep(workflow, "Step 2");
   step2->setName("Step 2");

+ 10 - 0
Libs/Core/ctkWorkflow.cpp

@@ -538,6 +538,10 @@ ctkWorkflow::~ctkWorkflow()
     {
     d->StateMachine->stop();
     }
+
+  // Clean registered step
+  while (!d->registeredSteps.isEmpty())
+      delete d->registeredSteps.takeFirst();
 }
 
 // --------------------------------------------------------------------------
@@ -620,6 +624,12 @@ bool ctkWorkflow::addTransition(ctkWorkflowStep* origin, ctkWorkflowStep* destin
   return true;
 }
 
+void ctkWorkflow::registerWorkflowStep(ctkWorkflowStep* step)
+{
+  Q_D(ctkWorkflow);
+  d->registeredSteps.append(step);
+}
+
 // --------------------------------------------------------------------------
 bool ctkWorkflow::hasTransition(ctkWorkflowStep* origin, ctkWorkflowStep* destination,
                                 const QString& branchId,

+ 3 - 0
Libs/Core/ctkWorkflow.h

@@ -110,6 +110,9 @@ public:
   Q_INVOKABLE ctkWorkflowStep* initialStep()const;
   Q_INVOKABLE virtual void setInitialStep(ctkWorkflowStep* step);
 
+  /// \brief Register standard steps for cleaning purpose
+  Q_INVOKABLE virtual void registerWorkflowStep(ctkWorkflowStep* step);
+
   /// Get the current step of the state machine
   Q_INVOKABLE ctkWorkflowStep* currentStep()const;
 

+ 2 - 1
Libs/Core/ctkWorkflowStep.cpp

@@ -127,6 +127,7 @@ ctkWorkflowStep::ctkWorkflowStep(ctkWorkflow* newWorkflow, const QString& newId)
 
   d->Id = newId;
   d->Workflow = newWorkflow;
+  newWorkflow->registerWorkflowStep(this);
 }
 
 // --------------------------------------------------------------------------
@@ -141,6 +142,7 @@ ctkWorkflowStep::ctkWorkflowStep(ctkWorkflowStepPrivate * pimpl,
   Q_D(ctkWorkflowStep);
   d->Id = newId;
   d->Workflow = newWorkflow;
+  newWorkflow->registerWorkflowStep(this);
 }
 
 // --------------------------------------------------------------------------
@@ -150,7 +152,6 @@ ctkWorkflowStep::~ctkWorkflowStep()
 
 // --------------------------------------------------------------------------
 CTK_GET_CPP(ctkWorkflowStep, ctkWorkflow*, workflow, Workflow);
-CTK_SET_CPP(ctkWorkflowStep, ctkWorkflow*, setWorkflow, Workflow);
 
 // --------------------------------------------------------------------------
 CTK_GET_CPP(ctkWorkflowStep, QString, id, Id);

+ 3 - 0
Libs/Core/ctkWorkflow_p.h

@@ -266,6 +266,9 @@ public:
   typedef QMap<ctkWorkflowStep*, forwardAndBackwardSteps*> StepToForwardAndBackwardStepMapType;
   typedef QList<ctkWorkflowStep*>                          StepListType;
 
+  // Register a list of pointers to the steps in the worflow for cleaning purpose
+  StepListType registeredSteps;
+
   // Maintain a map of <state, step> key/value pairs, to find the step
   // that a given state belongs to
   typedef QMap<const QAbstractState*, ctkWorkflowStep*>           StateToStepMapType;