32 Commits

Author SHA1 Message Date
Andrew Johnson 428adb270e Update version numbers to 4.5.0 for EPICS 7.0.2.2 release 2019-04-15 11:27:27 -05:00
Marty Kraimer 3111e90de8 Merge pull request #55 from mrkraimer/master
address issue #53 plus more for getDouble, putDouble, getString, putDouble, etc
2019-04-11 14:50:03 -04:00
mrkraimer 365a0b846f update RELEASE_NOTES 2019-04-11 14:13:53 -04:00
mrkraimer 440c8fa496 update RELEASE_NOTES 2019-04-11 14:11:03 -04:00
mrkraimer 150ac45de3 bug in pvaClientData; fix doxygen warning; update doc 2019-04-09 11:15:00 -04:00
mrkraimer fb6f4355f3 getDoubleArray and putDoubleArray now work for all numeric scalar arrays 2019-04-09 06:19:14 -04:00
mrkraimer 0bb17d5b09 make them work if not top level value field 2019-04-08 14:23:58 -04:00
mrkraimer 00103f8207 getStringArray and putStringArray support all numeric array types 2019-04-08 14:11:27 -04:00
mrkraimer 522a050945 add double and string methods to pvaClientChannel 2019-04-07 14:34:56 -04:00
mrkraimer 99a7e3b0b5 more changes 2019-04-06 11:30:10 -04:00
mrkraimer 763c41caa3 setElementData=>setData 2019-04-05 14:37:05 -04:00
mrkraimer 9ffeffd23f mistake 2019-04-04 16:27:53 -04:00
mrkraimer 3f6d93b22f lots of minor changes 2019-04-04 16:02:47 -04:00
mrkraimer d650865a6f address issue #53; reorganize Client*Data 2019-04-03 10:32:45 -04:00
Andrew Johnson b1c101578b Update version numbers and formatting in documentation 2018-12-17 16:17:52 -06:00
Andrew Johnson 8ab4dd1fdb Correct SHRLIB_VERSION 2018-12-17 16:16:59 -06:00
Andrew Johnson 5242540725 Update and unify README.md 2018-12-17 16:16:06 -06:00
Michael Davidsaver a8f296ceb3 update travis-ci 2018-10-29 18:02:20 -07:00
Marty Kraimer 6633d4f21e Merge pull request #52 from mrkraimer/master
with multiple threads callback can occur before create completes
2018-10-06 05:59:14 -04:00
mrkraimer 8745dd03b3 with multithreads callback can occur before create completes 2018-10-05 15:59:59 -04:00
Marty Kraimer cfc3c9b998 Merge pull request #51 from mrkraimer/master
several changes
2018-09-28 07:00:34 -04:00
mrkraimer d57893b566 remove #include <pv/pvCopy.h> 2018-09-27 15:34:02 -04:00
mrkraimer b7ea0fe59a fix bug that causes failure in monotor::stop for privider ca 2018-07-27 05:43:47 -04:00
Marty Kraimer 4e4554af4e Merge pull request #50 from mrkraimer/master
re-implement methods used by pvaPy
2018-01-30 09:11:28 -05:00
mrkraimer d6d5bcf771 merge with epics-base 2018-01-12 15:20:47 -05:00
mrkraimer 6bcc036c71 reimplement methods called by pvaPy
The methods are:
static PvaClientPtr create() EPICS_DEPRECATED;
and
static PvaClientMonitorPtr create(
    PvaClientPtr const &pvaClient,
    std::string const & channelName,
    std::string const & providerName,
    std::string const & request,
    PvaClientChannelStateChangeRequesterPtr const & stateChangeRequester
            = PvaClientChannelStateChangeRequesterPtr(),
    PvaClientMonitorRequesterPtr const & monitorRequester
            = PvaClientMonitorRequesterPtr()
) EPICS_DEPRECATED;
2018-01-12 13:51:13 -05:00
Marty Kraimer a405dd7bdb Merge pull request #49 from epics-base/revert-48-master
Revert "Minor changes"
2018-01-09 15:58:58 -05:00
Marty Kraimer 22e260351c Revert "Minor changes" 2018-01-09 15:14:30 -05:00
Marty Kraimer 5a5b8f809d Merge pull request #48 from mrkraimer/master
Minor changes
2018-01-09 11:16:52 -05:00
mrkraimer 9d5f06c11d pull latest from epics-base 2018-01-08 09:20:13 -05:00
mrkraimer 28a23dc5a8 remove a create method from monitor; remove unused channelStateChange methods 2018-01-05 14:38:42 -05:00
Ralph Lange dcda03c9fc jenkins-ci: fix CloudBees doc job 2017-12-19 09:20:11 +01:00
29 changed files with 939 additions and 1202 deletions
+2 -13
View File
@@ -1,21 +1,10 @@
#!/bin/sh #!/bin/sh
set -e -x set -e -x
# set RTEMS to eg. "4.9" or "4.10"
# requires qemu, bison, flex, texinfo, install-info
if [ -n "$RTEMS" ]
then
# find local qemu-system-i386
export PATH="$HOME/.cache/qemu/usr/bin:$PATH"
echo -n "Using QEMU: "
type qemu-system-i386 || echo "Missing qemu"
EXTRA=RTEMS_QEMU_FIXUPS=YES
fi
make -j2 $EXTRA make -j2 $EXTRA
if [ "$TEST" != "NO" ] if [ "$TEST" != "NO" ]
then then
make tapfiles make -j2 tapfiles
make -s test-results make -j2 -s test-results
fi fi
+11 -80
View File
@@ -3,35 +3,6 @@ set -e -x
CURDIR="$PWD" CURDIR="$PWD"
QDIR="$HOME/.cache/qemu"
if [ -n "$RTEMS" -a "$TEST" = "YES" ]
then
git clone --quiet --branch vme --depth 10 https://github.com/mdavidsaver/qemu.git "$HOME/.build/qemu"
cd "$HOME/.build/qemu"
HEAD=`git log -n1 --pretty=format:%H`
echo "HEAD revision $HEAD"
[ -e "$HOME/.cache/qemu/built" ] && BUILT=`cat "$HOME/.cache/qemu/built"`
echo "Cached revision $BUILT"
if [ "$HEAD" != "$BUILT" ]
then
echo "Building QEMU"
git submodule --quiet update --init
install -d "$HOME/.build/qemu/build"
cd "$HOME/.build/qemu/build"
"$HOME/.build/qemu/configure" --prefix="$HOME/.cache/qemu/usr" --target-list=i386-softmmu --disable-werror
make -j2
make install
echo "$HEAD" > "$HOME/.cache/qemu/built"
fi
fi
cat << EOF > $CURDIR/configure/RELEASE.local cat << EOF > $CURDIR/configure/RELEASE.local
EPICS_BASE=$HOME/.source/epics-base EPICS_BASE=$HOME/.source/epics-base
EOF EOF
@@ -39,24 +10,6 @@ EOF
install -d "$HOME/.source" install -d "$HOME/.source"
cd "$HOME/.source" cd "$HOME/.source"
add_base_module() {
MODULE=$1
BRANCH=$2
( cd epics-base/modules && \
git clone --quiet --depth 5 --branch $MODULE/$BRANCH https://github.com/${REPOBASE:-epics-base}/epics-base.git $MODULE && \
cd $MODULE && git log -n1 )
}
add_gh_module() {
MODULE=$1
REPOOWNER=$2
REPONAME=$3
BRANCH=$4
( cd epics-base/modules && \
git clone --quiet --depth 5 --branch $BRANCH https://github.com/$REPOOWNER/$REPONAME.git $MODULE && \
cd $MODULE && git log -n1 )
}
add_gh_flat() { add_gh_flat() {
MODULE=$1 MODULE=$1
REPOOWNER=$2 REPOOWNER=$2
@@ -71,23 +24,12 @@ ${MODULE_UC}=$HOME/.source/$MODULE
EOF EOF
} }
if [ "$BRBASE" ] # not recursive
then git clone --quiet --depth 5 --branch "$BRBASE" https://github.com/${REPOBASE:-epics-base}/epics-base.git epics-base
git clone --quiet --depth 5 --branch "$BRBASE" https://github.com/${REPOBASE:-epics-base}/epics-base.git epics-base (cd epics-base && git log -n1 )
(cd epics-base && git log -n1 ) add_gh_flat pvData ${REPOPVD:-epics-base} pvDataCPP ${BRPVD:-master}
add_gh_flat pvData ${REPOPVD:-epics-base} pvDataCPP ${BRPVD:-master} add_gh_flat pvAccess ${REPOPVA:-epics-base} pvAccessCPP ${BRPVA:-master}
add_gh_flat pvAccess ${REPOPVA:-epics-base} pvAccessCPP ${BRPVA:-master} add_gh_flat normativeTypes ${REPONT:-epics-base} normativeTypesCPP ${BRNT:-master}
add_gh_flat normativeTypes ${REPONT:-epics-base} normativeTypesCPP ${BRNT:-master}
else
git clone --quiet --depth 5 --branch core/"${BRCORE:-master}" https://github.com/${REPOBASE:-epics-base}/epics-base.git epics-base
( cd epics-base && git log -n1 )
add_base_module libcom "${BRLIBCOM:-master}"
add_base_module ca "${BRCA:-master}"
add_base_module database "${BRDATABASE:-master}"
add_gh_module pvData ${REPOPVD:-epics-base} pvDataCPP ${BRPVD:-master}
add_gh_module pvAccess ${REPOPVA:-epics-base} pvAccessCPP ${BRPVA:-master}
add_gh_module normativeTypes ${REPONT:-epics-base} normativeTypesCPP ${BRNT:-master}
fi
if [ -e $CURDIR/configure/RELEASE.local ] if [ -e $CURDIR/configure/RELEASE.local ]
then then
@@ -150,31 +92,20 @@ EOF
if [ -n "$RTEMS" ] if [ -n "$RTEMS" ]
then then
echo "Cross RTEMS${RTEMS} for pc386" echo "Cross RTEMS${RTEMS} for pc386"
install -d /home/travis/.cache curl -L "https://github.com/mdavidsaver/rsb/releases/download/20171203-${RTEMS}/i386-rtems${RTEMS}-trusty-20171203-${RTEMS}.tar.bz2" \
curl -L "https://github.com/mdavidsaver/rsb/releases/download/travis-20160306-2/rtems${RTEMS}-i386-trusty-20190306-2.tar.gz" \ | tar -C / -xmj
| tar -C /home/travis/.cache -xj
sed -i -e '/^RTEMS_VERSION/d' -e '/^RTEMS_BASE/d' epics-base/configure/os/CONFIG_SITE.Common.RTEMS sed -i -e '/^RTEMS_VERSION/d' -e '/^RTEMS_BASE/d' epics-base/configure/os/CONFIG_SITE.Common.RTEMS
cat << EOF >> epics-base/configure/os/CONFIG_SITE.Common.RTEMS cat << EOF >> epics-base/configure/os/CONFIG_SITE.Common.RTEMS
RTEMS_VERSION=$RTEMS RTEMS_VERSION=$RTEMS
RTEMS_BASE=/home/travis/.cache/rtems${RTEMS}-i386 RTEMS_BASE=$HOME/.rtems
EOF EOF
cat << EOF >> epics-base/configure/CONFIG_SITE cat << EOF >> epics-base/configure/CONFIG_SITE
CROSS_COMPILER_TARGET_ARCHS+=RTEMS-pc386 CROSS_COMPILER_TARGET_ARCHS += RTEMS-pc386-qemu
EOF EOF
# find local qemu-system-i386
export PATH="$HOME/.cache/qemu/usr/bin:$PATH"
echo -n "Using QEMU: "
type qemu-system-i386 || echo "Missing qemu"
EXTRA=RTEMS_QEMU_FIXUPS=YES
fi fi
make -j2 -C epics-base $EXTRA make -j2 -C epics-base $EXTRA
if [ "$BRBASE" ]
then
make -j2 -C pvData $EXTRA make -j2 -C pvData $EXTRA
make -j2 -C pvAccess $EXTRA
make -j2 -C normativeTypes $EXTRA make -j2 -C normativeTypes $EXTRA
fi make -j2 -C pvAccess $EXTRA
+13 -11
View File
@@ -11,19 +11,21 @@ addons:
- perl - perl
- clang - clang
- g++-mingw-w64-i686 - g++-mingw-w64-i686
- qemu-system-x86
install: install:
- ./.ci/travis-prepare.sh - ./.ci/travis-prepare.sh
script: script:
- ./.ci/travis-build.sh - ./.ci/travis-build.sh
env: env:
- BRCORE=master BRLIBCOM=master BRPVD=master BRPVA=master BRNT=master TEST=NO - BRBASE=7.0
- CMPLR=clang TEST=NO - BRBASE=7.0 CMPLR=clang
- USR_CXXFLAGS=-std=c++11 TEST=NO - BRBASE=7.0 EXTRA="CMD_CXXFLAGS=-std=c++98"
- CMPLR=clang USR_CXXFLAGS=-std=c++11 TEST=NO - BRBASE=7.0 EXTRA="CMD_CXXFLAGS=-std=c++11"
- WINE=32 TEST=NO STATIC=YES - BRBASE=7.0 CMPLR=clang EXTRA="CMD_CXXFLAGS=-std=c++11"
- WINE=32 TEST=NO STATIC=NO - BRBASE=7.0 WINE=32 TEST=NO STATIC=YES
- RTEMS=4.10 TEST=NO - BRBASE=7.0 WINE=32 TEST=NO STATIC=NO
- RTEMS=4.9 TEST=NO - BRBASE=7.0 RTEMS=4.10 TEST=NO
- BRBASE=3.16 TEST=NO - BRBASE=7.0 RTEMS=4.9 TEST=NO
- BRBASE=3.15 TEST=NO - BRBASE=3.16
- BRBASE=3.14 TEST=NO - BRBASE=3.15
- BRBASE=3.14
+11 -17
View File
@@ -1,23 +1,17 @@
pvaClientCPP # pvaClientCPP
============
pvaClient is a synchronous client interface to pvAccess, The **pvaClient** API provides a synchronous client interface that was designed to be easier to use than the original basic pvAccess client API.
which is callback based.
pvaClient is thus easier to use than pvAccess itself.
See documentation/pvaClientCPP.html for details. The pvaClientCPP module implements the pvaClient API for C++ client applications.
Building ## Links
--------
If a proper RELEASE.local file exists one directory level above pvaClientCPP - General information about EPICS can be found at the
then just type: [EPICS Controls website](https://epics-controls.org).
- API documentation for this module can be found in its
documentation directory, in particular the file
pvaClientCPP.html
make ## Building
It can also be built by:
cp configure/ExampleRELEASE.local configure/RELEASE.local
edit configure/RELEASE.local
make
This module is included as a submodule of a full EPICS 7 release and will be compiled during builds of that software.
+50 -19
View File
@@ -1,18 +1,55 @@
pvaClientCPP Version 4.3.0 # pvaClientCPP Module
==========================
Works with pvDataCPP-7.0 and pvAccessCPP-6.0 versions This document summarizes the changes to the module between releases.
-----------------------------------------------------
Will not work with older versions of these modules. ## Release 4.5.0 (EPICS 7.0.2.2, Apr 2019)
destroy methods removed Changes have been made for getDouble, putDouble, getDoubleArray, putDoubleArray, getString, putString, getStringArray, and putStringArray.
-----------------------
All the destroy methods are removed since implementation is RAII compliant. 1) Previously each only had support for a top level field named value.
Each now allows access to a single sub field that has the correct type.
Thus pvRequest must select a single field. For example
API changes to PvaClientMonitor pva->channel("PVRdumbPowerSupply")->putDouble(1.0,"power.value" );
-------------------------------
2) PvaChannel now has a method for each of the above.
For example instead of
PvaClientChannelPtr channel = pva->channel("PVRdouble");
PvaClientPutPtr clientPut = channel->put();
PvaClientPutDataPtr putData = clientPut->getData();
putData->putDouble(1.0); clientPut->put();
now it can be
pva->channel("PVRdouble")->putDouble(1.0 );
3) getDoubleArray and putDoubleArray work with any numeric scalar array
4) getStringArray and putStringArray work with any scalar array.
## Release 4.4 (EPICS 7.0.2, Dec 2018)
### API changes to PvaClientMonitor
The create method that had arguments for stateChangeRequester and monitorRequester no longer exists.
### API changes to PvaClientGet, ..., PvaClientMonitor
Previously the pvaClientGet, ..., pvaClientMonitor classes all implemented PvaClientChannelStateChangeRequester(). This method was never called and has been removed.
## Release 4.3 (EPICS 7.0.1, Dec 2017)
### Requires pvDataCPP-7.0 and pvAccessCPP-6.0 versions
This release will not work with older versions of these modules.
### Destroy methods removed
All the destroy() methods have been removed, implementation is RAII compliant.
### API changes to PvaClientMonitor
The second argument of method The second argument of method
@@ -22,7 +59,7 @@ The second argument of method
epics::pvData::PVStructurePtr const &pvRequest epics::pvData::PVStructurePtr const &pvRequest
); );
Is now changed to is now changed to
static PvaClientMonitorPtr create( static PvaClientMonitorPtr create(
PvaClientPtr const &pvaClient, PvaClientPtr const &pvaClient,
@@ -42,22 +79,16 @@ A new method is also implemented
); );
pvaClientCPP Version 4.2 ## Release 4.2 (EPICS V4.6, Aug 2016)
========================
* The examples are moved to exampleCPP. * The examples are moved to exampleCPP.
* Support for channelRPC is now available. * Support for channelRPC is now available.
* In PvaClientMultiChannel checkConnected() now throws an exception if connect fails. * In PvaClientMultiChannel checkConnected() now throws an exception if connect fails.
## Release 4.1 (EPICS V4.5, Oct 2015)
pvaClientCPP Version 4.1
========================
pvaClient is a synchronous API for pvAccess. pvaClient is a synchronous API for pvAccess.
This is the first release of pvaClientCPP. This is the first release of pvaClientCPP.
It provides an API that is similar to pvaClientJava. It provides an API that is similar to pvaClientJava.
+7 -7
View File
@@ -26,13 +26,13 @@
<div class="head"> <div class="head">
<h1>EPICS pvaClientCPP</h1> <h1>EPICS pvaClientCPP</h1>
<h2 class="nocount">Release 4.3.0 - 2017-12-14</h2> <h2 class="nocount">Release 4.4 - April 2019</h2>
<h2 class="nocount">Abstract</h2> <h2 class="nocount">Abstract</h2>
<p>pvaClient is a software library that provides, to an EPICS client programmer, a friendly <p>pvaClient is a software library that provides, to an EPICS client programmer, a friendly
client side programming interface to the data of an EPICS based control system. It is intended client side programming interface to the data of an EPICS based control system. It is intended
for such uses as rapid development of ad hoc programs by controls engineers, or to provide for such uses as rapid development of ad hoc programs by controls engineers, or to provide
scientists a way to directly develop analytical applications.</p> scientists a way to directly develop analytical applications.</p>
<p>Specifically, pvaClient provides a synchronous interface for pvAccess, which is the <p>Specifically, pvaClient provides a synchronous interface for pvAccess, which is the
@@ -41,7 +41,7 @@ pvAccess provides a callback based interface, which can be hard to use.
pvaClient provides an interface that does not require callbacks even for monitors. pvaClient provides an interface that does not require callbacks even for monitors.
</p> </p>
<p> <p>
pvaClientChannel provides many "convenience" methods to directly get and put pvaClientChannel provides many "convenience" methods to directly get and put
scalar and scalarArray data types. scalar and scalarArray data types.
Additional methods provide access to the full features of pvAccess. Additional methods provide access to the full features of pvAccess.
</p> </p>
@@ -62,11 +62,11 @@ The data for the channels is presented via normative type NTMultiChannel.
</div> <!-- head --> </div> <!-- head -->
<div id="contents" class="contents"> <div id="contents" class="contents">
<hr /> <hr />
<h2>Overview</h2> <h2>Overview</h2>
<p> <p>
pvaClientCPP is one of the components of pvaClientCPP is one of the components of
<a href="http://epics-pvdata.sourceforge.net"> <a href="http://epics-pvdata.sourceforge.net">
EPICS Version 4 EPICS Version 4
</a> </a>
@@ -79,7 +79,7 @@ It is intended for developers that want to use pvaClientCPP.
<h2>Developer Guide</h2> <h2>Developer Guide</h2>
<p>A guide for developers is available at <p>A guide for developers is available at
<a <a
href="http://epics-pvdata.sourceforge.net/informative/developerGuide/developerGuide.html"> href="https://mrkraimer.github.io/website/developerGuide/developerGuide.html">
developerGuide developerGuide
</a> </a>
</p> </p>
+1 -8
View File
@@ -21,14 +21,7 @@ installE4 () {
local module=$1 local module=$1
local branch=$2 local branch=$2
# If microbench version does not exist, try without wget -nv https://openepics.ci.cloudbees.com/job/e4-cpp-${module}-${branch}-build/BASE=${BASE}/lastSuccessfulBuild/artifact/${module}.CB-dist.tar.gz
if [ "${MB}" = "WITH_MICROBENCH" ]; then
if ! wget -nv https://openepics.ci.cloudbees.com/job/e4-cpp-${module}-${branch}-build/BASE=${BASE},MB=WITH_MICROBENCH/lastSuccessfulBuild/artifact/${module}.CB-dist.tar.gz; then
wget -nv https://openepics.ci.cloudbees.com/job/e4-cpp-${module}-${branch}-build/BASE=${BASE},MB=NO_MICROBENCH/lastSuccessfulBuild/artifact/${module}.CB-dist.tar.gz
fi
else
wget -nv https://openepics.ci.cloudbees.com/job/e4-cpp-${module}-${branch}-build/BASE=${BASE},MB=NO_MICROBENCH/lastSuccessfulBuild/artifact/${module}.CB-dist.tar.gz
fi
tar -xzf ${module}.CB-dist.tar.gz tar -xzf ${module}.CB-dist.tar.gz
} }
+2 -1
View File
@@ -6,12 +6,13 @@ include $(TOP)/configure/CONFIG
LIBRARY += pvaClient LIBRARY += pvaClient
# shared library ABI version. # shared library ABI version.
SHRLIB_VERSION ?= 4.3.0 SHRLIB_VERSION ?= 4.5.0
INC += pv/pvaClient.h INC += pv/pvaClient.h
INC += pv/pvaClientMultiChannel.h INC += pv/pvaClientMultiChannel.h
LIBSRCS += pvaClient.cpp LIBSRCS += pvaClient.cpp
LIBSRCS += pvaClientData.cpp
LIBSRCS += pvaClientPutData.cpp LIBSRCS += pvaClientPutData.cpp
LIBSRCS += pvaClientGetData.cpp LIBSRCS += pvaClientGetData.cpp
LIBSRCS += pvaClientMonitorData.cpp LIBSRCS += pvaClientMonitorData.cpp
+141 -254
View File
@@ -23,7 +23,6 @@
#include <pv/event.h> #include <pv/event.h>
#include <pv/lock.h> #include <pv/lock.h>
#include <pv/pvData.h> #include <pv/pvData.h>
#include <pv/pvCopy.h>
#include <pv/pvTimeStamp.h> #include <pv/pvTimeStamp.h>
#include <pv/timeStamp.h> #include <pv/timeStamp.h>
#include <pv/pvAlarm.h> #include <pv/pvAlarm.h>
@@ -45,6 +44,8 @@ namespace epics { namespace pvaClient {
class PvaClient; class PvaClient;
typedef std::tr1::shared_ptr<PvaClient> PvaClientPtr; typedef std::tr1::shared_ptr<PvaClient> PvaClientPtr;
class PvaClientData;
typedef std::tr1::shared_ptr<PvaClientData> PvaClientDataPtr;
class PvaClientGetData; class PvaClientGetData;
typedef std::tr1::shared_ptr<PvaClientGetData> PvaClientGetDataPtr; typedef std::tr1::shared_ptr<PvaClientGetData> PvaClientGetDataPtr;
class PvaClientPutData; class PvaClientPutData;
@@ -120,6 +121,12 @@ public:
/** @brief Get the requester name. /** @brief Get the requester name.
* @return The name. * @return The name.
*/ */
/** @brief Create an instance of PvaClient with providerName "pva ca".
* @return shared pointer to the single instance
* @deprecated This method will go away in future versions. Use get instead.
*/
static PvaClientPtr create() EPICS_DEPRECATED;
std::string getRequesterName(); std::string getRequesterName();
/** @brief A new message. /** @brief A new message.
* *
@@ -306,11 +313,42 @@ public:
PvaClientGetPtr createGet(std::string const & request = "field(value,alarm,timeStamp)"); PvaClientGetPtr createGet(std::string const & request = "field(value,alarm,timeStamp)");
/** @brief Creates an PvaClientGet. /** @brief Creates an PvaClientGet.
* *
* @param pvRequest The syntax of pvRequest is defined by the copy facility of pvData. * @param pvRequest The syntax of request is defined by the copy facility of pvData.
* @return The interface.
* @return The interface. * @return The interface.
* @throw runtime_error if failure. * @throw runtime_error if failure.
*/ */
PvaClientGetPtr createGet(epics::pvData::PVStructurePtr const & pvRequest); PvaClientGetPtr createGet(epics::pvData::PVStructurePtr const & pvRequest);
/** @brief Get the value as a double.
*
* @param request The syntax of request is defined by the copy facility of pvData.
* @return The value.
* @throw runtime_error if failure.
*/
double getDouble(std::string const & request = "field(value)");
/** Get the value as a string.
*
* @param request The syntax of request is defined by the copy facility of pvData.
* @return The value.
* @throw runtime_error if failure.
*/
std::string getString(std::string const & request = "field(value)");
/** @brief Get the value as a double array.
*
* @param request The syntax of request is defined by the copy facility of pvData.
* @return The value.
* @throw runtime_error if failure.
*/
epics::pvData::shared_vector<const double> getDoubleArray(
std::string const & request = "field(value)");
/** @brief Get the value as a string array.
*
* @param request The syntax of request is defined by the copy facility of pvData.
* @return The value.
* @throw runtime_error if failure.
*/
epics::pvData::shared_vector<const std::string> getStringArray(
std::string const & request = "field(value)");
/** @brief create a PvaClientPut. /** @brief create a PvaClientPut.
* *
* Get a cached PvaClientPut or create and connect to a new PvaClientPut. * Get a cached PvaClientPut or create and connect to a new PvaClientPut.
@@ -334,6 +372,44 @@ public:
* @return The interface. * @return The interface.
*/ */
PvaClientPutPtr createPut(epics::pvData::PVStructurePtr const & pvRequest); PvaClientPutPtr createPut(epics::pvData::PVStructurePtr const & pvRequest);
/** @brief Put the value as a double.
*
* @param value The new value.
* @param request The syntax of request is defined by the copy facility of pvData.
* @throw runtime_error if failure.
*/
void putDouble(double value,std::string const & request = "field(value)");
/** @brief Put the value as a string.
*
* @param value The new value.
* @param request The syntax of request is defined by the copy facility of pvData.
* @throw runtime_error if failure.
*/
void putString(std::string const & value,std::string const & request = "field(value)");
/** @brief Copy the array to the value field.
*
* @param value The new value.
* @param request The syntax of request is defined by the copy facility of pvData.
* @throw runtime_error if failure.
*/
void putDoubleArray(
epics::pvData::shared_vector<const double> const & value,
std::string const & request = "field(value)");
/** @brief Copy array to the value field.
*
* @param value The new value.
* @param request The syntax of request is defined by the copy facility of pvData.
* @throw runtime_error if failure.
*/
void putStringArray(
epics::pvData::shared_vector<const std::string> const & value,
std::string const & request = "field(value)");
/** @brief Copy array to the value field.
* @param value The data used to update the channel value.
* @param request The request as a string to pass to createRequest.
* @throw runtime_error if failure.
*/
void putStringArray(std::vector<std::string> const & value,std::string const & request = "field(value)");
/** @brief create a PvaClientPutGet. /** @brief create a PvaClientPutGet.
* *
* First call createRequest as implemented by pvDataJava and then calls the next method. * First call createRequest as implemented by pvDataJava and then calls the next method.
@@ -485,18 +561,18 @@ public:
}; };
/** /**
* @brief A class that holds data returned by PvaClientGet or PvaClientPutGet * @brief A base class for PvaClientGetData, PvaClientPutData, and PvaClientMonitorData.
* *
* <a href = "../htmldoxygen/pvaClientGetData.html">Overview of PvaClientGetData</a> * <a href = "../htmldoxygen/pvaClientData.html">Overview of PvaClientData</a>
*/ */
class epicsShareClass PvaClientGetData class epicsShareClass PvaClientData
{ {
public: public:
POINTER_DEFINITIONS(PvaClientGetData); POINTER_DEFINITIONS(PvaClientData);
/** /**
* @brief Destructor * @brief Destructor
*/ */
~PvaClientGetData() {} ~PvaClientData() {}
/** @brief Set a prefix for throw messages. /** @brief Set a prefix for throw messages.
* *
* This is called by other pvaClient classes. * This is called by other pvaClient classes.
@@ -603,6 +679,44 @@ public:
* @return The timeStamp. * @return The timeStamp.
*/ */
epics::pvData::TimeStamp getTimeStamp(); epics::pvData::TimeStamp getTimeStamp();
/** @brief Factory method for creating an instance of PvaClientData.
*
* NOTE: Not normally called by clients
* @param structure Introspection interface
* @throw runtime_error if failure.
*/
static PvaClientDataPtr create(epics::pvData::StructureConstPtr const & structure);
protected:
PvaClientData(epics::pvData::StructureConstPtr const & structure);
void checkValue();
std::string messagePrefix;
private:
epics::pvData::StructureConstPtr structure;
epics::pvData::PVStructurePtr pvStructure;
epics::pvData::BitSetPtr bitSet;
epics::pvData::PVFieldPtr pvValue;
epics::pvData::PVAlarm pvAlarm;
epics::pvData::PVTimeStamp pvTimeStamp;
friend class PvaClientGet;
friend class PvaClientPutGet;
};
/**
* @brief A class that holds data returned by PvaClientGet or PvaClientPutGet
*
* <a href = "../htmldoxygen/pvaClientGetData.html">Overview of PvaClientGetData</a>
*/
class epicsShareClass PvaClientGetData : public PvaClientData
{
public:
POINTER_DEFINITIONS(PvaClientGetData);
/**
* @brief Destructor
*/
~PvaClientGetData() {}
/** @brief Factory method for creating an instance of PvaClientGetData. /** @brief Factory method for creating an instance of PvaClientGetData.
* *
* NOTE: Not normally called by clients * NOTE: Not normally called by clients
@@ -612,15 +726,6 @@ public:
static PvaClientGetDataPtr create(epics::pvData::StructureConstPtr const & structure); static PvaClientGetDataPtr create(epics::pvData::StructureConstPtr const & structure);
private: private:
PvaClientGetData(epics::pvData::StructureConstPtr const & structure); PvaClientGetData(epics::pvData::StructureConstPtr const & structure);
void checkValue();
epics::pvData::StructureConstPtr structure;
epics::pvData::PVStructurePtr pvStructure;
epics::pvData::BitSetPtr bitSet;
std::string messagePrefix;
epics::pvData::PVFieldPtr pvValue;
epics::pvData::PVAlarm pvAlarm;
epics::pvData::PVTimeStamp pvTimeStamp;
friend class PvaClientGet; friend class PvaClientGet;
friend class PvaClientPutGet; friend class PvaClientPutGet;
}; };
@@ -631,7 +736,7 @@ class PvaClientPostHandlerPvt; // private to PvaClientPutData
* *
* <a href = "../htmldoxygen/pvaClientPutData.html">Overview of PvaClientPutData</a> * <a href = "../htmldoxygen/pvaClientPutData.html">Overview of PvaClientPutData</a>
*/ */
class epicsShareClass PvaClientPutData class epicsShareClass PvaClientPutData : public PvaClientData
{ {
public: public:
POINTER_DEFINITIONS(PvaClientPutData); POINTER_DEFINITIONS(PvaClientPutData);
@@ -639,93 +744,6 @@ public:
* @brief Destructor * @brief Destructor
*/ */
~PvaClientPutData() {} ~PvaClientPutData() {}
/** @brief Set a prefix for throw messages.
*
* @param value The prefix.
*/
void setMessagePrefix(std::string const & value);
/** @brief Get the structure.
*
* @return The Structure
* @throw runtime_error if failure.
*/
epics::pvData::StructureConstPtr getStructure();
/** @brief Get the pvStructure.
*
* @return the pvStructure.
* @throw runtime_error if failure.
*/
epics::pvData::PVStructurePtr getPVStructure();
/** @brief Get the changed BitSet for the pvStructure
*
* This shows which fields have changed values.
* @return The bitSet
* @throw runtime_error if failure.
*/
epics::pvData::BitSetPtr getChangedBitSet();
/** @brief Show the fields that have changed values.
*
* @param out The stream that shows the changed fields.
* @return The stream that was passed as out.
*/
std::ostream & showChanged(std::ostream & out);
/**
* @brief Is there a top level field named value.
*
* @return The answer.
*/
bool hasValue();
/** @brief Is the value field a scalar?
*
* @return The answer.
*/
bool isValueScalar();
/** @brief Is the value field a scalar array?
* @return The answer.
*/
bool isValueScalarArray();
/** Get the interface to the value field.
*
* @return The interface. an excetion is thrown if a value field does not exist.
*/
epics::pvData::PVFieldPtr getValue();
/** @brief Get the interface to a scalar value field.
*
* @return The interface for a scalar value field.
* @throw runtime_error if failure.
*/
epics::pvData::PVScalarPtr getScalarValue();
/** @brief Get the interface to an array value field.
* @return The interface.
* An exception is thown if no array value field.
*/
std::tr1::shared_ptr<epics::pvData::PVArray> getArrayValue();
/** @brief Get the interface to a scalar array value field.
* @return Return the interface.
* @throw runtime_error if failure.
*/
std::tr1::shared_ptr<epics::pvData::PVScalarArray> getScalarArrayValue();
/** @brief Get the value as a double.
*
* If value is not a numeric scalar an exception is thrown.
* @return The value.
*/
double getDouble();
/** @brief Get the value as a string.
* @return The value.
* @throw runtime_error if failure.
*/
std::string getString();
/** @brief Get the value as a double array.
* If the value is not a numeric array an exception is thrown.
* @return The value.
*/
epics::pvData::shared_vector<const double> getDoubleArray();
/** @brief Get the value as a string array.
* @return The value.
* @throw runtime_error if failure.
*/
epics::pvData::shared_vector<const std::string> getStringArray();
/** @brief Put the value as a double. /** @brief Put the value as a double.
* @param value The new value. * @param value The new value.
* An exception is also thrown if the actualy type can cause an overflow. * An exception is also thrown if the actualy type can cause an overflow.
@@ -759,17 +777,9 @@ public:
static PvaClientPutDataPtr create(epics::pvData::StructureConstPtr const & structure); static PvaClientPutDataPtr create(epics::pvData::StructureConstPtr const & structure);
private: private:
PvaClientPutData(epics::pvData::StructureConstPtr const &structure); PvaClientPutData(epics::pvData::StructureConstPtr const &structure);
void checkValue();
void postPut(size_t fieldNumber); void postPut(size_t fieldNumber);
std::vector<epics::pvData::PostHandlerPtr> postHandler; std::vector<epics::pvData::PostHandlerPtr> postHandler;
epics::pvData::StructureConstPtr structure;
epics::pvData::PVStructurePtr pvStructure;
epics::pvData::BitSetPtr bitSet;
friend class PvaClientPostHandlerPvt; friend class PvaClientPostHandlerPvt;
std::string messagePrefix;
epics::pvData::PVFieldPtr pvValue;
friend class PvaClientPut; friend class PvaClientPut;
friend class PvaClientPutGet; friend class PvaClientPutGet;
}; };
@@ -779,7 +789,7 @@ private:
* *
* <a href = "../htmldoxygen/pvaClientMonitorData.html">Overview of PvaClientMonitorData</a> * <a href = "../htmldoxygen/pvaClientMonitorData.html">Overview of PvaClientMonitorData</a>
*/ */
class epicsShareClass PvaClientMonitorData class epicsShareClass PvaClientMonitorData : public PvaClientData
{ {
public: public:
POINTER_DEFINITIONS(PvaClientMonitorData); POINTER_DEFINITIONS(PvaClientMonitorData);
@@ -787,27 +797,6 @@ public:
* @brief Destructor * @brief Destructor
*/ */
~PvaClientMonitorData() {} ~PvaClientMonitorData() {}
/** @brief Set a prefix for throw messages.
* @param value The prefix.
*/
void setMessagePrefix(std::string const & value);
/** @brief Get the structure.
* @return The Structure
* @throw runtime_error if failure.
*/
epics::pvData::StructureConstPtr getStructure();
/** @brief Get the pvStructure.
* @return the pvStructure.
* @throw runtime_error if failure.
*/
epics::pvData::PVStructurePtr getPVStructure();
/** @brief Get the changed BitSet for the pvStructure,
*
* This shows which fields have changed value.
* @return The bitSet
* @throw runtime_error if failure.
*/
epics::pvData::BitSetPtr getChangedBitSet();
/** @brief Get the overrun BitSet for the pvStructure /** @brief Get the overrun BitSet for the pvStructure
* This shows which fields have had more than one change. * This shows which fields have had more than one change.
* @return The bitSet * @return The bitSet
@@ -818,111 +807,21 @@ public:
* @param out The stream that shows the changed fields. * @param out The stream that shows the changed fields.
* @return The stream that was passed as out. * @return The stream that was passed as out.
*/ */
std::ostream & showChanged(std::ostream & out);
/** @brief Show the fields that have overrun.
* @param out The stream that shows the overrun fields.
* @return The stream that was passed as out
*/
std::ostream & showOverrun(std::ostream & out); std::ostream & showOverrun(std::ostream & out);
/** @brief Is there a top level field named value.
* @return The answer.
*/
bool hasValue();
/** @brief Is the value field a scalar?
* @return The answer.
*/
bool isValueScalar();
/** @brief Is the value field a scalar array?
* @return The answer.
*/
bool isValueScalarArray();
/** @brief Get the interface to the value field.
* @return The interface. an excetion is thrown if a value field does not exist.
*/
epics::pvData::PVFieldPtr getValue();
/** @brief Get the interface to a scalar value field.
* @return The interface for a scalar value field.
* @throw runtime_error if failure.
* An exception is thown if no scalar value field.
*/
epics::pvData::PVScalarPtr getScalarValue();
/** @brief Get the interface to an array value field.
* @return The interface.
* @throw runtime_error if failure.
* An exception is thown if no array value field.
*/
std::tr1::shared_ptr<epics::pvData::PVArray> getArrayValue();
/** @brief Get the interface to a scalar array value field.
* @return Return the interface.
* @throw runtime_error if failure.
* An exception is thown if no scalar array value field.
*/
std::tr1::shared_ptr<epics::pvData::PVScalarArray> getScalarArrayValue();
/** @brief Get the value as a double.
*
* If value is not a numeric scalar an exception is thrown.
* @return The value.
*/
double getDouble();
/** @brief Get the value as a string.
*
* If value is not a scalar an exception is thrown
* @return The value.
* @throw runtime_error if failure.
*/
std::string getString();
/** @brief Get the value as a double array.
*
* If the value is not a numeric array an exception is thrown.
* @return The value.
* @throw runtime_error if failure.
*/
epics::pvData::shared_vector<const double> getDoubleArray();
/** @brief Get the value as a string array.
*
* If the value is not a string array an exception is thrown.
* @return The value.
* @throw runtime_error if failure.
*/
epics::pvData::shared_vector<const std::string> getStringArray();
/** @brief Get the alarm.
*
* If the pvStructure as an alarm field it's values are returned.
* If no then alarm shows that not alarm defined.
* @return The alarm.
* @throw runtime_error if failure.
*/
epics::pvData::Alarm getAlarm();
/** @brief Get the timeStamp.
*
* If the pvStructure has a timeStamp field, it's values are returned.
* If no then all fields are 0.
* @return The timeStamp.
*/
epics::pvData::TimeStamp getTimeStamp();
/** Factory method for creating an instance of PvaClientGetData.
* NOTE: Not normally called by clients
* @param structure Introspection interface
*/
static PvaClientMonitorDataPtr create(epics::pvData::StructureConstPtr const & structure);
/** Put data into PVStructure from monitorElement /** Put data into PVStructure from monitorElement
* NOTE: Not normally called by clients * NOTE: Not normally called by clients
* @param monitorElement the monitorElement that has new data. * @param monitorElement the monitorElement that has new data.
*/ */
void setData(epics::pvData::MonitorElementPtr const & monitorElement); void setData(epics::pvData::MonitorElementPtr const & monitorElement);
/** Factory method for creating an instance of PvaClientGetData.
* NOTE: Not normally called by clients
* @param structure Introspection interface
*/
static PvaClientMonitorDataPtr create(epics::pvData::StructureConstPtr const & structure);
private: private:
PvaClientMonitorData(epics::pvData::StructureConstPtr const & structure); PvaClientMonitorData(epics::pvData::StructureConstPtr const & structure);
void checkValue();
epics::pvData::StructureConstPtr structure;
epics::pvData::PVStructurePtr pvStructure;
epics::pvData::BitSetPtr changedBitSet;
epics::pvData::BitSetPtr overrunBitSet; epics::pvData::BitSetPtr overrunBitSet;
std::string messagePrefix;
epics::pvData::PVFieldPtr pvValue;
epics::pvData::PVAlarm pvAlarm;
epics::pvData::PVTimeStamp pvTimeStamp;
friend class PvaClientMonitor; friend class PvaClientMonitor;
}; };
@@ -967,14 +866,13 @@ typedef std::tr1::shared_ptr<ChannelProcessRequesterImpl> ChannelProcessRequeste
* <a href = "../htmldoxygen/pvaClientProcess.html">Overview of PvaClientProcess</a> * <a href = "../htmldoxygen/pvaClientProcess.html">Overview of PvaClientProcess</a>
*/ */
class epicsShareClass PvaClientProcess : class epicsShareClass PvaClientProcess :
public PvaClientChannelStateChangeRequester,
public std::tr1::enable_shared_from_this<PvaClientProcess> public std::tr1::enable_shared_from_this<PvaClientProcess>
{ {
public: public:
POINTER_DEFINITIONS(PvaClientProcess); POINTER_DEFINITIONS(PvaClientProcess);
/** @brief Create a PvaClientProcess. /** @brief Create a PvaClientProcess.
* @param &pvaClient Interface to PvaClient * @param pvaClient Interface to PvaClient
* @param channel Interface to Channel * @param pvaClientChannel Interface to Channel
* @param pvRequest The request structure. * @param pvRequest The request structure.
* @return The interface to the PvaClientProcess. * @return The interface to the PvaClientProcess.
*/ */
@@ -1054,13 +952,11 @@ private:
ProcessConnectState connectState; ProcessConnectState connectState;
PvaClientChannelStateChangeRequesterWPtr pvaClientChannelStateChangeRequester;
PvaClientProcessRequesterWPtr pvaClientProcessRequester; PvaClientProcessRequesterWPtr pvaClientProcessRequester;
enum ProcessState {processIdle,processActive,processComplete}; enum ProcessState {processIdle,processActive,processComplete};
ProcessState processState; ProcessState processState;
ChannelProcessRequesterImplPtr channelProcessRequester; ChannelProcessRequesterImplPtr channelProcessRequester;
public: public:
void channelStateChange(PvaClientChannelPtr const & pvaClientChannel, bool isConnected);
friend class ChannelProcessRequesterImpl; friend class ChannelProcessRequesterImpl;
}; };
@@ -1104,7 +1000,6 @@ public:
* <a href = "../htmldoxygen/pvaClientGet.html">Overview of PvaClientGet</a> * <a href = "../htmldoxygen/pvaClientGet.html">Overview of PvaClientGet</a>
*/ */
class epicsShareClass PvaClientGet : class epicsShareClass PvaClientGet :
public PvaClientChannelStateChangeRequester,
public std::tr1::enable_shared_from_this<PvaClientGet> public std::tr1::enable_shared_from_this<PvaClientGet>
{ {
public: public:
@@ -1183,7 +1078,7 @@ private:
PvaClientChannelPtr const & pvaClientChannel, PvaClientChannelPtr const & pvaClientChannel,
epics::pvData::PVStructurePtr const &pvRequest); epics::pvData::PVStructurePtr const &pvRequest);
void checkGetState(); void checkConnectState();
enum GetConnectState {connectIdle,connectActive,connected}; enum GetConnectState {connectIdle,connectActive,connected};
PvaClient::weak_pointer pvaClient; PvaClient::weak_pointer pvaClient;
@@ -1200,14 +1095,12 @@ private:
GetConnectState connectState; GetConnectState connectState;
PvaClientChannelStateChangeRequesterWPtr pvaClientChannelStateChangeRequester;
PvaClientGetRequesterWPtr pvaClientGetRequester; PvaClientGetRequesterWPtr pvaClientGetRequester;
enum GetState {getIdle,getActive,getComplete}; enum GetState {getIdle,getActive,getComplete};
GetState getState; GetState getState;
ChannelGetRequesterImplPtr channelGetRequester; ChannelGetRequesterImplPtr channelGetRequester;
public: public:
void channelStateChange(PvaClientChannelPtr const & pvaClientChannel, bool isConnected);
friend class ChannelGetRequesterImpl; friend class ChannelGetRequesterImpl;
}; };
@@ -1263,14 +1156,13 @@ public:
* <a href = "../htmldoxygen/pvaClientPut.html">Overview of PvaClientPut</a> * <a href = "../htmldoxygen/pvaClientPut.html">Overview of PvaClientPut</a>
*/ */
class epicsShareClass PvaClientPut : class epicsShareClass PvaClientPut :
public PvaClientChannelStateChangeRequester,
public std::tr1::enable_shared_from_this<PvaClientPut> public std::tr1::enable_shared_from_this<PvaClientPut>
{ {
public: public:
POINTER_DEFINITIONS(PvaClientPut); POINTER_DEFINITIONS(PvaClientPut);
/** @brief Create a PvaClientPut. /** @brief Create a PvaClientPut.
* @param &pvaClient Interface to PvaClient * @param pvaClient Interface to PvaClient
* @param channel Interface to Channel * @param pvaClientChannel Interface to Channel
* @param pvRequest The request structure. * @param pvRequest The request structure.
* @return The interface to the PvaClientPut. * @return The interface to the PvaClientPut.
*/ */
@@ -1355,7 +1247,7 @@ private :
PvaClientChannelPtr const & pvaClientChannel, PvaClientChannelPtr const & pvaClientChannel,
epics::pvData::PVStructurePtr const &pvRequest); epics::pvData::PVStructurePtr const &pvRequest);
void checkPutState(); void checkConnectState();
enum PutConnectState {connectIdle,connectActive,connected}; enum PutConnectState {connectIdle,connectActive,connected};
PvaClient::weak_pointer pvaClient; PvaClient::weak_pointer pvaClient;
@@ -1374,10 +1266,8 @@ private :
enum PutState {putIdle,getActive,putActive,putComplete}; enum PutState {putIdle,getActive,putActive,putComplete};
PutState putState; PutState putState;
ChannelPutRequesterImplPtr channelPutRequester; ChannelPutRequesterImplPtr channelPutRequester;
PvaClientChannelStateChangeRequesterWPtr pvaClientChannelStateChangeRequester;
PvaClientPutRequesterWPtr pvaClientPutRequester; PvaClientPutRequesterWPtr pvaClientPutRequester;
public: public:
void channelStateChange(PvaClientChannelPtr const & pvaClientChannel, bool isConnected);
friend class ChannelPutRequesterImpl; friend class ChannelPutRequesterImpl;
}; };
@@ -1444,14 +1334,13 @@ public:
* <a href = "../htmldoxygen/pvaClientPutGet.html">Overview of PvaClientPutGet</a> * <a href = "../htmldoxygen/pvaClientPutGet.html">Overview of PvaClientPutGet</a>
*/ */
class epicsShareClass PvaClientPutGet : class epicsShareClass PvaClientPutGet :
public PvaClientChannelStateChangeRequester,
public std::tr1::enable_shared_from_this<PvaClientPutGet> public std::tr1::enable_shared_from_this<PvaClientPutGet>
{ {
public: public:
POINTER_DEFINITIONS(PvaClientPutGet); POINTER_DEFINITIONS(PvaClientPutGet);
/** @brief Create a PvaClientPutGet. /** @brief Create a PvaClientPutGet.
* @param &pvaClient Interface to PvaClient * @param pvaClient Interface to PvaClient
* @param channel Interface to Channel * @param pvaClientChannel Interface to Channel
* @param pvRequest The request structure. * @param pvRequest The request structure.
* @return The interface to the PvaClientPutGet. * @return The interface to the PvaClientPutGet.
*/ */
@@ -1584,10 +1473,8 @@ private :
enum PutGetState {putGetIdle,putGetActive,putGetComplete}; enum PutGetState {putGetIdle,putGetActive,putGetComplete};
PutGetState putGetState; PutGetState putGetState;
ChannelPutGetRequesterImplPtr channelPutGetRequester; ChannelPutGetRequesterImplPtr channelPutGetRequester;
PvaClientChannelStateChangeRequesterWPtr pvaClientChannelStateChangeRequester;
PvaClientPutGetRequesterWPtr pvaClientPutGetRequester; PvaClientPutGetRequesterWPtr pvaClientPutGetRequester;
public: public:
void channelStateChange(PvaClientChannelPtr const & pvaClientChannel, bool isConnected);
friend class ChannelPutGetRequesterImpl; friend class ChannelPutGetRequesterImpl;
}; };
@@ -1639,7 +1526,7 @@ typedef std::tr1::shared_ptr<MonitorRequesterImpl> MonitorRequesterImplPtr;
* <a href = "../htmldoxygen/pvaClientMonitor.html">Overview of PvaClientMonitor</a> * <a href = "../htmldoxygen/pvaClientMonitor.html">Overview of PvaClientMonitor</a>
*/ */
class epicsShareClass PvaClientMonitor : class epicsShareClass PvaClientMonitor :
public PvaClientChannelStateChangeRequester, public PvaClientChannelStateChangeRequester, // remove when deprecated create removed
public PvaClientMonitorRequester, public PvaClientMonitorRequester,
public std::tr1::enable_shared_from_this<PvaClientMonitor> public std::tr1::enable_shared_from_this<PvaClientMonitor>
{ {
@@ -1664,6 +1551,7 @@ public:
* @param stateChangeRequester The state change requester. Can be null. * @param stateChangeRequester The state change requester. Can be null.
* @param monitorRequester The monitor requester. Can be null; * @param monitorRequester The monitor requester. Can be null;
* @return The new instance. * @return The new instance.
* @deprecated client can create PvaClientMonitor on first channel connect.
*/ */
static PvaClientMonitorPtr create( static PvaClientMonitorPtr create(
PvaClientPtr const &pvaClient, PvaClientPtr const &pvaClient,
@@ -1674,7 +1562,7 @@ public:
= PvaClientChannelStateChangeRequesterPtr(), = PvaClientChannelStateChangeRequesterPtr(),
PvaClientMonitorRequesterPtr const & monitorRequester PvaClientMonitorRequesterPtr const & monitorRequester
= PvaClientMonitorRequesterPtr() = PvaClientMonitorRequesterPtr()
); ) EPICS_DEPRECATED;
/** @brief Destructor /** @brief Destructor
*/ */
~PvaClientMonitor(); ~PvaClientMonitor();
@@ -1767,15 +1655,14 @@ private:
epics::pvData::MonitorPtr monitor; epics::pvData::MonitorPtr monitor;
epics::pvData::MonitorElementPtr monitorElement; epics::pvData::MonitorElementPtr monitorElement;
PvaClientChannelStateChangeRequesterWPtr pvaClientChannelStateChangeRequester;
PvaClientMonitorRequesterWPtr pvaClientMonitorRequester; PvaClientMonitorRequesterWPtr pvaClientMonitorRequester;
MonitorConnectState connectState; MonitorConnectState connectState;
bool userPoll; bool userPoll;
bool userWait; bool userWait;
MonitorRequesterImplPtr monitorRequester; MonitorRequesterImplPtr monitorRequester;
PvaClientChannelStateChangeRequesterWPtr pvaClientChannelStateChangeRequester; //deprecate
public: public:
void channelStateChange(PvaClientChannelPtr const & channel, bool isConnected); void channelStateChange(PvaClientChannelPtr const & channel, bool isConnected); //deprecate
void event(PvaClientMonitorPtr const & monitor); void event(PvaClientMonitorPtr const & monitor);
friend class MonitorRequesterImpl; friend class MonitorRequesterImpl;
}; };
+2 -2
View File
@@ -18,7 +18,6 @@
#include <pv/pvaClient.h> #include <pv/pvaClient.h>
using std::tr1::static_pointer_cast;
using namespace epics::pvData; using namespace epics::pvData;
using namespace epics::pvAccess; using namespace epics::pvAccess;
using namespace epics::pvAccess::ca; using namespace epics::pvAccess::ca;
@@ -111,6 +110,7 @@ PvaClientPtr PvaClient::get(std::string const & providerNames)
return master; return master;
} }
PvaClientPtr PvaClient::create() {return get();}
PvaClient::PvaClient(std::string const & providerNames) PvaClient::PvaClient(std::string const & providerNames)
: pvaClientChannelCache(new PvaClientChannelCache()), : pvaClientChannelCache(new PvaClientChannelCache()),
@@ -231,4 +231,4 @@ size_t PvaClient::cacheSize()
} }
}} }}
+62 -2
View File
@@ -18,7 +18,6 @@
#include <pv/pvaClient.h> #include <pv/pvaClient.h>
using std::tr1::static_pointer_cast;
using namespace epics::pvData; using namespace epics::pvData;
using namespace epics::pvAccess; using namespace epics::pvAccess;
using namespace std; using namespace std;
@@ -170,6 +169,7 @@ void PvaClientChannel::channelCreated(const Status& status, Channel::shared_poin
<< endl; << endl;
} }
Lock xx(mutex); Lock xx(mutex);
this->channel = channel;
if(connectState==connected) return; if(connectState==connected) return;
if(connectState!=connectActive) { if(connectState!=connectActive) {
string message("PvaClientChannel::channelCreated"); string message("PvaClientChannel::channelCreated");
@@ -198,15 +198,17 @@ void PvaClientChannel::channelStateChange(
<< " " << Channel::ConnectionStateNames[connectionState] << " " << Channel::ConnectionStateNames[connectionState]
<< endl; << endl;
} }
bool waitingForConnect = false; bool waitingForConnect = false;
if(connectState==connectActive) waitingForConnect = true; if(connectState==connectActive) waitingForConnect = true;
if(connectionState!=Channel::CONNECTED) { if(connectionState!=Channel::CONNECTED) {
Lock xx(mutex);
string mess(channelName + string mess(channelName +
" connection state " + Channel::ConnectionStateNames[connectionState]); " connection state " + Channel::ConnectionStateNames[connectionState]);
message(mess,errorMessage); message(mess,errorMessage);
connectState = notConnected; connectState = notConnected;
} else { } else {
Lock xx(mutex);
this->channel = channel;
connectState = connected; connectState = connected;
} }
if(waitingForConnect) { if(waitingForConnect) {
@@ -378,6 +380,26 @@ PvaClientGetPtr PvaClientChannel::createGet(PVStructurePtr const & pvRequest)
return PvaClientGet::create(yyy,shared_from_this(),pvRequest); return PvaClientGet::create(yyy,shared_from_this(),pvRequest);
} }
double PvaClientChannel::getDouble(string const & request)
{
return get(request)->getData()->getDouble();
}
string PvaClientChannel::getString(string const & request)
{
return get(request)->getData()->getString();
}
shared_vector<const double> PvaClientChannel::getDoubleArray(string const & request)
{
return get(request)->getData()->getDoubleArray();
}
shared_vector<const std::string> PvaClientChannel::getStringArray(string const & request)
{
return get(request)->getData()->getStringArray();
}
PvaClientPutPtr PvaClientChannel::put(string const & request) PvaClientPutPtr PvaClientChannel::put(string const & request)
{ {
@@ -413,6 +435,44 @@ PvaClientPutPtr PvaClientChannel::createPut(PVStructurePtr const & pvRequest)
return PvaClientPut::create(yyy,shared_from_this(),pvRequest); return PvaClientPut::create(yyy,shared_from_this(),pvRequest);
} }
void PvaClientChannel::putDouble(double value,string const & request)
{
PvaClientPutPtr clientPut = put(request);
PvaClientPutDataPtr putData = clientPut->getData();
putData->putDouble(value); clientPut->put();
}
void PvaClientChannel::putString(std::string const & value,string const & request)
{
PvaClientPutPtr clientPut = put(request);
PvaClientPutDataPtr putData = clientPut->getData();
putData->putString(value); clientPut->put();
}
void PvaClientChannel::putDoubleArray(
shared_vector<const double> const & value,
string const & request)
{
PvaClientPutPtr clientPut = put(request);
PvaClientPutDataPtr putData = clientPut->getData();
size_t n = value.size();
shared_vector<double> valueArray(n);
for(size_t i=0; i<n; ++i) valueArray[i] = value[i];
putData->putDoubleArray(freeze(valueArray)); clientPut->put();
}
void PvaClientChannel::putStringArray(
shared_vector<const string> const & value,
string const & request)
{
PvaClientPutPtr clientPut = put(request);
PvaClientPutDataPtr putData = clientPut->getData();
size_t n = value.size();
shared_vector<string> valueArray(n);
for(size_t i=0; i<n; ++i) valueArray[i] = value[i];
putData->putStringArray(freeze(valueArray)); clientPut->put();
}
PvaClientPutGetPtr PvaClientChannel::createPutGet(string const & request) PvaClientPutGetPtr PvaClientChannel::createPutGet(string const & request)
{ {
PVStructurePtr pvRequest = createRequest->createRequest(request); PVStructurePtr pvRequest = createRequest->createRequest(request);
+361
View File
@@ -0,0 +1,361 @@
/* pvaClientData.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 2019.04
*/
#include <typeinfo>
#include <sstream>
#include <pv/createRequest.h>
#include <pv/convert.h>
#define epicsExportSharedSymbols
#include <pv/pvaClient.h>
using std::tr1::static_pointer_cast;
using namespace epics::pvData;
using namespace epics::pvAccess;
using namespace std;
namespace epics { namespace pvaClient {
typedef std::tr1::shared_ptr<PVArray> PVArrayPtr;
static ConvertPtr convert = getConvert();
static string noStructure("no pvStructure ");
static string noValue("no value field");
static string noScalar("value is not a scalar");
static string noArray("value is not an array");
static string noScalarArray("value is not a scalarArray");
static string noAlarm("no alarm");
static string noTimeStamp("no timeStamp");
PvaClientDataPtr PvaClientData::create(StructureConstPtr const & structure)
{
if(PvaClient::getDebug()) cout << "PvaClientData::create\n";
PvaClientDataPtr epv(new PvaClientData(structure));
return epv;
}
PvaClientData::PvaClientData(StructureConstPtr const & structure)
: structure(structure)
{
}
void PvaClientData::checkValue()
{
if(PvaClient::getDebug()) cout << "PvaClientData::checkValue\n";
if(pvValue) return;
throw std::runtime_error(messagePrefix + noValue);
}
void PvaClientData::setMessagePrefix(std::string const & value)
{
messagePrefix = value + " ";
}
StructureConstPtr PvaClientData::getStructure()
{
return structure;
}
PVStructurePtr PvaClientData::getPVStructure()
{
if(pvStructure) return pvStructure;
throw std::runtime_error(messagePrefix + noStructure);
}
BitSetPtr PvaClientData::getChangedBitSet()
{
if(bitSet)return bitSet;
throw std::runtime_error(messagePrefix + noStructure);
}
std::ostream & PvaClientData::showChanged(std::ostream & out)
{
if(!bitSet) throw std::runtime_error(messagePrefix + noStructure);
size_t nextSet = bitSet->nextSetBit(0);
PVFieldPtr pvField;
while(nextSet!=string::npos) {
if(nextSet==0) {
pvField = pvStructure;
} else {
pvField = pvStructure->getSubField(nextSet);
}
string name = pvField->getFullName();
out << name << " = " << pvField << endl;
nextSet = bitSet->nextSetBit(nextSet+1);
}
return out;
}
void PvaClientData::setData(
PVStructurePtr const & pvStructureFrom,
BitSetPtr const & bitSetFrom)
{
if(PvaClient::getDebug()) cout << "PvaClientData::setData\n";
pvStructure = pvStructureFrom;
bitSet = bitSetFrom;
pvValue = pvStructure->getSubField("value");
}
bool PvaClientData::hasValue()
{
if(PvaClient::getDebug()) cout << "PvaClientData::hasValue\n";
if(!pvValue) return false;
return true;
}
bool PvaClientData::isValueScalar()
{
if(PvaClient::getDebug()) cout << "PvaClientData::isValueScalar\n";
if(!pvValue) return false;
if(pvValue->getField()->getType()==scalar) return true;
return false;
}
bool PvaClientData::isValueScalarArray()
{
if(PvaClient::getDebug()) cout << "PvaClientData::isValueScalarArray\n";
if(!pvValue) return false;
if(pvValue->getField()->getType()==scalarArray) return true;
return false;
}
PVFieldPtr PvaClientData::getValue()
{
if(PvaClient::getDebug()) cout << "PvaClientData::getValue\n";
checkValue();
return pvValue;
}
PVScalarPtr PvaClientData::getScalarValue()
{
if(PvaClient::getDebug()) cout << "PvaClientData::getScalarValue\n";
checkValue();
if(pvValue->getField()->getType()!=scalar) {
throw std::runtime_error(messagePrefix + noScalar);
}
return pvStructure->getSubField<PVScalar>("value");
}
PVArrayPtr PvaClientData::getArrayValue()
{
if(PvaClient::getDebug()) cout << "PvaClientData::getArrayValue\n";
checkValue();
Type type = pvValue->getField()->getType();
if(type!=scalarArray && type!=structureArray && type!=unionArray) {
throw std::runtime_error(messagePrefix + noArray);
}
return pvStructure->getSubField<PVArray>("value");
}
PVScalarArrayPtr PvaClientData::getScalarArrayValue()
{
if(PvaClient::getDebug()) cout << "PvaClientData::getScalarArrayValue\n";
checkValue();
Type type = pvValue->getField()->getType();
if(type!=scalarArray) {
throw std::runtime_error(messagePrefix + noScalarArray);
}
return pvStructure->getSubField<PVScalarArray>("value");
}
double PvaClientData::getDouble()
{
if(PvaClient::getDebug()) cout << "PvaClientData::getDouble\n";
PVScalarPtr pvScalar;
PVStructurePtr pvStructure = getPVStructure();
PVFieldPtr pvValue = pvStructure->getSubField("value");
if(pvValue) {
Type type = pvValue->getField()->getType();
if(type==scalar) pvScalar = static_pointer_cast<PVScalar>(pvValue);
}
if(!pvScalar) {
while(true) {
const PVFieldPtrArray fieldPtrArray(pvStructure->getPVFields());
if(fieldPtrArray.size()!=1) {
throw std::logic_error(
"PvaClientData::getDouble() pvRequest for multiple fields");
}
PVFieldPtr pvField(fieldPtrArray[0]);
Type type = pvField->getField()->getType();
if(type==scalar) {
pvScalar = static_pointer_cast<PVScalar>(pvField);
break;
}
if(pvField->getField()->getType()!=epics::pvData::structure) break;
pvStructure = static_pointer_cast<PVStructure>(pvField);
}
}
if(!pvScalar) {
throw std::logic_error(
"PvaClientData::getDouble() did not find a scalar field");
}
ScalarType scalarType = pvScalar->getScalar()->getScalarType();
if(scalarType==pvDouble) {
PVDoublePtr pvDouble = static_pointer_cast<PVDouble>(pvScalar);
return pvDouble->get();
}
if(!ScalarTypeFunc::isNumeric(scalarType)) {
throw std::logic_error(
"PvaClientData::getDouble() did not find a numeric scalar field");
}
return convert->toDouble(pvScalar);
}
string PvaClientData::getString()
{
if(PvaClient::getDebug()) cout << "PvaClientData::getString\n";
PVScalarPtr pvScalar;
PVStructurePtr pvStructure = getPVStructure();
PVFieldPtr pvValue = pvStructure->getSubField("value");
if(pvValue) {
Type type = pvValue->getField()->getType();
if(type==scalar) pvScalar = static_pointer_cast<PVScalar>(pvValue);
}
if(!pvScalar) {
while(true) {
const PVFieldPtrArray fieldPtrArray(pvStructure->getPVFields());
if(fieldPtrArray.size()!=1) {
throw std::logic_error(
"PvaClientData::getString() pvRequest for multiple fields");
}
PVFieldPtr pvField(fieldPtrArray[0]);
Type type = pvField->getField()->getType();
if(type==scalar) {
pvScalar = static_pointer_cast<PVScalar>(pvField);
break;
}
if(pvField->getField()->getType()!=epics::pvData::structure) break;
pvStructure = static_pointer_cast<PVStructure>(pvField);
}
}
if(!pvScalar) {
throw std::logic_error(
"PvaClientData::getString() did not find a scalar field");
}
return convert->toString(pvScalar);
}
shared_vector<const double> PvaClientData::getDoubleArray()
{
if(PvaClient::getDebug()) cout << "PvaClientData::getDoubleArray\n";
PVScalarArrayPtr pvScalarArray;
PVStructurePtr pvStructure = getPVStructure();
PVFieldPtr pvValue = pvStructure->getSubField("value");
if(pvValue) {
Type type = pvValue->getField()->getType();
if(type==scalarArray) {
pvScalarArray = static_pointer_cast<PVScalarArray>(pvValue);
}
}
if(!pvScalarArray) {
while(true) {
const PVFieldPtrArray fieldPtrArray(pvStructure->getPVFields());
if(fieldPtrArray.size()!=1) {
throw std::logic_error(
"PvaClientData::getDoubleArray() pvRequest for multiple fields");
}
PVFieldPtr pvField(fieldPtrArray[0]);
Type type = pvField->getField()->getType();
if(type==scalarArray) {
pvScalarArray = static_pointer_cast<PVScalarArray>(pvField);
break;
}
if(pvField->getField()->getType()!=epics::pvData::structure) break;
pvStructure = static_pointer_cast<PVStructure>(pvField);
}
}
if(!pvScalarArray) {
throw std::logic_error(
"PvaClientData::getDoubleArray() did not find a scalarArray field");
}
ScalarType scalarType = pvScalarArray->getScalarArray()->getElementType();
if(!ScalarTypeFunc::isNumeric(scalarType)) {
throw std::logic_error(
"PvaClientData::getDoubleArray() did not find a numeric scalarArray field");
}
shared_vector<const double> retValue;
pvScalarArray->getAs<const double>(retValue);
return retValue;
}
shared_vector<const string> PvaClientData::getStringArray()
{
if(PvaClient::getDebug()) cout << "PvaClientData::getStringArray\n";
PVScalarArrayPtr pvScalarArray;
PVStructurePtr pvStructure = getPVStructure();
PVFieldPtr pvValue = pvStructure->getSubField("value");
if(pvValue) {
Type type = pvValue->getField()->getType();
if(type==scalarArray) {
pvScalarArray = static_pointer_cast<PVScalarArray>(pvValue);
}
}
if(!pvScalarArray) {
while(true) {
const PVFieldPtrArray fieldPtrArray(pvStructure->getPVFields());
if(fieldPtrArray.size()!=1) {
throw std::logic_error(
"PvaClientData::getStringArray() pvRequest for multiple fields");
}
PVFieldPtr pvField(fieldPtrArray[0]);
Type type = pvField->getField()->getType();
if(type==scalarArray) {
pvScalarArray = static_pointer_cast<PVScalarArray>(pvField);
break;
}
if(pvField->getField()->getType()!=epics::pvData::structure) break;
pvStructure = static_pointer_cast<PVStructure>(pvField);
}
}
if(!pvScalarArray) {
throw std::logic_error(
"PvaClientData::getStringArray() did not find a scalarArray field");
}
shared_vector<const string> retValue;
pvScalarArray->getAs<const string>(retValue);
return retValue;
}
Alarm PvaClientData::getAlarm()
{
if(PvaClient::getDebug()) cout << "PvaClientData::getAlarm\n";
if(!pvStructure) throw new std::runtime_error(messagePrefix + noStructure);
PVStructurePtr pvs = pvStructure->getSubField<PVStructure>("alarm");
if(!pvs) throw std::runtime_error(messagePrefix + noAlarm);
pvAlarm.attach(pvs);
if(pvAlarm.isAttached()) {
Alarm alarm;
pvAlarm.get(alarm);
pvAlarm.detach();
return alarm;
}
throw std::runtime_error(messagePrefix + noAlarm);
}
TimeStamp PvaClientData::getTimeStamp()
{
if(PvaClient::getDebug()) cout << "PvaClientData::getTimeStamp\n";
if(!pvStructure) throw new std::runtime_error(messagePrefix + noStructure);
PVStructurePtr pvs = pvStructure->getSubField<PVStructure>("timeStamp");
if(!pvs) throw std::runtime_error(messagePrefix + noTimeStamp);
pvTimeStamp.attach(pvs);
if(pvTimeStamp.isAttached()) {
TimeStamp timeStamp;
pvTimeStamp.get(timeStamp);
pvTimeStamp.detach();
return timeStamp;
}
throw std::runtime_error(messagePrefix + noTimeStamp);
}
}}
+31 -61
View File
@@ -15,7 +15,6 @@
#include <pv/pvaClient.h> #include <pv/pvaClient.h>
using std::tr1::static_pointer_cast;
using namespace epics::pvData; using namespace epics::pvData;
using namespace epics::pvAccess; using namespace epics::pvAccess;
using namespace std; using namespace std;
@@ -99,50 +98,29 @@ PvaClientGet::PvaClientGet(
getState(getIdle) getState(getIdle)
{ {
if(PvaClient::getDebug()) { if(PvaClient::getDebug()) {
cout << "PvaClientGet::PvaClientGet::PvaClientGet" cout << "PvaClientGet::PvaClientGet channelName "
<< " channelName " << pvaClientChannel->getChannel()->getChannelName() << pvaClientChannel->getChannel()->getChannelName() << "\n";
<< endl;
} }
} }
PvaClientGet::~PvaClientGet() PvaClientGet::~PvaClientGet()
{ {
if(PvaClient::getDebug()) { if(PvaClient::getDebug()) {
cout<< "PvaClientGet::~PvaClientGet" cout<< "PvaClientGet::~PvaClientGet channelName "
<< " channelName " << pvaClientChannel->getChannel()->getChannelName() << pvaClientChannel->getChannel()->getChannelName() << "\n";
<< endl;
} }
} }
void PvaClientGet::channelStateChange(PvaClientChannelPtr const & pvaClientChannel, bool isConnected)
{
if(PvaClient::getDebug()) {
cout<< "PvaClientGet::channelStateChange"
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
<< " isConnected " << (isConnected ? "true" : "false")
<< endl;
}
if(isConnected&&!channelGet)
{
connectState = connectActive;
channelGet = pvaClientChannel->getChannel()->createChannelGet(channelGetRequester,pvRequest);
}
PvaClientChannelStateChangeRequesterPtr req(pvaClientChannelStateChangeRequester.lock());
if(req) {
req->channelStateChange(pvaClientChannel,isConnected);
}
}
void PvaClientGet::checkGetState() void PvaClientGet::checkConnectState()
{ {
if(PvaClient::getDebug()) { if(PvaClient::getDebug()) {
cout << "PvaClientGet::checkGetState" cout << "PvaClientGet::checkConnectState channelName "
<< " channelName " << pvaClientChannel->getChannel()->getChannelName() << pvaClientChannel->getChannel()->getChannelName() << "\n";
<< endl;
} }
if(!pvaClientChannel->getChannel()->isConnected()) { if(!pvaClientChannel->getChannel()->isConnected()) {
string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName() string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName()
+ " PvaClientGet::checkGetState channel not connected "; + " PvaClientGet::checkConnectState channel not connected ";
throw std::runtime_error(message); throw std::runtime_error(message);
} }
if(connectState==connectIdle) { if(connectState==connectIdle) {
@@ -177,10 +155,10 @@ void PvaClientGet::channelGetConnect(
StructureConstPtr const & structure) StructureConstPtr const & structure)
{ {
if(PvaClient::getDebug()) { if(PvaClient::getDebug()) {
cout << "PvaClientGet::channelGetConnect" cout << "PvaClientGet::channelGetConnect channelName "
<< " channelName " << pvaClientChannel->getChannel()->getChannelName() << pvaClientChannel->getChannel()->getChannelName()
<< " status.isOK " << (status.isOK() ? "true" : "false") << " status.isOK " << (status.isOK() ? "true" : "false")
<< endl; << "\n";
} }
{ {
Lock xx(mutex); Lock xx(mutex);
@@ -214,10 +192,10 @@ void PvaClientGet::getDone(
BitSetPtr const & bitSet) BitSetPtr const & bitSet)
{ {
if(PvaClient::getDebug()) { if(PvaClient::getDebug()) {
cout << "PvaClientGet::getDone" cout << "PvaClientGet::getDone channelName "
<< " channelName " << pvaClientChannel->getChannel()->getChannelName() << pvaClientChannel->getChannel()->getChannelName()
<< " status.isOK " << (status.isOK() ? "true" : "false") << " status.isOK " << (status.isOK() ? "true" : "false")
<< endl; << "\n";
} }
{ {
Lock xx(mutex); Lock xx(mutex);
@@ -237,9 +215,8 @@ void PvaClientGet::getDone(
void PvaClientGet::connect() void PvaClientGet::connect()
{ {
if(PvaClient::getDebug()) { if(PvaClient::getDebug()) {
cout << "PvaClientGet::connect" cout << "PvaClientGet::connect channelName "
<< " channelName " << pvaClientChannel->getChannel()->getChannelName() << pvaClientChannel->getChannel()->getChannelName() << "\n";
<< endl;
} }
issueConnect(); issueConnect();
Status status = waitConnect(); Status status = waitConnect();
@@ -252,9 +229,8 @@ void PvaClientGet::connect()
void PvaClientGet::issueConnect() void PvaClientGet::issueConnect()
{ {
if(PvaClient::getDebug()) { if(PvaClient::getDebug()) {
cout << "PvaClientGet::issueConnect" cout << "PvaClientGet::issueConnect channelName "
<< " channelName " << pvaClientChannel->getChannel()->getChannelName() << pvaClientChannel->getChannel()->getChannelName() << "\n";
<< endl;
} }
if(connectState!=connectIdle) { if(connectState!=connectIdle) {
string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName() string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName()
@@ -269,9 +245,8 @@ void PvaClientGet::issueConnect()
Status PvaClientGet::waitConnect() Status PvaClientGet::waitConnect()
{ {
if(PvaClient::getDebug()) { if(PvaClient::getDebug()) {
cout << "PvaClientGet::waitConnect" cout << "PvaClientGet::waitConnect channelName "
<< " channelName " << pvaClientChannel->getChannel()->getChannelName() << pvaClientChannel->getChannel()->getChannelName() << "\n";
<< endl;
} }
{ {
Lock xx(mutex); Lock xx(mutex);
@@ -293,9 +268,8 @@ Status PvaClientGet::waitConnect()
void PvaClientGet::get() void PvaClientGet::get()
{ {
if(PvaClient::getDebug()) { if(PvaClient::getDebug()) {
cout << "PvaClientGet::get" cout << "PvaClientGet::get channelName "
<< " channelName " << pvaClientChannel->getChannel()->getChannelName() << pvaClientChannel->getChannel()->getChannelName() << "\n";
<< endl;
} }
issueGet(); issueGet();
Status status = waitGet(); Status status = waitGet();
@@ -308,9 +282,8 @@ void PvaClientGet::get()
void PvaClientGet::issueGet() void PvaClientGet::issueGet()
{ {
if(PvaClient::getDebug()) { if(PvaClient::getDebug()) {
cout << "PvaClientGet::issueGet" cout << "PvaClientGet::issueGet channelName "
<< " channelName " << pvaClientChannel->getChannel()->getChannelName() << pvaClientChannel->getChannel()->getChannelName() << "\n";
<< endl;
} }
if(connectState==connectIdle) connect(); if(connectState==connectIdle) connect();
if(getState==getActive) { if(getState==getActive) {
@@ -325,9 +298,8 @@ void PvaClientGet::issueGet()
Status PvaClientGet::waitGet() Status PvaClientGet::waitGet()
{ {
if(PvaClient::getDebug()) { if(PvaClient::getDebug()) {
cout << "PvaClientGet::waitGet" cout << "PvaClientGet::waitGet channelName "
<< " channelName " << pvaClientChannel->getChannel()->getChannelName() << pvaClientChannel->getChannel()->getChannelName() << "\n";
<< endl;
} }
{ {
Lock xx(mutex); Lock xx(mutex);
@@ -348,11 +320,10 @@ Status PvaClientGet::waitGet()
PvaClientGetDataPtr PvaClientGet::getData() PvaClientGetDataPtr PvaClientGet::getData()
{ {
if(PvaClient::getDebug()) { if(PvaClient::getDebug()) {
cout<< "PvaClientGet::getData" cout<< "PvaClientGet::getData channelName "
<< " channelName " << pvaClientChannel->getChannel()->getChannelName() << pvaClientChannel->getChannel()->getChannelName() << "\n";
<< endl;
} }
checkGetState(); checkConnectState();
if(getState==getIdle) get(); if(getState==getIdle) get();
return pvaClientData; return pvaClientData;
} }
@@ -360,9 +331,8 @@ PvaClientGetDataPtr PvaClientGet::getData()
void PvaClientGet::setRequester(PvaClientGetRequesterPtr const & pvaClientGetRequester) void PvaClientGet::setRequester(PvaClientGetRequesterPtr const & pvaClientGetRequester)
{ {
if(PvaClient::getDebug()) { if(PvaClient::getDebug()) {
cout << "PvaClientGet::setRequester" cout << "PvaClientGet::setRequester channelName "
<< " channelName " << pvaClientChannel->getChannel()->getChannelName() << pvaClientChannel->getChannel()->getChannelName() << "\n";
<< endl;
} }
this->pvaClientGetRequester = pvaClientGetRequester; this->pvaClientGetRequester = pvaClientGetRequester;
} }
+3 -203
View File
@@ -19,7 +19,6 @@
#include <pv/pvaClient.h> #include <pv/pvaClient.h>
using std::tr1::static_pointer_cast;
using namespace epics::pvData; using namespace epics::pvData;
using namespace epics::pvAccess; using namespace epics::pvAccess;
using namespace std; using namespace std;
@@ -27,214 +26,15 @@ using namespace std;
namespace epics { namespace pvaClient { namespace epics { namespace pvaClient {
typedef std::tr1::shared_ptr<PVArray> PVArrayPtr;
static ConvertPtr convert = getConvert();
static string noStructure("no pvStructure ");
static string noValue("no value field");
static string noScalar("value is not a scalar");
static string notCompatibleScalar("value is not a compatible scalar");
static string noArray("value is not an array");
static string noScalarArray("value is not a scalarArray");
static string notDoubleArray("value is not a doubleArray");
static string notStringArray("value is not a stringArray");
static string noAlarm("no alarm");
static string noTimeStamp("no timeStamp");
PvaClientGetDataPtr PvaClientGetData::create(StructureConstPtr const & structure) PvaClientGetDataPtr PvaClientGetData::create(StructureConstPtr const & structure)
{ {
if(PvaClient::getDebug()) { if(PvaClient::getDebug()) cout << "PvaClientGetData::create\n";
cout << "PvaClientGetData::create"
<< endl;
}
PvaClientGetDataPtr epv(new PvaClientGetData(structure)); PvaClientGetDataPtr epv(new PvaClientGetData(structure));
return epv; return epv;
} }
PvaClientGetData::PvaClientGetData(StructureConstPtr const & structure) PvaClientGetData::PvaClientGetData(StructureConstPtr const & structure)
: structure(structure), : PvaClientData(structure)
pvStructure(getPVDataCreate()->createPVStructure(structure)), {}
bitSet(BitSetPtr(new BitSet(pvStructure->getNumberFields())))
{
messagePrefix = "";
pvValue = pvStructure->getSubField("value");
}
void PvaClientGetData::checkValue()
{
if(PvaClient::getDebug()) {
cout << "PvaClientGetData::checkValue"
<< endl;
}
if(pvValue) return;
throw std::runtime_error(messagePrefix + noValue);
}
void PvaClientGetData::setMessagePrefix(std::string const & value)
{
messagePrefix = value + " ";
}
StructureConstPtr PvaClientGetData::getStructure()
{return structure;}
PVStructurePtr PvaClientGetData::getPVStructure()
{
if(pvStructure) return pvStructure;
throw std::runtime_error(messagePrefix + noStructure);
}
BitSetPtr PvaClientGetData::getChangedBitSet()
{
if(bitSet)return bitSet;
throw std::runtime_error(messagePrefix + noStructure);
}
std::ostream & PvaClientGetData::showChanged(std::ostream & out)
{
if(!bitSet) throw std::runtime_error(messagePrefix + noStructure);
size_t nextSet = bitSet->nextSetBit(0);
PVFieldPtr pvField;
while(nextSet!=string::npos) {
if(nextSet==0) {
pvField = pvStructure;
} else {
pvField = pvStructure->getSubField(nextSet);
}
string name = pvField->getFullName();
out << name << " = " << pvField << endl;
nextSet = bitSet->nextSetBit(nextSet+1);
}
return out;
}
void PvaClientGetData::setData(
PVStructurePtr const & pvStructureFrom,
BitSetPtr const & bitSetFrom)
{
if(PvaClient::getDebug()) {
cout << "PvaClientGetData::setData"
<< endl;
}
pvStructure = pvStructureFrom;
bitSet = bitSetFrom;
pvValue = pvStructure->getSubField("value");
}
bool PvaClientGetData::hasValue()
{
if(!pvValue) return false;
return true;
}
bool PvaClientGetData::isValueScalar()
{
if(!pvValue) return false;
if(pvValue->getField()->getType()==scalar) return true;
return false;
}
bool PvaClientGetData::isValueScalarArray()
{
if(!pvValue) return false;
if(pvValue->getField()->getType()==scalarArray) return true;
return false;
}
PVFieldPtr PvaClientGetData::getValue()
{
checkValue();
return pvValue;
}
PVScalarPtr PvaClientGetData::getScalarValue()
{
checkValue();
PVScalarPtr pv = pvStructure->getSubField<PVScalar>("value");
if(!pv) throw std::runtime_error(messagePrefix + noScalar);
return pv;
}
PVArrayPtr PvaClientGetData::getArrayValue()
{
checkValue();
PVArrayPtr pv = pvStructure->getSubField<PVArray>("value");
if(!pv) throw std::runtime_error(messagePrefix + noArray);
return pv;
}
PVScalarArrayPtr PvaClientGetData::getScalarArrayValue()
{
checkValue();
PVScalarArrayPtr pv = pvStructure->getSubField<PVScalarArray>("value");
if(!pv) throw std::runtime_error(messagePrefix + noScalarArray);
return pv;
}
double PvaClientGetData::getDouble()
{
PVScalarPtr pvScalar = getScalarValue();
ScalarType scalarType = pvScalar->getScalar()->getScalarType();
if(scalarType==pvDouble) {
PVDoublePtr pvDouble = static_pointer_cast<PVDouble>(pvScalar);
return pvDouble->get();
}
if(!ScalarTypeFunc::isNumeric(scalarType)) {
throw std::runtime_error(messagePrefix + notCompatibleScalar);
}
return convert->toDouble(pvScalar);
}
string PvaClientGetData::getString()
{
PVScalarPtr pvScalar = getScalarValue();
return convert->toString(pvScalar);
}
shared_vector<const double> PvaClientGetData::getDoubleArray()
{
checkValue();
PVDoubleArrayPtr pv = pvStructure->getSubField<PVDoubleArray>("value");
if(!pv) throw std::runtime_error(messagePrefix + notDoubleArray);
return pv->view();
}
shared_vector<const string> PvaClientGetData::getStringArray()
{
checkValue();
PVStringArrayPtr pv = pvStructure->getSubField<PVStringArray>("value");
if(!pv) throw std::runtime_error(messagePrefix + notStringArray);
return pv->view();
}
Alarm PvaClientGetData::getAlarm()
{
if(!pvStructure) throw new std::runtime_error(messagePrefix + noStructure);
PVStructurePtr pvs = pvStructure->getSubField<PVStructure>("alarm");
if(!pvs) throw std::runtime_error(messagePrefix + noAlarm);
pvAlarm.attach(pvs);
if(pvAlarm.isAttached()) {
Alarm alarm;
pvAlarm.get(alarm);
pvAlarm.detach();
return alarm;
}
throw std::runtime_error(messagePrefix + noAlarm);
}
TimeStamp PvaClientGetData::getTimeStamp()
{
if(!pvStructure) throw new std::runtime_error(messagePrefix + noStructure);
PVStructurePtr pvs = pvStructure->getSubField<PVStructure>("timeStamp");
if(!pvs) throw std::runtime_error(messagePrefix + noTimeStamp);
pvTimeStamp.attach(pvs);
if(pvTimeStamp.isAttached()) {
TimeStamp timeStamp;
pvTimeStamp.get(timeStamp);
pvTimeStamp.detach();
return timeStamp;
}
throw std::runtime_error(messagePrefix + noTimeStamp);
}
}} }}
+8 -23
View File
@@ -17,8 +17,6 @@
#include <pv/pvaClient.h> #include <pv/pvaClient.h>
using std::tr1::static_pointer_cast;
using std::tr1::dynamic_pointer_cast;
using namespace epics::pvData; using namespace epics::pvData;
using namespace epics::pvAccess; using namespace epics::pvAccess;
using namespace std; using namespace std;
@@ -83,11 +81,6 @@ PvaClientMonitorPtr PvaClientMonitor::create(
PvaClientChannelPtr const & pvaClientChannel, PvaClientChannelPtr const & pvaClientChannel,
PVStructurePtr const &pvRequest) PVStructurePtr const &pvRequest)
{ {
if(PvaClient::getDebug()) {
cout<< "PvaClientMonitor::create(pvaClient,pvaClientChannel,pvRequest)\n"
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
<< endl;
}
PvaClientMonitorPtr clientMonitor(new PvaClientMonitor(pvaClient,pvaClientChannel,pvRequest)); PvaClientMonitorPtr clientMonitor(new PvaClientMonitor(pvaClient,pvaClientChannel,pvRequest));
clientMonitor->monitorRequester = MonitorRequesterImplPtr( clientMonitor->monitorRequester = MonitorRequesterImplPtr(
new MonitorRequesterImpl(clientMonitor,pvaClient)); new MonitorRequesterImpl(clientMonitor,pvaClient));
@@ -137,7 +130,9 @@ PvaClientMonitor::PvaClientMonitor(
userWait(false) userWait(false)
{ {
if(PvaClient::getDebug()) { if(PvaClient::getDebug()) {
cout<< "PvaClientMonitor::PvaClientMonitor()" << endl; cout<< "PvaClientMonitor::PvaClientMonitor\n"
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
<< endl;
} }
} }
@@ -174,6 +169,11 @@ void PvaClientMonitor::channelStateChange(PvaClientChannelPtr const & channel, b
void PvaClientMonitor::event(PvaClientMonitorPtr const & monitor) void PvaClientMonitor::event(PvaClientMonitorPtr const & monitor)
{ {
if(PvaClient::getDebug()) {
cout << "PvaClientMonitor::event"
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
<< endl;
}
PvaClientMonitorRequesterPtr req(pvaClientMonitorRequester.lock()); PvaClientMonitorRequesterPtr req(pvaClientMonitorRequester.lock());
if(req) req->event(monitor); if(req) req->event(monitor);
} }
@@ -434,16 +434,6 @@ bool PvaClientMonitor::poll()
<< endl; << endl;
} }
checkMonitorState(); checkMonitorState();
if(!isStarted) {
string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName()
+ " PvaClientMonitor::poll illegal state ";
throw std::runtime_error(message);
}
if(userPoll) {
string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName()
+ " PvaClientMonitor::poll did not release last";
throw std::runtime_error(message);
}
monitorElement = monitor->poll(); monitorElement = monitor->poll();
if(!monitorElement) return false; if(!monitorElement) return false;
userPoll = true; userPoll = true;
@@ -481,11 +471,6 @@ void PvaClientMonitor::releaseEvent()
<< " channelName " << pvaClientChannel->getChannel()->getChannelName() << " channelName " << pvaClientChannel->getChannel()->getChannelName()
<< endl; << endl;
} }
if(!isStarted) {
string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName()
+ " PvaClientMonitor::releaseEvent monitor not started ";
throw std::runtime_error(message);
}
if(!userPoll) { if(!userPoll) {
string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName() string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName()
+ " PvaClientMonitor::releaseEvent did not call poll"; + " PvaClientMonitor::releaseEvent did not call poll";
+6 -183
View File
@@ -19,7 +19,6 @@
#include <pv/pvaClient.h> #include <pv/pvaClient.h>
using std::tr1::static_pointer_cast;
using namespace epics::pvData; using namespace epics::pvData;
using namespace epics::pvAccess; using namespace epics::pvAccess;
using namespace std; using namespace std;
@@ -53,43 +52,16 @@ PvaClientMonitorDataPtr PvaClientMonitorData::create(StructureConstPtr const & s
} }
PvaClientMonitorData::PvaClientMonitorData(StructureConstPtr const & structure) PvaClientMonitorData::PvaClientMonitorData(StructureConstPtr const & structure)
: structure(structure) : PvaClientData(structure)
{ {
messagePrefix = "";
} }
void PvaClientMonitorData::setData(MonitorElementPtr const & monitorElement) void PvaClientMonitorData::setData(MonitorElementPtr const & monitorElement)
{ {
pvStructure = monitorElement->pvStructurePtr; PVStructurePtr pvStructure = monitorElement->pvStructurePtr;
changedBitSet = monitorElement->changedBitSet; BitSetPtr changedBitSet = monitorElement->changedBitSet;
PvaClientData::setData(pvStructure,changedBitSet);
overrunBitSet = monitorElement->overrunBitSet; overrunBitSet = monitorElement->overrunBitSet;
pvValue = pvStructure->getSubField("value");
}
void PvaClientMonitorData::checkValue()
{
if(pvValue) return;
throw std::runtime_error(messagePrefix + noValue);
}
void PvaClientMonitorData::setMessagePrefix(std::string const & value)
{
messagePrefix = value + " ";
}
StructureConstPtr PvaClientMonitorData::getStructure()
{return structure;}
PVStructurePtr PvaClientMonitorData::getPVStructure()
{
if(pvStructure) return pvStructure;
throw std::runtime_error(messagePrefix + noStructure);
}
BitSetPtr PvaClientMonitorData::getChangedBitSet()
{
if(!changedBitSet) throw std::runtime_error(messagePrefix + noStructure);
return changedBitSet;
} }
BitSetPtr PvaClientMonitorData::getOverrunBitSet() BitSetPtr PvaClientMonitorData::getOverrunBitSet()
@@ -98,24 +70,6 @@ BitSetPtr PvaClientMonitorData::getOverrunBitSet()
return overrunBitSet; return overrunBitSet;
} }
std::ostream & PvaClientMonitorData::showChanged(std::ostream & out)
{
if(!changedBitSet) throw std::runtime_error(messagePrefix + noStructure);
size_t nextSet = changedBitSet->nextSetBit(0);
PVFieldPtr pvField;
while(nextSet!=string::npos) {
if(nextSet==0) {
pvField = pvStructure;
} else {
pvField = pvStructure->getSubField(nextSet);
}
string name = pvField->getFullName();
out << name << " = " << pvField << endl;
nextSet = changedBitSet->nextSetBit(nextSet+1);
}
return out;
}
std::ostream & PvaClientMonitorData::showOverrun(std::ostream & out) std::ostream & PvaClientMonitorData::showOverrun(std::ostream & out)
{ {
if(!overrunBitSet) throw std::runtime_error(messagePrefix + noStructure); if(!overrunBitSet) throw std::runtime_error(messagePrefix + noStructure);
@@ -123,9 +77,9 @@ std::ostream & PvaClientMonitorData::showOverrun(std::ostream & out)
PVFieldPtr pvField; PVFieldPtr pvField;
while(nextSet!=string::npos) { while(nextSet!=string::npos) {
if(nextSet==0) { if(nextSet==0) {
pvField = pvStructure; pvField = getPVStructure();
} else { } else {
pvField = pvStructure->getSubField(nextSet); pvField = getPVStructure()->getSubField(nextSet);
} }
string name = pvField->getFullName(); string name = pvField->getFullName();
out << name << " = " << pvField << endl; out << name << " = " << pvField << endl;
@@ -134,135 +88,4 @@ std::ostream & PvaClientMonitorData::showOverrun(std::ostream & out)
return out; return out;
} }
bool PvaClientMonitorData::hasValue()
{
if(!pvValue) return false;
return true;
}
bool PvaClientMonitorData::isValueScalar()
{
if(!pvValue) return false;
if(pvValue->getField()->getType()==scalar) return true;
return false;
}
bool PvaClientMonitorData::isValueScalarArray()
{
if(!pvValue) return false;
if(pvValue->getField()->getType()==scalarArray) return true;
return false;
}
PVFieldPtr PvaClientMonitorData::getValue()
{
checkValue();
return pvValue;
}
PVScalarPtr PvaClientMonitorData::getScalarValue()
{
checkValue();
PVScalarPtr pv = pvStructure->getSubField<PVScalar>("value");
if(!pv) {
throw std::runtime_error(messagePrefix + noScalar);
}
return pv;
}
PVArrayPtr PvaClientMonitorData::getArrayValue()
{
checkValue();
PVArrayPtr pv = pvStructure->getSubField<PVArray>("value");
if(!pv) {
throw std::runtime_error(messagePrefix + noArray);
}
return pv;
}
PVScalarArrayPtr PvaClientMonitorData::getScalarArrayValue()
{
checkValue();
PVScalarArrayPtr pv = pvStructure->getSubField<PVScalarArray>("value");
if(!pv) {
throw std::runtime_error(messagePrefix + noScalarArray);
}
return pv;
}
double PvaClientMonitorData::getDouble()
{
PVScalarPtr pvScalar = getScalarValue();
ScalarType scalarType = pvScalar->getScalar()->getScalarType();
if(scalarType==pvDouble) {
PVDoublePtr pvDouble = static_pointer_cast<PVDouble>(pvScalar);
return pvDouble->get();
}
if(!ScalarTypeFunc::isNumeric(scalarType)) {
throw std::runtime_error(messagePrefix + notCompatibleScalar);
}
return convert->toDouble(pvScalar);
}
string PvaClientMonitorData::getString()
{
PVScalarPtr pvScalar = getScalarValue();
return convert->toString(pvScalar);
}
shared_vector<const double> PvaClientMonitorData::getDoubleArray()
{
checkValue();
PVDoubleArrayPtr pv = pvStructure->getSubField<PVDoubleArray>("value");
if(!pv) {
throw std::runtime_error(messagePrefix + notDoubleArray);
}
return pv->view();
}
shared_vector<const string> PvaClientMonitorData::getStringArray()
{
checkValue();
PVStringArrayPtr pv = pvStructure->getSubField<PVStringArray>("value");
if(!pv) {
throw std::runtime_error(messagePrefix + notStringArray);
}
return pv->view();
}
Alarm PvaClientMonitorData::getAlarm()
{
if(!pvStructure) {
throw std::runtime_error(messagePrefix + noAlarm);
}
PVStructurePtr pvs = pvStructure->getSubField<PVStructure>("alarm");
if(!pvs) throw std::runtime_error(messagePrefix + noAlarm);
pvAlarm.attach(pvs);
if(pvAlarm.isAttached()) {
Alarm alarm;
pvAlarm.get(alarm);
pvAlarm.detach();
return alarm;
}
throw std::runtime_error(messagePrefix + noAlarm);
}
TimeStamp PvaClientMonitorData::getTimeStamp()
{
if(!pvStructure) {
throw std::runtime_error(messagePrefix + noTimeStamp);
}
PVStructurePtr pvs = pvStructure->getSubField<PVStructure>("timeStamp");
if(!pvs) throw std::runtime_error(messagePrefix + noTimeStamp);
pvTimeStamp.attach(pvs);
if(pvTimeStamp.isAttached()) {
TimeStamp timeStamp;
pvTimeStamp.get(timeStamp);
pvTimeStamp.detach();
return timeStamp;
}
throw std::runtime_error(messagePrefix + noTimeStamp);
}
}} }}
-3
View File
@@ -17,9 +17,6 @@
#include <pv/pvaClientMultiChannel.h> #include <pv/pvaClientMultiChannel.h>
using std::tr1::static_pointer_cast;
using namespace epics::pvData; using namespace epics::pvData;
using namespace epics::pvAccess; using namespace epics::pvAccess;
using namespace std; using namespace std;
-1
View File
@@ -16,7 +16,6 @@
#include <pv/pvaClientMultiChannel.h> #include <pv/pvaClientMultiChannel.h>
using std::tr1::static_pointer_cast;
using namespace epics::pvData; using namespace epics::pvData;
using namespace epics::pvAccess; using namespace epics::pvAccess;
using namespace epics::nt; using namespace epics::nt;
-1
View File
@@ -16,7 +16,6 @@
#include <pv/pvaClientMultiChannel.h> #include <pv/pvaClientMultiChannel.h>
using std::tr1::static_pointer_cast;
using namespace epics::pvData; using namespace epics::pvData;
using namespace epics::pvAccess; using namespace epics::pvAccess;
using namespace epics::nt; using namespace epics::nt;
-1
View File
@@ -16,7 +16,6 @@
#include <pv/pvaClientMultiChannel.h> #include <pv/pvaClientMultiChannel.h>
using std::tr1::static_pointer_cast;
using namespace epics::pvData; using namespace epics::pvData;
using namespace epics::pvAccess; using namespace epics::pvAccess;
using namespace epics::nt; using namespace epics::nt;
-1
View File
@@ -15,7 +15,6 @@
#include <pv/pvaClientMultiChannel.h> #include <pv/pvaClientMultiChannel.h>
using std::tr1::static_pointer_cast;
using namespace epics::pvData; using namespace epics::pvData;
using namespace epics::pvAccess; using namespace epics::pvAccess;
using namespace epics::nt; using namespace epics::nt;
-1
View File
@@ -15,7 +15,6 @@
#include <pv/pvaClientMultiChannel.h> #include <pv/pvaClientMultiChannel.h>
using std::tr1::static_pointer_cast;
using namespace epics::pvData; using namespace epics::pvData;
using namespace epics::pvAccess; using namespace epics::pvAccess;
using namespace epics::nt; using namespace epics::nt;
-1
View File
@@ -18,7 +18,6 @@
#include <pv/pvaClientMultiChannel.h> #include <pv/pvaClientMultiChannel.h>
using std::tr1::static_pointer_cast;
using namespace epics::pvData; using namespace epics::pvData;
using namespace epics::pvAccess; using namespace epics::pvAccess;
using namespace epics::nt; using namespace epics::nt;
-1
View File
@@ -17,7 +17,6 @@
#include <pv/pvaClientMultiChannel.h> #include <pv/pvaClientMultiChannel.h>
using std::tr1::static_pointer_cast;
using namespace epics::pvData; using namespace epics::pvData;
using namespace epics::pvAccess; using namespace epics::pvAccess;
using namespace epics::nt; using namespace epics::nt;
+2 -46
View File
@@ -15,7 +15,6 @@
#include <pv/pvaClient.h> #include <pv/pvaClient.h>
using std::tr1::static_pointer_cast;
using namespace epics::pvData; using namespace epics::pvData;
using namespace epics::pvAccess; using namespace epics::pvAccess;
using namespace std; using namespace std;
@@ -112,50 +111,6 @@ PvaClientProcess::~PvaClientProcess()
} }
} }
void PvaClientProcess::channelStateChange(PvaClientChannelPtr const & pvaClientChannel, bool isConnected)
{
if(PvaClient::getDebug()) {
cout<< "PvaClientProcess::channelStateChange"
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
<< " isConnected " << (isConnected ? "true" : "false")
<< endl;
}
if(isConnected)
{
connectState = connectActive;
channelProcess = pvaClientChannel->getChannel()->createChannelProcess(channelProcessRequester,pvRequest);
}
PvaClientChannelStateChangeRequesterPtr req(pvaClientChannelStateChangeRequester.lock());
if(req) {
req->channelStateChange(pvaClientChannel,isConnected);
}
}
void PvaClientProcess::checkProcessState()
{
if(PvaClient::getDebug()) {
cout << "PvaClientProcess::checkProcessState"
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
<< endl;
}
if(!pvaClientChannel->getChannel()->isConnected()) {
string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName()
+ " PvaClientProcess::checkProcessState channel not connected ";
throw std::runtime_error(message);
}
if(connectState==connectIdle) {
connect();
}
if(connectState==connectActive){
string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName()
+ " "
+ channelProcessConnectStatus.getMessage();
throw std::runtime_error(message);
}
if(processState==processIdle) process();
}
// from ChannelProcessRequester // from ChannelProcessRequester
string PvaClientProcess::getRequesterName() string PvaClientProcess::getRequesterName()
{ {
@@ -255,6 +210,7 @@ void PvaClientProcess::issueConnect()
throw std::runtime_error(message); throw std::runtime_error(message);
} }
connectState = connectActive; connectState = connectActive;
channelProcessConnectStatus = Status(Status::STATUSTYPE_ERROR, "connect active");
channelProcess = pvaClientChannel->getChannel()->createChannelProcess(channelProcessRequester,pvRequest); channelProcess = pvaClientChannel->getChannel()->createChannelProcess(channelProcessRequester,pvRequest);
} }
@@ -302,7 +258,7 @@ void PvaClientProcess::issueProcess()
<< endl; << endl;
} }
if(connectState==connectIdle) connect(); if(connectState==connectIdle) connect();
if(processState!=processIdle) { if(processState==processActive) {
string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName() string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName()
+ " PvaClientProcess::issueProcess process aleady active "; + " PvaClientProcess::issueProcess process aleady active ";
throw std::runtime_error(message); throw std::runtime_error(message);
+38 -43
View File
@@ -15,7 +15,6 @@
#include <pv/pvaClient.h> #include <pv/pvaClient.h>
using std::tr1::static_pointer_cast;
using namespace epics::pvData; using namespace epics::pvData;
using namespace epics::pvAccess; using namespace epics::pvAccess;
using namespace std; using namespace std;
@@ -118,29 +117,11 @@ PvaClientPut::~PvaClientPut()
} }
} }
void PvaClientPut::channelStateChange(PvaClientChannelPtr const & pvaClientChannel, bool isConnected)
{
if(PvaClient::getDebug()) {
cout<< "PvaClientPut::channelStateChange"
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
<< " isConnected " << (isConnected ? "true" : "false")
<< endl;
}
if(isConnected&&!channelPut)
{
connectState = connectActive;
channelPut = pvaClientChannel->getChannel()->createChannelPut(channelPutRequester,pvRequest);
}
PvaClientChannelStateChangeRequesterPtr req(pvaClientChannelStateChangeRequester.lock());
if(req) {
req->channelStateChange(pvaClientChannel,isConnected);
}
}
void PvaClientPut::checkPutState() void PvaClientPut::checkConnectState()
{ {
if(PvaClient::getDebug()) { if(PvaClient::getDebug()) {
cout << "PvaClientPut::checkPutState" cout << "PvaClientPut::checkConnectState"
<< " channelName " << pvaClientChannel->getChannel()->getChannelName() << " channelName " << pvaClientChannel->getChannel()->getChannelName()
<< endl; << endl;
} }
@@ -217,13 +198,17 @@ void PvaClientPut::getDone(
<< " status.isOK " << (status.isOK() ? "true" : "false") << " status.isOK " << (status.isOK() ? "true" : "false")
<< endl; << endl;
} }
channelGetPutStatus = status; {
if(status.isOK()) { Lock xx(mutex);
PVStructurePtr pvs = pvaClientData->getPVStructure(); channelGetPutStatus = status;
pvs->copyUnchecked(*pvStructure,*bitSet); if(status.isOK()) {
BitSetPtr bs = pvaClientData->getChangedBitSet(); PVStructurePtr pvs = pvaClientData->getPVStructure();
bs->clear(); pvs->copyUnchecked(*pvStructure,*bitSet);
*bs |= *bitSet; BitSetPtr bs = pvaClientData->getChangedBitSet();
bs->clear();
*bs |= *bitSet;
putState = putComplete;
}
} }
PvaClientPutRequesterPtr req(pvaClientPutRequester.lock()); PvaClientPutRequesterPtr req(pvaClientPutRequester.lock());
if(req) { if(req) {
@@ -242,7 +227,11 @@ void PvaClientPut::putDone(
<< " status.isOK " << (status.isOK() ? "true" : "false") << " status.isOK " << (status.isOK() ? "true" : "false")
<< endl; << endl;
} }
channelGetPutStatus = status; {
Lock xx(mutex);
channelGetPutStatus = status;
putState = putComplete;
}
PvaClientPutRequesterPtr req(pvaClientPutRequester.lock()); PvaClientPutRequesterPtr req(pvaClientPutRequester.lock());
if(req) { if(req) {
req->putDone(status,shared_from_this()); req->putDone(status,shared_from_this());
@@ -351,14 +340,17 @@ Status PvaClientPut::waitGet()
<< " channelName " << pvaClientChannel->getChannel()->getChannelName() << " channelName " << pvaClientChannel->getChannel()->getChannelName()
<< endl; << endl;
} }
if(putState!=getActive){ {
string message = string("channel ") Lock xx(mutex);
+ pvaClientChannel->getChannel()->getChannelName() if(putState==putComplete) return channelGetPutStatus;
+ " PvaClientPut::waitGet illegal put state"; if(putState!=getActive){
throw std::runtime_error(message); string message = string("channel ")
+ pvaClientChannel->getChannel()->getChannelName()
+ " PvaClientPut::waitGet illegal put state";
throw std::runtime_error(message);
}
} }
waitForGetPut.wait(); waitForGetPut.wait();
putState = putComplete;
return channelGetPutStatus; return channelGetPutStatus;
} }
@@ -392,7 +384,7 @@ void PvaClientPut::issuePut()
if(putState==getActive || putState==putActive) { if(putState==getActive || putState==putActive) {
string message = string("channel ") string message = string("channel ")
+ pvaClientChannel->getChannel()->getChannelName() + pvaClientChannel->getChannel()->getChannelName()
+ "PvaClientPut::issueGet get or put aleady active "; + "PvaClientPut::issuePut get or put aleady active ";
throw std::runtime_error(message); throw std::runtime_error(message);
} }
putState = putActive; putState = putActive;
@@ -406,14 +398,17 @@ Status PvaClientPut::waitPut()
<< " channelName " << pvaClientChannel->getChannel()->getChannelName() << " channelName " << pvaClientChannel->getChannel()->getChannelName()
<< endl; << endl;
} }
if(putState!=putActive){ {
string message = string("channel ") Lock xx(mutex);
+ pvaClientChannel->getChannel()->getChannelName() if(putState==putComplete) return channelGetPutStatus;
+ " PvaClientPut::waitPut illegal put state"; if(putState!=putActive){
throw std::runtime_error(message); string message = string("channel ")
+ pvaClientChannel->getChannel()->getChannelName()
+ " PvaClientPut::waitPut illegal put state";
throw std::runtime_error(message);
}
} }
waitForGetPut.wait(); waitForGetPut.wait();
putState = putComplete;
if(channelGetPutStatus.isOK()) pvaClientData->getChangedBitSet()->clear(); if(channelGetPutStatus.isOK()) pvaClientData->getChangedBitSet()->clear();
return channelGetPutStatus; return channelGetPutStatus;
} }
@@ -425,7 +420,7 @@ PvaClientPutDataPtr PvaClientPut::getData()
<< " channelName " << pvaClientChannel->getChannel()->getChannelName() << " channelName " << pvaClientChannel->getChannel()->getChannelName()
<< endl; << endl;
} }
checkPutState(); checkConnectState();
if(putState==putIdle) get(); if(putState==putIdle) get();
return pvaClientData; return pvaClientData;
} }
+151 -168
View File
@@ -25,6 +25,10 @@ using namespace epics::pvAccess;
using namespace std; using namespace std;
namespace epics { namespace pvaClient { namespace epics { namespace pvaClient {
static ConvertPtr convert = getConvert();
static string notCompatibleScalar("value is not a compatible scalar");
static string notDoubleArray("value is not a doubleArray");
static string notStringArray("value is not a stringArray");
class PvaClientPostHandlerPvt: public PostHandler class PvaClientPostHandlerPvt: public PostHandler
{ {
@@ -36,28 +40,21 @@ public:
void postPut() { putData->postPut(fieldNumber);} void postPut() { putData->postPut(fieldNumber);}
}; };
typedef std::tr1::shared_ptr<PVArray> PVArrayPtr;
static ConvertPtr convert = getConvert();
static string noValue("no value field");
static string notScalar("value is not a scalar");
static string notCompatibleScalar("value is not a compatible scalar");
static string notArray("value is not an array");
static string notScalarArray("value is not a scalarArray");
static string notDoubleArray("value is not a doubleArray");
static string notStringArray("value is not a stringArray");
PvaClientPutDataPtr PvaClientPutData::create(StructureConstPtr const & structure) PvaClientPutDataPtr PvaClientPutData::create(StructureConstPtr const & structure)
{ {
if(PvaClient::getDebug()) cout << "PvaClientPutData::create\n";
PvaClientPutDataPtr epv(new PvaClientPutData(structure)); PvaClientPutDataPtr epv(new PvaClientPutData(structure));
return epv; return epv;
} }
PvaClientPutData::PvaClientPutData(StructureConstPtr const & structure) PvaClientPutData::PvaClientPutData(StructureConstPtr const & structure)
: structure(structure), : PvaClientData(structure)
pvStructure(getPVDataCreate()->createPVStructure(structure)),
bitSet(BitSetPtr(new BitSet(pvStructure->getNumberFields())))
{ {
messagePrefix = ""; if(PvaClient::getDebug()) cout << "PvaClientPutData::PvaClientPutData\n";
PVStructurePtr pvStructure(getPVDataCreate()->createPVStructure(structure));
BitSetPtr bitSet(BitSetPtr(new BitSet(pvStructure->getNumberFields())));
setData(pvStructure,bitSet);
size_t nfields = pvStructure->getNumberFields(); size_t nfields = pvStructure->getNumberFields();
postHandler.resize(nfields); postHandler.resize(nfields);
PVFieldPtr pvField; PVFieldPtr pvField;
@@ -71,145 +68,40 @@ PvaClientPutData::PvaClientPutData(StructureConstPtr const & structure)
} }
pvField->setPostHandler(postHandler[i]); pvField->setPostHandler(postHandler[i]);
} }
pvValue = pvStructure->getSubField("value");
} }
void PvaClientPutData::checkValue()
{
if(pvValue) return;
throw std::runtime_error(messagePrefix + noValue);
}
void PvaClientPutData::postPut(size_t fieldNumber)
{
bitSet->set(fieldNumber);
}
void PvaClientPutData::setMessagePrefix(std::string const & value)
{
messagePrefix = value + " ";
}
StructureConstPtr PvaClientPutData::getStructure()
{return structure;}
PVStructurePtr PvaClientPutData::getPVStructure()
{return pvStructure;}
BitSetPtr PvaClientPutData::getChangedBitSet()
{return bitSet;}
std::ostream & PvaClientPutData::showChanged(std::ostream & out)
{
size_t nextSet = bitSet->nextSetBit(0);
PVFieldPtr pvField;
while(nextSet!=string::npos) {
if(nextSet==0) {
pvField = pvStructure;
} else {
pvField = pvStructure->getSubField(nextSet);
}
string name = pvField->getFullName();
out << name << " = " << pvField << endl;
nextSet = bitSet->nextSetBit(nextSet+1);
}
return out;
}
bool PvaClientPutData::hasValue()
{
if(!pvValue) return false;
return true;
}
bool PvaClientPutData::isValueScalar()
{
if(!pvValue) return false;
if(pvValue->getField()->getType()==scalar) return true;
return false;
}
bool PvaClientPutData::isValueScalarArray()
{
if(!pvValue) return false;
if(pvValue->getField()->getType()==scalarArray) return true;
return false;
}
PVFieldPtr PvaClientPutData::getValue()
{
checkValue();
return pvValue;
}
PVScalarPtr PvaClientPutData::getScalarValue()
{
checkValue();
PVScalarPtr pv = pvStructure->getSubField<PVScalar>("value");
if(!pv) throw std::runtime_error(messagePrefix + notScalar);
return pv;
}
PVArrayPtr PvaClientPutData::getArrayValue()
{
checkValue();
PVArrayPtr pv = pvStructure->getSubField<PVArray>("value");
if(!pv) throw std::runtime_error(messagePrefix + notArray);
return pv;
}
PVScalarArrayPtr PvaClientPutData::getScalarArrayValue()
{
checkValue();
PVScalarArrayPtr pv = pvStructure->getSubField<PVScalarArray>("value");
if(!pv) throw std::runtime_error(messagePrefix + notScalarArray);
return pv;
}
double PvaClientPutData::getDouble()
{
PVScalarPtr pvScalar = getScalarValue();
ScalarType scalarType = pvScalar->getScalar()->getScalarType();
if(scalarType==pvDouble) {
PVDoublePtr pvDouble = static_pointer_cast<PVDouble>(pvScalar);
return pvDouble->get();
}
if(!ScalarTypeFunc::isNumeric(scalarType)) {
throw std::runtime_error(messagePrefix + notCompatibleScalar);
}
return convert->toDouble(pvScalar);
}
string PvaClientPutData::getString()
{
PVScalarPtr pvScalar = getScalarValue();
return convert->toString(pvScalar);
}
shared_vector<const double> PvaClientPutData::getDoubleArray()
{
checkValue();
PVDoubleArrayPtr pv = pvStructure->getSubField<PVDoubleArray>("value");
if(!pv) {
throw std::runtime_error(messagePrefix + notDoubleArray);
}
return pv->view();
}
shared_vector<const string> PvaClientPutData::getStringArray()
{
checkValue();
PVStringArrayPtr pv = pvStructure->getSubField<PVStringArray>("value");
if(!pv) {
throw std::runtime_error(messagePrefix + notStringArray);
}
return pv->view();
}
void PvaClientPutData::putDouble(double value) void PvaClientPutData::putDouble(double value)
{ {
PVScalarPtr pvScalar = getScalarValue(); if(PvaClient::getDebug()) cout << "PvaClientPutData::putDouble\n";
PVScalarPtr pvScalar;
PVStructurePtr pvStructure = getPVStructure();
PVFieldPtr pvValue = pvStructure->getSubField("value");
if(pvValue) {
Type type = pvValue->getField()->getType();
if(type==scalar) pvScalar = static_pointer_cast<PVScalar>(pvValue);
}
if(!pvScalar) {
while(true) {
const PVFieldPtrArray fieldPtrArray(pvStructure->getPVFields());
if(fieldPtrArray.size()!=1) {
throw std::logic_error(
"PvaClientData::putDouble() pvRequest for multiple fields");
}
PVFieldPtr pvField(fieldPtrArray[0]);
Type type = pvField->getField()->getType();
if(type==scalar) {
pvScalar = static_pointer_cast<PVScalar>(pvField);
break;
}
if(pvField->getField()->getType()!=epics::pvData::structure) break;
pvStructure = static_pointer_cast<PVStructure>(pvField);
}
}
if(!pvScalar) {
throw std::logic_error(
"PvaClientData::putDouble() did not find a scalar field");
}
ScalarType scalarType = pvScalar->getScalar()->getScalarType(); ScalarType scalarType = pvScalar->getScalar()->getScalarType();
if(scalarType==pvDouble) { if(scalarType==pvDouble) {
PVDoublePtr pvDouble = static_pointer_cast<PVDouble>(pvScalar); PVDoublePtr pvDouble = static_pointer_cast<PVDouble>(pvScalar);
@@ -217,47 +109,138 @@ void PvaClientPutData::putDouble(double value)
return; return;
} }
if(!ScalarTypeFunc::isNumeric(scalarType)) { if(!ScalarTypeFunc::isNumeric(scalarType)) {
throw std::runtime_error(messagePrefix + notCompatibleScalar); throw std::logic_error(
"PvaClientData::putDouble() did not find a numeric scalar field");
} }
convert->fromDouble(pvScalar,value); convert->fromDouble(pvScalar,value);
} }
void PvaClientPutData::putString(std::string const & value) void PvaClientPutData::putString(std::string const & value)
{ {
PVScalarPtr pvScalar = getScalarValue(); if(PvaClient::getDebug()) cout << "PvaClientPutData::putString\n";
PVScalarPtr pvScalar;
PVStructurePtr pvStructure = getPVStructure();
PVFieldPtr pvValue = pvStructure->getSubField("value");
if(pvValue) {
Type type = pvValue->getField()->getType();
if(type==scalar) pvScalar = static_pointer_cast<PVScalar>(pvValue);
}
if(!pvScalar) {
while(true) {
const PVFieldPtrArray fieldPtrArray(pvStructure->getPVFields());
if(fieldPtrArray.size()!=1) {
throw std::logic_error(
"PvaClientData::putString() pvRequest for multiple fields");
}
PVFieldPtr pvField(fieldPtrArray[0]);
Type type = pvField->getField()->getType();
if(type==scalar) {
pvScalar = static_pointer_cast<PVScalar>(pvField);
break;
}
if(pvField->getField()->getType()!=epics::pvData::structure) break;
pvStructure = static_pointer_cast<PVStructure>(pvField);
}
}
if(!pvScalar) {
throw std::logic_error(
"PvaClientData::putString() did not find a scalar field");
}
convert->fromString(pvScalar,value); convert->fromString(pvScalar,value);
} }
void PvaClientPutData::putDoubleArray(shared_vector<const double> const & value) void PvaClientPutData::putDoubleArray(shared_vector<const double> const & value)
{ {
checkValue(); if(PvaClient::getDebug()) cout << "PvaClientPutData::putDoubleArray\n";
PVDoubleArrayPtr pv = pvStructure->getSubField<PVDoubleArray>("value"); PVScalarArrayPtr pvScalarArray;
if(!pv) { PVStructurePtr pvStructure = getPVStructure();
throw std::runtime_error(messagePrefix + notDoubleArray); PVFieldPtr pvValue = pvStructure->getSubField("value");
if(pvValue) {
Type type = pvValue->getField()->getType();
if(type==scalarArray) {
pvScalarArray = static_pointer_cast<PVScalarArray>(pvValue);
}
} }
pv->replace(value); if(!pvScalarArray) {
while(true) {
const PVFieldPtrArray fieldPtrArray(pvStructure->getPVFields());
if(fieldPtrArray.size()!=1) {
throw std::logic_error(
"PvaClientData::putDoubleArray() pvRequest for multiple fields");
}
PVFieldPtr pvField(fieldPtrArray[0]);
Type type = pvField->getField()->getType();
if(type==scalarArray) {
PVScalarArrayPtr pvScalarArray = static_pointer_cast<PVScalarArray>(pvField);
break;
}
if(pvField->getField()->getType()!=epics::pvData::structure) break;
pvStructure = static_pointer_cast<PVStructure>(pvField);
}
}
if(!pvScalarArray) {
throw std::logic_error(
"PvaClientData::putDoubleArray() did not find a scalarArray field");
}
ScalarType scalarType = pvScalarArray->getScalarArray()->getElementType();
if(!ScalarTypeFunc::isNumeric(scalarType)) {
throw std::logic_error(
"PvaClientData::putDoubleArray() did not find a numeric scalarArray field");
}
pvScalarArray->putFrom<const double>(value);
} }
void PvaClientPutData::putStringArray(shared_vector<const std::string> const & value) void PvaClientPutData::putStringArray(shared_vector<const std::string> const & value)
{ {
checkValue(); if(PvaClient::getDebug()) cout << "PvaClientPutData::putStringArray\n";
PVStringArrayPtr pv = pvStructure->getSubField<PVStringArray>("value"); PVScalarArrayPtr pvScalarArray;
if(!pv) { PVStructurePtr pvStructure = getPVStructure();
throw std::runtime_error(messagePrefix + notStringArray); PVFieldPtr pvValue = pvStructure->getSubField("value");
if(pvValue) {
Type type = pvValue->getField()->getType();
if(type==scalarArray) {
pvScalarArray = static_pointer_cast<PVScalarArray>(pvValue);
}
} }
pv->replace(value); if(!pvScalarArray) {
while(true) {
const PVFieldPtrArray fieldPtrArray(pvStructure->getPVFields());
if(fieldPtrArray.size()!=1) {
throw std::logic_error(
"PvaClientData::putStringArray() pvRequest for multiple fields");
}
PVFieldPtr pvField(fieldPtrArray[0]);
Type type = pvField->getField()->getType();
if(type==scalarArray) {
pvScalarArray = static_pointer_cast<PVScalarArray>(pvField);
break;
}
if(pvField->getField()->getType()!=epics::pvData::structure) break;
pvStructure = static_pointer_cast<PVStructure>(pvField);
}
}
if(!pvScalarArray) {
throw std::logic_error(
"PvaClientData::putStringArray() did not find a scalarArray field");
}
pvScalarArray->putFrom<const string>(value);
return;
} }
void PvaClientPutData::putStringArray(std::vector<std::string> const & value) void PvaClientPutData::putStringArray(std::vector<string> const & value)
{ {
checkValue(); size_t length = value.size();
PVScalarArrayPtr pv = pvStructure->getSubField<PVScalarArray>("value"); shared_vector<string> val(length);
if(!pv) { for(size_t i=0; i < length; ++i) val[i] = value[i];
throw std::runtime_error(messagePrefix + notScalarArray); putStringArray(freeze(val));
} return;
convert->fromStringArray(pv,0,value.size(),value,0);
} }
void PvaClientPutData::postPut(size_t fieldNumber)
{
if(PvaClient::getDebug()) cout << "PvaClientPutData::postPut\n";
getChangedBitSet()->set(fieldNumber);
}
}} }}
+37 -49
View File
@@ -14,7 +14,6 @@
#include <pv/pvaClient.h> #include <pv/pvaClient.h>
using std::tr1::static_pointer_cast;
using namespace epics::pvData; using namespace epics::pvData;
using namespace epics::pvAccess; using namespace epics::pvAccess;
using namespace std; using namespace std;
@@ -131,25 +130,6 @@ PvaClientPutGet::~PvaClientPutGet()
} }
} }
void PvaClientPutGet::channelStateChange(PvaClientChannelPtr const & pvaClientChannel, bool isConnected)
{
if(PvaClient::getDebug()) {
cout<< "PvaClientPutGet::channelStateChange"
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
<< " isConnected " << (isConnected ? "true" : "false")
<< endl;
}
if(isConnected&&!channelPutGet)
{
connectState = connectActive;
channelPutGet = pvaClientChannel->getChannel()->createChannelPutGet(channelPutGetRequester,pvRequest);
}
PvaClientChannelStateChangeRequesterPtr req(pvaClientChannelStateChangeRequester.lock());
if(req) {
req->channelStateChange(pvaClientChannel,isConnected);
}
}
void PvaClientPutGet::checkPutGetState() void PvaClientPutGet::checkPutGetState()
{ {
if(PvaClient::getDebug()) { if(PvaClient::getDebug()) {
@@ -193,7 +173,7 @@ void PvaClientPutGet::channelPutGetConnect(
<< " channelName " << pvaClientChannel->getChannel()->getChannelName() << " channelName " << pvaClientChannel->getChannel()->getChannelName()
<< " status.isOK " << (status.isOK() ? "true" : "false") << " status.isOK " << (status.isOK() ? "true" : "false")
<< endl; << endl;
} }
{ {
Lock xx(mutex); Lock xx(mutex);
this->channelPutGet = channelPutGet; this->channelPutGet = channelPutGet;
@@ -234,13 +214,13 @@ void PvaClientPutGet::putGetDone(
<< " status.isOK " << (status.isOK() ? "true" : "false") << " status.isOK " << (status.isOK() ? "true" : "false")
<< endl; << endl;
} }
channelPutGetStatus = status; {
if(status.isOK()) { Lock xx(mutex);
PVStructurePtr pvs = pvaClientGetData->getPVStructure(); channelPutGetStatus = status;
pvs->copyUnchecked(*getPVStructure,*getChangedBitSet); putGetState = putGetComplete;
BitSetPtr bs = pvaClientGetData->getChangedBitSet(); if(status.isOK()) {
bs->clear(); pvaClientGetData->setData(getPVStructure,getChangedBitSet);
*bs |= *getChangedBitSet; }
} }
PvaClientPutGetRequesterPtr req(pvaClientPutGetRequester.lock()); PvaClientPutGetRequesterPtr req(pvaClientPutGetRequester.lock());
if(req) { if(req) {
@@ -261,13 +241,17 @@ void PvaClientPutGet::getPutDone(
<< " status.isOK " << (status.isOK() ? "true" : "false") << " status.isOK " << (status.isOK() ? "true" : "false")
<< endl; << endl;
} }
channelPutGetStatus = status; {
if(status.isOK()) { Lock xx(mutex);
PVStructurePtr pvs = pvaClientPutData->getPVStructure(); channelPutGetStatus = status;
pvs->copyUnchecked(*putPVStructure,*putBitSet); putGetState = putGetComplete;
BitSetPtr bs = pvaClientPutData->getChangedBitSet(); if(status.isOK()) {
bs->clear(); PVStructurePtr pvs = pvaClientPutData->getPVStructure();
*bs |= *putBitSet; pvs->copyUnchecked(*putPVStructure,*putBitSet);
BitSetPtr bs = pvaClientPutData->getChangedBitSet();
bs->clear();
*bs |= *putBitSet;
}
} }
PvaClientPutGetRequesterPtr req(pvaClientPutGetRequester.lock()); PvaClientPutGetRequesterPtr req(pvaClientPutGetRequester.lock());
if(req) { if(req) {
@@ -288,13 +272,13 @@ void PvaClientPutGet::getGetDone(
<< " status.isOK " << (status.isOK() ? "true" : "false") << " status.isOK " << (status.isOK() ? "true" : "false")
<< endl; << endl;
} }
channelPutGetStatus = status; {
if(status.isOK()) { Lock xx(mutex);
PVStructurePtr pvs = pvaClientGetData->getPVStructure(); channelPutGetStatus = status;
pvs->copyUnchecked(*getPVStructure,*getChangedBitSet); putGetState = putGetComplete;
BitSetPtr bs = pvaClientGetData->getChangedBitSet(); if(status.isOK()) {
bs->clear(); pvaClientGetData->setData(getPVStructure,getChangedBitSet);
*bs |= *getChangedBitSet; }
} }
PvaClientPutGetRequesterPtr req(pvaClientPutGetRequester.lock()); PvaClientPutGetRequesterPtr req(pvaClientPutGetRequester.lock());
if(req) { if(req) {
@@ -407,6 +391,7 @@ Status PvaClientPutGet::waitPutGet()
<< " channelName " << pvaClientChannel->getChannel()->getChannelName() << " channelName " << pvaClientChannel->getChannel()->getChannelName()
<< endl; << endl;
} }
if(putGetState==putGetComplete) return channelPutGetStatus;
if(putGetState!=putGetActive){ if(putGetState!=putGetActive){
string message = string("channel ") string message = string("channel ")
+ pvaClientChannel->getChannel()->getChannelName() + pvaClientChannel->getChannel()->getChannelName()
@@ -414,7 +399,6 @@ Status PvaClientPutGet::waitPutGet()
throw std::runtime_error(message); throw std::runtime_error(message);
} }
waitForPutGet.wait(); waitForPutGet.wait();
putGetState = putGetComplete;
if(channelPutGetStatus.isOK()) pvaClientPutData->getChangedBitSet()->clear(); if(channelPutGetStatus.isOK()) pvaClientPutData->getChangedBitSet()->clear();
return channelPutGetStatus; return channelPutGetStatus;
} }
@@ -461,6 +445,7 @@ Status PvaClientPutGet::waitGetGet()
<< " channelName " << pvaClientChannel->getChannel()->getChannelName() << " channelName " << pvaClientChannel->getChannel()->getChannelName()
<< endl; << endl;
} }
if(putGetState==putGetComplete) return channelPutGetStatus;
if(putGetState!=putGetActive){ if(putGetState!=putGetActive){
string message = string("channel ") string message = string("channel ")
+ pvaClientChannel->getChannel()->getChannelName() + pvaClientChannel->getChannel()->getChannelName()
@@ -468,7 +453,6 @@ Status PvaClientPutGet::waitGetGet()
throw std::runtime_error(message); throw std::runtime_error(message);
} }
waitForPutGet.wait(); waitForPutGet.wait();
putGetState = putGetComplete;
return channelPutGetStatus; return channelPutGetStatus;
} }
@@ -514,6 +498,7 @@ Status PvaClientPutGet::waitGetPut()
<< " channelName " << pvaClientChannel->getChannel()->getChannelName() << " channelName " << pvaClientChannel->getChannel()->getChannelName()
<< endl; << endl;
} }
if(putGetState==putGetComplete) return channelPutGetStatus;
if(putGetState!=putGetActive){ if(putGetState!=putGetActive){
string message = string("channel ") string message = string("channel ")
+ pvaClientChannel->getChannel()->getChannelName() + pvaClientChannel->getChannel()->getChannelName()
@@ -521,7 +506,6 @@ Status PvaClientPutGet::waitGetPut()
throw std::runtime_error(message); throw std::runtime_error(message);
} }
waitForPutGet.wait(); waitForPutGet.wait();
putGetState = putGetComplete;
return channelPutGetStatus; return channelPutGetStatus;
} }
@@ -533,7 +517,10 @@ PvaClientGetDataPtr PvaClientPutGet::getGetData()
<< endl; << endl;
} }
checkPutGetState(); checkPutGetState();
if(putGetState==putGetIdle) getGet(); if(putGetState==putGetIdle){
getGet();
getPut();
}
return pvaClientGetData; return pvaClientGetData;
} }
@@ -545,7 +532,10 @@ PvaClientPutDataPtr PvaClientPutGet::getPutData()
<< endl; << endl;
} }
checkPutGetState(); checkPutGetState();
if(putGetState==putGetIdle) getPut(); if(putGetState==putGetIdle){
getGet();
getPut();
}
return pvaClientPutData; return pvaClientPutData;
} }
@@ -565,6 +555,4 @@ PvaClientChannelPtr PvaClientPutGet::getPvaClientChannel()
return pvaClientChannel; return pvaClientChannel;
} }
}} }}
-2
View File
@@ -17,8 +17,6 @@
#include <pv/pvaClient.h> #include <pv/pvaClient.h>
using std::tr1::static_pointer_cast;
using std::tr1::dynamic_pointer_cast;
using namespace epics::pvData; using namespace epics::pvData;
using namespace epics::pvAccess; using namespace epics::pvAccess;
using namespace std; using namespace std;