Compare commits
88 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| aba40922e6 | |||
| 2c1cb03cd0 | |||
| 4c56116827 | |||
| 81f5e25276 | |||
| 703b2224ce | |||
| ed0b1cbf08 | |||
| 914e382dea | |||
| fd77d35b20 | |||
| 428adb270e | |||
| 3111e90de8 | |||
| 365a0b846f | |||
| 440c8fa496 | |||
| 150ac45de3 | |||
| fb6f4355f3 | |||
| 0bb17d5b09 | |||
| 00103f8207 | |||
| 522a050945 | |||
| 99a7e3b0b5 | |||
| 763c41caa3 | |||
| 9ffeffd23f | |||
| 3f6d93b22f | |||
| d650865a6f | |||
| b1c101578b | |||
| 8ab4dd1fdb | |||
| 5242540725 | |||
| a8f296ceb3 | |||
| 6633d4f21e | |||
| 8745dd03b3 | |||
| cfc3c9b998 | |||
| d57893b566 | |||
| b7ea0fe59a | |||
| 4e4554af4e | |||
| d6d5bcf771 | |||
| 6bcc036c71 | |||
| a405dd7bdb | |||
| 22e260351c | |||
| 5a5b8f809d | |||
| 9d5f06c11d | |||
| 28a23dc5a8 | |||
| dcda03c9fc | |||
| b5291d9619 | |||
| 74d381e68c | |||
| c789406f0b | |||
| a21e5b5913 | |||
| cb374fcefa | |||
| 90b2bdc162 | |||
| ea5809be9b | |||
| 0fb4612680 | |||
| 5a84b94520 | |||
| 411560ea8d | |||
| 3e9645c883 | |||
| 25b621890b | |||
| fe15b9dd09 | |||
| 64fc25c240 | |||
| c9e7bc32bd | |||
| ab4c69301f | |||
| 5b9b84f7d0 | |||
| dd65681630 | |||
| e11cc25dd7 | |||
| 05a454fa69 | |||
| b5e9aa6a60 | |||
| 4606d84185 | |||
| 97d9dc2034 | |||
| e1d50000d4 | |||
| 878cc27aa7 | |||
| 5c99282ee2 | |||
| 3b344fdb25 | |||
| 932d90ff70 | |||
| d7bf6a8910 | |||
| 9b1539f368 | |||
| 8c7506449b | |||
| 609c887c19 | |||
| 8f6cc08f85 | |||
| ae49f8ad99 | |||
| 696c251ecc | |||
| 594d8dd19f | |||
| d8ab89e96a | |||
| 9712f001c8 | |||
| 91e6392e77 | |||
| 094336b5e0 | |||
| f0efef68ea | |||
| 0912756a2e | |||
| e071e0f9e3 | |||
| 619bacc0f4 | |||
| 7fd5af9e3c | |||
| 6762c54e60 | |||
| 63947e1c3c | |||
| c019b205dd |
Executable
+10
@@ -0,0 +1,10 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
set -e -x
|
||||||
|
|
||||||
|
make -j2 $EXTRA
|
||||||
|
|
||||||
|
if [ "$TEST" != "NO" ]
|
||||||
|
then
|
||||||
|
make -j2 tapfiles
|
||||||
|
make -j2 -s test-results
|
||||||
|
fi
|
||||||
Executable
+111
@@ -0,0 +1,111 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
set -e -x
|
||||||
|
|
||||||
|
CURDIR="$PWD"
|
||||||
|
|
||||||
|
cat << EOF > $CURDIR/configure/RELEASE.local
|
||||||
|
EPICS_BASE=$HOME/.source/epics-base
|
||||||
|
EOF
|
||||||
|
|
||||||
|
install -d "$HOME/.source"
|
||||||
|
cd "$HOME/.source"
|
||||||
|
|
||||||
|
add_gh_flat() {
|
||||||
|
MODULE=$1
|
||||||
|
REPOOWNER=$2
|
||||||
|
REPONAME=$3
|
||||||
|
BRANCH=$4
|
||||||
|
MODULE_UC=$(echo $MODULE | tr 'a-z' 'A-Z')
|
||||||
|
( git clone --quiet --depth 5 --branch $BRANCH https://github.com/$REPOOWNER/$REPONAME.git $MODULE && \
|
||||||
|
cd $MODULE && git log -n1 )
|
||||||
|
cat < $CURDIR/configure/RELEASE.local > $MODULE/configure/RELEASE.local
|
||||||
|
cat << EOF >> $CURDIR/configure/RELEASE.local
|
||||||
|
${MODULE_UC}=$HOME/.source/$MODULE
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
# not recursive
|
||||||
|
git clone --quiet --depth 5 --branch "$BRBASE" https://github.com/${REPOBASE:-epics-base}/epics-base.git epics-base
|
||||||
|
(cd epics-base && git log -n1 )
|
||||||
|
add_gh_flat pvData ${REPOPVD:-epics-base} pvDataCPP ${BRPVD:-master}
|
||||||
|
add_gh_flat pvAccess ${REPOPVA:-epics-base} pvAccessCPP ${BRPVA:-master}
|
||||||
|
add_gh_flat normativeTypes ${REPONT:-epics-base} normativeTypesCPP ${BRNT:-master}
|
||||||
|
|
||||||
|
if [ -e $CURDIR/configure/RELEASE.local ]
|
||||||
|
then
|
||||||
|
cat $CURDIR/configure/RELEASE.local
|
||||||
|
fi
|
||||||
|
|
||||||
|
EPICS_HOST_ARCH=`sh epics-base/startup/EpicsHostArch`
|
||||||
|
|
||||||
|
# requires wine and g++-mingw-w64-i686
|
||||||
|
if [ "$WINE" = "32" ]
|
||||||
|
then
|
||||||
|
echo "Cross mingw32"
|
||||||
|
sed -i -e '/CMPLR_PREFIX/d' epics-base/configure/os/CONFIG_SITE.linux-x86.win32-x86-mingw
|
||||||
|
cat << EOF >> epics-base/configure/os/CONFIG_SITE.linux-x86.win32-x86-mingw
|
||||||
|
CMPLR_PREFIX=i686-w64-mingw32-
|
||||||
|
EOF
|
||||||
|
cat << EOF >> epics-base/configure/CONFIG_SITE
|
||||||
|
CROSS_COMPILER_TARGET_ARCHS+=win32-x86-mingw
|
||||||
|
EOF
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$STATIC" = "YES" ]
|
||||||
|
then
|
||||||
|
echo "Build static libraries/executables"
|
||||||
|
cat << EOF >> epics-base/configure/CONFIG_SITE
|
||||||
|
SHARED_LIBRARIES=NO
|
||||||
|
STATIC_BUILD=YES
|
||||||
|
EOF
|
||||||
|
fi
|
||||||
|
|
||||||
|
case "$CMPLR" in
|
||||||
|
clang)
|
||||||
|
echo "Host compiler is clang"
|
||||||
|
cat << EOF >> epics-base/configure/os/CONFIG_SITE.Common.$EPICS_HOST_ARCH
|
||||||
|
GNU = NO
|
||||||
|
CMPLR_CLASS = clang
|
||||||
|
CC = clang
|
||||||
|
CCC = clang++
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# hack
|
||||||
|
sed -i -e 's/CMPLR_CLASS = gcc/CMPLR_CLASS = clang/' epics-base/configure/CONFIG.gnuCommon
|
||||||
|
|
||||||
|
clang --version
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "Host compiler is default"
|
||||||
|
gcc --version
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
cat <<EOF >> epics-base/configure/CONFIG_SITE
|
||||||
|
USR_CPPFLAGS += $USR_CPPFLAGS
|
||||||
|
USR_CFLAGS += $USR_CFLAGS
|
||||||
|
USR_CXXFLAGS += $USR_CXXFLAGS
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# set RTEMS to eg. "4.9" or "4.10"
|
||||||
|
# requires qemu, bison, flex, texinfo, install-info
|
||||||
|
if [ -n "$RTEMS" ]
|
||||||
|
then
|
||||||
|
echo "Cross RTEMS${RTEMS} for pc386"
|
||||||
|
curl -L "https://github.com/mdavidsaver/rsb/releases/download/20171203-${RTEMS}/i386-rtems${RTEMS}-trusty-20171203-${RTEMS}.tar.bz2" \
|
||||||
|
| tar -C / -xmj
|
||||||
|
|
||||||
|
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
|
||||||
|
RTEMS_VERSION=$RTEMS
|
||||||
|
RTEMS_BASE=$HOME/.rtems
|
||||||
|
EOF
|
||||||
|
cat << EOF >> epics-base/configure/CONFIG_SITE
|
||||||
|
CROSS_COMPILER_TARGET_ARCHS += RTEMS-pc386-qemu
|
||||||
|
EOF
|
||||||
|
fi
|
||||||
|
|
||||||
|
make -j2 -C epics-base $EXTRA
|
||||||
|
make -j2 -C pvData $EXTRA
|
||||||
|
make -j2 -C normativeTypes $EXTRA
|
||||||
|
make -j2 -C pvAccess $EXTRA
|
||||||
+16
-12
@@ -1,13 +1,17 @@
|
|||||||
bin/
|
/cfg/
|
||||||
lib/
|
/bin/
|
||||||
doc/
|
/lib/
|
||||||
include/
|
/db/
|
||||||
db/
|
/dbd/
|
||||||
dbd/
|
/html/
|
||||||
documentation/html
|
/include/
|
||||||
documentation/*.tag
|
/templates/
|
||||||
|
/configure/*.local
|
||||||
|
/documentation/html
|
||||||
|
/documentation/*.tag
|
||||||
|
O.*/
|
||||||
|
/QtC-*
|
||||||
envPaths
|
envPaths
|
||||||
configure/*.local
|
*.orig
|
||||||
!configure/ExampleRELEASE.local
|
*.log
|
||||||
**/O.*
|
.*.swp
|
||||||
QtC-*
|
|
||||||
|
|||||||
+31
@@ -0,0 +1,31 @@
|
|||||||
|
sudo: false
|
||||||
|
dist: trusty
|
||||||
|
language: c++
|
||||||
|
compiler:
|
||||||
|
- gcc
|
||||||
|
addons:
|
||||||
|
apt:
|
||||||
|
packages:
|
||||||
|
- libreadline6-dev
|
||||||
|
- libncurses5-dev
|
||||||
|
- perl
|
||||||
|
- clang
|
||||||
|
- g++-mingw-w64-i686
|
||||||
|
- qemu-system-x86
|
||||||
|
install:
|
||||||
|
- ./.ci/travis-prepare.sh
|
||||||
|
script:
|
||||||
|
- ./.ci/travis-build.sh
|
||||||
|
env:
|
||||||
|
- BRBASE=7.0
|
||||||
|
- BRBASE=7.0 CMPLR=clang
|
||||||
|
- BRBASE=7.0 EXTRA="CMD_CXXFLAGS=-std=c++98"
|
||||||
|
- BRBASE=7.0 EXTRA="CMD_CXXFLAGS=-std=c++11"
|
||||||
|
- BRBASE=7.0 CMPLR=clang EXTRA="CMD_CXXFLAGS=-std=c++11"
|
||||||
|
- BRBASE=7.0 WINE=32 TEST=NO STATIC=YES
|
||||||
|
- BRBASE=7.0 WINE=32 TEST=NO STATIC=NO
|
||||||
|
- BRBASE=7.0 RTEMS=4.10 TEST=NO
|
||||||
|
- BRBASE=7.0 RTEMS=4.9 TEST=NO
|
||||||
|
- BRBASE=3.16
|
||||||
|
- BRBASE=3.15
|
||||||
|
- BRBASE=3.14
|
||||||
@@ -1,49 +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:
|
This module is included as a submodule of a full EPICS 7 release and will be compiled during builds of that software.
|
||||||
|
|
||||||
cp configure/ExampleRELEASE.local configure/RELEASE.local
|
|
||||||
edit configure/RELEASE.local
|
|
||||||
make
|
|
||||||
|
|
||||||
|
|
||||||
Examples
|
|
||||||
------------
|
|
||||||
|
|
||||||
Project exampleCPP has examples for pvaClientCPP
|
|
||||||
|
|
||||||
Status
|
|
||||||
------
|
|
||||||
|
|
||||||
* The API is for EPICS Version 4 release 4.6.0
|
|
||||||
* Everything defined in pvaClient.h is ready but see below for remaining work.
|
|
||||||
* Everything defined in pvaClientMultiChannel.h is ready but see below for remaining work.
|
|
||||||
|
|
||||||
|
|
||||||
pvaClientChannel
|
|
||||||
---------------
|
|
||||||
|
|
||||||
Channel::getField and channelArray are not supported for release 4.6
|
|
||||||
|
|
||||||
pvaClientMultiChannel
|
|
||||||
---------------
|
|
||||||
|
|
||||||
For release 4.5 support is available for multiDouble and NTMultiChannel.
|
|
||||||
In the future additional support should be provided that at least includes NTScalarMultiChannel.
|
|
||||||
|
|
||||||
Testing with some channels not connected has not been done.
|
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
EPICS_PVACLIENT_MAJOR_VERSION = 4
|
||||||
|
EPICS_PVACLIENT_MINOR_VERSION = 6
|
||||||
|
EPICS_PVACLIENT_MAINTENANCE_VERSION = 0
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
EPICS4_DIR=/home/epicsv4/master
|
|
||||||
PVACCESS=${EPICS4_DIR}/pvAccessCPP
|
|
||||||
NORMATIVETYPES=${EPICS4_DIR}/normativeTypesCPP
|
|
||||||
PVDATA=${EPICS4_DIR}/pvDataCPP
|
|
||||||
PVCOMMON=${EPICS4_DIR}/pvCommonCPP
|
|
||||||
|
|
||||||
TEMPLATE_TOP=$(EPICS_BASE)/templates/makeBaseApp/top
|
|
||||||
EPICS_BASE=/home/install/epics/base
|
|
||||||
@@ -2,6 +2,8 @@ TOP=..
|
|||||||
|
|
||||||
include $(TOP)/configure/CONFIG
|
include $(TOP)/configure/CONFIG
|
||||||
|
|
||||||
|
CFG += CONFIG_PVACLIENT_VERSION
|
||||||
|
|
||||||
TARGETS = $(CONFIG_TARGETS)
|
TARGETS = $(CONFIG_TARGETS)
|
||||||
CONFIGS += $(subst ../,,$(wildcard $(CONFIG_INSTALLS)))
|
CONFIGS += $(subst ../,,$(wildcard $(CONFIG_INSTALLS)))
|
||||||
|
|
||||||
|
|||||||
+33
-19
@@ -1,30 +1,44 @@
|
|||||||
# easyPVACPP RELEASE - Location of external support modules
|
# RELEASE - Location of external support modules
|
||||||
#
|
#
|
||||||
# IF YOU CHANGE this file or any file it includes you must
|
# IF YOU CHANGE ANY PATHS in this file or make API changes to
|
||||||
# subsequently do a "gnumake rebuild" in the application's
|
# any modules it refers to, you should do a "make rebuild" in
|
||||||
# top level directory.
|
# this application's top level directory.
|
||||||
#
|
#
|
||||||
# The build process does not check dependencies against files
|
# The EPICS build process does not check dependencies against
|
||||||
# that are outside this application, thus you should also do a
|
# any files from outside the application, so it is safest to
|
||||||
# "gnumake rebuild" in the top level directory after EPICS_BASE
|
# rebuild it completely if any modules it depends on change.
|
||||||
# or any other external module pointed to below is rebuilt.
|
|
||||||
#
|
#
|
||||||
# Host- or target-specific settings can be given in files named
|
# Host- or target-specific settings can be given in files named
|
||||||
# RELEASE.$(EPICS_HOST_ARCH).Common
|
# RELEASE.$(EPICS_HOST_ARCH).Common
|
||||||
# RELEASE.Common.$(T_A)
|
# RELEASE.Common.$(T_A)
|
||||||
# RELEASE.$(EPICS_HOST_ARCH).$(T_A)
|
# RELEASE.$(EPICS_HOST_ARCH).$(T_A)
|
||||||
|
|
||||||
# EPICS V4 Developers: Do not edit the locations in this file!
|
|
||||||
#
|
#
|
||||||
# A RELEASE.local must exist that has the following definitions
|
# This file is parsed by both GNUmake and an EPICS Perl script,
|
||||||
# EPICS_BASE=/home/install/epics/base
|
# so it may ONLY contain definititions of paths to other support
|
||||||
# EPICS4_DIR=/home/epicsv4
|
# modules, variable definitions that are used in module paths,
|
||||||
# PVCOMMON=${EPICS4_DIR}/pvCommonCPP
|
# and include statements that pull in other RELEASE files.
|
||||||
# PVDATA=${EPICS4_DIR}/pvDataCPP
|
# Variables may be used before their values have been set.
|
||||||
# NORMATIVETYPES=${EPICSV4}/normativeTypesCPP
|
# Build variables that are NOT used in paths should be set in
|
||||||
# PVACCESS=${EPICS4_DIR}/pvAccessCPP
|
# the CONFIG_SITE file.
|
||||||
#Either create a RELEASE.local one level above the TOP for this module
|
|
||||||
#OR copy ExampleRELEASE.local to RELEASE.local and edit it.
|
|
||||||
|
|
||||||
|
# Variables and paths to dependent modules:
|
||||||
|
#MODULES = /path/to/modules
|
||||||
|
#MYMODULE = $(MODULES)/my-module
|
||||||
|
|
||||||
|
# If building the EPICS modules individually, set these:
|
||||||
|
#EPICS_PVACCESS = $(MODULES)/pvAccess
|
||||||
|
#EPICS_NORMATIVETYPES = $(MODULES)/normativeTypes
|
||||||
|
#EPICS_PVDATA = $(MODULES)/pvData
|
||||||
|
#EPICS_DATABASE = $(MODULES)/database
|
||||||
|
#EPICS_CA = $(MODULES)/ca
|
||||||
|
#EPICS_LIBCOM = $(MODULES)/libcom
|
||||||
|
#EPICS_BASE = $(MODULES)/core
|
||||||
|
|
||||||
|
# Set RULES here if you want to use build rules from elsewhere:
|
||||||
|
#RULES = $(MODULES)/build-rules
|
||||||
|
|
||||||
|
# These allow developers to override the RELEASE variable settings
|
||||||
|
# without having to modify the configure/RELEASE file itself.
|
||||||
-include $(TOP)/../RELEASE.local
|
-include $(TOP)/../RELEASE.local
|
||||||
|
-include $(TOP)/../RELEASE.$(EPICS_HOST_ARCH).local
|
||||||
-include $(TOP)/configure/RELEASE.local
|
-include $(TOP)/configure/RELEASE.local
|
||||||
|
|||||||
@@ -1,19 +1,100 @@
|
|||||||
EPICS V4 release 4.6
|
# pvaClientCPP Module
|
||||||
==========================
|
|
||||||
|
This document summarizes the changes to the module between releases.
|
||||||
|
|
||||||
|
## Release 4.6.0 (EPICS 7.0.3, Jul 2019)
|
||||||
|
|
||||||
|
* pvaClient now handles exceptions from the server properly (issue #54).
|
||||||
|
* MultiChannel classes now properly handle PV structures that don't have a top-level `value` field (issue #56), and are more tolerant of other missing fields (issue #57).
|
||||||
|
|
||||||
|
|
||||||
|
## Release 4.5.0 (EPICS 7.0.2.2, Apr 2019)
|
||||||
|
|
||||||
|
Changes have been made for getDouble, putDouble, getDoubleArray, putDoubleArray, getString, putString, getStringArray, and putStringArray.
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
static PvaClientMonitorPtr create(
|
||||||
|
PvaClientPtr const &pvaClient,
|
||||||
|
epics::pvAccess::Channel::shared_pointer const & channel,
|
||||||
|
epics::pvData::PVStructurePtr const &pvRequest
|
||||||
|
);
|
||||||
|
|
||||||
|
is now changed to
|
||||||
|
|
||||||
|
static PvaClientMonitorPtr create(
|
||||||
|
PvaClientPtr const &pvaClient,
|
||||||
|
PvaClientChannelPtr const & pvaClientChannel,
|
||||||
|
epics::pvData::PVStructurePtr const &pvRequest
|
||||||
|
);
|
||||||
|
|
||||||
|
A new method is also implemented
|
||||||
|
|
||||||
|
static PvaClientMonitorPtr create(
|
||||||
|
PvaClientPtr const &pvaClient,
|
||||||
|
std::string const & channelName,
|
||||||
|
std::string const & providerName,
|
||||||
|
std::string const & request,
|
||||||
|
PvaClientChannelStateChangeRequesterPtr const & stateChangeRequester,
|
||||||
|
PvaClientMonitorRequesterPtr const & monitorRequester
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
## 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)
|
||||||
EPICS V4 release 4.5
|
|
||||||
==========================
|
|
||||||
|
|
||||||
|
|
||||||
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.
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
NOT FOR DIRECT USE
|
||||||
|
==================
|
||||||
|
|
||||||
|
This directory holds files that are used by doxygen.
|
||||||
|
The files are not meant to be read except via the doxygen documention.
|
||||||
@@ -0,0 +1,146 @@
|
|||||||
|
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||||
|
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
|
||||||
|
<title>PvaClient</title>
|
||||||
|
<link rel="stylesheet" type="text/css"
|
||||||
|
href="http://epics-pvdata.sourceforge.net/base.css" />
|
||||||
|
<link rel="stylesheet" type="text/css"
|
||||||
|
href="http://epics-pvdata.sourceforge.net/epicsv4.css" />
|
||||||
|
<style type="text/css">
|
||||||
|
/*<![CDATA[*/
|
||||||
|
.about { margin-left: 3em; margin-right: 3em; font-size: .83em}
|
||||||
|
table { margin-left: auto; margin-right: auto }
|
||||||
|
.diagram { text-align: center; margin: 2.5em 0 }
|
||||||
|
span.opt { color: grey }
|
||||||
|
span.nterm { font-style:italic }
|
||||||
|
span.term { font-family:courier }
|
||||||
|
span.user { font-family:courier }
|
||||||
|
span.user:before { content:"<" }
|
||||||
|
span.user:after { content:">" }
|
||||||
|
.nonnorm { font-style:italic }
|
||||||
|
p.ed { color: #AA0000 }
|
||||||
|
span.ed { color: #AA0000 }
|
||||||
|
p.ed.priv { display: inline; }
|
||||||
|
span.ed.priv { display: inline; }
|
||||||
|
/*]]>*/</style>
|
||||||
|
<!-- Script that generates the Table of Contents -->
|
||||||
|
<script type="text/javascript"
|
||||||
|
src="http://epics-pvdata.sourceforge.net/script/tocgen.js">
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<h1>PvaClient</h1>
|
||||||
|
|
||||||
|
|
||||||
|
<h2>Overview</h2>
|
||||||
|
<p>
|
||||||
|
pvaClient is a synchronous wrapper for the pvAccess API, which is a callback based API.
|
||||||
|
Thus it is easier to use than pvAccess itself.
|
||||||
|
In addition pvaClient provides many convenience methods.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Class <b>PvaClient</b> is a class that is used by all the other pvaClient classes.
|
||||||
|
An application that uses pvaClient must call:</p>
|
||||||
|
<pre>
|
||||||
|
PvaClientPtr pvaClient = PvaClient::get(providers);
|
||||||
|
</pre>
|
||||||
|
<p>
|
||||||
|
before it uses any other pvaClient classes.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
This is a singleton method, i. e. only one instance of PvaClient is created.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<b>pvaClient</b> must not be deleted until the client no longer wants to use any part
|
||||||
|
of pvaClient.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<b>providers</b> is a blank separated set of provider names.
|
||||||
|
For example:</p>
|
||||||
|
<pre>
|
||||||
|
PvaClientPtr pvaClient = PvaClient::get("ca pva");
|
||||||
|
</pre>
|
||||||
|
<p>
|
||||||
|
The providers <b>ca</b> and <b>pva</b> are special.
|
||||||
|
For each of these a client context is created when the <b>PvaClient</b>
|
||||||
|
is constructed and the context destroyed when <b>PvaClient</b> is deleted.
|
||||||
|
</p>
|
||||||
|
<h2>Channel Caching</h2>
|
||||||
|
<p>
|
||||||
|
<b>PvaClient</b> has a method:
|
||||||
|
</p>
|
||||||
|
<pre>
|
||||||
|
PvaClientChannelPtr channel(
|
||||||
|
string const & channelName,
|
||||||
|
string const &providerName = "pva",
|
||||||
|
double timeOut = 5.0);
|
||||||
|
</pre>
|
||||||
|
<p>
|
||||||
|
This method creates a
|
||||||
|
<b>PvaClientChannel</b> and then connects to the channel.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
If a call is successful then multiple calls to the same channelName and providerName
|
||||||
|
share the same PvaClientChannel, i. e. the PvaClientChannel is cached.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<b>pvaClientChannelGet</b> and <b>pvaClientChannelPut</b> also implement caching.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
For example consider a client that makes multiple calls like:
|
||||||
|
</p>
|
||||||
|
<pre>
|
||||||
|
double value;
|
||||||
|
value = pva->channel(channelName)->get()->getData()->getDouble();
|
||||||
|
...
|
||||||
|
value = pva->channel(channelName)->get()->getData()->getDouble();
|
||||||
|
</pre>
|
||||||
|
<p>
|
||||||
|
Only the first call creates a new PvaClientChannel and a new PvaClientGet.
|
||||||
|
The second call reuses the cached PvaClientChannel and PvaClientGet.
|
||||||
|
</p>
|
||||||
|
<h2>Non Cached Channels</h2>
|
||||||
|
<p>
|
||||||
|
<b>PvaClient</b> has a method:
|
||||||
|
</p>
|
||||||
|
<pre>
|
||||||
|
PvaClientChannelPtr createChannel(
|
||||||
|
string const & channelName,
|
||||||
|
string const &providerName = "pva");
|
||||||
|
</pre>
|
||||||
|
<p>
|
||||||
|
This method is just creates a new PvaClientChannel and returns it to the caller.
|
||||||
|
The caller must call the PvaClientChannel connect methods.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h2>Blocking vs Non-Blocking Methods</h2>
|
||||||
|
<p>Each component of pvaClient provides a set of blocking and non-blocking calls.
|
||||||
|
For example several components (examples are <b>PvaClientChannel</b> and <b>PvaChannelGet</b>)
|
||||||
|
have methods:</p>
|
||||||
|
<dl>
|
||||||
|
<dt>connect</dt>
|
||||||
|
<dd>
|
||||||
|
This calls issueConnect and then waitConnect.
|
||||||
|
If waitConnect fails an exception is thrown.
|
||||||
|
Since waitConnect is a blocking method so is this.
|
||||||
|
</dd>
|
||||||
|
<dt>issueConnect</dt>
|
||||||
|
<dd>
|
||||||
|
This is a request to connect, i. e. issue a request to the server to create something
|
||||||
|
on the server. This is a non blocking call.
|
||||||
|
</dd>
|
||||||
|
<dt>waitConnect</dt>
|
||||||
|
<dd>
|
||||||
|
This waits for the server to respond to issueConnect.
|
||||||
|
It blocks until the server responds or a timeout occurs.
|
||||||
|
</dd>
|
||||||
|
</dl>
|
||||||
|
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
||||||
@@ -0,0 +1,123 @@
|
|||||||
|
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||||
|
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
|
||||||
|
<title>PvaClientChannel</title>
|
||||||
|
<link rel="stylesheet" type="text/css"
|
||||||
|
href="http://epics-pvdata.sourceforge.net/base.css" />
|
||||||
|
<link rel="stylesheet" type="text/css"
|
||||||
|
href="http://epics-pvdata.sourceforge.net/epicsv4.css" />
|
||||||
|
<style type="text/css">
|
||||||
|
/*<![CDATA[*/
|
||||||
|
.about { margin-left: 3em; margin-right: 3em; font-size: .83em}
|
||||||
|
table { margin-left: auto; margin-right: auto }
|
||||||
|
.diagram { text-align: center; margin: 2.5em 0 }
|
||||||
|
span.opt { color: grey }
|
||||||
|
span.nterm { font-style:italic }
|
||||||
|
span.term { font-family:courier }
|
||||||
|
span.user { font-family:courier }
|
||||||
|
span.user:before { content:"<" }
|
||||||
|
span.user:after { content:">" }
|
||||||
|
.nonnorm { font-style:italic }
|
||||||
|
p.ed { color: #AA0000 }
|
||||||
|
span.ed { color: #AA0000 }
|
||||||
|
p.ed.priv { display: inline; }
|
||||||
|
span.ed.priv { display: inline; }
|
||||||
|
/*]]>*/</style>
|
||||||
|
<!-- Script that generates the Table of Contents -->
|
||||||
|
<script type="text/javascript"
|
||||||
|
src="http://epics-pvdata.sourceforge.net/script/tocgen.js">
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<h1>PvaClientChannel</h1>
|
||||||
|
|
||||||
|
<h2>Overview</h2>
|
||||||
|
<p>
|
||||||
|
pvaClientChannel is a synchronous wrapper for the pvAccess::Channel API, which is a callback based API.
|
||||||
|
Thus it is easier to use than pvAccess::Channel itself.
|
||||||
|
</p>
|
||||||
|
<p>An instance of <b>PvaClientChannel</b> connects to a single channel.
|
||||||
|
An instance can only be created via class <b>PvaClient</b> which has both synchronous methods, which block, and non blocking methods.
|
||||||
|
The synchrouous methods block until a connection is made to the channel and throw an exception if a
|
||||||
|
timeout occurs while trying to make a connection.
|
||||||
|
The non blocking methods leave connection to the caller.
|
||||||
|
</p>
|
||||||
|
<p><b>PvaClientChannel</b> has methods:</p>
|
||||||
|
<dl>
|
||||||
|
<dt>Connect to channel</dt>
|
||||||
|
<dd>These can be called indirectly by a blocking request to <b>PvaClient</b>
|
||||||
|
or by the client if a non blocking request is made to <b>PvaClient</b>.
|
||||||
|
</dd>
|
||||||
|
<dt>Channel state change requester</dt>
|
||||||
|
<dd>The client can provide a callback that is called each time the connection state
|
||||||
|
of the channel changes.
|
||||||
|
</dd>
|
||||||
|
<dt>Creating all of the following</dt>
|
||||||
|
<dd>
|
||||||
|
<pre>
|
||||||
|
PvaClientField NOT IMPLEMENTED
|
||||||
|
PvaClientProcess
|
||||||
|
PvaClientGet
|
||||||
|
PvaClientPut
|
||||||
|
PvaClientPutGet
|
||||||
|
PvaClientMonitor
|
||||||
|
PvaClientArray NOT IMPLEMENTED
|
||||||
|
PvaClientRPC
|
||||||
|
</pre>
|
||||||
|
</dd>
|
||||||
|
</dl>
|
||||||
|
<h2>Connect: Blocking vs Non-Blocking </h2>
|
||||||
|
<p><b>PvaClientChannel</b> has methods:</p>
|
||||||
|
<dl>
|
||||||
|
<dt>connect</dt>
|
||||||
|
<dd>
|
||||||
|
This calls issueConnect and then waitConnect.
|
||||||
|
If waitConnect fails an exception is thrown.
|
||||||
|
Since waitConnect is a blocking method so is this.
|
||||||
|
</dd>
|
||||||
|
<dt>issueConnect</dt>
|
||||||
|
<dd>
|
||||||
|
This is a request to connect to the channel. This is a non blocking call.
|
||||||
|
</dd>
|
||||||
|
<dt>waitConnect</dt>
|
||||||
|
<dd>
|
||||||
|
This waits for the server to respond to issueConnect.
|
||||||
|
It blocks until the server responds or a timeout occurs.
|
||||||
|
</dd>
|
||||||
|
</dl>
|
||||||
|
|
||||||
|
<h2>Get and Put Caching</h2>
|
||||||
|
<p>
|
||||||
|
<b>PvaClientChannel</b> has methods:
|
||||||
|
</p>
|
||||||
|
<pre>
|
||||||
|
PvaClientGetPtr get(std::string const & request);
|
||||||
|
PvaClientPutPtr put(std::string const & request);
|
||||||
|
</pre>
|
||||||
|
<p>
|
||||||
|
Each of these caches.
|
||||||
|
For example all calls to <b>get</b> with the same <b>request</b> will share the same
|
||||||
|
<b>PvaChannelGet</b>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
For example consider a client that makes multiple calls like:
|
||||||
|
</p>
|
||||||
|
<pre>
|
||||||
|
double value;
|
||||||
|
value = pva->channel(channelName)->get()->getData()->getDouble();
|
||||||
|
...
|
||||||
|
value = pva->channel(channelName)->get()->getData()->getDouble();
|
||||||
|
</pre>
|
||||||
|
<p>
|
||||||
|
Only the first call creates a new PvaClientChannel and a new PvaClientGet.
|
||||||
|
The second call reuses the cached PvaClientChannel and PvaClientGet.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
||||||
@@ -0,0 +1,81 @@
|
|||||||
|
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||||
|
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
|
||||||
|
<title>PvaClientChannelStateChangeRequester</title>
|
||||||
|
<link rel="stylesheet" type="text/css"
|
||||||
|
href="http://epics-pvdata.sourceforge.net/base.css" />
|
||||||
|
<link rel="stylesheet" type="text/css"
|
||||||
|
href="http://epics-pvdata.sourceforge.net/epicsv4.css" />
|
||||||
|
<style type="text/css">
|
||||||
|
/*<![CDATA[*/
|
||||||
|
.about { margin-left: 3em; margin-right: 3em; font-size: .83em}
|
||||||
|
table { margin-left: auto; margin-right: auto }
|
||||||
|
.diagram { text-align: center; margin: 2.5em 0 }
|
||||||
|
span.opt { color: grey }
|
||||||
|
span.nterm { font-style:italic }
|
||||||
|
span.term { font-family:courier }
|
||||||
|
span.user { font-family:courier }
|
||||||
|
span.user:before { content:"<" }
|
||||||
|
span.user:after { content:">" }
|
||||||
|
.nonnorm { font-style:italic }
|
||||||
|
p.ed { color: #AA0000 }
|
||||||
|
span.ed { color: #AA0000 }
|
||||||
|
p.ed.priv { display: inline; }
|
||||||
|
span.ed.priv { display: inline; }
|
||||||
|
/*]]>*/</style>
|
||||||
|
<!-- Script that generates the Table of Contents -->
|
||||||
|
<script type="text/javascript"
|
||||||
|
src="http://epics-pvdata.sourceforge.net/script/tocgen.js">
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<h1>PvaClientChannelStateChangeRequester</h1>
|
||||||
|
|
||||||
|
<p>This class has the single method <b>channelStateChange</b>.
|
||||||
|
It is called each time the channel connection status changes.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<b>NOTE:</b>
|
||||||
|
The implementation must not call a method that blocks waiting for a response from the server.
|
||||||
|
It it does the client may be blocked forever.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
An example of illegal code is:
|
||||||
|
</p>
|
||||||
|
<pre>
|
||||||
|
virtual void channelStateChange(PvaClientChannelPtr const & channel, bool isConnected)
|
||||||
|
{
|
||||||
|
if(isConnected&&!pvaClientPut)
|
||||||
|
{
|
||||||
|
pvaClientPut = pvaClientChannel->createPut(request);
|
||||||
|
pvaClientPut->connect();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</pre>
|
||||||
|
<p>
|
||||||
|
This is illegal because the call to <b>connect</b> blocks.
|
||||||
|
</p>
|
||||||
|
<p>The following is an example of legal code:
|
||||||
|
</p>
|
||||||
|
<pre>
|
||||||
|
virtual void channelStateChange(PvaClientChannelPtr const & channel, bool isConnected)
|
||||||
|
{
|
||||||
|
if(isConnected&&!pvaClientPut)
|
||||||
|
{
|
||||||
|
pvaClientPut = pvaClientChannel->createPut(request);
|
||||||
|
pvaClientPut->issueConnect();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</pre>
|
||||||
|
<p>This is legal code because neither <b>createPut</b> or <b>issueConnect</b>
|
||||||
|
blocks.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
||||||
@@ -0,0 +1,74 @@
|
|||||||
|
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||||
|
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
|
||||||
|
<title>PvaClientGet</title>
|
||||||
|
<link rel="stylesheet" type="text/css"
|
||||||
|
href="http://epics-pvdata.sourceforge.net/base.css" />
|
||||||
|
<link rel="stylesheet" type="text/css"
|
||||||
|
href="http://epics-pvdata.sourceforge.net/epicsv4.css" />
|
||||||
|
<style type="text/css">
|
||||||
|
/*<![CDATA[*/
|
||||||
|
.about { margin-left: 3em; margin-right: 3em; font-size: .83em}
|
||||||
|
table { margin-left: auto; margin-right: auto }
|
||||||
|
.diagram { text-align: center; margin: 2.5em 0 }
|
||||||
|
span.opt { color: grey }
|
||||||
|
span.nterm { font-style:italic }
|
||||||
|
span.term { font-family:courier }
|
||||||
|
span.user { font-family:courier }
|
||||||
|
span.user:before { content:"<" }
|
||||||
|
span.user:after { content:">" }
|
||||||
|
.nonnorm { font-style:italic }
|
||||||
|
p.ed { color: #AA0000 }
|
||||||
|
span.ed { color: #AA0000 }
|
||||||
|
p.ed.priv { display: inline; }
|
||||||
|
span.ed.priv { display: inline; }
|
||||||
|
/*]]>*/</style>
|
||||||
|
<!-- Script that generates the Table of Contents -->
|
||||||
|
<script type="text/javascript"
|
||||||
|
src="http://epics-pvdata.sourceforge.net/script/tocgen.js">
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<h1>PvaClientGet</h1>
|
||||||
|
|
||||||
|
|
||||||
|
<p>
|
||||||
|
pvaClientGet is a synchronous wrapper for the pvAccess::ChannelGet API, which is a callback based API.
|
||||||
|
Thus it is easier to use than pvAccess::ChannelGet itself.
|
||||||
|
</p>
|
||||||
|
<p>An instance of PvaClientGet is created via a call to one of the following:</p>
|
||||||
|
<pre>
|
||||||
|
class PvaClientChannel
|
||||||
|
...
|
||||||
|
{
|
||||||
|
...
|
||||||
|
PvaClientGetPtr get(std::string const & request = "field(value,alarm,timeStamp)");
|
||||||
|
PvaClientGetPtr createGet(std::string const & request = "");
|
||||||
|
PvaClientGetPtr createGet(epics::pvData::PVStructurePtr const & pvRequest);
|
||||||
|
...
|
||||||
|
};
|
||||||
|
<p>An instance of <b>PvaClientGet</b> connects to a single channel.
|
||||||
|
<b>PvaClientGet</b> has both synchronous methods, which block, and non blocking methods.
|
||||||
|
</p>
|
||||||
|
<p><b>PvaClientChannel</b> has methods:</p>
|
||||||
|
<pre>
|
||||||
|
connect Calls issueConnect and then waitConnect.
|
||||||
|
issueConnect issues a request to the server to create the server side of ChannelPut.
|
||||||
|
waitConnect blocks until server responds that it has created the ChannelPut.
|
||||||
|
get Calls issueGet and then waitGet.
|
||||||
|
issueGet issues a get request to the server.
|
||||||
|
waitGet waits until the server send a message that the get is complete.
|
||||||
|
getData get the data.
|
||||||
|
</pre>
|
||||||
|
<p>
|
||||||
|
<b>issueConnect</b> and <b>issueGet</b> do not block.
|
||||||
|
All other methods can block.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
||||||
@@ -0,0 +1,63 @@
|
|||||||
|
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||||
|
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
|
||||||
|
<title>PvaClientGetData</title>
|
||||||
|
<link rel="stylesheet" type="text/css"
|
||||||
|
href="http://epics-pvdata.sourceforge.net/base.css" />
|
||||||
|
<link rel="stylesheet" type="text/css"
|
||||||
|
href="http://epics-pvdata.sourceforge.net/epicsv4.css" />
|
||||||
|
<style type="text/css">
|
||||||
|
/*<![CDATA[*/
|
||||||
|
.about { margin-left: 3em; margin-right: 3em; font-size: .83em}
|
||||||
|
table { margin-left: auto; margin-right: auto }
|
||||||
|
.diagram { text-align: center; margin: 2.5em 0 }
|
||||||
|
span.opt { color: grey }
|
||||||
|
span.nterm { font-style:italic }
|
||||||
|
span.term { font-family:courier }
|
||||||
|
span.user { font-family:courier }
|
||||||
|
span.user:before { content:"<" }
|
||||||
|
span.user:after { content:">" }
|
||||||
|
.nonnorm { font-style:italic }
|
||||||
|
p.ed { color: #AA0000 }
|
||||||
|
span.ed { color: #AA0000 }
|
||||||
|
p.ed.priv { display: inline; }
|
||||||
|
span.ed.priv { display: inline; }
|
||||||
|
/*]]>*/</style>
|
||||||
|
<!-- Script that generates the Table of Contents -->
|
||||||
|
<script type="text/javascript"
|
||||||
|
src="http://epics-pvdata.sourceforge.net/script/tocgen.js">
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<h1>PvaClientGetData</h1>
|
||||||
|
|
||||||
|
<p>This class provides access to the data returned by calls to get data via <b>PvaChannelGet</b>
|
||||||
|
It provides methods:</p>
|
||||||
|
<pre>
|
||||||
|
getStructure Get the introspection interface for data returned from server
|
||||||
|
getPVStructure Get the complete set of data returned from the server.
|
||||||
|
getChangedBitSet Get the bitSet that shows which fields have a new value since last get.
|
||||||
|
showChanged Show all the fields that have changed value since the last get,
|
||||||
|
getAlarm If a alarm field is available get it.
|
||||||
|
getTimeStamp If a timeStamp field is available get it.
|
||||||
|
hasValue Does the PVStructure have a top level field named value
|
||||||
|
NOTE: The following only apply if hasValue is true.
|
||||||
|
isValueScalar Is the value field a scalar?
|
||||||
|
isValueScalarArray Is the value field a scalar array?
|
||||||
|
getValue Get the value field.
|
||||||
|
getScalarValue Get a scalar value field.
|
||||||
|
getArrayValue Get an array value field.
|
||||||
|
getScalarArrayValue Get a scalar array value field.
|
||||||
|
getDouble Get scalar value field as a double.
|
||||||
|
getString Get value field as a string.
|
||||||
|
getDoubleArray Get value field as a double array.
|
||||||
|
getStringArray Get value field as a string array.
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||||
|
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
|
||||||
|
<title>PvaClientGetRequester</title>
|
||||||
|
<link rel="stylesheet" type="text/css"
|
||||||
|
href="http://epics-pvdata.sourceforge.net/base.css" />
|
||||||
|
<link rel="stylesheet" type="text/css"
|
||||||
|
href="http://epics-pvdata.sourceforge.net/epicsv4.css" />
|
||||||
|
<style type="text/css">
|
||||||
|
/*<![CDATA[*/
|
||||||
|
.about { margin-left: 3em; margin-right: 3em; font-size: .83em}
|
||||||
|
table { margin-left: auto; margin-right: auto }
|
||||||
|
.diagram { text-align: center; margin: 2.5em 0 }
|
||||||
|
span.opt { color: grey }
|
||||||
|
span.nterm { font-style:italic }
|
||||||
|
span.term { font-family:courier }
|
||||||
|
span.user { font-family:courier }
|
||||||
|
span.user:before { content:"<" }
|
||||||
|
span.user:after { content:">" }
|
||||||
|
.nonnorm { font-style:italic }
|
||||||
|
p.ed { color: #AA0000 }
|
||||||
|
span.ed { color: #AA0000 }
|
||||||
|
p.ed.priv { display: inline; }
|
||||||
|
span.ed.priv { display: inline; }
|
||||||
|
/*]]>*/</style>
|
||||||
|
<!-- Script that generates the Table of Contents -->
|
||||||
|
<script type="text/javascript"
|
||||||
|
src="http://epics-pvdata.sourceforge.net/script/tocgen.js">
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<h1>PvaClientGetRequester</h1>
|
||||||
|
|
||||||
|
<p>This is a virtual class that can be implemented by a client that uses <b>PvaClientGet</b>.
|
||||||
|
It has the methods:</p>
|
||||||
|
<pre>
|
||||||
|
virtual void channelGetConnect(
|
||||||
|
const Status& status,
|
||||||
|
PvaClientGetPtr const & clientGet) {}
|
||||||
|
virtual void getDone(
|
||||||
|
const Status& status,
|
||||||
|
PvaClientGetPtr const & clientGet) = 0;
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<p>The client must call</p>
|
||||||
|
<pre>
|
||||||
|
pvaClientGet->setRequester(shared_from_this());
|
||||||
|
</pre>
|
||||||
|
<p>
|
||||||
|
after creating an instance of PvaClientGet.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
||||||
@@ -0,0 +1,106 @@
|
|||||||
|
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||||
|
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
|
||||||
|
<title>PvaClientMonitor</title>
|
||||||
|
<link rel="stylesheet" type="text/css"
|
||||||
|
href="http://epics-pvdata.sourceforge.net/base.css" />
|
||||||
|
<link rel="stylesheet" type="text/css"
|
||||||
|
href="http://epics-pvdata.sourceforge.net/epicsv4.css" />
|
||||||
|
<style type="text/css">
|
||||||
|
/*<![CDATA[*/
|
||||||
|
.about { margin-left: 3em; margin-right: 3em; font-size: .83em}
|
||||||
|
table { margin-left: auto; margin-right: auto }
|
||||||
|
.diagram { text-align: center; margin: 2.5em 0 }
|
||||||
|
span.opt { color: grey }
|
||||||
|
span.nterm { font-style:italic }
|
||||||
|
span.term { font-family:courier }
|
||||||
|
span.user { font-family:courier }
|
||||||
|
span.user:before { content:"<" }
|
||||||
|
span.user:after { content:">" }
|
||||||
|
.nonnorm { font-style:italic }
|
||||||
|
p.ed { color: #AA0000 }
|
||||||
|
span.ed { color: #AA0000 }
|
||||||
|
p.ed.priv { display: inline; }
|
||||||
|
span.ed.priv { display: inline; }
|
||||||
|
/*]]>*/</style>
|
||||||
|
<!-- Script that generates the Table of Contents -->
|
||||||
|
<script type="text/javascript"
|
||||||
|
src="http://epics-pvdata.sourceforge.net/script/tocgen.js">
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<h1>PvaClientMonitor</h1>
|
||||||
|
<p>
|
||||||
|
<b>NOTE:</b> This is a work in progress.
|
||||||
|
</p>
|
||||||
|
<h2>Overview</h2>
|
||||||
|
<p>
|
||||||
|
This provides an easier way to create a monitor on a channel than to use pvAccessCPP itself.
|
||||||
|
It provides two main ways to create a monitor:
|
||||||
|
</p>
|
||||||
|
<h3>The client first creates a PvaClientMonitorChannel and then creates a monitor</h3>
|
||||||
|
The client calls:
|
||||||
|
<pre>
|
||||||
|
static PvaClientMonitorPtr create(
|
||||||
|
PvaClientMonitorPtr const &PvaClientMonitor,
|
||||||
|
PvaClientMonitorChannelPtr const & PvaClientMonitorChannel,
|
||||||
|
epics::pvData::PVStructurePtr const &pvRequest
|
||||||
|
);
|
||||||
|
|
||||||
|
where
|
||||||
|
|
||||||
|
PvaClientMonitor
|
||||||
|
The PvaClientMonitor.
|
||||||
|
|
||||||
|
PvaClientMonitorChannel
|
||||||
|
The PvaClientMonitorChannel that has already been created by the client.
|
||||||
|
|
||||||
|
pvRequest
|
||||||
|
The pvRequest for creating the monitor.
|
||||||
|
</pre>
|
||||||
|
With this method the monitor is created and started.
|
||||||
|
This method blocks while the monitor is created.
|
||||||
|
<h3>The client provides names for a channel and a provider</h3>
|
||||||
|
The client calls:
|
||||||
|
<pre>
|
||||||
|
static PvaClientMonitorPtr create(
|
||||||
|
PvaClientMonitorPtr const &PvaClientMonitor,
|
||||||
|
std::string const & channelName,
|
||||||
|
std::string const & providerName,
|
||||||
|
std::string const & request,
|
||||||
|
PvaClientMonitorChannelStateChangeRequesterPtr const & stateChangeRequester,
|
||||||
|
PvaClientMonitorRequesterPtr const & monitorRequester
|
||||||
|
);
|
||||||
|
|
||||||
|
where
|
||||||
|
|
||||||
|
PvaClientMonitor
|
||||||
|
The PvaClientMonitor.
|
||||||
|
|
||||||
|
channelName
|
||||||
|
The name of the channel.
|
||||||
|
|
||||||
|
providerName
|
||||||
|
The name of the provider
|
||||||
|
|
||||||
|
request
|
||||||
|
The request for creating the monitor
|
||||||
|
|
||||||
|
stateChangeRequester
|
||||||
|
The client supplied state change requester.
|
||||||
|
This will be called each time a state change for the channel occurs.
|
||||||
|
|
||||||
|
monitorRequester
|
||||||
|
The client supplied monitor requester.
|
||||||
|
This is called each time a new monitor event is available.
|
||||||
|
</pre>
|
||||||
|
With this method a pvaChannel is created and after it connects a pvaMonitor is created and started.
|
||||||
|
This method never blocks.
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
||||||
@@ -0,0 +1,66 @@
|
|||||||
|
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||||
|
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
|
||||||
|
<title>PvaClientMonitorData</title>
|
||||||
|
<link rel="stylesheet" type="text/css"
|
||||||
|
href="http://epics-pvdata.sourceforge.net/base.css" />
|
||||||
|
<link rel="stylesheet" type="text/css"
|
||||||
|
href="http://epics-pvdata.sourceforge.net/epicsv4.css" />
|
||||||
|
<style type="text/css">
|
||||||
|
/*<![CDATA[*/
|
||||||
|
.about { margin-left: 3em; margin-right: 3em; font-size: .83em}
|
||||||
|
table { margin-left: auto; margin-right: auto }
|
||||||
|
.diagram { text-align: center; margin: 2.5em 0 }
|
||||||
|
span.opt { color: grey }
|
||||||
|
span.nterm { font-style:italic }
|
||||||
|
span.term { font-family:courier }
|
||||||
|
span.user { font-family:courier }
|
||||||
|
span.user:before { content:"<" }
|
||||||
|
span.user:after { content:">" }
|
||||||
|
.nonnorm { font-style:italic }
|
||||||
|
p.ed { color: #AA0000 }
|
||||||
|
span.ed { color: #AA0000 }
|
||||||
|
p.ed.priv { display: inline; }
|
||||||
|
span.ed.priv { display: inline; }
|
||||||
|
/*]]>*/</style>
|
||||||
|
<!-- Script that generates the Table of Contents -->
|
||||||
|
<script type="text/javascript"
|
||||||
|
src="http://epics-pvdata.sourceforge.net/script/tocgen.js">
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<h1>PvaClientMonitorData</h1>
|
||||||
|
|
||||||
|
|
||||||
|
<p>This class provides access to the data returned by calls to get data via <b>PvaChannelGet</b>
|
||||||
|
It provides methods:</p>
|
||||||
|
<pre>
|
||||||
|
getStructure Get the introspection interface for data returned from server
|
||||||
|
getPVStructure Get the complete set of data returned from the server.
|
||||||
|
getChangedBitSet Get the bitSet that shows which fields have a new value since last monitor event.
|
||||||
|
getOverrunBitSet Get the bitSet that shows which fields have changed more than once since last monitor event.
|
||||||
|
showChanged Show all the fields that have changed value since the last monitor event,
|
||||||
|
showChanged Show all the fields that have changed value more than once since last monitor event.
|
||||||
|
getAlarm If a alarm field is available get it.
|
||||||
|
getTimeStamp If a timeStamp field is available get it.
|
||||||
|
hasValue Does the PVStructure have a top level field named value
|
||||||
|
NOTE: The following only apply if hasValue is true.
|
||||||
|
isValueScalar Is the value field a scalar?
|
||||||
|
isValueScalarArray Is the value field a scalar array?
|
||||||
|
getValue Get the value field.
|
||||||
|
getScalarValue Get a scalar value field.
|
||||||
|
getArrayValue Get an array value field.
|
||||||
|
getScalarArrayValue Get a scalar array value field.
|
||||||
|
getDouble Get scalar value field as a double.
|
||||||
|
getString Get value field as a string.
|
||||||
|
getDoubleArray Get value field as a double array.
|
||||||
|
getStringArray Get value field as a string array.
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
||||||
@@ -0,0 +1,65 @@
|
|||||||
|
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||||
|
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
|
||||||
|
<title>PvaClientMonitorRequester</title>
|
||||||
|
<link rel="stylesheet" type="text/css"
|
||||||
|
href="http://epics-pvdata.sourceforge.net/base.css" />
|
||||||
|
<link rel="stylesheet" type="text/css"
|
||||||
|
href="http://epics-pvdata.sourceforge.net/epicsv4.css" />
|
||||||
|
<style type="text/css">
|
||||||
|
/*<![CDATA[*/
|
||||||
|
.about { margin-left: 3em; margin-right: 3em; font-size: .83em}
|
||||||
|
table { margin-left: auto; margin-right: auto }
|
||||||
|
.diagram { text-align: center; margin: 2.5em 0 }
|
||||||
|
span.opt { color: grey }
|
||||||
|
span.nterm { font-style:italic }
|
||||||
|
span.term { font-family:courier }
|
||||||
|
span.user { font-family:courier }
|
||||||
|
span.user:before { content:"<" }
|
||||||
|
span.user:after { content:">" }
|
||||||
|
.nonnorm { font-style:italic }
|
||||||
|
p.ed { color: #AA0000 }
|
||||||
|
span.ed { color: #AA0000 }
|
||||||
|
p.ed.priv { display: inline; }
|
||||||
|
span.ed.priv { display: inline; }
|
||||||
|
/*]]>*/</style>
|
||||||
|
<!-- Script that generates the Table of Contents -->
|
||||||
|
<script type="text/javascript"
|
||||||
|
src="http://epics-pvdata.sourceforge.net/script/tocgen.js">
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<h1>PvaClientMonitorRequester</h1>
|
||||||
|
|
||||||
|
<p>This is a virtual class that can be implemented by a client that uses <b>PvaClientMonitor</b>.
|
||||||
|
It has the methods:</p>
|
||||||
|
<pre>
|
||||||
|
virtual void monitorConnect(
|
||||||
|
const Status& status,
|
||||||
|
PvaClientMonitorPtr const & clientMonitor,
|
||||||
|
StructureConstPtr const & structure) {}
|
||||||
|
virtual void event(
|
||||||
|
PvaClientMonitor const & clientGet) = 0;
|
||||||
|
virtual void unlisten()
|
||||||
|
{
|
||||||
|
std::cerr << "PvaClientMonitorRequester::unlisten called"
|
||||||
|
<< " but no PvaClientMonitorRequester::unlisten\n";
|
||||||
|
}
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<p>The client must call</p>
|
||||||
|
<pre>
|
||||||
|
pvaClientMonitor->setRequester(shared_from_this());
|
||||||
|
</pre>
|
||||||
|
<p>
|
||||||
|
after creating an instance of PvaClientMonitor.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
||||||
@@ -0,0 +1,71 @@
|
|||||||
|
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||||
|
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
|
||||||
|
<title>PvaClientProcess</title>
|
||||||
|
<link rel="stylesheet" type="text/css"
|
||||||
|
href="http://epics-pvdata.sourceforge.net/base.css" />
|
||||||
|
<link rel="stylesheet" type="text/css"
|
||||||
|
href="http://epics-pvdata.sourceforge.net/epicsv4.css" />
|
||||||
|
<style type="text/css">
|
||||||
|
/*<![CDATA[*/
|
||||||
|
.about { margin-left: 3em; margin-right: 3em; font-size: .83em}
|
||||||
|
table { margin-left: auto; margin-right: auto }
|
||||||
|
.diagram { text-align: center; margin: 2.5em 0 }
|
||||||
|
span.opt { color: grey }
|
||||||
|
span.nterm { font-style:italic }
|
||||||
|
span.term { font-family:courier }
|
||||||
|
span.user { font-family:courier }
|
||||||
|
span.user:before { content:"<" }
|
||||||
|
span.user:after { content:">" }
|
||||||
|
.nonnorm { font-style:italic }
|
||||||
|
p.ed { color: #AA0000 }
|
||||||
|
span.ed { color: #AA0000 }
|
||||||
|
p.ed.priv { display: inline; }
|
||||||
|
span.ed.priv { display: inline; }
|
||||||
|
/*]]>*/</style>
|
||||||
|
<!-- Script that generates the Table of Contents -->
|
||||||
|
<script type="text/javascript"
|
||||||
|
src="http://epics-pvdata.sourceforge.net/script/tocgen.js">
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<h1>PvaClientProcess</h1>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
pvaClientProcess is a synchronous wrapper for the pvAccess::ChannelProcess API, which is a callback based API.
|
||||||
|
Thus it is easier to use than pvAccess::ChannelProcess itself.
|
||||||
|
</p>
|
||||||
|
<p>An instance of PvaClientProcess is created via a call to one of the followimg:</p>
|
||||||
|
<pre>
|
||||||
|
class PvaClientChannel
|
||||||
|
...
|
||||||
|
{
|
||||||
|
...
|
||||||
|
PvaClientProcessPtr createProcess(std::string const & request = "");
|
||||||
|
PvaClientProcessPtr createProcess(epics::pvData::PVStructurePtr const & pvRequest);
|
||||||
|
...
|
||||||
|
};
|
||||||
|
<p>An instance of <b>PvaClientProcess</b> connects to a single channel.
|
||||||
|
<b>PvaClientProcess</b> has both synchronous methods, which block, and non blocking methods.
|
||||||
|
</p>
|
||||||
|
<p><b>PvaClientChannel</b> has methods:</p>
|
||||||
|
<pre>
|
||||||
|
connect Calls issueConnect and then waitConnect.
|
||||||
|
issueConnect issues a request to the server to create the server side of ChannelPut.
|
||||||
|
waitConnect blocks until server responds that it has created the ChannelPut.
|
||||||
|
process Calls issueProcess and then waitProcess.
|
||||||
|
issueProcess issues a process request to the server.
|
||||||
|
waitProcess waits until the server send a message that the process is complete.
|
||||||
|
</pre>
|
||||||
|
<p>
|
||||||
|
<b>issueConnect</b> and <b>issueProcess</b> do not block.
|
||||||
|
All other methods can block.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
||||||
@@ -0,0 +1,82 @@
|
|||||||
|
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||||
|
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
|
||||||
|
<title>PvaClientChannelPut</title>
|
||||||
|
<link rel="stylesheet" type="text/css"
|
||||||
|
href="http://epics-pvdata.sourceforge.net/base.css" />
|
||||||
|
<link rel="stylesheet" type="text/css"
|
||||||
|
href="http://epics-pvdata.sourceforge.net/epicsv4.css" />
|
||||||
|
<style type="text/css">
|
||||||
|
/*<![CDATA[*/
|
||||||
|
.about { margin-left: 3em; margin-right: 3em; font-size: .83em}
|
||||||
|
table { margin-left: auto; margin-right: auto }
|
||||||
|
.diagram { text-align: center; margin: 2.5em 0 }
|
||||||
|
span.opt { color: grey }
|
||||||
|
span.nterm { font-style:italic }
|
||||||
|
span.term { font-family:courier }
|
||||||
|
span.user { font-family:courier }
|
||||||
|
span.user:before { content:"<" }
|
||||||
|
span.user:after { content:">" }
|
||||||
|
.nonnorm { font-style:italic }
|
||||||
|
p.ed { color: #AA0000 }
|
||||||
|
span.ed { color: #AA0000 }
|
||||||
|
p.ed.priv { display: inline; }
|
||||||
|
span.ed.priv { display: inline; }
|
||||||
|
/*]]>*/</style>
|
||||||
|
<!-- Script that generates the Table of Contents -->
|
||||||
|
<script type="text/javascript"
|
||||||
|
src="http://epics-pvdata.sourceforge.net/script/tocgen.js">
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<h1>PvaClientChannelPut</h1>s
|
||||||
|
|
||||||
|
<p>
|
||||||
|
pvaClientPut is a synchronous wrapper for the pvAccess::ChannelPut API, which is a callback based API.
|
||||||
|
Thus it is easier to use than pvAccess::ChannelPut itself.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<b>NOTE:</b>
|
||||||
|
Except for union fields pvaClientPut takes care of modifying the bitSet associated with
|
||||||
|
the data sent to the server.
|
||||||
|
</p>
|
||||||
|
<p>An instance of PvaClientPut is created via a call to one of the followimg:</p>
|
||||||
|
<pre>
|
||||||
|
class PvaClientChannel
|
||||||
|
...
|
||||||
|
{
|
||||||
|
...
|
||||||
|
PvaClientPutPtr put(std::string const & request = "field(value,alarm,timeStamp)");
|
||||||
|
PvaClientPutPtr createPut(std::string const & request = "");
|
||||||
|
PvaClientPutPtr createPut(epics::pvData::PVStructurePtr const & pvRequest);
|
||||||
|
...
|
||||||
|
};
|
||||||
|
<p>An instance of <b>PvaClientPut/b> connects to a single channel.
|
||||||
|
<b>PvaClientPut</b> has both synchronous methods, which block, and non blocking methods.
|
||||||
|
</p>
|
||||||
|
<p><b>PvaClientPut</b> has methods:</p>
|
||||||
|
<pre>
|
||||||
|
connect Calls issueConnect and then waitConnect.
|
||||||
|
issueConnect issues a request to the server to create the server side of ChannelPut.
|
||||||
|
waitConnect blocks until server responds that it has created the ChannelPut.
|
||||||
|
get Calls issueGet and then waitGet.
|
||||||
|
issueGet issues a request to the server to get the latest data.
|
||||||
|
waitGet waits until the server send a message that the get is complete.
|
||||||
|
put Calls issuePut and then waitPut.
|
||||||
|
issuePut issues a put request to the server.
|
||||||
|
waitPut waits until the server send a message that the put is complete.
|
||||||
|
getData get the data.
|
||||||
|
</pre>
|
||||||
|
<p>
|
||||||
|
Note that <b>issueConnect</b>, <b>issueGet</b> and <b>issuePut</b> do not block but all other methods
|
||||||
|
do block.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
||||||
@@ -0,0 +1,75 @@
|
|||||||
|
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||||
|
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
|
||||||
|
<title>PvaClientPutData</title>
|
||||||
|
<link rel="stylesheet" type="text/css"
|
||||||
|
href="http://epics-pvdata.sourceforge.net/base.css" />
|
||||||
|
<link rel="stylesheet" type="text/css"
|
||||||
|
href="http://epics-pvdata.sourceforge.net/epicsv4.css" />
|
||||||
|
<style type="text/css">
|
||||||
|
/*<![CDATA[*/
|
||||||
|
.about { margin-left: 3em; margin-right: 3em; font-size: .83em}
|
||||||
|
table { margin-left: auto; margin-right: auto }
|
||||||
|
.diagram { text-align: center; margin: 2.5em 0 }
|
||||||
|
span.opt { color: grey }
|
||||||
|
span.nterm { font-style:italic }
|
||||||
|
span.term { font-family:courier }
|
||||||
|
span.user { font-family:courier }
|
||||||
|
span.user:before { content:"<" }
|
||||||
|
span.user:after { content:">" }
|
||||||
|
.nonnorm { font-style:italic }
|
||||||
|
p.ed { color: #AA0000 }
|
||||||
|
span.ed { color: #AA0000 }
|
||||||
|
p.ed.priv { display: inline; }
|
||||||
|
span.ed.priv { display: inline; }
|
||||||
|
/*]]>*/</style>
|
||||||
|
<!-- Script that generates the Table of Contents -->
|
||||||
|
<script type="text/javascript"
|
||||||
|
src="http://epics-pvdata.sourceforge.net/script/tocgen.js">
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<h1>PvaClientPutData</h1>
|
||||||
|
|
||||||
|
<p>This class provides access to data to send to the server via a <b>PvaChannelPut</b>
|
||||||
|
It is created by <b>PvaChannelPut</b> or <b>PvaChannelPutGet</b>.
|
||||||
|
This the client only gets access to an instance by getting it from <b>PvaChannelPut</b> or <b>PvaChannelPutGet</b>.
|
||||||
|
<p>
|
||||||
|
<p>Note also that for all field types except <b>union</b> the <b>BitSet</b> for the data is updated
|
||||||
|
by <b>PvaChannelPut</b> or <b>PvaChannelPutGet</b> whenever the client changes a field.
|
||||||
|
For a <b>union</b> or <b>unionArray</b> field the client must update the <b>BitSet</b>.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
PvaClientPutData provides methods:</p>
|
||||||
|
<pre>
|
||||||
|
getStructure Get the introspection interface for data sent to server
|
||||||
|
getPVStructure Get the complete set of data sent to the server.
|
||||||
|
getChangedBitSet Get the bitSet that shows which fields have a new value since last get.
|
||||||
|
showChanged Show all the fields that have changed value since the last get,
|
||||||
|
getAlarm If a alarm field is available get it.
|
||||||
|
getTimeStamp If a timeStamp field is available get it.
|
||||||
|
hasValue Does the PVStructure have a top level field named value
|
||||||
|
NOTE: The following only apply if hasValue is true.
|
||||||
|
isValueScalar Is the value field a scalar?
|
||||||
|
isValueScalarArray Is the value field a scalar array?
|
||||||
|
getValue Get the value field.
|
||||||
|
getScalarValue Get a scalar value field.
|
||||||
|
getArrayValue Get an array value field.
|
||||||
|
getScalarArrayValue Get a scalar array value field.
|
||||||
|
getDouble Get scalar value field as a double.
|
||||||
|
getString Get value field as a string.
|
||||||
|
getDoubleArray Get value field as a double array.
|
||||||
|
getStringArray Get value field as a string array.
|
||||||
|
putDouble Put scalar value field as a double.
|
||||||
|
putString Put value field as a string.
|
||||||
|
putDoubleArray Put value field as a double array.
|
||||||
|
putStringArray Put value field as a string array.
|
||||||
|
</pre>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
||||||
@@ -0,0 +1,85 @@
|
|||||||
|
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||||
|
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
|
||||||
|
<title>PvaClientPutGetGet</title>
|
||||||
|
<link rel="stylesheet" type="text/css"
|
||||||
|
href="http://epics-pvdata.sourceforge.net/base.css" />
|
||||||
|
<link rel="stylesheet" type="text/css"
|
||||||
|
href="http://epics-pvdata.sourceforge.net/epicsv4.css" />
|
||||||
|
<style type="text/css">
|
||||||
|
/*<![CDATA[*/
|
||||||
|
.about { margin-left: 3em; margin-right: 3em; font-size: .83em}
|
||||||
|
table { margin-left: auto; margin-right: auto }
|
||||||
|
.diagram { text-align: center; margin: 2.5em 0 }
|
||||||
|
span.opt { color: grey }
|
||||||
|
span.nterm { font-style:italic }
|
||||||
|
span.term { font-family:courier }
|
||||||
|
span.user { font-family:courier }
|
||||||
|
span.user:before { content:"<" }
|
||||||
|
span.user:after { content:">" }
|
||||||
|
.nonnorm { font-style:italic }
|
||||||
|
p.ed { color: #AA0000 }
|
||||||
|
span.ed { color: #AA0000 }
|
||||||
|
p.ed.priv { display: inline; }
|
||||||
|
span.ed.priv { display: inline; }
|
||||||
|
/*]]>*/</style>
|
||||||
|
<!-- Script that generates the Table of Contents -->
|
||||||
|
<script type="text/javascript"
|
||||||
|
src="http://epics-pvdata.sourceforge.net/script/tocgen.js">
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<h1>PvaClientPutGetGet</h1>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
pvaClientPutGet is a synchronous wrapper for the pvAccess::ChannelPutGet API, which is a callback based API.
|
||||||
|
Thus it is easier to use than pvAccess::ChannelPut itself.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<b>NOTE:</b>
|
||||||
|
Except for union fields pvaClientPutGet takes care of modifying the bitSet associated with
|
||||||
|
the data sent to the server.
|
||||||
|
</p>
|
||||||
|
<p>An instance of PvaClientPutGet is created via a call to one of the followimg:</p>
|
||||||
|
<pre>
|
||||||
|
class PvaClientChannel
|
||||||
|
...
|
||||||
|
{
|
||||||
|
...
|
||||||
|
PvaClientPutGetPtr createPutGet(std::string const & request);
|
||||||
|
PvaClientPutGetPtr createPutGet(epics::pvData::PVStructurePtr const & pvRequest);
|
||||||
|
...
|
||||||
|
};
|
||||||
|
<p>An instance of <b>PvaClientPutGet</b> connects to a single channel.
|
||||||
|
<b>PvaClientPutGet</b> has both synchronous methods, which block, and non blocking methods.
|
||||||
|
</p>
|
||||||
|
<p><b>PvaClientPutGet</b> has methods:</p>
|
||||||
|
<pre>
|
||||||
|
connect calls issueConnect and then waitConnect.
|
||||||
|
issueConnect issues a request to the server to create the server side of ChannelPut.
|
||||||
|
waitConnect blocks until server responds that it has created the ChannelPut.
|
||||||
|
putGet call issuePutGet and then waitPutGet.
|
||||||
|
issuePutGet issue a putGet and return immediately.
|
||||||
|
waitPutGet wait until putGet completes.
|
||||||
|
getGet calls issueGetGet and then waitGetGet.
|
||||||
|
issueGetGet issues a request to the server to get the latest data for the get data.
|
||||||
|
waitGetGet waits until the server send a message that the getGet is complete.
|
||||||
|
getPut calls issueGetPut and then waitGetPut.
|
||||||
|
issueGetPut issues a request to the server to get the latest data for the put data.
|
||||||
|
waitGetPut waits until the server send a message that the getPut is complete.
|
||||||
|
getPutData get the put portion of the data.
|
||||||
|
getGetData get the get portion of the data.
|
||||||
|
</pre>
|
||||||
|
<p>
|
||||||
|
<b>issueConnect</b>, <b>issuePutGet</b>, <b>issueGetGet</b> and <b>issueGetPut</b> do not block.
|
||||||
|
All other methods can block.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
||||||
@@ -0,0 +1,66 @@
|
|||||||
|
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||||
|
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
|
||||||
|
<title>PvaClientPutGetRequester</title>
|
||||||
|
<link rel="stylesheet" type="text/css"
|
||||||
|
href="http://epics-pvdata.sourceforge.net/base.css" />
|
||||||
|
<link rel="stylesheet" type="text/css"
|
||||||
|
href="http://epics-pvdata.sourceforge.net/epicsv4.css" />
|
||||||
|
<style type="text/css">
|
||||||
|
/*<![CDATA[*/
|
||||||
|
.about { margin-left: 3em; margin-right: 3em; font-size: .83em}
|
||||||
|
table { margin-left: auto; margin-right: auto }
|
||||||
|
.diagram { text-align: center; margin: 2.5em 0 }
|
||||||
|
span.opt { color: grey }
|
||||||
|
span.nterm { font-style:italic }
|
||||||
|
span.term { font-family:courier }
|
||||||
|
span.user { font-family:courier }
|
||||||
|
span.user:before { content:"<" }
|
||||||
|
span.user:after { content:">" }
|
||||||
|
.nonnorm { font-style:italic }
|
||||||
|
p.ed { color: #AA0000 }
|
||||||
|
span.ed { color: #AA0000 }
|
||||||
|
p.ed.priv { display: inline; }
|
||||||
|
span.ed.priv { display: inline; }
|
||||||
|
/*]]>*/</style>
|
||||||
|
<!-- Script that generates the Table of Contents -->
|
||||||
|
<script type="text/javascript"
|
||||||
|
src="http://epics-pvdata.sourceforge.net/script/tocgen.js">
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<h1>PvaClientPutGetRequester</h1>
|
||||||
|
|
||||||
|
<p>This is a virtual class that can be implemented by a client that uses <b>PvaClientPut</b>.
|
||||||
|
It has the methods:</p>
|
||||||
|
<pre>
|
||||||
|
virtual void channelPutGetConnect(
|
||||||
|
const Status& status,
|
||||||
|
PvaClientPutGetPtr const & clientPutGet) {}
|
||||||
|
virtual void putGetDone(
|
||||||
|
const Status& status,
|
||||||
|
PvaClientPutGetPtr const & clientPutGet) {}
|
||||||
|
virtual void getPutDone(
|
||||||
|
const Status& status,
|
||||||
|
PvaClientPutGetPtr const & clientPutGet) = 0;
|
||||||
|
virtual void getGetDone(
|
||||||
|
const Status& status,
|
||||||
|
PvaClientPutGetPtr const & clientPutGet) = 0;
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<p>The client must call</p>
|
||||||
|
<pre>
|
||||||
|
pvaClientPutGet->setRequester(shared_from_this());
|
||||||
|
</pre>
|
||||||
|
<p>
|
||||||
|
after creating an instance of PvaClientPutGet.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
||||||
@@ -0,0 +1,63 @@
|
|||||||
|
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||||
|
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
|
||||||
|
<title>PvaClientPutRequester</title>
|
||||||
|
<link rel="stylesheet" type="text/css"
|
||||||
|
href="http://epics-pvdata.sourceforge.net/base.css" />
|
||||||
|
<link rel="stylesheet" type="text/css"
|
||||||
|
href="http://epics-pvdata.sourceforge.net/epicsv4.css" />
|
||||||
|
<style type="text/css">
|
||||||
|
/*<![CDATA[*/
|
||||||
|
.about { margin-left: 3em; margin-right: 3em; font-size: .83em}
|
||||||
|
table { margin-left: auto; margin-right: auto }
|
||||||
|
.diagram { text-align: center; margin: 2.5em 0 }
|
||||||
|
span.opt { color: grey }
|
||||||
|
span.nterm { font-style:italic }
|
||||||
|
span.term { font-family:courier }
|
||||||
|
span.user { font-family:courier }
|
||||||
|
span.user:before { content:"<" }
|
||||||
|
span.user:after { content:">" }
|
||||||
|
.nonnorm { font-style:italic }
|
||||||
|
p.ed { color: #AA0000 }
|
||||||
|
span.ed { color: #AA0000 }
|
||||||
|
p.ed.priv { display: inline; }
|
||||||
|
span.ed.priv { display: inline; }
|
||||||
|
/*]]>*/</style>
|
||||||
|
<!-- Script that generates the Table of Contents -->
|
||||||
|
<script type="text/javascript"
|
||||||
|
src="http://epics-pvdata.sourceforge.net/script/tocgen.js">
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<h1>PvaClientPutRequester</h1>
|
||||||
|
|
||||||
|
<p>This is a virtual class that can be implemented by a client that uses <b>PvaClientPut</b>.
|
||||||
|
It has the methods:</p>
|
||||||
|
<pre>
|
||||||
|
virtual void channelPutConnect(
|
||||||
|
const Status& status,
|
||||||
|
PvaClientPutPtr const & clientPut) {}
|
||||||
|
virtual void getDone(
|
||||||
|
const Status& status,
|
||||||
|
PvaClientPutPtr const & clientPut) {}
|
||||||
|
virtual void putDone(
|
||||||
|
const Status& status,
|
||||||
|
PvaClientPutPtr const & clientPut) = 0;
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<p>The client must call</p>
|
||||||
|
<pre>
|
||||||
|
pvaClientPut->setRequester(shared_from_this());
|
||||||
|
</pre>
|
||||||
|
<p>
|
||||||
|
after creating an instance of PvaClientPut.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||||
|
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
|
||||||
|
<title>PvaClientRPC</title>
|
||||||
|
<link rel="stylesheet" type="text/css"
|
||||||
|
href="http://epics-pvdata.sourceforge.net/base.css" />
|
||||||
|
<link rel="stylesheet" type="text/css"
|
||||||
|
href="http://epics-pvdata.sourceforge.net/epicsv4.css" />
|
||||||
|
<style type="text/css">
|
||||||
|
/*<![CDATA[*/
|
||||||
|
.about { margin-left: 3em; margin-right: 3em; font-size: .83em}
|
||||||
|
table { margin-left: auto; margin-right: auto }
|
||||||
|
.diagram { text-align: center; margin: 2.5em 0 }
|
||||||
|
span.opt { color: grey }
|
||||||
|
span.nterm { font-style:italic }
|
||||||
|
span.term { font-family:courier }
|
||||||
|
span.user { font-family:courier }
|
||||||
|
span.user:before { content:"<" }
|
||||||
|
span.user:after { content:">" }
|
||||||
|
.nonnorm { font-style:italic }
|
||||||
|
p.ed { color: #AA0000 }
|
||||||
|
span.ed { color: #AA0000 }
|
||||||
|
p.ed.priv { display: inline; }
|
||||||
|
span.ed.priv { display: inline; }
|
||||||
|
/*]]>*/</style>
|
||||||
|
<!-- Script that generates the Table of Contents -->
|
||||||
|
<script type="text/javascript"
|
||||||
|
src="http://epics-pvdata.sourceforge.net/script/tocgen.js">
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<h1>PvaClientRPC</h1>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<b>Not Yet Written</b>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||||
|
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
|
||||||
|
<title>PvaClientRPCRequester</title>
|
||||||
|
<link rel="stylesheet" type="text/css"
|
||||||
|
href="http://epics-pvdata.sourceforge.net/base.css" />
|
||||||
|
<link rel="stylesheet" type="text/css"
|
||||||
|
href="http://epics-pvdata.sourceforge.net/epicsv4.css" />
|
||||||
|
<style type="text/css">
|
||||||
|
/*<![CDATA[*/
|
||||||
|
.about { margin-left: 3em; margin-right: 3em; font-size: .83em}
|
||||||
|
table { margin-left: auto; margin-right: auto }
|
||||||
|
.diagram { text-align: center; margin: 2.5em 0 }
|
||||||
|
span.opt { color: grey }
|
||||||
|
span.nterm { font-style:italic }
|
||||||
|
span.term { font-family:courier }
|
||||||
|
span.user { font-family:courier }
|
||||||
|
span.user:before { content:"<" }
|
||||||
|
span.user:after { content:">" }
|
||||||
|
.nonnorm { font-style:italic }
|
||||||
|
p.ed { color: #AA0000 }
|
||||||
|
span.ed { color: #AA0000 }
|
||||||
|
p.ed.priv { display: inline; }
|
||||||
|
span.ed.priv { display: inline; }
|
||||||
|
/*]]>*/</style>
|
||||||
|
<!-- Script that generates the Table of Contents -->
|
||||||
|
<script type="text/javascript"
|
||||||
|
src="http://epics-pvdata.sourceforge.net/script/tocgen.js">
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<h1>PvaClientRPCRequester</h1>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<b>Not Yet Written</b>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
||||||
@@ -4,7 +4,7 @@
|
|||||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||||
<head>
|
<head>
|
||||||
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
|
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
|
||||||
<title>EPICS pva</title>
|
<title>EPICS pvaClientCPP</title>
|
||||||
<link rel="stylesheet" type="text/css"
|
<link rel="stylesheet" type="text/css"
|
||||||
href="http://epics-pvdata.sourceforge.net/base.css" />
|
href="http://epics-pvdata.sourceforge.net/base.css" />
|
||||||
<link rel="stylesheet" type="text/css"
|
<link rel="stylesheet" type="text/css"
|
||||||
@@ -26,13 +26,13 @@
|
|||||||
|
|
||||||
<div class="head">
|
<div class="head">
|
||||||
<h1>EPICS pvaClientCPP</h1>
|
<h1>EPICS pvaClientCPP</h1>
|
||||||
<h2 class="nocount">Release 4.2.0-SNAPSHOT - 2016-07-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,40 +62,32 @@ The data for the channels is presented via normative type NTMultiChannel.
|
|||||||
|
|
||||||
</div> <!-- head -->
|
</div> <!-- head -->
|
||||||
|
|
||||||
<div id="toc">
|
<div id="contents" class="contents">
|
||||||
<h2 class="nocount">Table of Contents</h2>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Place what you would like in the Table of Contents, inside the contents div -->
|
|
||||||
<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>
|
||||||
</p>
|
</p>
|
||||||
<p>This document is only a guide to help locate code and documentation related to pvDatabaseCPP
|
<p>This document is only a guide to help locate code and documentation related to pvaClientCPP
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
It is intended for developers that want to use pvDatabaseCPP.
|
It is intended for developers that want to use pvaClientCPP.
|
||||||
</p>
|
</p>
|
||||||
<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>
|
||||||
<p>This guide discusses all the components that are part of an <b>EPICS V4</b> release.
|
<p>This guide provides an overview of the components that are part of an <b>EPICS V4</b> release.
|
||||||
Some understanding of the components and how they are related is necessary in order to
|
Some understanding of the components and how they are related is necessary in order to
|
||||||
develop code that uses pvDatabaseCPP.
|
develop code that uses pvaClientCPP.
|
||||||
In particular read everything related to pvaClient.
|
In particular read everything related to pvaClient.
|
||||||
</p>
|
</p>
|
||||||
<p>The developerGuide discusses code in a way that applies to both CPP and C++.
|
|
||||||
For the descriptions of the CPP specific code consult the next section.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h2>doxygen</h2>
|
<h2>doxygen</h2>
|
||||||
<p>doxygen documentation is available at
|
<p>doxygen documentation is available at
|
||||||
@@ -104,9 +96,9 @@ href="./html/index.html">doxygen</a>
|
|||||||
</p>
|
</p>
|
||||||
|
|
||||||
<h2>exampleCPP</h2>
|
<h2>exampleCPP</h2>
|
||||||
<p>Example code is available as part of this release.
|
<p>Example code is available at
|
||||||
<a
|
<a
|
||||||
href="http://epics-pvdata.sourceforge.net/docbuild/exampleCPP/tip/documentation/exampleCPP.html">
|
href="https://github.com/epics-base/exampleCPP">
|
||||||
exampleCPP
|
exampleCPP
|
||||||
</a>
|
</a>
|
||||||
</p>
|
</p>
|
||||||
|
|||||||
+5
-15
@@ -21,31 +21,22 @@ 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
|
||||||
}
|
}
|
||||||
|
|
||||||
###########################################
|
###########################################
|
||||||
# Defaults for EPICS Base and MB
|
# Defaults for EPICS Base
|
||||||
|
|
||||||
DEFAULT_BASE=3.15.4
|
DEFAULT_BASE=3.15.4
|
||||||
BASE=${BASE:-${DEFAULT_BASE}}
|
BASE=${BASE:-${DEFAULT_BASE}}
|
||||||
MB=${MB:-"NO_MICROBENCH"}
|
|
||||||
|
|
||||||
###########################################
|
###########################################
|
||||||
# Dependent module branches
|
# Dependent module branches
|
||||||
|
|
||||||
PVCOMMON_BRANCH="release-4.2"
|
PVDATA_BRANCH="master"
|
||||||
PVDATA_BRANCH="release-6.0"
|
PVACCESS_BRANCH="master"
|
||||||
PVACCESS_BRANCH="release-5.0"
|
NORMATIVETYPES_BRANCH="master"
|
||||||
NORMATIVETYPES_BRANCH="release-5.1"
|
|
||||||
|
|
||||||
###########################################
|
###########################################
|
||||||
# Fetch and unpack dependencies
|
# Fetch and unpack dependencies
|
||||||
@@ -59,7 +50,6 @@ cd ${STUFF}
|
|||||||
installTool Boost 1.61.0
|
installTool Boost 1.61.0
|
||||||
installTool Base ${BASE}
|
installTool Base ${BASE}
|
||||||
|
|
||||||
installE4 pvCommon ${PVCOMMON_BRANCH}
|
|
||||||
installE4 pvData ${PVDATA_BRANCH}
|
installE4 pvData ${PVDATA_BRANCH}
|
||||||
installE4 pvAccess ${PVACCESS_BRANCH}
|
installE4 pvAccess ${PVACCESS_BRANCH}
|
||||||
installE4 normativeTypes ${NORMATIVETYPES_BRANCH}
|
installE4 normativeTypes ${NORMATIVETYPES_BRANCH}
|
||||||
|
|||||||
@@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+5
-4
@@ -6,12 +6,13 @@ include $(TOP)/configure/CONFIG
|
|||||||
LIBRARY += pvaClient
|
LIBRARY += pvaClient
|
||||||
|
|
||||||
# shared library ABI version.
|
# shared library ABI version.
|
||||||
SHRLIB_VERSION ?= 4.2.0
|
SHRLIB_VERSION ?= $(EPICS_PVACLIENT_MAJOR_VERSION).$(EPICS_PVACLIENT_MINOR_VERSION).$(EPICS_PVACLIENT_MAINTENANCE_VERSION)
|
||||||
|
|
||||||
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
|
||||||
@@ -31,8 +32,8 @@ LIBSRCS += pvaClientNTMultiGet.cpp
|
|||||||
LIBSRCS += pvaClientNTMultiMonitor.cpp
|
LIBSRCS += pvaClientNTMultiMonitor.cpp
|
||||||
LIBSRCS += pvaClientRPC.cpp
|
LIBSRCS += pvaClientRPC.cpp
|
||||||
|
|
||||||
pvaClient_LIBS += pvAccess nt pvData Com
|
pvaClient_LIBS += nt
|
||||||
pvaClient_LIBS += $(EPICS_BASE_IOC_LIBS)
|
pvaClient_LIBS += $(EPICS_BASE_PVA_CORE_LIBS)
|
||||||
|
pvaClient_LIBS += $(EPICS_BASE_IOC_LIBS)
|
||||||
|
|
||||||
include $(TOP)/configure/RULES
|
include $(TOP)/configure/RULES
|
||||||
|
|
||||||
|
|||||||
+503
-341
File diff suppressed because it is too large
Load Diff
@@ -145,10 +145,6 @@ public:
|
|||||||
*/
|
*/
|
||||||
PvaClientNTMultiMonitorPtr createNTMonitor(
|
PvaClientNTMultiMonitorPtr createNTMonitor(
|
||||||
std::string const &request= "field(value,alarm,timeStamp)");
|
std::string const &request= "field(value,alarm,timeStamp)");
|
||||||
/** Deprecated method
|
|
||||||
* \deprecated This method will go away in future versions.
|
|
||||||
*/
|
|
||||||
void destroy() EPICS_DEPRECATED {}
|
|
||||||
private:
|
private:
|
||||||
PvaClientMultiChannel(
|
PvaClientMultiChannel(
|
||||||
PvaClientPtr const &pvaClient,
|
PvaClientPtr const &pvaClient,
|
||||||
@@ -209,10 +205,6 @@ public:
|
|||||||
{
|
{
|
||||||
return shared_from_this();
|
return shared_from_this();
|
||||||
}
|
}
|
||||||
/** Deprecated method
|
|
||||||
* \deprecated This method will go away in future versions.
|
|
||||||
*/
|
|
||||||
void destroy() EPICS_DEPRECATED {}
|
|
||||||
private:
|
private:
|
||||||
PvaClientMultiGetDouble(
|
PvaClientMultiGetDouble(
|
||||||
PvaClientMultiChannelPtr const &pvaClientMultiChannel,
|
PvaClientMultiChannelPtr const &pvaClientMultiChannel,
|
||||||
@@ -262,10 +254,6 @@ public:
|
|||||||
{
|
{
|
||||||
return shared_from_this();
|
return shared_from_this();
|
||||||
}
|
}
|
||||||
/** Deprecated method
|
|
||||||
* \deprecated This method will go away in future versions.
|
|
||||||
*/
|
|
||||||
void destroy() EPICS_DEPRECATED {}
|
|
||||||
private:
|
private:
|
||||||
PvaClientMultiPutDouble(
|
PvaClientMultiPutDouble(
|
||||||
PvaClientMultiChannelPtr const &pvaClientMultiChannel,
|
PvaClientMultiChannelPtr const &pvaClientMultiChannel,
|
||||||
@@ -329,10 +317,6 @@ public:
|
|||||||
{
|
{
|
||||||
return shared_from_this();
|
return shared_from_this();
|
||||||
}
|
}
|
||||||
/** Deprecated method
|
|
||||||
* \deprecated This method will go away in future versions.
|
|
||||||
*/
|
|
||||||
void destroy() EPICS_DEPRECATED {}
|
|
||||||
private:
|
private:
|
||||||
PvaClientMultiMonitorDouble(
|
PvaClientMultiMonitorDouble(
|
||||||
PvaClientMultiChannelPtr const &pvaClientMultiChannel,
|
PvaClientMultiChannelPtr const &pvaClientMultiChannel,
|
||||||
@@ -376,8 +360,10 @@ public:
|
|||||||
void connect();
|
void connect();
|
||||||
/**
|
/**
|
||||||
* @brief Get each channel.
|
* @brief Get each channel.
|
||||||
|
*
|
||||||
|
* @param valueOnly use only value for union.
|
||||||
*/
|
*/
|
||||||
void get();
|
void get(bool valueOnly = true);
|
||||||
/**
|
/**
|
||||||
* @brief Get the data from the last get.
|
* @brief Get the data from the last get.
|
||||||
* @return the pvaClientNTMultiData.
|
* @return the pvaClientNTMultiData.
|
||||||
@@ -390,10 +376,6 @@ public:
|
|||||||
{
|
{
|
||||||
return shared_from_this();
|
return shared_from_this();
|
||||||
}
|
}
|
||||||
/** Deprecated method
|
|
||||||
* \deprecated This method will go away in future versions.
|
|
||||||
*/
|
|
||||||
void destroy() EPICS_DEPRECATED {}
|
|
||||||
private:
|
private:
|
||||||
PvaClientNTMultiGet(
|
PvaClientNTMultiGet(
|
||||||
epics::pvData::UnionConstPtr const & u,
|
epics::pvData::UnionConstPtr const & u,
|
||||||
@@ -453,10 +435,6 @@ public:
|
|||||||
{
|
{
|
||||||
return shared_from_this();
|
return shared_from_this();
|
||||||
}
|
}
|
||||||
/** Deprecated method
|
|
||||||
* \deprecated This method will go away in future versions.
|
|
||||||
*/
|
|
||||||
void destroy() EPICS_DEPRECATED {}
|
|
||||||
private:
|
private:
|
||||||
PvaClientNTMultiPut(
|
PvaClientNTMultiPut(
|
||||||
PvaClientMultiChannelPtr const &pvaClientMultiChannel,
|
PvaClientMultiChannelPtr const &pvaClientMultiChannel,
|
||||||
@@ -500,10 +478,11 @@ public:
|
|||||||
/**
|
/**
|
||||||
* @brief Poll each channel.
|
* @brief Poll each channel.
|
||||||
*
|
*
|
||||||
|
* @param valueOnly use only value for union.
|
||||||
* If any has new data it is used to update the double[].
|
* If any has new data it is used to update the double[].
|
||||||
* @return (false,true) if (no, at least one) value was updated.
|
* @return (false,true) if (no, at least one) value was updated.
|
||||||
*/
|
*/
|
||||||
bool poll();
|
bool poll(bool valueOnly = true);
|
||||||
/**
|
/**
|
||||||
* @brief Wait until poll returns true.
|
* @brief Wait until poll returns true.
|
||||||
* @param secondsToWait The time to keep trying.
|
* @param secondsToWait The time to keep trying.
|
||||||
@@ -523,10 +502,6 @@ public:
|
|||||||
{
|
{
|
||||||
return shared_from_this();
|
return shared_from_this();
|
||||||
}
|
}
|
||||||
/** Deprecated method
|
|
||||||
* \deprecated This method will go away in future versions.
|
|
||||||
*/
|
|
||||||
void destroy() EPICS_DEPRECATED {}
|
|
||||||
private:
|
private:
|
||||||
PvaClientNTMultiMonitor(
|
PvaClientNTMultiMonitor(
|
||||||
epics::pvData::UnionConstPtr const & u,
|
epics::pvData::UnionConstPtr const & u,
|
||||||
@@ -579,11 +554,12 @@ public:
|
|||||||
* @brief Set the timeStamp base for computing deltaTimes.
|
* @brief Set the timeStamp base for computing deltaTimes.
|
||||||
*/
|
*/
|
||||||
void startDeltaTime();
|
void startDeltaTime();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Update NTMultiChannel fields.
|
* @brief Update NTMultiChannel fields.
|
||||||
|
*
|
||||||
|
* @param valueOnly use only value for union.
|
||||||
*/
|
*/
|
||||||
void endDeltaTime();
|
void endDeltaTime(bool valueOnly = true);
|
||||||
/**
|
/**
|
||||||
* @brief Get the time when the last get was made.
|
* @brief Get the time when the last get was made.
|
||||||
* @return The timeStamp.
|
* @return The timeStamp.
|
||||||
@@ -601,17 +577,12 @@ public:
|
|||||||
{
|
{
|
||||||
return shared_from_this();
|
return shared_from_this();
|
||||||
}
|
}
|
||||||
/** Deprecated method
|
|
||||||
* \deprecated This method will go away in future versions.
|
|
||||||
*/
|
|
||||||
void destroy() EPICS_DEPRECATED {}
|
|
||||||
private:
|
private:
|
||||||
PvaClientNTMultiData(
|
PvaClientNTMultiData(
|
||||||
epics::pvData::UnionConstPtr const & u,
|
epics::pvData::UnionConstPtr const & u,
|
||||||
PvaClientMultiChannelPtr const &pvaNTMultiChannel,
|
PvaClientMultiChannelPtr const &pvaNTMultiChannel,
|
||||||
PvaClientChannelArray const &pvaClientChannelArray,
|
PvaClientChannelArray const &pvaClientChannelArray,
|
||||||
epics::pvData::PVStructurePtr const & pvRequest);
|
epics::pvData::PVStructurePtr const & pvRequest);
|
||||||
void setStructure(epics::pvData::StructureConstPtr const & structure,size_t index);
|
|
||||||
void setPVStructure(
|
void setPVStructure(
|
||||||
epics::pvData::PVStructurePtr const &pvStructure,size_t index);
|
epics::pvData::PVStructurePtr const &pvStructure,size_t index);
|
||||||
|
|
||||||
|
|||||||
+34
-13
@@ -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;
|
||||||
@@ -87,7 +86,18 @@ size_t PvaClientChannelCache::cacheSize()
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PvaClient::debug = false;
|
// MSVC doesn't like making this a class static data member:
|
||||||
|
static bool debug = 0;
|
||||||
|
|
||||||
|
void PvaClient::setDebug(bool value)
|
||||||
|
{
|
||||||
|
debug = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PvaClient::getDebug()
|
||||||
|
{
|
||||||
|
return debug;
|
||||||
|
}
|
||||||
|
|
||||||
PvaClientPtr PvaClient::get(std::string const & providerNames)
|
PvaClientPtr PvaClient::get(std::string const & providerNames)
|
||||||
{
|
{
|
||||||
@@ -100,47 +110,58 @@ 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()),
|
||||||
pvaStarted(false),
|
pvaStarted(false),
|
||||||
caStarted(false)
|
caStarted(false),
|
||||||
|
channelRegistry(ChannelProviderRegistry::clients())
|
||||||
{
|
{
|
||||||
stringstream ss(providerNames);
|
stringstream ss(providerNames);
|
||||||
string providerName;
|
string providerName;
|
||||||
|
if(getDebug()) {
|
||||||
|
cout<< "PvaClient::PvaClient()\n";
|
||||||
|
}
|
||||||
while (getline(ss, providerName, ' '))
|
while (getline(ss, providerName, ' '))
|
||||||
{
|
{
|
||||||
ChannelProviderRegistry::shared_pointer registry(getChannelProviderRegistry());
|
|
||||||
if(providerName=="pva") {
|
if(providerName=="pva") {
|
||||||
|
if(getDebug()) {
|
||||||
|
cout<< "calling ClientFactory::start()\n";
|
||||||
|
}
|
||||||
ClientFactory::start();
|
ClientFactory::start();
|
||||||
pvaStarted = true;
|
pvaStarted = true;
|
||||||
} else if(providerName=="ca") {
|
} else if(providerName=="ca") {
|
||||||
|
if(getDebug()) {
|
||||||
|
cout<< "calling CAClientFactory::start()\n";
|
||||||
|
}
|
||||||
CAClientFactory::start();
|
CAClientFactory::start();
|
||||||
caStarted = true;
|
caStarted = true;
|
||||||
} else {
|
} else {
|
||||||
if(!registry->getProvider(providerName)) {
|
if(!channelRegistry->getProvider(providerName)) {
|
||||||
cerr << "PvaClient::get provider " << providerName << " not known" << endl;
|
cerr << "PvaClient::get provider " << providerName << " not known" << endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PvaClient::~PvaClient() {
|
PvaClient::~PvaClient() {
|
||||||
if(PvaClient::debug) {
|
if(getDebug()) {
|
||||||
cout<< "PvaClient::~PvaClient()\n"
|
cout<< "PvaClient::~PvaClient()\n"
|
||||||
<< "pvaChannel cache:\n";
|
<< "pvaChannel cache:\n";
|
||||||
showCache();
|
showCache();
|
||||||
}
|
}
|
||||||
if(pvaStarted){
|
if(pvaStarted){
|
||||||
if(PvaClient::debug) cout<< "calling ClientFactory::stop()\n";
|
if(getDebug()) cout<< "calling ClientFactory::stop()\n";
|
||||||
ClientFactory::stop();
|
ClientFactory::stop();
|
||||||
if(PvaClient::debug) cout<< "after calling ClientFactory::stop()\n";
|
if(getDebug()) cout<< "after calling ClientFactory::stop()\n";
|
||||||
}
|
}
|
||||||
if(caStarted) {
|
if(caStarted) {
|
||||||
if(PvaClient::debug) cout<< "calling CAClientFactory::stop()\n";
|
if(getDebug()) cout<< "calling CAClientFactory::stop()\n";
|
||||||
CAClientFactory::stop();
|
CAClientFactory::stop();
|
||||||
if(PvaClient::debug) cout<< "after calling CAClientFactory::stop()\n";
|
if(getDebug()) cout<< "after calling CAClientFactory::stop()\n";
|
||||||
}
|
}
|
||||||
|
channelRegistry.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
string PvaClient:: getRequesterName()
|
string PvaClient:: getRequesterName()
|
||||||
@@ -210,4 +231,4 @@ size_t PvaClient::cacheSize()
|
|||||||
}
|
}
|
||||||
|
|
||||||
}}
|
}}
|
||||||
|
|
||||||
|
|||||||
+103
-81
@@ -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;
|
||||||
@@ -122,60 +121,12 @@ size_t PvaClientPutCache::cacheSize()
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class epicsShareClass ChannelRequesterImpl : public ChannelRequester
|
|
||||||
{
|
|
||||||
PvaClientChannel::weak_pointer pvaClientChannel;
|
|
||||||
PvaClient::weak_pointer pvaClient;
|
|
||||||
public:
|
|
||||||
ChannelRequesterImpl(
|
|
||||||
PvaClientChannelPtr const & pvaClientChannel,
|
|
||||||
PvaClientPtr const &pvaClient)
|
|
||||||
: pvaClientChannel(pvaClientChannel),
|
|
||||||
pvaClient(pvaClient)
|
|
||||||
{}
|
|
||||||
virtual ~ChannelRequesterImpl() {
|
|
||||||
if(PvaClient::getDebug()) std::cout << "~ChannelRequesterImpl" << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual std::string getRequesterName() {
|
|
||||||
PvaClientChannelPtr clientChannel(pvaClientChannel.lock());
|
|
||||||
if(!clientChannel) return string("clientChannel is null");
|
|
||||||
return clientChannel->getRequesterName();
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void message(std::string const & message, epics::pvData::MessageType messageType) {
|
|
||||||
PvaClientChannelPtr clientChannel(pvaClientChannel.lock());
|
|
||||||
if(!clientChannel) return;
|
|
||||||
clientChannel->message(message,messageType);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void channelCreated(
|
|
||||||
const epics::pvData::Status& status,
|
|
||||||
Channel::shared_pointer const & channel)
|
|
||||||
{
|
|
||||||
PvaClientChannelPtr clientChannel(pvaClientChannel.lock());
|
|
||||||
if(!clientChannel) return;
|
|
||||||
clientChannel->channelCreated(status,channel);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void channelStateChange(
|
|
||||||
Channel::shared_pointer const & channel,
|
|
||||||
Channel::ConnectionState connectionState)
|
|
||||||
{
|
|
||||||
PvaClientChannelPtr clientChannel(pvaClientChannel.lock());
|
|
||||||
if(!clientChannel) return;
|
|
||||||
clientChannel->channelStateChange(channel,connectionState);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
PvaClientChannelPtr PvaClientChannel::create(
|
PvaClientChannelPtr PvaClientChannel::create(
|
||||||
PvaClientPtr const &pvaClient,
|
PvaClientPtr const &pvaClient,
|
||||||
string const & channelName,
|
string const & channelName,
|
||||||
string const & providerName)
|
string const & providerName)
|
||||||
{
|
{
|
||||||
PvaClientChannelPtr channel(new PvaClientChannel(pvaClient,channelName,providerName));
|
PvaClientChannelPtr channel(new PvaClientChannel(pvaClient,channelName,providerName));
|
||||||
channel->channelRequester = ChannelRequesterImplPtr(
|
|
||||||
new ChannelRequesterImpl(channel,pvaClient));
|
|
||||||
return channel;
|
return channel;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -218,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");
|
||||||
@@ -246,25 +198,28 @@ void PvaClientChannel::channelStateChange(
|
|||||||
<< " " << Channel::ConnectionStateNames[connectionState]
|
<< " " << Channel::ConnectionStateNames[connectionState]
|
||||||
<< endl;
|
<< endl;
|
||||||
}
|
}
|
||||||
|
bool waitingForConnect = false;
|
||||||
|
if(connectState==connectActive) waitingForConnect = true;
|
||||||
|
if(connectionState!=Channel::CONNECTED) {
|
||||||
|
Lock xx(mutex);
|
||||||
|
string mess(channelName +
|
||||||
|
" connection state " + Channel::ConnectionStateNames[connectionState]);
|
||||||
|
message(mess,errorMessage);
|
||||||
|
connectState = notConnected;
|
||||||
|
} else {
|
||||||
|
Lock xx(mutex);
|
||||||
|
this->channel = channel;
|
||||||
|
connectState = connected;
|
||||||
|
}
|
||||||
|
if(waitingForConnect) {
|
||||||
|
Lock xx(mutex);
|
||||||
|
waitForConnect.signal();
|
||||||
|
}
|
||||||
PvaClientChannelStateChangeRequesterPtr req(stateChangeRequester.lock());
|
PvaClientChannelStateChangeRequesterPtr req(stateChangeRequester.lock());
|
||||||
if(req) {
|
if(req) {
|
||||||
bool value = (connectionState==Channel::CONNECTED ? true : false);
|
bool value = (connectionState==Channel::CONNECTED ? true : false);
|
||||||
req->channelStateChange(shared_from_this(),value);
|
req->channelStateChange(shared_from_this(),value);
|
||||||
}
|
}
|
||||||
|
|
||||||
Lock xx(mutex);
|
|
||||||
bool waitingForConnect = false;
|
|
||||||
if(connectState==connectActive) waitingForConnect = true;
|
|
||||||
if(connectionState!=Channel::CONNECTED) {
|
|
||||||
string mess(channelName +
|
|
||||||
" connection state " + Channel::ConnectionStateNames[connectionState]);
|
|
||||||
message(mess,errorMessage);
|
|
||||||
connectState = notConnected;
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
connectState = connected;
|
|
||||||
}
|
|
||||||
if(waitingForConnect) waitForConnect.signal();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
string PvaClientChannel::getRequesterName()
|
string PvaClientChannel::getRequesterName()
|
||||||
@@ -297,6 +252,9 @@ void PvaClientChannel::setStateChangeRequester(
|
|||||||
PvaClientChannelStateChangeRequesterPtr const & stateChangeRequester)
|
PvaClientChannelStateChangeRequesterPtr const & stateChangeRequester)
|
||||||
{
|
{
|
||||||
this->stateChangeRequester = stateChangeRequester;
|
this->stateChangeRequester = stateChangeRequester;
|
||||||
|
bool isConnected = false;
|
||||||
|
if(channel) isConnected = channel->isConnected();
|
||||||
|
stateChangeRequester->channelStateChange(shared_from_this(),isConnected);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PvaClientChannel::connect(double timeout)
|
void PvaClientChannel::connect(double timeout)
|
||||||
@@ -328,13 +286,13 @@ void PvaClientChannel::issueConnect()
|
|||||||
}
|
}
|
||||||
connectState = connectActive;
|
connectState = connectActive;
|
||||||
}
|
}
|
||||||
ChannelProviderRegistry::shared_pointer reg = getChannelProviderRegistry();
|
ChannelProviderRegistry::shared_pointer reg(ChannelProviderRegistry::clients());
|
||||||
ChannelProvider::shared_pointer provider = reg->getProvider(providerName);
|
channelProvider = reg->getProvider(providerName);
|
||||||
if(!provider) {
|
if(!channelProvider) {
|
||||||
throw std::runtime_error(channelName + " provider " + providerName + " not registered");
|
throw std::runtime_error(channelName + " provider " + providerName + " not registered");
|
||||||
}
|
}
|
||||||
if(PvaClient::getDebug()) cout << "PvaClientChannel::issueConnect calling provider->createChannel\n";
|
if(PvaClient::getDebug()) cout << "PvaClientChannel::issueConnect calling provider->createChannel\n";
|
||||||
channel = provider->createChannel(channelName,channelRequester,ChannelProvider::PRIORITY_DEFAULT);
|
channel = channelProvider->createChannel(channelName,shared_from_this(),ChannelProvider::PRIORITY_DEFAULT);
|
||||||
if(!channel) {
|
if(!channel) {
|
||||||
throw std::runtime_error(channelName + " channelCreate failed ");
|
throw std::runtime_error(channelName + " channelCreate failed ");
|
||||||
}
|
}
|
||||||
@@ -348,6 +306,7 @@ Status PvaClientChannel::waitConnect(double timeout)
|
|||||||
}
|
}
|
||||||
{
|
{
|
||||||
Lock xx(mutex);
|
Lock xx(mutex);
|
||||||
|
if(!channel) return Status(Status::STATUSTYPE_ERROR,"");
|
||||||
if(channel->isConnected()) return Status::Ok;
|
if(channel->isConnected()) return Status::Ok;
|
||||||
}
|
}
|
||||||
if(timeout>0.0) {
|
if(timeout>0.0) {
|
||||||
@@ -355,8 +314,9 @@ Status PvaClientChannel::waitConnect(double timeout)
|
|||||||
} else {
|
} else {
|
||||||
waitForConnect.wait();
|
waitForConnect.wait();
|
||||||
}
|
}
|
||||||
|
if(!channel) return Status(Status::STATUSTYPE_ERROR,"pvaClientChannel::waitConnect channel is null");
|
||||||
if(channel->isConnected()) return Status::Ok;
|
if(channel->isConnected()) return Status::Ok;
|
||||||
return Status(Status::STATUSTYPE_ERROR,channelName + " not connected");
|
return Status(Status::STATUSTYPE_ERROR," not connected");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -383,17 +343,19 @@ PvaClientProcessPtr PvaClientChannel::createProcess(PVStructurePtr const & pvRe
|
|||||||
if(connectState!=connected) connect(5.0);
|
if(connectState!=connected) connect(5.0);
|
||||||
PvaClientPtr yyy = pvaClient.lock();
|
PvaClientPtr yyy = pvaClient.lock();
|
||||||
if(!yyy) throw std::runtime_error("PvaClient was destroyed");
|
if(!yyy) throw std::runtime_error("PvaClient was destroyed");
|
||||||
return PvaClientProcess::create(yyy,channel,pvRequest);
|
return PvaClientProcess::create(yyy,shared_from_this(),pvRequest);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
PvaClientGetPtr PvaClientChannel::get(string const & request)
|
PvaClientGetPtr PvaClientChannel::get(string const & request)
|
||||||
{
|
{
|
||||||
PvaClientGetPtr pvaClientGet = pvaClientGetCache->getGet(request);
|
PvaClientGetPtr pvaClientGet = pvaClientGetCache->getGet(request);
|
||||||
if(pvaClientGet) return pvaClientGet;
|
if(!pvaClientGet) {
|
||||||
pvaClientGet = createGet(request);
|
pvaClientGet = createGet(request);
|
||||||
pvaClientGet->connect();
|
pvaClientGet->connect();
|
||||||
pvaClientGetCache->addGet(request,pvaClientGet);
|
pvaClientGetCache->addGet(request,pvaClientGet);
|
||||||
|
}
|
||||||
|
pvaClientGet->get();
|
||||||
return pvaClientGet;
|
return pvaClientGet;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -415,7 +377,27 @@ PvaClientGetPtr PvaClientChannel::createGet(PVStructurePtr const & pvRequest)
|
|||||||
if(connectState!=connected) connect(5.0);
|
if(connectState!=connected) connect(5.0);
|
||||||
PvaClientPtr yyy = pvaClient.lock();
|
PvaClientPtr yyy = pvaClient.lock();
|
||||||
if(!yyy) throw std::runtime_error("PvaClient was destroyed");
|
if(!yyy) throw std::runtime_error("PvaClient was destroyed");
|
||||||
return PvaClientGet::create(yyy,channel,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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -423,10 +405,12 @@ PvaClientPutPtr PvaClientChannel::put(string const & request)
|
|||||||
{
|
{
|
||||||
PvaClientPutPtr pvaClientPut = pvaClientPutCache->getPut(request);
|
PvaClientPutPtr pvaClientPut = pvaClientPutCache->getPut(request);
|
||||||
if(pvaClientPut) return pvaClientPut;
|
if(pvaClientPut) return pvaClientPut;
|
||||||
pvaClientPut = createPut(request);
|
if(!pvaClientPut) {
|
||||||
pvaClientPut->connect();
|
pvaClientPut = createPut(request);
|
||||||
pvaClientPut->get();
|
pvaClientPut->connect();
|
||||||
pvaClientPutCache->addPut(request,pvaClientPut);
|
pvaClientPut->get();
|
||||||
|
pvaClientPutCache->addPut(request,pvaClientPut);
|
||||||
|
}
|
||||||
return pvaClientPut;
|
return pvaClientPut;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -448,7 +432,45 @@ PvaClientPutPtr PvaClientChannel::createPut(PVStructurePtr const & pvRequest)
|
|||||||
if(connectState!=connected) connect(5.0);
|
if(connectState!=connected) connect(5.0);
|
||||||
PvaClientPtr yyy = pvaClient.lock();
|
PvaClientPtr yyy = pvaClient.lock();
|
||||||
if(!yyy) throw std::runtime_error("PvaClient was destroyed");
|
if(!yyy) throw std::runtime_error("PvaClient was destroyed");
|
||||||
return PvaClientPut::create(yyy,channel,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)
|
||||||
@@ -468,7 +490,7 @@ PvaClientPutGetPtr PvaClientChannel::createPutGet(PVStructurePtr const & pvReque
|
|||||||
if(connectState!=connected) connect(5.0);
|
if(connectState!=connected) connect(5.0);
|
||||||
PvaClientPtr yyy = pvaClient.lock();
|
PvaClientPtr yyy = pvaClient.lock();
|
||||||
if(!yyy) throw std::runtime_error("PvaClient was destroyed");
|
if(!yyy) throw std::runtime_error("PvaClient was destroyed");
|
||||||
return PvaClientPutGet::create(yyy,channel,pvRequest);
|
return PvaClientPutGet::create(yyy,shared_from_this(),pvRequest);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -532,7 +554,7 @@ PvaClientMonitorPtr PvaClientChannel::createMonitor(PVStructurePtr const & pvR
|
|||||||
if(connectState!=connected) connect(5.0);
|
if(connectState!=connected) connect(5.0);
|
||||||
PvaClientPtr yyy = pvaClient.lock();
|
PvaClientPtr yyy = pvaClient.lock();
|
||||||
if(!yyy) throw std::runtime_error("PvaClient was destroyed");
|
if(!yyy) throw std::runtime_error("PvaClient was destroyed");
|
||||||
return PvaClientMonitor::create(yyy,channel,pvRequest);
|
return PvaClientMonitor::create(yyy,shared_from_this(),pvRequest);
|
||||||
}
|
}
|
||||||
|
|
||||||
PVStructurePtr PvaClientChannel::rpc(
|
PVStructurePtr PvaClientChannel::rpc(
|
||||||
|
|||||||
@@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}}
|
||||||
+118
-70
@@ -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;
|
||||||
@@ -73,50 +72,66 @@ public:
|
|||||||
|
|
||||||
PvaClientGetPtr PvaClientGet::create(
|
PvaClientGetPtr PvaClientGet::create(
|
||||||
PvaClientPtr const &pvaClient,
|
PvaClientPtr const &pvaClient,
|
||||||
Channel::shared_pointer const & channel,
|
PvaClientChannelPtr const & pvaClientChannel,
|
||||||
PVStructurePtr const &pvRequest)
|
PVStructurePtr const &pvRequest)
|
||||||
{
|
{
|
||||||
PvaClientGetPtr epv(new PvaClientGet(pvaClient,channel,pvRequest));
|
if(PvaClient::getDebug()) {
|
||||||
epv->channelGetRequester = ChannelGetRequesterImplPtr(
|
cout<< "PvaClientGet::create(pvaClient,channelName,pvRequest)\n"
|
||||||
new ChannelGetRequesterImpl(epv,pvaClient));
|
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
|
||||||
return epv;
|
<< " pvRequest " << pvRequest
|
||||||
|
<< endl;
|
||||||
|
}
|
||||||
|
PvaClientGetPtr clientGet(new PvaClientGet(pvaClient,pvaClientChannel,pvRequest));
|
||||||
|
clientGet->channelGetRequester = ChannelGetRequesterImplPtr(
|
||||||
|
new ChannelGetRequesterImpl(clientGet,pvaClient));
|
||||||
|
return clientGet;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
PvaClientGet::PvaClientGet(
|
PvaClientGet::PvaClientGet(
|
||||||
PvaClientPtr const &pvaClient,
|
PvaClientPtr const &pvaClient,
|
||||||
Channel::shared_pointer const & channel,
|
PvaClientChannelPtr const & pvaClientChannel,
|
||||||
PVStructurePtr const &pvRequest)
|
PVStructurePtr const &pvRequest)
|
||||||
: pvaClient(pvaClient),
|
: pvaClient(pvaClient),
|
||||||
channel(channel),
|
pvaClientChannel(pvaClientChannel),
|
||||||
pvRequest(pvRequest),
|
pvRequest(pvRequest),
|
||||||
connectState(connectIdle),
|
connectState(connectIdle),
|
||||||
getState(getIdle)
|
getState(getIdle)
|
||||||
{
|
{
|
||||||
if(PvaClient::getDebug()) {
|
if(PvaClient::getDebug()) {
|
||||||
cout << "PvaClientGet::PvaClientGet::PvaClientGet"
|
cout << "PvaClientGet::PvaClientGet channelName "
|
||||||
<< " channelName " << channel->getChannelName()
|
<< pvaClientChannel->getChannel()->getChannelName() << "\n";
|
||||||
<< endl;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PvaClientGet::~PvaClientGet()
|
PvaClientGet::~PvaClientGet()
|
||||||
{
|
{
|
||||||
if(PvaClient::getDebug()) {
|
if(PvaClient::getDebug()) {
|
||||||
string channelName("disconnected");
|
cout<< "PvaClientGet::~PvaClientGet channelName "
|
||||||
Channel::shared_pointer chan(channel.lock());
|
<< pvaClientChannel->getChannel()->getChannelName() << "\n";
|
||||||
if(chan) channelName = chan->getChannelName();
|
|
||||||
cout<< "PvaClientGet::~PvaClientGet"
|
|
||||||
<< " channelName " << channelName
|
|
||||||
<< endl;
|
|
||||||
}
|
}
|
||||||
if(channelGet) channelGet->destroy();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PvaClientGet::checkGetState()
|
|
||||||
|
void PvaClientGet::checkConnectState()
|
||||||
{
|
{
|
||||||
if(connectState==connectIdle) connect();
|
if(PvaClient::getDebug()) {
|
||||||
if(getState==getIdle) get();
|
cout << "PvaClientGet::checkConnectState channelName "
|
||||||
|
<< pvaClientChannel->getChannel()->getChannelName() << "\n";
|
||||||
|
}
|
||||||
|
if(!pvaClientChannel->getChannel()->isConnected()) {
|
||||||
|
string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName()
|
||||||
|
+ " PvaClientGet::checkConnectState channel not connected ";
|
||||||
|
throw std::runtime_error(message);
|
||||||
|
}
|
||||||
|
if(connectState==connectIdle) {
|
||||||
|
connect();
|
||||||
|
}
|
||||||
|
if(connectState==connectActive){
|
||||||
|
string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName()
|
||||||
|
+ " "
|
||||||
|
+ channelGetConnectStatus.getMessage();
|
||||||
|
throw std::runtime_error(message);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// from ChannelGetRequester
|
// from ChannelGetRequester
|
||||||
@@ -140,24 +155,32 @@ void PvaClientGet::channelGetConnect(
|
|||||||
StructureConstPtr const & structure)
|
StructureConstPtr const & structure)
|
||||||
{
|
{
|
||||||
if(PvaClient::getDebug()) {
|
if(PvaClient::getDebug()) {
|
||||||
string channelName("disconnected");
|
cout << "PvaClientGet::channelGetConnect channelName "
|
||||||
Channel::shared_pointer chan(channel.lock());
|
<< pvaClientChannel->getChannel()->getChannelName()
|
||||||
if(chan) channelName = chan->getChannelName();
|
|
||||||
cout << "PvaClientGet::channelGetConnect"
|
|
||||||
<< " channelName " << channelName
|
|
||||||
<< " status.isOK " << (status.isOK() ? "true" : "false")
|
<< " status.isOK " << (status.isOK() ? "true" : "false")
|
||||||
<< endl;
|
<< "\n";
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
Lock xx(mutex);
|
Lock xx(mutex);
|
||||||
channelGetConnectStatus = status;
|
|
||||||
connectState = connected;
|
|
||||||
this->channelGet = channelGet;
|
this->channelGet = channelGet;
|
||||||
if(status.isOK()) {
|
if(status.isOK()) {
|
||||||
|
channelGetConnectStatus = status;
|
||||||
|
connectState = connected;
|
||||||
pvaClientData = PvaClientGetData::create(structure);
|
pvaClientData = PvaClientGetData::create(structure);
|
||||||
pvaClientData->setMessagePrefix(channelGet->getChannel()->getChannelName());
|
pvaClientData->setMessagePrefix(channelGet->getChannel()->getChannelName());
|
||||||
|
} else {
|
||||||
|
stringstream ss;
|
||||||
|
ss << pvRequest;
|
||||||
|
string message = string("\nPvaClientGet::channelGetConnect)")
|
||||||
|
+ "\npvRequest\n" + ss.str()
|
||||||
|
+ "\nerror\n" + status.getMessage();
|
||||||
|
channelGetConnectStatus = Status(Status::STATUSTYPE_ERROR,message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
PvaClientGetRequesterPtr req(pvaClientGetRequester.lock());
|
||||||
|
if(req) {
|
||||||
|
req->channelGetConnect(status,shared_from_this());
|
||||||
|
}
|
||||||
waitForConnect.signal();
|
waitForConnect.signal();
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -169,57 +192,62 @@ void PvaClientGet::getDone(
|
|||||||
BitSetPtr const & bitSet)
|
BitSetPtr const & bitSet)
|
||||||
{
|
{
|
||||||
if(PvaClient::getDebug()) {
|
if(PvaClient::getDebug()) {
|
||||||
string channelName("disconnected");
|
cout << "PvaClientGet::getDone channelName "
|
||||||
Channel::shared_pointer chan(channel.lock());
|
<< pvaClientChannel->getChannel()->getChannelName()
|
||||||
if(chan) channelName = chan->getChannelName();
|
|
||||||
cout << "PvaClientGet::getDone"
|
|
||||||
<< " channelName " << channelName
|
|
||||||
<< " status.isOK " << (status.isOK() ? "true" : "false")
|
<< " status.isOK " << (status.isOK() ? "true" : "false")
|
||||||
<< endl;
|
<< "\n";
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
Lock xx(mutex);
|
Lock xx(mutex);
|
||||||
channelGetStatus = status;
|
channelGetStatus = status;
|
||||||
|
getState = getComplete;
|
||||||
if(status.isOK()) {
|
if(status.isOK()) {
|
||||||
pvaClientData->setData(pvStructure,bitSet);
|
pvaClientData->setData(pvStructure,bitSet);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
PvaClientGetRequesterPtr req(pvaClientGetRequester.lock());
|
||||||
|
if(req) {
|
||||||
|
req->getDone(status,shared_from_this());
|
||||||
|
}
|
||||||
waitForGet.signal();
|
waitForGet.signal();
|
||||||
}
|
}
|
||||||
|
|
||||||
void PvaClientGet::connect()
|
void PvaClientGet::connect()
|
||||||
{
|
{
|
||||||
|
if(PvaClient::getDebug()) {
|
||||||
|
cout << "PvaClientGet::connect channelName "
|
||||||
|
<< pvaClientChannel->getChannel()->getChannelName() << "\n";
|
||||||
|
}
|
||||||
issueConnect();
|
issueConnect();
|
||||||
Status status = waitConnect();
|
Status status = waitConnect();
|
||||||
if(status.isOK()) return;
|
if(status.isOK()) return;
|
||||||
Channel::shared_pointer chan(channel.lock());
|
string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName()
|
||||||
string channelName("disconnected");
|
|
||||||
if(chan) channelName = chan->getChannelName();
|
|
||||||
string message = string("channel ") + channelName
|
|
||||||
+ " PvaClientGet::connect " + status.getMessage();
|
+ " PvaClientGet::connect " + status.getMessage();
|
||||||
throw std::runtime_error(message);
|
throw std::runtime_error(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PvaClientGet::issueConnect()
|
void PvaClientGet::issueConnect()
|
||||||
{
|
{
|
||||||
Channel::shared_pointer chan(channel.lock());
|
if(PvaClient::getDebug()) {
|
||||||
|
cout << "PvaClientGet::issueConnect channelName "
|
||||||
|
<< pvaClientChannel->getChannel()->getChannelName() << "\n";
|
||||||
|
}
|
||||||
if(connectState!=connectIdle) {
|
if(connectState!=connectIdle) {
|
||||||
string channelName("disconnected");
|
string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName()
|
||||||
if(chan) channelName = chan->getChannelName();
|
|
||||||
string message = string("channel ") + channelName
|
|
||||||
+ " pvaClientGet already connected ";
|
+ " pvaClientGet already connected ";
|
||||||
throw std::runtime_error(message);
|
throw std::runtime_error(message);
|
||||||
}
|
}
|
||||||
if(chan) {
|
connectState = connectActive;
|
||||||
connectState = connectActive;
|
channelGetConnectStatus = Status(Status::STATUSTYPE_ERROR, "connect active");
|
||||||
channelGet = chan->createChannelGet(channelGetRequester,pvRequest);
|
channelGet = pvaClientChannel->getChannel()->createChannelGet(channelGetRequester,pvRequest);
|
||||||
return;
|
|
||||||
}
|
|
||||||
throw std::runtime_error("PvaClientGet::issueConnect channel was destroyed");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Status PvaClientGet::waitConnect()
|
Status PvaClientGet::waitConnect()
|
||||||
{
|
{
|
||||||
|
if(PvaClient::getDebug()) {
|
||||||
|
cout << "PvaClientGet::waitConnect channelName "
|
||||||
|
<< pvaClientChannel->getChannel()->getChannelName() << "\n";
|
||||||
|
}
|
||||||
{
|
{
|
||||||
Lock xx(mutex);
|
Lock xx(mutex);
|
||||||
if(connectState==connected) {
|
if(connectState==connected) {
|
||||||
@@ -227,10 +255,7 @@ Status PvaClientGet::waitConnect()
|
|||||||
return channelGetConnectStatus;
|
return channelGetConnectStatus;
|
||||||
}
|
}
|
||||||
if(connectState!=connectActive) {
|
if(connectState!=connectActive) {
|
||||||
Channel::shared_pointer chan(channel.lock());
|
string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName()
|
||||||
string channelName("disconnected");
|
|
||||||
if(chan) channelName = chan->getChannelName();
|
|
||||||
string message = string("channel ") + channelName
|
|
||||||
+ " PvaClientGet::waitConnect illegal connect state ";
|
+ " PvaClientGet::waitConnect illegal connect state ";
|
||||||
throw std::runtime_error(message);
|
throw std::runtime_error(message);
|
||||||
}
|
}
|
||||||
@@ -242,25 +267,27 @@ Status PvaClientGet::waitConnect()
|
|||||||
|
|
||||||
void PvaClientGet::get()
|
void PvaClientGet::get()
|
||||||
{
|
{
|
||||||
|
if(PvaClient::getDebug()) {
|
||||||
|
cout << "PvaClientGet::get channelName "
|
||||||
|
<< pvaClientChannel->getChannel()->getChannelName() << "\n";
|
||||||
|
}
|
||||||
issueGet();
|
issueGet();
|
||||||
Status status = waitGet();
|
Status status = waitGet();
|
||||||
if(status.isOK()) return;
|
if(status.isOK()) return;
|
||||||
Channel::shared_pointer chan(channel.lock());
|
string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName()
|
||||||
string channelName("disconnected");
|
|
||||||
if(chan) channelName = chan->getChannelName();
|
|
||||||
string message = string("channel ") + channelName
|
|
||||||
+ " PvaClientGet::get " + status.getMessage();
|
+ " PvaClientGet::get " + status.getMessage();
|
||||||
throw std::runtime_error(message);
|
throw std::runtime_error(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PvaClientGet::issueGet()
|
void PvaClientGet::issueGet()
|
||||||
{
|
{
|
||||||
|
if(PvaClient::getDebug()) {
|
||||||
|
cout << "PvaClientGet::issueGet channelName "
|
||||||
|
<< pvaClientChannel->getChannel()->getChannelName() << "\n";
|
||||||
|
}
|
||||||
if(connectState==connectIdle) connect();
|
if(connectState==connectIdle) connect();
|
||||||
if(getState!=getIdle) {
|
if(getState==getActive) {
|
||||||
Channel::shared_pointer chan(channel.lock());
|
string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName()
|
||||||
string channelName("disconnected");
|
|
||||||
if(chan) channelName = chan->getChannelName();
|
|
||||||
string message = string("channel ") + channelName
|
|
||||||
+ " PvaClientGet::issueGet get aleady active ";
|
+ " PvaClientGet::issueGet get aleady active ";
|
||||||
throw std::runtime_error(message);
|
throw std::runtime_error(message);
|
||||||
}
|
}
|
||||||
@@ -270,30 +297,51 @@ void PvaClientGet::issueGet()
|
|||||||
|
|
||||||
Status PvaClientGet::waitGet()
|
Status PvaClientGet::waitGet()
|
||||||
{
|
{
|
||||||
|
if(PvaClient::getDebug()) {
|
||||||
|
cout << "PvaClientGet::waitGet channelName "
|
||||||
|
<< pvaClientChannel->getChannel()->getChannelName() << "\n";
|
||||||
|
}
|
||||||
{
|
{
|
||||||
Lock xx(mutex);
|
Lock xx(mutex);
|
||||||
if(getState==getComplete) {
|
if(getState==getComplete) {
|
||||||
getState =getIdle;
|
getState = getIdle;
|
||||||
return channelGetStatus;
|
return channelGetStatus;
|
||||||
}
|
}
|
||||||
if(getState!=getActive){
|
if(getState!=getActive){
|
||||||
Channel::shared_pointer chan(channel.lock());
|
string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName()
|
||||||
string channelName("disconnected");
|
|
||||||
if(chan) channelName = chan->getChannelName();
|
|
||||||
string message = string("channel ") + channelName
|
|
||||||
+ " PvaClientGet::waitGet llegal get state";
|
+ " PvaClientGet::waitGet llegal get state";
|
||||||
throw std::runtime_error(message);
|
throw std::runtime_error(message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
waitForGet.wait();
|
waitForGet.wait();
|
||||||
getState = getIdle;
|
getState = getComplete;
|
||||||
return channelGetStatus;
|
return channelGetStatus;
|
||||||
}
|
}
|
||||||
PvaClientGetDataPtr PvaClientGet::getData()
|
PvaClientGetDataPtr PvaClientGet::getData()
|
||||||
{
|
{
|
||||||
checkGetState();
|
if(PvaClient::getDebug()) {
|
||||||
|
cout<< "PvaClientGet::getData channelName "
|
||||||
|
<< pvaClientChannel->getChannel()->getChannelName() << "\n";
|
||||||
|
}
|
||||||
|
checkConnectState();
|
||||||
|
if(getState==getIdle) get();
|
||||||
return pvaClientData;
|
return pvaClientData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PvaClientGet::setRequester(PvaClientGetRequesterPtr const & pvaClientGetRequester)
|
||||||
|
{
|
||||||
|
if(PvaClient::getDebug()) {
|
||||||
|
cout << "PvaClientGet::setRequester channelName "
|
||||||
|
<< pvaClientChannel->getChannel()->getChannelName() << "\n";
|
||||||
|
}
|
||||||
|
this->pvaClientGetRequester = pvaClientGetRequester;
|
||||||
|
}
|
||||||
|
|
||||||
|
PvaClientChannelPtr PvaClientGet::getPvaClientChannel()
|
||||||
|
{
|
||||||
|
return pvaClientChannel;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}}
|
}}
|
||||||
|
|||||||
+3
-188
@@ -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,199 +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()) cout << "PvaClientGetData::create\n";
|
||||||
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)
|
||||||
{
|
{}
|
||||||
messagePrefix = "";
|
|
||||||
}
|
|
||||||
|
|
||||||
void PvaClientGetData::checkValue()
|
|
||||||
{
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
}}
|
}}
|
||||||
|
|||||||
+190
-153
@@ -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;
|
||||||
@@ -80,21 +78,51 @@ public:
|
|||||||
|
|
||||||
PvaClientMonitorPtr PvaClientMonitor::create(
|
PvaClientMonitorPtr PvaClientMonitor::create(
|
||||||
PvaClientPtr const &pvaClient,
|
PvaClientPtr const &pvaClient,
|
||||||
Channel::shared_pointer const & channel,
|
PvaClientChannelPtr const & pvaClientChannel,
|
||||||
PVStructurePtr const &pvRequest)
|
PVStructurePtr const &pvRequest)
|
||||||
{
|
{
|
||||||
PvaClientMonitorPtr epv(new PvaClientMonitor(pvaClient,channel,pvRequest));
|
PvaClientMonitorPtr clientMonitor(new PvaClientMonitor(pvaClient,pvaClientChannel,pvRequest));
|
||||||
epv->monitorRequester = MonitorRequesterImplPtr(
|
clientMonitor->monitorRequester = MonitorRequesterImplPtr(
|
||||||
new MonitorRequesterImpl(epv,pvaClient));
|
new MonitorRequesterImpl(clientMonitor,pvaClient));
|
||||||
return epv;
|
return clientMonitor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PvaClientMonitorPtr PvaClientMonitor::create(
|
||||||
|
PvaClientPtr const &pvaClient,
|
||||||
|
std::string const & channelName,
|
||||||
|
std::string const & providerName,
|
||||||
|
std::string const & request,
|
||||||
|
PvaClientChannelStateChangeRequesterPtr const & stateChangeRequester,
|
||||||
|
PvaClientMonitorRequesterPtr const & monitorRequester)
|
||||||
|
{
|
||||||
|
if(PvaClient::getDebug()) {
|
||||||
|
cout<< "PvaClientMonitor::create(pvaClient,channelName,providerName,request,stateChangeRequester,monitorRequester)\n"
|
||||||
|
<< " channelName " << channelName
|
||||||
|
<< " providerName " << providerName
|
||||||
|
<< " request " << request
|
||||||
|
<< endl;
|
||||||
|
}
|
||||||
|
CreateRequest::shared_pointer createRequest(CreateRequest::create());
|
||||||
|
PVStructurePtr pvRequest(createRequest->createRequest(request));
|
||||||
|
if(!pvRequest) throw std::runtime_error(createRequest->getMessage());
|
||||||
|
PvaClientChannelPtr pvaClientChannel = pvaClient->createChannel(channelName,providerName);
|
||||||
|
PvaClientMonitorPtr clientMonitor(new PvaClientMonitor(pvaClient,pvaClientChannel,pvRequest));
|
||||||
|
clientMonitor->monitorRequester = MonitorRequesterImplPtr(
|
||||||
|
new MonitorRequesterImpl(clientMonitor,pvaClient));
|
||||||
|
if(stateChangeRequester) clientMonitor->pvaClientChannelStateChangeRequester = stateChangeRequester;
|
||||||
|
if(monitorRequester) clientMonitor->pvaClientMonitorRequester = monitorRequester;
|
||||||
|
pvaClientChannel->setStateChangeRequester(clientMonitor);
|
||||||
|
pvaClientChannel->issueConnect();
|
||||||
|
return clientMonitor;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
PvaClientMonitor::PvaClientMonitor(
|
PvaClientMonitor::PvaClientMonitor(
|
||||||
PvaClientPtr const &pvaClient,
|
PvaClientPtr const &pvaClient,
|
||||||
Channel::shared_pointer const & channel,
|
PvaClientChannelPtr const & pvaClientChannel,
|
||||||
PVStructurePtr const &pvRequest)
|
PVStructurePtr const &pvRequest)
|
||||||
: pvaClient(pvaClient),
|
: pvaClient(pvaClient),
|
||||||
channel(channel),
|
pvaClientChannel(pvaClientChannel),
|
||||||
pvRequest(pvRequest),
|
pvRequest(pvRequest),
|
||||||
isStarted(false),
|
isStarted(false),
|
||||||
connectState(connectIdle),
|
connectState(connectIdle),
|
||||||
@@ -102,42 +130,73 @@ PvaClientMonitor::PvaClientMonitor(
|
|||||||
userWait(false)
|
userWait(false)
|
||||||
{
|
{
|
||||||
if(PvaClient::getDebug()) {
|
if(PvaClient::getDebug()) {
|
||||||
cout<< "PvaClientMonitor::PvaClientMonitor()"
|
cout<< "PvaClientMonitor::PvaClientMonitor\n"
|
||||||
<< " channelName " << channel->getChannelName()
|
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
|
||||||
<< endl;
|
<< endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PvaClientMonitor::~PvaClientMonitor()
|
PvaClientMonitor::~PvaClientMonitor()
|
||||||
{
|
{
|
||||||
if(PvaClient::getDebug()) cout<< "PvaClientMonitor::~PvaClientMonitor\n";
|
|
||||||
if(PvaClient::getDebug()) {
|
if(PvaClient::getDebug()) {
|
||||||
string channelName("disconnected");
|
|
||||||
Channel::shared_pointer chan(channel.lock());
|
|
||||||
if(chan) channelName = chan->getChannelName();
|
|
||||||
cout<< "PvaClientMonitor::~PvaClientMonitor"
|
cout<< "PvaClientMonitor::~PvaClientMonitor"
|
||||||
<< " channelName " << channelName
|
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
|
||||||
<< endl;
|
<< endl;
|
||||||
}
|
}
|
||||||
if(monitor) {
|
if(monitor) {
|
||||||
if(isStarted) monitor->stop();
|
if(isStarted) monitor->stop();
|
||||||
monitor->destroy();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PvaClientMonitor::channelStateChange(PvaClientChannelPtr const & channel, bool isConnected)
|
||||||
|
{
|
||||||
|
if(PvaClient::getDebug()) {
|
||||||
|
cout<< "PvaClientMonitor::channelStateChange"
|
||||||
|
<< " channelName " << channel->getChannelName()
|
||||||
|
<< " isConnected " << (isConnected ? "true" : "false")
|
||||||
|
<< endl;
|
||||||
|
}
|
||||||
|
if(isConnected&&!monitor)
|
||||||
|
{
|
||||||
|
connectState = connectActive;
|
||||||
|
monitor = pvaClientChannel->getChannel()->createMonitor(monitorRequester,pvRequest);
|
||||||
|
}
|
||||||
|
PvaClientChannelStateChangeRequesterPtr req(pvaClientChannelStateChangeRequester.lock());
|
||||||
|
if(req) {
|
||||||
|
req->channelStateChange(channel,isConnected);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PvaClientMonitor::event(PvaClientMonitorPtr const & monitor)
|
||||||
|
{
|
||||||
|
if(PvaClient::getDebug()) {
|
||||||
|
cout << "PvaClientMonitor::event"
|
||||||
|
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
|
||||||
|
<< endl;
|
||||||
|
}
|
||||||
|
PvaClientMonitorRequesterPtr req(pvaClientMonitorRequester.lock());
|
||||||
|
if(req) req->event(monitor);
|
||||||
|
}
|
||||||
|
|
||||||
void PvaClientMonitor::checkMonitorState()
|
void PvaClientMonitor::checkMonitorState()
|
||||||
{
|
{
|
||||||
if(PvaClient::getDebug()) {
|
if(PvaClient::getDebug()) {
|
||||||
string channelName("disconnected");
|
|
||||||
Channel::shared_pointer chan(channel.lock());
|
|
||||||
if(chan) channelName = chan->getChannelName();
|
|
||||||
cout << "PvaClientMonitor::checkMonitorState"
|
cout << "PvaClientMonitor::checkMonitorState"
|
||||||
<< " channelName " << channelName
|
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
|
||||||
<< " connectState " << connectState
|
<< " connectState " << connectState
|
||||||
<< endl;
|
<< endl;
|
||||||
}
|
}
|
||||||
if(connectState==connectIdle) connect();
|
if(connectState==connectIdle) {
|
||||||
if(connectState==connected && !isStarted) start();
|
connect();
|
||||||
|
if(!isStarted) start();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(connectState==connectActive){
|
||||||
|
string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName()
|
||||||
|
+ " "
|
||||||
|
+ monitorConnectStatus.getMessage();
|
||||||
|
throw std::runtime_error(message);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
string PvaClientMonitor::getRequesterName()
|
string PvaClientMonitor::getRequesterName()
|
||||||
@@ -159,50 +218,63 @@ void PvaClientMonitor::monitorConnect(
|
|||||||
Monitor::shared_pointer const & monitor,
|
Monitor::shared_pointer const & monitor,
|
||||||
StructureConstPtr const & structure)
|
StructureConstPtr const & structure)
|
||||||
{
|
{
|
||||||
Channel::shared_pointer chan(channel.lock());
|
|
||||||
if(PvaClient::getDebug()) {
|
if(PvaClient::getDebug()) {
|
||||||
string channelName("disconnected");
|
|
||||||
Channel::shared_pointer chan(channel.lock());
|
|
||||||
if(chan) channelName = chan->getChannelName();
|
|
||||||
cout << "PvaClientMonitor::monitorConnect"
|
cout << "PvaClientMonitor::monitorConnect"
|
||||||
<< " channelName " << channelName
|
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
|
||||||
<< " status.isOK " << (status.isOK() ? "true" : "false")
|
<< " status.isOK " << (status.isOK() ? "true" : "false")
|
||||||
<< endl;
|
<< endl;
|
||||||
}
|
}
|
||||||
connectStatus = status;
|
{
|
||||||
|
Lock xx(mutex);
|
||||||
|
this->monitor = monitor;
|
||||||
|
if(!status.isOK()) {
|
||||||
|
stringstream ss;
|
||||||
|
ss << pvRequest;
|
||||||
|
string message = string("\nPvaClientMonitor::monitorConnect)")
|
||||||
|
+ "\npvRequest\n" + ss.str()
|
||||||
|
+ "\nerror\n" + status.getMessage();
|
||||||
|
monitorConnectStatus = Status(Status::STATUSTYPE_ERROR,message);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bool signal = (connectState==connectWait) ? true : false;
|
||||||
|
monitorConnectStatus = status;
|
||||||
connectState = connected;
|
connectState = connected;
|
||||||
this->monitor = monitor;
|
|
||||||
if(isStarted) {
|
if(isStarted) {
|
||||||
if(PvaClient::getDebug()) {
|
if(PvaClient::getDebug()) {
|
||||||
string channelName("disconnected");
|
|
||||||
Channel::shared_pointer chan(channel.lock());
|
|
||||||
if(chan) channelName = chan->getChannelName();
|
|
||||||
cout << "PvaClientMonitor::monitorConnect"
|
cout << "PvaClientMonitor::monitorConnect"
|
||||||
<< " channelName " << channelName
|
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
|
||||||
<< " is already started "
|
<< " is already started "
|
||||||
<< endl;
|
<< endl;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(status.isOK() && chan) {
|
pvaClientData = PvaClientMonitorData::create(structure);
|
||||||
pvaClientData = PvaClientMonitorData::create(structure);
|
pvaClientData->setMessagePrefix(pvaClientChannel->getChannel()->getChannelName());
|
||||||
pvaClientData->setMessagePrefix(chan->getChannelName());
|
if(signal) {
|
||||||
|
if(PvaClient::getDebug()) {
|
||||||
|
cout << "PvaClientMonitor::monitorConnect calling waitForConnect.signal\n";
|
||||||
|
}
|
||||||
|
waitForConnect.signal();
|
||||||
|
if(PvaClient::getDebug()) {
|
||||||
|
cout << "PvaClientMonitor::monitorConnect calling start\n";
|
||||||
|
}
|
||||||
|
start();
|
||||||
|
} else {
|
||||||
|
if(PvaClient::getDebug()) {
|
||||||
|
cout << "PvaClientMonitor::monitorConnect calling start\n";
|
||||||
|
}
|
||||||
|
start();
|
||||||
}
|
}
|
||||||
if(PvaClient::getDebug()) {
|
PvaClientMonitorRequesterPtr req(pvaClientMonitorRequester.lock());
|
||||||
cout << "PvaClientMonitor::monitorConnect calling waitForConnect.signal\n";
|
if(req) req->monitorConnect(status,shared_from_this(),structure);
|
||||||
}
|
|
||||||
waitForConnect.signal();
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PvaClientMonitor::monitorEvent(MonitorPtr const & monitor)
|
void PvaClientMonitor::monitorEvent(MonitorPtr const & monitor)
|
||||||
{
|
{
|
||||||
if(PvaClient::getDebug()) {
|
if(PvaClient::getDebug()) {
|
||||||
string channelName("disconnected");
|
|
||||||
Channel::shared_pointer chan(channel.lock());
|
|
||||||
if(chan) channelName = chan->getChannelName();
|
|
||||||
cout << "PvaClientMonitor::monitorEvent"
|
cout << "PvaClientMonitor::monitorEvent"
|
||||||
<< " channelName " << channelName
|
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
|
||||||
<< endl;
|
<< endl;
|
||||||
}
|
}
|
||||||
PvaClientMonitorRequesterPtr req = pvaClientMonitorRequester.lock();
|
PvaClientMonitorRequesterPtr req = pvaClientMonitorRequester.lock();
|
||||||
@@ -218,10 +290,7 @@ void PvaClientMonitor::unlisten(MonitorPtr const & monitor)
|
|||||||
req->unlisten();
|
req->unlisten();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
string channelName("disconnected");
|
cerr << pvaClientChannel->getChannel()->getChannelName() + "pvaClientMonitor::unlisten called but no PvaClientMonitorRequester\n";
|
||||||
Channel::shared_pointer chan(channel.lock());
|
|
||||||
if(chan) channelName = chan->getChannelName();
|
|
||||||
cerr << channelName + "pvaClientMonitor::unlisten called but no PvaClientMonitorRequester\n";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -231,11 +300,8 @@ void PvaClientMonitor::connect()
|
|||||||
issueConnect();
|
issueConnect();
|
||||||
Status status = waitConnect();
|
Status status = waitConnect();
|
||||||
if(status.isOK()) return;
|
if(status.isOK()) return;
|
||||||
Channel::shared_pointer chan(channel.lock());
|
|
||||||
string channelName("disconnected");
|
|
||||||
if(chan) channelName = chan->getChannelName();
|
|
||||||
string message = string("channel ")
|
string message = string("channel ")
|
||||||
+ channelName
|
+ pvaClientChannel->getChannel()->getChannelName()
|
||||||
+ " PvaClientMonitor::connect "
|
+ " PvaClientMonitor::connect "
|
||||||
+ status.getMessage();
|
+ status.getMessage();
|
||||||
throw std::runtime_error(message);
|
throw std::runtime_error(message);
|
||||||
@@ -244,59 +310,50 @@ void PvaClientMonitor::connect()
|
|||||||
void PvaClientMonitor::issueConnect()
|
void PvaClientMonitor::issueConnect()
|
||||||
{
|
{
|
||||||
if(PvaClient::getDebug()) cout << "PvaClientMonitor::issueConnect\n";
|
if(PvaClient::getDebug()) cout << "PvaClientMonitor::issueConnect\n";
|
||||||
Channel::shared_pointer chan(channel.lock());
|
|
||||||
if(connectState!=connectIdle) {
|
if(connectState!=connectIdle) {
|
||||||
string channelName("disconnected");
|
|
||||||
if(chan) channelName = chan->getChannelName();
|
|
||||||
string message = string("channel ")
|
string message = string("channel ")
|
||||||
+ channelName
|
+ pvaClientChannel->getChannel()->getChannelName()
|
||||||
+ " pvaClientMonitor already connected ";
|
+ " pvaClientMonitor already connected ";
|
||||||
throw std::runtime_error(message);
|
throw std::runtime_error(message);
|
||||||
}
|
}
|
||||||
if(chan) {
|
connectState = connectWait;
|
||||||
connectState = connectActive;
|
monitor = pvaClientChannel->getChannel()->createMonitor(monitorRequester,pvRequest);
|
||||||
monitor = chan->createMonitor(monitorRequester,pvRequest);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
throw std::runtime_error("PvaClientMonitor::issueConnect() but channel disconnected");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Status PvaClientMonitor::waitConnect()
|
Status PvaClientMonitor::waitConnect()
|
||||||
{
|
{
|
||||||
if(PvaClient::getDebug()) cout << "PvaClientMonitor::waitConnect\n";
|
|
||||||
if(connectState==connected) {
|
|
||||||
if(!connectStatus.isOK()) connectState = connectIdle;
|
|
||||||
return connectStatus;
|
|
||||||
}
|
|
||||||
if(connectState!=connectActive) {
|
|
||||||
Channel::shared_pointer chan(channel.lock());
|
|
||||||
string channelName("disconnected");
|
|
||||||
if(chan) channelName = chan->getChannelName();
|
|
||||||
string message = string("channel ")
|
|
||||||
+ channelName
|
|
||||||
+ " PvaClientMonitor::waitConnect illegal connect state ";
|
|
||||||
throw std::runtime_error(message);
|
|
||||||
}
|
|
||||||
if(PvaClient::getDebug()) {
|
if(PvaClient::getDebug()) {
|
||||||
cout << "PvaClientMonitor::waitConnect calling waitForConnect.wait\n";
|
cout << "PvaClientMonitor::waitConnect "
|
||||||
|
<< pvaClientChannel->getChannel()->getChannelName()
|
||||||
|
<< endl;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
Lock xx(mutex);
|
||||||
|
if(connectState==connected) {
|
||||||
|
if(!monitorConnectStatus.isOK()) connectState = connectIdle;
|
||||||
|
return monitorConnectStatus;
|
||||||
|
}
|
||||||
|
if(connectState!=connectWait) {
|
||||||
|
string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName()
|
||||||
|
+ " PvaClientMonitor::waitConnect illegal connect state ";
|
||||||
|
throw std::runtime_error(message);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
waitForConnect.wait();
|
waitForConnect.wait();
|
||||||
connectState = connectStatus.isOK() ? connected : connectIdle;
|
connectState = monitorConnectStatus.isOK() ? connected : connectIdle;
|
||||||
if(PvaClient::getDebug()) {
|
if(PvaClient::getDebug()) {
|
||||||
cout << "PvaClientMonitor::waitConnect"
|
cout << "PvaClientMonitor::waitConnect"
|
||||||
<< " connectStatus " << (connectStatus.isOK() ? "connected" : "not connected");
|
<< " monitorConnectStatus " << (monitorConnectStatus.isOK() ? "connected" : "not connected")
|
||||||
|
<< endl;
|
||||||
}
|
}
|
||||||
return connectStatus;
|
return monitorConnectStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PvaClientMonitor::setRequester(PvaClientMonitorRequesterPtr const & pvaClientMonitorRequester)
|
void PvaClientMonitor::setRequester(PvaClientMonitorRequesterPtr const & pvaClientMonitorRequester)
|
||||||
{
|
{
|
||||||
if(PvaClient::getDebug()) {
|
if(PvaClient::getDebug()) {
|
||||||
string channelName("disconnected");
|
|
||||||
Channel::shared_pointer chan(channel.lock());
|
|
||||||
if(chan) channelName = chan->getChannelName();
|
|
||||||
cout << "PvaClientMonitor::setRequester"
|
cout << "PvaClientMonitor::setRequester"
|
||||||
<< " channelName " << channelName
|
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
|
||||||
<< endl;
|
<< endl;
|
||||||
}
|
}
|
||||||
this->pvaClientMonitorRequester = pvaClientMonitorRequester;
|
this->pvaClientMonitorRequester = pvaClientMonitorRequester;
|
||||||
@@ -305,30 +362,17 @@ void PvaClientMonitor::setRequester(PvaClientMonitorRequesterPtr const & pvaClie
|
|||||||
void PvaClientMonitor::start()
|
void PvaClientMonitor::start()
|
||||||
{
|
{
|
||||||
if(PvaClient::getDebug()) {
|
if(PvaClient::getDebug()) {
|
||||||
string channelName("disconnected");
|
|
||||||
Channel::shared_pointer chan(channel.lock());
|
|
||||||
if(chan) channelName = chan->getChannelName();
|
|
||||||
cout << "PvaClientMonitor::start"
|
cout << "PvaClientMonitor::start"
|
||||||
<< " channelName " << channelName
|
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
|
||||||
<< " connectState " << connectState
|
<< " connectState " << connectState
|
||||||
<< endl;
|
<< endl;
|
||||||
}
|
}
|
||||||
if(isStarted) {
|
if(isStarted) {
|
||||||
string channelName("disconnected");
|
|
||||||
Channel::shared_pointer chan(channel.lock());
|
|
||||||
if(chan) channelName = chan->getChannelName();
|
|
||||||
cerr << "PvaClientMonitor::start"
|
|
||||||
<< " channelName " << channelName
|
|
||||||
<< " why is this called twice "
|
|
||||||
<< endl;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(connectState==connectIdle) connect();
|
if(connectState==connectIdle) connect();
|
||||||
if(connectState!=connected) {
|
if(connectState!=connected) {
|
||||||
Channel::shared_pointer chan(channel.lock());
|
string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName()
|
||||||
string channelName("disconnected");
|
|
||||||
if(chan) channelName = chan->getChannelName();
|
|
||||||
string message = string("channel ") + channelName
|
|
||||||
+ " PvaClientMonitor::start illegal state ";
|
+ " PvaClientMonitor::start illegal state ";
|
||||||
throw std::runtime_error(message);
|
throw std::runtime_error(message);
|
||||||
}
|
}
|
||||||
@@ -336,15 +380,45 @@ void PvaClientMonitor::start()
|
|||||||
monitor->start();
|
monitor->start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PvaClientMonitor::start(string const & request)
|
||||||
|
{
|
||||||
|
if(PvaClient::getDebug()) {
|
||||||
|
cout<< "PvaMonitor::start(request)"
|
||||||
|
<< " request " << request
|
||||||
|
<< endl;
|
||||||
|
}
|
||||||
|
PvaClientPtr client(pvaClient.lock());
|
||||||
|
if(!client) throw std::runtime_error("pvaClient was deleted");
|
||||||
|
if(!pvaClientChannel->getChannel()->isConnected()) {
|
||||||
|
client->message(
|
||||||
|
"PvaClientMonitor::start(request) but not connected",
|
||||||
|
errorMessage);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
CreateRequest::shared_pointer createRequest(CreateRequest::create());
|
||||||
|
PVStructurePtr pvr(createRequest->createRequest(request));
|
||||||
|
if(!pvr) throw std::runtime_error(createRequest->getMessage());
|
||||||
|
if(monitor) {
|
||||||
|
if(isStarted) monitor->stop();
|
||||||
|
}
|
||||||
|
monitorRequester.reset();
|
||||||
|
monitor.reset();
|
||||||
|
isStarted = false;
|
||||||
|
connectState = connectIdle;
|
||||||
|
userPoll = false;
|
||||||
|
userWait = false;
|
||||||
|
monitorRequester = MonitorRequesterImplPtr(
|
||||||
|
new MonitorRequesterImpl(shared_from_this(),client));
|
||||||
|
pvRequest = pvr;
|
||||||
|
connect();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void PvaClientMonitor::stop()
|
void PvaClientMonitor::stop()
|
||||||
{
|
{
|
||||||
if(PvaClient::getDebug()) {
|
if(PvaClient::getDebug()) {
|
||||||
string channelName("disconnected");
|
|
||||||
Channel::shared_pointer chan(channel.lock());
|
|
||||||
if(chan) channelName = chan->getChannelName();
|
|
||||||
cout << "PvaClientMonitor::stop"
|
cout << "PvaClientMonitor::stop"
|
||||||
<< " channelName " << channelName
|
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
|
||||||
<< endl;
|
<< endl;
|
||||||
}
|
}
|
||||||
if(!isStarted) return;
|
if(!isStarted) return;
|
||||||
@@ -355,30 +429,11 @@ void PvaClientMonitor::stop()
|
|||||||
bool PvaClientMonitor::poll()
|
bool PvaClientMonitor::poll()
|
||||||
{
|
{
|
||||||
if(PvaClient::getDebug()) {
|
if(PvaClient::getDebug()) {
|
||||||
string channelName("disconnected");
|
|
||||||
Channel::shared_pointer chan(channel.lock());
|
|
||||||
if(chan) channelName = chan->getChannelName();
|
|
||||||
cout << "PvaClientMonitor::poll"
|
cout << "PvaClientMonitor::poll"
|
||||||
<< " channelName " << channelName
|
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
|
||||||
<< endl;
|
<< endl;
|
||||||
}
|
}
|
||||||
checkMonitorState();
|
checkMonitorState();
|
||||||
if(!isStarted) {
|
|
||||||
string channelName("disconnected");
|
|
||||||
Channel::shared_pointer chan(channel.lock());
|
|
||||||
if(chan) channelName = chan->getChannelName();
|
|
||||||
string message = string("channel ") + channelName
|
|
||||||
+ " PvaClientMonitor::poll illegal state ";
|
|
||||||
throw std::runtime_error(message);
|
|
||||||
}
|
|
||||||
if(userPoll) {
|
|
||||||
string channelName("disconnected");
|
|
||||||
Channel::shared_pointer chan(channel.lock());
|
|
||||||
if(chan) channelName = chan->getChannelName();
|
|
||||||
string message = string("channel ") + channelName
|
|
||||||
+ " 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;
|
||||||
@@ -389,18 +444,12 @@ bool PvaClientMonitor::poll()
|
|||||||
bool PvaClientMonitor::waitEvent(double secondsToWait)
|
bool PvaClientMonitor::waitEvent(double secondsToWait)
|
||||||
{
|
{
|
||||||
if(PvaClient::getDebug()) {
|
if(PvaClient::getDebug()) {
|
||||||
string channelName("disconnected");
|
|
||||||
Channel::shared_pointer chan(channel.lock());
|
|
||||||
if(chan) channelName = chan->getChannelName();
|
|
||||||
cout << "PvaClientMonitor::waitEvent"
|
cout << "PvaClientMonitor::waitEvent"
|
||||||
<< " channelName " << channelName
|
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
|
||||||
<< endl;
|
<< endl;
|
||||||
}
|
}
|
||||||
if(!isStarted) {
|
if(!isStarted) {
|
||||||
Channel::shared_pointer chan(channel.lock());
|
string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName()
|
||||||
string channelName("disconnected");
|
|
||||||
if(chan) channelName = chan->getChannelName();
|
|
||||||
string message = string("channel ") + channelName
|
|
||||||
+ " PvaClientMonitor::waitEvent illegal state ";
|
+ " PvaClientMonitor::waitEvent illegal state ";
|
||||||
throw std::runtime_error(message);
|
throw std::runtime_error(message);
|
||||||
}
|
}
|
||||||
@@ -418,26 +467,12 @@ bool PvaClientMonitor::waitEvent(double secondsToWait)
|
|||||||
void PvaClientMonitor::releaseEvent()
|
void PvaClientMonitor::releaseEvent()
|
||||||
{
|
{
|
||||||
if(PvaClient::getDebug()) {
|
if(PvaClient::getDebug()) {
|
||||||
string channelName("disconnected");
|
|
||||||
Channel::shared_pointer chan(channel.lock());
|
|
||||||
if(chan) channelName = chan->getChannelName();
|
|
||||||
cout << "PvaClientMonitor::releaseEvent"
|
cout << "PvaClientMonitor::releaseEvent"
|
||||||
<< " channelName " << channelName
|
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
|
||||||
<< endl;
|
<< endl;
|
||||||
}
|
}
|
||||||
if(!isStarted) {
|
|
||||||
Channel::shared_pointer chan(channel.lock());
|
|
||||||
string channelName("disconnected");
|
|
||||||
if(chan) channelName = chan->getChannelName();
|
|
||||||
string message = string("channel ") + channelName
|
|
||||||
+ " PvaClientMonitor::releaseEvent monitor not started ";
|
|
||||||
throw std::runtime_error(message);
|
|
||||||
}
|
|
||||||
if(!userPoll) {
|
if(!userPoll) {
|
||||||
Channel::shared_pointer chan(channel.lock());
|
string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName()
|
||||||
string channelName("disconnected");
|
|
||||||
if(chan) channelName = chan->getChannelName();
|
|
||||||
string message = string("channel ") + channelName
|
|
||||||
+ " PvaClientMonitor::releaseEvent did not call poll";
|
+ " PvaClientMonitor::releaseEvent did not call poll";
|
||||||
throw std::runtime_error(message);
|
throw std::runtime_error(message);
|
||||||
}
|
}
|
||||||
@@ -445,14 +480,16 @@ void PvaClientMonitor::releaseEvent()
|
|||||||
monitor->release(monitorElement);
|
monitor->release(monitorElement);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PvaClientChannelPtr PvaClientMonitor::getPvaClientChannel()
|
||||||
|
{
|
||||||
|
return pvaClientChannel;
|
||||||
|
}
|
||||||
|
|
||||||
PvaClientMonitorDataPtr PvaClientMonitor::getData()
|
PvaClientMonitorDataPtr PvaClientMonitor::getData()
|
||||||
{
|
{
|
||||||
if(PvaClient::getDebug()) {
|
if(PvaClient::getDebug()) {
|
||||||
string channelName("disconnected");
|
|
||||||
Channel::shared_pointer chan(channel.lock());
|
|
||||||
if(chan) channelName = chan->getChannelName();
|
|
||||||
cout << "PvaClientMonitor::getData"
|
cout << "PvaClientMonitor::getData"
|
||||||
<< " channelName " << channelName
|
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
|
||||||
<< endl;
|
<< endl;
|
||||||
}
|
}
|
||||||
checkMonitorState();
|
checkMonitorState();
|
||||||
|
|||||||
@@ -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);
|
|
||||||
}
|
|
||||||
|
|
||||||
}}
|
}}
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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;
|
||||||
@@ -45,10 +44,6 @@ PvaClientNTMultiData::PvaClientNTMultiData(
|
|||||||
gotTimeStamp(false)
|
gotTimeStamp(false)
|
||||||
{
|
{
|
||||||
if(PvaClient::getDebug()) cout<< "PvaClientNTMultiData::PvaClientNTMultiData()\n";
|
if(PvaClient::getDebug()) cout<< "PvaClientNTMultiData::PvaClientNTMultiData()\n";
|
||||||
PVFieldPtr pvValue = pvRequest->getSubField("field.value");
|
|
||||||
if(!pvValue) {
|
|
||||||
throw std::runtime_error("pvRequest did not specify value");
|
|
||||||
}
|
|
||||||
topPVStructure.resize(nchannel);
|
topPVStructure.resize(nchannel);
|
||||||
unionValue.resize(nchannel);
|
unionValue.resize(nchannel);
|
||||||
PVDataCreatePtr pvDataCreate = getPVDataCreate();
|
PVDataCreatePtr pvDataCreate = getPVDataCreate();
|
||||||
@@ -89,18 +84,6 @@ PvaClientNTMultiData::~PvaClientNTMultiData()
|
|||||||
if(PvaClient::getDebug()) cout<< "PvaClientNTMultiData::~PvaClientNTMultiData()\n";
|
if(PvaClient::getDebug()) cout<< "PvaClientNTMultiData::~PvaClientNTMultiData()\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void PvaClientNTMultiData::setStructure(StructureConstPtr const & structure,size_t index)
|
|
||||||
{
|
|
||||||
FieldConstPtr field = structure->getField("value");
|
|
||||||
if(!field) {
|
|
||||||
string message = "channel "
|
|
||||||
+ pvaClientChannelArray[index]->getChannel()->getChannelName()
|
|
||||||
+ " does not have top level value field";
|
|
||||||
throw std::runtime_error(message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void PvaClientNTMultiData::setPVStructure(
|
void PvaClientNTMultiData::setPVStructure(
|
||||||
PVStructurePtr const &pvStructure,size_t index)
|
PVStructurePtr const &pvStructure,size_t index)
|
||||||
{
|
{
|
||||||
@@ -138,26 +121,49 @@ void PvaClientNTMultiData::startDeltaTime()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void PvaClientNTMultiData::endDeltaTime()
|
void PvaClientNTMultiData::endDeltaTime(bool valueOnly)
|
||||||
{
|
{
|
||||||
for(size_t i=0; i<nchannel; ++i)
|
for(size_t i=0; i<nchannel; ++i)
|
||||||
{
|
{
|
||||||
PVStructurePtr pvst = topPVStructure[i];
|
PVStructurePtr pvst = topPVStructure[i];
|
||||||
if(!pvst) {
|
if(!pvst) {
|
||||||
unionValue[i] = PVUnionPtr();
|
unionValue[i] = PVUnionPtr();
|
||||||
} else {
|
} else if(unionValue[i]) {
|
||||||
unionValue[i]->set(pvst->getSubField("value"));
|
if(valueOnly) {
|
||||||
|
PVFieldPtr pvValue = pvst->getSubField("value");
|
||||||
|
if(pvValue) {
|
||||||
|
unionValue[i]->set(pvst->getSubField("value"));
|
||||||
|
} else {
|
||||||
|
unionValue[i] = PVUnionPtr();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
unionValue[i]->set(pvst);
|
||||||
|
}
|
||||||
if(gotAlarm)
|
if(gotAlarm)
|
||||||
{
|
{
|
||||||
severity[i] = pvst->getSubField<PVInt>("alarm.severity")->get();
|
PVIntPtr pvSeverity = pvst->getSubField<PVInt>("alarm.severity");
|
||||||
status[i] = pvst->getSubField<PVInt>("alarm.status")->get();
|
PVIntPtr pvStatus = pvst->getSubField<PVInt>("alarm.status");
|
||||||
message[i] = pvst->getSubField<PVString>("alarm.message")->get();
|
PVStringPtr pvMessage = pvst->getSubField<PVString>("alarm.message");
|
||||||
|
if(pvSeverity&&pvStatus&&pvMessage) {
|
||||||
|
severity[i] = pvSeverity->get();
|
||||||
|
status[i] = pvStatus->get();
|
||||||
|
message[i] = pvMessage->get();
|
||||||
|
} else {
|
||||||
|
severity[i] = undefinedAlarm;
|
||||||
|
status[i] = undefinedStatus;
|
||||||
|
message[i] = "no alarm field";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if(gotTimeStamp)
|
if(gotTimeStamp)
|
||||||
{
|
{
|
||||||
secondsPastEpoch[i] = pvst->getSubField<PVLong>("timeStamp.secondsPastEpoch")->get();
|
PVLongPtr pvEpoch = pvst->getSubField<PVLong>("timeStamp.secondsPastEpoch");
|
||||||
nanoseconds[i] = pvst->getSubField<PVInt>("timeStamp.nanoseconds")->get();
|
PVIntPtr pvNano = pvst->getSubField<PVInt>("timeStamp.nanoseconds");
|
||||||
userTag[i] = pvst->getSubField<PVInt>("timeStamp.userTag")->get();
|
PVIntPtr pvTag = pvst->getSubField<PVInt>("timeStamp.userTag");
|
||||||
|
if(pvEpoch&&pvNano&&pvTag) {
|
||||||
|
secondsPastEpoch[i] = pvEpoch->get();
|
||||||
|
nanoseconds[i] = pvNano->get();
|
||||||
|
userTag[i] = pvTag->get();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
@@ -64,13 +63,10 @@ void PvaClientNTMultiGet::connect()
|
|||||||
{
|
{
|
||||||
pvaClientGet.resize(nchannel);
|
pvaClientGet.resize(nchannel);
|
||||||
shared_vector<epics::pvData::boolean> isConnected = pvaClientMultiChannel->getIsConnected();
|
shared_vector<epics::pvData::boolean> isConnected = pvaClientMultiChannel->getIsConnected();
|
||||||
string request = "value";
|
|
||||||
if(pvRequest->getSubField("field.alarm")) request += ",alarm";
|
|
||||||
if(pvRequest->getSubField("field.timeStamp")) request += ",timeStamp";
|
|
||||||
for(size_t i=0; i<nchannel; ++i)
|
for(size_t i=0; i<nchannel; ++i)
|
||||||
{
|
{
|
||||||
if(isConnected[i]) {
|
if(isConnected[i]) {
|
||||||
pvaClientGet[i] = pvaClientChannelArray[i]->createGet(request);
|
pvaClientGet[i] = pvaClientChannelArray[i]->createGet(pvRequest);
|
||||||
pvaClientGet[i]->issueConnect();
|
pvaClientGet[i]->issueConnect();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -87,7 +83,7 @@ void PvaClientNTMultiGet::connect()
|
|||||||
this->isConnected = true;
|
this->isConnected = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PvaClientNTMultiGet::get()
|
void PvaClientNTMultiGet::get(bool valueOnly)
|
||||||
{
|
{
|
||||||
if(!isConnected) connect();
|
if(!isConnected) connect();
|
||||||
shared_vector<epics::pvData::boolean> isConnected = pvaClientMultiChannel->getIsConnected();
|
shared_vector<epics::pvData::boolean> isConnected = pvaClientMultiChannel->getIsConnected();
|
||||||
@@ -115,7 +111,7 @@ void PvaClientNTMultiGet::get()
|
|||||||
pvaClientNTMultiData->setPVStructure(pvaClientGet[i]->getData()->getPVStructure(),i);
|
pvaClientNTMultiData->setPVStructure(pvaClientGet[i]->getData()->getPVStructure(),i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pvaClientNTMultiData->endDeltaTime();
|
pvaClientNTMultiData->endDeltaTime(valueOnly);
|
||||||
}
|
}
|
||||||
|
|
||||||
PvaClientNTMultiDataPtr PvaClientNTMultiGet::getData()
|
PvaClientNTMultiDataPtr PvaClientNTMultiGet::getData()
|
||||||
|
|||||||
@@ -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;
|
||||||
@@ -68,13 +67,10 @@ void PvaClientNTMultiMonitor::connect()
|
|||||||
{
|
{
|
||||||
pvaClientMonitor.resize(nchannel);
|
pvaClientMonitor.resize(nchannel);
|
||||||
shared_vector<epics::pvData::boolean> isConnected = pvaClientMultiChannel->getIsConnected();
|
shared_vector<epics::pvData::boolean> isConnected = pvaClientMultiChannel->getIsConnected();
|
||||||
string request = "value";
|
|
||||||
if(pvRequest->getSubField("field.alarm")) request += ",alarm";
|
|
||||||
if(pvRequest->getSubField("field.timeStamp")) request += ",timeStamp";
|
|
||||||
for(size_t i=0; i<nchannel; ++i)
|
for(size_t i=0; i<nchannel; ++i)
|
||||||
{
|
{
|
||||||
if(isConnected[i]) {
|
if(isConnected[i]) {
|
||||||
pvaClientMonitor[i] = pvaClientChannelArray[i]->createMonitor(request);
|
pvaClientMonitor[i] = pvaClientChannelArray[i]->createMonitor(pvRequest);
|
||||||
pvaClientMonitor[i]->issueConnect();
|
pvaClientMonitor[i]->issueConnect();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -95,7 +91,7 @@ void PvaClientNTMultiMonitor::connect()
|
|||||||
this->isConnected = true;
|
this->isConnected = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PvaClientNTMultiMonitor::poll()
|
bool PvaClientNTMultiMonitor::poll(bool valueOnly)
|
||||||
{
|
{
|
||||||
if(!isConnected) connect();
|
if(!isConnected) connect();
|
||||||
bool result = false;
|
bool result = false;
|
||||||
@@ -112,7 +108,7 @@ bool PvaClientNTMultiMonitor::poll()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(result) pvaClientNTMultiData->endDeltaTime();
|
if(result) pvaClientNTMultiData->endDeltaTime(valueOnly);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
+129
-31
@@ -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;
|
||||||
@@ -70,33 +69,46 @@ public:
|
|||||||
|
|
||||||
PvaClientProcessPtr PvaClientProcess::create(
|
PvaClientProcessPtr PvaClientProcess::create(
|
||||||
PvaClientPtr const &pvaClient,
|
PvaClientPtr const &pvaClient,
|
||||||
Channel::shared_pointer const & channel,
|
PvaClientChannelPtr const & pvaClientChannel,
|
||||||
PVStructurePtr const &pvRequest)
|
PVStructurePtr const &pvRequest)
|
||||||
{
|
{
|
||||||
PvaClientProcessPtr epv(new PvaClientProcess(pvaClient,channel,pvRequest));
|
if(PvaClient::getDebug()) {
|
||||||
epv->channelProcessRequester = ChannelProcessRequesterImplPtr(
|
cout<< "PvaClientProcess::create(pvaClient,channelName,pvRequest)\n"
|
||||||
new ChannelProcessRequesterImpl(epv,pvaClient));
|
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
|
||||||
return epv;
|
<< " pvRequest " << pvRequest
|
||||||
|
<< endl;
|
||||||
|
}
|
||||||
|
PvaClientProcessPtr channelProcess(new PvaClientProcess(pvaClient,pvaClientChannel,pvRequest));
|
||||||
|
channelProcess->channelProcessRequester = ChannelProcessRequesterImplPtr(
|
||||||
|
new ChannelProcessRequesterImpl(channelProcess,pvaClient));
|
||||||
|
return channelProcess;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
PvaClientProcess::PvaClientProcess(
|
PvaClientProcess::PvaClientProcess(
|
||||||
PvaClientPtr const &pvaClient,
|
PvaClientPtr const &pvaClient,
|
||||||
Channel::shared_pointer const & channel,
|
PvaClientChannelPtr const & pvaClientChannel,
|
||||||
PVStructurePtr const &pvRequest)
|
PVStructurePtr const &pvRequest)
|
||||||
: pvaClient(pvaClient),
|
: pvaClient(pvaClient),
|
||||||
channel(channel),
|
pvaClientChannel(pvaClientChannel),
|
||||||
pvRequest(pvRequest),
|
pvRequest(pvRequest),
|
||||||
connectState(connectIdle),
|
connectState(connectIdle),
|
||||||
processState(processIdle)
|
processState(processIdle)
|
||||||
{
|
{
|
||||||
if(PvaClient::getDebug()) cout<< "PvaClientProcess::PvaClientProcess()\n";
|
if(PvaClient::getDebug()) {
|
||||||
|
cout<< "PvaClientProcess::PvaClientProcess()"
|
||||||
|
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
|
||||||
|
<< endl;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PvaClientProcess::~PvaClientProcess()
|
PvaClientProcess::~PvaClientProcess()
|
||||||
{
|
{
|
||||||
if(PvaClient::getDebug()) cout<< "PvaClientProcess::~PvaClientProcess()\n";
|
if(PvaClient::getDebug()) {
|
||||||
channelProcess->destroy();
|
cout<< "PvaClientProcess::~PvaClientProcess()"
|
||||||
|
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
|
||||||
|
<< endl;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// from ChannelProcessRequester
|
// from ChannelProcessRequester
|
||||||
@@ -118,9 +130,31 @@ void PvaClientProcess::channelProcessConnect(
|
|||||||
const Status& status,
|
const Status& status,
|
||||||
ChannelProcess::shared_pointer const & channelProcess)
|
ChannelProcess::shared_pointer const & channelProcess)
|
||||||
{
|
{
|
||||||
channelProcessConnectStatus = status;
|
if(PvaClient::getDebug()) {
|
||||||
connectState = connected;
|
cout << "PvaClientProcess::channelProcessConnect"
|
||||||
this->channelProcess = channelProcess;
|
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
|
||||||
|
<< " status.isOK " << (status.isOK() ? "true" : "false")
|
||||||
|
<< endl;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
Lock xx(mutex);
|
||||||
|
this->channelProcess = channelProcess;
|
||||||
|
if(status.isOK()) {
|
||||||
|
channelProcessConnectStatus = status;
|
||||||
|
connectState = connected;
|
||||||
|
} else {
|
||||||
|
stringstream ss;
|
||||||
|
ss << pvRequest;
|
||||||
|
string message = string("PvaClientProcess::channelProcessConnect")
|
||||||
|
+ "\npvRequest\n" + ss.str()
|
||||||
|
+ "\nerror\n" + status.getMessage();
|
||||||
|
channelProcessConnectStatus = Status(Status::STATUSTYPE_ERROR,message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PvaClientProcessRequesterPtr req(pvaClientProcessRequester.lock());
|
||||||
|
if(req) {
|
||||||
|
req->channelProcessConnect(status,shared_from_this());
|
||||||
|
}
|
||||||
waitForConnect.signal();
|
waitForConnect.signal();
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -129,40 +163,70 @@ void PvaClientProcess::processDone(
|
|||||||
const Status& status,
|
const Status& status,
|
||||||
ChannelProcess::shared_pointer const & channelProcess)
|
ChannelProcess::shared_pointer const & channelProcess)
|
||||||
{
|
{
|
||||||
channelProcessStatus = status;
|
if(PvaClient::getDebug()) {
|
||||||
processState = processComplete;
|
cout << "PvaClientProcess::processDone"
|
||||||
|
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
|
||||||
|
<< " status.isOK " << (status.isOK() ? "true" : "false")
|
||||||
|
<< endl;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
Lock xx(mutex);
|
||||||
|
channelProcessStatus = status;
|
||||||
|
processState = processComplete;
|
||||||
|
}
|
||||||
|
|
||||||
|
PvaClientProcessRequesterPtr req(pvaClientProcessRequester.lock());
|
||||||
|
if(req) {
|
||||||
|
req->processDone(status,shared_from_this());
|
||||||
|
}
|
||||||
waitForProcess.signal();
|
waitForProcess.signal();
|
||||||
}
|
}
|
||||||
|
|
||||||
void PvaClientProcess::connect()
|
void PvaClientProcess::connect()
|
||||||
{
|
{
|
||||||
|
if(PvaClient::getDebug()) {
|
||||||
|
cout << "PvaClientProcess::connect"
|
||||||
|
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
|
||||||
|
<< endl;
|
||||||
|
}
|
||||||
issueConnect();
|
issueConnect();
|
||||||
Status status = waitConnect();
|
Status status = waitConnect();
|
||||||
if(status.isOK()) return;
|
if(status.isOK()) return;
|
||||||
string message = string("channel ") + channel->getChannelName()
|
string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName()
|
||||||
+ " PvaClientProcess::connect " + status.getMessage();
|
+ " PvaClientProcess::connect " + status.getMessage();
|
||||||
throw std::runtime_error(message);
|
throw std::runtime_error(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PvaClientProcess::issueConnect()
|
void PvaClientProcess::issueConnect()
|
||||||
{
|
{
|
||||||
|
if(PvaClient::getDebug()) {
|
||||||
|
cout << "PvaClientProcess::issueConnect"
|
||||||
|
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
|
||||||
|
<< endl;
|
||||||
|
}
|
||||||
if(connectState!=connectIdle) {
|
if(connectState!=connectIdle) {
|
||||||
string message = string("channel ") + channel->getChannelName()
|
string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName()
|
||||||
+ " pvaClientProcess already connected ";
|
+ " pvaClientProcess already connected ";
|
||||||
throw std::runtime_error(message);
|
throw std::runtime_error(message);
|
||||||
}
|
}
|
||||||
connectState = connectActive;
|
connectState = connectActive;
|
||||||
channelProcess = channel->createChannelProcess(channelProcessRequester,pvRequest);
|
channelProcessConnectStatus = Status(Status::STATUSTYPE_ERROR, "connect active");
|
||||||
|
channelProcess = pvaClientChannel->getChannel()->createChannelProcess(channelProcessRequester,pvRequest);
|
||||||
}
|
}
|
||||||
|
|
||||||
Status PvaClientProcess::waitConnect()
|
Status PvaClientProcess::waitConnect()
|
||||||
{
|
{
|
||||||
|
if(PvaClient::getDebug()) {
|
||||||
|
cout << "PvaClientProcess::waitConnect"
|
||||||
|
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
|
||||||
|
<< endl;
|
||||||
|
}
|
||||||
if(connectState==connected) {
|
if(connectState==connected) {
|
||||||
if(!channelProcessConnectStatus.isOK()) connectState = connectIdle;
|
if(!channelProcessConnectStatus.isOK()) connectState = connectIdle;
|
||||||
return channelProcessConnectStatus;
|
return channelProcessConnectStatus;
|
||||||
}
|
}
|
||||||
if(connectState!=connectActive) {
|
if(connectState!=connectActive) {
|
||||||
string message = string("channel ") + channel->getChannelName()
|
string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName()
|
||||||
+ " pvaClientProcess illegal connect state ";
|
+ " pvaClientProcess illegal connect state ";
|
||||||
throw std::runtime_error(message);
|
throw std::runtime_error(message);
|
||||||
}
|
}
|
||||||
@@ -173,19 +237,29 @@ Status PvaClientProcess::waitConnect()
|
|||||||
|
|
||||||
void PvaClientProcess::process()
|
void PvaClientProcess::process()
|
||||||
{
|
{
|
||||||
|
if(PvaClient::getDebug()) {
|
||||||
|
cout << "PvaClientProcess::process"
|
||||||
|
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
|
||||||
|
<< endl;
|
||||||
|
}
|
||||||
issueProcess();
|
issueProcess();
|
||||||
Status status = waitProcess();
|
Status status = waitProcess();
|
||||||
if(status.isOK()) return;
|
if(status.isOK()) return;
|
||||||
string message = string("channel ") + channel->getChannelName()
|
string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName()
|
||||||
+ " PvaClientProcess::process" + status.getMessage();
|
+ " PvaClientProcess::process" + status.getMessage();
|
||||||
throw std::runtime_error(message);
|
throw std::runtime_error(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PvaClientProcess::issueProcess()
|
void PvaClientProcess::issueProcess()
|
||||||
{
|
{
|
||||||
|
if(PvaClient::getDebug()) {
|
||||||
|
cout << "PvaClientProcess::issueProcess"
|
||||||
|
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
|
||||||
|
<< endl;
|
||||||
|
}
|
||||||
if(connectState==connectIdle) connect();
|
if(connectState==connectIdle) connect();
|
||||||
if(processState!=processIdle) {
|
if(processState==processActive) {
|
||||||
string message = string("channel ") + channel->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);
|
||||||
}
|
}
|
||||||
@@ -195,18 +269,42 @@ void PvaClientProcess::issueProcess()
|
|||||||
|
|
||||||
Status PvaClientProcess::waitProcess()
|
Status PvaClientProcess::waitProcess()
|
||||||
{
|
{
|
||||||
if(processState==processComplete) {
|
if(PvaClient::getDebug()) {
|
||||||
processState = processIdle;
|
cout << "PvaClientProcess::waitProcess"
|
||||||
return channelProcessStatus;
|
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
|
||||||
|
<< endl;
|
||||||
}
|
}
|
||||||
if(processState!=processActive){
|
{
|
||||||
string message = string("channel ") + channel->getChannelName()
|
Lock xx(mutex);
|
||||||
+ " PvaClientProcess::waitProcess llegal process state";
|
if(processState==processComplete) {
|
||||||
throw std::runtime_error(message);
|
processState = processIdle;
|
||||||
|
return channelProcessStatus;
|
||||||
|
}
|
||||||
|
if(processState!=processActive){
|
||||||
|
string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName()
|
||||||
|
+ " PvaClientProcess::waitProcess llegal process state";
|
||||||
|
throw std::runtime_error(message);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
waitForProcess.wait();
|
waitForProcess.wait();
|
||||||
processState = processIdle;
|
processState = processComplete;
|
||||||
return channelProcessStatus;
|
return channelProcessStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PvaClientProcess::setRequester(PvaClientProcessRequesterPtr const & pvaClientProcessRequester)
|
||||||
|
{
|
||||||
|
if(PvaClient::getDebug()) {
|
||||||
|
cout << "PvaClientProcess::setRequester"
|
||||||
|
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
|
||||||
|
<< endl;
|
||||||
|
}
|
||||||
|
this->pvaClientProcessRequester = pvaClientProcessRequester;
|
||||||
|
}
|
||||||
|
|
||||||
|
PvaClientChannelPtr PvaClientProcess::getPvaClientChannel()
|
||||||
|
{
|
||||||
|
return pvaClientChannel;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}}
|
}}
|
||||||
|
|||||||
+163
-95
@@ -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;
|
||||||
@@ -70,7 +69,7 @@ public:
|
|||||||
clientPut->getDone(status,channelPut,pvStructure,bitSet);
|
clientPut->getDone(status,channelPut,pvStructure,bitSet);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void putDone(
|
virtual void putDone(
|
||||||
const Status& status,
|
const Status& status,
|
||||||
ChannelPut::shared_pointer const & channelPut)
|
ChannelPut::shared_pointer const & channelPut)
|
||||||
{
|
{
|
||||||
@@ -82,30 +81,29 @@ public:
|
|||||||
|
|
||||||
PvaClientPutPtr PvaClientPut::create(
|
PvaClientPutPtr PvaClientPut::create(
|
||||||
PvaClientPtr const &pvaClient,
|
PvaClientPtr const &pvaClient,
|
||||||
Channel::shared_pointer const & channel,
|
PvaClientChannelPtr const & pvaClientChannel,
|
||||||
PVStructurePtr const &pvRequest)
|
PVStructurePtr const &pvRequest)
|
||||||
{
|
{
|
||||||
PvaClientPutPtr epv(new PvaClientPut(pvaClient,channel,pvRequest));
|
PvaClientPutPtr clientPut(new PvaClientPut(pvaClient,pvaClientChannel,pvRequest));
|
||||||
epv->channelPutRequester = ChannelPutRequesterImplPtr(
|
clientPut->channelPutRequester = ChannelPutRequesterImplPtr(
|
||||||
new ChannelPutRequesterImpl(epv,pvaClient));
|
new ChannelPutRequesterImpl(clientPut,pvaClient));
|
||||||
return epv;
|
return clientPut;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
PvaClientPut::PvaClientPut(
|
PvaClientPut::PvaClientPut(
|
||||||
PvaClientPtr const &pvaClient,
|
PvaClientPtr const &pvaClient,
|
||||||
Channel::shared_pointer const & channel,
|
PvaClientChannelPtr const & pvaClientChannel,
|
||||||
PVStructurePtr const &pvRequest)
|
PVStructurePtr const &pvRequest)
|
||||||
: pvaClient(pvaClient),
|
: pvaClient(pvaClient),
|
||||||
channel(channel),
|
pvaClientChannel(pvaClientChannel),
|
||||||
pvRequest(pvRequest),
|
pvRequest(pvRequest),
|
||||||
connectState(connectIdle),
|
connectState(connectIdle),
|
||||||
putState(putIdle)
|
putState(putIdle)
|
||||||
{
|
{
|
||||||
if(PvaClient::getDebug()) {
|
if(PvaClient::getDebug()) {
|
||||||
cout<< "PvaClientPut::PvaClientPut"
|
cout<< "PvaClientPut::PvaClientPut"
|
||||||
<< " channelName " << channel->getChannelName()
|
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
|
||||||
<< endl;
|
<< endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -113,21 +111,28 @@ PvaClientPut::PvaClientPut(
|
|||||||
PvaClientPut::~PvaClientPut()
|
PvaClientPut::~PvaClientPut()
|
||||||
{
|
{
|
||||||
if(PvaClient::getDebug()) {
|
if(PvaClient::getDebug()) {
|
||||||
string channelName("disconnected");
|
|
||||||
Channel::shared_pointer chan(channel.lock());
|
|
||||||
if(chan) channelName = chan->getChannelName();
|
|
||||||
cout<< "PvaClientPut::~PvaClientPut"
|
cout<< "PvaClientPut::~PvaClientPut"
|
||||||
<< " channelName " << channelName
|
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
|
||||||
<< endl;
|
<< endl;
|
||||||
}
|
}
|
||||||
if(channelPut) channelPut->destroy();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PvaClientPut::checkPutState()
|
|
||||||
|
void PvaClientPut::checkConnectState()
|
||||||
{
|
{
|
||||||
|
if(PvaClient::getDebug()) {
|
||||||
|
cout << "PvaClientPut::checkConnectState"
|
||||||
|
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
|
||||||
|
<< endl;
|
||||||
|
}
|
||||||
if(connectState==connectIdle){
|
if(connectState==connectIdle){
|
||||||
connect();
|
connect();
|
||||||
get();
|
}
|
||||||
|
if(connectState==connectActive){
|
||||||
|
string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName()
|
||||||
|
+ " "
|
||||||
|
+ channelPutConnectStatus.getMessage();
|
||||||
|
throw std::runtime_error(message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -151,23 +156,32 @@ void PvaClientPut::channelPutConnect(
|
|||||||
StructureConstPtr const & structure)
|
StructureConstPtr const & structure)
|
||||||
{
|
{
|
||||||
if(PvaClient::getDebug()) {
|
if(PvaClient::getDebug()) {
|
||||||
string channelName("disconnected");
|
|
||||||
Channel::shared_pointer chan(channel.lock());
|
|
||||||
if(chan) channelName = chan->getChannelName();
|
|
||||||
cout << "PvaClientPut::channelPutConnect"
|
cout << "PvaClientPut::channelPutConnect"
|
||||||
<< " channelName " << channelName
|
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
|
||||||
<< " status.isOK " << (status.isOK() ? "true" : "false")
|
<< " status.isOK " << (status.isOK() ? "true" : "false")
|
||||||
<< endl;
|
<< endl;
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
Lock xx(mutex);
|
Lock xx(mutex);
|
||||||
channelPutConnectStatus = status;
|
|
||||||
this->channelPut = channelPut;
|
this->channelPut = channelPut;
|
||||||
if(status.isOK()) {
|
if(status.isOK()) {
|
||||||
|
channelPutConnectStatus = status;
|
||||||
|
connectState = connected;
|
||||||
pvaClientData = PvaClientPutData::create(structure);
|
pvaClientData = PvaClientPutData::create(structure);
|
||||||
pvaClientData->setMessagePrefix(channelPut->getChannel()->getChannelName());
|
pvaClientData->setMessagePrefix(channelPut->getChannel()->getChannelName());
|
||||||
|
} else {
|
||||||
|
stringstream ss;
|
||||||
|
ss << pvRequest;
|
||||||
|
string message = string("\nPvaClientPut::channelPutConnect)")
|
||||||
|
+ "\npvRequest\n" + ss.str()
|
||||||
|
+ "\nerror\n" + status.getMessage();
|
||||||
|
channelPutConnectStatus = Status(Status::STATUSTYPE_ERROR,message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
PvaClientPutRequesterPtr req(pvaClientPutRequester.lock());
|
||||||
|
if(req) {
|
||||||
|
req->channelPutConnect(status,shared_from_this());
|
||||||
|
}
|
||||||
waitForConnect.signal();
|
waitForConnect.signal();
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -179,21 +193,26 @@ void PvaClientPut::getDone(
|
|||||||
BitSetPtr const & bitSet)
|
BitSetPtr const & bitSet)
|
||||||
{
|
{
|
||||||
if(PvaClient::getDebug()) {
|
if(PvaClient::getDebug()) {
|
||||||
string channelName("disconnected");
|
|
||||||
Channel::shared_pointer chan(channel.lock());
|
|
||||||
if(chan) channelName = chan->getChannelName();
|
|
||||||
cout << "PvaClientPut::getDone"
|
cout << "PvaClientPut::getDone"
|
||||||
<< " channelName " << channelName
|
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
|
||||||
<< " 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());
|
||||||
|
if(req) {
|
||||||
|
req->getDone(status,shared_from_this());
|
||||||
}
|
}
|
||||||
waitForGetPut.signal();
|
waitForGetPut.signal();
|
||||||
}
|
}
|
||||||
@@ -203,28 +222,35 @@ void PvaClientPut::putDone(
|
|||||||
ChannelPut::shared_pointer const & channelPut)
|
ChannelPut::shared_pointer const & channelPut)
|
||||||
{
|
{
|
||||||
if(PvaClient::getDebug()) {
|
if(PvaClient::getDebug()) {
|
||||||
string channelName("disconnected");
|
|
||||||
Channel::shared_pointer chan(channel.lock());
|
|
||||||
if(chan) channelName = chan->getChannelName();
|
|
||||||
cout << "PvaClientPut::putDone"
|
cout << "PvaClientPut::putDone"
|
||||||
<< " channelName " << channelName
|
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
|
||||||
<< " 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());
|
||||||
|
if(req) {
|
||||||
|
req->putDone(status,shared_from_this());
|
||||||
|
}
|
||||||
waitForGetPut.signal();
|
waitForGetPut.signal();
|
||||||
}
|
}
|
||||||
|
|
||||||
void PvaClientPut::connect()
|
void PvaClientPut::connect()
|
||||||
{
|
{
|
||||||
|
if(PvaClient::getDebug()) {
|
||||||
|
cout << "PvaClientPut::connect"
|
||||||
|
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
|
||||||
|
<< endl;
|
||||||
|
}
|
||||||
issueConnect();
|
issueConnect();
|
||||||
Status status = waitConnect();
|
Status status = waitConnect();
|
||||||
if(status.isOK()) return;
|
if(status.isOK()) return;
|
||||||
Channel::shared_pointer chan(channel.lock());
|
|
||||||
string channelName("disconnected");
|
|
||||||
if(chan) channelName = chan->getChannelName();
|
|
||||||
string message = string("channel ")
|
string message = string("channel ")
|
||||||
+ channelName
|
+ pvaClientChannel->getChannel()->getChannelName()
|
||||||
+ " PvaClientPut::connect "
|
+ " PvaClientPut::connect "
|
||||||
+ status.getMessage();
|
+ status.getMessage();
|
||||||
throw std::runtime_error(message);
|
throw std::runtime_error(message);
|
||||||
@@ -232,24 +258,29 @@ void PvaClientPut::connect()
|
|||||||
|
|
||||||
void PvaClientPut::issueConnect()
|
void PvaClientPut::issueConnect()
|
||||||
{
|
{
|
||||||
Channel::shared_pointer chan(channel.lock());
|
if(PvaClient::getDebug()) {
|
||||||
|
cout << "PvaClientPut::issueConnect"
|
||||||
|
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
|
||||||
|
<< endl;
|
||||||
|
}
|
||||||
if(connectState!=connectIdle) {
|
if(connectState!=connectIdle) {
|
||||||
string channelName("disconnected");
|
string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName()
|
||||||
if(chan) channelName = chan->getChannelName();
|
|
||||||
string message = string("channel ") + channelName
|
|
||||||
+ " pvaClientPut already connected ";
|
+ " pvaClientPut already connected ";
|
||||||
throw std::runtime_error(message);
|
throw std::runtime_error(message);
|
||||||
}
|
}
|
||||||
if(chan) {
|
connectState = connectActive;
|
||||||
connectState = connectActive;
|
channelPutConnectStatus = Status(Status::STATUSTYPE_ERROR, "connect active");
|
||||||
channelPut = chan->createChannelPut(channelPutRequester,pvRequest);
|
channelPut = pvaClientChannel->getChannel()->createChannelPut(channelPutRequester,pvRequest);
|
||||||
return;
|
|
||||||
}
|
|
||||||
throw std::runtime_error("PvaClientPut::issueConnect() but channel disconnected");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Status PvaClientPut::waitConnect()
|
Status PvaClientPut::waitConnect()
|
||||||
{
|
{
|
||||||
|
if(PvaClient::getDebug()) {
|
||||||
|
cout << "PvaClientPut::waitConnect"
|
||||||
|
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
|
||||||
|
<< endl;
|
||||||
|
}
|
||||||
{
|
{
|
||||||
Lock xx(mutex);
|
Lock xx(mutex);
|
||||||
if(connectState==connected) {
|
if(connectState==connected) {
|
||||||
@@ -257,10 +288,7 @@ Status PvaClientPut::waitConnect()
|
|||||||
return channelPutConnectStatus;
|
return channelPutConnectStatus;
|
||||||
}
|
}
|
||||||
if(connectState!=connectActive) {
|
if(connectState!=connectActive) {
|
||||||
Channel::shared_pointer chan(channel.lock());
|
string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName()
|
||||||
string channelName("disconnected");
|
|
||||||
if(chan) channelName = chan->getChannelName();
|
|
||||||
string message = string("channel ") + channelName
|
|
||||||
+ " PvaClientPut::waitConnect illegal connect state ";
|
+ " PvaClientPut::waitConnect illegal connect state ";
|
||||||
throw std::runtime_error(message);
|
throw std::runtime_error(message);
|
||||||
}
|
}
|
||||||
@@ -272,14 +300,16 @@ Status PvaClientPut::waitConnect()
|
|||||||
|
|
||||||
void PvaClientPut::get()
|
void PvaClientPut::get()
|
||||||
{
|
{
|
||||||
|
if(PvaClient::getDebug()) {
|
||||||
|
cout << "PvaClientPut::get"
|
||||||
|
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
|
||||||
|
<< endl;
|
||||||
|
}
|
||||||
issueGet();
|
issueGet();
|
||||||
Status status = waitGet();
|
Status status = waitGet();
|
||||||
if(status.isOK()) return;
|
if(status.isOK()) return;
|
||||||
Channel::shared_pointer chan(channel.lock());
|
|
||||||
string channelName("disconnected");
|
|
||||||
if(chan) channelName = chan->getChannelName();
|
|
||||||
string message = string("channel ")
|
string message = string("channel ")
|
||||||
+ channelName
|
+ pvaClientChannel->getChannel()->getChannelName()
|
||||||
+ " PvaClientPut::get "
|
+ " PvaClientPut::get "
|
||||||
+ status.getMessage();
|
+ status.getMessage();
|
||||||
throw std::runtime_error(message);
|
throw std::runtime_error(message);
|
||||||
@@ -287,13 +317,15 @@ void PvaClientPut::get()
|
|||||||
|
|
||||||
void PvaClientPut::issueGet()
|
void PvaClientPut::issueGet()
|
||||||
{
|
{
|
||||||
|
if(PvaClient::getDebug()) {
|
||||||
|
cout << "PvaClientPut::issueGet"
|
||||||
|
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
|
||||||
|
<< endl;
|
||||||
|
}
|
||||||
if(connectState==connectIdle) connect();
|
if(connectState==connectIdle) connect();
|
||||||
if(putState!=putIdle) {
|
if(putState==getActive || putState==putActive) {
|
||||||
Channel::shared_pointer chan(channel.lock());
|
|
||||||
string channelName("disconnected");
|
|
||||||
if(chan) channelName = chan->getChannelName();
|
|
||||||
string message = string("channel ")
|
string message = string("channel ")
|
||||||
+ channelName
|
+ pvaClientChannel->getChannel()->getChannelName()
|
||||||
+ "PvaClientPut::issueGet get or put aleady active ";
|
+ "PvaClientPut::issueGet get or put aleady active ";
|
||||||
throw std::runtime_error(message);
|
throw std::runtime_error(message);
|
||||||
}
|
}
|
||||||
@@ -303,30 +335,37 @@ void PvaClientPut::issueGet()
|
|||||||
|
|
||||||
Status PvaClientPut::waitGet()
|
Status PvaClientPut::waitGet()
|
||||||
{
|
{
|
||||||
if(putState!=getActive){
|
if(PvaClient::getDebug()) {
|
||||||
Channel::shared_pointer chan(channel.lock());
|
cout << "PvaClientPut::waitGet"
|
||||||
string channelName("disconnected");
|
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
|
||||||
if(chan) channelName = chan->getChannelName();
|
<< endl;
|
||||||
string message = string("channel ")
|
}
|
||||||
+ channelName
|
{
|
||||||
+ " PvaClientPut::waitGet illegal put state";
|
Lock xx(mutex);
|
||||||
throw std::runtime_error(message);
|
if(putState==putComplete) return channelGetPutStatus;
|
||||||
|
if(putState!=getActive){
|
||||||
|
string message = string("channel ")
|
||||||
|
+ pvaClientChannel->getChannel()->getChannelName()
|
||||||
|
+ " PvaClientPut::waitGet illegal put state";
|
||||||
|
throw std::runtime_error(message);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
waitForGetPut.wait();
|
waitForGetPut.wait();
|
||||||
putState = putIdle;
|
|
||||||
return channelGetPutStatus;
|
return channelGetPutStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PvaClientPut::put()
|
void PvaClientPut::put()
|
||||||
{
|
{
|
||||||
|
if(PvaClient::getDebug()) {
|
||||||
|
cout << "PvaClientPut::put"
|
||||||
|
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
|
||||||
|
<< endl;
|
||||||
|
}
|
||||||
issuePut();
|
issuePut();
|
||||||
Status status = waitPut();
|
Status status = waitPut();
|
||||||
if(status.isOK()) return;
|
if(status.isOK()) return;
|
||||||
Channel::shared_pointer chan(channel.lock());
|
|
||||||
string channelName("disconnected");
|
|
||||||
if(chan) channelName = chan->getChannelName();
|
|
||||||
string message = string("channel ")
|
string message = string("channel ")
|
||||||
+ channelName
|
+ pvaClientChannel->getChannel()->getChannelName()
|
||||||
+ " PvaClientPut::put "
|
+ " PvaClientPut::put "
|
||||||
+ status.getMessage();
|
+ status.getMessage();
|
||||||
throw std::runtime_error(message);
|
throw std::runtime_error(message);
|
||||||
@@ -334,14 +373,18 @@ void PvaClientPut::put()
|
|||||||
|
|
||||||
void PvaClientPut::issuePut()
|
void PvaClientPut::issuePut()
|
||||||
{
|
{
|
||||||
|
if(PvaClient::getDebug()) {
|
||||||
|
cout << "PvaClientPut::issuePut"
|
||||||
|
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
|
||||||
|
<< " pvStructure\n" << pvaClientData->getPVStructure()
|
||||||
|
<< " bitSet " << *pvaClientData->getChangedBitSet() << endl
|
||||||
|
<< endl;
|
||||||
|
}
|
||||||
if(connectState==connectIdle) connect();
|
if(connectState==connectIdle) connect();
|
||||||
if(putState!=putIdle) {
|
if(putState==getActive || putState==putActive) {
|
||||||
Channel::shared_pointer chan(channel.lock());
|
|
||||||
string channelName("disconnected");
|
|
||||||
if(chan) channelName = chan->getChannelName();
|
|
||||||
string message = string("channel ")
|
string message = string("channel ")
|
||||||
+ channelName
|
+ 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;
|
||||||
@@ -350,26 +393,51 @@ void PvaClientPut::issuePut()
|
|||||||
|
|
||||||
Status PvaClientPut::waitPut()
|
Status PvaClientPut::waitPut()
|
||||||
{
|
{
|
||||||
if(putState!=putActive){
|
if(PvaClient::getDebug()) {
|
||||||
Channel::shared_pointer chan(channel.lock());
|
cout << "PvaClientPut::waitPut"
|
||||||
string channelName("disconnected");
|
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
|
||||||
if(chan) channelName = chan->getChannelName();
|
<< endl;
|
||||||
string message = string("channel ")
|
}
|
||||||
+ channelName
|
{
|
||||||
+ " PvaClientPut::waitPut illegal put state";
|
Lock xx(mutex);
|
||||||
throw std::runtime_error(message);
|
if(putState==putComplete) return channelGetPutStatus;
|
||||||
|
if(putState!=putActive){
|
||||||
|
string message = string("channel ")
|
||||||
|
+ pvaClientChannel->getChannel()->getChannelName()
|
||||||
|
+ " PvaClientPut::waitPut illegal put state";
|
||||||
|
throw std::runtime_error(message);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
waitForGetPut.wait();
|
waitForGetPut.wait();
|
||||||
putState = putIdle;
|
|
||||||
if(channelGetPutStatus.isOK()) pvaClientData->getChangedBitSet()->clear();
|
if(channelGetPutStatus.isOK()) pvaClientData->getChangedBitSet()->clear();
|
||||||
return channelGetPutStatus;
|
return channelGetPutStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
PvaClientPutDataPtr PvaClientPut::getData()
|
PvaClientPutDataPtr PvaClientPut::getData()
|
||||||
{
|
{
|
||||||
checkPutState();
|
if(PvaClient::getDebug()) {
|
||||||
|
cout<< "PvaClientPut::getData"
|
||||||
|
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
|
||||||
|
<< endl;
|
||||||
|
}
|
||||||
|
checkConnectState();
|
||||||
|
if(putState==putIdle) get();
|
||||||
return pvaClientData;
|
return pvaClientData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PvaClientPut::setRequester(PvaClientPutRequesterPtr const & pvaClientPutRequester)
|
||||||
|
{
|
||||||
|
if(PvaClient::getDebug()) {
|
||||||
|
cout << "PvaClientPut::setRequester"
|
||||||
|
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
|
||||||
|
<< endl;
|
||||||
|
}
|
||||||
|
this->pvaClientPutRequester = pvaClientPutRequester;
|
||||||
|
}
|
||||||
|
|
||||||
|
PvaClientChannelPtr PvaClientPut::getPvaClientChannel()
|
||||||
|
{
|
||||||
|
return pvaClientChannel;
|
||||||
|
}
|
||||||
|
|
||||||
}}
|
}}
|
||||||
|
|||||||
+151
-168
@@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}}
|
}}
|
||||||
|
|||||||
+210
-110
@@ -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;
|
||||||
@@ -96,28 +95,28 @@ public:
|
|||||||
|
|
||||||
PvaClientPutGetPtr PvaClientPutGet::create(
|
PvaClientPutGetPtr PvaClientPutGet::create(
|
||||||
PvaClientPtr const &pvaClient,
|
PvaClientPtr const &pvaClient,
|
||||||
Channel::shared_pointer const & channel,
|
PvaClientChannelPtr const & pvaClientChannel,
|
||||||
PVStructurePtr const &pvRequest)
|
PVStructurePtr const &pvRequest)
|
||||||
{
|
{
|
||||||
PvaClientPutGetPtr epv(new PvaClientPutGet(pvaClient,channel,pvRequest));
|
PvaClientPutGetPtr clientPutGet(new PvaClientPutGet(pvaClient,pvaClientChannel,pvRequest));
|
||||||
epv->channelPutGetRequester = ChannelPutGetRequesterImplPtr(
|
clientPutGet->channelPutGetRequester = ChannelPutGetRequesterImplPtr(
|
||||||
new ChannelPutGetRequesterImpl(epv,pvaClient));
|
new ChannelPutGetRequesterImpl(clientPutGet,pvaClient));
|
||||||
return epv;
|
return clientPutGet;
|
||||||
}
|
}
|
||||||
|
|
||||||
PvaClientPutGet::PvaClientPutGet(
|
PvaClientPutGet::PvaClientPutGet(
|
||||||
PvaClientPtr const &pvaClient,
|
PvaClientPtr const &pvaClient,
|
||||||
Channel::shared_pointer const & channel,
|
PvaClientChannelPtr const & pvaClientChannel,
|
||||||
PVStructurePtr const &pvRequest)
|
PVStructurePtr const &pvRequest)
|
||||||
: pvaClient(pvaClient),
|
: pvaClient(pvaClient),
|
||||||
channel(channel),
|
pvaClientChannel(pvaClientChannel),
|
||||||
pvRequest(pvRequest),
|
pvRequest(pvRequest),
|
||||||
connectState(connectIdle),
|
connectState(connectIdle),
|
||||||
putGetState(putGetIdle)
|
putGetState(putGetIdle)
|
||||||
{
|
{
|
||||||
if(PvaClient::getDebug()) {
|
if(PvaClient::getDebug()) {
|
||||||
cout<< "PvaClientPutGet::PvaClientPutGet"
|
cout<< "PvaClientPutGet::PvaClientPutGet"
|
||||||
<< " channelName " << channel->getChannelName()
|
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
|
||||||
<< endl;
|
<< endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -125,21 +124,27 @@ PvaClientPutGet::PvaClientPutGet(
|
|||||||
PvaClientPutGet::~PvaClientPutGet()
|
PvaClientPutGet::~PvaClientPutGet()
|
||||||
{
|
{
|
||||||
if(PvaClient::getDebug()) {
|
if(PvaClient::getDebug()) {
|
||||||
string channelName("disconnected");
|
|
||||||
Channel::shared_pointer chan(channel.lock());
|
|
||||||
if(chan) channelName = chan->getChannelName();
|
|
||||||
cout<< "PvaClientPutGet::~PvaClientPutGet"
|
cout<< "PvaClientPutGet::~PvaClientPutGet"
|
||||||
<< " channelName " << channelName
|
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
|
||||||
<< endl;
|
<< endl;
|
||||||
}
|
}
|
||||||
channelPutGet->destroy();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PvaClientPutGet::checkPutGetState()
|
void PvaClientPutGet::checkPutGetState()
|
||||||
{
|
{
|
||||||
|
if(PvaClient::getDebug()) {
|
||||||
|
cout << "PvaClientPutGet::checkPutGetState"
|
||||||
|
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
|
||||||
|
<< endl;
|
||||||
|
}
|
||||||
if(connectState==connectIdle){
|
if(connectState==connectIdle){
|
||||||
connect();
|
connect();
|
||||||
getPut();
|
}
|
||||||
|
if(connectState==connectActive){
|
||||||
|
string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName()
|
||||||
|
+ " "
|
||||||
|
+ channelPutGetConnectStatus.getMessage();
|
||||||
|
throw std::runtime_error(message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -165,17 +170,33 @@ void PvaClientPutGet::channelPutGetConnect(
|
|||||||
{
|
{
|
||||||
if(PvaClient::getDebug()) {
|
if(PvaClient::getDebug()) {
|
||||||
cout << "PvaClientPutGet::channelPutGetConnect"
|
cout << "PvaClientPutGet::channelPutGetConnect"
|
||||||
<< " channelName " << channelPutGet->getChannel()->getChannelName()
|
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
|
||||||
<< " status.isOK " << (status.isOK() ? "true" : "false")
|
<< " status.isOK " << (status.isOK() ? "true" : "false")
|
||||||
<< endl;
|
<< endl;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
Lock xx(mutex);
|
||||||
|
this->channelPutGet = channelPutGet;
|
||||||
|
if(status.isOK()) {
|
||||||
|
channelPutGetConnectStatus = status;
|
||||||
|
connectState = connected;
|
||||||
|
pvaClientPutData = PvaClientPutData::create(putStructure);
|
||||||
|
pvaClientPutData->setMessagePrefix(channelPutGet->getChannel()->getChannelName());
|
||||||
|
pvaClientGetData = PvaClientGetData::create(getStructure);
|
||||||
|
pvaClientGetData->setMessagePrefix(channelPutGet->getChannel()->getChannelName());
|
||||||
|
|
||||||
|
} else {
|
||||||
|
stringstream ss;
|
||||||
|
ss << pvRequest;
|
||||||
|
string message = string("\nPvaClientPutGet::channelPutGetConnect)")
|
||||||
|
+ "\npvRequest\n" + ss.str()
|
||||||
|
+ "\nerror\n" + status.getMessage();
|
||||||
|
channelPutGetConnectStatus = Status(Status::STATUSTYPE_ERROR,message);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
channelPutGetConnectStatus = status;
|
PvaClientPutGetRequesterPtr req(pvaClientPutGetRequester.lock());
|
||||||
this->channelPutGet = channelPutGet;
|
if(req) {
|
||||||
if(status.isOK()) {
|
req->channelPutGetConnect(status,shared_from_this());
|
||||||
pvaClientPutData = PvaClientPutData::create(putStructure);
|
|
||||||
pvaClientPutData->setMessagePrefix(channelPutGet->getChannel()->getChannelName());
|
|
||||||
pvaClientGetData = PvaClientGetData::create(getStructure);
|
|
||||||
pvaClientGetData->setMessagePrefix(channelPutGet->getChannel()->getChannelName());
|
|
||||||
}
|
}
|
||||||
waitForConnect.signal();
|
waitForConnect.signal();
|
||||||
|
|
||||||
@@ -188,17 +209,22 @@ void PvaClientPutGet::putGetDone(
|
|||||||
BitSetPtr const & getChangedBitSet)
|
BitSetPtr const & getChangedBitSet)
|
||||||
{
|
{
|
||||||
if(PvaClient::getDebug()) {
|
if(PvaClient::getDebug()) {
|
||||||
string channelName("disconnected");
|
|
||||||
Channel::shared_pointer chan(channel.lock());
|
|
||||||
if(chan) channelName = chan->getChannelName();
|
|
||||||
cout << "PvaClientPutGet::putGetDone"
|
cout << "PvaClientPutGet::putGetDone"
|
||||||
<< " channelName " << channelName
|
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
|
||||||
<< " status.isOK " << (status.isOK() ? "true" : "false")
|
<< " status.isOK " << (status.isOK() ? "true" : "false")
|
||||||
<< endl;
|
<< endl;
|
||||||
}
|
}
|
||||||
channelPutGetStatus = status;
|
{
|
||||||
if(status.isOK()) {
|
Lock xx(mutex);
|
||||||
pvaClientGetData->setData(getPVStructure,getChangedBitSet);
|
channelPutGetStatus = status;
|
||||||
|
putGetState = putGetComplete;
|
||||||
|
if(status.isOK()) {
|
||||||
|
pvaClientGetData->setData(getPVStructure,getChangedBitSet);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PvaClientPutGetRequesterPtr req(pvaClientPutGetRequester.lock());
|
||||||
|
if(req) {
|
||||||
|
req->putGetDone(status,shared_from_this());
|
||||||
}
|
}
|
||||||
waitForPutGet.signal();
|
waitForPutGet.signal();
|
||||||
}
|
}
|
||||||
@@ -210,21 +236,26 @@ void PvaClientPutGet::getPutDone(
|
|||||||
BitSetPtr const & putBitSet)
|
BitSetPtr const & putBitSet)
|
||||||
{
|
{
|
||||||
if(PvaClient::getDebug()) {
|
if(PvaClient::getDebug()) {
|
||||||
string channelName("disconnected");
|
|
||||||
Channel::shared_pointer chan(channel.lock());
|
|
||||||
if(chan) channelName = chan->getChannelName();
|
|
||||||
cout << "PvaClientPutGet::getPutDone"
|
cout << "PvaClientPutGet::getPutDone"
|
||||||
<< " channelName " << channelName
|
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
|
||||||
<< " 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());
|
||||||
|
if(req) {
|
||||||
|
req->getPutDone(status,shared_from_this());
|
||||||
}
|
}
|
||||||
waitForPutGet.signal();
|
waitForPutGet.signal();
|
||||||
}
|
}
|
||||||
@@ -236,31 +267,38 @@ void PvaClientPutGet::getGetDone(
|
|||||||
BitSetPtr const & getChangedBitSet)
|
BitSetPtr const & getChangedBitSet)
|
||||||
{
|
{
|
||||||
if(PvaClient::getDebug()) {
|
if(PvaClient::getDebug()) {
|
||||||
string channelName("disconnected");
|
|
||||||
Channel::shared_pointer chan(channel.lock());
|
|
||||||
if(chan) channelName = chan->getChannelName();
|
|
||||||
cout << "PvaClientPutGet::getGetDone"
|
cout << "PvaClientPutGet::getGetDone"
|
||||||
<< " channelName " << channelName
|
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
|
||||||
<< " status.isOK " << (status.isOK() ? "true" : "false")
|
<< " status.isOK " << (status.isOK() ? "true" : "false")
|
||||||
<< endl;
|
<< endl;
|
||||||
}
|
}
|
||||||
channelPutGetStatus = status;
|
{
|
||||||
if(status.isOK()) {
|
Lock xx(mutex);
|
||||||
pvaClientGetData->setData(getPVStructure,getChangedBitSet);
|
channelPutGetStatus = status;
|
||||||
|
putGetState = putGetComplete;
|
||||||
|
if(status.isOK()) {
|
||||||
|
pvaClientGetData->setData(getPVStructure,getChangedBitSet);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PvaClientPutGetRequesterPtr req(pvaClientPutGetRequester.lock());
|
||||||
|
if(req) {
|
||||||
|
req->getGetDone(status,shared_from_this());
|
||||||
}
|
}
|
||||||
waitForPutGet.signal();
|
waitForPutGet.signal();
|
||||||
}
|
}
|
||||||
|
|
||||||
void PvaClientPutGet::connect()
|
void PvaClientPutGet::connect()
|
||||||
{
|
{
|
||||||
|
if(PvaClient::getDebug()) {
|
||||||
|
cout << "PvaClientPutGet::connect"
|
||||||
|
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
|
||||||
|
<< endl;
|
||||||
|
}
|
||||||
issueConnect();
|
issueConnect();
|
||||||
Status status = waitConnect();
|
Status status = waitConnect();
|
||||||
if(status.isOK()) return;
|
if(status.isOK()) return;
|
||||||
Channel::shared_pointer chan(channel.lock());
|
|
||||||
string channelName("disconnected");
|
|
||||||
if(chan) channelName = chan->getChannelName();
|
|
||||||
string message = string("channel ")
|
string message = string("channel ")
|
||||||
+ channelName
|
+ pvaClientChannel->getChannel()->getChannelName()
|
||||||
+ " PvaClientPutGet::connect "
|
+ " PvaClientPutGet::connect "
|
||||||
+ status.getMessage();
|
+ status.getMessage();
|
||||||
throw std::runtime_error(message);
|
throw std::runtime_error(message);
|
||||||
@@ -268,24 +306,29 @@ void PvaClientPutGet::connect()
|
|||||||
|
|
||||||
void PvaClientPutGet::issueConnect()
|
void PvaClientPutGet::issueConnect()
|
||||||
{
|
{
|
||||||
Channel::shared_pointer chan(channel.lock());
|
if(PvaClient::getDebug()) {
|
||||||
|
cout << "PvaClientPutGet::issueConnect"
|
||||||
|
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
|
||||||
|
<< endl;
|
||||||
|
}
|
||||||
if(connectState!=connectIdle) {
|
if(connectState!=connectIdle) {
|
||||||
string channelName("disconnected");
|
string message = string("channel ")
|
||||||
if(chan) channelName = chan->getChannelName();
|
+ pvaClientChannel->getChannel()->getChannelName()
|
||||||
string message = string("channel ") + channelName
|
|
||||||
+ " pvaClientPutGet already connected ";
|
+ " pvaClientPutGet already connected ";
|
||||||
throw std::runtime_error(message);
|
throw std::runtime_error(message);
|
||||||
}
|
}
|
||||||
if(chan) {
|
connectState = connectActive;
|
||||||
connectState = connectActive;
|
channelPutGetConnectStatus = Status(Status::STATUSTYPE_ERROR, "connect active");
|
||||||
channelPutGet = chan->createChannelPutGet(channelPutGetRequester,pvRequest);
|
channelPutGet = pvaClientChannel->getChannel()->createChannelPutGet(channelPutGetRequester,pvRequest);
|
||||||
return;
|
|
||||||
}
|
|
||||||
throw std::runtime_error("PvaClientPutGet::issueConnect() but channel disconnected");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Status PvaClientPutGet::waitConnect()
|
Status PvaClientPutGet::waitConnect()
|
||||||
{
|
{
|
||||||
|
if(PvaClient::getDebug()) {
|
||||||
|
cout << "PvaClientPutGet::waitConnect"
|
||||||
|
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
|
||||||
|
<< endl;
|
||||||
|
}
|
||||||
{
|
{
|
||||||
Lock xx(mutex);
|
Lock xx(mutex);
|
||||||
if(connectState==connected) {
|
if(connectState==connected) {
|
||||||
@@ -293,30 +336,30 @@ Status PvaClientPutGet::waitConnect()
|
|||||||
return channelPutGetConnectStatus;
|
return channelPutGetConnectStatus;
|
||||||
}
|
}
|
||||||
if(connectState!=connectActive) {
|
if(connectState!=connectActive) {
|
||||||
Channel::shared_pointer chan(channel.lock());
|
string message = string("channel ")
|
||||||
string channelName("disconnected");
|
+ pvaClientChannel->getChannel()->getChannelName()
|
||||||
if(chan) channelName = chan->getChannelName();
|
|
||||||
string message = string("channel ") + channelName
|
|
||||||
+ " PvaClientPutGet::waitConnect illegal connect state ";
|
+ " PvaClientPutGet::waitConnect illegal connect state ";
|
||||||
throw std::runtime_error(message);
|
throw std::runtime_error(message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
waitForConnect.wait();
|
waitForConnect.wait();
|
||||||
connectState = channelPutGetConnectStatus.isOK() ? connected : connectIdle;
|
if(!channelPutGetConnectStatus.isOK()) connectState = connectIdle;
|
||||||
return channelPutGetConnectStatus;
|
return channelPutGetConnectStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void PvaClientPutGet::putGet()
|
void PvaClientPutGet::putGet()
|
||||||
{
|
{
|
||||||
|
if(PvaClient::getDebug()) {
|
||||||
|
cout << "PvaClientPutGet::putGet"
|
||||||
|
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
|
||||||
|
<< endl;
|
||||||
|
}
|
||||||
issuePutGet();
|
issuePutGet();
|
||||||
Status status = waitPutGet();
|
Status status = waitPutGet();
|
||||||
if(status.isOK()) return;
|
if(status.isOK()) return;
|
||||||
Channel::shared_pointer chan(channel.lock());
|
|
||||||
string channelName("disconnected");
|
|
||||||
if(chan) channelName = chan->getChannelName();
|
|
||||||
string message = string("channel ")
|
string message = string("channel ")
|
||||||
+ channelName
|
+ pvaClientChannel->getChannel()->getChannelName()
|
||||||
+ " PvaClientPut::putGet "
|
+ " PvaClientPut::putGet "
|
||||||
+ status.getMessage();
|
+ status.getMessage();
|
||||||
throw std::runtime_error(message);
|
throw std::runtime_error(message);
|
||||||
@@ -324,12 +367,15 @@ void PvaClientPutGet::putGet()
|
|||||||
|
|
||||||
void PvaClientPutGet::issuePutGet()
|
void PvaClientPutGet::issuePutGet()
|
||||||
{
|
{
|
||||||
|
if(PvaClient::getDebug()) {
|
||||||
|
cout << "PvaClientPutGet::issuePutGet"
|
||||||
|
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
|
||||||
|
<< endl;
|
||||||
|
}
|
||||||
if(connectState==connectIdle) connect();
|
if(connectState==connectIdle) connect();
|
||||||
if(putGetState!=putGetIdle) {
|
if(putGetState==putGetActive) {
|
||||||
Channel::shared_pointer chan(channel.lock());
|
string message = string("channel ")
|
||||||
string channelName("disconnected");
|
+ pvaClientChannel->getChannel()->getChannelName()
|
||||||
if(chan) channelName = chan->getChannelName();
|
|
||||||
string message = string("channel ") + channelName
|
|
||||||
+ " PvaClientPutGet::issuePutGet get or put aleady active ";
|
+ " PvaClientPutGet::issuePutGet get or put aleady active ";
|
||||||
throw std::runtime_error(message);
|
throw std::runtime_error(message);
|
||||||
}
|
}
|
||||||
@@ -340,29 +386,35 @@ void PvaClientPutGet::issuePutGet()
|
|||||||
|
|
||||||
Status PvaClientPutGet::waitPutGet()
|
Status PvaClientPutGet::waitPutGet()
|
||||||
{
|
{
|
||||||
|
if(PvaClient::getDebug()) {
|
||||||
|
cout << "PvaClientPutGet::waitPutGet"
|
||||||
|
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
|
||||||
|
<< endl;
|
||||||
|
}
|
||||||
|
if(putGetState==putGetComplete) return channelPutGetStatus;
|
||||||
if(putGetState!=putGetActive){
|
if(putGetState!=putGetActive){
|
||||||
Channel::shared_pointer chan(channel.lock());
|
string message = string("channel ")
|
||||||
string channelName("disconnected");
|
+ pvaClientChannel->getChannel()->getChannelName()
|
||||||
if(chan) channelName = chan->getChannelName();
|
|
||||||
string message = string("channel ") + channelName
|
|
||||||
+ " PvaClientPutGet::waitPutGet get or put aleady active ";
|
+ " PvaClientPutGet::waitPutGet get or put aleady active ";
|
||||||
throw std::runtime_error(message);
|
throw std::runtime_error(message);
|
||||||
}
|
}
|
||||||
waitForPutGet.wait();
|
waitForPutGet.wait();
|
||||||
putGetState = putGetIdle;
|
if(channelPutGetStatus.isOK()) pvaClientPutData->getChangedBitSet()->clear();
|
||||||
return channelPutGetStatus;
|
return channelPutGetStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PvaClientPutGet::getGet()
|
void PvaClientPutGet::getGet()
|
||||||
{
|
{
|
||||||
|
if(PvaClient::getDebug()) {
|
||||||
|
cout << "PvaClientPutGet::getGet"
|
||||||
|
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
|
||||||
|
<< endl;
|
||||||
|
}
|
||||||
issueGetGet();
|
issueGetGet();
|
||||||
Status status = waitGetGet();
|
Status status = waitGetGet();
|
||||||
if(status.isOK()) return;
|
if(status.isOK()) return;
|
||||||
Channel::shared_pointer chan(channel.lock());
|
|
||||||
string channelName("disconnected");
|
|
||||||
if(chan) channelName = chan->getChannelName();
|
|
||||||
string message = string("channel ")
|
string message = string("channel ")
|
||||||
+ channelName
|
+ pvaClientChannel->getChannel()->getChannelName()
|
||||||
+ " PvaClientPut::getGet "
|
+ " PvaClientPut::getGet "
|
||||||
+ status.getMessage();
|
+ status.getMessage();
|
||||||
throw std::runtime_error(message);
|
throw std::runtime_error(message);
|
||||||
@@ -370,12 +422,15 @@ void PvaClientPutGet::getGet()
|
|||||||
|
|
||||||
void PvaClientPutGet::issueGetGet()
|
void PvaClientPutGet::issueGetGet()
|
||||||
{
|
{
|
||||||
|
if(PvaClient::getDebug()) {
|
||||||
|
cout << "PvaClientPutGet::issueGetGet"
|
||||||
|
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
|
||||||
|
<< endl;
|
||||||
|
}
|
||||||
if(connectState==connectIdle) connect();
|
if(connectState==connectIdle) connect();
|
||||||
if(putGetState!=putGetIdle) {
|
if(putGetState==putGetActive) {
|
||||||
Channel::shared_pointer chan(channel.lock());
|
string message = string("channel ")
|
||||||
string channelName("disconnected");
|
+ pvaClientChannel->getChannel()->getChannelName()
|
||||||
if(chan) channelName = chan->getChannelName();
|
|
||||||
string message = string("channel ") + channelName
|
|
||||||
+ " PvaClientPutGet::issueGetGet get or put aleady active ";
|
+ " PvaClientPutGet::issueGetGet get or put aleady active ";
|
||||||
throw std::runtime_error(message);
|
throw std::runtime_error(message);
|
||||||
}
|
}
|
||||||
@@ -385,29 +440,34 @@ void PvaClientPutGet::issueGetGet()
|
|||||||
|
|
||||||
Status PvaClientPutGet::waitGetGet()
|
Status PvaClientPutGet::waitGetGet()
|
||||||
{
|
{
|
||||||
|
if(PvaClient::getDebug()) {
|
||||||
|
cout << "PvaClientPutGet::waitGetGet"
|
||||||
|
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
|
||||||
|
<< endl;
|
||||||
|
}
|
||||||
|
if(putGetState==putGetComplete) return channelPutGetStatus;
|
||||||
if(putGetState!=putGetActive){
|
if(putGetState!=putGetActive){
|
||||||
Channel::shared_pointer chan(channel.lock());
|
string message = string("channel ")
|
||||||
string channelName("disconnected");
|
+ pvaClientChannel->getChannel()->getChannelName()
|
||||||
if(chan) channelName = chan->getChannelName();
|
|
||||||
string message = string("channel ") + channelName
|
|
||||||
+ " PvaClientPutGet::waitGetGet get or put aleady active ";
|
+ " PvaClientPutGet::waitGetGet get or put aleady active ";
|
||||||
throw std::runtime_error(message);
|
throw std::runtime_error(message);
|
||||||
}
|
}
|
||||||
waitForPutGet.wait();
|
waitForPutGet.wait();
|
||||||
putGetState = putGetIdle;
|
|
||||||
return channelPutGetStatus;
|
return channelPutGetStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PvaClientPutGet::getPut()
|
void PvaClientPutGet::getPut()
|
||||||
{
|
{
|
||||||
|
if(PvaClient::getDebug()) {
|
||||||
|
cout << "PvaClientPutGet::getGetPut"
|
||||||
|
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
|
||||||
|
<< endl;
|
||||||
|
}
|
||||||
issueGetPut();
|
issueGetPut();
|
||||||
Status status = waitGetPut();
|
Status status = waitGetPut();
|
||||||
if(status.isOK()) return;
|
if(status.isOK()) return;
|
||||||
Channel::shared_pointer chan(channel.lock());
|
|
||||||
string channelName("disconnected");
|
|
||||||
if(chan) channelName = chan->getChannelName();
|
|
||||||
string message = string("channel ")
|
string message = string("channel ")
|
||||||
+ channelName
|
+ pvaClientChannel->getChannel()->getChannelName()
|
||||||
+ " PvaClientPut::getPut "
|
+ " PvaClientPut::getPut "
|
||||||
+ status.getMessage();
|
+ status.getMessage();
|
||||||
throw std::runtime_error(message);
|
throw std::runtime_error(message);
|
||||||
@@ -415,12 +475,15 @@ void PvaClientPutGet::getPut()
|
|||||||
|
|
||||||
void PvaClientPutGet::issueGetPut()
|
void PvaClientPutGet::issueGetPut()
|
||||||
{
|
{
|
||||||
|
if(PvaClient::getDebug()) {
|
||||||
|
cout << "PvaClientPutGet::issueGetPut"
|
||||||
|
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
|
||||||
|
<< endl;
|
||||||
|
}
|
||||||
if(connectState==connectIdle) connect();
|
if(connectState==connectIdle) connect();
|
||||||
if(putGetState!=putGetIdle) {
|
if(putGetState==putGetActive) {
|
||||||
Channel::shared_pointer chan(channel.lock());
|
string message = string("channel ")
|
||||||
string channelName("disconnected");
|
+ pvaClientChannel->getChannel()->getChannelName()
|
||||||
if(chan) channelName = chan->getChannelName();
|
|
||||||
string message = string("channel ") + channelName
|
|
||||||
+ " PvaClientPutGet::issueGetPut get or put aleady active ";
|
+ " PvaClientPutGet::issueGetPut get or put aleady active ";
|
||||||
throw std::runtime_error(message);
|
throw std::runtime_error(message);
|
||||||
}
|
}
|
||||||
@@ -430,29 +493,66 @@ void PvaClientPutGet::issueGetPut()
|
|||||||
|
|
||||||
Status PvaClientPutGet::waitGetPut()
|
Status PvaClientPutGet::waitGetPut()
|
||||||
{
|
{
|
||||||
|
if(PvaClient::getDebug()) {
|
||||||
|
cout << "PvaClientPutGet::waitGetPut"
|
||||||
|
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
|
||||||
|
<< endl;
|
||||||
|
}
|
||||||
|
if(putGetState==putGetComplete) return channelPutGetStatus;
|
||||||
if(putGetState!=putGetActive){
|
if(putGetState!=putGetActive){
|
||||||
Channel::shared_pointer chan(channel.lock());
|
string message = string("channel ")
|
||||||
string channelName("disconnected");
|
+ pvaClientChannel->getChannel()->getChannelName()
|
||||||
if(chan) channelName = chan->getChannelName();
|
|
||||||
string message = string("channel ") + channelName
|
|
||||||
+ " PvaClientPutGet::waitGetPut get or put aleady active ";
|
+ " PvaClientPutGet::waitGetPut get or put aleady active ";
|
||||||
throw std::runtime_error(message);
|
throw std::runtime_error(message);
|
||||||
}
|
}
|
||||||
waitForPutGet.wait();
|
waitForPutGet.wait();
|
||||||
putGetState = putGetIdle;
|
|
||||||
return channelPutGetStatus;
|
return channelPutGetStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
PvaClientGetDataPtr PvaClientPutGet::getGetData()
|
PvaClientGetDataPtr PvaClientPutGet::getGetData()
|
||||||
{
|
{
|
||||||
|
if(PvaClient::getDebug()) {
|
||||||
|
cout<< "PvaClientPutGet::getGetData"
|
||||||
|
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
|
||||||
|
<< endl;
|
||||||
|
}
|
||||||
checkPutGetState();
|
checkPutGetState();
|
||||||
|
if(putGetState==putGetIdle){
|
||||||
|
getGet();
|
||||||
|
getPut();
|
||||||
|
}
|
||||||
return pvaClientGetData;
|
return pvaClientGetData;
|
||||||
}
|
}
|
||||||
|
|
||||||
PvaClientPutDataPtr PvaClientPutGet::getPutData()
|
PvaClientPutDataPtr PvaClientPutGet::getPutData()
|
||||||
{
|
{
|
||||||
|
if(PvaClient::getDebug()) {
|
||||||
|
cout<< "PvaClientPutGet::getPutData"
|
||||||
|
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
|
||||||
|
<< endl;
|
||||||
|
}
|
||||||
checkPutGetState();
|
checkPutGetState();
|
||||||
|
if(putGetState==putGetIdle){
|
||||||
|
getGet();
|
||||||
|
getPut();
|
||||||
|
}
|
||||||
return pvaClientPutData;
|
return pvaClientPutData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PvaClientPutGet::setRequester(PvaClientPutGetRequesterPtr const & pvaClientPutGetRequester)
|
||||||
|
{
|
||||||
|
if(PvaClient::getDebug()) {
|
||||||
|
cout << "PvaClientPutGet::setRequester"
|
||||||
|
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
|
||||||
|
<< endl;
|
||||||
|
}
|
||||||
|
this->pvaClientPutGetRequester = pvaClientPutGetRequester;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PvaClientChannelPtr PvaClientPutGet::getPvaClientChannel()
|
||||||
|
{
|
||||||
|
return pvaClientChannel;
|
||||||
|
}
|
||||||
|
|
||||||
}}
|
}}
|
||||||
|
|||||||
+13
-5
@@ -12,13 +12,12 @@
|
|||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <pv/event.h>
|
#include <pv/event.h>
|
||||||
#include <pv/bitSetUtil.h>
|
#include <pv/bitSetUtil.h>
|
||||||
|
#include <pv/rpcService.h>
|
||||||
|
|
||||||
#define epicsExportSharedSymbols
|
#define epicsExportSharedSymbols
|
||||||
|
|
||||||
#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;
|
||||||
@@ -182,6 +181,7 @@ void PvaClientRPC::requestDone(
|
|||||||
PvaClientRPCRequesterPtr req = pvaClientRPCRequester.lock();
|
PvaClientRPCRequesterPtr req = pvaClientRPCRequester.lock();
|
||||||
{
|
{
|
||||||
Lock xx(mutex);
|
Lock xx(mutex);
|
||||||
|
requestStatus = status;
|
||||||
if(PvaClient::getDebug()) {
|
if(PvaClient::getDebug()) {
|
||||||
string channelName("disconnected");
|
string channelName("disconnected");
|
||||||
Channel::shared_pointer chan(channel.lock());
|
Channel::shared_pointer chan(channel.lock());
|
||||||
@@ -226,7 +226,7 @@ void PvaClientRPC::connect()
|
|||||||
+ channelName
|
+ channelName
|
||||||
+ " PvaClientRPC::connect "
|
+ " PvaClientRPC::connect "
|
||||||
+ status.getMessage();
|
+ status.getMessage();
|
||||||
throw std::runtime_error(message);
|
throw RPCRequestException(Status::STATUSTYPE_ERROR,message);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PvaClientRPC::issueConnect()
|
void PvaClientRPC::issueConnect()
|
||||||
@@ -307,10 +307,18 @@ PVStructure::shared_pointer PvaClientRPC::request(PVStructure::shared_pointer co
|
|||||||
string message = "channel "
|
string message = "channel "
|
||||||
+ channelName
|
+ channelName
|
||||||
+ " PvaClientRPC::request request timeout ";
|
+ " PvaClientRPC::request request timeout ";
|
||||||
throw std::runtime_error(message);
|
throw RPCRequestException(Status::STATUSTYPE_ERROR,message);
|
||||||
}
|
}
|
||||||
rpcState = rpcIdle;
|
rpcState = rpcIdle;
|
||||||
return pvResponse;
|
if(requestStatus.isOK()) return pvResponse;
|
||||||
|
Channel::shared_pointer chan(channel.lock());
|
||||||
|
string channelName("disconnected");
|
||||||
|
if(chan) channelName = chan->getChannelName();
|
||||||
|
string message = "channel "
|
||||||
|
+ channelName
|
||||||
|
+ " PvaClientRPC::request status ";
|
||||||
|
message += requestStatus.getMessage();
|
||||||
|
throw RPCRequestException(Status::STATUSTYPE_ERROR,message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user