Main Page | Namespace List | Class Hierarchy | Class List | File List | Class Members | File Members

src/DataSource/DataSource.cpp

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 /***************************************************************************
00003  *
00004  * The IPPL Framework
00005  * 
00006  * This program was prepared by PSI. 
00007  * All rights in the program are reserved by PSI.
00008  * Neither PSI nor the author(s)
00009  * makes any warranty, express or implied, or assumes any liability or
00010  * responsibility for the use of this software
00011  *
00012  * Visit http://www.acl.lanl.gov/POOMS for more details
00013  *
00014  ***************************************************************************/
00015 
00016 // -*- C++ -*-
00017 /***************************************************************************
00018  *
00019  * The IPPL Framework
00020  * 
00021  *
00022  * Visit http://people.web.psi.ch/adelmann/ for more details
00023  *
00024  ***************************************************************************/
00025 
00026 // include files
00027 #include "DataSource/DataSource.h"
00028 #include "DataSource/DataSourceObject.h"
00029 #include "DataSource/DataConnect.h"
00030 #include "DataSource/DataConnectCreator.h"
00031 #include "Utility/IpplInfo.h"
00032 
00033 
00035 // constructor
00036 DataSource::DataSource() {
00037   // nothing to do
00038 }
00039 
00040 
00042 // destructor
00043 DataSource::~DataSource() {
00044   //Inform dbgmsg("DataSource::~DataSource", INFORM_ALL_NODES);
00045   //dbgmsg << "Calling disconnect() from DataSource destructor." << endl;
00046 
00047   // disconnect from all existing connections, if we still have any
00048   disconnect();
00049 }
00050 
00051 
00053 // find the first DataSourceObject which is connected to the given DataConnect,
00054 // and return it; otherwise, return 0
00055 DataSourceObject *DataSource::findDataSourceObject(DataConnect *dc) const {
00056   container_t::const_iterator a = ConnectionList.begin();
00057   for ( ; a != ConnectionList.end(); ++a)
00058     if (dc == (*a)->getConnection())
00059       return (*a);
00060 
00061   // if we're here, we're not connected
00062   return 0;
00063 }
00064 
00065 
00067 // Are we connected to the given DataConnect?  If not specified, just return
00068 // whether we're connected to anything.
00069 bool DataSource::connected(DataConnect *dataconn) const {
00070   if (dataconn == 0)
00071     return ( ! ConnectionList.empty() );
00072   else
00073     return (findDataSourceObject(dataconn) != 0);
00074 }
00075 
00076 
00078 // Register an object as something that can be a source of data.  Return
00079 // success.  Arguments = name of item, connection to use, and type of
00080 // connection (INPUT, OUTPUT, or BOTH).  If the connection
00081 // has not been created yet (e.g., it is NULL), create a new default
00082 // connection (or use the existing default one).  Return the connection.
00083 DataConnect *DataSource::connect(const char *nm,DataConnect *dataconn,int tm) {
00084   //Inform dbgmsg("DataSource::connect", INFORM_ALL_NODES);
00085   //dbgmsg << "Connecting '" << nm << "'" << endl;
00086   //if (dataconn != 0)
00087   //  dbgmsg << " to '" << dataconn->name() << "'";
00088   //dbgmsg << endl;
00089 
00090   // figure out which connection to use ... if none given, we must get a
00091   // new one
00092   if (dataconn == 0) {
00093     //dbgmsg << "Creating new connection ..." << endl;
00094     dataconn = DataConnectCreator::create();
00095   }
00096 
00097   // make sure we're not already connected to this object
00098   if (connected(dataconn)) {
00099     ERRORMSG("Cannot connect '" << nm << "' to the same agency twice." <<endl);
00100     ERRORMSG("dataconn = " << (void *)dataconn << endl);
00101     return 0;
00102   }
00103 
00104   // set the transfer method properly, if we are requested to use the default
00105   if (tm == DataSource::DEFAULT)
00106     tm = dataconn->getDefaultTransferMethod();
00107 
00108   // OK, connect away ... create new DataSourceObject, which establishes
00109   // the connection.  If we fail to connect, delete the created Obj
00110   DataSourceObject *dso = createDataSourceObject(nm, dataconn, tm);
00111   if (dso != 0 && !connect(dso)) {
00112     delete dso;
00113     return 0;
00114   }
00115 
00116   // if we're here, everything was ok ... return the connection we used
00117   return dataconn;
00118 }
00119 
00120 
00122 // Register the given DataSourceObject directly.  This is simpler than
00123 // the above version of connect, since the DataSourceObject has already
00124 // been created.  It can be used to register most any type of connection,
00125 // even one using DataConnect objects that are not part of IPPL itself.
00126 // Return success.
00127 bool DataSource::connect(DataSourceObject *dso) {
00128 
00129   // make sure the connection is OK
00130   if (dso != 0 && dso->connected() && dso->getSource() == this) {
00131     ConnectionList.push_back(dso);
00132     dso->getConnection()->checkin(this);
00133     return true;
00134   }
00135 
00136   // if we're here, there was a problem
00137   return false;
00138 }
00139 
00140 
00142 // Disconnect an object from the given receiver.  Return success.
00143 bool DataSource::disconnect(DataConnect *dataconn) {
00144   //Inform dbgmsg("DataSource::disconnect", INFORM_ALL_NODES);
00145   //dbgmsg << "Disconnecting source from connection(s) '";
00146   //dbgmsg << (dataconn != 0 ? dataconn->name() : "(all)")<< "' ..." << endl;
00147 
00148   container_t::iterator a = ConnectionList.begin();
00149   for ( ; a != ConnectionList.end(); ++a) {
00150     DataConnect *dc = (*a)->getConnection();
00151     if (dataconn == 0 || dataconn == dc) {
00152       //dbgmsg << "Calling checkout from the DataSource ..." << endl;
00153       dc->checkout(this, false);
00154       //dbgmsg << "Deleting DSO '" << (*a)->name() << "' ..." << endl;
00155       delete (*a);
00156       if (dataconn == dc) {
00157         ConnectionList.erase(a);
00158         return true;
00159       }
00160     }
00161   }
00162 
00163   // if we've removed all, we can erase all
00164   if (dataconn == 0 && ConnectionList.size() > 0) {
00165     //dbgmsg<<"Erasing all " << ConnectionList.size() << " DSO's ..." << endl;
00166     ConnectionList.erase(ConnectionList.begin(), ConnectionList.end());
00167   }
00168 
00169   return (dataconn == 0);
00170 }
00171 
00172 
00174 // Update the object, that is, make sure the receiver of the data has a
00175 // current and consistent snapshot of the current state.  Return success.
00176 bool DataSource::updateConnection(DataConnect *dataconn) {
00177   container_t::iterator a = ConnectionList.begin();
00178   for ( ; a != ConnectionList.end(); ++a) {
00179     if (dataconn == 0)
00180       (*a)->update();
00181     else if (dataconn == (*a)->getConnection())
00182       return (*a)->update();
00183   }
00184 
00185   // if we're here, we were successful only if we tried to disconnect all
00186   return (dataconn == 0);
00187 }
00188 
00189 
00191 // Indicate to the receiver that we're allowing them time to manipulate the
00192 // data (e.g., for a viz program, to rotate it, change representation, etc.)
00193 // This should only return when the manipulation is done.  For some cases,
00194 // this will be a no-op.
00195 void DataSource::interact(DataConnect *dataconn) {
00196   container_t::iterator a = ConnectionList.begin();
00197   for ( ; a != ConnectionList.end(); ++a) {
00198     if (dataconn == 0 || dataconn == (*a)->getConnection())
00199       (*a)->interact();
00200   }
00201 }
00202 
00203 
00205 // Pass on a string to the connection, most likely to give it a
00206 // command to do some action.  Similar to the above interact, except
00207 // the request for interaction involves the given string
00208 void DataSource::interact(const char *str, DataConnect *dataconn) {
00209   container_t::iterator a = ConnectionList.begin();
00210   for ( ; a != ConnectionList.end(); ++a) {
00211     if (dataconn == 0 || dataconn == (*a)->getConnection())
00212       (*a)->interact(str);
00213   }
00214 }
00215 
00216 
00217 /***************************************************************************
00218  * $RCSfile: DataSource.cpp,v $   $Author: adelmann $
00219  * $Revision: 1.1.1.1 $   $Date: 2003/01/23 07:40:25 $
00220  * IPPL_VERSION_ID: $Id: DataSource.cpp,v 1.1.1.1 2003/01/23 07:40:25 adelmann Exp $ 
00221  ***************************************************************************/

Generated on Fri Nov 2 01:25:55 2007 for IPPL by doxygen 1.3.5