1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175
|
%%
%% This file is part of the ViTE project.
%%
%% This software is governed by the CeCILL-A 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-A license as circulated by CEA, CNRS and INRIA at the following
%% URL: "http://www.cecill.info".
%%
%% 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.
%%
%% In this respect, the user's attention is drawn to the risks associated
%% with loading, using, modifying and/or developing or reproducing the
%% software by the user in light of its specific status of free software,
%% that may mean that it is complicated to manipulate, and that also
%% therefore means that it is reserved for developers and experienced
%% professionals having in-depth computer knowledge. Users are therefore
%% encouraged to load and test the software's suitability as regards
%% their requirements in conditions enabling the security of their
%% systems and/or data to be ensured and, more generally, to use and
%% operate it in the same conditions as regards security.
%%
%% The fact that you are presently reading this means that you have had
%% knowledge of the CeCILL-A license and that you accept its terms.
%%
%%
%% ViTE developers are:
%%
%% - COULOMB Kevin
%% - FAVERGE Mathieu
%% - JAZEIX Johnny
%% - LAGRASSE Olivier
%% - MARCOUEILLE Jule
%% - NOISETTE Pascal
%% - REDONDY Arthur
%% - VUCHENER Clément
%%
The interface is divided into two main classes : the \emph{console\_interface} and the \emph{graphical\_interface} inherited from the \emph{Interface} class.
\section{The Interface class}
The class Interface declares three pure virtual functions that are used by inherited classes to display messages for users :
\begin{itemize}
\item \verb?virtual void error(const string) const = 0;?
\item \verb?virtual void warning(const string) const = 0;?
\item \verb?virtual void information(const string) const = 0;?
\end{itemize}
These functions are defined inside the Console User Interface (\emph{Interface\_console} class) and the Graphical User Interface (\emph{Interface\_graphic} class) which both inherit of the \emph{Interface} interface.
In the first case, the messages are displayed in the Operating System terminal. In the second class, Qt text feature is used to display the messages inside a window: \emph{Info\_window}.
\newline
Nevertheless, \emph{ViTE} modules (like the Parser, the Data Structure, the Render area, etc.) need to:
\begin{itemize}
\item Have an easy way to display message.
\item Be independant of the place the message is displayed
\end{itemize}
Thus, to respect these two requirements, the \emph{Message} class was created.
\section{The \emph{ViTE} notify message system : the \emph{Message} class}
The \emph{Message} class was developped with the following leitmotiv~: to provide an easy-to-use way to display messages for users anywhere inside the \emph{ViTE} source code.
\newline
For all the \emph{ViTE} parts, just a single \emph{Message} class instance is needed. Thus, this class is a singleton. To pass many different argument types (such as \emph{int}, \emph{string}, \emph{bool}), the \emph{stringstream} class is used.
\newline
To display messages just recover the instance (the only instance) and use it like \emph{cout} or \emph{cerr} of the \emph{STD} library. Nevertheless, you need to finish your message to pass a special object instance~: it will be \emph{Message::endi} (for informative message), \emph{Message::endw} (for warning message) or \emph{Message::ende} (for error message).
A message processing is different, depending on the special object used to end the message. For example, it influences the message color (orange for warning, red for error) in the graphical interface or add \verb?Warning? or \verb?ERROR? at the beginning of the message in the console interface.
Moreover, there is an other special object~: \emph{Message::endsi} (for selection informative message). It is used to display information about the mouse selected entity in the graphical interface only.
\textbf{NOTE}~: In the graphical interface, messages are displayed in the \emph{Info window}.
\textbf{Example 1:}
\textit{You need to notify the user that an error occured.}
\begin{verbatim}
*Message::get_instance() << "An error occured." << Message::ende;
\end{verbatim}
\begin{figure}[ht!]
\centering
\includegraphics{images/message_example1_console}
\includegraphics{images/message_example1_window}
\caption{Message render: \textbf{Left}: in the System terminal - \textbf{Right}: int the \emph{Info window}.\label{Message}}
\end{figure}
\textbf{Example 2:}
\textit{You need to notify the user that the trace is misformed. Use a warning message.}
\begin{verbatim}
*Message::get_instance() << "Incorrect value l." << line << " of \
file: " << file << "." << Message::endw;
\end{verbatim}
Take advice that you can define macro to use as debug~:
\begin{verbatim}
#define message *Message::get_instance() << "(" << __FILE__ <<" l."\
<< __LINE__ << "): "
\end{verbatim}
Thus, just use \verb?message? instead of \verb?*Message::get_instance()? in the source code.
\section{Console User Interface : class Interface\_console}
\subsection{Description}
The \emph{Interface\_console} class is the most critical class of the software. It is the \emph{ViTE} core since it manages and connects all the application modules.
For example, it analyses the command line, launches window interface, creates a parser and triggers the data structure filling. Moreover, it is used to broadcast the messages between the render area (in OpenGL) and the graphical interface (in Qt).
Besides, it triggers the SVG export of an opened file.
\emph{ViTE} modules connections can be seen as a star where the \emph{Interface\_console} class is set on the middle. This organisation was designed to provide an easy and safe way to manage threads.
\subsection{How it works}
First, the \emph{main} function of \emph{ViTE} creates a console interface and gives it to the command line parameters.
Then the console interface analyses the parameters from its \emph{constructor}. It gives them the \verb?get_state()? function, which returns a code number of the right action to be executed.
This latter is given the \verb?launch_action()? function which executs the action corresponding to the code number.
\textbf{For example}: if the user calls \emph{ViTE} with the command line:
\verb?vite -h?
\verb?get_state()? returns the \verb?STATE_DISPLAY_HELP? code number. Then from this latter, \verb?launch_action()? will be called and will apply the \verb?diplay_help()? function that displays in the terminal the \emph{ViTE} synopsis.
\subsection{Managing of the arguments}
We saw, in the last section, an example of using \emph{ViTE} by command line to launch the help.
The arguments are managed by a loop in the \verb?get_state()? function and the action to do is set in the integer \verb?state?.
The loop can be considered like an automaton which recognizes the arguments passed in parameter.
There are two kinds of arguments : the ones beginning with a "-" and the others.
The ones beginning with a "-" are the options of \emph{ViTE} and are predefined in the \verb?get_state()? function. The others are the arguments of these options or, by default, the file to open.
When the option is known, the \verb?state? value will be changed depending on the option and the option consumes the next argument if needed. If the option is unknown, the help is printed.
For example, to export a file in svg you can call~:
\verb?./bin/vite -f in -e out? .
The loop starts by reading the \verb?-f? option. This option consumes the next token which corresponds to the file to open (the \verb?in? token here). Then, because of the consumption of the argument \verb?in?, the loop will read the \verb?-e? option and set the next argument as the name of the destination file.
The loop makes a comparison between the argument and all the pre-defined options.
So, it is easy to add options~:\\
First of all, depending on the option aim, you will need to add a new state in the header (for example \verb?_STATE_OPEN_FILE? is used to set the state for opening a file).
Then, in the \verb?get_state()? function, add the case you want and what you want to do with it. If you want to change a parameter of another class, the best way is to do a static method in this class and call it in the case (it is what has be done to add the epsilon option for the export in svg and this method do not need a new state). Do not forget to consume the next parameter if necessary (check before if one exists).
Maybe, you will need to do another thing and to set a new state, and moreover you will need to return it without preoccuping of the other ones.
The action to set then has to be put in the \verb?launch_action()? function.
Do not forget to add the option in the help.
Some states are compatible, like for example the opening or exporting a file in an interval which are two different arguments.
The choice made is to use binary operands for them and to do binary OR when we have the "-t" argument. To help to the comprehension, two states were added to specify that we are in an interval.
\subsection{Graphical User Interface : class Interface\_graphic}
Graphical window interface is created by \emph{Qt designer} in a .ui file (\emph{main\_window.ui}). The graphical interface loads it and displays the window generated from the file.
In a same way, the informative window is loaded from the \emph{info\_window.ui} file.
In the \verb?_render_area_layout?, a \verb?Render_area? object is created. It displays an OpenGL scene.
|