]> Creatis software - bbtk.git/blobdiff - kernel/doc/bbtkDevelopersGuide/bbtkDevelopersGuide.tex
Feature #1774
[bbtk.git] / kernel / doc / bbtkDevelopersGuide / bbtkDevelopersGuide.tex
index f35e947b7f5438b5e5010028d1005e80d3a54b2f..0b61996d1fdf4742dcbb8698f197f11403a41a8b 100644 (file)
-\documentclass[a4paper,11pt]{report}
+% # ---------------------------------------------------------------------
+% #
+% # Copyright (c) CREATIS (Centre de Recherche en Acquisition et Traitement de l'Image
+% #                        pour la SantÈ)
+% # Authors : Eduardo Davila, Frederic Cervenansky, Claire Mouton
+% # Previous Authors : Laurent Guigues, Jean-Pierre Roux
+% # CreaTools website : www.creatis.insa-lyon.fr/site/fr/creatools_accueil
+% #
+% #  This software is governed by the CeCILL-B license under French law and
+% #  abiding by the rules of distribution of free software. You can  use,
+% #  modify and/ or redistribute the software under the terms of the CeCILL-B
+% #  license as circulated by CEA, CNRS and INRIA at the following URL
+% #  http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
+% #  or in the file LICENSE.txt.
+% #
+% #  As a counterpart to the access to the source code and  rights to copy,
+% #  modify and redistribute granted by the license, users are provided only
+% #  with a limited warranty  and the software's author,  the holder of the
+% #  economic rights,  and the successive licensors  have only  limited
+% #  liability.
+% #
+% #  The fact that you are presently reading this means that you have had
+% #  knowledge of the CeCILL-B license and that you accept its terms.
+% # ------------------------------------------------------------------------ */
+%
+
+\documentclass[a4paper,11pt,final]{article}
 \input{config.tex}
 
 
-\def\todo{\scriptsize\fbox{\bf TODO !!}\normalsize}
-\def\x{\bm{x}}
-\def\BBTK{{\xspace}The {\bf Black Box Toolkit} }
-\def\bbtk{{\xspace}$\texttt{bbtk}$ }
-\def\bbi{{\xspace}$\texttt{bbi}$ }
-\def\bbStudio{{\xspace}$\texttt{bbStudio}$ }
-\def\bbfy{{\xspace}$\texttt{bbfy}$ }
-\def\bbdoc{{\xspace}$\texttt{bbdoc}$ }
-\def\bbCreatePackage{{\xspace}$\texttt{bbCreatePackage}$ }
 
-\def\bb{{\xspace}$\texttt{bb}$ }
-%\def\bbp{{\xspace}$\texttt{bbp}$\xspace}
+\begin{document}
+\bbtkGuide[Developer's Guide]
+
 
-\def\cmake{{\xspace}$\texttt{cmake}$ }
 
-\def\C{{\xspace}$\texttt{C}$ }
-\def\CPP{{\xspace}$\texttt{C++}$ }
 
-\def\xml{{\xspace}$\texttt{xml}$ }
 
-\def\itk{{\xspace}$\texttt{itk}$ }
-\def\vtk{{\xspace}$\texttt{vtk}$ }
-\def\gdcm{{\xspace}$\texttt{gdcm}$ }
-\def\gsmis{{\xspace}$\texttt{gsmis}$ }
-\def\wx{{\xspace}$\texttt{wxWidgets}$ }
+% ==========================================
+%\tableofcontents
+% ==========================================
 
-\def\lin{{\xspace}\textit{Linux} }
-\def\win{{\xspace}\textit{Windows} }
+% ==========================================
+\newpage
+\hrule
 
-% the same macros with no space at the end
+% ==========================================
+\section{Introduction}
+% ==========================================
 
-\def\BBTKns{{\xspace}The {\bf Black Box Toolkit}}
-\def\bbtkns{{\xspace}$\texttt{bbtk}$}
-\def\bbins{{\xspace}$\texttt{bbi}$}
-\def\bbfyns{{\xspace}$\texttt{bbfy}$}
-\def\bbdocns{{\xspace}$\texttt{bbdoc}$}
-\def\bbCreatePackagens{{\xspace}$\texttt{bbCreatePackage}$}
+% ==========================================
+\section{The library architecture}
+% ==========================================
 
-\def\bbns{{\xspace}$\texttt{bb}$}
-%\def\bbp{{\xspace}$\texttt{bbp}$\xspace}
+% ==========================================
+\subsection{BlackBox and related classes}
+% ==========================================
 
-\def\cmakens{{\xspace}$\texttt{cmake}$}
+% ==========================================
+\subsection{Factory and Package}
+% ==========================================
 
-\def\Cns{{\xspace}$\texttt{C}$}
-\def\CPPns{{\xspace}$\texttt{C++}$}
+% ==========================================
+\subsection{Interpreter, VirtualExec, Executer and Transcriptor}
+% ==========================================
 
-\def\xmlns{{\xspace}$\texttt{xml}$}
+% ==========================================
+\subsection{WxGUI elements}
+% ==========================================
 
-\def\itkns{{\xspace}$\texttt{itk}$}
-\def\vtkns{{\xspace}$\texttt{vtk}$}
-\def\gdcmns{{\xspace}$\texttt{gdcm}$}
-\def\gsmisns{{\xspace}$\texttt{gsmis}$}
-\def\wxns{{\xspace}$\texttt{wxWidgets}$}
+% ==========================================
+\subsection{Utilities}
+% ==========================================
 
-\def\linns{{\xspace}\textit{Linux}}
-\def\winns{{\xspace}\textit{Windows}}
+% ==========================================
+\section{Pipeline processing algorithm}
+% ==========================================
 
-\author{L. Guigues}
-\title{The Black Box Tool Kit\\Developers' Guide}
+% ==========================================
+\subsection{Input and output status}
+% ==========================================
+Each input of a black box has a Status, 
+of type IOStatus (defined in bbtkConnection.h) 
+which can take one of the three values:
+\begin{itemize}
+\item UPTODATE (==0): The input did not change since last processing 
+\item MODIFIED (==1): [Initial value on construction] The input changed since last processing but is synchronized with the amont box output to which it is connected, if any. This status has only a NOTIFICATION purpose, to let the processing method of the box know which inputs have changed since last time. If it is connected, a MODIFIED input will not call the amont box update during pipeline execution.
+\item OUTOFDATE (==2): The input changed since last processing and is NOT synchronized with the amont box output to which it is connected. This means that the pipeline update must recurse to the amont box next time it is executed, in order to update the input value.
+\end{itemize}
+The status of an input is stored by the class BlackBoxInputConnector.
 
-\begin{document}
-\maketitle
-\tableofcontents
-\chapter{Introduction}
+Each output of a black box instance also has a Status, 
+of type IOStatus but which can only take the two values:
+\begin{itemize}
+\item UPTODATE (==0): The output is up-to-date (the box does not need to be reprocessed).
+\item OUTOFDATE (==2): [Initial value on construction] The output is out-of-date (the box needs to be reprocessed).
+\end{itemize}
+The status of an output is stored by the class BlackBoxOutputConnector.
+
+If a box output 'O' is connected to another box input 'I' then there are some consistency constraints on their I/O statuses:
+
+\begin{tabular}{|l|p{10cm}|}
+\hline
+If & then \\ \hline
+'I' is UPTODATE & 'O' is necesseraly UPTODATE\\
+'I' is MODIFIED & 'O' is necesseraly UPTODATE\\
+'I' is OUTOFDATE & 'O' can be in any Status (The case 'O' is UPTODATE occurs for example when the amont box was created and executed - hence setting its outputs UPTODATE - *BEFORE* being connected to the aval box)\\ \hline
+'O' is UPTODATE & 'I' can be in any Status\\
+'O' is OUTOFDATE & 'I' is necessarly OUTOFDATE\\ \hline
+\end{tabular}
+
+The status of an input can be modified:
+\begin{itemize}
+\item By BlackBox::bbSetStatusAndPropagate which is called by:
+\begin{itemize}
+\item BlackBox::bbSetInput when a new value of an input is set.
+\item BlackBox::bbSignalOutputModification when the output which is connected to it is signaled as modified.
+\item BlackBox::bbConnectInput which is called when a Connection is connected to the input.
+\item Connection::OnOutputChange 
+\end{itemize}
+\item By BlackBox::bbComputePostProcessStatus which is called after bbProcess in BlackBox::bbRecursiveExecute.
+\item By Connection::RecursiveExecute which is responsible for updating its amont box, transfering the output value to the input and updating the input status.
+\end{itemize}
+
+The status of an output can be modifed in:
+\begin{itemize}
+\item By BlackBox::bbSetStatusAndPropagate, when propagating the new input status to the outputs. 
+\item By BlackBox::bbComputePostProcessStatus, which is called after bbProcess in BlackBox::bbRecursiveExecute.
+\end{itemize}
+
+
+% ==========================================
+\subsection{Pipeline execution}
+% ==========================================
+The main execution method of a black box is bbExecute.
+bbExecute checks werther the box is not already executing (bbGetExecuting()) 
+to prevent reentrance and 
+checks werther the execution is not frozen (bbGlobalGetFreezeExecution()).
+If it is not the case then it calls bbRecursiveExecute which is 
+the main recursive pipeline processing method of a box.
+
+bbRecursiveExecute does:
+\begin{enumerate}
+\item Update the inputs of the box calling bbUpdateInputs
+\item If at least one input is MODIFIED or OUTOFDATE or the 
+BoxProcessMode is 'Always' then it:
+\begin{enumerate}
+\item Calls the virtual method bbProcess 
+which is responsible for the actual box processing. 
+bbProcess is overloaded in AtomicBlackBox to call a user defined method 
+and in widget box descendents (WxBlackBox, KWBlackBox) to handle 
+the widget creation.
+\item Compute the post-process statuses of inputs and outputs calling 
+bbComputePostProcessStatus.
+\end{enumerate}
+\end{enumerate}
+\bigskip\hrule\begin{verbatim}
+void BlackBox::bbRecursiveExecute ( Connection::Pointer caller )
+{
+  // Updates the box inputs. Returns the max input IOStatus after update
+  IOStatus s = bbUpdateInputs();
+  // If at least one input is modified or BoxProcessMode=='Always'
+  if ( (s != UPTODATE) || bbBoxProcessModeIsAlways() )
+    {
+      // User process (virtual)
+      bbProcess();
+      // Compute the final status of inputs and outputs
+      bbComputePostProcessStatus();
+    }
+}
+\end{verbatim}\hrule\bigskip
+
+bbUpdateInputs iterates the InputConnectorMap of the box and 
+calls RecursiveExecute on each BlackBoxInputConnector. 
+It returns the max of the final status of the input connectors:
+\bigskip\hrule\begin{verbatim}
+IOStatus BlackBox::bbUpdateInputs()
+{
+  IOStatus s = UPTODATE;
+  InputConnectorMapType::iterator i;
+  for ( i = bbGetInputConnectorMap().begin(); 
+        i!= bbGetInputConnectorMap().end(); ++i) 
+    {
+      i->second->RecursiveExecute();
+      IOStatus t = i->second->GetStatus();
+      if (t > s) s = t;
+    }
+  return s;    
+}
+\end{verbatim}\hrule\bigskip
+
+bbComputPostProcessStatus computes the new status of inputs and outputs 
+after box processing.
+
+The input status update rules are simple:
+\begin{tabular}{|lll|}
+\hline
+UPTODATE & remains & UPTODATE\\ \hline
+MODIFIED & becomes & UPTODATE\\ \hline
+OUTOFDATE & remains & OUTOFDATE\\ \hline
+\end{tabular}
+
+The new output status is:
+
+\begin{tabular}{|ll|}
+\hline
+OUTOFDATE & if any input is OUTOFDATE\\ 
+& or bbBoxProcessModeIsAlways() is true\\ \hline
+UPTODATE & in any other case\\ \hline
+\end{tabular}
 
+\bigskip\hrule\begin{verbatim}
+void BlackBox::bbComputePostProcessStatus()
+{
+  // A priori, the new output status is UPTODATE 
+  // except if the BoxProcessMode is always
+  IOStatus new_output_status = UPTODATE;
+  if (bbBoxProcessModeIsAlways()) new_output_status = OUTOFDATE;
 
-\chapter{Misc}
-\section{Displaying messages}
+  // Update the input statuses
+  InputConnectorMapType::iterator i;
+  for ( i = bbGetInputConnectorMap().begin(); 
+        i!= bbGetInputConnectorMap().end(); ++i) 
+  {
+    IOStatus t = i->second->GetStatus();
+    // If any input is OUTOFDATE then the outputs also are
+    if (t == OUTOFDATE) new_output_status = OUTOFDATE;
+    // A previously MODIFIED status turns to UPTODATE
+    if (t==MODIFIED) i->second->SetStatus(UPTODATE);
+  }
+
+  // Update the output statuses
+  OutputConnectorMapType::iterator o;
+  for ( o = bbGetOutputConnectorMap().begin(); 
+        o!= bbGetOutputConnectorMap().end(); ++o) 
+  {
+    o->second->SetStatus(new_output_status);
+  }
+}
+\end{verbatim}\hrule\bigskip
+
+
+BlackBox::bbUpdateInputs may calls BlackBoxInputConnector::RecursiveExecute
+which is responsible for recursive update of the input value.
+If it is connected and its status is OUTOFDATE then it calls 
+RecursiveExecute on the Connection which is plugged into:
+\bigskip\hrule\begin{verbatim}
+void BlackBoxInputConnector::RecursiveExecute()
+{
+  // If connected and OUTOFDATE : recursive update
+  // Post-update status is updated by the connection 
+  // (either MODIFIED or OUTOFDATE)
+   if ( mConnection && (mStatus == OUTOFDATE) ) 
+    {
+      mConnection->RecursiveExecute();
+    }
+}
+\end{verbatim}\hrule\bigskip
+
+Connection::RecursiveExecute does:
+\begin{enumerate}
+\item Call bbRecursiveExecute on the initial box of the connection 
+\item Transfer the data from the initial box output to the final box input, adpating it if needed (add crossref).
+\item Update the final box input status. It sets it to:
+
+\begin{tabular}{lll}
+MODIFIED  & If the initial box output is & UPTODATE \\
+OUTOFDATE & If the initial box output is & OUTOFDATE 
+\end{tabular}
+\end{enumerate}
+
+\bigskip\hrule\begin{verbatim}
+void Connection::RecursiveExecute()
+{
+  // Calls bbRecursiveExecute on the initial box
+  mFrom->bbRecursiveExecute(GetThisPointer<Connection>());
+  // Transfers the data from the initial box output to the 
+  // final box input adapting it if necessary
+  TransferData();
+  // Updates the status of the final box input
+  IOStatus s = MODIFIED;
+  if ( mFrom->bbGetOutputConnector(mOutput).GetStatus() == OUTOFDATE) 
+    s = OUTOFDATE;
+  mTo->bbGetInputConnector(mInput).SetStatus(s);
+}
+\end{verbatim}\hrule\bigskip
+
+% ==========================================
+\subsection{The main processing method (bbProcess) overloads}
+% ==========================================
+
+BlackBox::bbProcess 
+
+
+
+
+% ==========================================
+\section{Misc}
+% ==========================================
+
+\subsection{Displaying messages}
+
+\begin{verbatim}
+bbtkMessage("Kind",level,"message "<<"to "<<" display : i="<<i<<std::endl);
+bbtkDebugMessage("Kind",level,"message "<<"to "<<" display : i="<<i<<std::endl);
+\end{verbatim}
 
 \section{Types and RTTI}
 
@@ -83,7 +318,7 @@ which is simply a typedef on
 \begin{verbatim}
 const std::type_info&
 \end{verbatim}
-Remember that all constructors ofthe std::type\_info class are private, 
+Remember that all constructors of the std::type\_info class are private, 
 hence objects can only be created by the operator \texttt{typeid} 
 which returns a const reference on a type\_info. 
 Hence the \bbtk type TypeInfo conveys that const reference