Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members  

AlephInteractiveHandler.cpp

Go to the documentation of this file.
00001 
00002 //
00003 // Implementation of
00004 // CLASS AlephInteractiveHandler
00005 // handles the communication with the external world
00006 // for interactive sessions
00007 //
00008 // Author :  C. Delaere
00009 //
00011 
00012 #include <iostream>
00013 #include <string>
00014 #include <string.h>
00015 #include <stdio.h> 
00016 #include "AlephInteractiveHandler.h"
00017 #include "AlephRegisteredAction.h"
00018 #include "AlephAbstractInteractiveFunction.h"
00019 #include "AlphaBanks.h"
00020 
00021 
00022 AlephInteractiveHandler* AlephInteractiveHandler::TheAlephInteractiveHandler()
00023 {
00024         if (_theAlephInteractiveHandler)
00025                 return _theAlephInteractiveHandler;
00026         else
00027                 _theAlephInteractiveHandler = new AlephInteractiveHandler;
00028         return _theAlephInteractiveHandler;
00029 }
00030 
00031 AlephInteractiveHandler::AlephInteractiveHandler()
00032 {
00033         kae = true;      // want all events (default)
00034         me  = "ALPHA++"; // why change it ?
00035         you = "AlVisu";  // default client
00036 }
00037 
00038 AlephInteractiveHandler::~AlephInteractiveHandler()
00039 {
00040         ClearAll();
00041 }
00042 
00043 void AlephInteractiveHandler::ConfigureProtocol(string myname, string yourname)
00044 {
00045         me = myname;
00046         you = yourname;
00047 }
00048 
00049 vector<AlephAbstractInteractiveFunction*> AlephInteractiveHandler::InteractiveFunctionsList = vector<AlephAbstractInteractiveFunction*>(0);
00050 
00051 AlephInteractiveHandler* AlephInteractiveHandler::_theAlephInteractiveHandler = NULL;
00052 
00053 void AlephInteractiveHandler::ClearAll()
00054 {
00055         for(vector<AlephAbstractInteractiveFunction*>::iterator existing = AlephInteractiveHandler::InteractiveFunctionsList.begin();
00056                         existing<AlephInteractiveHandler::InteractiveFunctionsList.end(); existing++)
00057         {
00058                 delete *existing;
00059         }
00060         AlephInteractiveHandler::InteractiveFunctionsList.clear();
00061 }
00062 
00063 void AlephInteractiveHandler::InitiateConnection(int& ier)
00064 {
00065         //first send the list of user's functions
00066         int funccnt = InteractiveFunctionsList.size();
00067         for(vector<AlephAbstractInteractiveFunction*>::iterator existing = AlephInteractiveHandler::InteractiveFunctionsList.begin();
00068                         existing<AlephInteractiveHandler::InteractiveFunctionsList.end(); existing++)
00069         {
00070                 vector<float> optionstosend;
00071                 optionstosend.push_back(--funccnt);                             // index
00072                 optionstosend.push_back((*existing)->OptionsList().size());     // option[0]
00073                 optionstosend.push_back((*existing)->Code());                   // option[1]
00074                 SendMessage(-1,optionstosend,(*existing)->Name());
00075                 vector<pair<string,float> > options = (*existing)->OptionsList();
00076                 int cnt = -options.size();
00077                 for(vector<pair<string,float> >::iterator subopt=options.begin();subopt<options.end();subopt++)
00078                 {
00079                         vector<float> optionstosend;
00080                         optionstosend.push_back(funccnt);                       // index
00081                         optionstosend.push_back(cnt++);                         // option[0]
00082                         optionstosend.push_back((*existing)->Code());           // option[1]
00083                         optionstosend.push_back(subopt->second);                // option[2]
00084                         SendMessage(-1,optionstosend,subopt->first);
00085                 }
00086         }
00087         //then send the ready message
00088         vector<float> options;
00089         options.push_back(0);
00090         SendMessage(0,options,"Ready");
00091         //wait for the first next message
00092         int code = 0;
00093         string comment = "";
00094         while(code!=100)
00095         {
00096                 vector<float> options = ReceiveMessage(code, comment);
00097                 if(code==999) {ier = 1; code = 100;}
00098         }
00099         kae = !options[0];
00100 }
00101 
00102 int AlephInteractiveHandler::HandleEvent(AlphaBanks& bb)
00103 {
00104         // This is the main "event loop" in interactive sessions
00105         // message are received
00106         // then the right function is called
00107         // this is done as long as the user don't request the next event.
00108         vector<float> dummy(0);
00109         int code = 0;
00110         string comment = "";
00111         // first return the general event info...
00112         for(vector<AlephAbstractInteractiveFunction*>::iterator existing = AlephInteractiveHandler::InteractiveFunctionsList.begin();
00113                         existing<AlephInteractiveHandler::InteractiveFunctionsList.end(); existing++)
00114         {
00115                 if((*existing)->Code() == 100)
00116                 {
00117                         (*existing)->Run(dummy,bb);
00118                         break;
00119                 }
00120         }
00121         // now wait for another request...
00122         while(1)
00123         {                               
00124                 vector<float> options = ReceiveMessage(code, comment);
00125                 // look in the table for the appropriate function to call
00126                 for(vector<AlephAbstractInteractiveFunction*>::iterator existing = AlephInteractiveHandler::InteractiveFunctionsList.begin();
00127                                 existing<AlephInteractiveHandler::InteractiveFunctionsList.end(); existing++)
00128                 {
00129                         if((*existing)->Code() == code)
00130                         {
00131                                 (*existing)->Run(options,bb);
00132                                 break;
00133                         }
00134                 }
00135                 if (code==100) kae = !options[0]; 
00136                 if ((code==100)||(code==999)) break;
00137         }
00138         return (code==999 ? 1 : 0);
00139 }
00140 
00141 void AlephInteractiveHandler::CloseConnection()
00142 {
00143         vector<float> options;
00144         options.push_back(0);
00145         SendMessage(999,options,"Terminated");
00146 }
00147 
00148 void AlephInteractiveHandler::SendMessage(int code, vector<float>& options, string comment)
00149 {
00150         char buffer[256];
00151         // build the message according to options passed
00152         string message = me;
00153         message += "><";
00154         sprintf ( buffer, "%i><", code); 
00155         message += buffer;
00156         for(vector<float>::iterator i=options.begin();i<options.end();i++)
00157         {
00158                 sprintf ( buffer, "%f><", *i);
00159                 message += buffer;
00160         }
00161         message += comment;
00162         // send the message to the standard output.
00163         cout << message << endl;
00164 }
00165 
00166 void Tokenize(const string& str, vector<string>& tokens,const string& delimiters = " ")
00167 {
00168     // Skip delimiters at beginning.
00169     string::size_type lastPos = str.find_first_not_of(delimiters, 0);
00170     // Find first "non-delimiter".
00171     string::size_type pos     = str.find_first_of(delimiters, lastPos);
00172 
00173     while (string::npos != pos || string::npos != lastPos)
00174     {
00175           // Found a token, add it to the vector.
00176           tokens.push_back(str.substr(lastPos, pos - lastPos));
00177           // Skip delimiters.  Note the "not_of"
00178           lastPos = str.find_first_not_of(delimiters, pos);
00179           // Find next "non-delimiter"
00180           pos = str.find_first_of(delimiters, lastPos);
00181     }
00182 }
00183 
00184 vector<float> AlephInteractiveHandler::ReceiveMessage(int& code, string& comment)
00185 {
00186         // wait for a full line...
00187         char command[1024] = {0};
00188         cin.getline(command,1024);
00189         // test if it is a formated message (step1)
00190         if(strcspn(command, you.c_str())!=0)
00191         {
00192                 code = -1;
00193                 comment = "";
00194                 vector<float> result;
00195                 return result;
00196         }
00197         // put the result in a string
00198         string tobeanalyzed = command;
00199         // decompose the command in tokens
00200         vector<string> tokens;
00201         Tokenize(tobeanalyzed,tokens,"><");
00202         // Now we have got the tokens... interpret them.
00203         // test if it is a formated message (step2)
00204         if(tokens.size()<4)
00205         {
00206                 code = -1;
00207                 comment = "";
00208                 vector<float> result;
00209                 return result;
00210         }
00211         // seems ok... use it.
00212         sscanf( tokens[1].c_str(), "%i", &code);
00213         comment = *(tokens.end()-1);
00214         vector<float> result;
00215         for(vector<string>::iterator i=tokens.begin()+2;i<tokens.end()-1;i++)
00216         {
00217                 float num;
00218                 sscanf( i->c_str(), "%f", &num);
00219                 result.push_back(num);
00220         }
00221         return result;
00222 }
00223 

Generated at Wed Jun 18 17:19:09 2003 for ALPHA++ by doxygen1.2.8.1 written by Dimitri van Heesch, © 1997-2001