First commit
[anna.git] / include / anna / comm / ReceiverFactory.hpp
1 // ANNA - Anna is Not 'N' Anymore
2 //
3 // (c) Copyright 2005-2014 Eduardo Ramos Testillano & Francisco Ruiz Rayo
4 //
5 // https://bitbucket.org/testillano/anna
6 //
7 // Redistribution and use in source and binary forms, with or without
8 // modification, are permitted provided that the following conditions
9 // are met:
10 //
11 //     * Redistributions of source code must retain the above copyright
12 // notice, this list of conditions and the following disclaimer.
13 //     * Redistributions in binary form must reproduce the above
14 // copyright notice, this list of conditions and the following disclaimer
15 // in the documentation and/or other materials provided with the
16 // distribution.
17 //     * Neither the name of Google Inc. nor the names of its
18 // contributors may be used to endorse or promote products derived from
19 // this software without specific prior written permission.
20 //
21 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 //
33 // Authors: eduardo.ramos.testillano@gmail.com
34 //          cisco.tierra@gmail.com
35
36
37 #ifndef anna_comm_ReceiverFactory_hpp
38 #define anna_comm_ReceiverFactory_hpp
39
40 #include <anna/core/RuntimeException.hpp>
41 #include <anna/core/mt/Mutex.hpp>
42 #include <anna/config/defines.hpp>
43
44 namespace anna {
45
46 namespace xml {
47 class Node;
48 }
49
50 namespace comm {
51
52 class Receiver;
53
54 /**
55    Interfaz que deben cumplir las factorias de receptores.
56
57    Es muy aconsejable que la implementacion particular de esta clase que use nuestra
58    aplicacion este basada en el uso de #Recycler<T>. Como muestra el siguiente ejemplo:
59
60    \code
61
62    class MyReceiver;
63
64    class MyReceiverFactory : public ReceiverFactory {
65    public:
66       MyReceiverFactory () : ReceiverFactory ("MyReceiverFactory") {;}
67
68    private:
69       anna::Recycler<MyReceiver> a_receivers;
70
71       Receiver* do_create () throw () { return a_receivers.create (); }
72       void do_release (Receiver* receiver) throw () { a_receivers.release (static_cast <MyReceiver*> (receiver)); }
73    };
74
75    \endcode
76
77    En la mayoria de los casos seria aconsejable usar un instancia de comm::ReceiverFactoryImpl
78    instanciado con el tipo de receptor usado por nuestra aplicacion.
79
80    \see Receiver
81    \see ReceiverFactoryImpl
82 */
83 class ReceiverFactory : public Mutex {
84 public:
85   /**
86      Devuelve el nombre logico de este gestor de receptores.
87      \return el nombre logico de este gestor de receptores.
88   */
89   const std::string& getName() const throw() { return a_name; }
90
91   /**
92      Crea una instancia del receptor asociado a esta factoria, realiza las comprobaciones
93      necesarias para optimizar el reuso de instancias de la clase Receiver.
94
95      \return La instancia de un nuevo receiver.
96      \warning Cada uno de los receptores obtenidos debera ser liberado invocando a #release.
97   */
98   Receiver* create() throw(RuntimeException);
99
100   /**
101      Libera la instancia del receptor recibido como parametro. Realiza las comprobaciones
102      necesarias para optimizar el reuso de instancias de la clase Receiver.
103
104      \param receiver Instancia del receiver a liberar.
105      \warning El transporte recibido como parametro debera haberse obtenido mediante #create.
106   */
107   void release(Receiver* receiver) throw();
108
109   /**
110      Devuelve una cadena con la informacion relevante sobre esta instancia.
111      \return una cadena con la informacion relevante sobre esta instancia.
112   */
113   std::string asString() const
114   throw() {
115     std::string msg("anna::comm::ReceiverFactory { Name: ");
116     msg += a_name;
117     return msg += " }";
118   }
119
120   /**
121      Devuelve un documento XML con la informacion relevante sobre esta instancia.
122      \param parent Nodo XML del que debe depender el documento generado.
123      \return un documento XML con la informacion relevante sobre esta instancia.
124   */
125   xml::Node* asXML(xml::Node* parent) const throw();
126
127 protected:
128   /**
129      Constructor
130      \param name Nombre logico de esta factoria de receptores.
131   */
132   ReceiverFactory(const char* name);
133
134   /**
135      Crea realmente la instancia del receptor asociado a esta factoria, solo sera invocado
136      en caso de que no haya ninguna otra instancia disponible que pueda ser reusada.
137
138      La invocacion a este metodo se realiza desde una seccion critica activada sobre esta
139      instancia.
140
141      Es muy aconsejable que la implementacion particular de este metodo este basada en el
142      uso de #Recycler<T>.
143
144      \return La instancia de un nuevo receiver.
145      \warning Cada uno de los receptores obtenidos debera ser liberado invocando a #release.
146   */
147   virtual Receiver* do_create() throw() = 0;
148
149   /**
150      Libera realmente la instancia del receptor recibido como parametro.
151
152      Es muy aconsejable que la implementacion particular de este metodo este basada en el
153      uso de #Recycler<T>.
154
155      La invocacion a este metodo se realiza desde una seccion critica activada sobre esta
156      instancia.
157
158      \param receiver Instancia del receiver a liberar.
159   */
160   virtual void do_release(Receiver* receiver) throw() = 0;
161
162 private:
163   const std::string a_name;
164
165   ReceiverFactory(const ReceiverFactory&);
166
167   WHEN_SINGLETHREAD(Receiver* a_receiver;)
168 };
169
170 }
171 }
172
173 #endif