201 lines
5.8 KiB
C++
201 lines
5.8 KiB
C++
/* pvaClientMultiChannel.cpp */
|
|
/**
|
|
* Copyright - See the COPYRIGHT that is included with this distribution.
|
|
* EPICS pvData is distributed subject to a Software License Agreement found
|
|
* in file LICENSE that is included with this distribution.
|
|
*/
|
|
/**
|
|
* @author mrk
|
|
* @date 2015.02
|
|
*/
|
|
|
|
#include <map>
|
|
#include <pv/event.h>
|
|
#include <pv/lock.h>
|
|
|
|
#define epicsExportSharedSymbols
|
|
|
|
#include <pv/pvaClientMultiChannel.h>
|
|
|
|
|
|
|
|
using std::tr1::static_pointer_cast;
|
|
using namespace epics::pvData;
|
|
using namespace epics::pvAccess;
|
|
using namespace std;
|
|
|
|
namespace epics { namespace pvaClient {
|
|
|
|
static FieldCreatePtr fieldCreate = getFieldCreate();
|
|
static CreateRequest::shared_pointer createRequestPvt = CreateRequest::create();
|
|
|
|
PvaClientMultiChannelPtr PvaClientMultiChannel::create(
|
|
PvaClientPtr const &pvaClient,
|
|
epics::pvData::shared_vector<const string> const & channelNames,
|
|
string const & providerName,
|
|
size_t maxNotConnected)
|
|
{
|
|
return PvaClientMultiChannelPtr(
|
|
new PvaClientMultiChannel(pvaClient,channelNames,providerName,maxNotConnected));
|
|
}
|
|
|
|
|
|
PvaClientMultiChannel::PvaClientMultiChannel(
|
|
PvaClientPtr const &pvaClient,
|
|
epics::pvData::shared_vector<const string> const & channelName,
|
|
string const & providerName,
|
|
size_t maxNotConnected)
|
|
: pvaClient(pvaClient),
|
|
channelName(channelName),
|
|
providerName(providerName),
|
|
maxNotConnected(maxNotConnected),
|
|
numChannel(channelName.size()),
|
|
numConnected(0),
|
|
pvaClientChannelArray(PvaClientChannelArray(numChannel,PvaClientChannelPtr())),
|
|
isConnected(shared_vector<epics::pvData::boolean>(numChannel,false)),
|
|
createRequest(CreateRequest::create())
|
|
{
|
|
if(PvaClient::getDebug()) cout<< "PvaClientMultiChannel::PvaClientMultiChannel()\n";
|
|
}
|
|
|
|
PvaClientMultiChannel::~PvaClientMultiChannel()
|
|
{
|
|
if(PvaClient::getDebug()) cout<< "PvaClientMultiChannel::~PvaClientMultiChannel()\n";
|
|
}
|
|
|
|
void PvaClientMultiChannel::checkConnected()
|
|
{
|
|
if(numConnected==0) connect();
|
|
}
|
|
|
|
epics::pvData::shared_vector<const string> PvaClientMultiChannel::getChannelNames()
|
|
{
|
|
return channelName;
|
|
}
|
|
|
|
Status PvaClientMultiChannel::connect(double timeout)
|
|
{
|
|
for(size_t i=0; i< numChannel; ++i) {
|
|
pvaClientChannelArray[i] = pvaClient->createChannel(channelName[i],providerName);
|
|
pvaClientChannelArray[i]->issueConnect();
|
|
}
|
|
Status returnStatus = Status::Ok;
|
|
Status status = Status::Ok;
|
|
size_t numBad = 0;
|
|
for(size_t i=0; i< numChannel; ++i) {
|
|
if(numBad==0) {
|
|
status = pvaClientChannelArray[i]->waitConnect(timeout);
|
|
} else {
|
|
status = pvaClientChannelArray[i]->waitConnect(.001);
|
|
}
|
|
if(status.isOK()) {
|
|
++numConnected;
|
|
isConnected[i] = true;
|
|
continue;
|
|
}
|
|
if(returnStatus.isOK()) returnStatus = status;
|
|
++numBad;
|
|
if(numBad>maxNotConnected) break;
|
|
}
|
|
return numBad>maxNotConnected ? returnStatus : Status::Ok;
|
|
}
|
|
|
|
|
|
bool PvaClientMultiChannel::allConnected()
|
|
{
|
|
return (numConnected==numChannel) ? true : false;
|
|
}
|
|
|
|
bool PvaClientMultiChannel::connectionChange()
|
|
{
|
|
for(size_t i=0; i<numChannel; ++i) {
|
|
PvaClientChannelPtr pvaClientChannel = pvaClientChannelArray[i];
|
|
Channel::shared_pointer channel = pvaClientChannel->getChannel();
|
|
Channel::ConnectionState stateNow = channel->getConnectionState();
|
|
bool connectedNow = stateNow==Channel::CONNECTED ? true : false;
|
|
if(connectedNow!=isConnected[i]) return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
epics::pvData::shared_vector<epics::pvData::boolean> PvaClientMultiChannel::getIsConnected()
|
|
{
|
|
for(size_t i=0; i<numChannel; ++i) {
|
|
PvaClientChannelPtr pvaClientChannel = pvaClientChannelArray[i];
|
|
if(!pvaClientChannel) {
|
|
isConnected[i] = false;
|
|
continue;
|
|
}
|
|
Channel::shared_pointer channel = pvaClientChannel->getChannel();
|
|
Channel::ConnectionState stateNow = channel->getConnectionState();
|
|
isConnected[i] = (stateNow==Channel::CONNECTED) ? true : false;
|
|
}
|
|
return isConnected;
|
|
}
|
|
|
|
PvaClientChannelArray PvaClientMultiChannel::getPvaClientChannelArray()
|
|
{
|
|
return pvaClientChannelArray;
|
|
}
|
|
|
|
PvaClientPtr PvaClientMultiChannel::getPvaClient()
|
|
{
|
|
return pvaClient;
|
|
}
|
|
|
|
|
|
|
|
PvaClientMultiGetDoublePtr PvaClientMultiChannel::createGet()
|
|
{
|
|
checkConnected();
|
|
return PvaClientMultiGetDouble::create(shared_from_this(),pvaClientChannelArray);
|
|
}
|
|
|
|
|
|
PvaClientMultiPutDoublePtr PvaClientMultiChannel::createPut()
|
|
{
|
|
checkConnected();
|
|
return PvaClientMultiPutDouble::create(shared_from_this(),pvaClientChannelArray);
|
|
}
|
|
|
|
|
|
PvaClientMultiMonitorDoublePtr PvaClientMultiChannel::createMonitor()
|
|
{
|
|
checkConnected();
|
|
return PvaClientMultiMonitorDouble::create(shared_from_this(), pvaClientChannelArray);
|
|
}
|
|
|
|
PvaClientNTMultiPutPtr PvaClientMultiChannel::createNTPut()
|
|
{
|
|
checkConnected();
|
|
return PvaClientNTMultiPut::create(shared_from_this(), pvaClientChannelArray);
|
|
}
|
|
|
|
|
|
PvaClientNTMultiGetPtr PvaClientMultiChannel::createNTGet(std::string const &request)
|
|
{
|
|
checkConnected();
|
|
PVStructurePtr pvRequest = createRequest->createRequest(request);
|
|
if(!pvRequest) {
|
|
string message = " PvaClientMultiChannel::createNTGet invalid pvRequest: "
|
|
+ createRequest->getMessage();
|
|
throw std::runtime_error(message);
|
|
}
|
|
return PvaClientNTMultiGet::create(shared_from_this(), pvaClientChannelArray,pvRequest);
|
|
}
|
|
|
|
PvaClientNTMultiMonitorPtr PvaClientMultiChannel::createNTMonitor(std::string const &request)
|
|
{
|
|
checkConnected();
|
|
PVStructurePtr pvRequest = createRequest->createRequest(request);
|
|
if(!pvRequest) {
|
|
string message = " PvaClientMultiChannel::createNTMonitor invalid pvRequest: "
|
|
+ createRequest->getMessage();
|
|
throw std::runtime_error(message);
|
|
}
|
|
return PvaClientNTMultiMonitor::create(shared_from_this(), pvaClientChannelArray,pvRequest);
|
|
}
|
|
|
|
|
|
}}
|