pvaClientCPP  4.8.1-dev
pvaClientNTMultiPut.cpp
Go to the documentation of this file.
1 /* PvaClientNTMultiPut.cpp */
12 #include <pv/standardField.h>
13 #include <pv/convert.h>
14 #include <epicsMath.h>
15 
16 #define epicsExportSharedSymbols
17 
19 
20 using namespace epics::pvData;
21 using namespace epics::pvAccess;
22 using namespace epics::nt;
23 using namespace std;
24 
25 namespace epics { namespace pvaClient {
26 
27 PvaClientNTMultiPutPtr PvaClientNTMultiPut::create(
28  PvaClientMultiChannelPtr const &pvaMultiChannel,
29  PvaClientChannelArray const &pvaClientChannelArray)
30 {
32  new PvaClientNTMultiPut(pvaMultiChannel,pvaClientChannelArray));
33 }
34 
35 PvaClientNTMultiPut::PvaClientNTMultiPut(
36  PvaClientMultiChannelPtr const &pvaClientMultiChannel,
37  PvaClientChannelArray const &pvaClientChannelArray)
38 : pvaClientMultiChannel(pvaClientMultiChannel),
39  pvaClientChannelArray(pvaClientChannelArray),
40  nchannel(pvaClientChannelArray.size()),
41  unionValue(shared_vector<PVUnionPtr>(nchannel,PVUnionPtr())),
42  value(shared_vector<PVFieldPtr>(nchannel,PVFieldPtr())),
43  isConnected(false)
44 {
45  if(PvaClient::getDebug()) cout<< "PvaClientNTMultiPut::PvaClientNTMultiPut()\n";
46 }
47 
48 
49 PvaClientNTMultiPut::~PvaClientNTMultiPut()
50 {
51  if(PvaClient::getDebug()) cout<< "PvaClientNTMultiPut::~PvaClientNTMultiPut()\n";
52 }
53 
54 void PvaClientNTMultiPut::connect()
55 {
56  pvaClientPut.resize(nchannel);
57  shared_vector<epics::pvData::boolean> isConnected = pvaClientMultiChannel->getIsConnected();
58  for(size_t i=0; i<nchannel; ++i)
59  {
60  if(isConnected[i]) {
61  pvaClientPut[i] = pvaClientChannelArray[i]->createPut();
62  pvaClientPut[i]->issueConnect();
63  }
64  }
65  for(size_t i=0; i<nchannel; ++i)
66  {
67  if(isConnected[i]) {
68  Status status = pvaClientPut[i]->waitConnect();
69  if(status.isOK()) continue;
70  string message = string("channel ") +pvaClientChannelArray[i]->getChannelName()
71  + " PvaChannelPut::waitConnect " + status.getMessage();
72  throw std::runtime_error(message);
73  }
74  }
75  for(size_t i=0; i<nchannel; ++i)
76  {
77  if(isConnected[i]) {
78  pvaClientPut[i]->issueGet();
79  }
80  }
81  for(size_t i=0; i<nchannel; ++i)
82  {
83  if(isConnected[i]) {
84  Status status = pvaClientPut[i]->waitGet();
85  if(status.isOK()) continue;
86  string message = string("channel ") +pvaClientChannelArray[i]->getChannelName()
87  + " PvaChannelPut::waitGet " + status.getMessage();
88  throw std::runtime_error(message);
89  }
90  }
91  FieldCreatePtr fieldCreate = getFieldCreate();
92  PVDataCreatePtr pvDataCreate = getPVDataCreate();
93  for(size_t i=0; i<nchannel; ++i)
94  {
95  if(isConnected[i]) {
96  value[i] = pvaClientPut[i]->getData()->getValue();
97  FieldBuilderPtr builder = fieldCreate->createFieldBuilder();
98  builder->add("value",value[i]->getField());
99  unionValue[i] = pvDataCreate->createPVUnion(builder->createUnion());
100  }
101  }
102  this->isConnected = true;
103 }
104 
105 shared_vector<PVUnionPtr> PvaClientNTMultiPut::getValues()
106 {
107  if(!isConnected) connect();
108  shared_vector<epics::pvData::boolean> isConnected = pvaClientMultiChannel->getIsConnected();
109  for(size_t i=0; i<nchannel; ++i)
110  {
111  if(isConnected[i]) {
112  if(!pvaClientPut[i]){
113  pvaClientPut[i] = pvaClientChannelArray[i]->createPut();
114  pvaClientPut[i]->connect();
115  pvaClientPut[i]->get();
116  value[i] = pvaClientPut[i]->getData()->getValue();
117  FieldCreatePtr fieldCreate = getFieldCreate();
118  PVDataCreatePtr pvDataCreate = getPVDataCreate();
119  FieldBuilderPtr builder = fieldCreate->createFieldBuilder();
120  builder->add("value",value[i]->getField());
121  unionValue[i] = pvDataCreate->createPVUnion(builder->createUnion());
122  }
123  }
124  }
125  return unionValue;
126 }
127 
128 void PvaClientNTMultiPut::put()
129 {
130  if(!isConnected) connect();
131  shared_vector<epics::pvData::boolean> isConnected = pvaClientMultiChannel->getIsConnected();
132  for(size_t i=0; i<nchannel; ++i)
133  {
134  if(isConnected[i]) {
135  if(!pvaClientPut[i]){
136  pvaClientPut[i] = pvaClientChannelArray[i]->createPut();
137  pvaClientPut[i]->connect();
138  pvaClientPut[i]->get();
139  value[i] = pvaClientPut[i]->getData()->getValue();
140  FieldCreatePtr fieldCreate = getFieldCreate();
141  PVDataCreatePtr pvDataCreate = getPVDataCreate();
142  FieldBuilderPtr builder = fieldCreate->createFieldBuilder();
143  builder->add("value",value[i]->getField());
144  unionValue[i] = pvDataCreate->createPVUnion(builder->createUnion());
145  }
146  value[i]->copy(*unionValue[i]->get());
147  pvaClientPut[i]->issuePut();
148  }
149  }
150  for(size_t i=0; i<nchannel; ++i)
151  {
152  if(isConnected[i]) {
153  Status status = pvaClientPut[i]->waitPut();
154  if(status.isOK()) continue;
155  string message = string("channel ") +pvaClientChannelArray[i]->getChannelName()
156  + " PvaChannelPut::waitPut " + status.getMessage();
157  throw std::runtime_error(message);
158  }
159  }
160 }
161 
162 
163 }}
epics::pvData::shared_vector< PvaClientChannelPtr > PvaClientChannelArray
STL namespace.
Provides channelPut to multiple channels where the value field of each channel is presented as a unio...
std::tr1::shared_ptr< PvaClientNTMultiPut > PvaClientNTMultiPutPtr
std::tr1::shared_ptr< PvaClientMultiChannel > PvaClientMultiChannelPtr