00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "eclipse_thread.h"
00024 #include "externals/fawkes_bb_interface.h"
00025 #include "externals/fawkes_logger.h"
00026
00027 #include <interfaces/TestInterface.h>
00028 #include <core/exception.h>
00029
00030 #include <eclipseclass.h>
00031
00032 #include <cstdlib>
00033 #include <cstring>
00034 #include <vector>
00035
00036 using namespace std;
00037 using namespace fawkes;
00038
00039
00040
00041
00042
00043
00044
00045 extern "C" int ec_external( dident, int (*) (), dident );
00046
00047 EclipseAgentThread* EclipseAgentThread::m_instance = NULL;
00048
00049
00050 EclipseAgentThread::EclipseAgentThread()
00051 : Thread( "ECLiPSe thread", fawkes::Thread::OPMODE_CONTINUOUS ),
00052 m_initialized( false )
00053 {
00054 m_instance = this;
00055 }
00056
00057
00058 EclipseAgentThread::~EclipseAgentThread()
00059 {
00060 }
00061
00062 void
00063 EclipseAgentThread::init()
00064 {
00065
00066 char* eclipse_dir = NULL;
00067 try
00068 {
00069 eclipse_dir = strdup( config->get_string( "/readylogagent/eclipse_dir" ).c_str() );
00070 logger->log_info( name(), "Setting ECLIPSEDIR to %s", eclipse_dir );
00071 ec_set_option_ptr( EC_OPTION_ECLIPSEDIR, (void*) eclipse_dir );
00072 }
00073 catch (...)
00074 {
00075
00076 }
00077
00078
00079 if ( 0 != ec_init() )
00080 { throw fawkes::Exception( "Failed to initialize ECLiPSe context" ); }
00081
00082 free( eclipse_dir );
00083
00084
00085 if ( EC_succeed != ec_external( ec_did( "read_interface", 2 ), p_read_interface, ec_did( "eclipse", 0 ) ) )
00086 { throw Exception( "Registering external predicate read_interface/2 failed" ); }
00087 if ( EC_succeed != ec_external( ec_did( "write_interface", 2 ), p_write_interface, ec_did( "eclipse", 0 ) ) )
00088 { throw Exception( "Registering external predicate write_interface/2 failed" ); }
00089 if ( EC_succeed != ec_external( ec_did( "send_message", 2 ), p_send_message, ec_did( "eclipse", 0 ) ) )
00090 { throw Exception( "Registering external predicate send_message/2 failed" ); }
00091 if ( EC_succeed != ec_external( ec_did( "recv_messages", 2 ), p_recv_messages, ec_did( "eclipse", 0 ) ) )
00092 { throw Exception( "Registering external predicate recv_messages/2 failed" ); }
00093 if ( EC_succeed != ec_external( ec_did( "log", 2 ), p_log, ec_did( "eclipse", 0 ) ) )
00094 { throw Exception( "Registering external predicate log/2 failed" ); }
00095
00096 m_initialized = true;
00097
00098
00099 try
00100 {
00101
00102 Configuration::ValueIterator* vit = config->search( "/readylogagent/interfaces/reading" );
00103 while ( vit->next() )
00104 {
00105 if ( vit->is_string() )
00106 {
00107 string s = vit->get_string();
00108 if ( s.find("::") == string::npos )
00109 { throw Exception( "Not a valid interface id: %s", s.c_str() ); }
00110
00111 string iftype = s.substr( 0, s.find( "::" ) );
00112 string ifname = s.substr( s.find( "::" ) + 2 );
00113
00114 logger->log_debug( name(), "Opening interface %s of type %s for reading",
00115 ifname.c_str(), iftype.c_str() );
00116
00117 Interface* iface = blackboard->open_for_reading( iftype.c_str(), ifname.c_str() );
00118 m_reading_ifaces.push_back( iface );
00119 register_interface( iface );
00120 }
00121 }
00122
00123
00124 vit = config->search( "/readylogagent/interfaces/writing" );
00125 while ( vit->next() )
00126 {
00127 if ( vit->is_string() )
00128 {
00129 string s = vit->get_string();
00130 if ( s.find("::") == string::npos )
00131 { throw Exception( "Not a valid interface id: %s", s.c_str() ); }
00132
00133 string iftype = s.substr( 0, s.find( "::" ) );
00134 string ifname = s.substr( s.find( "::" ) + 2 );
00135
00136 logger->log_debug( name(), "Opening interface %s of type %s for writing",
00137 ifname.c_str(), iftype.c_str() );
00138
00139 Interface* iface = blackboard->open_for_writing( iftype.c_str(), ifname.c_str() );
00140 m_writing_ifaces.push_back( iface );
00141 register_interface( iface );
00142 }
00143 }
00144 }
00145 catch ( Exception& e )
00146 {
00147 e.append( "Failed to open interfaces" );
00148 throw e;
00149 }
00150
00151
00152 load_file( ECLIPSE_CODE_DIR"/utils/logging.ecl" );
00153
00154
00155 load_file( ECLIPSE_CODE_DIR"/interpreter/dummy.ecl" );
00156 }
00157
00158 void
00159 EclipseAgentThread::finalize()
00160 {
00161 ec_cleanup();
00162 }
00163
00164 void
00165 EclipseAgentThread::once()
00166 {
00167 post_goal( "run" );
00168 if ( EC_succeed != EC_resume() )
00169 { throw Exception( "Error running agent program" ); }
00170 }
00171
00172
00173
00174
00175 void
00176 EclipseAgentThread::post_event( const char* event )
00177 {
00178 if ( !m_initialized ) { return; }
00179
00180
00181 char* atom = strdup( event );
00182 ::post_event( EC_atom( atom ) );
00183 free( atom );
00184 }
00185
00186
00187 void
00188 EclipseAgentThread::read_interfaces()
00189 {
00190 for ( vector< Interface* >::iterator i = m_reading_ifaces.begin();
00191 i != m_reading_ifaces.end();
00192 ++i )
00193 { (*i)->read(); }
00194
00195 for ( vector< Interface* >::iterator i = m_writing_ifaces.begin();
00196 i != m_writing_ifaces.end();
00197 ++i )
00198 { (*i)->read(); }
00199 }
00200
00201
00202 void
00203 EclipseAgentThread::write_interfaces()
00204 {
00205 for ( vector< Interface* >::iterator i = m_writing_ifaces.begin();
00206 i != m_writing_ifaces.end();
00207 ++i )
00208 { (*i)->write(); }
00209 }
00210
00211
00212
00213
00214
00215 bool
00216 EclipseAgentThread::load_file( const char* filename )
00217 {
00218 if ( !m_initialized ) { return false; }
00219
00220 char* ensure_loaded = strdup( "ensure_loaded" );
00221 post_goal( term( EC_functor( ensure_loaded, 1 ), filename ) );
00222 free( ensure_loaded );
00223
00224 if ( EC_succeed != ec_resume() )
00225 { throw Exception( "File %s could not be loaded", filename ); }
00226
00227 return true;
00228 }
00229
00230
00231
00232
00233
00234 bool
00235 EclipseAgentThread::register_interface( fawkes::Interface* interface )
00236 {
00237 if ( !m_initialized ) { return false; }
00238
00239 m_registered_interfaces[ string( interface->id() ) ] = interface;
00240
00241
00242
00243
00244
00245
00246 char* struct_name;
00247 asprintf( &struct_name, "data_%s", interface->type() );
00248
00249 char* current_struct = strdup( "current_struct" );
00250 post_goal( term( EC_functor( current_struct, 2 ),
00251 EC_atom( struct_name ),
00252 newvar() ) );
00253
00254 if ( EC_succeed != ec_resume() )
00255 {
00256
00257
00258
00259 vector< string > fields;
00260 for ( InterfaceFieldIterator i = interface->fields();
00261 i != interface->fields_end();
00262 ++i )
00263 { fields.push_back( i.get_name() ); }
00264
00265 EC_word args[ fields.size() ];
00266
00267 for ( size_t i = 0 ; i < fields.size(); ++i )
00268 {
00269 char* c = strdup( fields.at( i ).c_str() );
00270 args[ i ] = EC_atom( c );
00271 free( c );
00272 }
00273
00274 EC_word new_struct = term( EC_functor( struct_name, (int) fields.size() ), args );
00275
00276 char* local = strdup( "local" );
00277 char* strct = strdup( "struct" );
00278 EC_word struct_def = term( EC_functor( strct, 1 ), new_struct );
00279 EC_word struct_def_local = term( EC_functor( local, 1), struct_def );
00280
00281 char* call = strdup( "call" );
00282
00283 post_goal( term( EC_functor( call, 1 ), struct_def_local ) );
00284
00285
00286 free( local );
00287 free( strct );
00288 free( call );
00289
00290 if ( EC_succeed != ec_resume() )
00291 { throw Exception( "Failed to define structure %s", struct_name ); }
00292 }
00293
00294 free( struct_name );
00295
00296
00297
00298
00299
00300 list<const char *> message_types = interface->get_message_types();
00301 for ( list<const char *>::iterator type_iter = message_types.begin();
00302 type_iter != message_types.end();
00303 ++type_iter )
00304 {
00305
00306 char* struct_name;
00307 asprintf( &struct_name, "data_%s_%s", interface->type(), *type_iter );
00308
00309 post_goal( term( EC_functor( current_struct, 2 ),
00310 EC_atom( struct_name ),
00311 newvar() ) );
00312
00313 if ( EC_succeed != ec_resume() )
00314 {
00315
00316
00317
00318 Message* msg = interface->create_message( type_iter->c_str() );
00319
00320 vector< string > fields;
00321 for ( InterfaceFieldIterator field_iter = msg->fields();
00322 field_iter != msg->fields_end();
00323 ++field_iter )
00324 {
00325 string name = field_iter.get_name();
00326 fields.push_back( name );
00327 }
00328
00329 delete msg;
00330
00331 EC_word args[ fields.size() ];
00332
00333 for ( size_t i = 0; i < fields.size(); ++i )
00334 {
00335 char* c = strdup( fields.at( i ).c_str() );
00336 args[ i ] = EC_atom( c );
00337 free( c );
00338 }
00339
00340 EC_word new_struct = term( EC_functor( struct_name, (int) fields.size() ), args );
00341 char* local = strdup( "local" );
00342 char* strct = strdup( "struct" );
00343 EC_word struct_def = term( EC_functor( strct, 1 ), new_struct );
00344 EC_word struct_def_local = term( EC_functor( local, 1), struct_def );
00345
00346 char* call = strdup( "call" );
00347
00348 post_goal( term( EC_functor( call, 1 ), struct_def_local ) );
00349
00350
00351 free( local );
00352 free( strct );
00353 free( call );
00354
00355 if ( EC_succeed != ec_resume() )
00356 { throw Exception( "Failed to define structure %s", struct_name ); }
00357 }
00358
00359 free( struct_name );
00360 }
00361
00362
00363 free( current_struct );
00364
00365 return true;
00366 }
00367
00368
00369
00370
00371
00372 fawkes::Interface*
00373 EclipseAgentThread::get_registered_interface( const char* id )
00374 {
00375 map< string, fawkes::Interface* >::iterator i = m_registered_interfaces.find( string( id ) );
00376
00377 if ( i == m_registered_interfaces.end() ) { return NULL; }
00378
00379 return i->second;
00380 }
00381
00382
00383
00384
00385 fawkes::Logger*
00386 EclipseAgentThread::get_logger()
00387 {
00388 return logger;
00389 }
00390
00391
00392
00393
00394 EclipseAgentThread*
00395 EclipseAgentThread::instance()
00396 {
00397 if ( !m_instance )
00398 { throw Exception( "No instance of type EclipseThread instantiated" ); }
00399
00400 return m_instance;
00401 }