added stateChangeRequester; improve semantics for unlisten and channelStateChange

This commit is contained in:
mrkraimer
2016-06-24 15:03:19 -04:00
parent 5398d67e2a
commit fac07c7f3a
3 changed files with 60 additions and 3 deletions

View File

@@ -53,6 +53,9 @@ class PvaClientPutData;
typedef std::tr1::shared_ptr<PvaClientPutData> PvaClientPutDataPtr;
class PvaClientMonitorData;
typedef std::tr1::shared_ptr<PvaClientMonitorData> PvaClientMonitorDataPtr;
class PvaClientChannelStateChangeRequester;
typedef std::tr1::shared_ptr<PvaClientChannelStateChangeRequester> PvaClientChannelStateChangeRequesterPtr;
typedef std::tr1::weak_ptr<PvaClientChannelStateChangeRequester> PvaClientChannelStateChangeRequesterWPtr;
class PvaClientChannel;
typedef std::tr1::shared_ptr<PvaClientChannel> PvaClientChannelPtr;
class PvaClientField;
@@ -194,13 +197,35 @@ typedef std::tr1::shared_ptr<PvaClientPutCache> PvaClientPutCachePtr;
class ChannelRequesterImpl;
typedef std::tr1::shared_ptr<ChannelRequesterImpl> ChannelRequesterImplPtr;
/**
* @brief An easy to be notified of a change in connection status.
*
* @author mrk
*/
class epicsShareClass PvaClientChannelStateChangeRequester
{
public:
POINTER_DEFINITIONS(PvaClientChannelStateChangeRequester);
/**
* Destructor
*/
virtual ~PvaClientChannelStateChangeRequester(){}
/**
* A channel connection state change has occurred.
* @param channel The channel.
* @param isConnected The new connection status.
*/
virtual void channelStateChange(PvaClientChannelPtr const & channel, bool isConnected) = 0;
};
/**
* @brief An easy to use alternative to directly calling the Channel methods of pvAccess.
*
* @author mrk
*/
class epicsShareClass PvaClientChannel
class epicsShareClass PvaClientChannel :
public std::tr1::enable_shared_from_this<PvaClientChannel>
{
public:
POINTER_DEFINITIONS(PvaClientChannel);
@@ -208,6 +233,7 @@ public:
* Destructor
*/
~PvaClientChannel();
void setStateChangeRequester(PvaClientChannelStateChangeRequesterPtr const &stateChangeRequester);
/** Get the name of the channel to which PvaClientChannel is connected.
* @return The channel name.
*/
@@ -421,9 +447,11 @@ private:
epics::pvData::Mutex mutex;
epics::pvData::Event waitForConnect;
epics::pvAccess::Channel::shared_pointer channel;
PvaClientChannelStateChangeRequesterWPtr stateChangeRequester;
ChannelRequesterImplPtr channelRequester;
friend class PvaClient;
friend class ChannelRequesterImpl;
};
/**
@@ -1312,6 +1340,15 @@ public:
* @param monitor The PvaClientMonitor that received the event.
*/
virtual void event(PvaClientMonitorPtr const & monitor) = 0;
/**
* The data source is no longer available.
*/
virtual void unlisten()
{
std::cerr << "PvaClientMonitorRequester::unlisten called"
<< " but no PvaClientMonitorRequester::unlisten\n";
}
};

View File

@@ -213,7 +213,6 @@ PvaClientChannel::~PvaClientChannel()
if(PvaClient::getDebug()) showCache();
}
void PvaClientChannel::channelCreated(const Status& status, Channel::shared_pointer const & channel)
{
if(PvaClient::getDebug()) {
@@ -252,6 +251,12 @@ void PvaClientChannel::channelStateChange(
<< " " << Channel::ConnectionStateNames[connectionState]
<< endl;
}
PvaClientChannelStateChangeRequesterPtr req(stateChangeRequester.lock());
if(req) {
bool value = (connectionState==Channel::CONNECTED ? true : false);
req->channelStateChange(shared_from_this(),value);
}
Lock xx(mutex);
bool waitingForConnect = false;
if(connectState==connectActive) waitingForConnect = true;
@@ -293,6 +298,12 @@ Channel::shared_pointer PvaClientChannel::getChannel()
return channel;
}
void PvaClientChannel::setStateChangeRequester(
PvaClientChannelStateChangeRequesterPtr const & stateChangeRequester)
{
this->stateChangeRequester = stateChangeRequester;
}
void PvaClientChannel::connect(double timeout)
{
if(PvaClient::getDebug()) {

View File

@@ -219,9 +219,18 @@ void PvaClientMonitor::monitorEvent(MonitorPtr const & monitor)
void PvaClientMonitor::unlisten(MonitorPtr const & monitor)
{
if(PvaClient::getDebug()) cout << "PvaClientMonitor::unlisten\n";
throw std::runtime_error("pvaClientMonitor::unlisten called but do not know what to do");
PvaClientMonitorRequesterPtr req = pvaClientMonitorRequester.lock();
if(req) {
req->unlisten();
return;
}
string channelName("disconnected");
Channel::shared_pointer chan(channel.lock());
if(chan) channelName = chan->getChannelName();
cerr << channelName + "pvaClientMonitor::unlisten called but no PvaClientMonitorRequester\n";
}
void PvaClientMonitor::connect()
{
if(PvaClient::getDebug()) cout << "PvaClientMonitor::connect\n";