Browse Source

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 13 years ago
parent
commit
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;