pvaClientCPP  4.8.1-dev
pvaClientMultiChannel.cpp
Go to the documentation of this file.
1 /* pvaClientMultiChannel.cpp */
12 #include <map>
13 #include <pv/event.h>
14 #include <pv/lock.h>
15 
16 #define epicsExportSharedSymbols
17 
19 
20 using namespace epics::pvData;
21 using namespace epics::pvAccess;
22 using namespace std;
23 
24 namespace epics { namespace pvaClient {
25 
26 static FieldCreatePtr fieldCreate = getFieldCreate();
27 static CreateRequest::shared_pointer createRequestPvt = CreateRequest::create();
28 
29 PvaClientMultiChannelPtr PvaClientMultiChannel::create(
30  PvaClientPtr const &pvaClient,
31  shared_vector<const string> const & channelNames,
32  string const & providerName,
33  size_t maxNotConnected,
34  shared_vector<const string> const & providerNames)
35 {
38  pvaClient,channelNames,providerName,maxNotConnected,providerNames));
39 }
40 
41 
42 PvaClientMultiChannel::PvaClientMultiChannel(
43  PvaClientPtr const &pvaClient,
44  shared_vector<const string> const & channelNames,
45  string const & providerName,
46  size_t maxNotConnected,
47  shared_vector<const string> const & providerNames)
48 : pvaClient(pvaClient),
49  channelNames(channelNames),
50  providerName(providerName),
51  maxNotConnected(maxNotConnected),
52  providerNames(providerNames),
53  numChannel(channelNames.size()),
54  numProviderNames(providerNames.size()),
55  numConnected(0),
56  firstConnect(true),
57  pvaClientChannelArray(PvaClientChannelArray(numChannel,PvaClientChannelPtr())),
58  isConnected(shared_vector<epics::pvData::boolean>(numChannel,false)),
59  createRequest(CreateRequest::create())
60 {
61  if(PvaClient::getDebug()) cout<< "PvaClientMultiChannel::PvaClientMultiChannel()\n";
62 }
63 
64 PvaClientMultiChannel::~PvaClientMultiChannel()
65 {
66  if(PvaClient::getDebug()) cout<< "PvaClientMultiChannel::~PvaClientMultiChannel()\n";
67 }
68 
69 void PvaClientMultiChannel::checkConnected()
70 {
71  if(firstConnect) {
72  connect();
73  firstConnect = false;
74  }
75 }
76 
77 shared_vector<const string> PvaClientMultiChannel::getChannelNames()
78 {
79  return channelNames;
80 }
81 
82 Status PvaClientMultiChannel::connect(double timeout)
83 {
84  if(!firstConnect) return Status::Ok;
85  firstConnect = false;
86  for(size_t i=0; i< numChannel; ++i) {
87  if(numProviderNames<=i) {
88  pvaClientChannelArray[i] = pvaClient->createChannel(channelNames[i],providerName);
89  } else {
90  pvaClientChannelArray[i] = pvaClient->createChannel(channelNames[i],providerNames[i]);
91  }
92  pvaClientChannelArray[i]->issueConnect();
93  }
94  Status returnStatus = Status::Ok;
95  Status status = Status::Ok;
96  size_t numBad = 0;
97  for(size_t i=0; i< numChannel; ++i) {
98  if(numBad==0) {
99  status = pvaClientChannelArray[i]->waitConnect(timeout);
100  } else {
101  status = pvaClientChannelArray[i]->waitConnect(.001);
102  }
103  if(status.isOK()) {
104  ++numConnected;
105  isConnected[i] = true;
106  } else {
107  if(returnStatus.isOK()) returnStatus = status;
108  ++numBad;
109  }
110  }
111  return numBad>maxNotConnected ? returnStatus : Status::Ok;
112 }
113 
114 
115 bool PvaClientMultiChannel::allConnected()
116 {
117  return (numConnected==numChannel) ? true : false;
118 }
119 
120 bool PvaClientMultiChannel::connectionChange()
121 {
122  for(size_t i=0; i<numChannel; ++i) {
123  PvaClientChannelPtr pvaClientChannel = pvaClientChannelArray[i];
124  Channel::shared_pointer channel = pvaClientChannel->getChannel();
125  Channel::ConnectionState stateNow = channel->getConnectionState();
126  bool connectedNow = stateNow==Channel::CONNECTED ? true : false;
127  if(connectedNow!=isConnected[i]) return true;
128  }
129  return false;
130 }
131 
132 shared_vector<epics::pvData::boolean> PvaClientMultiChannel::getIsConnected()
133 {
134  for(size_t i=0; i<numChannel; ++i) {
135  PvaClientChannelPtr pvaClientChannel = pvaClientChannelArray[i];
136  if(!pvaClientChannel) {
137  isConnected[i] = false;
138  continue;
139  }
140  Channel::shared_pointer channel = pvaClientChannel->getChannel();
141  Channel::ConnectionState stateNow = channel->getConnectionState();
142  isConnected[i] = (stateNow==Channel::CONNECTED) ? true : false;
143  }
144  return isConnected;
145 }
146 
147 PvaClientChannelArray PvaClientMultiChannel::getPvaClientChannelArray()
148 {
149  return pvaClientChannelArray;
150 }
151 
152 PvaClientPtr PvaClientMultiChannel::getPvaClient()
153 {
154  return pvaClient;
155 }
156 
157 
158 
159 PvaClientMultiGetDoublePtr PvaClientMultiChannel::createGet()
160 {
161  checkConnected();
162  return PvaClientMultiGetDouble::create(shared_from_this(),pvaClientChannelArray);
163 }
164 
165 
166 PvaClientMultiPutDoublePtr PvaClientMultiChannel::createPut()
167 {
168  checkConnected();
169  return PvaClientMultiPutDouble::create(shared_from_this(),pvaClientChannelArray);
170 }
171 
172 
173 PvaClientMultiMonitorDoublePtr PvaClientMultiChannel::createMonitor()
174 {
175  checkConnected();
176  return PvaClientMultiMonitorDouble::create(shared_from_this(), pvaClientChannelArray);
177 }
178 
179 PvaClientNTMultiPutPtr PvaClientMultiChannel::createNTPut()
180 {
181  checkConnected();
182  return PvaClientNTMultiPut::create(shared_from_this(), pvaClientChannelArray);
183 }
184 
185 
186 PvaClientNTMultiGetPtr PvaClientMultiChannel::createNTGet(std::string const &request)
187 {
188  checkConnected();
189  PVStructurePtr pvRequest = createRequest->createRequest(request);
190  if(!pvRequest) {
191  string message = " PvaClientMultiChannel::createNTGet invalid pvRequest: "
192  + createRequest->getMessage();
193  throw std::runtime_error(message);
194  }
195  return PvaClientNTMultiGet::create(shared_from_this(), pvaClientChannelArray,pvRequest);
196 }
197 
198 PvaClientNTMultiMonitorPtr PvaClientMultiChannel::createNTMonitor(std::string const &request)
199 {
200  checkConnected();
201  PVStructurePtr pvRequest = createRequest->createRequest(request);
202  if(!pvRequest) {
203  string message = " PvaClientMultiChannel::createNTMonitor invalid pvRequest: "
204  + createRequest->getMessage();
205  throw std::runtime_error(message);
206  }
207  return PvaClientNTMultiMonitor::create(shared_from_this(), pvaClientChannelArray,pvRequest);
208 }
209 
210 
211 }}
std::tr1::shared_ptr< PvaClient > PvaClientPtr
Definition: pvaClient.h:46
epics::pvData::shared_vector< PvaClientChannelPtr > PvaClientChannelArray
PvaMultiChannel is a synchronous interface for accessing multiple channels.
std::tr1::shared_ptr< PvaClientChannel > PvaClientChannelPtr
Definition: pvaClient.h:59
STL namespace.
std::tr1::shared_ptr< PvaClientNTMultiGet > PvaClientNTMultiGetPtr
std::tr1::shared_ptr< PvaClientNTMultiPut > PvaClientNTMultiPutPtr
std::tr1::shared_ptr< PvaClientMultiMonitorDouble > PvaClientMultiMonitorDoublePtr
std::tr1::shared_ptr< PvaClientNTMultiMonitor > PvaClientNTMultiMonitorPtr
std::tr1::shared_ptr< PvaClientMultiGetDouble > PvaClientMultiGetDoublePtr
std::tr1::shared_ptr< PvaClientMultiChannel > PvaClientMultiChannelPtr
std::tr1::shared_ptr< PvaClientMultiPutDouble > PvaClientMultiPutDoublePtr