]> Creatis software - bbtk.git/blob - kernel/doc/bbtkDevelopersGuide/bbtkDevelopersGuide.tex
Feature #1774
[bbtk.git] / kernel / doc / bbtkDevelopersGuide / bbtkDevelopersGuide.tex
1 % # ---------------------------------------------------------------------
2 % #
3 % # Copyright (c) CREATIS (Centre de Recherche en Acquisition et Traitement de l'Image
4 % #                        pour la SantÈ)
5 % # Authors : Eduardo Davila, Frederic Cervenansky, Claire Mouton
6 % # Previous Authors : Laurent Guigues, Jean-Pierre Roux
7 % # CreaTools website : www.creatis.insa-lyon.fr/site/fr/creatools_accueil
8 % #
9 % #  This software is governed by the CeCILL-B license under French law and
10 % #  abiding by the rules of distribution of free software. You can  use,
11 % #  modify and/ or redistribute the software under the terms of the CeCILL-B
12 % #  license as circulated by CEA, CNRS and INRIA at the following URL
13 % #  http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
14 % #  or in the file LICENSE.txt.
15 % #
16 % #  As a counterpart to the access to the source code and  rights to copy,
17 % #  modify and redistribute granted by the license, users are provided only
18 % #  with a limited warranty  and the software's author,  the holder of the
19 % #  economic rights,  and the successive licensors  have only  limited
20 % #  liability.
21 % #
22 % #  The fact that you are presently reading this means that you have had
23 % #  knowledge of the CeCILL-B license and that you accept its terms.
24 % # ------------------------------------------------------------------------ */
25 %
26
27 \documentclass[a4paper,11pt,final]{article}
28 \input{config.tex}
29
30
31
32 \begin{document}
33 \bbtkGuide[Developer's Guide]
34
35
36
37
38
39 % ==========================================
40 %\tableofcontents
41 % ==========================================
42
43 % ==========================================
44 \newpage
45 \hrule
46
47 % ==========================================
48 \section{Introduction}
49 % ==========================================
50
51 % ==========================================
52 \section{The library architecture}
53 % ==========================================
54
55 % ==========================================
56 \subsection{BlackBox and related classes}
57 % ==========================================
58
59 % ==========================================
60 \subsection{Factory and Package}
61 % ==========================================
62
63 % ==========================================
64 \subsection{Interpreter, VirtualExec, Executer and Transcriptor}
65 % ==========================================
66
67 % ==========================================
68 \subsection{WxGUI elements}
69 % ==========================================
70
71 % ==========================================
72 \subsection{Utilities}
73 % ==========================================
74
75 % ==========================================
76 \section{Pipeline processing algorithm}
77 % ==========================================
78
79 % ==========================================
80 \subsection{Input and output status}
81 % ==========================================
82 Each input of a black box has a Status, 
83 of type IOStatus (defined in bbtkConnection.h) 
84 which can take one of the three values:
85 \begin{itemize}
86 \item UPTODATE (==0): The input did not change since last processing 
87 \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.
88 \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.
89 \end{itemize}
90 The status of an input is stored by the class BlackBoxInputConnector.
91
92 Each output of a black box instance also has a Status, 
93 of type IOStatus but which can only take the two values:
94 \begin{itemize}
95 \item UPTODATE (==0): The output is up-to-date (the box does not need to be reprocessed).
96 \item OUTOFDATE (==2): [Initial value on construction] The output is out-of-date (the box needs to be reprocessed).
97 \end{itemize}
98 The status of an output is stored by the class BlackBoxOutputConnector.
99
100 If a box output 'O' is connected to another box input 'I' then there are some consistency constraints on their I/O statuses:
101
102 \begin{tabular}{|l|p{10cm}|}
103 \hline
104 If & then \\ \hline
105 'I' is UPTODATE & 'O' is necesseraly UPTODATE\\
106 'I' is MODIFIED & 'O' is necesseraly UPTODATE\\
107 '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
108 'O' is UPTODATE & 'I' can be in any Status\\
109 'O' is OUTOFDATE & 'I' is necessarly OUTOFDATE\\ \hline
110 \end{tabular}
111
112 The status of an input can be modified:
113 \begin{itemize}
114 \item By BlackBox::bbSetStatusAndPropagate which is called by:
115 \begin{itemize}
116 \item BlackBox::bbSetInput when a new value of an input is set.
117 \item BlackBox::bbSignalOutputModification when the output which is connected to it is signaled as modified.
118 \item BlackBox::bbConnectInput which is called when a Connection is connected to the input.
119 \item Connection::OnOutputChange 
120 \end{itemize}
121 \item By BlackBox::bbComputePostProcessStatus which is called after bbProcess in BlackBox::bbRecursiveExecute.
122 \item By Connection::RecursiveExecute which is responsible for updating its amont box, transfering the output value to the input and updating the input status.
123 \end{itemize}
124
125 The status of an output can be modifed in:
126 \begin{itemize}
127 \item By BlackBox::bbSetStatusAndPropagate, when propagating the new input status to the outputs. 
128 \item By BlackBox::bbComputePostProcessStatus, which is called after bbProcess in BlackBox::bbRecursiveExecute.
129 \end{itemize}
130
131
132 % ==========================================
133 \subsection{Pipeline execution}
134 % ==========================================
135 The main execution method of a black box is bbExecute.
136 bbExecute checks werther the box is not already executing (bbGetExecuting()) 
137 to prevent reentrance and 
138 checks werther the execution is not frozen (bbGlobalGetFreezeExecution()).
139 If it is not the case then it calls bbRecursiveExecute which is 
140 the main recursive pipeline processing method of a box.
141
142 bbRecursiveExecute does:
143 \begin{enumerate}
144 \item Update the inputs of the box calling bbUpdateInputs
145 \item If at least one input is MODIFIED or OUTOFDATE or the 
146 BoxProcessMode is 'Always' then it:
147 \begin{enumerate}
148 \item Calls the virtual method bbProcess 
149 which is responsible for the actual box processing. 
150 bbProcess is overloaded in AtomicBlackBox to call a user defined method 
151 and in widget box descendents (WxBlackBox, KWBlackBox) to handle 
152 the widget creation.
153 \item Compute the post-process statuses of inputs and outputs calling 
154 bbComputePostProcessStatus.
155 \end{enumerate}
156 \end{enumerate}
157 \bigskip\hrule\begin{verbatim}
158 void BlackBox::bbRecursiveExecute ( Connection::Pointer caller )
159 {
160   // Updates the box inputs. Returns the max input IOStatus after update
161   IOStatus s = bbUpdateInputs();
162   // If at least one input is modified or BoxProcessMode=='Always'
163   if ( (s != UPTODATE) || bbBoxProcessModeIsAlways() )
164     {
165       // User process (virtual)
166       bbProcess();
167       // Compute the final status of inputs and outputs
168       bbComputePostProcessStatus();
169     }
170 }
171 \end{verbatim}\hrule\bigskip
172
173 bbUpdateInputs iterates the InputConnectorMap of the box and 
174 calls RecursiveExecute on each BlackBoxInputConnector. 
175 It returns the max of the final status of the input connectors:
176 \bigskip\hrule\begin{verbatim}
177 IOStatus BlackBox::bbUpdateInputs()
178 {
179   IOStatus s = UPTODATE;
180   InputConnectorMapType::iterator i;
181   for ( i = bbGetInputConnectorMap().begin(); 
182         i!= bbGetInputConnectorMap().end(); ++i) 
183     {
184       i->second->RecursiveExecute();
185       IOStatus t = i->second->GetStatus();
186       if (t > s) s = t;
187     }
188   return s;    
189 }
190 \end{verbatim}\hrule\bigskip
191
192 bbComputPostProcessStatus computes the new status of inputs and outputs 
193 after box processing.
194
195 The input status update rules are simple:
196  
197 \begin{tabular}{|lll|}
198 \hline
199 UPTODATE & remains & UPTODATE\\ \hline
200 MODIFIED & becomes & UPTODATE\\ \hline
201 OUTOFDATE & remains & OUTOFDATE\\ \hline
202 \end{tabular}
203
204 The new output status is:
205
206 \begin{tabular}{|ll|}
207 \hline
208 OUTOFDATE & if any input is OUTOFDATE\\ 
209 & or bbBoxProcessModeIsAlways() is true\\ \hline
210 UPTODATE & in any other case\\ \hline
211 \end{tabular}
212
213 \bigskip\hrule\begin{verbatim}
214 void BlackBox::bbComputePostProcessStatus()
215 {
216   // A priori, the new output status is UPTODATE 
217   // except if the BoxProcessMode is always
218   IOStatus new_output_status = UPTODATE;
219   if (bbBoxProcessModeIsAlways()) new_output_status = OUTOFDATE;
220
221   // Update the input statuses
222   InputConnectorMapType::iterator i;
223   for ( i = bbGetInputConnectorMap().begin(); 
224         i!= bbGetInputConnectorMap().end(); ++i) 
225   {
226     IOStatus t = i->second->GetStatus();
227     // If any input is OUTOFDATE then the outputs also are
228     if (t == OUTOFDATE) new_output_status = OUTOFDATE;
229     // A previously MODIFIED status turns to UPTODATE
230     if (t==MODIFIED) i->second->SetStatus(UPTODATE);
231   }
232
233   // Update the output statuses
234   OutputConnectorMapType::iterator o;
235   for ( o = bbGetOutputConnectorMap().begin(); 
236         o!= bbGetOutputConnectorMap().end(); ++o) 
237   {
238     o->second->SetStatus(new_output_status);
239   }
240 }
241 \end{verbatim}\hrule\bigskip
242
243
244 BlackBox::bbUpdateInputs may calls BlackBoxInputConnector::RecursiveExecute
245 which is responsible for recursive update of the input value.
246 If it is connected and its status is OUTOFDATE then it calls 
247 RecursiveExecute on the Connection which is plugged into:
248 \bigskip\hrule\begin{verbatim}
249 void BlackBoxInputConnector::RecursiveExecute()
250 {
251   // If connected and OUTOFDATE : recursive update
252   // Post-update status is updated by the connection 
253   // (either MODIFIED or OUTOFDATE)
254    if ( mConnection && (mStatus == OUTOFDATE) ) 
255     {
256       mConnection->RecursiveExecute();
257     }
258 }
259 \end{verbatim}\hrule\bigskip
260
261 Connection::RecursiveExecute does:
262 \begin{enumerate}
263 \item Call bbRecursiveExecute on the initial box of the connection 
264 \item Transfer the data from the initial box output to the final box input, adpating it if needed (add crossref).
265 \item Update the final box input status. It sets it to:
266
267 \begin{tabular}{lll}
268 MODIFIED  & If the initial box output is & UPTODATE \\
269 OUTOFDATE & If the initial box output is & OUTOFDATE 
270 \end{tabular}
271 \end{enumerate}
272
273 \bigskip\hrule\begin{verbatim}
274 void Connection::RecursiveExecute()
275 {
276   // Calls bbRecursiveExecute on the initial box
277   mFrom->bbRecursiveExecute(GetThisPointer<Connection>());
278   // Transfers the data from the initial box output to the 
279   // final box input adapting it if necessary
280   TransferData();
281   // Updates the status of the final box input
282   IOStatus s = MODIFIED;
283   if ( mFrom->bbGetOutputConnector(mOutput).GetStatus() == OUTOFDATE) 
284     s = OUTOFDATE;
285   mTo->bbGetInputConnector(mInput).SetStatus(s);
286 }
287 \end{verbatim}\hrule\bigskip
288
289 % ==========================================
290 \subsection{The main processing method (bbProcess) overloads}
291 % ==========================================
292
293 BlackBox::bbProcess 
294
295
296
297
298 % ==========================================
299 \section{Misc}
300 % ==========================================
301
302 \subsection{Displaying messages}
303
304 \begin{verbatim}
305 bbtkMessage("Kind",level,"message "<<"to "<<" display : i="<<i<<std::endl);
306 bbtkDebugMessage("Kind",level,"message "<<"to "<<" display : i="<<i<<std::endl);
307 \end{verbatim}
308
309 \section{Types and RTTI}
310
311
312
313 In \bbtk the class conveying the information on a type is 
314 \begin{verbatim}
315 bbtk::TypeInfo
316 \end{verbatim}
317 which is simply a typedef on 
318 \begin{verbatim}
319 const std::type_info&
320 \end{verbatim}
321 Remember that all constructors of the std::type\_info class are private, 
322 hence objects can only be created by the operator \texttt{typeid} 
323 which returns a const reference on a type\_info. 
324 Hence the \bbtk type TypeInfo conveys that const reference 
325 and cannot be itself referenced. 
326 Any function or method which takes or returns a TypeInfo must take 
327 or return it \emph{by value} (see e.g. the TypeName function below).
328 To print the name of a type use one of the template functions 
329 \begin{verbatim}
330 template <class T> std::string TypeName();
331 template <class T> std::string TypeName(const T&);
332 template <class T> std::string TypeName(bbtk::TypeInfo);
333 \end{verbatim}
334
335
336 \begin{verbatim}
337 BBTK_DEFINE_HUMAN_READABLE_TYPE_NAME(std::string,"string");
338 \end{verbatim}
339
340 \end{document}