OPAL (Object Oriented Parallel Accelerator Library) 2022.1
OPAL
DataSource.cpp
Go to the documentation of this file.
1// -*- C++ -*-
2/***************************************************************************
3 *
4 * The IPPL Framework
5 *
6 * This program was prepared by PSI.
7 * All rights in the program are reserved by PSI.
8 * Neither PSI nor the author(s)
9 * makes any warranty, express or implied, or assumes any liability or
10 * responsibility for the use of this software
11 *
12 * Visit www.amas.web.psi for more details
13 *
14 ***************************************************************************/
15
16// -*- C++ -*-
17/***************************************************************************
18 *
19 * The IPPL Framework
20 *
21 *
22 * Visit http://people.web.psi.ch/adelmann/ for more details
23 *
24 ***************************************************************************/
25
26// include files
31#include "Utility/IpplInfo.h"
32
33
35// constructor
37 // nothing to do
38}
39
40
42// destructor
44 //Inform dbgmsg("DataSource::~DataSource", INFORM_ALL_NODES);
45 //dbgmsg << "Calling disconnect() from DataSource destructor." << endl;
46
47 // disconnect from all existing connections, if we still have any
48 disconnect();
49}
50
51
53// find the first DataSourceObject which is connected to the given DataConnect,
54// and return it; otherwise, return 0
56 container_t::const_iterator a = ConnectionList.begin();
57 for ( ; a != ConnectionList.end(); ++a)
58 if (dc == (*a)->getConnection())
59 return (*a);
60
61 // if we're here, we're not connected
62 return 0;
63}
64
65
67// Are we connected to the given DataConnect? If not specified, just return
68// whether we're connected to anything.
69bool DataSource::connected(DataConnect *dataconn) const {
70 if (dataconn == 0)
71 return ( ! ConnectionList.empty() );
72 else
73 return (findDataSourceObject(dataconn) != 0);
74}
75
76
78// Register an object as something that can be a source of data. Return
79// success. Arguments = name of item, connection to use, and type of
80// connection (INPUT, OUTPUT, or BOTH). If the connection
81// has not been created yet (e.g., it is NULL), create a new default
82// connection (or use the existing default one). Return the connection.
83DataConnect *DataSource::connect(const char *nm,DataConnect *dataconn,int tm) {
84 //Inform dbgmsg("DataSource::connect", INFORM_ALL_NODES);
85 //dbgmsg << "Connecting '" << nm << "'" << endl;
86 //if (dataconn != 0)
87 // dbgmsg << " to '" << dataconn->name() << "'";
88 //dbgmsg << endl;
89
90 // figure out which connection to use ... if none given, we must get a
91 // new one
92 if (dataconn == 0) {
93 //dbgmsg << "Creating new connection ..." << endl;
94 dataconn = DataConnectCreator::create();
95 }
96
97 // make sure we're not already connected to this object
98 if (connected(dataconn)) {
99 ERRORMSG("Cannot connect '" << nm << "' to the same agency twice." <<endl);
100 ERRORMSG("dataconn = " << (void *)dataconn << endl);
101 return 0;
102 }
103
104 // set the transfer method properly, if we are requested to use the default
105 if (tm == DataSource::DEFAULT)
106 tm = dataconn->getDefaultTransferMethod();
107
108 // OK, connect away ... create new DataSourceObject, which establishes
109 // the connection. If we fail to connect, delete the created Obj
110 DataSourceObject *dso = createDataSourceObject(nm, dataconn, tm);
111 if (dso != 0 && !connect(dso)) {
112 delete dso;
113 return 0;
114 }
115
116 // if we're here, everything was ok ... return the connection we used
117 return dataconn;
118}
119
120
122// Register the given DataSourceObject directly. This is simpler than
123// the above version of connect, since the DataSourceObject has already
124// been created. It can be used to register most any type of connection,
125// even one using DataConnect objects that are not part of IPPL itself.
126// Return success.
128
129 // make sure the connection is OK
130 if (dso != 0 && dso->connected() && dso->getSource() == this) {
131 ConnectionList.push_back(dso);
132 dso->getConnection()->checkin(this);
133 return true;
134 }
135
136 // if we're here, there was a problem
137 return false;
138}
139
140
142// Disconnect an object from the given receiver. Return success.
144 //Inform dbgmsg("DataSource::disconnect", INFORM_ALL_NODES);
145 //dbgmsg << "Disconnecting source from connection(s) '";
146 //dbgmsg << (dataconn != 0 ? dataconn->name() : "(all)")<< "' ..." << endl;
147
149 for ( ; a != ConnectionList.end(); ++a) {
150 DataConnect *dc = (*a)->getConnection();
151 if (dataconn == 0 || dataconn == dc) {
152 //dbgmsg << "Calling checkout from the DataSource ..." << endl;
153 dc->checkout(this, false);
154 //dbgmsg << "Deleting DSO '" << (*a)->name() << "' ..." << endl;
155 delete (*a);
156 if (dataconn == dc) {
157 ConnectionList.erase(a);
158 return true;
159 }
160 }
161 }
162
163 // if we've removed all, we can erase all
164 if (dataconn == 0 && !ConnectionList.empty()) {
165 //dbgmsg<<"Erasing all " << ConnectionList.size() << " DSO's ..." << endl;
166 ConnectionList.erase(ConnectionList.begin(), ConnectionList.end());
167 }
168
169 return (dataconn == 0);
170}
171
172
174// Update the object, that is, make sure the receiver of the data has a
175// current and consistent snapshot of the current state. Return success.
178 for ( ; a != ConnectionList.end(); ++a) {
179 if (dataconn == 0)
180 (*a)->update();
181 else if (dataconn == (*a)->getConnection())
182 return (*a)->update();
183 }
184
185 // if we're here, we were successful only if we tried to disconnect all
186 return (dataconn == 0);
187}
188
189
191// Indicate to the receiver that we're allowing them time to manipulate the
192// data (e.g., for a viz program, to rotate it, change representation, etc.)
193// This should only return when the manipulation is done. For some cases,
194// this will be a no-op.
197 for ( ; a != ConnectionList.end(); ++a) {
198 if (dataconn == 0 || dataconn == (*a)->getConnection())
199 (*a)->interact();
200 }
201}
202
203
205// Pass on a string to the connection, most likely to give it a
206// command to do some action. Similar to the above interact, except
207// the request for interaction involves the given string
208void DataSource::interact(const char *str, DataConnect *dataconn) {
210 for ( ; a != ConnectionList.end(); ++a) {
211 if (dataconn == 0 || dataconn == (*a)->getConnection())
212 (*a)->interact(str);
213 }
214}
215
216
217/***************************************************************************
218 * $RCSfile: DataSource.cpp,v $ $Author: adelmann $
219 * $Revision: 1.1.1.1 $ $Date: 2003/01/23 07:40:25 $
220 * IPPL_VERSION_ID: $Id: DataSource.cpp,v 1.1.1.1 2003/01/23 07:40:25 adelmann Exp $
221 ***************************************************************************/
std::complex< double > a
Inform & endl(Inform &inf)
Definition: Inform.cpp:42
#define ERRORMSG(msg)
Definition: IpplInfo.h:350
std::string::iterator iterator
Definition: MSLang.h:16
bool checkin(DataSource *)
bool checkout(DataSource *, bool=true)
int getDefaultTransferMethod() const
Definition: DataConnect.h:58
static DataConnect * create()
virtual ~DataSource()
Definition: DataSource.cpp:43
void interact(DataConnect *=0)
Definition: DataSource.cpp:195
bool connected(DataConnect *=0) const
Definition: DataSource.cpp:69
container_t ConnectionList
Definition: DataSource.h:138
virtual DataSourceObject * createDataSourceObject(const char *, DataConnect *, int)=0
DataConnect * connect(const char *, DataConnect *=0, int=DataSource::DEFAULT)
Definition: DataSource.cpp:83
DataSourceObject * findDataSourceObject(DataConnect *) const
Definition: DataSource.cpp:55
bool disconnect(DataConnect *=0)
Definition: DataSource.cpp:143
bool updateConnection(DataConnect *=0)
Definition: DataSource.cpp:176
bool connected() const
DataConnect * getConnection()
DataSource * getSource()