| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502 | 
							- /*=========================================================================
 
-   Library:   CTK
 
-   Copyright (c) Kitware Inc.
 
-   Licensed under the Apache License, Version 2.0 (the "License");
 
-   you may not use this file except in compliance with the License.
 
-   You may obtain a copy of the License at
 
-   http://www.commontk.org/LICENSE
 
-   Unless required by applicable law or agreed to in writing, software
 
-   distributed under the License is distributed on an "AS IS" BASIS,
 
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 
-   See the License for the specific language governing permissions and
 
-   limitations under the License.
 
-   =========================================================================*/
 
- // QT includes
 
- #include <QApplication>
 
- #include <QTimer>
 
- // CTK includes
 
- #include "ctkExampleDerivedWorkflowStep.h"
 
- #include "ctkWorkflow.h"
 
- // STD includes
 
- #include <cstdlib>
 
- #include <iostream>
 
- //-----------------------------------------------------------------------------
 
- int numberOfTimesEntryExitTest(ctkExampleDerivedWorkflowStep* step1=0, int step1Entry=0, int step1Exit=0, ctkExampleDerivedWorkflowStep* step2=0, int step2Entry=0, int step2Exit=0, ctkExampleDerivedWorkflowStep* step3=0, int step3Entry=0, int step3Exit=0, ctkExampleDerivedWorkflowStep* step4=0, int step4Entry=0, int step4Exit=0)
 
- {
 
-   if (step1)
 
-     {
 
-     if (step1->numberOfTimesRanOnEntry() != step1Entry || step1->numberOfTimesRanOnExit() != step1Exit)
 
-       {
 
-       return 0;
 
-       }
 
-     }
 
-   if (step2)
 
-     {
 
-     if (step2->numberOfTimesRanOnEntry() != step2Entry || step2->numberOfTimesRanOnExit() != step2Exit)
 
-       {
 
-       return 0;
 
-       }
 
-     }
 
-   if (step3)
 
-     {
 
-     if (step3->numberOfTimesRanOnEntry() != step3Entry || step3->numberOfTimesRanOnExit() != step3Exit)
 
-       {
 
-       return 0;
 
-       }
 
-     }
 
-   if (step4)
 
-     {
 
-     if (step4->numberOfTimesRanOnEntry() != step4Entry || step4->numberOfTimesRanOnExit() != step4Exit)
 
-       {
 
-       return 0;
 
-       }    
 
-     }
 
-   return 1;
 
- }
 
- //-----------------------------------------------------------------------------
 
- int currentStepAndNumberOfTimesEntryExitTest(ctkWorkflow* workflow, ctkExampleDerivedWorkflowStep* expectedStep, ctkExampleDerivedWorkflowStep* step1, int step1Entry, int step1Exit, ctkExampleDerivedWorkflowStep* step2, int step2Entry, int step2Exit, ctkExampleDerivedWorkflowStep* step3=0, int step3Entry=0, int step3Exit=0, ctkExampleDerivedWorkflowStep* step4=0, int step4Entry=0, int step4Exit=0)
 
- {
 
-   if (expectedStep)
 
-     {
 
-     if (workflow->currentStep() != expectedStep)
 
-       {
 
-       return 0;
 
-       }
 
-     }
 
-   return numberOfTimesEntryExitTest(step1, step1Entry, step1Exit, step2, step2Entry, step2Exit, step3, step3Entry, step3Exit, step4, step4Entry, step4Exit);
 
- }
 
- //-----------------------------------------------------------------------------
 
- int transitionTest(ctkWorkflow* workflow, int defaultTime, QApplication& app, ctkExampleDerivedWorkflowStep* expectedStep, ctkExampleDerivedWorkflowStep* step1, int step1Entry, int step1Exit, ctkExampleDerivedWorkflowStep* step2, int step2Entry, int step2Exit, ctkExampleDerivedWorkflowStep* step3=0, int step3Entry=0, int step3Exit=0, ctkExampleDerivedWorkflowStep* step4=0, int step4Entry=0, int step4Exit=0)
 
- {
 
-   QTimer::singleShot(defaultTime, &app, SLOT(quit()));
 
-   app.exec();
 
-   return currentStepAndNumberOfTimesEntryExitTest(workflow, expectedStep, step1, step1Entry, step1Exit, step2, step2Entry, step2Exit, step3, step3Entry, step3Exit, step4, step4Entry, step4Exit);
 
- }
 
- //-----------------------------------------------------------------------------
 
- int testStartWorkflow(ctkWorkflow* workflow, int defaultTime, QApplication& app, bool shouldRun, ctkExampleDerivedWorkflowStep* expectedStep=0, ctkExampleDerivedWorkflowStep* step1=0, int step1Entry=0, int step1Exit=0, ctkExampleDerivedWorkflowStep* step2=0, int step2Entry=0, int step2Exit=0, ctkExampleDerivedWorkflowStep* step3=0, int step3Entry=0, int step3Exit=0, ctkExampleDerivedWorkflowStep* step4=0, int step4Entry=0, int step4Exit=0)
 
- {
 
-   workflow->start();
 
-   QTimer::singleShot(defaultTime, &app, SLOT(quit()));
 
-   app.exec();
 
-   if (workflow->isRunning() != shouldRun)
 
-     {
 
-     return 0;
 
-     }
 
-   return currentStepAndNumberOfTimesEntryExitTest(workflow, expectedStep, step1, step1Entry, step1Exit, step2, step2Entry, step2Exit, step3, step3Entry, step3Exit, step4, step4Entry, step4Exit);
 
- }
 
- //-----------------------------------------------------------------------------
 
- int testStopWorkflow(ctkWorkflow* workflow, int defaultTime, QApplication& app, ctkExampleDerivedWorkflowStep* step1, int step1Entry, int step1Exit, ctkExampleDerivedWorkflowStep* step2, int step2Entry, int step2Exit, ctkExampleDerivedWorkflowStep* step3=0, int step3Entry=0, int step3Exit=0, ctkExampleDerivedWorkflowStep* step4=0, int step4Entry=0, int step4Exit=0)
 
- {
 
-   workflow->stop();
 
-   QTimer::singleShot(defaultTime, &app, SLOT(quit()));
 
-   app.exec();
 
-   if (workflow->isRunning())
 
-     {
 
-     return 0;
 
-     }
 
-   return numberOfTimesEntryExitTest(step1, step1Entry, step1Exit, step2, step2Entry, step2Exit, step3, step3Entry, step3Exit, step4, step4Entry, step4Exit);
 
- }
 
- //-----------------------------------------------------------------------------
 
- int ctkWorkflowTest1(int argc, char * argv [] )
 
- {
 
-   QApplication app(argc, argv);
 
-   int defaultTime = 100;
 
-   // create two steps and the workflow
 
-   ctkWorkflow *workflow = new ctkWorkflow();
 
-   ctkExampleDerivedWorkflowStep *step1 = new ctkExampleDerivedWorkflowStep(workflow, "Step 1");
 
-   step1->setName("Step 1");
 
-   step1->setDescription("Description for step 1");
 
-   ctkExampleDerivedWorkflowStep *step2 = new ctkExampleDerivedWorkflowStep(workflow, "Step 2");
 
-   step2->setName("Step 2");
 
-   step2->setDescription("Description for step 2");
 
-   // --------------------------------------------------------------------------
 
-   // try to add a transition for a step with the same id
 
-   ctkExampleDerivedWorkflowStep *step1Duplicated = new ctkExampleDerivedWorkflowStep(workflow, "Step 1");
 
-   if (workflow->addTransition(step1, step1Duplicated))
 
-     {
 
-     std::cerr << "workflow connected two steps with the same id";
 
-     return EXIT_FAILURE;
 
-     }
 
-   // try to add a transition from a step to itself
 
-   if (workflow->addTransition(step1, step1))
 
-     {
 
-     std::cerr << "workflow connected two steps with the same id";
 
-     return EXIT_FAILURE;
 
-     }
 
-   // --------------------------------------------------------------------------
 
-   // workflow with no steps
 
-   // try erroneously starting with no steps
 
-   if (!testStartWorkflow(workflow, defaultTime, app, false))
 
-     {
 
-     std::cerr << "empty workflow is running after start()";
 
-     return EXIT_FAILURE;
 
-     }
 
-   // add the first step
 
-   if (!workflow->addTransition(step1, 0))
 
-     {
 
-     std::cerr << "could not add first step";
 
-     return EXIT_FAILURE;
 
-     }
 
-   // try erroneously starting with no initial step
 
-   if (!testStartWorkflow(workflow, defaultTime, app, false))
 
-     {
 
-     std::cerr << "workflow is running after start() with no initial step";
 
-     return EXIT_FAILURE;
 
-     }
 
-   // --------------------------------------------------------------------------
 
-   // workflow with one step
 
-   
 
-   // set the initial step (which sets the initial state)
 
-   workflow->setInitialStep(step1);
 
-   // try starting with one step
 
-   if (!testStartWorkflow(workflow, defaultTime, app, true, step1, step1, 1, 0, step2, 0, 0))
 
-     {
 
-     std::cerr << "workflow is not running after start() with a single step";
 
-     return EXIT_FAILURE;
 
-     }
 
-   // triggering ValidationTransition and TransitionToPreviousStep
 
-   // should keep us in the same step, when there is only one step
 
-   workflow->goForward();
 
-   if (!transitionTest(workflow, defaultTime, app, step1, step1, 1, 0, step2, 0, 0))
 
-     {
 
-     std::cerr << "error in validation transition in a workflow with a single step";
 
-     return EXIT_FAILURE;
 
-     }
 
-   // transition to the previous step
 
-   workflow->goBackward();
 
-   if (!transitionTest(workflow, defaultTime, app, step1, step1, 1, 0, step2, 0, 0))
 
-     {
 
-     std::cerr << "error after transition to previous step in a workflow with a single step";
 
-     return EXIT_FAILURE;
 
-     }
 
-   // stop the workflow
 
-   if (!testStopWorkflow(workflow, defaultTime, app, step1, 1, 1, step2, 0, 0))
 
-     {
 
-     std::cerr << "workflow with one step still running after stop";
 
-     return EXIT_FAILURE;
 
-     }
 
-   // --------------------------------------------------------------------------
 
-   // workflow with two steps
 
-   // add the second step
 
-   if (!workflow->addTransition(step1, step2))
 
-     {
 
-     std::cerr << "could not add second step";
 
-     return EXIT_FAILURE;
 
-     }
 
-   // start the workflow
 
-   if (!testStartWorkflow(workflow, defaultTime, app, true, step1, step1, 2, 1, step2, 0, 0))
 
-     {
 
-     std::cerr << "workflow is not running after start() with two steps";
 
-     return EXIT_FAILURE;
 
-     }
 
-   // make sure the workflow has the steps
 
-   if (!workflow->hasStep(step1->id()))
 
-     {
 
-     std::cerr << "Step1 not added to workflow";
 
-     return EXIT_FAILURE;
 
-     }
 
-   if (!workflow->hasStep(step2->id()))
 
-     {
 
-     std::cerr << "Step2 not added to workflow";
 
-     return EXIT_FAILURE;
 
-     }
 
-   
 
-   // if (workflow->numberOfSteps() != 2)
 
-   //   {
 
-   //   std::cerr << "workflow has " << workflow->numberOfSteps() << " steps, not 2";
 
-   //   return EXIT_FAILURE;
 
-   //   }
 
-   // Test that the workflow transitions from processing to validation state
 
-   workflow->goForward();
 
-   if (!transitionTest(workflow, defaultTime, app, step2, step1, 2, 2, step2, 1, 0))
 
-     {
 
-     std::cerr << "error transitioning to next step in workflow with two steps";
 
-     return EXIT_FAILURE;
 
-     }
 
-   // Test that the workflow transitions back to the previous step
 
-   workflow->goBackward();
 
-   if (!transitionTest(workflow, defaultTime, app, step1, step1, 3, 2, step2, 1, 1))
 
-     {
 
-     std::cerr << "error transitioning to previous step in workflow with step steps";
 
-     return EXIT_FAILURE;
 
-     }
 
-   // make sure the workflow stops properly
 
-   if (!testStopWorkflow(workflow, defaultTime, app, step1, 3, 3, step2, 1, 1))
 
-     {
 
-     std::cerr << "workflow with two steps is running after stop()";
 
-     return EXIT_FAILURE;
 
-     }
 
-   // --------------------------------------------------------------------------
 
-   // Step3
 
-   ctkExampleDerivedWorkflowStep *step3 = new ctkExampleDerivedWorkflowStep(workflow, "Step 3");
 
-   step3->setName("Step 3");
 
-   step3->setDescription("Description for step 3");
 
-   // --------------------------------------------------------------------------
 
-   // Attempt to retrieve the forward or backward steps of step not yet added to the workflow
 
-   if (workflow->forwardSteps(step3).count() != 0)
 
-     {
 
-     std::cerr << "No forward steps should be associated with step3";
 
-     return EXIT_FAILURE;
 
-     }
 
-   if (workflow->backwardSteps(step3).count() != 0)
 
-     {
 
-     std::cerr << "No backward steps should be associated with step3";
 
-     return EXIT_FAILURE;
 
-     }
 
-   // --------------------------------------------------------------------------
 
-   // workflow with three steps
 
-   // add a third step manually
 
-   if (!workflow->addTransition(step2, step3, "", ctkWorkflow::Forward))
 
-     {
 
-     std::cerr << "could not add step 3 with forward transition";
 
-     return EXIT_FAILURE;
 
-     }
 
-   if (!workflow->addTransition(step2, step3, "",  ctkWorkflow::Backward))
 
-     {
 
-     std::cerr << "could not add next transition between step2 and step 3";
 
-     return EXIT_FAILURE;
 
-     }
 
-   if (workflow->forwardSteps(step1).length() != 1
 
-       || workflow->forwardSteps(step1).first() != step2
 
-       || workflow->forwardSteps(step2).length() != 1
 
-       || workflow->forwardSteps(step2).first() != step3
 
-       || workflow->forwardSteps(step3).length() != 0)
 
-     {
 
-     std::cerr << "error in list of forward steps" << std::endl;
 
-     return EXIT_FAILURE;
 
-     }
 
-   if (workflow->backwardSteps(step1).length() != 0
 
-       || workflow->backwardSteps(step2).length() != 1
 
-       || workflow->backwardSteps(step2).first() != step1
 
-       || workflow->backwardSteps(step3).length() != 1
 
-       || workflow->backwardSteps(step3).first() != step2)
 
-     {
 
-     std::cerr << "error in list of backward steps" << std::endl;
 
-     return EXIT_FAILURE;
 
-     }
 
-   if (!workflow->hasStep(step3->id()))
 
-     {
 
-     std::cerr << "Step3 not added to workflow";
 
-     return EXIT_FAILURE;
 
-     }
 
-   // if (workflow->numberOfSteps() != 3)
 
-   //   {
 
-   //   std::cerr << "workflow has " << workflow->numberOfSteps() << " steps, not 2";
 
-   //   return EXIT_FAILURE;
 
-   //   }
 
-   // now that we've stopped and restarted the state machine, we should
 
-   // be back in the initial step (step 1)
 
-   if (!testStartWorkflow(workflow, defaultTime, app, true, step1, step1, 4, 3, step2, 1, 1, step3, 0, 0))
 
-     {
 
-     std::cerr << "workflow is not running after start() with three steps";
 
-     return EXIT_FAILURE;
 
-     }
 
-   // test to make sure our lists of forward and backwards steps is correct
 
-   if (!workflow->canGoForward(step1)
 
-       || workflow->canGoBackward(step1)
 
-       || !workflow->canGoForward(step2)
 
-       || !workflow->canGoBackward(step2)
 
-       || workflow->canGoForward(step3)
 
-       || !workflow->canGoBackward(step3))
 
-     {
 
-     std::cerr << "error in can go forward/backward" << std::endl;
 
-     return EXIT_FAILURE;
 
-     }
 
-   // Test that the workflow transitions from step1 to step 2 to step 3
 
-   workflow->goForward();
 
-   QTimer::singleShot(defaultTime, &app, SLOT(quit()));
 
-   app.exec();
 
-   workflow->goForward();
 
-   if (!transitionTest(workflow, defaultTime, app, step3, step1, 4, 4, step2, 2, 2, step3, 1, 0))
 
-     {
 
-     std::cerr << "error transitioning to step3 in workflow with three steps";
 
-     return EXIT_FAILURE;
 
-     }
 
-   // Test that the workflow transitions back to the previous step
 
-   workflow->goBackward();
 
-   if (!transitionTest(workflow, defaultTime, app, step2, step1, 4, 4, step2, 3, 2, step3, 1, 1))
 
-     {
 
-     std::cerr << "error transitioning to previous step in workflow with three steps";
 
-     return EXIT_FAILURE;
 
-     }
 
-   // make sure the workflow stops properly
 
-   if (!testStopWorkflow(workflow, defaultTime, app, step1, 4, 4, step2, 3, 3, step3, 1, 1))
 
-     {
 
-     std::cerr << "error stopping workflow with three steps";
 
-     return EXIT_FAILURE;
 
-     }
 
-   // --------------------------------------------------------------------------
 
-   // workflow with a finish step (step 3)
 
-   // restart the workflow
 
-   if (!testStartWorkflow(workflow, defaultTime, app, true, step1, step1, 5, 4, step2, 3, 3, step3, 1, 1))
 
-     {
 
-     std::cerr << "workflow with finish step is not running after start()";
 
-     return EXIT_FAILURE;
 
-     }
 
-   // try to go automatically to step 3
 
-   workflow->goToStep("Step 3");
 
-   if (!transitionTest(workflow, defaultTime, app, step1, step1, 6, 5, step2, 4, 4, step3, 2, 2))
 
-     {
 
-     std::cerr << "error after going to finish step";
 
-     return EXIT_FAILURE;
 
-     }
 
-   // try to go automatically to step 3 again
 
-   workflow->goToStep("Step 3");
 
-   if (!transitionTest(workflow, defaultTime, app, step1, step1, 7, 6, step2, 5, 5, step3, 3, 3))
 
-     {
 
-     std::cerr << "error after going to finish step the second time";
 
-     return EXIT_FAILURE;
 
-     }
 
-   // stop workflow
 
-   if (!testStopWorkflow(workflow, defaultTime, app, step1, 7, 7, step2, 5, 5, step3, 3, 3))
 
-     {
 
-     std::cerr << "error stopping workflow with finish step";
 
-     return EXIT_FAILURE;
 
-     }
 
-   // --------------------------------------------------------------------------
 
-   // workflow with two finishing steps (step3 and step4)
 
-   ctkExampleDerivedWorkflowStep *step4 = new ctkExampleDerivedWorkflowStep(workflow, "Step 4");
 
-   step4->setName("Step 4");
 
-   step4->setDescription("Description for step 4");
 
-   workflow->addTransition(step3, step4);
 
-   // restart the workflow
 
-   if (!testStartWorkflow(workflow, defaultTime, app, true, step1, step1, 8, 7, step2, 5, 5, step3, 3, 3, step4, 0, 0))
 
-     {
 
-     std::cerr << "workflow with two finish steps is not running after start()";
 
-     return EXIT_FAILURE;
 
-     }
 
-   // try to go automatically to step 3
 
-   workflow->goToStep("Step 3");
 
-   if (!transitionTest(workflow, defaultTime, app, step1, step1, 9, 8, step2, 6, 6, step3, 4, 4, step4, 0, 0))
 
-     {
 
-     std::cerr << "error going to the first finish step of two";
 
-     return EXIT_FAILURE;
 
-     }
 
-   // try to go automatically to step 4
 
-   workflow->goToStep("Step 4");
 
-   if (!transitionTest(workflow, defaultTime, app, step1, step1, 10, 9, step2, 7, 7, step3, 5, 5, step4, 1, 1))
 
-     {
 
-     std::cerr << "error going to the second finish step of two";
 
-     return EXIT_FAILURE;
 
-     }
 
-   // go to step 3 (a finish step)
 
-   workflow->goForward();
 
-   QTimer::singleShot(defaultTime, &app, SLOT(quit()));
 
-   app.exec();
 
-   workflow->goForward();
 
-   if (!transitionTest(workflow, defaultTime, app, step3, step1, 10, 10, step2, 8, 8, step3, 6, 5, step4, 1, 1))
 
-     {
 
-     std::cerr << "error going from step1 to step3";
 
-     return EXIT_FAILURE;
 
-     }
 
-   // try to go automatically to step 4 (another goTo step)
 
-   workflow->goToStep("Step 4");
 
-   if (!transitionTest(workflow, defaultTime, app, step3, step1, 10, 10, step2, 8, 8, step3, 7, 6, step4, 2, 2))
 
-     {
 
-     std::cerr << "error going from the first finish step to the second finish step";
 
-     return EXIT_FAILURE;
 
-     }
 
-   // go to step 4, and then go forward (should not let you go past last step)
 
-   workflow->goForward();
 
-   QTimer::singleShot(defaultTime, &app, SLOT(quit()));
 
-   app.exec();
 
-   workflow->goForward();
 
-   if (!transitionTest(workflow, defaultTime, app, step4, step1, 10, 10, step2, 8, 8, step3, 7, 7, step4, 3, 2))
 
-     {
 
-     std::cerr << "error going forward past last step - shouldn't let you";
 
-     return EXIT_FAILURE;
 
-     }
 
-   // now try to go from step 4 to step 4 (should loop)
 
-   workflow->goToStep("Step 4");
 
-   if (!transitionTest(workflow, defaultTime, app, step4, step1, 10, 10, step2, 8, 8, step3, 7, 7, step4, 4, 3))
 
-     {
 
-     std::cerr << "error looping from step 4 to step 4";
 
-     return EXIT_FAILURE;
 
-     }  
 
-   // go back to step 3, and then go from step 3 to step 3 (should loop without hitting step4)
 
-   workflow->goBackward();
 
-   QTimer::singleShot(defaultTime, &app, SLOT(quit()));
 
-   app.exec();
 
-   workflow->goToStep("Step 3");
 
-   if (!transitionTest(workflow, defaultTime, app, step3, step1, 10, 10, step2, 8, 8, step3, 9, 8, step4, 4, 4))
 
-     {
 
-     std::cerr << "error looping from step 3 to step 3";
 
-     return EXIT_FAILURE;
 
-     }  
 
-   // handles deletions of the workflow, steps, states and transitions
 
-   delete workflow;
 
-   return EXIT_SUCCESS;
 
- }
 
 
  |