pvaClientCPP  4.8.1-dev
pvaClientNTMultiMonitor.cpp
Go to the documentation of this file.
1 /* pvaClientNTMultiMonitor.cpp */
12 #include <epicsThread.h>
13 #include <pv/standardField.h>
14 #include <pv/convert.h>
15 #include <epicsMath.h>
16 
17 #define epicsExportSharedSymbols
18 
20 
21 using namespace epics::pvData;
22 using namespace epics::pvAccess;
23 using namespace epics::nt;
24 using namespace std;
25 
26 namespace epics { namespace pvaClient {
27 
28 PvaClientNTMultiMonitorPtr PvaClientNTMultiMonitor::create(
29  PvaClientMultiChannelPtr const &pvaMultiChannel,
30  PvaClientChannelArray const &pvaClientChannelArray,
31  PVStructurePtr const & pvRequest)
32 {
33  UnionConstPtr u = getFieldCreate()->createVariantUnion();
34  PvaClientNTMultiMonitorPtr pvaClientNTMultiMonitor(
35  new PvaClientNTMultiMonitor(u,pvaMultiChannel,pvaClientChannelArray,pvRequest));
36  return pvaClientNTMultiMonitor;
37 }
38 
39 PvaClientNTMultiMonitor::PvaClientNTMultiMonitor(
40  UnionConstPtr const & u,
41  PvaClientMultiChannelPtr const &pvaClientMultiChannel,
42  PvaClientChannelArray const &pvaClientChannelArray,
43  PVStructurePtr const & pvRequest)
44 : pvaClientMultiChannel(pvaClientMultiChannel),
45  pvaClientChannelArray(pvaClientChannelArray),
46  pvRequest(pvRequest),
47  nchannel(pvaClientChannelArray.size()),
48  pvaClientNTMultiData(
49  PvaClientNTMultiData::create(
50  u,
51  pvaClientMultiChannel,
52  pvaClientChannelArray,
53  pvRequest)),
54  isConnected(false)
55 {
56  if(PvaClient::getDebug()) cout<< "PvaClientNTMultiMonitor::PvaClientNTMultiMonitor()\n";
57 }
58 
59 
60 PvaClientNTMultiMonitor::~PvaClientNTMultiMonitor()
61 {
62  if(PvaClient::getDebug()) cout<< "PvaClientNTMultiMonitor::~PvaClientNTMultiMonitor()\n";
63 }
64 
65 
66 void PvaClientNTMultiMonitor::connect()
67 {
68  pvaClientMonitor.resize(nchannel);
69  shared_vector<epics::pvData::boolean> isConnected = pvaClientMultiChannel->getIsConnected();
70  for(size_t i=0; i<nchannel; ++i)
71  {
72  if(isConnected[i]) {
73  pvaClientMonitor[i] = pvaClientChannelArray[i]->createMonitor(pvRequest);
74  pvaClientMonitor[i]->issueConnect();
75  }
76  }
77  for(size_t i=0; i<nchannel; ++i)
78  {
79  if(isConnected[i]) {
80  Status status = pvaClientMonitor[i]->waitConnect();
81  if(status.isOK()) continue;
82  string message = string("channel ") +pvaClientChannelArray[i]->getChannelName()
83  + " PvaChannelMonitor::waitConnect " + status.getMessage();
84  throw std::runtime_error(message);
85  }
86  }
87  for(size_t i=0; i<nchannel; ++i)
88  {
89  if(isConnected[i]) pvaClientMonitor[i]->start();
90  }
91  this->isConnected = true;
92 }
93 
94 bool PvaClientNTMultiMonitor::poll(bool valueOnly)
95 {
96  if(!isConnected) connect();
97  bool result = false;
98  shared_vector<epics::pvData::boolean> isConnected = pvaClientMultiChannel->getIsConnected();
99  pvaClientNTMultiData->startDeltaTime();
100  for(size_t i=0; i<nchannel; ++i)
101  {
102  if(isConnected[i]) {
103  if(!pvaClientMonitor[i]){
104  pvaClientMonitor[i]=pvaClientChannelArray[i]->createMonitor(pvRequest);
105  pvaClientMonitor[i]->connect();
106  pvaClientMonitor[i]->start();
107  }
108  if(pvaClientMonitor[i]->poll()) {
109  pvaClientNTMultiData->setPVStructure(
110  pvaClientMonitor[i]->getData()->getPVStructure(),i);
111  pvaClientMonitor[i]->releaseEvent();
112  result = true;
113  }
114  }
115  }
116  if(result) pvaClientNTMultiData->endDeltaTime(valueOnly);
117  return result;
118 }
119 
120 bool PvaClientNTMultiMonitor::waitEvent(double waitForEvent)
121 {
122  if(poll()) return true;
123  TimeStamp start;
124  start.getCurrent();
125  TimeStamp now;
126  while(true) {
127  epicsThreadSleep(.1);
128  if(poll()) return true;
129  now.getCurrent();
130  double diff = TimeStamp::diff(now,start);
131  if(diff>=waitForEvent) break;
132  }
133  return false;
134 }
135 
136 PvaClientNTMultiDataPtr PvaClientNTMultiMonitor::getData()
137 {
138  return pvaClientNTMultiData;
139 }
140 
141 }}
epics::pvData::shared_vector< PvaClientChannelPtr > PvaClientChannelArray
STL namespace.
Provides channel monitor to multiple channels where the value field of each channel is presented as a...
std::tr1::shared_ptr< PvaClientNTMultiData > PvaClientNTMultiDataPtr
std::tr1::shared_ptr< PvaClientNTMultiMonitor > PvaClientNTMultiMonitorPtr
std::tr1::shared_ptr< PvaClientMultiChannel > PvaClientMultiChannelPtr