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 <cstdio>
00033 #include <cstdlib>
00034 #include <cstring>
00035 #include <vector>
00036
00037 using namespace std;
00038 using namespace fawkes;
00039
00040
00041
00042
00043
00044
00045
00046 extern "C" int ec_external( dident, int (*) (), dident );
00047
00048 EclipseAgentThread* EclipseAgentThread::m_instance = NULL;
00049
00050
00051 EclipseAgentThread::EclipseAgentThread()
00052 : Thread( "ECLiPSe thread", fawkes::Thread::OPMODE_CONTINUOUS ),
00053 m_initialized( false )
00054 {
00055 m_instance = this;
00056 }
00057
00058
00059 EclipseAgentThread::~EclipseAgentThread()
00060 {
00061 }
00062
00063 void
00064 EclipseAgentThread::init()
00065 {
00066
00067 char* eclipse_dir = NULL;
00068 try
00069 {
00070 eclipse_dir = strdup( config->get_string( "/readylogagent/eclipse_dir" ).c_str() );
00071 logger->log_info( name(), "Setting ECLIPSEDIR to %s", eclipse_dir );
00072 ec_set_option_ptr( EC_OPTION_ECLIPSEDIR, (void*) eclipse_dir );
00073 }
00074 catch (...)
00075 {
00076
00077 }
00078
00079
00080 if ( 0 != ec_init() )
00081 { throw fawkes::Exception( "Failed to initialize ECLiPSe context" ); }
00082
00083 free( eclipse_dir );
00084
00085
00086 if ( EC_succeed != ec_external( ec_did( "read_interface", 2 ), p_read_interface, ec_did( "eclipse", 0 ) ) )
00087 { throw Exception( "Registering external predicate read_interface/2 failed" ); }
00088 if ( EC_succeed != ec_external( ec_did( "write_interface", 2 ), p_write_interface, ec_did( "eclipse", 0 ) ) )
00089 { throw Exception( "Registering external predicate write_interface/2 failed" ); }
00090 if ( EC_succeed != ec_external( ec_did( "send_message", 2 ), p_send_message, ec_did( "eclipse", 0 ) ) )
00091 { throw Exception( "Registering external predicate send_message/2 failed" ); }
00092 if ( EC_succeed != ec_external( ec_did( "recv_messages", 2 ), p_recv_messages, ec_did( "eclipse", 0 ) ) )
00093 { throw Exception( "Registering external predicate recv_messages/2 failed" ); }
00094 if ( EC_succeed != ec_external( ec_did( "log", 2 ), p_log, ec_did( "eclipse", 0 ) ) )
00095 { throw Exception( "Registering external predicate log/2 failed" ); }
00096
00097 m_initialized = true;
00098
00099
00100 try
00101 {
00102
00103 Configuration::ValueIterator* vit = config->search( "/readylogagent/interfaces/reading" );
00104 while ( vit->next() )
00105 {
00106 if ( vit->is_string() )
00107 {
00108 string s = vit->get_string();
00109 if ( s.find("::") == string::npos )
00110 { throw Exception( "Not a valid interface id: %s", s.c_str() ); }
00111
00112 string iftype = s.substr( 0, s.find( "::" ) );
00113 string ifname = s.substr( s.find( "::" ) + 2 );
00114
00115 logger->log_debug( name(), "Opening interface %s of type %s for reading",
00116 ifname.c_str(), iftype.c_str() );
00117
00118 Interface* iface = blackboard->open_for_reading( iftype.c_str(), ifname.c_str() );
00119 m_reading_ifaces.push_back( iface );
00120 register_interface( iface );
00121 }
00122 }
00123
00124
00125 vit = config->search( "/readylogagent/interfaces/writing" );
00126 while ( vit->next() )
00127 {
00128 if ( vit->is_string() )
00129 {
00130 string s = vit->get_string();
00131 if ( s.find("::") == string::npos )
00132 { throw Exception( "Not a valid interface id: %s", s.c_str() ); }
00133
00134 string iftype = s.substr( 0, s.find( "::" ) );
00135 string ifname = s.substr( s.find( "::" ) + 2 );
00136
00137 logger->log_debug( name(), "Opening interface %s of type %s for writing",
00138 ifname.c_str(), iftype.c_str() );
00139
00140 Interface* iface = blackboard->open_for_writing( iftype.c_str(), ifname.c_str() );
00141 m_writing_ifaces.push_back( iface );
00142 register_interface( iface );
00143 }
00144 }
00145 }
00146 catch ( Exception& e )
00147 {
00148 e.append( "Failed to open interfaces" );
00149 throw e;
00150 }
00151
00152
00153 load_file( ECLIPSE_CODE_DIR"/utils/logging.ecl" );
00154
00155
00156 load_file( ECLIPSE_CODE_DIR"/interpreter/dummy.ecl" );
00157 }
00158
00159 void
00160 EclipseAgentThread::finalize()
00161 {
00162 ec_cleanup();
00163 }
00164
00165 void
00166 EclipseAgentThread::once()
00167 {
00168 post_goal( "run" );
00169 if ( EC_succeed != EC_resume() )
00170 { throw Exception( "Error running agent program" ); }
00171 }
00172
00173
00174
00175
00176 void
00177 EclipseAgentThread::post_event( const char* event )
00178 {
00179 if ( !m_initialized ) { return; }
00180
00181
00182 char* atom = strdup( event );
00183 ::post_event( EC_atom( atom ) );
00184 free( atom );
00185 }
00186
00187
00188 void
00189 EclipseAgentThread::read_interfaces()
00190 {
00191 for ( vector< Interface* >::iterator i = m_reading_ifaces.begin();
00192 i != m_reading_ifaces.end();
00193 ++i )
00194 { (*i)->read(); }
00195
00196 for ( vector< Interface* >::iterator i = m_writing_ifaces.begin();
00197 i != m_writing_ifaces.end();
00198 ++i )
00199 { (*i)->read(); }
00200 }
00201
00202
00203 void
00204 EclipseAgentThread::write_interfaces()
00205 {
00206 for ( vector< Interface* >::iterator i = m_writing_ifaces.begin();
00207 i != m_writing_ifaces.end();
00208 ++i )
00209 { (*i)->write(); }
00210 }
00211
00212
00213
00214
00215
00216 bool
00217 EclipseAgentThread::load_file( const char* filename )
00218 {
00219 if ( !m_initialized ) { return false; }
00220
00221 char* ensure_loaded = strdup( "ensure_loaded" );
00222 post_goal( term( EC_functor( ensure_loaded, 1 ), filename ) );
00223 free( ensure_loaded );
00224
00225 if ( EC_succeed != ec_resume() )
00226 { throw Exception( "File %s could not be loaded", filename ); }
00227
00228 return true;
00229 }
00230
00231
00232
00233
00234
00235 bool
00236 EclipseAgentThread::register_interface( fawkes::Interface* interface )
00237 {
00238 if ( !m_initialized ) { return false; }
00239
00240 m_registered_interfaces[ string( interface->id() ) ] = interface;
00241
00242
00243
00244
00245
00246
00247 char* struct_name;
00248 asprintf( &struct_name, "data_%s", interface->type() );
00249
00250 post_goal( term( EC_functor( (char *) "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 std::list<const char *> message_types = interface->get_message_types();
00301 for ( std::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( (char *) "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 );
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 if ( 0 != fields.size() )
00341 {
00342 EC_word new_struct = term( EC_functor( struct_name, (int) fields.size() ), args );
00343 char* local = strdup( "local" );
00344 char* strct = strdup( "struct" );
00345 EC_word struct_def = term( EC_functor( strct, 1 ), new_struct );
00346 EC_word struct_def_local = term( EC_functor( local, 1), struct_def );
00347
00348 char* call = strdup( "call" );
00349
00350 post_goal( term( EC_functor( call, 1 ), struct_def_local ) );
00351
00352
00353 free( local );
00354 free( strct );
00355 free( call );
00356
00357 if ( EC_succeed != ec_resume() )
00358 { throw Exception( "Failed to define structure %s", struct_name ); }
00359 }
00360 }
00361
00362 free( struct_name );
00363 }
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 }