Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| b8cb8d9ca4 |
@@ -1,10 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
set -e -x
|
|
||||||
|
|
||||||
make -j2 $EXTRA
|
|
||||||
|
|
||||||
if [ "$TEST" != "NO" ]
|
|
||||||
then
|
|
||||||
make -j2 tapfiles
|
|
||||||
make -j2 -s test-results
|
|
||||||
fi
|
|
||||||
@@ -1,111 +0,0 @@
|
|||||||
#!/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
|
|
||||||
+12
-16
@@ -1,17 +1,13 @@
|
|||||||
/cfg/
|
bin/
|
||||||
/bin/
|
lib/
|
||||||
/lib/
|
doc/
|
||||||
/db/
|
include/
|
||||||
/dbd/
|
db/
|
||||||
/html/
|
dbd/
|
||||||
/include/
|
documentation/html
|
||||||
/templates/
|
documentation/*.tag
|
||||||
/configure/*.local
|
|
||||||
/documentation/html
|
|
||||||
/documentation/*.tag
|
|
||||||
O.*/
|
|
||||||
/QtC-*
|
|
||||||
envPaths
|
envPaths
|
||||||
*.orig
|
configure/*.local
|
||||||
*.log
|
!configure/ExampleRELEASE.local
|
||||||
.*.swp
|
**/O.*
|
||||||
|
QtC-*
|
||||||
|
|||||||
@@ -1,17 +0,0 @@
|
|||||||
# .readthedocs.yml
|
|
||||||
# Read the Docs configuration file
|
|
||||||
# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
|
|
||||||
|
|
||||||
# Required
|
|
||||||
version: 2
|
|
||||||
|
|
||||||
# Build documentation in the documentation/ directory with Sphinx
|
|
||||||
sphinx:
|
|
||||||
configuration: documentation/conf.py
|
|
||||||
|
|
||||||
# Build documentation with MkDocs
|
|
||||||
#mkdocs:
|
|
||||||
# configuration: mkdocs.yml
|
|
||||||
|
|
||||||
# Optionally build your docs in additional formats such as PDF and ePub
|
|
||||||
formats: all
|
|
||||||
-30
@@ -1,30 +0,0 @@
|
|||||||
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
|
|
||||||
@@ -38,7 +38,7 @@ PROJECT_NAME = pvaClientCPP
|
|||||||
# could be handy for archiving the generated documentation or if some version
|
# could be handy for archiving the generated documentation or if some version
|
||||||
# control system is used.
|
# control system is used.
|
||||||
|
|
||||||
PROJECT_NUMBER = 4.7.1
|
PROJECT_NUMBER =
|
||||||
|
|
||||||
# Using the PROJECT_BRIEF tag one can provide an optional one line description
|
# Using the PROJECT_BRIEF tag one can provide an optional one line description
|
||||||
# for a project that appears at the top of each page and should give viewer a
|
# for a project that appears at the top of each page and should give viewer a
|
||||||
@@ -152,7 +152,7 @@ FULL_PATH_NAMES = YES
|
|||||||
# will be relative from the directory where doxygen is started.
|
# will be relative from the directory where doxygen is started.
|
||||||
# This tag requires that the tag FULL_PATH_NAMES is set to YES.
|
# This tag requires that the tag FULL_PATH_NAMES is set to YES.
|
||||||
|
|
||||||
STRIP_FROM_PATH = src
|
STRIP_FROM_PATH =
|
||||||
|
|
||||||
# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the
|
# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the
|
||||||
# path mentioned in the documentation of a class, which tells the reader which
|
# path mentioned in the documentation of a class, which tells the reader which
|
||||||
@@ -161,7 +161,7 @@ STRIP_FROM_PATH = src
|
|||||||
# specify the list of include paths that are normally passed to the compiler
|
# specify the list of include paths that are normally passed to the compiler
|
||||||
# using the -I flag.
|
# using the -I flag.
|
||||||
|
|
||||||
STRIP_FROM_INC_PATH = src
|
STRIP_FROM_INC_PATH =
|
||||||
|
|
||||||
# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but
|
# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but
|
||||||
# less readable) file names. This can be useful is your file systems doesn't
|
# less readable) file names. This can be useful is your file systems doesn't
|
||||||
@@ -765,8 +765,7 @@ WARN_LOGFILE =
|
|||||||
# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING
|
# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING
|
||||||
# Note: If this tag is empty the current directory is searched.
|
# Note: If this tag is empty the current directory is searched.
|
||||||
|
|
||||||
INPUT = src \
|
INPUT = include
|
||||||
src/pv
|
|
||||||
|
|
||||||
# This tag can be used to specify the character encoding of the source files
|
# This tag can be used to specify the character encoding of the source files
|
||||||
# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
|
# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
|
||||||
@@ -797,7 +796,7 @@ FILE_PATTERNS =
|
|||||||
# be searched for input files as well.
|
# be searched for input files as well.
|
||||||
# The default value is: NO.
|
# The default value is: NO.
|
||||||
|
|
||||||
RECURSIVE = NO
|
RECURSIVE = YES
|
||||||
|
|
||||||
# The EXCLUDE tag can be used to specify files and/or directories that should be
|
# The EXCLUDE tag can be used to specify files and/or directories that should be
|
||||||
# excluded from the INPUT source files. This way you can easily exclude a
|
# excluded from the INPUT source files. This way you can easily exclude a
|
||||||
@@ -1036,7 +1035,7 @@ GENERATE_HTML = YES
|
|||||||
# The default directory is: html.
|
# The default directory is: html.
|
||||||
# This tag requires that the tag GENERATE_HTML is set to YES.
|
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||||
|
|
||||||
HTML_OUTPUT = html/doxygen
|
HTML_OUTPUT = documentation/html
|
||||||
|
|
||||||
# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each
|
# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each
|
||||||
# generated HTML page (for example: .htm, .php, .asp).
|
# generated HTML page (for example: .htm, .php, .asp).
|
||||||
|
|||||||
@@ -1,17 +1,49 @@
|
|||||||
# pvaClientCPP
|
pvaClientCPP
|
||||||
|
============
|
||||||
|
|
||||||
The **pvaClient** API provides a synchronous client interface that was designed to be easier to use than the original basic pvAccess client API.
|
pvaClient is a synchronous client interface to pvAccess,
|
||||||
|
which is callback based.
|
||||||
|
pvaClient is thus easier to use than pvAccess itself.
|
||||||
|
|
||||||
The pvaClientCPP module implements the pvaClient API for C++ client applications.
|
See documentation/pvaClientCPP.html for details.
|
||||||
|
|
||||||
## Links
|
Building
|
||||||
|
--------
|
||||||
|
|
||||||
- General information about EPICS can be found at the
|
If a proper RELEASE.local file exists one directory level above pvaClientCPP
|
||||||
[EPICS Controls website](https://epics-controls.org).
|
then just type:
|
||||||
- API documentation for this module can be found in its
|
|
||||||
documentation directory, in particular the file
|
|
||||||
pvaClientCPP.html
|
|
||||||
|
|
||||||
## Building
|
make
|
||||||
|
|
||||||
This module is included as a submodule of a full EPICS 7 release and will be compiled during builds of that software.
|
It can also be built by:
|
||||||
|
|
||||||
|
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.
|
||||||
|
|||||||
@@ -1,12 +0,0 @@
|
|||||||
# Version number for the PVA Client API and shared library
|
|
||||||
|
|
||||||
EPICS_PVACLIENT_MAJOR_VERSION = 4
|
|
||||||
EPICS_PVACLIENT_MINOR_VERSION = 7
|
|
||||||
EPICS_PVACLIENT_MAINTENANCE_VERSION = 1
|
|
||||||
|
|
||||||
# Development flag, set to zero for release versions
|
|
||||||
|
|
||||||
EPICS_PVACLIENT_DEVELOPMENT_FLAG = 0
|
|
||||||
|
|
||||||
# Immediately after a release the MAINTENANCE_VERSION
|
|
||||||
# will be incremented and the DEVELOPMENT_FLAG set to 1
|
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
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,8 +2,6 @@ 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)))
|
||||||
|
|
||||||
|
|||||||
+19
-33
@@ -1,44 +1,30 @@
|
|||||||
# RELEASE - Location of external support modules
|
# easyPVACPP RELEASE - Location of external support modules
|
||||||
#
|
#
|
||||||
# IF YOU CHANGE ANY PATHS in this file or make API changes to
|
# IF YOU CHANGE this file or any file it includes you must
|
||||||
# any modules it refers to, you should do a "make rebuild" in
|
# subsequently do a "gnumake rebuild" in the application's
|
||||||
# this application's top level directory.
|
# top level directory.
|
||||||
#
|
#
|
||||||
# The EPICS build process does not check dependencies against
|
# The build process does not check dependencies against files
|
||||||
# any files from outside the application, so it is safest to
|
# that are outside this application, thus you should also do a
|
||||||
# rebuild it completely if any modules it depends on change.
|
# "gnumake rebuild" in the top level directory after EPICS_BASE
|
||||||
|
# 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!
|
||||||
#
|
#
|
||||||
# This file is parsed by both GNUmake and an EPICS Perl script,
|
# A RELEASE.local must exist that has the following definitions
|
||||||
# so it may ONLY contain definititions of paths to other support
|
# EPICS_BASE=/home/install/epics/base
|
||||||
# modules, variable definitions that are used in module paths,
|
# EPICS4_DIR=/home/epicsv4
|
||||||
# and include statements that pull in other RELEASE files.
|
# PVCOMMON=${EPICS4_DIR}/pvCommonCPP
|
||||||
# Variables may be used before their values have been set.
|
# PVDATA=${EPICS4_DIR}/pvDataCPP
|
||||||
# Build variables that are NOT used in paths should be set in
|
# NORMATIVETYPES=${EPICSV4}/normativeTypesCPP
|
||||||
# the CONFIG_SITE file.
|
# PVACCESS=${EPICS4_DIR}/pvAccessCPP
|
||||||
|
#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,113 +1,19 @@
|
|||||||
pwd# pvaClientCPP Module
|
EPICS V4 release 4.6
|
||||||
|
==========================
|
||||||
This document summarizes the changes to the module between releases.
|
|
||||||
|
|
||||||
## Release 4.7.1 (EPICS 7.0.3.2 May 2020)
|
|
||||||
|
|
||||||
* support access to a union field that is a scalar or scalarArray
|
|
||||||
* fixed issues #62 and #63
|
|
||||||
|
|
||||||
## Release 4.7.0 (EPICS 7.0.3.1, Nov 2019)
|
|
||||||
|
|
||||||
* added JSON support for put and putGet
|
|
||||||
* Fix for
|
|
||||||
[GitHub issue #62](https://github.com/epics-base/pvaClientCPP/issues/62)
|
|
||||||
* Doxygen updates and read-the-docs integration.
|
|
||||||
|
|
||||||
|
|
||||||
## 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.
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +0,0 @@
|
|||||||
.wy-side-nav-search {
|
|
||||||
background-color: #18334B;
|
|
||||||
}
|
|
||||||
|
|
||||||
.wy-side-nav-search input[type="text"] {
|
|
||||||
border-color: #18334b;
|
|
||||||
}
|
|
||||||
@@ -1,80 +0,0 @@
|
|||||||
# Configuration file for the Sphinx documentation builder.
|
|
||||||
#
|
|
||||||
# This file only contains a selection of the most common options. For a full
|
|
||||||
# list see the documentation:
|
|
||||||
# http://www.sphinx-doc.org/en/master/config
|
|
||||||
|
|
||||||
# -- Path setup --------------------------------------------------------------
|
|
||||||
|
|
||||||
# If extensions (or modules to document with autodoc) are in another directory,
|
|
||||||
# add these directories to sys.path here. If the directory is relative to the
|
|
||||||
# documentation root, use os.path.abspath to make it absolute, like shown here.
|
|
||||||
#
|
|
||||||
# import os
|
|
||||||
# import sys
|
|
||||||
# sys.path.insert(0, os.path.abspath('.'))
|
|
||||||
|
|
||||||
|
|
||||||
# -- Project information -----------------------------------------------------
|
|
||||||
|
|
||||||
project = 'normativeTypes (C++)'
|
|
||||||
copyright = '2019, EPICS Controls.'
|
|
||||||
author = 'EPICS'
|
|
||||||
|
|
||||||
|
|
||||||
# -- General configuration ---------------------------------------------------
|
|
||||||
|
|
||||||
# Add any Sphinx extension module names here, as strings. They can be
|
|
||||||
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
|
|
||||||
# ones.
|
|
||||||
extensions = [
|
|
||||||
'sphinx.ext.intersphinx',
|
|
||||||
]
|
|
||||||
|
|
||||||
# Add any paths that contain templates here, relative to this directory.
|
|
||||||
templates_path = ['_templates']
|
|
||||||
|
|
||||||
# List of patterns, relative to source directory, that match files and
|
|
||||||
# directories to ignore when looking for source files.
|
|
||||||
# This pattern also affects html_static_path and html_extra_path.
|
|
||||||
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
|
|
||||||
|
|
||||||
# Intersphinx links to subprojects
|
|
||||||
intersphinx_mapping = {
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
# -- Options for HTML output -------------------------------------------------
|
|
||||||
|
|
||||||
# The theme to use for HTML and HTML Help pages. See the documentation for
|
|
||||||
# a list of builtin themes.
|
|
||||||
#
|
|
||||||
html_theme = 'sphinx_rtd_theme'
|
|
||||||
|
|
||||||
|
|
||||||
# Add any paths that contain custom static files (such as style sheets) here,
|
|
||||||
# relative to this directory. They are copied after the builtin static files,
|
|
||||||
# so a file named "default.css" will overwrite the builtin "default.css".
|
|
||||||
html_static_path = ['_static']
|
|
||||||
|
|
||||||
html_css_files = [
|
|
||||||
'css/custom.css',
|
|
||||||
]
|
|
||||||
|
|
||||||
master_doc = 'index'
|
|
||||||
|
|
||||||
html_theme_options = {
|
|
||||||
'logo_only': True,
|
|
||||||
}
|
|
||||||
html_logo = "images/EPICS_white_logo_v02.png"
|
|
||||||
|
|
||||||
html_extra_path = [
|
|
||||||
'../html',
|
|
||||||
'pvaClientCPP.html',
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
# -- Run Doxygen ------------------------------------------------------------
|
|
||||||
|
|
||||||
import subprocess
|
|
||||||
subprocess.call('cd ..; mkdir -p html/doxygen; doxygen', shell=True)
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
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.
|
|
||||||
@@ -1,146 +0,0 @@
|
|||||||
<?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>
|
|
||||||
|
|
||||||
@@ -1,123 +0,0 @@
|
|||||||
<?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>
|
|
||||||
|
|
||||||
@@ -1,81 +0,0 @@
|
|||||||
<?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>
|
|
||||||
|
|
||||||
@@ -1,74 +0,0 @@
|
|||||||
<?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>
|
|
||||||
|
|
||||||
@@ -1,63 +0,0 @@
|
|||||||
<?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>
|
|
||||||
|
|
||||||
@@ -1,59 +0,0 @@
|
|||||||
<?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>
|
|
||||||
|
|
||||||
@@ -1,106 +0,0 @@
|
|||||||
<?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>
|
|
||||||
|
|
||||||
@@ -1,66 +0,0 @@
|
|||||||
<?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>
|
|
||||||
|
|
||||||
@@ -1,65 +0,0 @@
|
|||||||
<?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>
|
|
||||||
|
|
||||||
@@ -1,71 +0,0 @@
|
|||||||
<?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>
|
|
||||||
|
|
||||||
@@ -1,82 +0,0 @@
|
|||||||
<?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>
|
|
||||||
|
|
||||||
@@ -1,75 +0,0 @@
|
|||||||
<?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>
|
|
||||||
|
|
||||||
@@ -1,85 +0,0 @@
|
|||||||
<?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>
|
|
||||||
|
|
||||||
@@ -1,66 +0,0 @@
|
|||||||
<?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>
|
|
||||||
|
|
||||||
@@ -1,63 +0,0 @@
|
|||||||
<?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>
|
|
||||||
|
|
||||||
@@ -1,44 +0,0 @@
|
|||||||
<?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>
|
|
||||||
|
|
||||||
@@ -1,44 +0,0 @@
|
|||||||
<?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>
|
|
||||||
|
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 5.5 KiB |
@@ -1,17 +0,0 @@
|
|||||||
pvaClient (C++) Library
|
|
||||||
========================
|
|
||||||
|
|
||||||
.. toctree::
|
|
||||||
:hidden:
|
|
||||||
|
|
||||||
EPICS Website <https://epics-controls.org>
|
|
||||||
EPICS Documentation Home <https://docs.epics-controls.org>
|
|
||||||
|
|
||||||
|
|
||||||
.. toctree::
|
|
||||||
:maxdepth: 1
|
|
||||||
:caption: pvaClientCPP
|
|
||||||
|
|
||||||
Reference Manual <https://docs.epics-controls.org/projects/pvaclient-cpp/en/latest/pvaClientCPP.html>
|
|
||||||
API Documentation <https://docs.epics-controls.org/projects/pvaclient-cpp/en/latest/doxygen>
|
|
||||||
Source Code Repository on GitHub <https://github.com/epics-base/pvaClientCPP>
|
|
||||||
@@ -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 pvaClientCPP</title>
|
<title>EPICS pva</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.4 - April 2019</h2>
|
<h2 class="nocount">Release 4.2.0-SNAPSHOT - 2016-07-14</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,32 +62,40 @@ The data for the channels is presented via normative type NTMultiChannel.
|
|||||||
|
|
||||||
</div> <!-- head -->
|
</div> <!-- head -->
|
||||||
|
|
||||||
<div id="contents" class="contents">
|
<div id="toc">
|
||||||
|
<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 pvaClientCPP
|
<p>This document is only a guide to help locate code and documentation related to pvDatabaseCPP
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
It is intended for developers that want to use pvaClientCPP.
|
It is intended for developers that want to use pvDatabaseCPP.
|
||||||
</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="https://mrkraimer.github.io/website/developerGuide/developerGuide.html">
|
href="http://epics-pvdata.sourceforge.net/informative/developerGuide/developerGuide.html">
|
||||||
developerGuide
|
developerGuide
|
||||||
</a>
|
</a>
|
||||||
</p>
|
</p>
|
||||||
<p>This guide provides an overview of the components that are part of an <b>EPICS V4</b> release.
|
<p>This guide discusses all 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 pvaClientCPP.
|
develop code that uses pvDatabaseCPP.
|
||||||
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
|
||||||
@@ -96,9 +104,9 @@ href="./html/index.html">doxygen</a>
|
|||||||
</p>
|
</p>
|
||||||
|
|
||||||
<h2>exampleCPP</h2>
|
<h2>exampleCPP</h2>
|
||||||
<p>Example code is available at
|
<p>Example code is available as part of this release.
|
||||||
<a
|
<a
|
||||||
href="https://github.com/epics-base/exampleCPP">
|
href="http://epics-pvdata.sourceforge.net/docbuild/exampleCPP/tip/documentation/exampleCPP.html">
|
||||||
exampleCPP
|
exampleCPP
|
||||||
</a>
|
</a>
|
||||||
</p>
|
</p>
|
||||||
|
|||||||
+15
-5
@@ -21,22 +21,31 @@ installE4 () {
|
|||||||
local module=$1
|
local module=$1
|
||||||
local branch=$2
|
local branch=$2
|
||||||
|
|
||||||
wget -nv https://openepics.ci.cloudbees.com/job/e4-cpp-${module}-${branch}-build/BASE=${BASE}/lastSuccessfulBuild/artifact/${module}.CB-dist.tar.gz
|
# If microbench version does not exist, try without
|
||||||
|
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
|
# Defaults for EPICS Base and MB
|
||||||
|
|
||||||
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
|
||||||
|
|
||||||
PVDATA_BRANCH="master"
|
PVCOMMON_BRANCH="release-4.2"
|
||||||
PVACCESS_BRANCH="master"
|
PVDATA_BRANCH="release-6.0"
|
||||||
NORMATIVETYPES_BRANCH="master"
|
PVACCESS_BRANCH="release-5.0"
|
||||||
|
NORMATIVETYPES_BRANCH="release-5.1"
|
||||||
|
|
||||||
###########################################
|
###########################################
|
||||||
# Fetch and unpack dependencies
|
# Fetch and unpack dependencies
|
||||||
@@ -50,6 +59,7 @@ 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,7 +21,14 @@ installE4 () {
|
|||||||
local module=$1
|
local module=$1
|
||||||
local branch=$2
|
local branch=$2
|
||||||
|
|
||||||
wget -nv https://openepics.ci.cloudbees.com/job/e4-cpp-${module}-${branch}-build/BASE=${BASE}/lastSuccessfulBuild/artifact/${module}.CB-dist.tar.gz
|
# If microbench version does not exist, try without
|
||||||
|
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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+4
-5
@@ -6,13 +6,12 @@ include $(TOP)/configure/CONFIG
|
|||||||
LIBRARY += pvaClient
|
LIBRARY += pvaClient
|
||||||
|
|
||||||
# shared library ABI version.
|
# shared library ABI version.
|
||||||
SHRLIB_VERSION ?= $(EPICS_PVACLIENT_MAJOR_VERSION).$(EPICS_PVACLIENT_MINOR_VERSION).$(EPICS_PVACLIENT_MAINTENANCE_VERSION)
|
SHRLIB_VERSION ?= 4.2.0
|
||||||
|
|
||||||
INC += pv/pvaClient.h
|
INC += pv/pvaClient.h
|
||||||
INC += pv/pvaClientMultiChannel.h
|
INC += pv/pvaClientMultiChannel.h
|
||||||
|
|
||||||
LIBSRCS += pvaClient.cpp
|
LIBSRCS += pvaClient.cpp
|
||||||
LIBSRCS += pvaClientData.cpp
|
|
||||||
LIBSRCS += pvaClientPutData.cpp
|
LIBSRCS += pvaClientPutData.cpp
|
||||||
LIBSRCS += pvaClientGetData.cpp
|
LIBSRCS += pvaClientGetData.cpp
|
||||||
LIBSRCS += pvaClientMonitorData.cpp
|
LIBSRCS += pvaClientMonitorData.cpp
|
||||||
@@ -32,8 +31,8 @@ LIBSRCS += pvaClientNTMultiGet.cpp
|
|||||||
LIBSRCS += pvaClientNTMultiMonitor.cpp
|
LIBSRCS += pvaClientNTMultiMonitor.cpp
|
||||||
LIBSRCS += pvaClientRPC.cpp
|
LIBSRCS += pvaClientRPC.cpp
|
||||||
|
|
||||||
pvaClient_LIBS += nt
|
pvaClient_LIBS += pvAccess nt pvData Com
|
||||||
pvaClient_LIBS += $(EPICS_BASE_PVA_CORE_LIBS)
|
pvaClient_LIBS += $(EPICS_BASE_IOC_LIBS)
|
||||||
pvaClient_LIBS += $(EPICS_BASE_IOC_LIBS)
|
|
||||||
|
|
||||||
include $(TOP)/configure/RULES
|
include $(TOP)/configure/RULES
|
||||||
|
|
||||||
|
|||||||
+362
-556
File diff suppressed because it is too large
Load Diff
@@ -21,14 +21,14 @@
|
|||||||
|
|
||||||
#ifdef pvaClientMultiChannelEpicsExportSharedSymbols
|
#ifdef pvaClientMultiChannelEpicsExportSharedSymbols
|
||||||
# define epicsExportSharedSymbols
|
# define epicsExportSharedSymbols
|
||||||
# undef pvaClientMultiChannelEpicsExportSharedSymbols
|
# undef pvaClientMultiChannelEpicsExportSharedSymbols
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#include <pv/pvaClient.h>
|
#include <pv/pvaClient.h>
|
||||||
|
|
||||||
|
|
||||||
namespace epics { namespace pvaClient {
|
namespace epics { namespace pvaClient {
|
||||||
|
|
||||||
|
|
||||||
class PvaClientMultiChannel;
|
class PvaClientMultiChannel;
|
||||||
@@ -115,7 +115,7 @@ public:
|
|||||||
* @brief create a pvaClientMultiGetDouble
|
* @brief create a pvaClientMultiGetDouble
|
||||||
* @return The interface.
|
* @return The interface.
|
||||||
*/
|
*/
|
||||||
PvaClientMultiGetDoublePtr createGet();
|
PvaClientMultiGetDoublePtr createGet();
|
||||||
/**
|
/**
|
||||||
* @brief Create a pvaClientMultiPutDouble.
|
* @brief Create a pvaClientMultiPutDouble.
|
||||||
* @return The interface.
|
* @return The interface.
|
||||||
@@ -145,6 +145,10 @@ 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,
|
||||||
@@ -152,7 +156,7 @@ private:
|
|||||||
std::string const & providerName,
|
std::string const & providerName,
|
||||||
size_t maxNotConnected);
|
size_t maxNotConnected);
|
||||||
void checkConnected();
|
void checkConnected();
|
||||||
|
|
||||||
PvaClientPtr pvaClient;
|
PvaClientPtr pvaClient;
|
||||||
epics::pvData::shared_vector<const std::string> channelName;
|
epics::pvData::shared_vector<const std::string> channelName;
|
||||||
std::string providerName;
|
std::string providerName;
|
||||||
@@ -176,7 +180,7 @@ class epicsShareClass PvaClientMultiGetDouble :
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
POINTER_DEFINITIONS(PvaClientMultiGetDouble);
|
POINTER_DEFINITIONS(PvaClientMultiGetDouble);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Create a PvaClientMultiGetDouble.
|
* @brief Create a PvaClientMultiGetDouble.
|
||||||
* @param pvaClientMultiChannel The interface to PvaClientMultiChannel.
|
* @param pvaClientMultiChannel The interface to PvaClientMultiChannel.
|
||||||
@@ -205,6 +209,10 @@ 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,
|
||||||
@@ -214,7 +222,7 @@ private:
|
|||||||
PvaClientChannelArray pvaClientChannelArray;
|
PvaClientChannelArray pvaClientChannelArray;
|
||||||
size_t nchannel;
|
size_t nchannel;
|
||||||
epics::pvData::Mutex mutex;
|
epics::pvData::Mutex mutex;
|
||||||
|
|
||||||
epics::pvData::shared_vector<double> doubleValue;
|
epics::pvData::shared_vector<double> doubleValue;
|
||||||
std::vector<PvaClientGetPtr> pvaClientGet;
|
std::vector<PvaClientGetPtr> pvaClientGet;
|
||||||
bool isGetConnected;
|
bool isGetConnected;
|
||||||
@@ -229,7 +237,7 @@ class epicsShareClass PvaClientMultiPutDouble :
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
POINTER_DEFINITIONS(PvaClientMultiPutDouble);
|
POINTER_DEFINITIONS(PvaClientMultiPutDouble);
|
||||||
|
|
||||||
/** @brief Create a PvaClientMultiPutDouble.
|
/** @brief Create a PvaClientMultiPutDouble.
|
||||||
* @param pvaClientMultiChannel The interface to PvaClientMultiChannel.
|
* @param pvaClientMultiChannel The interface to PvaClientMultiChannel.
|
||||||
* @param pvaClientChannelArray The PvaClientChannel array.
|
* @param pvaClientChannelArray The PvaClientChannel array.
|
||||||
@@ -254,6 +262,10 @@ 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,
|
||||||
@@ -277,7 +289,7 @@ class epicsShareClass PvaClientMultiMonitorDouble :
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
POINTER_DEFINITIONS(PvaClientMultiMonitorDouble);
|
POINTER_DEFINITIONS(PvaClientMultiMonitorDouble);
|
||||||
|
|
||||||
/** @brief Create a PvaClientMultiMonitorDouble.
|
/** @brief Create a PvaClientMultiMonitorDouble.
|
||||||
* @param pvaClientMultiChannel The interface to PvaClientMultiChannel.
|
* @param pvaClientMultiChannel The interface to PvaClientMultiChannel.
|
||||||
* @param pvaClientChannelArray The PvaClientChannel array.
|
* @param pvaClientChannelArray The PvaClientChannel array.
|
||||||
@@ -317,6 +329,10 @@ 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,
|
||||||
@@ -360,10 +376,8 @@ public:
|
|||||||
void connect();
|
void connect();
|
||||||
/**
|
/**
|
||||||
* @brief Get each channel.
|
* @brief Get each channel.
|
||||||
*
|
|
||||||
* @param valueOnly use only value for union.
|
|
||||||
*/
|
*/
|
||||||
void get(bool valueOnly = true);
|
void get();
|
||||||
/**
|
/**
|
||||||
* @brief Get the data from the last get.
|
* @brief Get the data from the last get.
|
||||||
* @return the pvaClientNTMultiData.
|
* @return the pvaClientNTMultiData.
|
||||||
@@ -376,6 +390,10 @@ 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,
|
||||||
@@ -388,8 +406,8 @@ private:
|
|||||||
epics::pvData::PVStructurePtr pvRequest;
|
epics::pvData::PVStructurePtr pvRequest;
|
||||||
size_t nchannel;
|
size_t nchannel;
|
||||||
epics::pvData::Mutex mutex;
|
epics::pvData::Mutex mutex;
|
||||||
|
|
||||||
|
|
||||||
PvaClientNTMultiDataPtr pvaClientNTMultiData;
|
PvaClientNTMultiDataPtr pvaClientNTMultiData;
|
||||||
std::vector<PvaClientGetPtr> pvaClientGet;
|
std::vector<PvaClientGetPtr> pvaClientGet;
|
||||||
bool isConnected;
|
bool isConnected;
|
||||||
@@ -413,7 +431,7 @@ public:
|
|||||||
static PvaClientNTMultiPutPtr create(
|
static PvaClientNTMultiPutPtr create(
|
||||||
PvaClientMultiChannelPtr const &pvaClientMultiChannel,
|
PvaClientMultiChannelPtr const &pvaClientMultiChannel,
|
||||||
PvaClientChannelArray const &pvaClientChannelArray);
|
PvaClientChannelArray const &pvaClientChannelArray);
|
||||||
|
|
||||||
~PvaClientNTMultiPut();
|
~PvaClientNTMultiPut();
|
||||||
/**
|
/**
|
||||||
* @brief Connect a channelPut for each channel.
|
* @brief Connect a channelPut for each channel.
|
||||||
@@ -435,6 +453,10 @@ 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,
|
||||||
@@ -478,11 +500,10 @@ 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 valueOnly = true);
|
bool poll();
|
||||||
/**
|
/**
|
||||||
* @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.
|
||||||
@@ -502,6 +523,10 @@ 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,
|
||||||
@@ -543,28 +568,27 @@ public:
|
|||||||
PvaClientChannelArray const &pvaClientChannelArray,
|
PvaClientChannelArray const &pvaClientChannelArray,
|
||||||
epics::pvData::PVStructurePtr const & pvRequest);
|
epics::pvData::PVStructurePtr const & pvRequest);
|
||||||
~PvaClientNTMultiData();
|
~PvaClientNTMultiData();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get the number of channels.
|
* @brief Get the number of channels.
|
||||||
* @return The number of channels.
|
* @return The number of channels.
|
||||||
*/
|
*/
|
||||||
size_t getNumber();
|
size_t getNumber();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @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(bool valueOnly = true);
|
void endDeltaTime();
|
||||||
/**
|
/**
|
||||||
* @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.
|
||||||
*/
|
*/
|
||||||
epics::pvData::TimeStamp getTimeStamp();
|
epics::pvData::TimeStamp getTimeStamp();
|
||||||
/**
|
/**
|
||||||
* @brief Get the NTMultiChannel.
|
* @brief Get the NTMultiChannel.
|
||||||
* @return The value.
|
* @return The value.
|
||||||
@@ -577,12 +601,17 @@ 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);
|
||||||
|
|
||||||
@@ -594,7 +623,7 @@ private:
|
|||||||
std::vector<epics::pvData::PVStructurePtr> topPVStructure;
|
std::vector<epics::pvData::PVStructurePtr> topPVStructure;
|
||||||
bool gotAlarm;
|
bool gotAlarm;
|
||||||
bool gotTimeStamp;
|
bool gotTimeStamp;
|
||||||
|
|
||||||
epics::pvData::StructureConstPtr ntMultiChannelStructure;
|
epics::pvData::StructureConstPtr ntMultiChannelStructure;
|
||||||
epics::pvData::shared_vector<epics::pvData::PVUnionPtr> unionValue;
|
epics::pvData::shared_vector<epics::pvData::PVUnionPtr> unionValue;
|
||||||
epics::pvData::shared_vector<epics::pvData::int32> severity;
|
epics::pvData::shared_vector<epics::pvData::int32> severity;
|
||||||
@@ -615,3 +644,4 @@ private:
|
|||||||
}}
|
}}
|
||||||
|
|
||||||
#endif /* PVACLIENTMULTICHANNEL_H */
|
#endif /* PVACLIENTMULTICHANNEL_H */
|
||||||
|
|
||||||
|
|||||||
+16
-36
@@ -18,12 +18,13 @@
|
|||||||
|
|
||||||
#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;
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
namespace epics { namespace pvaClient {
|
namespace epics { namespace pvaClient {
|
||||||
|
|
||||||
|
|
||||||
class epicsShareClass PvaClientChannelCache
|
class epicsShareClass PvaClientChannelCache
|
||||||
@@ -42,7 +43,7 @@ public:
|
|||||||
private:
|
private:
|
||||||
map<string,PvaClientChannelPtr> pvaClientChannelMap;
|
map<string,PvaClientChannelPtr> pvaClientChannelMap;
|
||||||
};
|
};
|
||||||
|
|
||||||
PvaClientChannelPtr PvaClientChannelCache::getChannel(
|
PvaClientChannelPtr PvaClientChannelCache::getChannel(
|
||||||
string const & channelName,
|
string const & channelName,
|
||||||
string const & providerName)
|
string const & providerName)
|
||||||
@@ -77,7 +78,7 @@ void PvaClientChannelCache::showCache()
|
|||||||
string providerName = channel->getProvider()->getProviderName();
|
string providerName = channel->getProvider()->getProviderName();
|
||||||
cout << "channel " << channelName << " provider " << providerName << endl;
|
cout << "channel " << channelName << " provider " << providerName << endl;
|
||||||
pvaChannel->showCache();
|
pvaChannel->showCache();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t PvaClientChannelCache::cacheSize()
|
size_t PvaClientChannelCache::cacheSize()
|
||||||
@@ -86,18 +87,7 @@ size_t PvaClientChannelCache::cacheSize()
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// MSVC doesn't like making this a class static data member:
|
bool PvaClient::debug = false;
|
||||||
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)
|
||||||
{
|
{
|
||||||
@@ -110,58 +100,47 @@ 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(!channelRegistry->getProvider(providerName)) {
|
if(!registry->getProvider(providerName)) {
|
||||||
cerr << "PvaClient::get provider " << providerName << " not known" << endl;
|
cerr << "PvaClient::get provider " << providerName << " not known" << endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PvaClient::~PvaClient() {
|
PvaClient::~PvaClient() {
|
||||||
if(getDebug()) {
|
if(PvaClient::debug) {
|
||||||
cout<< "PvaClient::~PvaClient()\n"
|
cout<< "PvaClient::~PvaClient()\n"
|
||||||
<< "pvaChannel cache:\n";
|
<< "pvaChannel cache:\n";
|
||||||
showCache();
|
showCache();
|
||||||
}
|
}
|
||||||
if(pvaStarted){
|
if(pvaStarted){
|
||||||
if(getDebug()) cout<< "calling ClientFactory::stop()\n";
|
if(PvaClient::debug) cout<< "calling ClientFactory::stop()\n";
|
||||||
ClientFactory::stop();
|
ClientFactory::stop();
|
||||||
if(getDebug()) cout<< "after calling ClientFactory::stop()\n";
|
if(PvaClient::debug) cout<< "after calling ClientFactory::stop()\n";
|
||||||
}
|
}
|
||||||
if(caStarted) {
|
if(caStarted) {
|
||||||
if(getDebug()) cout<< "calling CAClientFactory::stop()\n";
|
if(PvaClient::debug) cout<< "calling CAClientFactory::stop()\n";
|
||||||
CAClientFactory::stop();
|
CAClientFactory::stop();
|
||||||
if(getDebug()) cout<< "after calling CAClientFactory::stop()\n";
|
if(PvaClient::debug) cout<< "after calling CAClientFactory::stop()\n";
|
||||||
}
|
}
|
||||||
channelRegistry.reset();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
string PvaClient:: getRequesterName()
|
string PvaClient:: getRequesterName()
|
||||||
@@ -191,7 +170,7 @@ PvaClientChannelPtr PvaClient::channel(
|
|||||||
std::string const & providerName,
|
std::string const & providerName,
|
||||||
double timeOut)
|
double timeOut)
|
||||||
{
|
{
|
||||||
PvaClientChannelPtr pvaClientChannel =
|
PvaClientChannelPtr pvaClientChannel =
|
||||||
pvaClientChannelCache->getChannel(channelName,providerName);
|
pvaClientChannelCache->getChannel(channelName,providerName);
|
||||||
if(pvaClientChannel) return pvaClientChannel;
|
if(pvaClientChannel) return pvaClientChannel;
|
||||||
pvaClientChannel = createChannel(channelName,providerName);
|
pvaClientChannel = createChannel(channelName,providerName);
|
||||||
@@ -231,3 +210,4 @@ size_t PvaClient::cacheSize()
|
|||||||
}
|
}
|
||||||
|
|
||||||
}}
|
}}
|
||||||
|
|
||||||
|
|||||||
+90
-112
@@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
#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;
|
||||||
@@ -121,12 +122,60 @@ 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -169,7 +218,6 @@ 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");
|
||||||
@@ -183,7 +231,7 @@ void PvaClientChannel::channelCreated(const Status& status, Channel::shared_poin
|
|||||||
throw std::runtime_error(message);
|
throw std::runtime_error(message);
|
||||||
}
|
}
|
||||||
if(channel->isConnected()) {
|
if(channel->isConnected()) {
|
||||||
connectState = connected;
|
connectState = connected;
|
||||||
waitForConnect.signal();
|
waitForConnect.signal();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -198,28 +246,25 @@ 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()
|
||||||
@@ -252,9 +297,6 @@ 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)
|
||||||
@@ -267,7 +309,7 @@ void PvaClientChannel::connect(double timeout)
|
|||||||
Status status = waitConnect(timeout);
|
Status status = waitConnect(timeout);
|
||||||
if(status.isOK()) return;
|
if(status.isOK()) return;
|
||||||
if(PvaClient::getDebug()) cout << "PvaClientChannel::connect waitConnect failed\n";
|
if(PvaClient::getDebug()) cout << "PvaClientChannel::connect waitConnect failed\n";
|
||||||
string message = string("channel ") + channelName
|
string message = string("channel ") + channelName
|
||||||
+ " PvaClientChannel::connect " + status.getMessage();
|
+ " PvaClientChannel::connect " + status.getMessage();
|
||||||
throw std::runtime_error(message);
|
throw std::runtime_error(message);
|
||||||
}
|
}
|
||||||
@@ -286,13 +328,13 @@ void PvaClientChannel::issueConnect()
|
|||||||
}
|
}
|
||||||
connectState = connectActive;
|
connectState = connectActive;
|
||||||
}
|
}
|
||||||
ChannelProviderRegistry::shared_pointer reg(ChannelProviderRegistry::clients());
|
ChannelProviderRegistry::shared_pointer reg = getChannelProviderRegistry();
|
||||||
channelProvider = reg->getProvider(providerName);
|
ChannelProvider::shared_pointer provider = reg->getProvider(providerName);
|
||||||
if(!channelProvider) {
|
if(!provider) {
|
||||||
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 = channelProvider->createChannel(channelName,shared_from_this(),ChannelProvider::PRIORITY_DEFAULT);
|
channel = provider->createChannel(channelName,channelRequester,ChannelProvider::PRIORITY_DEFAULT);
|
||||||
if(!channel) {
|
if(!channel) {
|
||||||
throw std::runtime_error(channelName + " channelCreate failed ");
|
throw std::runtime_error(channelName + " channelCreate failed ");
|
||||||
}
|
}
|
||||||
@@ -306,7 +348,6 @@ 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) {
|
||||||
@@ -314,9 +355,8 @@ 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," not connected");
|
return Status(Status::STATUSTYPE_ERROR,channelName + " not connected");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -330,7 +370,7 @@ PvaClientProcessPtr PvaClientChannel::createProcess(string const & request)
|
|||||||
{
|
{
|
||||||
PVStructurePtr pvRequest = createRequest->createRequest(request);
|
PVStructurePtr pvRequest = createRequest->createRequest(request);
|
||||||
if(!pvRequest) {
|
if(!pvRequest) {
|
||||||
string message = string("channel ") + channelName
|
string message = string("channel ") + channelName
|
||||||
+ " PvaClientChannel::createProcess invalid pvRequest: "
|
+ " PvaClientChannel::createProcess invalid pvRequest: "
|
||||||
+ createRequest->getMessage();
|
+ createRequest->getMessage();
|
||||||
throw std::runtime_error(message);
|
throw std::runtime_error(message);
|
||||||
@@ -343,19 +383,17 @@ 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,shared_from_this(),pvRequest);
|
return PvaClientProcess::create(yyy,channel,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) {
|
if(pvaClientGet) return 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -364,7 +402,7 @@ PvaClientGetPtr PvaClientChannel::createGet(string const & request)
|
|||||||
{
|
{
|
||||||
PVStructurePtr pvRequest = createRequest->createRequest(request);
|
PVStructurePtr pvRequest = createRequest->createRequest(request);
|
||||||
if(!pvRequest) {
|
if(!pvRequest) {
|
||||||
string message = string("channel ") + channelName
|
string message = string("channel ") + channelName
|
||||||
+ " PvaClientChannel::createGet invalid pvRequest: "
|
+ " PvaClientChannel::createGet invalid pvRequest: "
|
||||||
+ createRequest->getMessage();
|
+ createRequest->getMessage();
|
||||||
throw std::runtime_error(message);
|
throw std::runtime_error(message);
|
||||||
@@ -377,27 +415,7 @@ 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,shared_from_this(),pvRequest);
|
return PvaClientGet::create(yyy,channel,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();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -405,12 +423,10 @@ PvaClientPutPtr PvaClientChannel::put(string const & request)
|
|||||||
{
|
{
|
||||||
PvaClientPutPtr pvaClientPut = pvaClientPutCache->getPut(request);
|
PvaClientPutPtr pvaClientPut = pvaClientPutCache->getPut(request);
|
||||||
if(pvaClientPut) return pvaClientPut;
|
if(pvaClientPut) return pvaClientPut;
|
||||||
if(!pvaClientPut) {
|
pvaClientPut = createPut(request);
|
||||||
pvaClientPut = createPut(request);
|
pvaClientPut->connect();
|
||||||
pvaClientPut->connect();
|
pvaClientPut->get();
|
||||||
pvaClientPut->get();
|
pvaClientPutCache->addPut(request,pvaClientPut);
|
||||||
pvaClientPutCache->addPut(request,pvaClientPut);
|
|
||||||
}
|
|
||||||
return pvaClientPut;
|
return pvaClientPut;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -419,7 +435,7 @@ PvaClientPutPtr PvaClientChannel::createPut(string const & request)
|
|||||||
{
|
{
|
||||||
PVStructurePtr pvRequest = createRequest->createRequest(request);
|
PVStructurePtr pvRequest = createRequest->createRequest(request);
|
||||||
if(!pvRequest) {
|
if(!pvRequest) {
|
||||||
string message = string("channel ") + channelName
|
string message = string("channel ") + channelName
|
||||||
+ " PvaClientChannel::createPut invalid pvRequest: "
|
+ " PvaClientChannel::createPut invalid pvRequest: "
|
||||||
+ createRequest->getMessage();
|
+ createRequest->getMessage();
|
||||||
throw std::runtime_error(message);
|
throw std::runtime_error(message);
|
||||||
@@ -432,52 +448,14 @@ 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,shared_from_this(),pvRequest);
|
return PvaClientPut::create(yyy,channel,pvRequest);
|
||||||
}
|
|
||||||
|
|
||||||
void PvaClientChannel::putDouble(double value,string const & request)
|
|
||||||
{
|
|
||||||
PvaClientPutPtr clientPut = put(request);
|
|
||||||
PvaClientPutDataPtr putData = clientPut->getData();
|
|
||||||
putData->putDouble(value); clientPut->put();
|
|
||||||
}
|
|
||||||
|
|
||||||
void PvaClientChannel::putString(std::string const & value,string const & request)
|
|
||||||
{
|
|
||||||
PvaClientPutPtr clientPut = put(request);
|
|
||||||
PvaClientPutDataPtr putData = clientPut->getData();
|
|
||||||
putData->putString(value); clientPut->put();
|
|
||||||
}
|
|
||||||
|
|
||||||
void PvaClientChannel::putDoubleArray(
|
|
||||||
shared_vector<const double> const & value,
|
|
||||||
string const & request)
|
|
||||||
{
|
|
||||||
PvaClientPutPtr clientPut = put(request);
|
|
||||||
PvaClientPutDataPtr putData = clientPut->getData();
|
|
||||||
size_t n = value.size();
|
|
||||||
shared_vector<double> valueArray(n);
|
|
||||||
for(size_t i=0; i<n; ++i) valueArray[i] = value[i];
|
|
||||||
putData->putDoubleArray(freeze(valueArray)); clientPut->put();
|
|
||||||
}
|
|
||||||
|
|
||||||
void PvaClientChannel::putStringArray(
|
|
||||||
shared_vector<const string> const & value,
|
|
||||||
string const & request)
|
|
||||||
{
|
|
||||||
PvaClientPutPtr clientPut = put(request);
|
|
||||||
PvaClientPutDataPtr putData = clientPut->getData();
|
|
||||||
size_t n = value.size();
|
|
||||||
shared_vector<string> valueArray(n);
|
|
||||||
for(size_t i=0; i<n; ++i) valueArray[i] = value[i];
|
|
||||||
putData->putStringArray(freeze(valueArray)); clientPut->put();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PvaClientPutGetPtr PvaClientChannel::createPutGet(string const & request)
|
PvaClientPutGetPtr PvaClientChannel::createPutGet(string const & request)
|
||||||
{
|
{
|
||||||
PVStructurePtr pvRequest = createRequest->createRequest(request);
|
PVStructurePtr pvRequest = createRequest->createRequest(request);
|
||||||
if(!pvRequest) {
|
if(!pvRequest) {
|
||||||
string message = string("channel ") + channelName
|
string message = string("channel ") + channelName
|
||||||
+ " PvaClientChannel::createPutGet invalid pvRequest: "
|
+ " PvaClientChannel::createPutGet invalid pvRequest: "
|
||||||
+ createRequest->getMessage();
|
+ createRequest->getMessage();
|
||||||
throw std::runtime_error(message);
|
throw std::runtime_error(message);
|
||||||
@@ -490,7 +468,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,shared_from_this(),pvRequest);
|
return PvaClientPutGet::create(yyy,channel,pvRequest);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -499,7 +477,7 @@ PvaClientArrayPtr PvaClientChannel::createArray(string const & request)
|
|||||||
{
|
{
|
||||||
PVStructurePtr pvRequest = createRequest->createRequest(request);
|
PVStructurePtr pvRequest = createRequest->createRequest(request);
|
||||||
if(!pvRequest) {
|
if(!pvRequest) {
|
||||||
string message = string("channel ") + channelName
|
string message = string("channel ") + channelName
|
||||||
+ " PvaClientChannel::createArray invalid pvRequest: "
|
+ " PvaClientChannel::createArray invalid pvRequest: "
|
||||||
+ createRequest->getMessage();
|
+ createRequest->getMessage();
|
||||||
throw std::runtime_error(message);
|
throw std::runtime_error(message);
|
||||||
@@ -541,7 +519,7 @@ PvaClientMonitorPtr PvaClientChannel::createMonitor(string const & request)
|
|||||||
{
|
{
|
||||||
PVStructurePtr pvRequest = createRequest->createRequest(request);
|
PVStructurePtr pvRequest = createRequest->createRequest(request);
|
||||||
if(!pvRequest) {
|
if(!pvRequest) {
|
||||||
string message = string("channel ") + channelName
|
string message = string("channel ") + channelName
|
||||||
+ " PvaClientChannel::createMonitor invalid pvRequest: "
|
+ " PvaClientChannel::createMonitor invalid pvRequest: "
|
||||||
+ createRequest->getMessage();
|
+ createRequest->getMessage();
|
||||||
throw std::runtime_error(message);
|
throw std::runtime_error(message);
|
||||||
@@ -554,14 +532,14 @@ 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,shared_from_this(),pvRequest);
|
return PvaClientMonitor::create(yyy,channel,pvRequest);
|
||||||
}
|
}
|
||||||
|
|
||||||
PVStructurePtr PvaClientChannel::rpc(
|
PVStructurePtr PvaClientChannel::rpc(
|
||||||
PVStructurePtr const & pvRequest,
|
PVStructurePtr const & pvRequest,
|
||||||
PVStructurePtr const & pvArgument)
|
PVStructurePtr const & pvArgument)
|
||||||
{
|
{
|
||||||
|
|
||||||
PvaClientRPCPtr rpc = createRPC(pvRequest);
|
PvaClientRPCPtr rpc = createRPC(pvRequest);
|
||||||
return rpc->request(pvArgument);
|
return rpc->request(pvArgument);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,440 +0,0 @@
|
|||||||
/* 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 <istream>
|
|
||||||
#include <ostream>
|
|
||||||
|
|
||||||
#include <pv/createRequest.h>
|
|
||||||
#include <pv/convert.h>
|
|
||||||
#include <pv/pvEnumerated.h>
|
|
||||||
|
|
||||||
#if EPICS_VERSION_INT>=VERSION_INT(3,15,0,1)
|
|
||||||
# include <pv/json.h>
|
|
||||||
# define USE_JSON
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#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)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
PVFieldPtr PvaClientData::getSinglePVField()
|
|
||||||
{
|
|
||||||
if(PvaClient::getDebug()) cout << "PvaClientData::getSinglePVField\n";
|
|
||||||
PVStructurePtr pvStructure = getPVStructure();
|
|
||||||
while(true) {
|
|
||||||
const PVFieldPtrArray fieldPtrArray(pvStructure->getPVFields());
|
|
||||||
if(fieldPtrArray.size()==0) {
|
|
||||||
throw std::logic_error("PvaClientData::getSinglePVField() pvRequest for empty structure");
|
|
||||||
}
|
|
||||||
if(fieldPtrArray.size()!=1) {
|
|
||||||
PVFieldPtr pvValue = pvStructure->getSubField("value");
|
|
||||||
if(pvValue) {
|
|
||||||
Type type = pvValue->getField()->getType();
|
|
||||||
if(type!=epics::pvData::structure) return pvValue;
|
|
||||||
}
|
|
||||||
throw std::logic_error("PvaClientData::getSinglePVField() pvRequest for multiple fields");
|
|
||||||
}
|
|
||||||
PVFieldPtr pvField(fieldPtrArray[0]);
|
|
||||||
Type type = pvField->getField()->getType();
|
|
||||||
if(type!=epics::pvData::structure) return pvField;
|
|
||||||
pvStructure = static_pointer_cast<PVStructure>(pvField);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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";
|
|
||||||
PVFieldPtr pvField = getSinglePVField();
|
|
||||||
Type type = pvField->getField()->getType();
|
|
||||||
if(type!=scalar) {
|
|
||||||
throw std::logic_error("PvaClientData::getDouble() did not find a scalar field");
|
|
||||||
}
|
|
||||||
PVScalarPtr pvScalar = static_pointer_cast<PVScalar>(pvField);
|
|
||||||
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";
|
|
||||||
PVFieldPtr pvField = getSinglePVField();
|
|
||||||
Type type = pvField->getField()->getType();
|
|
||||||
if(type!=scalar) {
|
|
||||||
throw std::logic_error("PvaClientData::getString() did not find a scalar field");
|
|
||||||
}
|
|
||||||
PVScalarPtr pvScalar = static_pointer_cast<PVScalar>(pvField);
|
|
||||||
return convert->toString(pvScalar);
|
|
||||||
}
|
|
||||||
|
|
||||||
shared_vector<const double> PvaClientData::getDoubleArray()
|
|
||||||
{
|
|
||||||
if(PvaClient::getDebug()) cout << "PvaClientData::getDoubleArray\n";
|
|
||||||
PVFieldPtr pvField = getSinglePVField();
|
|
||||||
Type type = pvField->getField()->getType();
|
|
||||||
if(type!=scalarArray) {
|
|
||||||
throw std::logic_error("PvaClientData::getDoubleArray() did not find a scalarArray field");
|
|
||||||
}
|
|
||||||
PVScalarArrayPtr pvScalarArray = static_pointer_cast<PVScalarArray>(pvField);
|
|
||||||
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";
|
|
||||||
PVFieldPtr pvField = getSinglePVField();
|
|
||||||
Type type = pvField->getField()->getType();
|
|
||||||
if(type!=scalarArray) {
|
|
||||||
throw std::logic_error("PvaClientData::getStringArray() did not find a scalarArray field");
|
|
||||||
}
|
|
||||||
PVScalarArrayPtr pvScalarArray = static_pointer_cast<PVScalarArray>(pvField);
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
void PvaClientData::zeroArrayLength()
|
|
||||||
{
|
|
||||||
if(!pvStructure) throw new std::runtime_error(messagePrefix + noStructure);
|
|
||||||
zeroArrayLength(pvStructure);
|
|
||||||
}
|
|
||||||
void PvaClientData::parse(
|
|
||||||
const std::string &arg,const PVFieldPtr &dest,BitSetPtr & bitSet)
|
|
||||||
{
|
|
||||||
#ifdef USE_JSON
|
|
||||||
std::istringstream strm(arg);
|
|
||||||
parseJSON(strm, dest,&(*bitSet));
|
|
||||||
#else
|
|
||||||
throw std::runtime_error("JSON support not built");
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void PvaClientData::parse(
|
|
||||||
const std::string &arg,const PVUnionPtr &pvUnion)
|
|
||||||
{
|
|
||||||
if(pvUnion->getUnion()->isVariant()) {
|
|
||||||
throw std::runtime_error(messagePrefix + "varient union not implemented");
|
|
||||||
}
|
|
||||||
size_t iequals = arg.find_first_of('=');
|
|
||||||
string field;
|
|
||||||
string rest;
|
|
||||||
if(iequals==std::string::npos) {
|
|
||||||
string mess(arg);
|
|
||||||
mess += " was expected to start with field=";
|
|
||||||
throw std::runtime_error(messagePrefix + mess);
|
|
||||||
}
|
|
||||||
field = arg.substr(0,iequals);
|
|
||||||
rest = arg.substr(iequals+1);
|
|
||||||
PVFieldPtr pvField(pvUnion->select(field));
|
|
||||||
if(pvField->getField()->getType()==epics::pvData::union_) {
|
|
||||||
PVUnionPtr pvu = static_pointer_cast<PVUnion>(pvField);
|
|
||||||
parse(rest,pvu);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
BitSetPtr bs;
|
|
||||||
parse(rest,pvField,bs);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
void PvaClientData::parse(const std::vector<std::string> &args)
|
|
||||||
{
|
|
||||||
if(!pvStructure) throw std::runtime_error(messagePrefix + noStructure);
|
|
||||||
if(!bitSet) throw std::runtime_error(messagePrefix + noStructure);
|
|
||||||
size_t num = args.size();
|
|
||||||
if(num<1) throw std::runtime_error(messagePrefix + " no arguments");
|
|
||||||
for(size_t i=0; i<num; ++i)
|
|
||||||
{
|
|
||||||
string val = args[i];
|
|
||||||
size_t iequals = val.find_first_of('=');
|
|
||||||
string field;
|
|
||||||
string rest(val);
|
|
||||||
if(iequals==std::string::npos) {
|
|
||||||
parse(rest,pvStructure,bitSet);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
field = val.substr(0,iequals);
|
|
||||||
rest = val.substr(iequals+1);
|
|
||||||
if(field.size()==std::string::npos) {
|
|
||||||
parse(rest,pvStructure,bitSet);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
PVFieldPtr pvField(pvStructure->getSubField(field));
|
|
||||||
if(!pvField) throw std::runtime_error(messagePrefix + field +" does not exist");
|
|
||||||
// look for enumerated structure
|
|
||||||
PVEnumerated pvEnumerated;
|
|
||||||
bool result = pvEnumerated.attach(pvField);
|
|
||||||
if(result) {
|
|
||||||
PVStringArray::const_svector choices(pvEnumerated.getChoices());
|
|
||||||
for(size_t i=0; i<choices.size(); ++i) {
|
|
||||||
if(choices[i]==rest) {
|
|
||||||
pvEnumerated.setIndex(i);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// look for union
|
|
||||||
PVUnionPtr pvUnion(pvStructure->getSubField<PVUnion>(field));
|
|
||||||
if(pvUnion) {
|
|
||||||
parse(rest,pvUnion);
|
|
||||||
bitSet->set(pvUnion->getFieldOffset());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
parse(rest,pvField,bitSet);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void PvaClientData::streamJSON(
|
|
||||||
std::ostream& strm,
|
|
||||||
bool ignoreUnprintable,
|
|
||||||
bool multiLine)
|
|
||||||
{
|
|
||||||
#ifdef USE_JSON
|
|
||||||
JSONPrintOptions opts;
|
|
||||||
opts.ignoreUnprintable = ignoreUnprintable;
|
|
||||||
opts.multiLine = multiLine;
|
|
||||||
printJSON(strm,*pvStructure,*bitSet,opts);
|
|
||||||
#else
|
|
||||||
throw std::runtime_error("JSON support not built");
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void PvaClientData::zeroArrayLength(const epics::pvData::PVStructurePtr &pvStructure)
|
|
||||||
{
|
|
||||||
const PVFieldPtrArray pvFields(pvStructure->getPVFields());
|
|
||||||
for(size_t i=0; i<pvFields.size(); ++i) {
|
|
||||||
PVFieldPtr pvField = pvFields[i];
|
|
||||||
Type type(pvField->getField()->getType());
|
|
||||||
switch(type) {
|
|
||||||
case epics::pvData::scalarArray:
|
|
||||||
{
|
|
||||||
PVScalarArrayPtr pvScalarArray = static_pointer_cast<PVScalarArray>(pvField);
|
|
||||||
pvScalarArray->setLength(0);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case epics::pvData::structureArray:
|
|
||||||
{
|
|
||||||
PVStructureArrayPtr pvStructureArray = static_pointer_cast<PVStructureArray>(pvField);
|
|
||||||
pvStructureArray->setLength(0);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case epics::pvData::structure:
|
|
||||||
{
|
|
||||||
PVStructurePtr pvStructure = static_pointer_cast<PVStructure>(pvField);
|
|
||||||
zeroArrayLength(pvStructure);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}}
|
|
||||||
+72
-120
@@ -15,6 +15,7 @@
|
|||||||
|
|
||||||
#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;
|
||||||
@@ -55,7 +56,7 @@ public:
|
|||||||
{
|
{
|
||||||
PvaClientGetPtr clientGet(pvaClientGet.lock());
|
PvaClientGetPtr clientGet(pvaClientGet.lock());
|
||||||
if(!clientGet) return;
|
if(!clientGet) return;
|
||||||
clientGet->channelGetConnect(status,channelGet,structure);
|
clientGet->channelGetConnect(status,channelGet,structure);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void getDone(
|
virtual void getDone(
|
||||||
@@ -72,66 +73,50 @@ public:
|
|||||||
|
|
||||||
PvaClientGetPtr PvaClientGet::create(
|
PvaClientGetPtr PvaClientGet::create(
|
||||||
PvaClientPtr const &pvaClient,
|
PvaClientPtr const &pvaClient,
|
||||||
PvaClientChannelPtr const & pvaClientChannel,
|
Channel::shared_pointer const & channel,
|
||||||
PVStructurePtr const &pvRequest)
|
PVStructurePtr const &pvRequest)
|
||||||
{
|
{
|
||||||
if(PvaClient::getDebug()) {
|
PvaClientGetPtr epv(new PvaClientGet(pvaClient,channel,pvRequest));
|
||||||
cout<< "PvaClientGet::create(pvaClient,channelName,pvRequest)\n"
|
epv->channelGetRequester = ChannelGetRequesterImplPtr(
|
||||||
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
|
new ChannelGetRequesterImpl(epv,pvaClient));
|
||||||
<< " pvRequest " << pvRequest
|
return epv;
|
||||||
<< 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,
|
||||||
PvaClientChannelPtr const & pvaClientChannel,
|
Channel::shared_pointer const & channel,
|
||||||
PVStructurePtr const &pvRequest)
|
PVStructurePtr const &pvRequest)
|
||||||
: pvaClient(pvaClient),
|
: pvaClient(pvaClient),
|
||||||
pvaClientChannel(pvaClientChannel),
|
channel(channel),
|
||||||
pvRequest(pvRequest),
|
pvRequest(pvRequest),
|
||||||
connectState(connectIdle),
|
connectState(connectIdle),
|
||||||
getState(getIdle)
|
getState(getIdle)
|
||||||
{
|
{
|
||||||
if(PvaClient::getDebug()) {
|
if(PvaClient::getDebug()) {
|
||||||
cout << "PvaClientGet::PvaClientGet channelName "
|
cout << "PvaClientGet::PvaClientGet::PvaClientGet"
|
||||||
<< pvaClientChannel->getChannel()->getChannelName() << "\n";
|
<< " channelName " << channel->getChannelName()
|
||||||
|
<< endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PvaClientGet::~PvaClientGet()
|
PvaClientGet::~PvaClientGet()
|
||||||
{
|
{
|
||||||
if(PvaClient::getDebug()) {
|
if(PvaClient::getDebug()) {
|
||||||
cout<< "PvaClientGet::~PvaClientGet channelName "
|
string channelName("disconnected");
|
||||||
<< pvaClientChannel->getChannel()->getChannelName() << "\n";
|
Channel::shared_pointer chan(channel.lock());
|
||||||
|
if(chan) channelName = chan->getChannelName();
|
||||||
|
cout<< "PvaClientGet::~PvaClientGet"
|
||||||
|
<< " channelName " << channelName
|
||||||
|
<< endl;
|
||||||
}
|
}
|
||||||
|
if(channelGet) channelGet->destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PvaClientGet::checkGetState()
|
||||||
void PvaClientGet::checkConnectState()
|
|
||||||
{
|
{
|
||||||
if(PvaClient::getDebug()) {
|
if(connectState==connectIdle) connect();
|
||||||
cout << "PvaClientGet::checkConnectState channelName "
|
if(getState==getIdle) get();
|
||||||
<< 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
|
||||||
@@ -155,34 +140,26 @@ void PvaClientGet::channelGetConnect(
|
|||||||
StructureConstPtr const & structure)
|
StructureConstPtr const & structure)
|
||||||
{
|
{
|
||||||
if(PvaClient::getDebug()) {
|
if(PvaClient::getDebug()) {
|
||||||
cout << "PvaClientGet::channelGetConnect channelName "
|
string channelName("disconnected");
|
||||||
<< pvaClientChannel->getChannel()->getChannelName()
|
Channel::shared_pointer chan(channel.lock());
|
||||||
|
if(chan) channelName = chan->getChannelName();
|
||||||
|
cout << "PvaClientGet::channelGetConnect"
|
||||||
|
<< " channelName " << channelName
|
||||||
<< " status.isOK " << (status.isOK() ? "true" : "false")
|
<< " status.isOK " << (status.isOK() ? "true" : "false")
|
||||||
<< "\n";
|
<< endl;
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
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();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PvaClientGet::getDone(
|
void PvaClientGet::getDone(
|
||||||
@@ -192,62 +169,57 @@ void PvaClientGet::getDone(
|
|||||||
BitSetPtr const & bitSet)
|
BitSetPtr const & bitSet)
|
||||||
{
|
{
|
||||||
if(PvaClient::getDebug()) {
|
if(PvaClient::getDebug()) {
|
||||||
cout << "PvaClientGet::getDone channelName "
|
string channelName("disconnected");
|
||||||
<< pvaClientChannel->getChannel()->getChannelName()
|
Channel::shared_pointer chan(channel.lock());
|
||||||
|
if(chan) channelName = chan->getChannelName();
|
||||||
|
cout << "PvaClientGet::getDone"
|
||||||
|
<< " channelName " << channelName
|
||||||
<< " status.isOK " << (status.isOK() ? "true" : "false")
|
<< " status.isOK " << (status.isOK() ? "true" : "false")
|
||||||
<< "\n";
|
<< endl;
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
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;
|
||||||
string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName()
|
Channel::shared_pointer chan(channel.lock());
|
||||||
|
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()
|
||||||
{
|
{
|
||||||
if(PvaClient::getDebug()) {
|
Channel::shared_pointer chan(channel.lock());
|
||||||
cout << "PvaClientGet::issueConnect channelName "
|
|
||||||
<< pvaClientChannel->getChannel()->getChannelName() << "\n";
|
|
||||||
}
|
|
||||||
if(connectState!=connectIdle) {
|
if(connectState!=connectIdle) {
|
||||||
string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName()
|
string channelName("disconnected");
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
connectState = connectActive;
|
if(chan) {
|
||||||
channelGetConnectStatus = Status(Status::STATUSTYPE_ERROR, "connect active");
|
connectState = connectActive;
|
||||||
channelGet = pvaClientChannel->getChannel()->createChannelGet(channelGetRequester,pvRequest);
|
channelGet = chan->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) {
|
||||||
@@ -255,7 +227,10 @@ Status PvaClientGet::waitConnect()
|
|||||||
return channelGetConnectStatus;
|
return channelGetConnectStatus;
|
||||||
}
|
}
|
||||||
if(connectState!=connectActive) {
|
if(connectState!=connectActive) {
|
||||||
string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName()
|
Channel::shared_pointer chan(channel.lock());
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
@@ -267,27 +242,25 @@ 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;
|
||||||
string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName()
|
Channel::shared_pointer chan(channel.lock());
|
||||||
|
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==getActive) {
|
if(getState!=getIdle) {
|
||||||
string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName()
|
Channel::shared_pointer chan(channel.lock());
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
@@ -297,51 +270,30 @@ 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){
|
||||||
string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName()
|
Channel::shared_pointer chan(channel.lock());
|
||||||
|
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 = getComplete;
|
getState = getIdle;
|
||||||
return channelGetStatus;
|
return channelGetStatus;
|
||||||
}
|
}
|
||||||
PvaClientGetDataPtr PvaClientGet::getData()
|
PvaClientGetDataPtr PvaClientGet::getData()
|
||||||
{
|
{
|
||||||
if(PvaClient::getDebug()) {
|
checkGetState();
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}}
|
}}
|
||||||
|
|||||||
+188
-3
@@ -19,6 +19,7 @@
|
|||||||
|
|
||||||
#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;
|
||||||
@@ -26,15 +27,199 @@ 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)
|
||||||
: PvaClientData(structure)
|
: structure(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);
|
||||||
|
}
|
||||||
|
|
||||||
}}
|
}}
|
||||||
|
|||||||
+158
-195
@@ -17,6 +17,8 @@
|
|||||||
|
|
||||||
#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;
|
||||||
@@ -57,72 +59,42 @@ public:
|
|||||||
{
|
{
|
||||||
PvaClientMonitorPtr clientMonitor(pvaClientMonitor.lock());
|
PvaClientMonitorPtr clientMonitor(pvaClientMonitor.lock());
|
||||||
if(!clientMonitor) return;
|
if(!clientMonitor) return;
|
||||||
clientMonitor->monitorConnect(status,monitor,structure);
|
clientMonitor->monitorConnect(status,monitor,structure);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void unlisten(epics::pvData::MonitorPtr const & monitor)
|
virtual void unlisten(epics::pvData::MonitorPtr const & monitor)
|
||||||
{
|
{
|
||||||
PvaClientMonitorPtr clientMonitor(pvaClientMonitor.lock());
|
PvaClientMonitorPtr clientMonitor(pvaClientMonitor.lock());
|
||||||
if(!clientMonitor) return;
|
if(!clientMonitor) return;
|
||||||
clientMonitor->unlisten(monitor);
|
clientMonitor->unlisten(monitor);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void monitorEvent(epics::pvData::MonitorPtr const & monitor)
|
virtual void monitorEvent(epics::pvData::MonitorPtr const & monitor)
|
||||||
{
|
{
|
||||||
PvaClientMonitorPtr clientMonitor(pvaClientMonitor.lock());
|
PvaClientMonitorPtr clientMonitor(pvaClientMonitor.lock());
|
||||||
if(!clientMonitor) return;
|
if(!clientMonitor) return;
|
||||||
clientMonitor->monitorEvent(monitor);
|
clientMonitor->monitorEvent(monitor);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
PvaClientMonitorPtr PvaClientMonitor::create(
|
PvaClientMonitorPtr PvaClientMonitor::create(
|
||||||
PvaClientPtr const &pvaClient,
|
PvaClientPtr const &pvaClient,
|
||||||
PvaClientChannelPtr const & pvaClientChannel,
|
Channel::shared_pointer const & channel,
|
||||||
PVStructurePtr const &pvRequest)
|
PVStructurePtr const &pvRequest)
|
||||||
{
|
{
|
||||||
PvaClientMonitorPtr clientMonitor(new PvaClientMonitor(pvaClient,pvaClientChannel,pvRequest));
|
PvaClientMonitorPtr epv(new PvaClientMonitor(pvaClient,channel,pvRequest));
|
||||||
clientMonitor->monitorRequester = MonitorRequesterImplPtr(
|
epv->monitorRequester = MonitorRequesterImplPtr(
|
||||||
new MonitorRequesterImpl(clientMonitor,pvaClient));
|
new MonitorRequesterImpl(epv,pvaClient));
|
||||||
return clientMonitor;
|
return epv;
|
||||||
}
|
}
|
||||||
|
|
||||||
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,
|
||||||
PvaClientChannelPtr const & pvaClientChannel,
|
Channel::shared_pointer const & channel,
|
||||||
PVStructurePtr const &pvRequest)
|
PVStructurePtr const &pvRequest)
|
||||||
: pvaClient(pvaClient),
|
: pvaClient(pvaClient),
|
||||||
pvaClientChannel(pvaClientChannel),
|
channel(channel),
|
||||||
pvRequest(pvRequest),
|
pvRequest(pvRequest),
|
||||||
isStarted(false),
|
isStarted(false),
|
||||||
connectState(connectIdle),
|
connectState(connectIdle),
|
||||||
@@ -130,73 +102,42 @@ PvaClientMonitor::PvaClientMonitor(
|
|||||||
userWait(false)
|
userWait(false)
|
||||||
{
|
{
|
||||||
if(PvaClient::getDebug()) {
|
if(PvaClient::getDebug()) {
|
||||||
cout<< "PvaClientMonitor::PvaClientMonitor\n"
|
cout<< "PvaClientMonitor::PvaClientMonitor()"
|
||||||
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
|
<< " channelName " << channel->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 " << pvaClientChannel->getChannel()->getChannelName()
|
<< " channelName " << channelName
|
||||||
<< 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 " << pvaClientChannel->getChannel()->getChannelName()
|
<< " channelName " << channelName
|
||||||
<< " connectState " << connectState
|
<< " connectState " << connectState
|
||||||
<< endl;
|
<< endl;
|
||||||
}
|
}
|
||||||
if(connectState==connectIdle) {
|
if(connectState==connectIdle) connect();
|
||||||
connect();
|
if(connectState==connected && !isStarted) start();
|
||||||
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()
|
||||||
@@ -218,65 +159,52 @@ 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 " << pvaClientChannel->getChannel()->getChannelName()
|
<< " channelName " << channelName
|
||||||
<< " 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 " << pvaClientChannel->getChannel()->getChannelName()
|
<< " channelName " << channelName
|
||||||
<< " is already started "
|
<< " is already started "
|
||||||
<< endl;
|
<< endl;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
pvaClientData = PvaClientMonitorData::create(structure);
|
if(status.isOK() && chan) {
|
||||||
pvaClientData->setMessagePrefix(pvaClientChannel->getChannel()->getChannelName());
|
pvaClientData = PvaClientMonitorData::create(structure);
|
||||||
if(signal) {
|
pvaClientData->setMessagePrefix(chan->getChannelName());
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
PvaClientMonitorRequesterPtr req(pvaClientMonitorRequester.lock());
|
if(PvaClient::getDebug()) {
|
||||||
if(req) req->monitorConnect(status,shared_from_this(),structure);
|
cout << "PvaClientMonitor::monitorConnect calling waitForConnect.signal\n";
|
||||||
|
}
|
||||||
|
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 " << pvaClientChannel->getChannel()->getChannelName()
|
<< " channelName " << channelName
|
||||||
<< endl;
|
<< endl;
|
||||||
}
|
}
|
||||||
PvaClientMonitorRequesterPtr req = pvaClientMonitorRequester.lock();
|
PvaClientMonitorRequesterPtr req = pvaClientMonitorRequester.lock();
|
||||||
if(req) req->event(shared_from_this());
|
if(req) req->event(shared_from_this());
|
||||||
if(userWait) waitForEvent.signal();
|
if(userWait) waitForEvent.signal();
|
||||||
@@ -290,7 +218,10 @@ void PvaClientMonitor::unlisten(MonitorPtr const & monitor)
|
|||||||
req->unlisten();
|
req->unlisten();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
cerr << pvaClientChannel->getChannel()->getChannelName() + "pvaClientMonitor::unlisten called but no PvaClientMonitorRequester\n";
|
string channelName("disconnected");
|
||||||
|
Channel::shared_pointer chan(channel.lock());
|
||||||
|
if(chan) channelName = chan->getChannelName();
|
||||||
|
cerr << channelName + "pvaClientMonitor::unlisten called but no PvaClientMonitorRequester\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -300,8 +231,11 @@ void PvaClientMonitor::connect()
|
|||||||
issueConnect();
|
issueConnect();
|
||||||
Status status = waitConnect();
|
Status status = waitConnect();
|
||||||
if(status.isOK()) return;
|
if(status.isOK()) return;
|
||||||
string message = string("channel ")
|
Channel::shared_pointer chan(channel.lock());
|
||||||
+ pvaClientChannel->getChannel()->getChannelName()
|
string channelName("disconnected");
|
||||||
|
if(chan) channelName = chan->getChannelName();
|
||||||
|
string message = string("channel ")
|
||||||
|
+ channelName
|
||||||
+ " PvaClientMonitor::connect "
|
+ " PvaClientMonitor::connect "
|
||||||
+ status.getMessage();
|
+ status.getMessage();
|
||||||
throw std::runtime_error(message);
|
throw std::runtime_error(message);
|
||||||
@@ -310,50 +244,59 @@ 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 ")
|
||||||
+ pvaClientChannel->getChannel()->getChannelName()
|
+ channelName
|
||||||
+ " pvaClientMonitor already connected ";
|
+ " pvaClientMonitor already connected ";
|
||||||
throw std::runtime_error(message);
|
throw std::runtime_error(message);
|
||||||
}
|
}
|
||||||
connectState = connectWait;
|
if(chan) {
|
||||||
monitor = pvaClientChannel->getChannel()->createMonitor(monitorRequester,pvRequest);
|
connectState = connectActive;
|
||||||
|
monitor = chan->createMonitor(monitorRequester,pvRequest);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
throw std::runtime_error("PvaClientMonitor::issueConnect() but channel disconnected");
|
||||||
}
|
}
|
||||||
|
|
||||||
Status PvaClientMonitor::waitConnect()
|
Status PvaClientMonitor::waitConnect()
|
||||||
{
|
{
|
||||||
if(PvaClient::getDebug()) {
|
if(PvaClient::getDebug()) cout << "PvaClientMonitor::waitConnect\n";
|
||||||
cout << "PvaClientMonitor::waitConnect "
|
if(connectState==connected) {
|
||||||
<< pvaClientChannel->getChannel()->getChannelName()
|
if(!connectStatus.isOK()) connectState = connectIdle;
|
||||||
<< endl;
|
return connectStatus;
|
||||||
}
|
}
|
||||||
{
|
if(connectState!=connectActive) {
|
||||||
Lock xx(mutex);
|
Channel::shared_pointer chan(channel.lock());
|
||||||
if(connectState==connected) {
|
string channelName("disconnected");
|
||||||
if(!monitorConnectStatus.isOK()) connectState = connectIdle;
|
if(chan) channelName = chan->getChannelName();
|
||||||
return monitorConnectStatus;
|
string message = string("channel ")
|
||||||
}
|
+ channelName
|
||||||
if(connectState!=connectWait) {
|
+ " PvaClientMonitor::waitConnect illegal connect state ";
|
||||||
string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName()
|
throw std::runtime_error(message);
|
||||||
+ " PvaClientMonitor::waitConnect illegal connect state ";
|
}
|
||||||
throw std::runtime_error(message);
|
if(PvaClient::getDebug()) {
|
||||||
}
|
cout << "PvaClientMonitor::waitConnect calling waitForConnect.wait\n";
|
||||||
}
|
}
|
||||||
waitForConnect.wait();
|
waitForConnect.wait();
|
||||||
connectState = monitorConnectStatus.isOK() ? connected : connectIdle;
|
connectState = connectStatus.isOK() ? connected : connectIdle;
|
||||||
if(PvaClient::getDebug()) {
|
if(PvaClient::getDebug()) {
|
||||||
cout << "PvaClientMonitor::waitConnect"
|
cout << "PvaClientMonitor::waitConnect"
|
||||||
<< " monitorConnectStatus " << (monitorConnectStatus.isOK() ? "connected" : "not connected")
|
<< " connectStatus " << (connectStatus.isOK() ? "connected" : "not connected");
|
||||||
<< endl;
|
|
||||||
}
|
}
|
||||||
return monitorConnectStatus;
|
return connectStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
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 " << pvaClientChannel->getChannel()->getChannelName()
|
<< " channelName " << channelName
|
||||||
<< endl;
|
<< endl;
|
||||||
}
|
}
|
||||||
this->pvaClientMonitorRequester = pvaClientMonitorRequester;
|
this->pvaClientMonitorRequester = pvaClientMonitorRequester;
|
||||||
@@ -362,17 +305,30 @@ 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 " << pvaClientChannel->getChannel()->getChannelName()
|
<< " channelName " << channelName
|
||||||
<< " 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) {
|
||||||
string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName()
|
Channel::shared_pointer chan(channel.lock());
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
@@ -380,45 +336,15 @@ 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 " << pvaClientChannel->getChannel()->getChannelName()
|
<< " channelName " << channelName
|
||||||
<< endl;
|
<< endl;
|
||||||
}
|
}
|
||||||
if(!isStarted) return;
|
if(!isStarted) return;
|
||||||
@@ -429,11 +355,30 @@ 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 " << pvaClientChannel->getChannel()->getChannelName()
|
<< " channelName " << channelName
|
||||||
<< 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;
|
||||||
@@ -444,12 +389,18 @@ 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 " << pvaClientChannel->getChannel()->getChannelName()
|
<< " channelName " << channelName
|
||||||
<< endl;
|
<< endl;
|
||||||
}
|
}
|
||||||
if(!isStarted) {
|
if(!isStarted) {
|
||||||
string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName()
|
Channel::shared_pointer chan(channel.lock());
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
@@ -467,12 +418,26 @@ 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 " << pvaClientChannel->getChannel()->getChannelName()
|
<< " channelName " << channelName
|
||||||
<< 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) {
|
||||||
string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName()
|
Channel::shared_pointer chan(channel.lock());
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
@@ -480,16 +445,14 @@ 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 " << pvaClientChannel->getChannel()->getChannelName()
|
<< " channelName " << channelName
|
||||||
<< endl;
|
<< endl;
|
||||||
}
|
}
|
||||||
checkMonitorState();
|
checkMonitorState();
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
|
|
||||||
#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;
|
||||||
@@ -52,16 +53,43 @@ PvaClientMonitorDataPtr PvaClientMonitorData::create(StructureConstPtr const & s
|
|||||||
}
|
}
|
||||||
|
|
||||||
PvaClientMonitorData::PvaClientMonitorData(StructureConstPtr const & structure)
|
PvaClientMonitorData::PvaClientMonitorData(StructureConstPtr const & structure)
|
||||||
: PvaClientData(structure)
|
: structure(structure)
|
||||||
{
|
{
|
||||||
|
messagePrefix = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
void PvaClientMonitorData::setData(MonitorElementPtr const & monitorElement)
|
void PvaClientMonitorData::setData(MonitorElementPtr const & monitorElement)
|
||||||
{
|
{
|
||||||
PVStructurePtr pvStructure = monitorElement->pvStructurePtr;
|
pvStructure = monitorElement->pvStructurePtr;
|
||||||
BitSetPtr changedBitSet = monitorElement->changedBitSet;
|
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()
|
||||||
@@ -70,6 +98,24 @@ 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);
|
||||||
@@ -77,9 +123,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 = getPVStructure();
|
pvField = pvStructure;
|
||||||
} else {
|
} else {
|
||||||
pvField = getPVStructure()->getSubField(nextSet);
|
pvField = pvStructure->getSubField(nextSet);
|
||||||
}
|
}
|
||||||
string name = pvField->getFullName();
|
string name = pvField->getFullName();
|
||||||
out << name << " = " << pvField << endl;
|
out << name << " = " << pvField << endl;
|
||||||
@@ -88,4 +134,135 @@ 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,6 +17,9 @@
|
|||||||
|
|
||||||
#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;
|
||||||
@@ -80,7 +83,7 @@ Status PvaClientMultiChannel::connect(double timeout)
|
|||||||
Status status = Status::Ok;
|
Status status = Status::Ok;
|
||||||
size_t numBad = 0;
|
size_t numBad = 0;
|
||||||
for(size_t i=0; i< numChannel; ++i) {
|
for(size_t i=0; i< numChannel; ++i) {
|
||||||
if(numBad==0) {
|
if(numBad==0) {
|
||||||
status = pvaClientChannelArray[i]->waitConnect(timeout);
|
status = pvaClientChannelArray[i]->waitConnect(timeout);
|
||||||
} else {
|
} else {
|
||||||
status = pvaClientChannelArray[i]->waitConnect(.001);
|
status = pvaClientChannelArray[i]->waitConnect(.001);
|
||||||
@@ -140,7 +143,7 @@ PvaClientPtr PvaClientMultiChannel::getPvaClient()
|
|||||||
return pvaClient;
|
return pvaClient;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
PvaClientMultiGetDoublePtr PvaClientMultiChannel::createGet()
|
PvaClientMultiGetDoublePtr PvaClientMultiChannel::createGet()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -16,12 +16,13 @@
|
|||||||
|
|
||||||
#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;
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
namespace epics { namespace pvaClient {
|
namespace epics { namespace pvaClient {
|
||||||
|
|
||||||
|
|
||||||
PvaClientMultiGetDoublePtr PvaClientMultiGetDouble::create(
|
PvaClientMultiGetDoublePtr PvaClientMultiGetDouble::create(
|
||||||
@@ -79,7 +80,7 @@ epics::pvData::shared_vector<double> PvaClientMultiGetDouble::get()
|
|||||||
{
|
{
|
||||||
if(!isGetConnected) connect();
|
if(!isGetConnected) connect();
|
||||||
shared_vector<epics::pvData::boolean> isConnected = pvaClientMultiChannel->getIsConnected();
|
shared_vector<epics::pvData::boolean> isConnected = pvaClientMultiChannel->getIsConnected();
|
||||||
|
|
||||||
for(size_t i=0; i<nchannel; ++i)
|
for(size_t i=0; i<nchannel; ++i)
|
||||||
{
|
{
|
||||||
if(isConnected[i]) {
|
if(isConnected[i]) {
|
||||||
@@ -96,7 +97,7 @@ epics::pvData::shared_vector<double> PvaClientMultiGetDouble::get()
|
|||||||
throw std::runtime_error(message);
|
throw std::runtime_error(message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for(size_t i=0; i<nchannel; ++i)
|
for(size_t i=0; i<nchannel; ++i)
|
||||||
{
|
{
|
||||||
if(isConnected[i])
|
if(isConnected[i])
|
||||||
|
|||||||
@@ -16,12 +16,13 @@
|
|||||||
|
|
||||||
#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;
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
namespace epics { namespace pvaClient {
|
namespace epics { namespace pvaClient {
|
||||||
|
|
||||||
|
|
||||||
PvaClientMultiMonitorDoublePtr PvaClientMultiMonitorDouble::create(
|
PvaClientMultiMonitorDoublePtr PvaClientMultiMonitorDouble::create(
|
||||||
|
|||||||
@@ -16,12 +16,13 @@
|
|||||||
|
|
||||||
#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;
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
namespace epics { namespace pvaClient {
|
namespace epics { namespace pvaClient {
|
||||||
|
|
||||||
|
|
||||||
PvaClientMultiPutDoublePtr PvaClientMultiPutDouble::create(
|
PvaClientMultiPutDoublePtr PvaClientMultiPutDouble::create(
|
||||||
|
|||||||
@@ -15,12 +15,13 @@
|
|||||||
|
|
||||||
#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;
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
namespace epics { namespace pvaClient {
|
namespace epics { namespace pvaClient {
|
||||||
|
|
||||||
PvaClientNTMultiDataPtr PvaClientNTMultiData::create(
|
PvaClientNTMultiDataPtr PvaClientNTMultiData::create(
|
||||||
epics::pvData::UnionConstPtr const & u,
|
epics::pvData::UnionConstPtr const & u,
|
||||||
@@ -44,6 +45,10 @@ 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();
|
||||||
@@ -63,7 +68,7 @@ PvaClientNTMultiData::PvaClientNTMultiData(
|
|||||||
severity.resize(nchannel);
|
severity.resize(nchannel);
|
||||||
status.resize(nchannel);
|
status.resize(nchannel);
|
||||||
message.resize(nchannel);
|
message.resize(nchannel);
|
||||||
|
|
||||||
}
|
}
|
||||||
if(pvRequest->getSubField("field.timeStamp")) {
|
if(pvRequest->getSubField("field.timeStamp")) {
|
||||||
gotTimeStamp = true;
|
gotTimeStamp = true;
|
||||||
@@ -84,6 +89,18 @@ 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)
|
||||||
{
|
{
|
||||||
@@ -121,51 +138,28 @@ void PvaClientNTMultiData::startDeltaTime()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void PvaClientNTMultiData::endDeltaTime(bool valueOnly)
|
void PvaClientNTMultiData::endDeltaTime()
|
||||||
{
|
{
|
||||||
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 if(unionValue[i]) {
|
} else {
|
||||||
if(valueOnly) {
|
unionValue[i]->set(pvst->getSubField("value"));
|
||||||
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)
|
||||||
{
|
{
|
||||||
PVIntPtr pvSeverity = pvst->getSubField<PVInt>("alarm.severity");
|
severity[i] = pvst->getSubField<PVInt>("alarm.severity")->get();
|
||||||
PVIntPtr pvStatus = pvst->getSubField<PVInt>("alarm.status");
|
status[i] = pvst->getSubField<PVInt>("alarm.status")->get();
|
||||||
PVStringPtr pvMessage = pvst->getSubField<PVString>("alarm.message");
|
message[i] = pvst->getSubField<PVString>("alarm.message")->get();
|
||||||
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)
|
||||||
{
|
{
|
||||||
PVLongPtr pvEpoch = pvst->getSubField<PVLong>("timeStamp.secondsPastEpoch");
|
secondsPastEpoch[i] = pvst->getSubField<PVLong>("timeStamp.secondsPastEpoch")->get();
|
||||||
PVIntPtr pvNano = pvst->getSubField<PVInt>("timeStamp.nanoseconds");
|
nanoseconds[i] = pvst->getSubField<PVInt>("timeStamp.nanoseconds")->get();
|
||||||
PVIntPtr pvTag = pvst->getSubField<PVInt>("timeStamp.userTag");
|
userTag[i] = pvst->getSubField<PVInt>("timeStamp.userTag")->get();
|
||||||
if(pvEpoch&&pvNano&&pvTag) {
|
|
||||||
secondsPastEpoch[i] = pvEpoch->get();
|
|
||||||
nanoseconds[i] = pvNano->get();
|
|
||||||
userTag[i] = pvTag->get();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -15,12 +15,13 @@
|
|||||||
|
|
||||||
#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;
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
namespace epics { namespace pvaClient {
|
namespace epics { namespace pvaClient {
|
||||||
|
|
||||||
|
|
||||||
PvaClientNTMultiGetPtr PvaClientNTMultiGet::create(
|
PvaClientNTMultiGetPtr PvaClientNTMultiGet::create(
|
||||||
@@ -63,10 +64,13 @@ 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(pvRequest);
|
pvaClientGet[i] = pvaClientChannelArray[i]->createGet(request);
|
||||||
pvaClientGet[i]->issueConnect();
|
pvaClientGet[i]->issueConnect();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -75,7 +79,7 @@ void PvaClientNTMultiGet::connect()
|
|||||||
if(isConnected[i]) {
|
if(isConnected[i]) {
|
||||||
Status status = pvaClientGet[i]->waitConnect();
|
Status status = pvaClientGet[i]->waitConnect();
|
||||||
if(status.isOK()) continue;
|
if(status.isOK()) continue;
|
||||||
string message = string("channel ") +pvaClientChannelArray[i]->getChannelName()
|
string message = string("channel ") +pvaClientChannelArray[i]->getChannelName()
|
||||||
+ " PvaChannelGet::waitConnect " + status.getMessage();
|
+ " PvaChannelGet::waitConnect " + status.getMessage();
|
||||||
throw std::runtime_error(message);
|
throw std::runtime_error(message);
|
||||||
}
|
}
|
||||||
@@ -83,11 +87,11 @@ void PvaClientNTMultiGet::connect()
|
|||||||
this->isConnected = true;
|
this->isConnected = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PvaClientNTMultiGet::get(bool valueOnly)
|
void PvaClientNTMultiGet::get()
|
||||||
{
|
{
|
||||||
if(!isConnected) connect();
|
if(!isConnected) connect();
|
||||||
shared_vector<epics::pvData::boolean> isConnected = pvaClientMultiChannel->getIsConnected();
|
shared_vector<epics::pvData::boolean> isConnected = pvaClientMultiChannel->getIsConnected();
|
||||||
|
|
||||||
for(size_t i=0; i<nchannel; ++i)
|
for(size_t i=0; i<nchannel; ++i)
|
||||||
{
|
{
|
||||||
if(isConnected[i]) {
|
if(isConnected[i]) {
|
||||||
@@ -99,7 +103,7 @@ void PvaClientNTMultiGet::get(bool valueOnly)
|
|||||||
if(isConnected[i]) {
|
if(isConnected[i]) {
|
||||||
Status status = pvaClientGet[i]->waitGet();
|
Status status = pvaClientGet[i]->waitGet();
|
||||||
if(status.isOK()) continue;
|
if(status.isOK()) continue;
|
||||||
string message = string("channel ") +pvaClientChannelArray[i]->getChannelName()
|
string message = string("channel ") +pvaClientChannelArray[i]->getChannelName()
|
||||||
+ " PvaChannelGet::waitGet " + status.getMessage();
|
+ " PvaChannelGet::waitGet " + status.getMessage();
|
||||||
throw std::runtime_error(message);
|
throw std::runtime_error(message);
|
||||||
}
|
}
|
||||||
@@ -111,7 +115,7 @@ void PvaClientNTMultiGet::get(bool valueOnly)
|
|||||||
pvaClientNTMultiData->setPVStructure(pvaClientGet[i]->getData()->getPVStructure(),i);
|
pvaClientNTMultiData->setPVStructure(pvaClientGet[i]->getData()->getPVStructure(),i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pvaClientNTMultiData->endDeltaTime(valueOnly);
|
pvaClientNTMultiData->endDeltaTime();
|
||||||
}
|
}
|
||||||
|
|
||||||
PvaClientNTMultiDataPtr PvaClientNTMultiGet::getData()
|
PvaClientNTMultiDataPtr PvaClientNTMultiGet::getData()
|
||||||
|
|||||||
@@ -18,12 +18,13 @@
|
|||||||
|
|
||||||
#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;
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
namespace epics { namespace pvaClient {
|
namespace epics { namespace pvaClient {
|
||||||
|
|
||||||
PvaClientNTMultiMonitorPtr PvaClientNTMultiMonitor::create(
|
PvaClientNTMultiMonitorPtr PvaClientNTMultiMonitor::create(
|
||||||
PvaClientMultiChannelPtr const &pvaMultiChannel,
|
PvaClientMultiChannelPtr const &pvaMultiChannel,
|
||||||
@@ -67,10 +68,13 @@ 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(pvRequest);
|
pvaClientMonitor[i] = pvaClientChannelArray[i]->createMonitor(request);
|
||||||
pvaClientMonitor[i]->issueConnect();
|
pvaClientMonitor[i]->issueConnect();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -79,7 +83,7 @@ void PvaClientNTMultiMonitor::connect()
|
|||||||
if(isConnected[i]) {
|
if(isConnected[i]) {
|
||||||
Status status = pvaClientMonitor[i]->waitConnect();
|
Status status = pvaClientMonitor[i]->waitConnect();
|
||||||
if(status.isOK()) continue;
|
if(status.isOK()) continue;
|
||||||
string message = string("channel ") +pvaClientChannelArray[i]->getChannelName()
|
string message = string("channel ") +pvaClientChannelArray[i]->getChannelName()
|
||||||
+ " PvaChannelMonitor::waitConnect " + status.getMessage();
|
+ " PvaChannelMonitor::waitConnect " + status.getMessage();
|
||||||
throw std::runtime_error(message);
|
throw std::runtime_error(message);
|
||||||
}
|
}
|
||||||
@@ -91,7 +95,7 @@ void PvaClientNTMultiMonitor::connect()
|
|||||||
this->isConnected = true;
|
this->isConnected = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PvaClientNTMultiMonitor::poll(bool valueOnly)
|
bool PvaClientNTMultiMonitor::poll()
|
||||||
{
|
{
|
||||||
if(!isConnected) connect();
|
if(!isConnected) connect();
|
||||||
bool result = false;
|
bool result = false;
|
||||||
@@ -108,7 +112,7 @@ bool PvaClientNTMultiMonitor::poll(bool valueOnly)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(result) pvaClientNTMultiData->endDeltaTime(valueOnly);
|
if(result) pvaClientNTMultiData->endDeltaTime();
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -17,12 +17,13 @@
|
|||||||
|
|
||||||
#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;
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
namespace epics { namespace pvaClient {
|
namespace epics { namespace pvaClient {
|
||||||
|
|
||||||
PvaClientNTMultiPutPtr PvaClientNTMultiPut::create(
|
PvaClientNTMultiPutPtr PvaClientNTMultiPut::create(
|
||||||
PvaClientMultiChannelPtr const &pvaMultiChannel,
|
PvaClientMultiChannelPtr const &pvaMultiChannel,
|
||||||
@@ -67,7 +68,7 @@ void PvaClientNTMultiPut::connect()
|
|||||||
if(isConnected[i]) {
|
if(isConnected[i]) {
|
||||||
Status status = pvaClientPut[i]->waitConnect();
|
Status status = pvaClientPut[i]->waitConnect();
|
||||||
if(status.isOK()) continue;
|
if(status.isOK()) continue;
|
||||||
string message = string("channel ") +pvaClientChannelArray[i]->getChannelName()
|
string message = string("channel ") +pvaClientChannelArray[i]->getChannelName()
|
||||||
+ " PvaChannelPut::waitConnect " + status.getMessage();
|
+ " PvaChannelPut::waitConnect " + status.getMessage();
|
||||||
throw std::runtime_error(message);
|
throw std::runtime_error(message);
|
||||||
}
|
}
|
||||||
@@ -83,7 +84,7 @@ void PvaClientNTMultiPut::connect()
|
|||||||
if(isConnected[i]) {
|
if(isConnected[i]) {
|
||||||
Status status = pvaClientPut[i]->waitGet();
|
Status status = pvaClientPut[i]->waitGet();
|
||||||
if(status.isOK()) continue;
|
if(status.isOK()) continue;
|
||||||
string message = string("channel ") +pvaClientChannelArray[i]->getChannelName()
|
string message = string("channel ") +pvaClientChannelArray[i]->getChannelName()
|
||||||
+ " PvaChannelPut::waitGet " + status.getMessage();
|
+ " PvaChannelPut::waitGet " + status.getMessage();
|
||||||
throw std::runtime_error(message);
|
throw std::runtime_error(message);
|
||||||
}
|
}
|
||||||
@@ -121,9 +122,9 @@ void PvaClientNTMultiPut::put()
|
|||||||
if(isConnected[i]) {
|
if(isConnected[i]) {
|
||||||
Status status = pvaClientPut[i]->waitPut();
|
Status status = pvaClientPut[i]->waitPut();
|
||||||
if(status.isOK()) continue;
|
if(status.isOK()) continue;
|
||||||
string message = string("channel ") +pvaClientChannelArray[i]->getChannelName()
|
string message = string("channel ") +pvaClientChannelArray[i]->getChannelName()
|
||||||
+ " PvaChannelPut::waitPut " + status.getMessage();
|
+ " PvaChannelPut::waitPut " + status.getMessage();
|
||||||
throw std::runtime_error(message);
|
throw std::runtime_error(message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+33
-131
@@ -15,6 +15,7 @@
|
|||||||
|
|
||||||
#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;
|
||||||
@@ -54,7 +55,7 @@ public:
|
|||||||
{
|
{
|
||||||
PvaClientProcessPtr clientProcess(pvaClientProcess.lock());
|
PvaClientProcessPtr clientProcess(pvaClientProcess.lock());
|
||||||
if(!clientProcess) return;
|
if(!clientProcess) return;
|
||||||
clientProcess->channelProcessConnect(status,channelProcess);
|
clientProcess->channelProcessConnect(status,channelProcess);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void processDone(
|
virtual void processDone(
|
||||||
@@ -69,46 +70,33 @@ public:
|
|||||||
|
|
||||||
PvaClientProcessPtr PvaClientProcess::create(
|
PvaClientProcessPtr PvaClientProcess::create(
|
||||||
PvaClientPtr const &pvaClient,
|
PvaClientPtr const &pvaClient,
|
||||||
PvaClientChannelPtr const & pvaClientChannel,
|
Channel::shared_pointer const & channel,
|
||||||
PVStructurePtr const &pvRequest)
|
PVStructurePtr const &pvRequest)
|
||||||
{
|
{
|
||||||
if(PvaClient::getDebug()) {
|
PvaClientProcessPtr epv(new PvaClientProcess(pvaClient,channel,pvRequest));
|
||||||
cout<< "PvaClientProcess::create(pvaClient,channelName,pvRequest)\n"
|
epv->channelProcessRequester = ChannelProcessRequesterImplPtr(
|
||||||
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
|
new ChannelProcessRequesterImpl(epv,pvaClient));
|
||||||
<< " pvRequest " << pvRequest
|
return epv;
|
||||||
<< 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,
|
||||||
PvaClientChannelPtr const & pvaClientChannel,
|
Channel::shared_pointer const & channel,
|
||||||
PVStructurePtr const &pvRequest)
|
PVStructurePtr const &pvRequest)
|
||||||
: pvaClient(pvaClient),
|
: pvaClient(pvaClient),
|
||||||
pvaClientChannel(pvaClientChannel),
|
channel(channel),
|
||||||
pvRequest(pvRequest),
|
pvRequest(pvRequest),
|
||||||
connectState(connectIdle),
|
connectState(connectIdle),
|
||||||
processState(processIdle)
|
processState(processIdle)
|
||||||
{
|
{
|
||||||
if(PvaClient::getDebug()) {
|
if(PvaClient::getDebug()) cout<< "PvaClientProcess::PvaClientProcess()\n";
|
||||||
cout<< "PvaClientProcess::PvaClientProcess()"
|
|
||||||
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
|
|
||||||
<< endl;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PvaClientProcess::~PvaClientProcess()
|
PvaClientProcess::~PvaClientProcess()
|
||||||
{
|
{
|
||||||
if(PvaClient::getDebug()) {
|
if(PvaClient::getDebug()) cout<< "PvaClientProcess::~PvaClientProcess()\n";
|
||||||
cout<< "PvaClientProcess::~PvaClientProcess()"
|
channelProcess->destroy();
|
||||||
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
|
|
||||||
<< endl;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// from ChannelProcessRequester
|
// from ChannelProcessRequester
|
||||||
@@ -130,103 +118,51 @@ void PvaClientProcess::channelProcessConnect(
|
|||||||
const Status& status,
|
const Status& status,
|
||||||
ChannelProcess::shared_pointer const & channelProcess)
|
ChannelProcess::shared_pointer const & channelProcess)
|
||||||
{
|
{
|
||||||
if(PvaClient::getDebug()) {
|
channelProcessConnectStatus = status;
|
||||||
cout << "PvaClientProcess::channelProcessConnect"
|
connectState = connected;
|
||||||
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
|
this->channelProcess = channelProcess;
|
||||||
<< " 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();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PvaClientProcess::processDone(
|
void PvaClientProcess::processDone(
|
||||||
const Status& status,
|
const Status& status,
|
||||||
ChannelProcess::shared_pointer const & channelProcess)
|
ChannelProcess::shared_pointer const & channelProcess)
|
||||||
{
|
{
|
||||||
if(PvaClient::getDebug()) {
|
channelProcessStatus = status;
|
||||||
cout << "PvaClientProcess::processDone"
|
processState = processComplete;
|
||||||
<< " 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 ") + pvaClientChannel->getChannel()->getChannelName()
|
string message = string("channel ") + channel->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 ") + pvaClientChannel->getChannel()->getChannelName()
|
string message = string("channel ") + channel->getChannelName()
|
||||||
+ " pvaClientProcess already connected ";
|
+ " pvaClientProcess already connected ";
|
||||||
throw std::runtime_error(message);
|
throw std::runtime_error(message);
|
||||||
}
|
}
|
||||||
connectState = connectActive;
|
connectState = connectActive;
|
||||||
channelProcessConnectStatus = Status(Status::STATUSTYPE_ERROR, "connect active");
|
channelProcess = channel->createChannelProcess(channelProcessRequester,pvRequest);
|
||||||
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 ") + pvaClientChannel->getChannel()->getChannelName()
|
string message = string("channel ") + channel->getChannelName()
|
||||||
+ " pvaClientProcess illegal connect state ";
|
+ " pvaClientProcess illegal connect state ";
|
||||||
throw std::runtime_error(message);
|
throw std::runtime_error(message);
|
||||||
}
|
}
|
||||||
@@ -237,29 +173,19 @@ 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 ") + pvaClientChannel->getChannel()->getChannelName()
|
string message = string("channel ") + channel->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==processActive) {
|
if(processState!=processIdle) {
|
||||||
string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName()
|
string message = string("channel ") + channel->getChannelName()
|
||||||
+ " PvaClientProcess::issueProcess process aleady active ";
|
+ " PvaClientProcess::issueProcess process aleady active ";
|
||||||
throw std::runtime_error(message);
|
throw std::runtime_error(message);
|
||||||
}
|
}
|
||||||
@@ -269,42 +195,18 @@ void PvaClientProcess::issueProcess()
|
|||||||
|
|
||||||
Status PvaClientProcess::waitProcess()
|
Status PvaClientProcess::waitProcess()
|
||||||
{
|
{
|
||||||
if(PvaClient::getDebug()) {
|
if(processState==processComplete) {
|
||||||
cout << "PvaClientProcess::waitProcess"
|
processState = processIdle;
|
||||||
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
|
return channelProcessStatus;
|
||||||
<< endl;
|
|
||||||
}
|
}
|
||||||
{
|
if(processState!=processActive){
|
||||||
Lock xx(mutex);
|
string message = string("channel ") + channel->getChannelName()
|
||||||
if(processState==processComplete) {
|
+ " PvaClientProcess::waitProcess llegal process state";
|
||||||
processState = processIdle;
|
throw std::runtime_error(message);
|
||||||
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 = processComplete;
|
processState = processIdle;
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}}
|
}}
|
||||||
|
|||||||
+99
-167
@@ -15,6 +15,7 @@
|
|||||||
|
|
||||||
#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;
|
||||||
@@ -55,7 +56,7 @@ public:
|
|||||||
{
|
{
|
||||||
PvaClientPutPtr clientPut(pvaClientPut.lock());
|
PvaClientPutPtr clientPut(pvaClientPut.lock());
|
||||||
if(!clientPut) return;
|
if(!clientPut) return;
|
||||||
clientPut->channelPutConnect(status,channelPut,structure);
|
clientPut->channelPutConnect(status,channelPut,structure);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void getDone(
|
virtual void getDone(
|
||||||
@@ -69,7 +70,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)
|
||||||
{
|
{
|
||||||
@@ -81,29 +82,30 @@ public:
|
|||||||
|
|
||||||
PvaClientPutPtr PvaClientPut::create(
|
PvaClientPutPtr PvaClientPut::create(
|
||||||
PvaClientPtr const &pvaClient,
|
PvaClientPtr const &pvaClient,
|
||||||
PvaClientChannelPtr const & pvaClientChannel,
|
Channel::shared_pointer const & channel,
|
||||||
PVStructurePtr const &pvRequest)
|
PVStructurePtr const &pvRequest)
|
||||||
{
|
{
|
||||||
PvaClientPutPtr clientPut(new PvaClientPut(pvaClient,pvaClientChannel,pvRequest));
|
PvaClientPutPtr epv(new PvaClientPut(pvaClient,channel,pvRequest));
|
||||||
clientPut->channelPutRequester = ChannelPutRequesterImplPtr(
|
epv->channelPutRequester = ChannelPutRequesterImplPtr(
|
||||||
new ChannelPutRequesterImpl(clientPut,pvaClient));
|
new ChannelPutRequesterImpl(epv,pvaClient));
|
||||||
return clientPut;
|
return epv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
PvaClientPut::PvaClientPut(
|
PvaClientPut::PvaClientPut(
|
||||||
PvaClientPtr const &pvaClient,
|
PvaClientPtr const &pvaClient,
|
||||||
PvaClientChannelPtr const & pvaClientChannel,
|
Channel::shared_pointer const & channel,
|
||||||
PVStructurePtr const &pvRequest)
|
PVStructurePtr const &pvRequest)
|
||||||
: pvaClient(pvaClient),
|
: pvaClient(pvaClient),
|
||||||
pvaClientChannel(pvaClientChannel),
|
channel(channel),
|
||||||
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 " << pvaClientChannel->getChannel()->getChannelName()
|
<< " channelName " << channel->getChannelName()
|
||||||
<< endl;
|
<< endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -111,28 +113,21 @@ 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 " << pvaClientChannel->getChannel()->getChannelName()
|
<< " channelName " << channelName
|
||||||
<< 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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -156,34 +151,25 @@ 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 " << pvaClientChannel->getChannel()->getChannelName()
|
<< " channelName " << channelName
|
||||||
<< " 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();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PvaClientPut::getDone(
|
void PvaClientPut::getDone(
|
||||||
@@ -193,26 +179,21 @@ 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 " << pvaClientChannel->getChannel()->getChannelName()
|
<< " channelName " << channelName
|
||||||
<< " status.isOK " << (status.isOK() ? "true" : "false")
|
<< " status.isOK " << (status.isOK() ? "true" : "false")
|
||||||
<< endl;
|
<< endl;
|
||||||
}
|
}
|
||||||
{
|
channelGetPutStatus = status;
|
||||||
Lock xx(mutex);
|
if(status.isOK()) {
|
||||||
channelGetPutStatus = status;
|
PVStructurePtr pvs = pvaClientData->getPVStructure();
|
||||||
if(status.isOK()) {
|
pvs->copyUnchecked(*pvStructure,*bitSet);
|
||||||
PVStructurePtr pvs = pvaClientData->getPVStructure();
|
BitSetPtr bs = pvaClientData->getChangedBitSet();
|
||||||
pvs->copyUnchecked(*pvStructure,*bitSet);
|
bs->clear();
|
||||||
BitSetPtr bs = pvaClientData->getChangedBitSet();
|
*bs |= *bitSet;
|
||||||
bs->clear();
|
|
||||||
*bs |= *bitSet;
|
|
||||||
putState = putComplete;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
PvaClientPutRequesterPtr req(pvaClientPutRequester.lock());
|
|
||||||
if(req) {
|
|
||||||
req->getDone(status,shared_from_this());
|
|
||||||
}
|
}
|
||||||
waitForGetPut.signal();
|
waitForGetPut.signal();
|
||||||
}
|
}
|
||||||
@@ -222,35 +203,28 @@ 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 " << pvaClientChannel->getChannel()->getChannelName()
|
<< " channelName " << channelName
|
||||||
<< " 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;
|
||||||
string message = string("channel ")
|
Channel::shared_pointer chan(channel.lock());
|
||||||
+ pvaClientChannel->getChannel()->getChannelName()
|
string channelName("disconnected");
|
||||||
|
if(chan) channelName = chan->getChannelName();
|
||||||
|
string message = string("channel ")
|
||||||
|
+ channelName
|
||||||
+ " PvaClientPut::connect "
|
+ " PvaClientPut::connect "
|
||||||
+ status.getMessage();
|
+ status.getMessage();
|
||||||
throw std::runtime_error(message);
|
throw std::runtime_error(message);
|
||||||
@@ -258,29 +232,24 @@ void PvaClientPut::connect()
|
|||||||
|
|
||||||
void PvaClientPut::issueConnect()
|
void PvaClientPut::issueConnect()
|
||||||
{
|
{
|
||||||
if(PvaClient::getDebug()) {
|
Channel::shared_pointer chan(channel.lock());
|
||||||
cout << "PvaClientPut::issueConnect"
|
|
||||||
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
|
|
||||||
<< endl;
|
|
||||||
}
|
|
||||||
if(connectState!=connectIdle) {
|
if(connectState!=connectIdle) {
|
||||||
string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName()
|
string channelName("disconnected");
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
connectState = connectActive;
|
if(chan) {
|
||||||
channelPutConnectStatus = Status(Status::STATUSTYPE_ERROR, "connect active");
|
connectState = connectActive;
|
||||||
channelPut = pvaClientChannel->getChannel()->createChannelPut(channelPutRequester,pvRequest);
|
channelPut = chan->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) {
|
||||||
@@ -288,7 +257,10 @@ Status PvaClientPut::waitConnect()
|
|||||||
return channelPutConnectStatus;
|
return channelPutConnectStatus;
|
||||||
}
|
}
|
||||||
if(connectState!=connectActive) {
|
if(connectState!=connectActive) {
|
||||||
string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName()
|
Channel::shared_pointer chan(channel.lock());
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
@@ -300,16 +272,14 @@ 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;
|
||||||
string message = string("channel ")
|
Channel::shared_pointer chan(channel.lock());
|
||||||
+ pvaClientChannel->getChannel()->getChannelName()
|
string channelName("disconnected");
|
||||||
|
if(chan) channelName = chan->getChannelName();
|
||||||
|
string message = string("channel ")
|
||||||
|
+ channelName
|
||||||
+ " PvaClientPut::get "
|
+ " PvaClientPut::get "
|
||||||
+ status.getMessage();
|
+ status.getMessage();
|
||||||
throw std::runtime_error(message);
|
throw std::runtime_error(message);
|
||||||
@@ -317,15 +287,13 @@ 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==getActive || putState==putActive) {
|
if(putState!=putIdle) {
|
||||||
|
Channel::shared_pointer chan(channel.lock());
|
||||||
|
string channelName("disconnected");
|
||||||
|
if(chan) channelName = chan->getChannelName();
|
||||||
string message = string("channel ")
|
string message = string("channel ")
|
||||||
+ pvaClientChannel->getChannel()->getChannelName()
|
+ channelName
|
||||||
+ "PvaClientPut::issueGet get or put aleady active ";
|
+ "PvaClientPut::issueGet get or put aleady active ";
|
||||||
throw std::runtime_error(message);
|
throw std::runtime_error(message);
|
||||||
}
|
}
|
||||||
@@ -335,37 +303,30 @@ void PvaClientPut::issueGet()
|
|||||||
|
|
||||||
Status PvaClientPut::waitGet()
|
Status PvaClientPut::waitGet()
|
||||||
{
|
{
|
||||||
if(PvaClient::getDebug()) {
|
if(putState!=getActive){
|
||||||
cout << "PvaClientPut::waitGet"
|
Channel::shared_pointer chan(channel.lock());
|
||||||
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
|
string channelName("disconnected");
|
||||||
<< endl;
|
if(chan) channelName = chan->getChannelName();
|
||||||
}
|
string message = string("channel ")
|
||||||
{
|
+ channelName
|
||||||
Lock xx(mutex);
|
+ " PvaClientPut::waitGet illegal put state";
|
||||||
if(putState==putComplete) return channelGetPutStatus;
|
throw std::runtime_error(message);
|
||||||
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 ")
|
||||||
+ pvaClientChannel->getChannel()->getChannelName()
|
+ channelName
|
||||||
+ " PvaClientPut::put "
|
+ " PvaClientPut::put "
|
||||||
+ status.getMessage();
|
+ status.getMessage();
|
||||||
throw std::runtime_error(message);
|
throw std::runtime_error(message);
|
||||||
@@ -373,18 +334,14 @@ 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==getActive || putState==putActive) {
|
if(putState!=putIdle) {
|
||||||
|
Channel::shared_pointer chan(channel.lock());
|
||||||
|
string channelName("disconnected");
|
||||||
|
if(chan) channelName = chan->getChannelName();
|
||||||
string message = string("channel ")
|
string message = string("channel ")
|
||||||
+ pvaClientChannel->getChannel()->getChannelName()
|
+ channelName
|
||||||
+ "PvaClientPut::issuePut get or put aleady active ";
|
+ "PvaClientPut::issueGet get or put aleady active ";
|
||||||
throw std::runtime_error(message);
|
throw std::runtime_error(message);
|
||||||
}
|
}
|
||||||
putState = putActive;
|
putState = putActive;
|
||||||
@@ -393,51 +350,26 @@ void PvaClientPut::issuePut()
|
|||||||
|
|
||||||
Status PvaClientPut::waitPut()
|
Status PvaClientPut::waitPut()
|
||||||
{
|
{
|
||||||
if(PvaClient::getDebug()) {
|
if(putState!=putActive){
|
||||||
cout << "PvaClientPut::waitPut"
|
Channel::shared_pointer chan(channel.lock());
|
||||||
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
|
string channelName("disconnected");
|
||||||
<< endl;
|
if(chan) channelName = chan->getChannelName();
|
||||||
}
|
string message = string("channel ")
|
||||||
{
|
+ channelName
|
||||||
Lock xx(mutex);
|
+ " PvaClientPut::waitPut illegal put state";
|
||||||
if(putState==putComplete) return channelGetPutStatus;
|
throw std::runtime_error(message);
|
||||||
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()
|
||||||
{
|
{
|
||||||
if(PvaClient::getDebug()) {
|
checkPutState();
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
}}
|
}}
|
||||||
|
|||||||
+168
-59
@@ -25,10 +25,6 @@ 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
|
||||||
{
|
{
|
||||||
@@ -40,21 +36,28 @@ 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)
|
||||||
: PvaClientData(structure)
|
: structure(structure),
|
||||||
|
pvStructure(getPVDataCreate()->createPVStructure(structure)),
|
||||||
|
bitSet(BitSetPtr(new BitSet(pvStructure->getNumberFields())))
|
||||||
{
|
{
|
||||||
if(PvaClient::getDebug()) cout << "PvaClientPutData::PvaClientPutData\n";
|
messagePrefix = "";
|
||||||
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;
|
||||||
@@ -68,18 +71,145 @@ 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)
|
||||||
{
|
{
|
||||||
if(PvaClient::getDebug()) cout << "PvaClientPutData::putDouble\n";
|
PVScalarPtr pvScalar = getScalarValue();
|
||||||
PVFieldPtr pvField = getSinglePVField();
|
|
||||||
Type type = pvField->getField()->getType();
|
|
||||||
if(type!=scalar) {
|
|
||||||
throw std::logic_error("PvaClientData::putDouble() did not find a scalar field");
|
|
||||||
}
|
|
||||||
PVScalarPtr pvScalar = static_pointer_cast<PVScalar>(pvField);
|
|
||||||
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);
|
||||||
@@ -87,68 +217,47 @@ void PvaClientPutData::putDouble(double value)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(!ScalarTypeFunc::isNumeric(scalarType)) {
|
if(!ScalarTypeFunc::isNumeric(scalarType)) {
|
||||||
throw std::logic_error(
|
throw std::runtime_error(messagePrefix + notCompatibleScalar);
|
||||||
"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)
|
||||||
{
|
{
|
||||||
if(PvaClient::getDebug()) cout << "PvaClientPutData::putString\n";
|
PVScalarPtr pvScalar = getScalarValue();
|
||||||
PVFieldPtr pvField = getSinglePVField();
|
|
||||||
Type type = pvField->getField()->getType();
|
|
||||||
if(type!=scalar) {
|
|
||||||
throw std::logic_error("PvaClientData::putString() did not find a scalar field");
|
|
||||||
}
|
|
||||||
PVScalarPtr pvScalar = static_pointer_cast<PVScalar>(pvField);
|
|
||||||
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)
|
||||||
{
|
{
|
||||||
if(PvaClient::getDebug()) cout << "PvaClientPutData::putDoubleArray\n";
|
checkValue();
|
||||||
PVFieldPtr pvField = getSinglePVField();
|
PVDoubleArrayPtr pv = pvStructure->getSubField<PVDoubleArray>("value");
|
||||||
Type type = pvField->getField()->getType();
|
if(!pv) {
|
||||||
if(type!=scalarArray) {
|
throw std::runtime_error(messagePrefix + notDoubleArray);
|
||||||
throw std::logic_error("PvaClientData::putDoubleArray() did not find a scalarArray field");
|
|
||||||
}
|
}
|
||||||
PVScalarArrayPtr pvScalarArray = static_pointer_cast<PVScalarArray>(pvField);
|
pv->replace(value);
|
||||||
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)
|
||||||
{
|
{
|
||||||
if(PvaClient::getDebug()) cout << "PvaClientPutData::putStringArray\n";
|
checkValue();
|
||||||
PVFieldPtr pvField = getSinglePVField();
|
PVStringArrayPtr pv = pvStructure->getSubField<PVStringArray>("value");
|
||||||
Type type = pvField->getField()->getType();
|
if(!pv) {
|
||||||
if(type!=scalarArray) {
|
throw std::runtime_error(messagePrefix + notStringArray);
|
||||||
throw std::logic_error("PvaClientData::putStringArray() did not find a scalarArray field");
|
|
||||||
}
|
}
|
||||||
PVScalarArrayPtr pvScalarArray = static_pointer_cast<PVScalarArray>(pvField);
|
pv->replace(value);
|
||||||
pvScalarArray->putFrom<const string>(value);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PvaClientPutData::putStringArray(std::vector<string> const & value)
|
void PvaClientPutData::putStringArray(std::vector<std::string> const & value)
|
||||||
{
|
{
|
||||||
size_t length = value.size();
|
checkValue();
|
||||||
shared_vector<string> val(length);
|
PVScalarArrayPtr pv = pvStructure->getSubField<PVScalarArray>("value");
|
||||||
for(size_t i=0; i < length; ++i) val[i] = value[i];
|
if(!pv) {
|
||||||
putStringArray(freeze(val));
|
throw std::runtime_error(messagePrefix + notScalarArray);
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}}
|
}}
|
||||||
|
|||||||
+116
-216
@@ -14,6 +14,7 @@
|
|||||||
|
|
||||||
#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;
|
||||||
@@ -55,7 +56,7 @@ public:
|
|||||||
{
|
{
|
||||||
PvaClientPutGetPtr clientPutGet(pvaClientPutGet.lock());
|
PvaClientPutGetPtr clientPutGet(pvaClientPutGet.lock());
|
||||||
if(!clientPutGet) return;
|
if(!clientPutGet) return;
|
||||||
clientPutGet->channelPutGetConnect(status,channelPutGet,putStructure,getStructure);
|
clientPutGet->channelPutGetConnect(status,channelPutGet,putStructure,getStructure);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void putGetDone(
|
virtual void putGetDone(
|
||||||
@@ -95,28 +96,28 @@ public:
|
|||||||
|
|
||||||
PvaClientPutGetPtr PvaClientPutGet::create(
|
PvaClientPutGetPtr PvaClientPutGet::create(
|
||||||
PvaClientPtr const &pvaClient,
|
PvaClientPtr const &pvaClient,
|
||||||
PvaClientChannelPtr const & pvaClientChannel,
|
Channel::shared_pointer const & channel,
|
||||||
PVStructurePtr const &pvRequest)
|
PVStructurePtr const &pvRequest)
|
||||||
{
|
{
|
||||||
PvaClientPutGetPtr clientPutGet(new PvaClientPutGet(pvaClient,pvaClientChannel,pvRequest));
|
PvaClientPutGetPtr epv(new PvaClientPutGet(pvaClient,channel,pvRequest));
|
||||||
clientPutGet->channelPutGetRequester = ChannelPutGetRequesterImplPtr(
|
epv->channelPutGetRequester = ChannelPutGetRequesterImplPtr(
|
||||||
new ChannelPutGetRequesterImpl(clientPutGet,pvaClient));
|
new ChannelPutGetRequesterImpl(epv,pvaClient));
|
||||||
return clientPutGet;
|
return epv;
|
||||||
}
|
}
|
||||||
|
|
||||||
PvaClientPutGet::PvaClientPutGet(
|
PvaClientPutGet::PvaClientPutGet(
|
||||||
PvaClientPtr const &pvaClient,
|
PvaClientPtr const &pvaClient,
|
||||||
PvaClientChannelPtr const & pvaClientChannel,
|
Channel::shared_pointer const & channel,
|
||||||
PVStructurePtr const &pvRequest)
|
PVStructurePtr const &pvRequest)
|
||||||
: pvaClient(pvaClient),
|
: pvaClient(pvaClient),
|
||||||
pvaClientChannel(pvaClientChannel),
|
channel(channel),
|
||||||
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 " << pvaClientChannel->getChannel()->getChannelName()
|
<< " channelName " << channel->getChannelName()
|
||||||
<< endl;
|
<< endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -124,27 +125,21 @@ 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 " << pvaClientChannel->getChannel()->getChannelName()
|
<< " channelName " << channelName
|
||||||
<< 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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -170,36 +165,20 @@ void PvaClientPutGet::channelPutGetConnect(
|
|||||||
{
|
{
|
||||||
if(PvaClient::getDebug()) {
|
if(PvaClient::getDebug()) {
|
||||||
cout << "PvaClientPutGet::channelPutGetConnect"
|
cout << "PvaClientPutGet::channelPutGetConnect"
|
||||||
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
|
<< " channelName " << channelPutGet->getChannel()->getChannelName()
|
||||||
<< " status.isOK " << (status.isOK() ? "true" : "false")
|
<< " status.isOK " << (status.isOK() ? "true" : "false")
|
||||||
<< endl;
|
<< endl;
|
||||||
}
|
}
|
||||||
{
|
channelPutGetConnectStatus = status;
|
||||||
Lock xx(mutex);
|
this->channelPutGet = channelPutGet;
|
||||||
this->channelPutGet = channelPutGet;
|
if(status.isOK()) {
|
||||||
if(status.isOK()) {
|
pvaClientPutData = PvaClientPutData::create(putStructure);
|
||||||
channelPutGetConnectStatus = status;
|
pvaClientPutData->setMessagePrefix(channelPutGet->getChannel()->getChannelName());
|
||||||
connectState = connected;
|
pvaClientGetData = PvaClientGetData::create(getStructure);
|
||||||
pvaClientPutData = PvaClientPutData::create(putStructure);
|
pvaClientGetData->setMessagePrefix(channelPutGet->getChannel()->getChannelName());
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
PvaClientPutGetRequesterPtr req(pvaClientPutGetRequester.lock());
|
|
||||||
if(req) {
|
|
||||||
req->channelPutGetConnect(status,shared_from_this());
|
|
||||||
}
|
}
|
||||||
waitForConnect.signal();
|
waitForConnect.signal();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PvaClientPutGet::putGetDone(
|
void PvaClientPutGet::putGetDone(
|
||||||
@@ -209,22 +188,17 @@ 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 " << pvaClientChannel->getChannel()->getChannelName()
|
<< " channelName " << channelName
|
||||||
<< " status.isOK " << (status.isOK() ? "true" : "false")
|
<< " status.isOK " << (status.isOK() ? "true" : "false")
|
||||||
<< endl;
|
<< endl;
|
||||||
}
|
}
|
||||||
{
|
channelPutGetStatus = status;
|
||||||
Lock xx(mutex);
|
if(status.isOK()) {
|
||||||
channelPutGetStatus = status;
|
pvaClientGetData->setData(getPVStructure,getChangedBitSet);
|
||||||
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();
|
||||||
}
|
}
|
||||||
@@ -236,26 +210,21 @@ 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 " << pvaClientChannel->getChannel()->getChannelName()
|
<< " channelName " << channelName
|
||||||
<< " status.isOK " << (status.isOK() ? "true" : "false")
|
<< " status.isOK " << (status.isOK() ? "true" : "false")
|
||||||
<< endl;
|
<< endl;
|
||||||
}
|
}
|
||||||
{
|
channelPutGetStatus = status;
|
||||||
Lock xx(mutex);
|
if(status.isOK()) {
|
||||||
channelPutGetStatus = status;
|
PVStructurePtr pvs = pvaClientPutData->getPVStructure();
|
||||||
putGetState = putGetComplete;
|
pvs->copyUnchecked(*putPVStructure,*putBitSet);
|
||||||
if(status.isOK()) {
|
BitSetPtr bs = pvaClientPutData->getChangedBitSet();
|
||||||
PVStructurePtr pvs = pvaClientPutData->getPVStructure();
|
bs->clear();
|
||||||
pvs->copyUnchecked(*putPVStructure,*putBitSet);
|
*bs |= *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();
|
||||||
}
|
}
|
||||||
@@ -267,38 +236,31 @@ 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 " << pvaClientChannel->getChannel()->getChannelName()
|
<< " channelName " << channelName
|
||||||
<< " status.isOK " << (status.isOK() ? "true" : "false")
|
<< " status.isOK " << (status.isOK() ? "true" : "false")
|
||||||
<< endl;
|
<< endl;
|
||||||
}
|
}
|
||||||
{
|
channelPutGetStatus = status;
|
||||||
Lock xx(mutex);
|
if(status.isOK()) {
|
||||||
channelPutGetStatus = status;
|
pvaClientGetData->setData(getPVStructure,getChangedBitSet);
|
||||||
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;
|
||||||
string message = string("channel ")
|
Channel::shared_pointer chan(channel.lock());
|
||||||
+ pvaClientChannel->getChannel()->getChannelName()
|
string channelName("disconnected");
|
||||||
|
if(chan) channelName = chan->getChannelName();
|
||||||
|
string message = string("channel ")
|
||||||
|
+ channelName
|
||||||
+ " PvaClientPutGet::connect "
|
+ " PvaClientPutGet::connect "
|
||||||
+ status.getMessage();
|
+ status.getMessage();
|
||||||
throw std::runtime_error(message);
|
throw std::runtime_error(message);
|
||||||
@@ -306,29 +268,24 @@ void PvaClientPutGet::connect()
|
|||||||
|
|
||||||
void PvaClientPutGet::issueConnect()
|
void PvaClientPutGet::issueConnect()
|
||||||
{
|
{
|
||||||
if(PvaClient::getDebug()) {
|
Channel::shared_pointer chan(channel.lock());
|
||||||
cout << "PvaClientPutGet::issueConnect"
|
|
||||||
<< " channelName " << pvaClientChannel->getChannel()->getChannelName()
|
|
||||||
<< endl;
|
|
||||||
}
|
|
||||||
if(connectState!=connectIdle) {
|
if(connectState!=connectIdle) {
|
||||||
string message = string("channel ")
|
string channelName("disconnected");
|
||||||
+ pvaClientChannel->getChannel()->getChannelName()
|
if(chan) channelName = chan->getChannelName();
|
||||||
|
string message = string("channel ") + channelName
|
||||||
+ " pvaClientPutGet already connected ";
|
+ " pvaClientPutGet already connected ";
|
||||||
throw std::runtime_error(message);
|
throw std::runtime_error(message);
|
||||||
}
|
}
|
||||||
connectState = connectActive;
|
if(chan) {
|
||||||
channelPutGetConnectStatus = Status(Status::STATUSTYPE_ERROR, "connect active");
|
connectState = connectActive;
|
||||||
channelPutGet = pvaClientChannel->getChannel()->createChannelPutGet(channelPutGetRequester,pvRequest);
|
channelPutGet = chan->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) {
|
||||||
@@ -336,30 +293,30 @@ Status PvaClientPutGet::waitConnect()
|
|||||||
return channelPutGetConnectStatus;
|
return channelPutGetConnectStatus;
|
||||||
}
|
}
|
||||||
if(connectState!=connectActive) {
|
if(connectState!=connectActive) {
|
||||||
string message = string("channel ")
|
Channel::shared_pointer chan(channel.lock());
|
||||||
+ pvaClientChannel->getChannel()->getChannelName()
|
string channelName("disconnected");
|
||||||
|
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();
|
||||||
if(!channelPutGetConnectStatus.isOK()) connectState = connectIdle;
|
connectState = channelPutGetConnectStatus.isOK() ? connected : 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;
|
||||||
string message = string("channel ")
|
Channel::shared_pointer chan(channel.lock());
|
||||||
+ pvaClientChannel->getChannel()->getChannelName()
|
string channelName("disconnected");
|
||||||
|
if(chan) channelName = chan->getChannelName();
|
||||||
|
string message = string("channel ")
|
||||||
|
+ channelName
|
||||||
+ " PvaClientPut::putGet "
|
+ " PvaClientPut::putGet "
|
||||||
+ status.getMessage();
|
+ status.getMessage();
|
||||||
throw std::runtime_error(message);
|
throw std::runtime_error(message);
|
||||||
@@ -367,15 +324,12 @@ 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==putGetActive) {
|
if(putGetState!=putGetIdle) {
|
||||||
string message = string("channel ")
|
Channel::shared_pointer chan(channel.lock());
|
||||||
+ pvaClientChannel->getChannel()->getChannelName()
|
string channelName("disconnected");
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
@@ -386,35 +340,29 @@ 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){
|
||||||
string message = string("channel ")
|
Channel::shared_pointer chan(channel.lock());
|
||||||
+ pvaClientChannel->getChannel()->getChannelName()
|
string channelName("disconnected");
|
||||||
|
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();
|
||||||
if(channelPutGetStatus.isOK()) pvaClientPutData->getChangedBitSet()->clear();
|
putGetState = putGetIdle;
|
||||||
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;
|
||||||
string message = string("channel ")
|
Channel::shared_pointer chan(channel.lock());
|
||||||
+ pvaClientChannel->getChannel()->getChannelName()
|
string channelName("disconnected");
|
||||||
|
if(chan) channelName = chan->getChannelName();
|
||||||
|
string message = string("channel ")
|
||||||
|
+ channelName
|
||||||
+ " PvaClientPut::getGet "
|
+ " PvaClientPut::getGet "
|
||||||
+ status.getMessage();
|
+ status.getMessage();
|
||||||
throw std::runtime_error(message);
|
throw std::runtime_error(message);
|
||||||
@@ -422,15 +370,12 @@ 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==putGetActive) {
|
if(putGetState!=putGetIdle) {
|
||||||
string message = string("channel ")
|
Channel::shared_pointer chan(channel.lock());
|
||||||
+ pvaClientChannel->getChannel()->getChannelName()
|
string channelName("disconnected");
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
@@ -440,34 +385,29 @@ 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){
|
||||||
string message = string("channel ")
|
Channel::shared_pointer chan(channel.lock());
|
||||||
+ pvaClientChannel->getChannel()->getChannelName()
|
string channelName("disconnected");
|
||||||
|
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;
|
||||||
string message = string("channel ")
|
Channel::shared_pointer chan(channel.lock());
|
||||||
+ pvaClientChannel->getChannel()->getChannelName()
|
string channelName("disconnected");
|
||||||
|
if(chan) channelName = chan->getChannelName();
|
||||||
|
string message = string("channel ")
|
||||||
|
+ channelName
|
||||||
+ " PvaClientPut::getPut "
|
+ " PvaClientPut::getPut "
|
||||||
+ status.getMessage();
|
+ status.getMessage();
|
||||||
throw std::runtime_error(message);
|
throw std::runtime_error(message);
|
||||||
@@ -475,15 +415,12 @@ 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==putGetActive) {
|
if(putGetState!=putGetIdle) {
|
||||||
string message = string("channel ")
|
Channel::shared_pointer chan(channel.lock());
|
||||||
+ pvaClientChannel->getChannel()->getChannelName()
|
string channelName("disconnected");
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
@@ -493,66 +430,29 @@ 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){
|
||||||
string message = string("channel ")
|
Channel::shared_pointer chan(channel.lock());
|
||||||
+ pvaClientChannel->getChannel()->getChannelName()
|
string channelName("disconnected");
|
||||||
|
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
}}
|
}}
|
||||||
|
|||||||
+12
-20
@@ -12,12 +12,13 @@
|
|||||||
#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;
|
||||||
@@ -94,7 +95,7 @@ PvaClientRPC::PvaClientRPC(
|
|||||||
PvaClientPtr const &pvaClient,
|
PvaClientPtr const &pvaClient,
|
||||||
Channel::shared_pointer const & channel,
|
Channel::shared_pointer const & channel,
|
||||||
PVStructurePtr const &pvRequest)
|
PVStructurePtr const &pvRequest)
|
||||||
:
|
:
|
||||||
connectState(connectIdle),
|
connectState(connectIdle),
|
||||||
pvaClient(pvaClient),
|
pvaClient(pvaClient),
|
||||||
channel(channel),
|
channel(channel),
|
||||||
@@ -104,7 +105,7 @@ PvaClientRPC::PvaClientRPC(
|
|||||||
{
|
{
|
||||||
if(PvaClient::getDebug()) {
|
if(PvaClient::getDebug()) {
|
||||||
cout<< "PvaClientRPC::PvaClientRPC()"
|
cout<< "PvaClientRPC::PvaClientRPC()"
|
||||||
<< " channelName " << channel->getChannelName()
|
<< " channelName " << channel->getChannelName()
|
||||||
<< endl;
|
<< endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -170,7 +171,7 @@ void PvaClientRPC::rpcConnect(
|
|||||||
cout << "PvaClientRPC::rpcConnect calling waitForConnect.signal\n";
|
cout << "PvaClientRPC::rpcConnect calling waitForConnect.signal\n";
|
||||||
}
|
}
|
||||||
waitForConnect.signal();
|
waitForConnect.signal();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PvaClientRPC::requestDone(
|
void PvaClientRPC::requestDone(
|
||||||
@@ -181,7 +182,6 @@ 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());
|
||||||
@@ -195,7 +195,7 @@ void PvaClientRPC::requestDone(
|
|||||||
Channel::shared_pointer chan(channel.lock());
|
Channel::shared_pointer chan(channel.lock());
|
||||||
if(chan) channelName = chan->getChannelName();
|
if(chan) channelName = chan->getChannelName();
|
||||||
string message = "channel "
|
string message = "channel "
|
||||||
+ channelName
|
+ channelName
|
||||||
+" PvaClientRPC::requestDone"
|
+" PvaClientRPC::requestDone"
|
||||||
+ " but not active";
|
+ " but not active";
|
||||||
throw std::runtime_error(message);
|
throw std::runtime_error(message);
|
||||||
@@ -222,11 +222,11 @@ void PvaClientRPC::connect()
|
|||||||
Channel::shared_pointer chan(channel.lock());
|
Channel::shared_pointer chan(channel.lock());
|
||||||
string channelName("disconnected");
|
string channelName("disconnected");
|
||||||
if(chan) channelName = chan->getChannelName();
|
if(chan) channelName = chan->getChannelName();
|
||||||
string message = string("channel ")
|
string message = string("channel ")
|
||||||
+ channelName
|
+ channelName
|
||||||
+ " PvaClientRPC::connect "
|
+ " PvaClientRPC::connect "
|
||||||
+ status.getMessage();
|
+ status.getMessage();
|
||||||
throw RPCRequestException(Status::STATUSTYPE_ERROR,message);
|
throw std::runtime_error(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PvaClientRPC::issueConnect()
|
void PvaClientRPC::issueConnect()
|
||||||
@@ -237,7 +237,7 @@ void PvaClientRPC::issueConnect()
|
|||||||
string channelName("disconnected");
|
string channelName("disconnected");
|
||||||
if(chan) channelName = chan->getChannelName();
|
if(chan) channelName = chan->getChannelName();
|
||||||
string message = string("channel ")
|
string message = string("channel ")
|
||||||
+ channelName
|
+ channelName
|
||||||
+ " pvaClientRPC already connected ";
|
+ " pvaClientRPC already connected ";
|
||||||
throw std::runtime_error(message);
|
throw std::runtime_error(message);
|
||||||
}
|
}
|
||||||
@@ -307,18 +307,10 @@ 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 RPCRequestException(Status::STATUSTYPE_ERROR,message);
|
throw std::runtime_error(message);
|
||||||
}
|
}
|
||||||
rpcState = rpcIdle;
|
rpcState = rpcIdle;
|
||||||
if(requestStatus.isOK()) return pvResponse;
|
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -326,7 +318,7 @@ void PvaClientRPC::request(
|
|||||||
PVStructure::shared_pointer const & pvArgument,
|
PVStructure::shared_pointer const & pvArgument,
|
||||||
PvaClientRPCRequesterPtr const & pvaClientRPCRequester)
|
PvaClientRPCRequesterPtr const & pvaClientRPCRequester)
|
||||||
{
|
{
|
||||||
checkRPCState();
|
checkRPCState();
|
||||||
this->pvaClientRPCRequester = pvaClientRPCRequester;
|
this->pvaClientRPCRequester = pvaClientRPCRequester;
|
||||||
if(responseTimeout<=0.0) {
|
if(responseTimeout<=0.0) {
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user