Remove dynamic exceptions
[anna.git] / example / comm / irkClient / main.cpp
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 /*
10    Establece un manejador externo para controlar el teclado, recoge los parametros de la operacion
11    por este y envia la peticion al servidor que devolvera el resultado de aplicar la operacion 
12    sobre los parametros recogidos.
13
14    Realiza las peticiones mediante un servicio de reparto por indice.
15
16    El cliente de esta aplicacion es: server.p rserver.p => Transporte: comm::Transport.
17 */
18 #include <iostream>
19 #include <ctype.h>
20
21 #include <string.h>
22
23 #include <anna/core/core.hpp>
24 #include <anna/comm/comm.hpp>
25
26 #include <anna/test/Menu.hpp>
27 #include <anna/test/Request.hpp>
28 #include <anna/test/Response.hpp>
29
30 class MyCommunicator : public Communicator {
31 public:   
32    MyCommunicator () : Communicator () {;}
33    
34 private:
35    test::Response a_response;   
36    test::Request a_request;
37    
38    void eventReceiveMessage (ClientSocket&, const Message&) noexcept(false);
39    void eventUser (const char* id, const void* context) ;   
40 };
41
42 typedef comm::IndexedDelivery MyService;
43
44 class IRKClient : public anna::comm::Application {
45 public:
46
47    IRKClient ();
48       
49    MyService* getService () const { return a_service; }
50    const test::Menu& getMenu () const { return a_menu; }
51    
52 private:
53    MyCommunicator a_communicator;
54    test::Menu a_menu;
55    MyService* a_service;
56
57    void initialize () noexcept(false);
58    void run () noexcept(false);    
59 };
60
61 using namespace std;
62 using namespace test;
63
64 int main (int argc, const char** argv)
65 {
66    CommandLine& commandLine (CommandLine::instantiate ());
67    IRKClient app;
68    
69    try {
70       commandLine.initialize (argv, argc);
71       commandLine.verify ();
72
73       Logger::setLevel (Logger::Debug); 
74       Logger::initialize ("kclient", new TraceWriter ("file.trace", 4096000));
75  
76       app.start ();
77    }
78    catch (Exception& ex) {
79       cout << ex.asString () << endl;
80    }
81    
82    return 0;
83 }
84
85 IRKClient::IRKClient () : 
86    Application ("kclient", "IRKClient", "1.0.0"),
87    a_menu (&a_communicator)
88 {
89    CommandLine& commandLine (CommandLine::instantiate ());
90       
91    commandLine.add ("a", CommandLine::Argument::Mandatory, "Direccion en el que el servidor atiende respuestas.");
92    commandLine.add ("mode", CommandLine::Argument::Mandatory, "Modo de reparto (S)trict o (F)lexible");
93    commandLine.add ("pp", CommandLine::Argument::Mandatory, "Puerto del servidor de +");
94    commandLine.add ("pm", CommandLine::Argument::Mandatory, "Puerto del servidor de -");
95    commandLine.add ("px", CommandLine::Argument::Mandatory, "Puerto del servidor de *");
96    commandLine.add ("pd", CommandLine::Argument::Mandatory, "Puerto del servidor de /");
97 }
98
99 void IRKClient::initialize () 
100    noexcept(false)
101 {
102    CommandLine& cl (CommandLine::instantiate ());    
103
104    Network& network = Network::instantiate ();
105
106    int port;
107    
108    const char* ip = cl.getValue ("a");
109    const char mode = toupper (*cl.getValue ("mode"));
110
111    a_service = new MyService ("Service_Arithmetic", true, (mode == 'S') ? MyService::Mode::Strict: MyService::Mode::Flexible);
112
113    port = cl.getIntegerValue ("pp");
114    a_service->attach (network.createServer (ip, port, true));
115
116    port = cl.getIntegerValue ("pm");
117    a_service->attach (network.createServer (ip, port, true));
118
119    port = cl.getIntegerValue ("px");
120    a_service->attach (network.createServer (ip, port, true));
121
122    port = cl.getIntegerValue ("pd");
123    a_service->attach (network.createServer (ip, port, true));
124
125    a_communicator.attach (a_service);
126    a_communicator.attach (&a_menu);
127 }
128
129 void IRKClient::run ()
130    noexcept(false)
131 {   
132    a_menu.paint ();
133    a_communicator.accept ();
134 }
135
136 void MyCommunicator::eventReceiveMessage (ClientSocket&, const Message& message)
137    noexcept(false)
138 {
139    a_response.decode (message.getBody ());
140
141    const Millisecond responseTime = anna::functions::millisecond () - a_response.initTime;
142    
143    cout << endl << "ResponseTime: " << responseTime << " ms" << endl;
144    cout << "Resultado de la peticion: " << a_response.x << (char) a_response.op << a_response.y  << " = " << a_response.result << endl << endl;
145    
146    static_cast <IRKClient&> (anna::comm::functions::getApp ()).getMenu ().paint ();
147 }
148
149 //-----------------------------------------------------------------------------------------
150 // Cuando el Menu tiene disponibles todos los datos necesarios para la peticiĆ³n se lo
151 // notifica al comunicador mediante un evento de usuario.
152 //-----------------------------------------------------------------------------------------
153 void MyCommunicator::eventUser (const char* id, const void* context) 
154    
155 {
156    LOGMETHOD (TraceMethod tm ("MyCommunicator", "eventUser", ANNA_FILE_LOCATION));
157    int index;
158
159    if (anna_strcmp (id, Menu::EventData) == 0) {
160       const Menu::Data* data (reinterpret_cast <const Menu::Data*>  (context));
161       
162       a_request.op = data->a_operation;
163       a_request.x = data->a_op1;
164       a_request.y = data->a_op2;
165       a_request.initTime = anna::functions::millisecond ();
166       
167       MyService* service = static_cast <IRKClient&> (anna::comm::functions::getApp ()).getService ();
168       
169       try {
170          switch (data->a_operation) {
171             case '+': index = 0; break;
172             case '-': index = 1; break;
173             case '*': index = 2; break;
174             case '/': index = 3; break;
175          }
176          service->prepare (index);
177          service->send (a_request);
178       }
179       catch (RuntimeException& ex) {
180          ex.trace ();
181       }
182    } 
183 }