Commit 50d034a1 authored by John Bonn's avatar John Bonn
Browse files

Updated documentation of workOrder for new design.

parent 6b36e8bb
Loading
Loading
Loading
Loading
+27 −40
Original line number Diff line number Diff line
@@ -1098,27 +1098,16 @@ namespace Isis {
   *        input.
   *  
   * @description This method is designed to be implemented by children work orders, but they need
   * to call this version inside of their setupExecution (at the beginning). The order of execution 
   * for work orders is: 
   *   setupExecution() - GUI thread, can ask user for input
   *   syncRedo() - GUI thread, should not prompt the user for input
   *   asyncRedo() - Pooled thread postSyncRedo() - GUI thread
   *
   *   syncUndo() - GUI thread, always called after redo finishes
   *   asyncUndo() - Pooled thread
   *   postSyncUndo() - GUI thread
   *
   *   syncRedo() - GUI thread
   *   asyncRedo() - Pooled thread
   *   postSyncRedo() - GUI thread
   *
   *   and so on...
   *
   * to call this version inside of their setupExecution (at the beginning).

   * State should only be set in the parent WorkOrder class in this method. You can set arbitrary
   *   state using setInternalData(). This method is always executed in the GUI thread and is the
   *   only place to ask the user questions.
   *
   * @return @b bool Returns True upon successful execution of the WorkOrder, False otherwise.
   * If this method returns false the workorder will be cancelled and will not be executed.
   *
   * @return @b bool Returns True upon successful preparation of the WorkOrder, False to
   *         cancel the workorder.
   */
  bool WorkOrder::setupExecution() {
    // We're finished at this point if we save/open a project, we're not finished if we need to do
@@ -1236,24 +1225,22 @@ namespace Isis {
  /**
   * @description Execute the workorder.
   * Execute() does the actual work in the work order. All necessary data for the execution (and
   * undo) of the
   * workorder should have been saved in the workorder prior to execute().  Execute() is also called
   * to redo a workorder for redoable workorders.  If the workorder is a synchrounous workorder
   * the workorder will be run on the GUI thread, otherwise it will be queued and run on a separate
   * thread.
   * undo) of the workorder should have been saved in the workorder prior to execute().  Execute()
   * is also called to redo a workorder for redoable workorders.  If the workorder is a synchrounous
   * workorder the workorder will be run on the GUI thread, otherwise it will be queued and run on a
   * separate thread.
   *
   * For Synchronous workorders:
   * State should only be read from the parent WorkOrder class in this method. You can set state to
   * be used in asyncRedo() and postSyncRedo() safely. This method is always executed in the GUI
   * thread and has no progress.
   * postExecution() safely. This method is always executed in the GUI thread.
   *
   * For asynchronous workorders:
   * State can be read from the parent WorkOrder class and from state set in syncRedo() while in
   *   this method. You can set state to be used in postSyncRedo() safely. Please be wary of
   * State can be read from the parent WorkOrder class while in
   *   this method. You can set state to be used in postExecution() safely. Please be wary of
   *   creating QObjects inside of this method because they will associated with the pooled thread
   *   and must be moved back to the GUI thread with QObject::moveToThread().  You can update
   *   progress by calling setProgressRange() and
   *   setProgressValue(). Please do not manipulate any GUI objects here.
   *   progress by calling setProgressRange() and setProgressValue(). Do not manipulate any
   *   GUI objects here.
   */
  void WorkOrder::execute() {
  }
@@ -1275,16 +1262,16 @@ namespace Isis {
   * The workorder should have all state necessary to undo itself stored in the workorder.
   *
   * For synchronous workorders:
   * State should only be read from the parent WorkOrder class in this method. You can set state to
   *   be used in asyncUndo() and postSyncUndo() safely. This method is always executed in the GUI
   *   State should only be read from the parent WorkOrder class in this method. You can set state
   *   to be used in postUndoExecution() safely. This method is always executed in the GUI
   *   thread and has no progress.
   *
   * For Asynchronous workorders:
   * State can be read from the parent WorkOrder class and from state set in syncUndo() while in
   *   this method. You can set state to be used in postSyncUndo() safely. Please be wary of
   *   deleting QObjects inside of this method because they will cause unpredictable crashes. This
   *   method is never executed in the GUI thread. You can update progress by calling
   *   setProgressRange() and setProgressValue(). Please do not manipulate any GUI objects here.
   *   State can be read from the parent WorkOrder class while in this method. You can set state
   *   to be used in postSyncUndo() safely. Please be wary of deleting QObjects inside of this
   *   method because they will cause unpredictable crashes. This method is never executed in the
   *   GUI thread. You can update progress by calling setProgressRange() and setProgressValue().
   *   Do not manipulate any GUI objects here.
   */
  void WorkOrder::undoExecution() {
  }
@@ -1293,8 +1280,8 @@ namespace Isis {
  /**
   * @description Perform any steps necessary after an undo of a workorder.
   *
   * State can be read from the parent WorkOrder class and from state set in either syncUndo() or
   *   asyncUndo() while in this method. You can not set state to be used in any of the redo code
   *  State can be read from the parent WorkOrder class and from state set undoExecution() while
   *  in this method. You can not set state to be used in any of the redo code
   *  safely. This method is always executed in the GUI thread and has no progress.
   */
  void WorkOrder::postUndoExecution() {
+49 −17
Original line number Diff line number Diff line
@@ -59,27 +59,58 @@ namespace Isis {
   *   undo/redo capabilities (which need to be implemented correctly), and the ability for the
   *   project to guarantee a good state on disk.
   *
   * State between the end of setupExecution() and the beginning of the redo methods must be saved 
   *   via the parent (WorkOrder) class. This is to ensure serializability. State between the redo
   *   methods and undo methods should work the same way. Child implementations may only save state
   *   (have member variables) that store state between syncRedo(), asyncRedo() and postSyncRedo()
   *   OR between syncUndo(), asyncUndo() and postSyncUndo(). Other forms of state will cause the
   * State between the end of setupExecution() and the beginning of the execute() method must be saved
   *   via the parent (WorkOrder) class. This is to ensure serializability. State between the execute()
   *   method and undoExecution() should work the same way. Child implementations may only save state
   *   (have member variables) that store state between execute() and postExecution()
   *   OR between undoExecution() and postUndoExecution(). Other forms of state will cause the
   *   work order to not function properly when saved/restored from disk.
   *  
   *   The order of execution for work orders is:
   *   setupExecution() - GUI thread, can ask user for input
   *   syncRedo() - GUI thread, should not prompt the user for input
   *   asyncRedo() - Pooled thread postSyncRedo() - GUI thread
   *   execute() - run on either the GUI thread or a non-GUI thread as specified by the m_isSynchronous flag
   *   postExecution() -
   *
   *   syncUndo() - GUI thread, always called after redo finishes
   *   asyncUndo() - Pooled thread
   *   postSyncUndo() - GUI thread
   *
   *   syncRedo() - GUI thread
   *   asyncRedo() - Pooled thread
   *   postSyncRedo() - GUI thread
   *   undoExecution() - run on either the GUI thread or a non-GUI thread as specified by the
   *                     m_isSynchronous flag
   *   postUndoExecution() -
   *
   * @startuml {workOrderFlow.png} "WorkOrder Flow"
   * |GUI thread|
   * start
   * :User selects workorder from menu<
   * if (workOrder::setupExecution()) then (true)
   *  repeat
   *   if (WorkOrder::isSynchronous()) then (true)
   *     :WorkOrder::execute() on GUI thread;
   *   else (false)
   *     |non-GUI thread|
   *     :WorkOrder::execute() on non-GUI thread;
   *     |GUI thread|
   *   endif
   *   :WorkOrder::postExecute();
   *
   *  :User selects undo from menu<
   *
   *   if (WorkOrder::isSynchronous()) then (true)
   *     :WorkOrder::undoExecution();
   *   else (false)
   *     |non-GUI thread|
   *     :WorkOrder::undoExecution();
   *    |GUI thread|
   *  endif
   *  :WorkOrder::postUndoExecution();
   *
   * :User selects redo from menu<
   * repeat while (test)
   *
   * else (false)
   *   stop
   * endif
   * stop
   * @enduml
   *
   *   and so on...
   *
   * @author 2012-??-?? Steven Lambright and Stuart Sides
   *
@@ -230,8 +261,8 @@ namespace Isis {
       *   work order. This could be a list of file names, an ImageList of images you're viewing,
       *   or really anything else.
       *
       * Finally, the actual work needs done in *Redo(), using only state (data) stored by the
       *   parent (this) WorkOrder class. You do not have to call *Redo() - this is done for you
       * Finally, the actual work needs done in execute(), using only state (data) stored by the
       *   parent (this) WorkOrder class. You do not have to call execute() - this is done for you
       *   by WorkOrder::redo().  WorkOrder::redo() is called from Project::addToProject() when the
       *   workOrder is pushed onto the undo stack.
       *
@@ -244,6 +275,7 @@ namespace Isis {
       *           into the history and redo will never be called.
       */
      virtual bool setupExecution();

      virtual void execute();

      virtual void redo();
@@ -344,7 +376,7 @@ namespace Isis {
      /**
       * Set the workorder to be undoable/redoable
       * This is defaulted to true - his will allow the workorder to be redone.  Note
       * the workorder Undo method must be implemented.  This will result on the
       * the workorder undoExecution() method must be implemented.  This will result on the
       * workorder being placed on the QUndoStack and being displayed in the history
       * as being undoable. If set to false, the work order will not be put on the
       * QUndoStack and the workorder will not be able to be undone.