7258012ad28566e849a2413896175bb9a69c3b1b
[anna.git] / Component.hpp
1 // ANNA - Anna is Not Nothingness Anymore                                                         //
2 //                                                                                                //
3 // (c) Copyright 2005-2015 Eduardo Ramos Testillano & Francisco Ruiz Rayo                         //
4 //                                                                                                //
5 // See project site at http://redmine.teslayout.com/projects/anna-suite                           //
6 // See accompanying file LICENSE or copy at http://www.teslayout.com/projects/public/anna.LICENSE //
7
8
9 #ifndef anna_app_Component_hpp
10 #define anna_app_Component_hpp
11
12 #include <vector>
13 #include <anna/core/util/Component.hpp>
14 #include <anna/app/Application.hpp>
15
16 namespace anna {
17
18 namespace xml {
19 class Node;
20 }
21
22 namespace app {
23
24 /**
25    Clase de la que heredan los componentes de aplicacion.
26
27    Solo deberia haber una instancia de cada uno de los componentes, pero no podemos
28    declararlos como heredados de anna::Singleton porque debemos dar la posiblidad de
29    que el programador re-escriba su comportamiento mediante herencia.
30
31    Todos los componentes se arrancan y paran automaticamente desde la aplicacion.
32
33    El siguiente ejemplo muestra como obtener la instancia de un componente asociado a nuestra aplicacion:
34
35    \code
36       Clase* objeto = anna::app::functions::component <Clase> (FILE_LOCATION);
37
38       ..... uso del objeto ....
39    \endcode
40
41    Si el componente \em 'Clase' no hubiera sido registrado (instanciado) en nuestra aplicacion el metodo
42    template anna::component lanzara una excepcion.
43 */
44 class Component : public anna::Component {
45 public:
46   /**
47      Destructor.
48   */
49   virtual ~Component();
50
51   /**
52      Conecta explicitamente este componente con la aplicacion. Sera necesario invocar a este metodo
53      cuando instanciemos un componentes despues de comenzar la ejecucion de nuestra aplicacion y
54      cuando el nuevo componente este completamente listo para su inicializacion.
55   */
56   void attach() noexcept(false);
57
58   /**
59      Devuelve una cadena con la informacion mas relevante de esta instancia.
60      \return Una cadena con la informacion mas relevante de esta instancia.
61   */
62   virtual std::string asString() const ;
63
64   /**
65      Devuelve un documento XML con la informacion mas relevante de esta instancia.
66      \param parent Nodo XML del que colgar la informacion referente a esta instancia.
67      \return Un documento XML con la informacion mas relevante de esta instancia.
68   */
69   virtual xml::Node* asXML(xml::Node* parent) const ;
70
71 protected:
72   /**
73      Estados en los que puede estar un componente.
74      \see Component.
75   */
76   struct State { enum _v { Stopped, Starting, Running }; };
77
78   /**
79      Contructor.
80      @param className Nombre lgico asociado a esta clase.
81   */
82   explicit Component(const char* className);
83
84   /**
85      Devuelve el estado de este componente.
86      \return el estado de este componente.
87   */
88   State::_v getState() const { return a_state; }
89
90   /**
91      Indica que el nombre de un componente que debe ser initializa antes que este.
92      \param componentName Nombre de componente requerido por esta instancia.
93      \warning Solo tendra efecto antes de inicializar el componente.
94   */
95   void addPredecessor(const char* componentName) ;
96
97   /**
98      metodo que debemos implementar si la clase heredada necesita algn tipo de inicializacin.
99      Este metodo se invocara automaticamente desde anna::Application::start.
100   */
101   void initialize() noexcept(false);
102
103   /**
104      metodo que debemos implementar en la clase heredada para implementar el proceso de parada de
105      esta clase.
106
107      Este metodo debe implementar un metodo de parada controlada. Se invocara automaticamente
108      desde el nucleo
109   */
110   void stop() { a_state = State::Stopped; do_stop(); }
111
112   /**
113      metodo que debemos implementar en la clase heredada para implementar el proceso de parada de
114      esta clase. Se invocara automaticamente desde el nucleo
115
116      Este metodo implementa un metodo de parada no controlada.
117   */
118   virtual void kill() { stop(); }
119
120 private:
121   typedef std::vector <std::string>::iterator iterator;
122
123   State::_v a_state;
124   std::vector <std::string> a_predecessors;
125
126   Component(const Component& other);
127   iterator begin() { return a_predecessors.begin(); }
128   iterator end() { return a_predecessors.end(); }
129   const std::string& data(iterator& ii) { return *ii; }
130
131   /**
132      metodo que debemos implementar si la clase heredada necesita algn tipo de inicializacin.
133      Este metodo se invocara automaticamente desde anna::Application::start.
134   */
135   virtual void do_initialize() noexcept(false) = 0;
136
137   /**
138      Metodo que debemos implementar en la clase heredada para tratar el proceso de parada de
139      esta clase.
140      Este metodo debe implementar un metodo de parada controlada. Se invocara automaticamente
141      desde el nucleo
142   */
143   virtual void do_stop()  = 0;
144
145   /**
146    * Metodo que debemos implementar en la clase heredada para tratar el proceso de clonado de
147    * esta clase desde el punto de vista del proceso original.
148    * \warning Si se detecta algun error terminara abortara la ejecucion del proceso hijo.
149    */
150   virtual void do_cloneParent() noexcept(false) { ; }
151
152   /**
153    * Metodo que debemos implementar en la clase heredada para tratar el proceso de clonado de
154    * esta clase desde el punto de vista del proceso hijo.
155    * \warning Si se detecta algun error terminara abortara la ejecucion de este proceso.
156    */
157   virtual void do_cloneChild() noexcept(false) { ; }
158
159   friend void Application::startComponents() noexcept(false);
160   friend void Application::stopComponents() noexcept(false);
161   friend void Application::attach(Component*) noexcept(false);
162   friend Application& Application::clone() noexcept(false);
163 };
164
165 }
166 }
167
168 #endif