From 0912756a2e743230dedd4130d0c058153baef7d2 Mon Sep 17 00:00:00 2001 From: mrkraimer Date: Thu, 15 Jun 2017 14:40:13 -0400 Subject: [PATCH] back out ChannelProvider change; add PvaMonitor --- src/Makefile | 1 + src/pv/pvaClient.h | 77 +++++++++++++++++++++++++++ src/pvaClient.cpp | 2 +- src/pvaClientChannel.cpp | 2 +- src/pvaMonitor.cpp | 111 +++++++++++++++++++++++++++++++++++++++ 5 files changed, 191 insertions(+), 2 deletions(-) create mode 100644 src/pvaMonitor.cpp diff --git a/src/Makefile b/src/Makefile index 7e945c7..daae48f 100644 --- a/src/Makefile +++ b/src/Makefile @@ -20,6 +20,7 @@ LIBSRCS += pvaClientProcess.cpp LIBSRCS += pvaClientGet.cpp LIBSRCS += pvaClientPut.cpp LIBSRCS += pvaClientMonitor.cpp +LIBSRCS += pvaMonitor.cpp LIBSRCS += pvaClientPutGet.cpp LIBSRCS += pvaClientMultiChannel.cpp LIBSRCS += pvaClientMultiGetDouble.cpp diff --git a/src/pv/pvaClient.h b/src/pv/pvaClient.h index 7ba6586..1150e55 100644 --- a/src/pv/pvaClient.h +++ b/src/pv/pvaClient.h @@ -28,6 +28,7 @@ #include #include #include +#include #include #ifdef pvaClientEpicsExportSharedSymbols @@ -64,6 +65,8 @@ class PvaClientPutGet; typedef std::tr1::shared_ptr PvaClientPutGetPtr; class PvaClientMonitor; typedef std::tr1::shared_ptr PvaClientMonitorPtr; +class PvaMonitor; +typedef std::tr1::shared_ptr PvaMonitorPtr; class PvaClientMonitorRequester; typedef std::tr1::shared_ptr PvaClientMonitorRequesterPtr; typedef std::tr1::weak_ptr PvaClientMonitorRequesterWPtr; @@ -1510,6 +1513,80 @@ private: friend class MonitorRequesterImpl; }; +/** + * @brief An easy to use alternative to Monitor. + * + */ +class epicsShareClass PvaMonitor : + public PvaClientChannelStateChangeRequester, + public PvaClientMonitorRequester, + public epics::pvData::Command, + public std::tr1::enable_shared_from_this +{ +public: + POINTER_DEFINITIONS(PvaMonitor); + /** @brief Create a PvaMonitor. + * @param &pvaClient Interface to PvaClient. + * @param channelName The channel name. + * @param providerName The provider name. + * @param request The request. For example "value,timeStamp" + * @param stateChangeRequester The state change requester. Can be null. + * @param monitorRequester The monitor requester. Can be null; + * @return The new instance. + */ + static PvaMonitorPtr create( + PvaClientPtr const &pvaClient, + std::string const & channelName, + std::string const & providerName, + std::string const & request, + PvaClientChannelStateChangeRequesterPtr const & stateChangeRequester, + PvaClientMonitorRequesterPtr const & monitorRequester + ); + /** @brief Destructor + */ + ~PvaMonitor(); + + /** + * @brief Get the PvaClientChannel + * + * @return The PvaClientChannel + */ + PvaClientChannelPtr getPvaClientChannel(); + /** + * @brief Get the PvaClientMonitor + * + * @return The PvaClientMonitor + */ + PvaClientMonitorPtr getPvaClientMonitor(); + +private: + static epics::pvData::ExecutorPtr executor; + PvaClient::weak_pointer pvaClient; + std::string channelName; + std::string providerName; + std::string request; + PvaClientChannelPtr pvaClientChannel; + PvaClientMonitorPtr pvaClientMonitor; + PvaClientChannelStateChangeRequesterPtr stateChangeRequester; + PvaClientMonitorRequesterPtr monitorRequester; + + PvaMonitor( + PvaClientPtr const &pvaClient, + std::string const & channelName, + std::string const & providerName, + std::string const & request, + PvaClientChannelStateChangeRequesterPtr const & stateChangeRequester, + PvaClientMonitorRequesterPtr const & monitorRequester + ); + + void init(); +public: + void channelStateChange(PvaClientChannelPtr const & channel, bool isConnected); + void event(PvaClientMonitorPtr const & monitor); + void command(); +}; + + /** * @brief Optional client callback. * diff --git a/src/pvaClient.cpp b/src/pvaClient.cpp index 141c58c..6078b49 100644 --- a/src/pvaClient.cpp +++ b/src/pvaClient.cpp @@ -105,7 +105,7 @@ PvaClient::PvaClient(std::string const & providerNames) : pvaClientChannelCache(new PvaClientChannelCache()), pvaStarted(false), caStarted(false), - channelRegistry(ChannelProviderRegistry::getChannelProviderRegistry()) + channelRegistry(getChannelProviderRegistry()) { stringstream ss(providerNames); string providerName; diff --git a/src/pvaClientChannel.cpp b/src/pvaClientChannel.cpp index 48b2bac..0cc956b 100644 --- a/src/pvaClientChannel.cpp +++ b/src/pvaClientChannel.cpp @@ -331,7 +331,7 @@ void PvaClientChannel::issueConnect() } connectState = connectActive; } - ChannelProviderRegistry::shared_pointer reg = ChannelProviderRegistry::getChannelProviderRegistry(); + ChannelProviderRegistry::shared_pointer reg(getChannelProviderRegistry());; ChannelProvider::shared_pointer provider = reg->getProvider(providerName); if(!provider) { throw std::runtime_error(channelName + " provider " + providerName + " not registered"); diff --git a/src/pvaMonitor.cpp b/src/pvaMonitor.cpp new file mode 100644 index 0000000..4c28bfb --- /dev/null +++ b/src/pvaMonitor.cpp @@ -0,0 +1,111 @@ +/* pvaClientMonitor.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 2017.06 + */ + + +#define epicsExportSharedSymbols + +#include + +using std::tr1::static_pointer_cast; +using std::tr1::dynamic_pointer_cast; +using namespace epics::pvData; +using namespace epics::pvAccess; +using namespace std; + +namespace epics { namespace pvaClient { + +ExecutorPtr PvaMonitor::executor(new Executor("pvaMonitor",middlePriority)); + + +PvaMonitorPtr PvaMonitor::create( + PvaClientPtr const &pvaClient, + std::string const & channelName, + std::string const & providerName, + std::string const & request, + PvaClientChannelStateChangeRequesterPtr const & stateChangeRequester, + PvaClientMonitorRequesterPtr const & monitorRequester) +{ + PvaMonitorPtr epv(new PvaMonitor(pvaClient,channelName,providerName,request, + stateChangeRequester,monitorRequester)); + epv->init(); + return epv; +} + +PvaMonitor::PvaMonitor( + PvaClientPtr const &pvaClient, + std::string const & channelName, + std::string const & providerName, + std::string const & request, + PvaClientChannelStateChangeRequesterPtr const & stateChangeRequester, + PvaClientMonitorRequesterPtr const & monitorRequester) +: pvaClient(pvaClient), + channelName(channelName), + providerName(providerName), + request(request), + stateChangeRequester(stateChangeRequester), + monitorRequester(monitorRequester) +{ + if(PvaClient::getDebug()) { + cout<< "PvaMonitor::PvaMonitor()" + << " channelName " << channelName + << endl; + } +} + +void PvaMonitor::init() +{ + PvaClientPtr client(pvaClient.lock()); + if(!client) throw std::runtime_error("pvaClient was destroyed"); + pvaClientChannel = client->createChannel(channelName,providerName); + pvaClientChannel->setStateChangeRequester(shared_from_this()); + pvaClientChannel->issueConnect(); +} + +PvaMonitor::~PvaMonitor() +{ + if(PvaClient::getDebug()) cout<< "PvaMonitor::~PvaMonitor\n"; + pvaClientChannel.reset(); + pvaClientMonitor.reset(); +} + +PvaClientChannelPtr PvaMonitor::getPvaClientChannel() +{ + return pvaClientChannel; +} + +PvaClientMonitorPtr PvaMonitor::getPvaClientMonitor() +{ + return pvaClientMonitor; +} + +void PvaMonitor::channelStateChange(PvaClientChannelPtr const & channel, bool isConnected) +{ + if(PvaClient::getDebug()) cout<< "PvaMonitor::channelStateChange isConnected " << (isConnected ? "true" : "false") << endl; + if(isConnected&&!pvaClientMonitor) + { + if(PvaClient::getDebug()) cout<< "PvaMonitor::channelStateChange calling executor.execute\n"; + executor->execute(shared_from_this()); + } + if(stateChangeRequester) stateChangeRequester->channelStateChange(channel,isConnected); + } + +void PvaMonitor::event(PvaClientMonitorPtr const & monitor) +{ + if(monitorRequester) monitorRequester->event(monitor); +} + +void PvaMonitor::command() +{ + if(PvaClient::getDebug()) cout<< "PvaMonitor::run\n"; + pvaClientMonitor = pvaClientChannel->monitor(request,shared_from_this()); +} + +}}