REVERT: Merge pull request #4 from mrkraimer/default
merged
(reverted from commit 9869e611ea
)
This commit is contained in:
13
.gitignore
vendored
13
.gitignore
vendored
@ -1,13 +0,0 @@
|
|||||||
QtC-
|
|
||||||
bin/
|
|
||||||
lib/
|
|
||||||
doc/
|
|
||||||
include/
|
|
||||||
db/
|
|
||||||
dbd/
|
|
||||||
documentation/html
|
|
||||||
documentation/*.tag
|
|
||||||
envPaths
|
|
||||||
configure/*.local
|
|
||||||
!configure/ExampleRELEASE.local
|
|
||||||
**/O.*
|
|
3
Doxyfile
3
Doxyfile
@ -908,8 +908,7 @@ HTML_STYLESHEET =
|
|||||||
# files. In the HTML_STYLESHEET file, use the file name only. Also note that
|
# files. In the HTML_STYLESHEET file, use the file name only. Also note that
|
||||||
# the files will be copied as-is; there are no commands or markers available.
|
# the files will be copied as-is; there are no commands or markers available.
|
||||||
|
|
||||||
HTML_EXTRA_FILES = documentation/pvAccessOverview.html
|
HTML_EXTRA_FILES =
|
||||||
HTML_EXTRA_FILES = documentation/pvaOverview.html
|
|
||||||
|
|
||||||
# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output.
|
# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output.
|
||||||
# Doxygen will adjust the colors in the style sheet and background images
|
# Doxygen will adjust the colors in the style sheet and background images
|
||||||
|
25
Makefile
25
Makefile
@ -2,25 +2,16 @@
|
|||||||
|
|
||||||
TOP = .
|
TOP = .
|
||||||
include $(TOP)/configure/CONFIG
|
include $(TOP)/configure/CONFIG
|
||||||
DIRS := $(DIRS) $(filter-out $(DIRS), configure)
|
|
||||||
DIRS := $(DIRS) $(filter-out $(DIRS), src)
|
|
||||||
DIRS := $(DIRS) $(filter-out $(DIRS), pvaSrc)
|
|
||||||
DIRS := $(DIRS) $(filter-out $(DIRS), pvtoolsSrc)
|
|
||||||
DIRS := $(DIRS) $(filter-out $(DIRS), testApp)
|
|
||||||
DIRS := $(DIRS) $(filter-out $(DIRS), pvaExample)
|
|
||||||
DIRS := $(DIRS) $(filter-out $(DIRS), pvaTest)
|
|
||||||
|
|
||||||
EMBEDDED_TOPS := $(EMBEDDED_TOPS) $(filter-out $(EMBEDDED_TOPS), pvaExample)
|
DIRS := configure
|
||||||
EMBEDDED_TOPS := $(EMBEDDED_TOPS) $(filter-out $(EMBEDDED_TOPS), pvaTest)
|
|
||||||
|
|
||||||
define DIR_template
|
DIRS += src
|
||||||
$(1)_DEPEND_DIRS = configure
|
src_DEPEND_DIRS = configure
|
||||||
endef
|
|
||||||
$(foreach dir, $(filter-out configure,$(DIRS)),$(eval $(call DIR_template,$(dir))))
|
|
||||||
|
|
||||||
define EMB_template
|
DIRS += pvtoolsSrc
|
||||||
$(1)_DEPEND_DIRS = src pvaSrc
|
pvtoolsSrc_DEPEND_DIRS = src
|
||||||
endef
|
|
||||||
$(foreach dir, $(EMBEDDED_TOPS),$(eval $(call EMB_template,$(dir))))
|
DIRS += testApp
|
||||||
|
testApp_DEPEND_DIRS = src
|
||||||
|
|
||||||
include $(TOP)/configure/RULES_TOP
|
include $(TOP)/configure/RULES_TOP
|
||||||
|
@ -1,7 +0,0 @@
|
|||||||
EPICS_BASE=/home/install/epics/base
|
|
||||||
|
|
||||||
EPICS4_DIR=/home/epicsv4
|
|
||||||
PVCOMMON=${EPICS4_DIR}/pvCommonCPP
|
|
||||||
PVDATA=${EPICS4_DIR}/pvDataCPP
|
|
||||||
|
|
||||||
|
|
@ -38,7 +38,7 @@
|
|||||||
<h1>EPICS pvAccessCPP</h1>
|
<h1>EPICS pvAccessCPP</h1>
|
||||||
<!-- Maturity: Working Draft or Request for Comments, or Recommendation, and date. -->
|
<!-- Maturity: Working Draft or Request for Comments, or Recommendation, and date. -->
|
||||||
|
|
||||||
<h2 class="nocount">EPICS v4 Working Group, Working Draft, 05-June-2011</h2>
|
<h2 class="nocount" id="L50">EPICS v4 Working Group, Working Draft, 09-July-2011</h2>
|
||||||
<dl>
|
<dl>
|
||||||
<dt>Latest version:</dt>
|
<dt>Latest version:</dt>
|
||||||
<dd><a
|
<dd><a
|
||||||
@ -46,11 +46,11 @@
|
|||||||
</a></dd>
|
</a></dd>
|
||||||
<dt>This version:</dt>
|
<dt>This version:</dt>
|
||||||
<dd><a
|
<dd><a
|
||||||
href="pvAccessCPP_20150505.html">pvAccessCPP_20150505.html
|
href="pvAccessCPP_20140709.html">pvAccessCPP_20140709.html
|
||||||
</a></dd>
|
</a></dd>
|
||||||
<dt>Previous version:</dt>
|
<dt>Previous version:</dt>
|
||||||
<dd><a
|
<dd><a
|
||||||
href="pvAccessCPP_20140709.html">pvAccessCPP_20140709.html
|
href="pvAccessCPP_20111220.html">pvAccessCPP_20111220.html
|
||||||
</a></dd>
|
</a></dd>
|
||||||
<dt>Editors:</dt>
|
<dt>Editors:</dt>
|
||||||
<dd>Marty Kraimer, BNL<br />
|
<dd>Marty Kraimer, BNL<br />
|
||||||
@ -59,77 +59,40 @@
|
|||||||
<hr />
|
<hr />
|
||||||
|
|
||||||
<h2 class="nocount">Abstract</h2>
|
<h2 class="nocount">Abstract</h2>
|
||||||
<p>pvAccessCPP is the C++ implementation of pvAccess,
|
<p>pvAccessCPP is the C++ implementation of pvAccess, which is one of a related
|
||||||
which is network support for transporting structured data as defined by pvData.
|
set of products:</br >
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
pvAccess is one of a related
|
|
||||||
set of products:
|
|
||||||
<a href="http://epics-pvdata.sourceforge.net/relatedDocumentsV4.html">relatedDocumentsV4.html</a>
|
<a href="http://epics-pvdata.sourceforge.net/relatedDocumentsV4.html">relatedDocumentsV4.html</a>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<h2 class="nocount">Status of this Document</h2>
|
<h2 class="nocount">Status of this Document</h2>
|
||||||
|
|
||||||
<p>This is the 05-June-2011 version of the C++ implementation of pvAccess. The
|
<p>This is the 09-July-2011 version of the C++ implementation of pvAccess. The
|
||||||
code is a complete implementation of pvAccess.</p>
|
code is a complete implementation of pvAccess as currently defined. This
|
||||||
|
overview is NOT written.</p>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="toc">
|
<div id="toc">
|
||||||
<h2 class="nocount">Table of Contents</h2>
|
<h2 class="nocount" style="page-break-before: always">Table of Contents</h2>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Place what you would like in the Table of Contents, inside the contents div -->
|
|
||||||
<div id="contents" class="contents">
|
<div id="contents" class="contents">
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<h2 id="L88">Introduction</h2>
|
||||||
<hr />
|
<hr />
|
||||||
|
|
||||||
<h2>Preface</h2>
|
<p>This product is available via an <a
|
||||||
<p>This document describes the pvAccess Application Program Interface (API).
|
href="http://epics-pvdata.sourceforge.net/LICENSE.html">open source
|
||||||
The reader is assumed to have a basic understanding of EPICS V4 as described in:</p>
|
license</a></p>
|
||||||
<a
|
|
||||||
href="http://epics-pvdata.sourceforge.net/informative/developerGuide/developerGuide.html">
|
|
||||||
EPICS V4 Developer's Guide
|
|
||||||
</a>
|
|
||||||
<p>The pvAccess API is callback based and uses Status to report problem to the
|
|
||||||
client, which means that it can be complex to use.
|
|
||||||
If your primary interest is client access then, instead of reading this document,
|
|
||||||
read:</p>
|
|
||||||
<a
|
|
||||||
href="pva.html">
|
|
||||||
EPICS pva
|
|
||||||
</a>
|
|
||||||
<p>If your primary interest is implementing pvAccess services then,
|
|
||||||
before reading this documement read:</p>
|
|
||||||
<a
|
|
||||||
href="http://epics-pvdata.sourceforge.net/docbuild/pvDatabaseCPP/tip/documentation/pvDatabaseCPP.html">
|
|
||||||
pvDatabaseCPP
|
|
||||||
</a>
|
|
||||||
|
|
||||||
|
<p>This overview for pvAccessCPP. Doxygen documentation is available at <a
|
||||||
|
href="./html/index.html">doxygenDoc</a></p>
|
||||||
|
|
||||||
|
<p><b>THIS IS NOT WRITTEN</b> For now please consult pvAccessJava.html.
|
||||||
|
In addition look at the Doxygen documentation for this project.</p>
|
||||||
<h2>Introduction</h2>
|
|
||||||
<p>This product is available via an
|
|
||||||
<a
|
|
||||||
href="http://epics-pvdata.sourceforge.net/LICENSE.html">open source license
|
|
||||||
</a>
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
A user overview is available via
|
|
||||||
<a
|
|
||||||
href="./pvAccessOverview.html">pvAccessOverview.html
|
|
||||||
</a>
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
Doxygen documentation is available at
|
|
||||||
<a
|
|
||||||
href="./html/index.html">doxygenDoc
|
|
||||||
</a>
|
|
||||||
|
|
||||||
<h2>???</h2>
|
|
||||||
<p>Matej decide what else should go in this document</p>
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
|
@ -1,136 +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>EPICS pvAccessCPP</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>
|
|
||||||
|
|
||||||
<div class="head">
|
|
||||||
<h1>EPICS pvAccessCPP</h1>
|
|
||||||
<!-- Maturity: Working Draft or Request for Comments, or Recommendation, and date. -->
|
|
||||||
|
|
||||||
<h2 class="nocount">EPICS v4 Working Group, Working Draft, 05-June-2011</h2>
|
|
||||||
<dl>
|
|
||||||
<dt>Latest version:</dt>
|
|
||||||
<dd><a
|
|
||||||
href="pvAccessCPP.html">pvAccessCPP.html
|
|
||||||
</a></dd>
|
|
||||||
<dt>This version:</dt>
|
|
||||||
<dd><a
|
|
||||||
href="pvAccessCPP_20150505.html">pvAccessCPP_20150505.html
|
|
||||||
</a></dd>
|
|
||||||
<dt>Previous version:</dt>
|
|
||||||
<dd><a
|
|
||||||
href="pvAccessCPP_20140709.html">pvAccessCPP_20140709.html
|
|
||||||
</a></dd>
|
|
||||||
<dt>Editors:</dt>
|
|
||||||
<dd>Marty Kraimer, BNL<br />
|
|
||||||
Matej Sekoranja, CosyLab</dd>
|
|
||||||
</dl>
|
|
||||||
<hr />
|
|
||||||
|
|
||||||
<h2 class="nocount">Abstract</h2>
|
|
||||||
<p>pvAccessCPP is the C++ implementation of pvAccess,
|
|
||||||
which is network support for transporting structured data as defined by pvData.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
pvAccess is one of a related
|
|
||||||
set of products:
|
|
||||||
<a href="http://epics-pvdata.sourceforge.net/relatedDocumentsV4.html">relatedDocumentsV4.html</a>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<h2 class="nocount">Status of this Document</h2>
|
|
||||||
|
|
||||||
<p>This is the 05-June-2011 version of the C++ implementation of pvAccess. The
|
|
||||||
code is a complete implementation of pvAccess.</p>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<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 />
|
|
||||||
|
|
||||||
<h2>Preface</h2>
|
|
||||||
<p>This document describes the pvAccess Application Program Interface (API).
|
|
||||||
The reader is assumed to have a basic understanding of EPICS V4 as described in:</p>
|
|
||||||
<a
|
|
||||||
href="http://epics-pvdata.sourceforge.net/informative/developerGuide/developerGuide.html">
|
|
||||||
EPICS V4 Developer's Guide
|
|
||||||
</a>
|
|
||||||
<p>The pvAccess API is callback based and uses Status to report problem to the
|
|
||||||
client, which means that it can be complex to use.
|
|
||||||
If your primary interest is client access then, instead of reading this document,
|
|
||||||
read:</p>
|
|
||||||
<a
|
|
||||||
href="pva.html">
|
|
||||||
EPICS pva
|
|
||||||
</a>
|
|
||||||
<p>If your primary interest is implementing pvAccess services then,
|
|
||||||
before reading this documement read:</p>
|
|
||||||
<a
|
|
||||||
href="http://epics-pvdata.sourceforge.net/docbuild/pvDatabaseCPP/tip/documentation/pvDatabaseCPP.html">
|
|
||||||
pvDatabaseCPP
|
|
||||||
</a>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<h2>Introduction</h2>
|
|
||||||
<p>This product is available via an
|
|
||||||
<a
|
|
||||||
href="http://epics-pvdata.sourceforge.net/LICENSE.html">open source license
|
|
||||||
</a>
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
A user overview is available via
|
|
||||||
<a
|
|
||||||
href="./pvAccessOverview.html">pvAccessOverview.html
|
|
||||||
</a>
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
Doxygen documentation is available at
|
|
||||||
<a
|
|
||||||
href="./html/index.html">doxygenDoc
|
|
||||||
</a>
|
|
||||||
|
|
||||||
<h2>???</h2>
|
|
||||||
<p>Matej decide what else should go in this document</p>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
File diff suppressed because it is too large
Load Diff
@ -1,202 +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>EPICS pva</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 }
|
|
||||||
body { margin-right: 10% }
|
|
||||||
/*]]>*/</style>
|
|
||||||
|
|
||||||
<!-- Script that generates the Table of Contents -->
|
|
||||||
<script type="text/javascript" src="http://epics-pvdata.sourceforge.net/script/tocgen.js"></script>
|
|
||||||
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
|
|
||||||
<div class="head">
|
|
||||||
<h1>EPICS pva</h1>
|
|
||||||
<!-- Maturity: Working Draft or Request for Comments, or Recommendation, and date. -->
|
|
||||||
<h2 class="nocount">EPICS V4 Working Group, Working Draft,
|
|
||||||
29-May-2015</h2>
|
|
||||||
<dl>
|
|
||||||
<dt>This version:</dt>
|
|
||||||
<dd><a
|
|
||||||
href="pva.html">pva.html
|
|
||||||
</a> </dd>
|
|
||||||
<dt>Latest version:</dt>
|
|
||||||
<dd><a
|
|
||||||
href="pva_20150529.html">pva_20150529.html</a>
|
|
||||||
</dd>
|
|
||||||
<dt>Previous version:</dt>
|
|
||||||
<dd>none</dd>
|
|
||||||
<dt>Editors:</dt>
|
|
||||||
<dd>Marty Kraimer, BNL</dd>
|
|
||||||
<dd>Matej Sekoranja, Cosylab</dd>
|
|
||||||
</dl>
|
|
||||||
|
|
||||||
<h2 class="nocount">Abstract</h2>
|
|
||||||
|
|
||||||
<p>Pva (Pva PVAccess) 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
|
|
||||||
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>
|
|
||||||
|
|
||||||
<p>Specifically, pva provides a synchronous interface for pvAccess, which is the
|
|
||||||
software support for high speed controls network communications used in EPICS version 4.
|
|
||||||
PvAccess provides a callback based interface, which can be hard to use.
|
|
||||||
Pva provides an interface that does not require callbacks even for monitors.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
PvaChannel provides many "convenience" methods to directly get and put
|
|
||||||
scalar and scalarArray data types.
|
|
||||||
Additional methods provide access to the full features of pvAccess.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
PvaMultiChannel provides access to data from multiple channels.
|
|
||||||
It can be used directly by a client or via PvaMultiDouble or PvaNTMultiChannel.
|
|
||||||
PvaMultiDouble allows the client to get and put data to multiple channels.
|
|
||||||
But each channel must have a value field that is a numeric scalar.
|
|
||||||
PvaNTMultiChannel allows the client to get and put data to multiple channels.
|
|
||||||
Each channel must have a value field.
|
|
||||||
The data for the channels is presented via normative type NTMultiChannel.
|
|
||||||
</p>
|
|
||||||
<!-- last para of Abstract is boilerplate reference to EPICS -->
|
|
||||||
<p>For more information about EPICS generally, please refer to the home page of the <a
|
|
||||||
href="http://www.aps.anl.gov/epics/">Experimental Physics and Industrial
|
|
||||||
Control System</a>.</p>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<h2 class="nocount">Status of this Document and of the Pva Software</h2>
|
|
||||||
|
|
||||||
<p>PvaCPP is ready for use.</p>
|
|
||||||
|
|
||||||
</div> <!-- head -->
|
|
||||||
|
|
||||||
<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 />
|
|
||||||
|
|
||||||
<h2>Introduction</h2>
|
|
||||||
|
|
||||||
<p>Pva is a synchronous API for accessing PVData via PVAccess. It provides
|
|
||||||
an interface to many of the features provided by pvData and pvAccess.</p>
|
|
||||||
|
|
||||||
<p>This document describes the layout of the source files in this project.</p>
|
|
||||||
<p>
|
|
||||||
A user overview is available via
|
|
||||||
<a
|
|
||||||
href="./pvaOverview.html">pvaOverview.html
|
|
||||||
</a>
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
Doxygen documentation is available at
|
|
||||||
<a
|
|
||||||
href="./html/index.html">doxygenDoc
|
|
||||||
</a>
|
|
||||||
</p>
|
|
||||||
<h2>Example and Test Database</h2>
|
|
||||||
<p>The examples and tests require that an example pvAccess server is runnimg.
|
|
||||||
This distribution has a file <b>exampleDatabasePva.zip</b>.
|
|
||||||
When unzipped this is used to create an example IOC database.
|
|
||||||
The database has the record used by the examples are tests that come with pvaJava.
|
|
||||||
It uses pvDatabaseCPP to build the database.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
After unzipping the file:
|
|
||||||
</p>
|
|
||||||
<pre>
|
|
||||||
cd configure
|
|
||||||
cp ExampleRELEASE.local RELEASE.local
|
|
||||||
edit RELEASE.local
|
|
||||||
cd ..
|
|
||||||
make
|
|
||||||
cd iocBoot/exampleDatabase
|
|
||||||
../../bin/<arch:>/exampleDatabase st.cmd
|
|
||||||
</pre>
|
|
||||||
<h2>Testing</h2>
|
|
||||||
<p>The tests will fail unless the example database is running.</p>
|
|
||||||
<p>Once it is running:</p>
|
|
||||||
<pre>
|
|
||||||
make runtests
|
|
||||||
</pre>
|
|
||||||
<h2>Examples</h2>
|
|
||||||
<p>Examples are in directory <b>pvaExample/src</b>.
|
|
||||||
An example of how to run them is:</p>
|
|
||||||
<pre>
|
|
||||||
mrk> pwd
|
|
||||||
/home/epicsv4/pvAccessCPP/pvaExample
|
|
||||||
mrk> bin/linux-x86_64/examplePvaGet
|
|
||||||
</pre>
|
|
||||||
<p>The following is a brief description of each example.
|
|
||||||
In order to understand each example it
|
|
||||||
helps to also look at the source for the example.</p>
|
|
||||||
<h2>examplePvaGet</h2>
|
|
||||||
<p>This has a number of examples:</p>
|
|
||||||
<dl>
|
|
||||||
<dt>exampleDouble</dt>
|
|
||||||
<dd>
|
|
||||||
This shows two methods for getting data from a channel that has a numeric
|
|
||||||
scalar value field.
|
|
||||||
</dd>
|
|
||||||
<dt>exampleDoubleArray</dt>
|
|
||||||
<dd>
|
|
||||||
This shows two methods for getting data from a channel that has a
|
|
||||||
double array value field.
|
|
||||||
</dd>
|
|
||||||
<dt>exampleCADouble</dt>
|
|
||||||
<dd>
|
|
||||||
This is like exampleDouble except it uses provider <b>ca</b>.
|
|
||||||
</dd>
|
|
||||||
<dt>exampleCADoubleArray</dt>
|
|
||||||
<dd>
|
|
||||||
This is like exampleDoubleArray except it uses provider <b>ca</b>.
|
|
||||||
</dd>
|
|
||||||
<dt>examplePowerSupply</dt>
|
|
||||||
<dd>
|
|
||||||
This is an example of getting data from a channel that does not
|
|
||||||
have a value field.
|
|
||||||
</dd>
|
|
||||||
</dl>
|
|
||||||
<h2>examplePvaMonitor</h2>
|
|
||||||
<p>This is an example of creating a monitor on a channel.
|
|
||||||
It monitors a channel that models a powerSupply, i. e. it is not a "standard" record.
|
|
||||||
It does not have a value field.
|
|
||||||
</p>
|
|
||||||
<p>After starting the example a change can be made to the powerSupply by issuing:</p>
|
|
||||||
<pre>
|
|
||||||
pvput -r "power.value,voltage.value" examplePowerSupply 6 6
|
|
||||||
</pre>
|
|
||||||
<h2>examplePvaPut</h2>
|
|
||||||
<p>This example gets and puts to channel exampleDouble.</p>
|
|
||||||
<h2>examplePvaProcess</h2>
|
|
||||||
<p>This example makes a process request to channel exampleDouble.</p>
|
|
||||||
<h2>helloWorldPutGet</h2>
|
|
||||||
<p>This is an example of issuing a channelPutGet.</p>
|
|
||||||
<h2>examplePvaMultiDouble</h2>
|
|
||||||
<p>This is an example of issuing gets and puts to multiple channels where each
|
|
||||||
channel has a numeric scalar value field.</p>
|
|
||||||
<h2>examplePvaNTMultiChannel</h2>
|
|
||||||
<p>This is an example of using NDMultiChannel to obtain data from multiple channels.
|
|
||||||
</p>
|
|
||||||
<h2>helloWorldRPC</h2>
|
|
||||||
<p>This is an example of issuing a channelRPC request.
|
|
||||||
It does <b>not</b> use pva.</p>
|
|
||||||
</div> <!-- class="contents" -->
|
|
||||||
</body>
|
|
||||||
</html>
|
|
@ -1,321 +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>pva C++ Overview</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 }
|
|
||||||
body { margin-right: 10% }
|
|
||||||
/*]]>*/</style>
|
|
||||||
|
|
||||||
<!-- Script that generates the Table of Contents -->
|
|
||||||
<script type="text/javascript" src="http://epics-pvdata.sourceforge.net/script/tocgen.js"></script>
|
|
||||||
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
|
|
||||||
<div class="head">
|
|
||||||
<h1>Pva C++ Overview</h1>
|
|
||||||
|
|
||||||
</div> <!-- head -->
|
|
||||||
|
|
||||||
<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 />
|
|
||||||
|
|
||||||
<h2>Introduction</h2>
|
|
||||||
|
|
||||||
<p>Pva is a synchronous API for accessing PVData via PVAccess.
|
|
||||||
It also provides a number of convenience methods.
|
|
||||||
It allows the client to request access without checking for failure,
|
|
||||||
but throws an exception if a request fails.
|
|
||||||
A client can also check for failues and thus prevent exceptions.</p>
|
|
||||||
|
|
||||||
<p>The Pva API has the following features:</p>
|
|
||||||
<ol>
|
|
||||||
<li>Provides a synchronous API rather than the callback API provided by pvAccess.</li>
|
|
||||||
<li>Makes common requests pva.</li>
|
|
||||||
<li>Provides full access to the pvAccess API for more demanding
|
|
||||||
applications</li>
|
|
||||||
<li>Allows efficient client side programs.</li>
|
|
||||||
<li>Takes care of most object resource management problems.</li>
|
|
||||||
</ol>
|
|
||||||
<p>Simple examples of using pva:</p>
|
|
||||||
<pre>
|
|
||||||
// pvaGet
|
|
||||||
PvaPtr pva = Pva::create();
|
|
||||||
double value = pva->channel("exampleDouble")->get()->getData()->getDouble();
|
|
||||||
|
|
||||||
// pvaPut
|
|
||||||
PvaChannelPtr channel = pva->channel("exampleDouble");
|
|
||||||
PvaPutPtr put = channel->put();
|
|
||||||
PvaPutDataPtr putData = put->getData();
|
|
||||||
putData->putDouble(3.0); put->put();
|
|
||||||
|
|
||||||
// pvaMonitor
|
|
||||||
PvaMonitorPtr monitor = pva->channel("examplePowerSupply")->monitor("");
|
|
||||||
PvaMonitorDataPtr pvaData = monitor->getData();
|
|
||||||
while(true) {
|
|
||||||
monitor->waitEvent();
|
|
||||||
cout << "changed\n";
|
|
||||||
pvaData->showChanged(cout);
|
|
||||||
cout << "overrun\n";
|
|
||||||
pvaData->showOverrun(cout);
|
|
||||||
monitor->releaseEvent();
|
|
||||||
}
|
|
||||||
|
|
||||||
// pvaProcess
|
|
||||||
PvaChannelPtr channel = pva->channel("exampleDouble");
|
|
||||||
PvaProcessPtr process = channel->createProcess();
|
|
||||||
process->process();
|
|
||||||
|
|
||||||
</pre>
|
|
||||||
<p><b>pvaExample</b> includes a number of examples.</p>
|
|
||||||
<p>pva does <b>not</b> provide support for:</p>
|
|
||||||
<dl>
|
|
||||||
<dt>ChannelArray</dt>
|
|
||||||
<dd>TBD</dd>
|
|
||||||
<dt>ChannelRPC</dt>
|
|
||||||
<dd>pvAccess itself already provides a synchronous interface.
|
|
||||||
The examples include helloWorldRPC, which is an example of using channelRP.
|
|
||||||
</dd>
|
|
||||||
</dl>
|
|
||||||
|
|
||||||
<h2>Pva</h2>
|
|
||||||
<p>An instance of Pva is obtained via the call:</p>
|
|
||||||
<pre>
|
|
||||||
PvaPtr pva = Pva::create();
|
|
||||||
</pre>
|
|
||||||
|
|
||||||
<p>Pva has methods to create instances of <b>PvaChannel</b>.
|
|
||||||
The client can specify the provider name or use the default provider.
|
|
||||||
The client can manage it's own channels or can let pva cache channels.
|
|
||||||
An example of using the cached method is:</p>
|
|
||||||
<pre>
|
|
||||||
PvaChannelPtr pvaChannel = pva->channel("exampleDouble");
|
|
||||||
</pre>
|
|
||||||
<p>This will attempt to connect to channel exampleDouble.
|
|
||||||
Since the client did not specify a timeout an exception wll be thrown if
|
|
||||||
the connection request fails.
|
|
||||||
The client will block until the connection is made or an exception is thrown.
|
|
||||||
If the request succeeds, pva caches the pvaChannel so that if the
|
|
||||||
client makes another request for the same channel the cached object is
|
|
||||||
returned to the client.
|
|
||||||
</p>
|
|
||||||
<p>An example of using a non cached method is:</p>
|
|
||||||
<pre>
|
|
||||||
PvaChannelPtr pvaChannel = pva->createChannel("exampleDouble");
|
|
||||||
</pre>
|
|
||||||
<p>This will create an PvaChannel and return it to the client.
|
|
||||||
The client must itself connect.
|
|
||||||
This is useful if the client wants to connect to multiple channels in parallel.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h2>PvaChannel - Wrapper For Single Channel</h2>
|
|
||||||
<h3>PvaChannel</h3>
|
|
||||||
<p>This provides methods for connecting to a channel and for creating instances of
|
|
||||||
PvaField, PvaProcess, ..., PvaPutGet.</p>
|
|
||||||
<p>Connection must be made before any create method is called or
|
|
||||||
an exception is raised.
|
|
||||||
The following is a synchronous connection request:</p>
|
|
||||||
<pre>
|
|
||||||
pvaChannel->connect(5.0); // BLOCKS AND THROWS IF NO CONNECT
|
|
||||||
</pre>
|
|
||||||
<p>This blocks until then connection is made or until timout occurs.
|
|
||||||
An exception is raised if the connection request fails.
|
|
||||||
</p>
|
|
||||||
<p>The same request can be made without blocking and without exceptions.</p>
|
|
||||||
<pre>
|
|
||||||
pvaChannel->issueConnect(); // DOES NOT BLOCK
|
|
||||||
.....
|
|
||||||
Status status =pvaChannel->waitConnect(5.0); // BLOCKS DOES NOT THROW
|
|
||||||
if(!status.isOK()) {
|
|
||||||
// failure do something
|
|
||||||
}
|
|
||||||
</pre>
|
|
||||||
<p>Once the channel is connected other Pva objects can be created.
|
|
||||||
For example:</p>
|
|
||||||
<pre>
|
|
||||||
PvaGetPtr pvaGet = pvaChannel->get(); // DOES BLOCK
|
|
||||||
</pre>
|
|
||||||
<p>This is a caching request.
|
|
||||||
If the client already has made an identical request the client will receive the
|
|
||||||
cached object.
|
|
||||||
If a new pvaGet is created than it is connected before it is returned to the client.
|
|
||||||
</p>
|
|
||||||
<p>The client can also managed it's own objects:</p>
|
|
||||||
<pre>
|
|
||||||
PvaGetPtr pvaGet = pvaChannel->createGet(); // DOES NOT BLOCK
|
|
||||||
</pre>
|
|
||||||
<p>The client must connect the pvaGet.</p>
|
|
||||||
|
|
||||||
<h3>PvaGetData</h3>
|
|
||||||
<p>This provides the data returned by pvaGet and pvaPutGet.
|
|
||||||
It is obtained via:</p>
|
|
||||||
<pre>
|
|
||||||
PvaGetDataPtr pvaData = pvaGet->getData();
|
|
||||||
</pre>
|
|
||||||
<p>It provides methods to get everything returned by channelGet.
|
|
||||||
In addition there are methods that make it easier to handle a value
|
|
||||||
field that is a scalar or a scalarArray.
|
|
||||||
Also for a scalar that is a double or a scalarArray with element type double.
|
|
||||||
</p>
|
|
||||||
<p>An example is:</p>
|
|
||||||
<pre>
|
|
||||||
double value = pvaData->getDouble();
|
|
||||||
</pre>
|
|
||||||
<p>It also keeps a bitSet showing which fields have changed since the last channelGet or channelPutGet.</p>
|
|
||||||
|
|
||||||
<h3>PvaMonitorData</h3>
|
|
||||||
<p>To the client this looks identical to PvaGetData except that
|
|
||||||
it provides two BitSets: changedBitSet and overrrunBitSet.
|
|
||||||
It is used by pvaMonitor.
|
|
||||||
</p>
|
|
||||||
<h3>PvaPutData</h3>
|
|
||||||
<p>This is used to provided data for pvaPut and pvaPutGet.
|
|
||||||
It has many of the same methods as pvaGetData.
|
|
||||||
It does not have a bitSet.
|
|
||||||
It also has put methods like:</p>
|
|
||||||
<pre>
|
|
||||||
void pvaData->putDouble(5.0);
|
|
||||||
</pre>
|
|
||||||
<h3>PvaGet</h3>
|
|
||||||
<p>This provides methods to connect to channelGet and to issue get request.
|
|
||||||
To connect via a single synchronous call:</p>
|
|
||||||
<pre>
|
|
||||||
eastGet->connect(); // BLOCKS AND CAN THROW
|
|
||||||
</pre>
|
|
||||||
<p>This can also be done in two steps:</p>
|
|
||||||
<pre>
|
|
||||||
pvaGet->issueConnect(); // DOES NOT BLOCK
|
|
||||||
...
|
|
||||||
Status status = pvaGet->waitConnect(); // BLOCKS AND DOES NOT HROW
|
|
||||||
</pre>
|
|
||||||
<p>Once connected gets are issued via either:</p>
|
|
||||||
<pre>
|
|
||||||
void pvaGet->get(); // BLOCKS AND CAN THROW
|
|
||||||
</pre>
|
|
||||||
or
|
|
||||||
<pre>
|
|
||||||
pvaGet->issueGet(); // DOES NOT BLOCK
|
|
||||||
...
|
|
||||||
Status status = pvaGet->waitGet(); // BLOCKS AND DOES NOT THROW
|
|
||||||
</pre>
|
|
||||||
<h3>PvaPut</h3>
|
|
||||||
<p>This is similar to pvaGet except that it wraps channelPut instead of channelGet.
|
|
||||||
</p>
|
|
||||||
<p>Once connected puts are issued via either:</p>
|
|
||||||
<pre>
|
|
||||||
void pvaPut->put(); // BLOCKS AND CAN THROW
|
|
||||||
</pre>
|
|
||||||
or
|
|
||||||
<pre>
|
|
||||||
pvaPut->issuePut(); // DOES NOT BLOCK
|
|
||||||
...
|
|
||||||
Status status = pvaPut->waitPut(); // BLOCKS AND DOES NOT THROW
|
|
||||||
</pre>
|
|
||||||
<h3>PvaMonitor</h3>
|
|
||||||
<p>Connecting is similar to pvaGet and pvaPut.
|
|
||||||
The other methods are:</p>
|
|
||||||
<dl>
|
|
||||||
<dt>start</dt>
|
|
||||||
<dd>Starts monitoring</dd>
|
|
||||||
<dt>stop</dt>
|
|
||||||
<dd>Stops monitoring</dd>
|
|
||||||
<dt>poll</dt>
|
|
||||||
<dd>polls for a monitorEvent.
|
|
||||||
The data is avalable via pvaMonitorData.
|
|
||||||
</dd>
|
|
||||||
<dt>releaseEvent</dt>
|
|
||||||
<dd>Release the data from the last poll.
|
|
||||||
Note that this must be called before another poll is requested.
|
|
||||||
</dd>
|
|
||||||
<dt>waitEvent</dt>
|
|
||||||
<dd>Block until a monitorEvent is available.
|
|
||||||
If true is returned a poll has already been issued.
|
|
||||||
</dd>
|
|
||||||
<dt>setRequester</dt>
|
|
||||||
<dd>A client callback is registered to receive notice of monitorEvents.</dd>
|
|
||||||
</dl>
|
|
||||||
<h3>PvaProcess</h3>
|
|
||||||
<p>Connecting is similar to pvaGet.
|
|
||||||
It has methods:</p>
|
|
||||||
<dl>
|
|
||||||
<dt>process</dt>
|
|
||||||
<dd>call issueProcess and waitProcess.</dd>
|
|
||||||
<dt>issueProcess</dt>
|
|
||||||
<dd>call channelProcess->process() and return immediately.
|
|
||||||
</dd>
|
|
||||||
<dt>waitProcess</dt>
|
|
||||||
<dd>Wait for process to complete.</dd>
|
|
||||||
</dl>
|
|
||||||
<h3>PvaPutGet</h3>
|
|
||||||
<p>Connecting is similar to pvaGet.
|
|
||||||
It has methods:</p>
|
|
||||||
<dl>
|
|
||||||
<dt>putGet</dt>
|
|
||||||
<dd>calls issuePutGet and waitPutGet.
|
|
||||||
throws an exception if not successfull.
|
|
||||||
</dd>
|
|
||||||
<dt>issuePutGet</dt>
|
|
||||||
<dd>
|
|
||||||
Calls channel->putGet() and returns.
|
|
||||||
</dd>
|
|
||||||
<dt>waitPutGet</dt>
|
|
||||||
<dd>
|
|
||||||
Waits until putGet completes and returns status.
|
|
||||||
</dd>
|
|
||||||
<dt>getGet,issueGetGet, and waitGetGet</dt>
|
|
||||||
<dd>Gets the data for the get part of channelPutGet.</dd>
|
|
||||||
<dt>getPut,issueGetPut,and waitGetPut</dt>
|
|
||||||
<dd>Gets the data for the put part of channelPutGet.</dd>
|
|
||||||
<dt>getPutData</dt>
|
|
||||||
<dd>
|
|
||||||
Returns the PvaData for the put part of channelPutGet.
|
|
||||||
</dd>
|
|
||||||
<dt>getGetData</dt>
|
|
||||||
<dd>
|
|
||||||
Returns the PvaData for the get part of channelPutGet.
|
|
||||||
</dd>
|
|
||||||
</dl>
|
|
||||||
<p>Look at javaDoc for details.</p>
|
|
||||||
|
|
||||||
<h2>PvaMultiChannel - Wrapper For Multiple Channels</h2>
|
|
||||||
<h3>PvaMultiChannel</h3>
|
|
||||||
<p>This provides methods for connecting to multiple channels.
|
|
||||||
A client can either use PvaMultiChannel directly or use PvaMultiDouble or PvaNTMultiChannel.
|
|
||||||
But both impose restrictions on what can be accessed.
|
|
||||||
</p>
|
|
||||||
<h3>PvaMultiDouble</h3>
|
|
||||||
<p>This provides support for gets and puts to the value field of multiple channels.
|
|
||||||
Each channel must have a value field that is a numeric scalar.
|
|
||||||
The client always sees the data as a PVDoubleArray.
|
|
||||||
All channels must connect.
|
|
||||||
If any problems occur an exception is thrown.
|
|
||||||
</p>
|
|
||||||
<h3>PvaNTMultiChannel</h3>
|
|
||||||
<p>This provides support for gets and puts to the value field of multiple channels.
|
|
||||||
Each channel must have a value field.
|
|
||||||
The client always sees the data as a NTMultiChannel, which is one
|
|
||||||
of the types provided by normativeTypesCPP.
|
|
||||||
All channels must connect.
|
|
||||||
If any problems occur an exception is thrown.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
</div> <!-- class="contents" -->
|
|
||||||
</body>
|
|
||||||
</html>
|
|
@ -1,202 +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>EPICS pva</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 }
|
|
||||||
body { margin-right: 10% }
|
|
||||||
/*]]>*/</style>
|
|
||||||
|
|
||||||
<!-- Script that generates the Table of Contents -->
|
|
||||||
<script type="text/javascript" src="http://epics-pvdata.sourceforge.net/script/tocgen.js"></script>
|
|
||||||
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
|
|
||||||
<div class="head">
|
|
||||||
<h1>EPICS pva</h1>
|
|
||||||
<!-- Maturity: Working Draft or Request for Comments, or Recommendation, and date. -->
|
|
||||||
<h2 class="nocount">EPICS V4 Working Group, Working Draft,
|
|
||||||
29-May-2015</h2>
|
|
||||||
<dl>
|
|
||||||
<dt>This version:</dt>
|
|
||||||
<dd><a
|
|
||||||
href="pva.html">pva.html
|
|
||||||
</a> </dd>
|
|
||||||
<dt>Latest version:</dt>
|
|
||||||
<dd><a
|
|
||||||
href="pva_20150529.html">pva_20150529.html</a>
|
|
||||||
</dd>
|
|
||||||
<dt>Previous version:</dt>
|
|
||||||
<dd>none</dd>
|
|
||||||
<dt>Editors:</dt>
|
|
||||||
<dd>Marty Kraimer, BNL</dd>
|
|
||||||
<dd>Matej Sekoranja, Cosylab</dd>
|
|
||||||
</dl>
|
|
||||||
|
|
||||||
<h2 class="nocount">Abstract</h2>
|
|
||||||
|
|
||||||
<p>Pva (Pva PVAccess) 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
|
|
||||||
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>
|
|
||||||
|
|
||||||
<p>Specifically, pva provides a synchronous interface for pvAccess, which is the
|
|
||||||
software support for high speed controls network communications used in EPICS version 4.
|
|
||||||
PvAccess provides a callback based interface, which can be hard to use.
|
|
||||||
Pva provides an interface that does not require callbacks even for monitors.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
PvaChannel provides many "convenience" methods to directly get and put
|
|
||||||
scalar and scalarArray data types.
|
|
||||||
Additional methods provide access to the full features of pvAccess.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
PvaMultiChannel provides access to data from multiple channels.
|
|
||||||
It can be used directly by a client or via PvaMultiDouble or PvaNTMultiChannel.
|
|
||||||
PvaMultiDouble allows the client to get and put data to multiple channels.
|
|
||||||
But each channel must have a value field that is a numeric scalar.
|
|
||||||
PvaNTMultiChannel allows the client to get and put data to multiple channels.
|
|
||||||
Each channel must have a value field.
|
|
||||||
The data for the channels is presented via normative type NTMultiChannel.
|
|
||||||
</p>
|
|
||||||
<!-- last para of Abstract is boilerplate reference to EPICS -->
|
|
||||||
<p>For more information about EPICS generally, please refer to the home page of the <a
|
|
||||||
href="http://www.aps.anl.gov/epics/">Experimental Physics and Industrial
|
|
||||||
Control System</a>.</p>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<h2 class="nocount">Status of this Document and of the Pva Software</h2>
|
|
||||||
|
|
||||||
<p>PvaCPP is ready for use.</p>
|
|
||||||
|
|
||||||
</div> <!-- head -->
|
|
||||||
|
|
||||||
<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 />
|
|
||||||
|
|
||||||
<h2>Introduction</h2>
|
|
||||||
|
|
||||||
<p>Pva is a synchronous API for accessing PVData via PVAccess. It provides
|
|
||||||
an interface to many of the features provided by pvData and pvAccess.</p>
|
|
||||||
|
|
||||||
<p>This document describes the layout of the source files in this project.</p>
|
|
||||||
<p>
|
|
||||||
A user overview is available via
|
|
||||||
<a
|
|
||||||
href="./pvaOverview.html">pvaOverview.html
|
|
||||||
</a>
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
Doxygen documentation is available at
|
|
||||||
<a
|
|
||||||
href="./html/index.html">doxygenDoc
|
|
||||||
</a>
|
|
||||||
</p>
|
|
||||||
<h2>Example and Test Database</h2>
|
|
||||||
<p>The examples and tests require that an example pvAccess server is runnimg.
|
|
||||||
This distribution has a file <b>exampleDatabasePva.zip</b>.
|
|
||||||
When unzipped this is used to create an example IOC database.
|
|
||||||
The database has the record used by the examples are tests that come with pvaJava.
|
|
||||||
It uses pvDatabaseCPP to build the database.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
After unzipping the file:
|
|
||||||
</p>
|
|
||||||
<pre>
|
|
||||||
cd configure
|
|
||||||
cp ExampleRELEASE.local RELEASE.local
|
|
||||||
edit RELEASE.local
|
|
||||||
cd ..
|
|
||||||
make
|
|
||||||
cd iocBoot/exampleDatabase
|
|
||||||
../../bin/<arch:>/exampleDatabase st.cmd
|
|
||||||
</pre>
|
|
||||||
<h2>Testing</h2>
|
|
||||||
<p>The tests will fail unless the example database is running.</p>
|
|
||||||
<p>Once it is running:</p>
|
|
||||||
<pre>
|
|
||||||
make runtests
|
|
||||||
</pre>
|
|
||||||
<h2>Examples</h2>
|
|
||||||
<p>Examples are in directory <b>pvaExample/src</b>.
|
|
||||||
An example of how to run them is:</p>
|
|
||||||
<pre>
|
|
||||||
mrk> pwd
|
|
||||||
/home/epicsv4/pvAccessCPP/pvaExample
|
|
||||||
mrk> bin/linux-x86_64/examplePvaGet
|
|
||||||
</pre>
|
|
||||||
<p>The following is a brief description of each example.
|
|
||||||
In order to understand each example it
|
|
||||||
helps to also look at the source for the example.</p>
|
|
||||||
<h2>examplePvaGet</h2>
|
|
||||||
<p>This has a number of examples:</p>
|
|
||||||
<dl>
|
|
||||||
<dt>exampleDouble</dt>
|
|
||||||
<dd>
|
|
||||||
This shows two methods for getting data from a channel that has a numeric
|
|
||||||
scalar value field.
|
|
||||||
</dd>
|
|
||||||
<dt>exampleDoubleArray</dt>
|
|
||||||
<dd>
|
|
||||||
This shows two methods for getting data from a channel that has a
|
|
||||||
double array value field.
|
|
||||||
</dd>
|
|
||||||
<dt>exampleCADouble</dt>
|
|
||||||
<dd>
|
|
||||||
This is like exampleDouble except it uses provider <b>ca</b>.
|
|
||||||
</dd>
|
|
||||||
<dt>exampleCADoubleArray</dt>
|
|
||||||
<dd>
|
|
||||||
This is like exampleDoubleArray except it uses provider <b>ca</b>.
|
|
||||||
</dd>
|
|
||||||
<dt>examplePowerSupply</dt>
|
|
||||||
<dd>
|
|
||||||
This is an example of getting data from a channel that does not
|
|
||||||
have a value field.
|
|
||||||
</dd>
|
|
||||||
</dl>
|
|
||||||
<h2>examplePvaMonitor</h2>
|
|
||||||
<p>This is an example of creating a monitor on a channel.
|
|
||||||
It monitors a channel that models a powerSupply, i. e. it is not a "standard" record.
|
|
||||||
It does not have a value field.
|
|
||||||
</p>
|
|
||||||
<p>After starting the example a change can be made to the powerSupply by issuing:</p>
|
|
||||||
<pre>
|
|
||||||
pvput -r "power.value,voltage.value" examplePowerSupply 6 6
|
|
||||||
</pre>
|
|
||||||
<h2>examplePvaPut</h2>
|
|
||||||
<p>This example gets and puts to channel exampleDouble.</p>
|
|
||||||
<h2>examplePvaProcess</h2>
|
|
||||||
<p>This example makes a process request to channel exampleDouble.</p>
|
|
||||||
<h2>helloWorldPutGet</h2>
|
|
||||||
<p>This is an example of issuing a channelPutGet.</p>
|
|
||||||
<h2>examplePvaMultiDouble</h2>
|
|
||||||
<p>This is an example of issuing gets and puts to multiple channels where each
|
|
||||||
channel has a numeric scalar value field.</p>
|
|
||||||
<h2>examplePvaNTMultiChannel</h2>
|
|
||||||
<p>This is an example of using NDMultiChannel to obtain data from multiple channels.
|
|
||||||
</p>
|
|
||||||
<h2>helloWorldRPC</h2>
|
|
||||||
<p>This is an example of issuing a channelRPC request.
|
|
||||||
It does <b>not</b> use pva.</p>
|
|
||||||
</div> <!-- class="contents" -->
|
|
||||||
</body>
|
|
||||||
</html>
|
|
Binary file not shown.
@ -1,13 +0,0 @@
|
|||||||
# Makefile at top of application tree
|
|
||||||
|
|
||||||
TOP = .
|
|
||||||
include $(TOP)/configure/CONFIG
|
|
||||||
|
|
||||||
DIRS += configure
|
|
||||||
|
|
||||||
DIRS += src
|
|
||||||
src_DEPEND_DIRS = configure
|
|
||||||
|
|
||||||
include $(TOP)/configure/RULES_TOP
|
|
||||||
|
|
||||||
|
|
@ -1,29 +0,0 @@
|
|||||||
# CONFIG - Load build configuration data
|
|
||||||
#
|
|
||||||
# Do not make changes to this file!
|
|
||||||
|
|
||||||
# Allow user to override where the build rules come from
|
|
||||||
RULES = $(EPICS_BASE)
|
|
||||||
|
|
||||||
# RELEASE files point to other application tops
|
|
||||||
include $(TOP)/configure/RELEASE
|
|
||||||
-include $(TOP)/configure/RELEASE.$(EPICS_HOST_ARCH).Common
|
|
||||||
ifdef T_A
|
|
||||||
-include $(TOP)/configure/RELEASE.Common.$(T_A)
|
|
||||||
-include $(TOP)/configure/RELEASE.$(EPICS_HOST_ARCH).$(T_A)
|
|
||||||
endif
|
|
||||||
|
|
||||||
CONFIG = $(RULES)/configure
|
|
||||||
include $(CONFIG)/CONFIG
|
|
||||||
|
|
||||||
# Override the Base definition:
|
|
||||||
INSTALL_LOCATION = $(TOP)
|
|
||||||
|
|
||||||
# CONFIG_SITE files contain other build configuration settings
|
|
||||||
include $(TOP)/configure/CONFIG_SITE
|
|
||||||
-include $(TOP)/configure/CONFIG_SITE.$(EPICS_HOST_ARCH).Common
|
|
||||||
ifdef T_A
|
|
||||||
-include $(TOP)/configure/CONFIG_SITE.Common.$(T_A)
|
|
||||||
-include $(TOP)/configure/CONFIG_SITE.$(EPICS_HOST_ARCH).$(T_A)
|
|
||||||
endif
|
|
||||||
|
|
@ -1,27 +0,0 @@
|
|||||||
# CONFIG_SITE
|
|
||||||
|
|
||||||
# Make any application-specific changes to the EPICS build
|
|
||||||
# configuration variables in this file.
|
|
||||||
#
|
|
||||||
# Host/target specific settings can be specified in files named
|
|
||||||
# CONFIG_SITE.$(EPICS_HOST_ARCH).Common
|
|
||||||
# CONFIG_SITE.Common.$(T_A)
|
|
||||||
# CONFIG_SITE.$(EPICS_HOST_ARCH).$(T_A)
|
|
||||||
|
|
||||||
# CHECK_RELEASE controls the consistency checking of the support
|
|
||||||
# applications pointed to by the RELEASE* files.
|
|
||||||
# Normally CHECK_RELEASE should be set to YES.
|
|
||||||
# Set CHECK_RELEASE to NO to disable checking completely.
|
|
||||||
# Set CHECK_RELEASE to WARN to perform consistency checking but
|
|
||||||
# continue building anyway if conflicts are found.
|
|
||||||
CHECK_RELEASE = WARN
|
|
||||||
|
|
||||||
# To install files into a location other than $(TOP) define
|
|
||||||
# INSTALL_LOCATION here.
|
|
||||||
#INSTALL_LOCATION=</path/name/to/install/top>
|
|
||||||
|
|
||||||
INSTALL_INCLUDE = $(INSTALL_LOCATION)/include/pv
|
|
||||||
USR_INCLUDES += -I $(INSTALL_LOCATION)/include
|
|
||||||
|
|
||||||
-include $(TOP)/../../CONFIG_SITE.local
|
|
||||||
-include $(TOP)/../configure/CONFIG_SITE.local
|
|
@ -1,6 +0,0 @@
|
|||||||
EPICS_BASE=/home/install/epics/base
|
|
||||||
TEMPLATE_TOP=$(EPICS_BASE)/templates/makeBaseApp/top
|
|
||||||
EPICSV4HOME=/home/epicsv4
|
|
||||||
PVCOMMON=${EPICSV4HOME}/pvCommonCPP
|
|
||||||
PVDATA=${EPICSV4HOME}/pvDataCPP
|
|
||||||
PVACCESS=${EPICSV4HOME}/pvAccessCPP
|
|
@ -1,8 +0,0 @@
|
|||||||
TOP=..
|
|
||||||
|
|
||||||
include $(TOP)/configure/CONFIG
|
|
||||||
|
|
||||||
TARGETS = $(CONFIG_TARGETS)
|
|
||||||
CONFIGS += $(subst ../,,$(wildcard $(CONFIG_INSTALLS)))
|
|
||||||
|
|
||||||
include $(TOP)/configure/RULES
|
|
@ -1,41 +0,0 @@
|
|||||||
# pvDatabaseCPP/example RELEASE - Location of external support modules
|
|
||||||
#
|
|
||||||
# IF YOU CHANGE this file or any file it includes you must
|
|
||||||
# subsequently do a "gnumake rebuild" in the application's
|
|
||||||
# top level directory.
|
|
||||||
#
|
|
||||||
# The build process does not check dependencies against files
|
|
||||||
# that are outside this application, thus you should also do a
|
|
||||||
# "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
|
|
||||||
# RELEASE.$(EPICS_HOST_ARCH).Common
|
|
||||||
# RELEASE.Common.$(T_A)
|
|
||||||
# RELEASE.$(EPICS_HOST_ARCH).$(T_A)
|
|
||||||
|
|
||||||
# EPICS V4 Developers: Do not edit the locations in this file!
|
|
||||||
#
|
|
||||||
# Create a file RELEASE.local pointing to your PVASRV, PVACCESS,
|
|
||||||
# PVDATA, PVCOMMON and EPICS_BASE build directories, e.g.
|
|
||||||
# PVASRV = /path/to/epics/pvaSrvCPP
|
|
||||||
# PVACCESS = /path/to/epics/pvAccessCPP
|
|
||||||
# PVDATA = /path/to/epics/pvDataCPP
|
|
||||||
# PVCOMMON = /path/to/epics/pvCommonCPP
|
|
||||||
# EPICS_BASE = /path/to/epics/base
|
|
||||||
|
|
||||||
# If this example is built in a directory under pvDatabaseCPP,
|
|
||||||
# use the following definitions:
|
|
||||||
|
|
||||||
EASYPVA = $(TOP)/..
|
|
||||||
|
|
||||||
-include $(TOP)/../configure/RELEASE.local
|
|
||||||
-include $(TOP)/../../RELEASE.local
|
|
||||||
|
|
||||||
# If you copied this example from pvDatabaseCPP to be built as a
|
|
||||||
# standalone TOP, adjust and use the following definitions:
|
|
||||||
|
|
||||||
#EASYPVA = /path/to/epics/easyPVACPP
|
|
||||||
|
|
||||||
#-include $(TOP)/../RELEASE.local
|
|
||||||
#-include $(TOP)/configure/RELEASE.local
|
|
@ -1,6 +0,0 @@
|
|||||||
# RULES
|
|
||||||
|
|
||||||
include $(CONFIG)/RULES
|
|
||||||
|
|
||||||
# Library should be rebuilt because LIBOBJS may have changed.
|
|
||||||
$(LIBNAME): ../Makefile
|
|
@ -1,2 +0,0 @@
|
|||||||
#RULES.ioc
|
|
||||||
include $(CONFIG)/RULES.ioc
|
|
@ -1,2 +0,0 @@
|
|||||||
#RULES_DIRS
|
|
||||||
include $(CONFIG)/RULES_DIRS
|
|
@ -1,3 +0,0 @@
|
|||||||
#RULES_TOP
|
|
||||||
include $(CONFIG)/RULES_TOP
|
|
||||||
|
|
@ -1,72 +0,0 @@
|
|||||||
TOP=..
|
|
||||||
|
|
||||||
include $(TOP)/configure/CONFIG
|
|
||||||
#----------------------------------------
|
|
||||||
# ADD MACRO DEFINITIONS AFTER THIS LINE
|
|
||||||
|
|
||||||
|
|
||||||
PROD_HOST += examplePvaProcess
|
|
||||||
examplePvaProcess_SRCS += examplePvaProcess.cpp
|
|
||||||
examplePvaProcess_LIBS += pva
|
|
||||||
examplePvaProcess_LIBS += pvAccess
|
|
||||||
examplePvaProcess_LIBS += pvData
|
|
||||||
examplePvaProcess_LIBS += Com
|
|
||||||
|
|
||||||
PROD_HOST += examplePvaGet
|
|
||||||
examplePvaGet_SRCS += examplePvaGet.cpp
|
|
||||||
examplePvaGet_LIBS += pva
|
|
||||||
examplePvaGet_LIBS += pvAccess
|
|
||||||
examplePvaGet_LIBS += pvData
|
|
||||||
examplePvaGet_LIBS += Com
|
|
||||||
|
|
||||||
PROD_HOST += examplePvaPut
|
|
||||||
examplePvaPut_SRCS += examplePvaPut.cpp
|
|
||||||
examplePvaPut_LIBS += pva
|
|
||||||
examplePvaPut_LIBS += pvAccess
|
|
||||||
examplePvaPut_LIBS += pvData
|
|
||||||
examplePvaPut_LIBS += Com
|
|
||||||
|
|
||||||
PROD_HOST += examplePvaMonitor
|
|
||||||
examplePvaMonitor_SRCS += examplePvaMonitor.cpp
|
|
||||||
examplePvaMonitor_LIBS += pva
|
|
||||||
examplePvaMonitor_LIBS += pvAccess
|
|
||||||
examplePvaMonitor_LIBS += pvData
|
|
||||||
examplePvaMonitor_LIBS += Com
|
|
||||||
|
|
||||||
PROD_HOST += examplePvaMultiDouble
|
|
||||||
examplePvaMultiDouble_SRCS += examplePvaMultiDouble.cpp
|
|
||||||
examplePvaMultiDouble_LIBS += pva
|
|
||||||
examplePvaMultiDouble_LIBS += pvAccess
|
|
||||||
examplePvaMultiDouble_LIBS += pvData
|
|
||||||
examplePvaMultiDouble_LIBS += Com
|
|
||||||
|
|
||||||
PROD_HOST += examplePvaNTMultiChannel
|
|
||||||
examplePvaNTMultiChannel_SRCS += examplePvaNTMultiChannel.cpp
|
|
||||||
examplePvaNTMultiChannel_LIBS += pva
|
|
||||||
examplePvaNTMultiChannel_LIBS += pvAccess
|
|
||||||
examplePvaNTMultiChannel_LIBS += nt
|
|
||||||
examplePvaNTMultiChannel_LIBS += pvData
|
|
||||||
examplePvaNTMultiChannel_LIBS += Com
|
|
||||||
|
|
||||||
PROD_HOST += helloWorldRPC
|
|
||||||
helloWorldRPC_SRCS += helloWorldRPC.cpp
|
|
||||||
helloWorldRPC_LIBS += pva
|
|
||||||
helloWorldRPC_LIBS += pvAccess
|
|
||||||
helloWorldRPC_LIBS += nt
|
|
||||||
helloWorldRPC_LIBS += pvData
|
|
||||||
helloWorldRPC_LIBS += Com
|
|
||||||
|
|
||||||
PROD_HOST += helloWorldPutGet
|
|
||||||
helloWorldPutGet_SRCS += helloWorldPutGet.cpp
|
|
||||||
helloWorldPutGet_LIBS += pva
|
|
||||||
helloWorldPutGet_LIBS += pvAccess
|
|
||||||
helloWorldPutGet_LIBS += nt
|
|
||||||
helloWorldPutGet_LIBS += pvData
|
|
||||||
helloWorldPutGet_LIBS += Com
|
|
||||||
|
|
||||||
#===========================
|
|
||||||
|
|
||||||
include $(TOP)/configure/RULES
|
|
||||||
#----------------------------------------
|
|
||||||
# ADD RULES AFTER THIS LINE
|
|
||||||
|
|
@ -1,146 +0,0 @@
|
|||||||
/*examplePvaGet.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
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Author: Marty Kraimer */
|
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
#include <pv/pva.h>
|
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
using namespace epics::pvData;
|
|
||||||
using namespace epics::pvAccess;
|
|
||||||
using namespace epics::pva;
|
|
||||||
|
|
||||||
|
|
||||||
static void exampleDouble(PvaPtr const &pva)
|
|
||||||
{
|
|
||||||
cout << "example double scalar\n";
|
|
||||||
double value;
|
|
||||||
try {
|
|
||||||
cout << "short way\n";
|
|
||||||
value = pva->channel("exampleDouble")->get()->getData()->getDouble();
|
|
||||||
cout << "as double " << value << endl;
|
|
||||||
} catch (std::runtime_error e) {
|
|
||||||
cout << "exception " << e.what() << endl;
|
|
||||||
}
|
|
||||||
cout << "long way\n";
|
|
||||||
PvaChannelPtr pvaChannel = pva->createChannel("exampleDouble");
|
|
||||||
pvaChannel->issueConnect();
|
|
||||||
Status status = pvaChannel->waitConnect(2.0);
|
|
||||||
if(!status.isOK()) {cout << " connect failed\n"; return;}
|
|
||||||
PvaGetPtr pvaGet = pvaChannel->createGet();
|
|
||||||
pvaGet->issueConnect();
|
|
||||||
status = pvaGet->waitConnect();
|
|
||||||
if(!status.isOK()) {cout << " createGet failed\n"; return;}
|
|
||||||
PvaGetDataPtr pvaData = pvaGet->getData();
|
|
||||||
value = pvaData->getDouble();
|
|
||||||
cout << "as double " << value << endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void exampleDoubleArray(PvaPtr const &pva)
|
|
||||||
{
|
|
||||||
cout << "example double array\n";
|
|
||||||
shared_vector<const double> value;
|
|
||||||
try {
|
|
||||||
cout << "short way\n";
|
|
||||||
value = pva->channel("exampleDoubleArray")->get()->getData()->getDoubleArray();
|
|
||||||
cout << "as doubleArray " << value << endl;
|
|
||||||
} catch (std::runtime_error e) {
|
|
||||||
cout << "exception " << e.what() << endl;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
cout << "long way\n";
|
|
||||||
PvaChannelPtr pvaChannel = pva->createChannel("exampleDoubleArray");
|
|
||||||
pvaChannel->connect(2.0);
|
|
||||||
PvaGetPtr pvaGet = pvaChannel->createGet();
|
|
||||||
PvaGetDataPtr pvaData = pvaGet->getData();
|
|
||||||
value = pvaData->getDoubleArray();
|
|
||||||
cout << "as doubleArray " << value << endl;
|
|
||||||
} catch (std::runtime_error e) {
|
|
||||||
cout << "exception " << e.what() << endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void examplePowerSupply(PvaPtr const &pva)
|
|
||||||
{
|
|
||||||
cout << "example powerSupply\n";
|
|
||||||
PVStructurePtr pvStructure;
|
|
||||||
try {
|
|
||||||
cout << "short way\n";
|
|
||||||
pvStructure = pva->channel("examplePowerSupply")->
|
|
||||||
get("field()")->getData()->getPVStructure();
|
|
||||||
cout << pvStructure << endl;
|
|
||||||
} catch (std::runtime_error e) {
|
|
||||||
cout << "exception " << e.what() << endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
static void exampleCADouble(PvaPtr const &pva)
|
|
||||||
{
|
|
||||||
cout << "example double scalar\n";
|
|
||||||
double value;
|
|
||||||
try {
|
|
||||||
cout << "short way\n";
|
|
||||||
value = pva->channel("double00","ca",5.0)->get()->getData()->getDouble();
|
|
||||||
cout << "as double " << value << endl;
|
|
||||||
} catch (std::runtime_error e) {
|
|
||||||
cout << "exception " << e.what() << endl;
|
|
||||||
}
|
|
||||||
cout << "long way\n";
|
|
||||||
PvaChannelPtr pvaChannel = pva->createChannel("double00","ca");
|
|
||||||
pvaChannel->issueConnect();
|
|
||||||
Status status = pvaChannel->waitConnect(2.0);
|
|
||||||
if(!status.isOK()) {cout << " connect failed\n"; return;}
|
|
||||||
PvaGetPtr pvaGet = pvaChannel->createGet();
|
|
||||||
pvaGet->issueConnect();
|
|
||||||
status = pvaGet->waitConnect();
|
|
||||||
if(!status.isOK()) {cout << " createGet failed\n"; return;}
|
|
||||||
PvaGetDataPtr pvaData = pvaGet->getData();
|
|
||||||
value = pvaData->getDouble();
|
|
||||||
cout << "as double " << value << endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void exampleCADoubleArray(PvaPtr const &pva)
|
|
||||||
{
|
|
||||||
cout << "example double array\n";
|
|
||||||
shared_vector<const double> value;
|
|
||||||
try {
|
|
||||||
cout << "short way\n";
|
|
||||||
value = pva->channel("doubleArray","ca",5.0)->get()->getData()->getDoubleArray();
|
|
||||||
cout << "as doubleArray " << value << endl;
|
|
||||||
} catch (std::runtime_error e) {
|
|
||||||
cout << "exception " << e.what() << endl;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
cout << "long way\n";
|
|
||||||
PvaChannelPtr pvaChannel = pva->createChannel("doubleArray","ca");
|
|
||||||
pvaChannel->connect(2.0);
|
|
||||||
PvaGetPtr pvaGet = pvaChannel->createGet();
|
|
||||||
PvaGetDataPtr pvaData = pvaGet->getData();
|
|
||||||
value = pvaData->getDoubleArray();
|
|
||||||
cout << "as doubleArray " << value << endl;
|
|
||||||
} catch (std::runtime_error e) {
|
|
||||||
cout << "exception " << e.what() << endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc,char *argv[])
|
|
||||||
{
|
|
||||||
PvaPtr pva = Pva::create();
|
|
||||||
exampleDouble(pva);
|
|
||||||
exampleDoubleArray(pva);
|
|
||||||
examplePowerSupply(pva);
|
|
||||||
exampleCADouble(pva);
|
|
||||||
exampleCADoubleArray(pva);
|
|
||||||
cout << "done\n";
|
|
||||||
return 0;
|
|
||||||
}
|
|
@ -1,46 +0,0 @@
|
|||||||
/*monitorPowerSupply.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
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Author: Marty Kraimer */
|
|
||||||
|
|
||||||
#include <epicsThread.h>
|
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
#include <pv/pva.h>
|
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
using namespace epics::pvData;
|
|
||||||
using namespace epics::pvAccess;
|
|
||||||
using namespace epics::pva;
|
|
||||||
|
|
||||||
|
|
||||||
static void exampleMonitor(PvaPtr const &pva)
|
|
||||||
{
|
|
||||||
PvaMonitorPtr monitor = pva->channel("examplePowerSupply")->monitor("");
|
|
||||||
PvaMonitorDataPtr pvaData = monitor->getData();
|
|
||||||
while(true) {
|
|
||||||
monitor->waitEvent();
|
|
||||||
cout << "changed\n";
|
|
||||||
pvaData->showChanged(cout);
|
|
||||||
cout << "overrun\n";
|
|
||||||
pvaData->showOverrun(cout);
|
|
||||||
monitor->releaseEvent();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int main(int argc,char *argv[])
|
|
||||||
{
|
|
||||||
PvaPtr pva = Pva::create();
|
|
||||||
exampleMonitor(pva);
|
|
||||||
cout << "done\n";
|
|
||||||
return 0;
|
|
||||||
}
|
|
@ -1,84 +0,0 @@
|
|||||||
/*examplePvaMultiDouble.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
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Author: Marty Kraimer */
|
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
#include <pv/pvaMultiDouble.h>
|
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
using namespace epics::pvData;
|
|
||||||
using namespace epics::pvAccess;
|
|
||||||
using namespace epics::pva;
|
|
||||||
|
|
||||||
|
|
||||||
static void example(PvaPtr const &pva)
|
|
||||||
{
|
|
||||||
cout << "example multiDouble\n";
|
|
||||||
size_t num = 5;
|
|
||||||
shared_vector<string> channelNames(num);
|
|
||||||
channelNames[0] = "exampleDouble01";
|
|
||||||
channelNames[1] = "exampleDouble02";
|
|
||||||
channelNames[2] = "exampleDouble03";
|
|
||||||
channelNames[3] = "exampleDouble04";
|
|
||||||
channelNames[4] = "exampleDouble05";
|
|
||||||
PVStringArrayPtr pvNames =
|
|
||||||
getPVDataCreate()->createPVScalarArray<PVStringArray>();
|
|
||||||
pvNames->replace(freeze(channelNames));
|
|
||||||
PvaMultiDoublePtr multiDouble(PvaMultiDouble::create(pva,pvNames));
|
|
||||||
try {
|
|
||||||
shared_vector<double> data = multiDouble->get();
|
|
||||||
cout << "initial " << data << endl;
|
|
||||||
for(size_t i=0; i<num; ++i) data[i] = data[i] + 1.1;
|
|
||||||
multiDouble->put(data);
|
|
||||||
data = multiDouble->get();
|
|
||||||
cout << "final " << data << endl;
|
|
||||||
} catch (std::runtime_error e) {
|
|
||||||
cout << "exception " << e.what() << endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
static void exampleCA(PvaPtr const &pva)
|
|
||||||
{
|
|
||||||
cout << "example multiDouble\n";
|
|
||||||
size_t num = 5;
|
|
||||||
shared_vector<string> channelNames(num);
|
|
||||||
channelNames[0] = "double01";
|
|
||||||
channelNames[1] = "double02";
|
|
||||||
channelNames[2] = "double03";
|
|
||||||
channelNames[3] = "double04";
|
|
||||||
channelNames[4] = "double05";
|
|
||||||
PVStringArrayPtr pvNames =
|
|
||||||
getPVDataCreate()->createPVScalarArray<PVStringArray>();
|
|
||||||
pvNames->replace(freeze(channelNames));
|
|
||||||
PvaMultiDoublePtr multiDouble(PvaMultiDouble::create(pva,pvNames,5.0,"ca"));
|
|
||||||
try {
|
|
||||||
shared_vector<double> data = multiDouble->get();
|
|
||||||
cout << "initial " << data << endl;
|
|
||||||
for(size_t i=0; i<num; ++i) data[i] = data[i] + 1.1;
|
|
||||||
multiDouble->put(data);
|
|
||||||
data = multiDouble->get();
|
|
||||||
cout << "final " << data << endl;
|
|
||||||
} catch (std::runtime_error e) {
|
|
||||||
cout << "exception " << e.what() << endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int main(int argc,char *argv[])
|
|
||||||
{
|
|
||||||
PvaPtr pva = Pva::create();
|
|
||||||
example(pva);
|
|
||||||
exampleCA(pva);
|
|
||||||
return 0;
|
|
||||||
}
|
|
@ -1,101 +0,0 @@
|
|||||||
/*examplePvaNTMultiChannel.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
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Author: Marty Kraimer */
|
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
#include <pv/pvaNTMultiChannel.h>
|
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
using namespace epics::pvData;
|
|
||||||
using namespace epics::pvAccess;
|
|
||||||
using namespace epics::pva;
|
|
||||||
using namespace epics::nt;
|
|
||||||
|
|
||||||
|
|
||||||
static void example(PvaPtr const &pva)
|
|
||||||
{
|
|
||||||
cout << "example ntMultiChannel\n";
|
|
||||||
size_t num = 5;
|
|
||||||
shared_vector<string> channelNames(num);
|
|
||||||
channelNames[0] = "exampleDouble";
|
|
||||||
channelNames[1] = "exampleDoubleArray";
|
|
||||||
channelNames[2] = "exampleString";
|
|
||||||
channelNames[3] = "exampleBoolean";
|
|
||||||
channelNames[4] = "exampleEnum";
|
|
||||||
PVStringArrayPtr pvNames =
|
|
||||||
getPVDataCreate()->createPVScalarArray<PVStringArray>();
|
|
||||||
pvNames->replace(freeze(channelNames));
|
|
||||||
NTMultiChannelBuilderPtr builder = NTMultiChannel::createBuilder();
|
|
||||||
StructureConstPtr structure = builder->
|
|
||||||
addTimeStamp()->
|
|
||||||
addSeverity() ->
|
|
||||||
addStatus() ->
|
|
||||||
addMessage() ->
|
|
||||||
addSecondsPastEpoch() ->
|
|
||||||
addNanoseconds() ->
|
|
||||||
addUserTag() ->
|
|
||||||
createStructure();
|
|
||||||
PvaNTMultiChannelPtr multi = PvaNTMultiChannel::create(
|
|
||||||
pva,pvNames,structure);
|
|
||||||
try {
|
|
||||||
NTMultiChannelPtr nt = multi->get();
|
|
||||||
cout << "initial\n" << nt->getPVStructure() << endl;
|
|
||||||
|
|
||||||
} catch (std::runtime_error e) {
|
|
||||||
cout << "exception " << e.what() << endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
static void exampleCA(PvaPtr const &pva)
|
|
||||||
{
|
|
||||||
cout << "example ntMultiChannel\n";
|
|
||||||
size_t num = 5;
|
|
||||||
shared_vector<string> channelNames(num);
|
|
||||||
channelNames[0] = "double00";
|
|
||||||
channelNames[1] = "doubleArray";
|
|
||||||
channelNames[2] = "string00";
|
|
||||||
channelNames[3] = "mbbiwierd";
|
|
||||||
channelNames[4] = "enum01";
|
|
||||||
PVStringArrayPtr pvNames =
|
|
||||||
getPVDataCreate()->createPVScalarArray<PVStringArray>();
|
|
||||||
pvNames->replace(freeze(channelNames));
|
|
||||||
NTMultiChannelBuilderPtr builder = NTMultiChannel::createBuilder();
|
|
||||||
StructureConstPtr structure = builder->
|
|
||||||
addTimeStamp()->
|
|
||||||
addSeverity() ->
|
|
||||||
addStatus() ->
|
|
||||||
addMessage() ->
|
|
||||||
addSecondsPastEpoch() ->
|
|
||||||
addNanoseconds() ->
|
|
||||||
addUserTag() ->
|
|
||||||
createStructure();
|
|
||||||
PvaNTMultiChannelPtr multi = PvaNTMultiChannel::create(
|
|
||||||
pva,pvNames,structure,5.0,"ca");
|
|
||||||
try {
|
|
||||||
NTMultiChannelPtr nt = multi->get();
|
|
||||||
cout << "initial\n" << nt->getPVStructure() << endl;
|
|
||||||
|
|
||||||
} catch (std::runtime_error e) {
|
|
||||||
cout << "exception " << e.what() << endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int main(int argc,char *argv[])
|
|
||||||
{
|
|
||||||
PvaPtr pva = Pva::create();
|
|
||||||
example(pva);
|
|
||||||
exampleCA(pva);
|
|
||||||
return 0;
|
|
||||||
}
|
|
@ -1,44 +0,0 @@
|
|||||||
/*examplePvaProcess.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
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Author: Marty Kraimer */
|
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
#include <pv/pva.h>
|
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
using namespace epics::pvData;
|
|
||||||
using namespace epics::pvAccess;
|
|
||||||
using namespace epics::pva;
|
|
||||||
|
|
||||||
|
|
||||||
static void exampleProcess(PvaPtr const &pva)
|
|
||||||
{
|
|
||||||
cout << "example process\n";
|
|
||||||
PvaChannelPtr channel = pva->channel("exampleDouble");
|
|
||||||
PvaProcessPtr process = channel->createProcess();
|
|
||||||
try {
|
|
||||||
process->process();
|
|
||||||
cout << channel->get("field()")->getData()->showChanged(cout) << endl;
|
|
||||||
process->process();
|
|
||||||
cout << channel->get("field()")->getData()->showChanged(cout) << endl;
|
|
||||||
} catch (std::runtime_error e) {
|
|
||||||
cout << "exception " << e.what() << endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int main(int argc,char *argv[])
|
|
||||||
{
|
|
||||||
PvaPtr pva = Pva::create();
|
|
||||||
exampleProcess(pva);
|
|
||||||
return 0;
|
|
||||||
}
|
|
@ -1,45 +0,0 @@
|
|||||||
/*examplePvaPut.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
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Author: Marty Kraimer */
|
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
#include <pv/pva.h>
|
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
using namespace epics::pvData;
|
|
||||||
using namespace epics::pvAccess;
|
|
||||||
using namespace epics::pva;
|
|
||||||
|
|
||||||
|
|
||||||
static void examplePut(PvaPtr const &pva)
|
|
||||||
{
|
|
||||||
cout << "example put\n";
|
|
||||||
PvaChannelPtr channel = pva->channel("exampleDouble");
|
|
||||||
PvaPutPtr put = channel->put();
|
|
||||||
PvaPutDataPtr putData = put->getData();
|
|
||||||
try {
|
|
||||||
putData->putDouble(3.0); put->put();
|
|
||||||
cout << channel->get("field()")->getData()->showChanged(cout) << endl;
|
|
||||||
putData->putDouble(4.0); put->put();
|
|
||||||
cout << channel->get("field()")->getData()->showChanged(cout) << endl;
|
|
||||||
} catch (std::runtime_error e) {
|
|
||||||
cout << "exception " << e.what() << endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int main(int argc,char *argv[])
|
|
||||||
{
|
|
||||||
PvaPtr pva = Pva::create();
|
|
||||||
examplePut(pva);
|
|
||||||
return 0;
|
|
||||||
}
|
|
@ -1,48 +0,0 @@
|
|||||||
/*helloWorldPutGet.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
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Author: Marty Kraimer */
|
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
#include <pv/pva.h>
|
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
using namespace epics::pvData;
|
|
||||||
using namespace epics::pvAccess;
|
|
||||||
using namespace epics::pva;
|
|
||||||
|
|
||||||
|
|
||||||
static void example(PvaPtr const &pva)
|
|
||||||
{
|
|
||||||
cout << "helloWorldPutGet\n";
|
|
||||||
try {
|
|
||||||
PvaChannelPtr channel = pva->channel("exampleHello");
|
|
||||||
PvaPutGetPtr putGet = channel->createPutGet();
|
|
||||||
putGet->connect();
|
|
||||||
PvaPutDataPtr putData = putGet->getPutData();
|
|
||||||
PVStructurePtr arg = putData->getPVStructure();
|
|
||||||
PVStringPtr pvValue = arg->getSubField<PVString>("argument.value");
|
|
||||||
pvValue->put("World");
|
|
||||||
putGet->putGet();
|
|
||||||
PvaGetDataPtr getData = putGet->getGetData();
|
|
||||||
cout << getData->getPVStructure() << endl;
|
|
||||||
} catch (std::runtime_error e) {
|
|
||||||
cout << "exception " << e.what() << endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int main(int argc,char *argv[])
|
|
||||||
{
|
|
||||||
PvaPtr pva = Pva::create();
|
|
||||||
example(pva);
|
|
||||||
return 0;
|
|
||||||
}
|
|
@ -1,77 +0,0 @@
|
|||||||
/*exampleChannelRPC.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
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Author: Marty Kraimer */
|
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
#include <pv/pvData.h>
|
|
||||||
#include <pv/pvAccess.h>
|
|
||||||
#include <pv/rpcClient.h>
|
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
using namespace epics::pvData;
|
|
||||||
using namespace epics::pvAccess;
|
|
||||||
|
|
||||||
static FieldCreatePtr fieldCreate = getFieldCreate();
|
|
||||||
static PVDataCreatePtr pvDataCreate = getPVDataCreate();
|
|
||||||
|
|
||||||
|
|
||||||
static void exampleSimple()
|
|
||||||
{
|
|
||||||
StructureConstPtr topStructure = fieldCreate->createFieldBuilder()->
|
|
||||||
add("value",pvString)->
|
|
||||||
createStructure();
|
|
||||||
PVStructurePtr pvRequest = pvDataCreate->createPVStructure(topStructure);
|
|
||||||
PVStringPtr pvArgument = pvRequest->getSubField<PVString>("value");
|
|
||||||
pvArgument->put("World");
|
|
||||||
cout << "example channeRPC simple\n";
|
|
||||||
try {
|
|
||||||
PVStructurePtr pvResult =
|
|
||||||
RPCClient::sendRequest("exampleHelloRPC", pvRequest);
|
|
||||||
cout << "result\n" << pvResult << endl;
|
|
||||||
} catch (RPCRequestException &e) {
|
|
||||||
cout << e.what() << endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void exampleMore()
|
|
||||||
{
|
|
||||||
StructureConstPtr topStructure = fieldCreate->createFieldBuilder()->
|
|
||||||
add("value",pvString)->
|
|
||||||
createStructure();
|
|
||||||
PVStructurePtr pvRequest = pvDataCreate->createPVStructure(topStructure);
|
|
||||||
PVStringPtr pvArgument = pvRequest->getSubField<PVString>("value");
|
|
||||||
pvArgument->put("World");
|
|
||||||
cout << "example channeRPC more\n";
|
|
||||||
try {
|
|
||||||
RPCClient::shared_pointer client = RPCClient::create("exampleHelloRPC");
|
|
||||||
client->issueConnect();
|
|
||||||
if (client->waitConnect())
|
|
||||||
{
|
|
||||||
client->issueRequest(pvRequest);
|
|
||||||
PVStructure::shared_pointer result = client->waitResponse();
|
|
||||||
std::cout << *result << std::endl;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
cout << "waitConnect timeout\n";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} catch (RPCRequestException &e) {
|
|
||||||
cout << e.what() << endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int main(int argc,char *argv[])
|
|
||||||
{
|
|
||||||
exampleSimple();
|
|
||||||
exampleMore();
|
|
||||||
return 0;
|
|
||||||
}
|
|
@ -1,34 +0,0 @@
|
|||||||
# This is a Makefile fragment, see ../Makefile
|
|
||||||
|
|
||||||
TOP = ..
|
|
||||||
include $(TOP)/configure/CONFIG
|
|
||||||
|
|
||||||
INSTALL_INCLUDE = $(INSTALL_LOCATION)/include/pv
|
|
||||||
USR_INCLUDES += -I$(INSTALL_LOCATION)/include
|
|
||||||
|
|
||||||
LIBRARY += pva
|
|
||||||
|
|
||||||
INC += pva.h
|
|
||||||
INC += pvaMultiDouble.h
|
|
||||||
INC += pvaNTMultiChannel.h
|
|
||||||
|
|
||||||
LIBSRCS += pva.cpp
|
|
||||||
LIBSRCS += pvaPutData.cpp
|
|
||||||
LIBSRCS += pvaGetData.cpp
|
|
||||||
LIBSRCS += pvaMonitorData.cpp
|
|
||||||
LIBSRCS += pvaChannel.cpp
|
|
||||||
LIBSRCS += pvaProcess.cpp
|
|
||||||
LIBSRCS += pvaGet.cpp
|
|
||||||
LIBSRCS += pvaPut.cpp
|
|
||||||
LIBSRCS += pvaMonitor.cpp
|
|
||||||
LIBSRCS += pvaPutGet.cpp
|
|
||||||
LIBSRCS += pvaMultiChannel.cpp
|
|
||||||
LIBSRCS += pvaMultiDouble.cpp
|
|
||||||
LIBSRCS += pvaNTMultiChannel.cpp
|
|
||||||
#LIBSRCS += pvaRPC.cpp
|
|
||||||
|
|
||||||
pva_LIBS += pvAccess pvData nt Com
|
|
||||||
pva_LIBS += $(EPICS_BASE_IOC_LIBS)
|
|
||||||
|
|
||||||
include $(TOP)/configure/RULES
|
|
||||||
|
|
199
pvaSrc/pva.cpp
199
pvaSrc/pva.cpp
@ -1,199 +0,0 @@
|
|||||||
/* pva.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 2015.02
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define epicsExportSharedSymbols
|
|
||||||
#include <map>
|
|
||||||
#include <pv/pva.h>
|
|
||||||
#include <pv/createRequest.h>
|
|
||||||
#include <pv/clientFactory.h>
|
|
||||||
#include <pv/caProvider.h>
|
|
||||||
|
|
||||||
using std::tr1::static_pointer_cast;
|
|
||||||
using namespace epics::pvData;
|
|
||||||
using namespace epics::pvAccess;
|
|
||||||
using namespace epics::pvAccess::ca;
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
namespace epics { namespace pva {
|
|
||||||
|
|
||||||
static FieldCreatePtr fieldCreate = getFieldCreate();
|
|
||||||
static const string pvaName = "pva";
|
|
||||||
static const string defaultProvider = "pva";
|
|
||||||
static UnionConstPtr variantUnion = fieldCreate->createVariantUnion();
|
|
||||||
|
|
||||||
namespace pvaPvt {
|
|
||||||
|
|
||||||
static size_t numberPva = 0;
|
|
||||||
static bool firstTime = true;
|
|
||||||
static Mutex mutex;
|
|
||||||
|
|
||||||
class StartStopClientFactory {
|
|
||||||
public:
|
|
||||||
static void PvaBeingConstructed()
|
|
||||||
{
|
|
||||||
bool saveFirst = false;
|
|
||||||
{
|
|
||||||
Lock xx(mutex);
|
|
||||||
++numberPva;
|
|
||||||
saveFirst = firstTime;
|
|
||||||
firstTime = false;
|
|
||||||
}
|
|
||||||
if(saveFirst) {
|
|
||||||
ClientFactory::start();
|
|
||||||
CAClientFactory::start();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void PvaBeingDestroyed() {
|
|
||||||
size_t numLeft = 0;
|
|
||||||
{
|
|
||||||
Lock xx(mutex);
|
|
||||||
--numberPva;
|
|
||||||
numLeft = numberPva;
|
|
||||||
}
|
|
||||||
if(numLeft<=0) {
|
|
||||||
ClientFactory::stop();
|
|
||||||
CAClientFactory::stop();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace pvaPvt
|
|
||||||
|
|
||||||
class PvaChannelCache
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
PvaChannelCache(){}
|
|
||||||
~PvaChannelCache(){
|
|
||||||
destroy();
|
|
||||||
}
|
|
||||||
void destroy() {
|
|
||||||
pvaChannelMap.clear();
|
|
||||||
}
|
|
||||||
PvaChannelPtr getChannel(string const & channelName);
|
|
||||||
void addChannel(PvaChannelPtr const & pvaChannel);
|
|
||||||
void removeChannel(string const & channelName);
|
|
||||||
private:
|
|
||||||
map<string,PvaChannelPtr> pvaChannelMap;
|
|
||||||
};
|
|
||||||
|
|
||||||
PvaChannelPtr PvaChannelCache::getChannel(string const & channelName)
|
|
||||||
{
|
|
||||||
map<string,PvaChannelPtr>::iterator iter = pvaChannelMap.find(channelName);
|
|
||||||
if(iter!=pvaChannelMap.end()) return iter->second;
|
|
||||||
return PvaChannelPtr();
|
|
||||||
}
|
|
||||||
|
|
||||||
void PvaChannelCache::addChannel(PvaChannelPtr const & pvaChannel)
|
|
||||||
{
|
|
||||||
pvaChannelMap.insert(std::pair<string,PvaChannelPtr>(
|
|
||||||
pvaChannel->getChannelName(),pvaChannel));
|
|
||||||
}
|
|
||||||
|
|
||||||
void PvaChannelCache::removeChannel(string const & channelName)
|
|
||||||
{
|
|
||||||
map<string,PvaChannelPtr>::iterator iter = pvaChannelMap.find(channelName);
|
|
||||||
if(iter!=pvaChannelMap.end()) pvaChannelMap.erase(iter);
|
|
||||||
}
|
|
||||||
|
|
||||||
using namespace epics::pva::pvaPvt;
|
|
||||||
|
|
||||||
PvaPtr Pva::create()
|
|
||||||
{
|
|
||||||
PvaPtr xx(new Pva());
|
|
||||||
StartStopClientFactory::PvaBeingConstructed();
|
|
||||||
return xx;
|
|
||||||
}
|
|
||||||
|
|
||||||
PVStructurePtr Pva::createRequest(string const &request)
|
|
||||||
{
|
|
||||||
CreateRequest::shared_pointer createRequest = CreateRequest::create();
|
|
||||||
PVStructurePtr pvRequest = createRequest->createRequest(request);
|
|
||||||
if(!pvRequest) {
|
|
||||||
throw std::invalid_argument("invalid pvRequest: " + createRequest->getMessage());
|
|
||||||
}
|
|
||||||
return pvRequest;
|
|
||||||
}
|
|
||||||
|
|
||||||
Pva::Pva()
|
|
||||||
: pvaChannelCache(new PvaChannelCache()),
|
|
||||||
isDestroyed(false)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
Pva::~Pva() {
|
|
||||||
destroy();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Pva::destroy()
|
|
||||||
{
|
|
||||||
{
|
|
||||||
Lock xx(mutex);
|
|
||||||
if(isDestroyed) return;
|
|
||||||
isDestroyed = true;
|
|
||||||
}
|
|
||||||
pvaChannelCache.reset();
|
|
||||||
channelList.clear();
|
|
||||||
multiChannelList.clear();
|
|
||||||
StartStopClientFactory::PvaBeingDestroyed();
|
|
||||||
}
|
|
||||||
|
|
||||||
string Pva:: getRequesterName()
|
|
||||||
{
|
|
||||||
static string name("pva");
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Pva::message(
|
|
||||||
string const & message,
|
|
||||||
MessageType messageType)
|
|
||||||
{
|
|
||||||
cout << getMessageTypeName(messageType) << " " << message << endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
PvaChannelPtr Pva::channel(
|
|
||||||
std::string const & channelName,
|
|
||||||
std::string const & providerName,
|
|
||||||
double timeOut)
|
|
||||||
{
|
|
||||||
PvaChannelPtr pvaChannel = pvaChannelCache->getChannel(channelName);
|
|
||||||
if(pvaChannel) return pvaChannel;
|
|
||||||
pvaChannel = createChannel(channelName,providerName);
|
|
||||||
pvaChannel->connect(timeOut);
|
|
||||||
pvaChannelCache->addChannel(pvaChannel);
|
|
||||||
return pvaChannel;
|
|
||||||
}
|
|
||||||
|
|
||||||
PvaChannelPtr Pva::createChannel(string const & channelName)
|
|
||||||
{
|
|
||||||
return PvaChannel::create(getPtrSelf(),channelName);
|
|
||||||
}
|
|
||||||
|
|
||||||
PvaChannelPtr Pva::createChannel(string const & channelName, string const & providerName)
|
|
||||||
{
|
|
||||||
return PvaChannel::create(getPtrSelf(),channelName,providerName);
|
|
||||||
}
|
|
||||||
|
|
||||||
PvaMultiChannelPtr Pva::createMultiChannel(
|
|
||||||
epics::pvData::PVStringArrayPtr const & channelNames)
|
|
||||||
{
|
|
||||||
return createMultiChannel(channelNames,"pva");
|
|
||||||
}
|
|
||||||
|
|
||||||
PvaMultiChannelPtr Pva::createMultiChannel(
|
|
||||||
epics::pvData::PVStringArrayPtr const & channelNames,
|
|
||||||
std::string const & providerName)
|
|
||||||
{
|
|
||||||
return PvaMultiChannel::create(getPtrSelf(),channelNames,providerName);
|
|
||||||
}
|
|
||||||
|
|
||||||
}}
|
|
||||||
|
|
1662
pvaSrc/pva.h
1662
pvaSrc/pva.h
File diff suppressed because it is too large
Load Diff
@ -1,495 +0,0 @@
|
|||||||
/* pvaChannel.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 2015.02
|
|
||||||
*/
|
|
||||||
#define epicsExportSharedSymbols
|
|
||||||
|
|
||||||
#include <map>
|
|
||||||
#include <sstream>
|
|
||||||
#include <pv/event.h>
|
|
||||||
#include <pv/lock.h>
|
|
||||||
#include <pv/pva.h>
|
|
||||||
#include <pv/createRequest.h>
|
|
||||||
|
|
||||||
|
|
||||||
using std::tr1::static_pointer_cast;
|
|
||||||
using namespace epics::pvData;
|
|
||||||
using namespace epics::pvAccess;
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
namespace epics { namespace pva {
|
|
||||||
|
|
||||||
|
|
||||||
class PvaGetCache
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
PvaGetCache(){}
|
|
||||||
~PvaGetCache();
|
|
||||||
void destroy() {
|
|
||||||
pvaGetMap.clear();
|
|
||||||
}
|
|
||||||
PvaGetPtr getGet(string const & request);
|
|
||||||
void addGet(string const & request,PvaGetPtr const & pvaGet);
|
|
||||||
private:
|
|
||||||
map<string,PvaGetPtr> pvaGetMap;
|
|
||||||
};
|
|
||||||
|
|
||||||
PvaGetCache::~PvaGetCache()
|
|
||||||
{
|
|
||||||
destroy();
|
|
||||||
}
|
|
||||||
|
|
||||||
PvaGetPtr PvaGetCache::getGet(string const & request)
|
|
||||||
{
|
|
||||||
map<string,PvaGetPtr>::iterator iter = pvaGetMap.find(request);
|
|
||||||
if(iter!=pvaGetMap.end()) return iter->second;
|
|
||||||
return PvaGetPtr();
|
|
||||||
}
|
|
||||||
|
|
||||||
void PvaGetCache::addGet(string const & request,PvaGetPtr const & pvaGet)
|
|
||||||
{
|
|
||||||
pvaGetMap.insert(std::pair<string,PvaGetPtr>(
|
|
||||||
request,pvaGet));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class PvaPutCache
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
PvaPutCache(){}
|
|
||||||
~PvaPutCache();
|
|
||||||
void destroy() {
|
|
||||||
pvaPutMap.clear();
|
|
||||||
}
|
|
||||||
PvaPutPtr getPut(string const & request);
|
|
||||||
void addPut(string const & request,PvaPutPtr const & pvaPut);
|
|
||||||
private:
|
|
||||||
map<string,PvaPutPtr> pvaPutMap;
|
|
||||||
};
|
|
||||||
|
|
||||||
PvaPutCache::~PvaPutCache()
|
|
||||||
{
|
|
||||||
destroy();
|
|
||||||
}
|
|
||||||
|
|
||||||
PvaPutPtr PvaPutCache::getPut(string const & request)
|
|
||||||
{
|
|
||||||
map<string,PvaPutPtr>::iterator iter = pvaPutMap.find(request);
|
|
||||||
if(iter!=pvaPutMap.end()) return iter->second;
|
|
||||||
return PvaPutPtr();
|
|
||||||
}
|
|
||||||
|
|
||||||
void PvaPutCache::addPut(string const & request,PvaPutPtr const & pvaPut)
|
|
||||||
{
|
|
||||||
pvaPutMap.insert(std::pair<string,PvaPutPtr>(
|
|
||||||
request,pvaPut));
|
|
||||||
}
|
|
||||||
|
|
||||||
class ChannelRequesterImpl : public ChannelRequester
|
|
||||||
{
|
|
||||||
PvaChannel *pvaChannel;
|
|
||||||
public:
|
|
||||||
ChannelRequesterImpl(PvaChannel *pvaChannel)
|
|
||||||
: pvaChannel(pvaChannel) {}
|
|
||||||
void channelCreated(
|
|
||||||
const Status& status,
|
|
||||||
Channel::shared_pointer const & channel)
|
|
||||||
{ pvaChannel->channelCreated(status,channel); }
|
|
||||||
void channelStateChange(
|
|
||||||
Channel::shared_pointer const & channel,
|
|
||||||
Channel::ConnectionState connectionState)
|
|
||||||
{pvaChannel->channelStateChange(channel,connectionState);}
|
|
||||||
tr1::shared_ptr<Channel> getChannel() {return pvaChannel->getChannel();}
|
|
||||||
string getRequesterName()
|
|
||||||
{return pvaChannel->getRequesterName();}
|
|
||||||
void message(
|
|
||||||
string const & message,
|
|
||||||
MessageType messageType)
|
|
||||||
{ pvaChannel->message(message,messageType); }
|
|
||||||
void destroy() {pvaChannel->destroy();}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
PvaChannel::PvaChannel(
|
|
||||||
PvaPtr const &pva,
|
|
||||||
string const & channelName,
|
|
||||||
string const & providerName)
|
|
||||||
: pva(pva),
|
|
||||||
channelName(channelName),
|
|
||||||
providerName(providerName),
|
|
||||||
connectState(connectIdle),
|
|
||||||
isDestroyed(false),
|
|
||||||
createRequest(CreateRequest::create()),
|
|
||||||
pvaGetCache(new PvaGetCache()),
|
|
||||||
pvaPutCache(new PvaPutCache())
|
|
||||||
{}
|
|
||||||
|
|
||||||
PvaChannel::~PvaChannel()
|
|
||||||
{
|
|
||||||
destroy();
|
|
||||||
}
|
|
||||||
|
|
||||||
void PvaChannel::channelCreated(const Status& status, Channel::shared_pointer const & channel)
|
|
||||||
{
|
|
||||||
if(isDestroyed) throw std::runtime_error("pvaChannel was destroyed");
|
|
||||||
if(status.isOK()) {
|
|
||||||
this->channel = channel;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
cout << "PvaChannel::channelCreated status " << status.getMessage() << " why??\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
void PvaChannel::channelStateChange(
|
|
||||||
Channel::shared_pointer const & channel,
|
|
||||||
Channel::ConnectionState connectionState)
|
|
||||||
{
|
|
||||||
if(isDestroyed) return;
|
|
||||||
bool waitingForConnect = false;
|
|
||||||
if(connectState==connectActive) waitingForConnect = true;
|
|
||||||
if(connectionState!=Channel::CONNECTED) {
|
|
||||||
string mess(channelName +
|
|
||||||
" connection state " + Channel::ConnectionStateNames[connectionState]);
|
|
||||||
message(mess,errorMessage);
|
|
||||||
channelConnectStatus = Status(Status::STATUSTYPE_ERROR,mess);
|
|
||||||
connectState = notConnected;
|
|
||||||
} else {
|
|
||||||
connectState = connected;
|
|
||||||
}
|
|
||||||
if(waitingForConnect) waitForConnect.signal();
|
|
||||||
}
|
|
||||||
|
|
||||||
string PvaChannel::getRequesterName()
|
|
||||||
{
|
|
||||||
PvaPtr yyy = pva.lock();
|
|
||||||
if(!yyy) throw std::runtime_error("Pva was destroyed");
|
|
||||||
return yyy->getRequesterName();
|
|
||||||
}
|
|
||||||
|
|
||||||
void PvaChannel::message(
|
|
||||||
string const & message,
|
|
||||||
MessageType messageType)
|
|
||||||
{
|
|
||||||
if(isDestroyed) throw std::runtime_error("pvaChannel was destroyed");
|
|
||||||
PvaPtr yyy = pva.lock();
|
|
||||||
if(!yyy) throw std::runtime_error("Pva was destroyed");
|
|
||||||
yyy->message(message, messageType);
|
|
||||||
}
|
|
||||||
|
|
||||||
void PvaChannel::destroy()
|
|
||||||
{
|
|
||||||
{
|
|
||||||
Lock xx(mutex);
|
|
||||||
if(isDestroyed) return;
|
|
||||||
isDestroyed = true;
|
|
||||||
}
|
|
||||||
if(channel) channel->destroy();
|
|
||||||
channel.reset();
|
|
||||||
pvaGetCache.reset();
|
|
||||||
pvaPutCache.reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
string PvaChannel::getChannelName()
|
|
||||||
{
|
|
||||||
if(isDestroyed) throw std::runtime_error("pvaChannel was destroyed");
|
|
||||||
return channelName;
|
|
||||||
}
|
|
||||||
|
|
||||||
Channel::shared_pointer PvaChannel::getChannel()
|
|
||||||
{
|
|
||||||
if(isDestroyed) throw std::runtime_error("pvaChannel was destroyed");
|
|
||||||
return channel;
|
|
||||||
}
|
|
||||||
|
|
||||||
void PvaChannel::connect(double timeout)
|
|
||||||
{
|
|
||||||
if(isDestroyed) throw std::runtime_error("pvaChannel was destroyed");
|
|
||||||
issueConnect();
|
|
||||||
Status status = waitConnect(timeout);
|
|
||||||
if(status.isOK()) return;
|
|
||||||
stringstream ss;
|
|
||||||
ss << "channel " << getChannelName() << " PvaChannel::connect " << status.getMessage();
|
|
||||||
throw std::runtime_error(ss.str());
|
|
||||||
}
|
|
||||||
|
|
||||||
void PvaChannel::issueConnect()
|
|
||||||
{
|
|
||||||
if(isDestroyed) throw std::runtime_error("pvaChannel was destroyed");
|
|
||||||
if(connectState!=connectIdle) {
|
|
||||||
throw std::runtime_error("pvaChannel already connected");
|
|
||||||
}
|
|
||||||
channelRequester = ChannelRequester::shared_pointer(new ChannelRequesterImpl(this));
|
|
||||||
|
|
||||||
channelConnectStatus = Status(
|
|
||||||
Status::STATUSTYPE_ERROR,
|
|
||||||
getChannelName() + " createChannel failed");
|
|
||||||
connectState = connectActive;
|
|
||||||
ChannelProviderRegistry::shared_pointer reg = getChannelProviderRegistry();
|
|
||||||
ChannelProvider::shared_pointer provider = reg->getProvider(providerName);
|
|
||||||
if(!provider) {
|
|
||||||
throw std::runtime_error(getChannelName() + " provider " + providerName + " not registered");
|
|
||||||
}
|
|
||||||
channel = provider->createChannel(channelName,channelRequester,ChannelProvider::PRIORITY_DEFAULT);
|
|
||||||
if(!channel) {
|
|
||||||
throw std::runtime_error(channelConnectStatus.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Status PvaChannel::waitConnect(double timeout)
|
|
||||||
{
|
|
||||||
if(isDestroyed) throw std::runtime_error("pvaChannel was destroyed");
|
|
||||||
waitForConnect.wait(timeout);
|
|
||||||
if(connectState==connected) return Status::Ok;
|
|
||||||
return Status(Status::STATUSTYPE_ERROR,channelConnectStatus.getMessage());
|
|
||||||
}
|
|
||||||
|
|
||||||
PvaFieldPtr PvaChannel::createField()
|
|
||||||
{
|
|
||||||
return createField("");
|
|
||||||
}
|
|
||||||
|
|
||||||
PvaFieldPtr PvaChannel::createField(string const & subField)
|
|
||||||
{
|
|
||||||
throw std::runtime_error("PvaChannel::createField not implemented");
|
|
||||||
}
|
|
||||||
|
|
||||||
PvaProcessPtr PvaChannel::createProcess()
|
|
||||||
{
|
|
||||||
return createProcess("");
|
|
||||||
}
|
|
||||||
|
|
||||||
PvaProcessPtr PvaChannel::createProcess(string const & request)
|
|
||||||
{
|
|
||||||
PVStructurePtr pvRequest = createRequest->createRequest(request);
|
|
||||||
if(!pvRequest) {
|
|
||||||
stringstream ss;
|
|
||||||
ss << "channel " << getChannelName();
|
|
||||||
ss << " PvaChannel::createProcess invalid pvRequest: " + createRequest->getMessage();
|
|
||||||
throw std::runtime_error(ss.str());
|
|
||||||
}
|
|
||||||
return createProcess(pvRequest);
|
|
||||||
}
|
|
||||||
|
|
||||||
PvaProcessPtr PvaChannel::createProcess(PVStructurePtr const & pvRequest)
|
|
||||||
{
|
|
||||||
if(connectState!=connected) connect(5.0);
|
|
||||||
if(connectState!=connected) throw std::runtime_error("PvaChannel::creatProcess not connected");
|
|
||||||
PvaPtr yyy = pva.lock();
|
|
||||||
if(!yyy) throw std::runtime_error("Pva was destroyed");
|
|
||||||
return PvaProcess::create(yyy,getPtrSelf(),channel,pvRequest);
|
|
||||||
}
|
|
||||||
|
|
||||||
PvaGetPtr PvaChannel::get() {return get("value,alarm,timeStamp");}
|
|
||||||
|
|
||||||
PvaGetPtr PvaChannel::get(string const & request)
|
|
||||||
{
|
|
||||||
PvaGetPtr pvaGet = pvaGetCache->getGet(request);
|
|
||||||
if(pvaGet) return pvaGet;
|
|
||||||
pvaGet = createGet(request);
|
|
||||||
pvaGet->connect();
|
|
||||||
pvaGetCache->addGet(request,pvaGet);
|
|
||||||
return pvaGet;
|
|
||||||
}
|
|
||||||
|
|
||||||
PvaGetPtr PvaChannel::createGet()
|
|
||||||
{
|
|
||||||
return PvaChannel::createGet("value,alarm,timeStamp");
|
|
||||||
}
|
|
||||||
|
|
||||||
PvaGetPtr PvaChannel::createGet(string const & request)
|
|
||||||
{
|
|
||||||
PVStructurePtr pvRequest = createRequest->createRequest(request);
|
|
||||||
if(!pvRequest) {
|
|
||||||
stringstream ss;
|
|
||||||
ss << "channel " << getChannelName();
|
|
||||||
ss << " PvaChannel::createGet invalid pvRequest: " + createRequest->getMessage();
|
|
||||||
throw std::runtime_error(ss.str());
|
|
||||||
}
|
|
||||||
return createGet(pvRequest);
|
|
||||||
}
|
|
||||||
|
|
||||||
PvaGetPtr PvaChannel::createGet(PVStructurePtr const & pvRequest)
|
|
||||||
{
|
|
||||||
if(connectState!=connected) connect(5.0);
|
|
||||||
if(connectState!=connected) throw std::runtime_error("PvaChannel::creatGet not connected");
|
|
||||||
PvaPtr yyy = pva.lock();
|
|
||||||
if(!yyy) throw std::runtime_error("Pva was destroyed");
|
|
||||||
return PvaGet::create(yyy,getPtrSelf(),channel,pvRequest);
|
|
||||||
}
|
|
||||||
|
|
||||||
PvaPutPtr PvaChannel::put() {return put("value");}
|
|
||||||
|
|
||||||
PvaPutPtr PvaChannel::put(string const & request)
|
|
||||||
{
|
|
||||||
PvaPutPtr pvaPut = pvaPutCache->getPut(request);
|
|
||||||
if(pvaPut) return pvaPut;
|
|
||||||
pvaPut = createPut(request);
|
|
||||||
pvaPut->connect();
|
|
||||||
pvaPut->get();
|
|
||||||
pvaPutCache->addPut(request,pvaPut);
|
|
||||||
return pvaPut;
|
|
||||||
}
|
|
||||||
|
|
||||||
PvaPutPtr PvaChannel::createPut()
|
|
||||||
{
|
|
||||||
return createPut("value");
|
|
||||||
}
|
|
||||||
|
|
||||||
PvaPutPtr PvaChannel::createPut(string const & request)
|
|
||||||
{
|
|
||||||
PVStructurePtr pvRequest = createRequest->createRequest(request);
|
|
||||||
if(!pvRequest) {
|
|
||||||
stringstream ss;
|
|
||||||
ss << "channel " << getChannelName();
|
|
||||||
ss << " PvaChannel::createPut invalid pvRequest: " + createRequest->getMessage();
|
|
||||||
throw std::runtime_error(ss.str());
|
|
||||||
}
|
|
||||||
return createPut(pvRequest);
|
|
||||||
}
|
|
||||||
|
|
||||||
PvaPutPtr PvaChannel::createPut(PVStructurePtr const & pvRequest)
|
|
||||||
{
|
|
||||||
if(connectState!=connected) connect(5.0);
|
|
||||||
if(connectState!=connected) throw std::runtime_error("PvaChannel::creatPut not connected");
|
|
||||||
PvaPtr yyy = pva.lock();
|
|
||||||
if(!yyy) throw std::runtime_error("Pva was destroyed");
|
|
||||||
return PvaPut::create(yyy,getPtrSelf(),channel,pvRequest);
|
|
||||||
}
|
|
||||||
|
|
||||||
PvaPutGetPtr PvaChannel::createPutGet()
|
|
||||||
{
|
|
||||||
return createPutGet("putField(argument)getField(result)");
|
|
||||||
}
|
|
||||||
|
|
||||||
PvaPutGetPtr PvaChannel::createPutGet(string const & request)
|
|
||||||
{
|
|
||||||
PVStructurePtr pvRequest = createRequest->createRequest(request);
|
|
||||||
if(!pvRequest) {
|
|
||||||
stringstream ss;
|
|
||||||
ss << "channel " << getChannelName();
|
|
||||||
ss << " PvaChannel::createPutGet invalid pvRequest: " + createRequest->getMessage();
|
|
||||||
throw std::runtime_error(ss.str());
|
|
||||||
}
|
|
||||||
return createPutGet(pvRequest);
|
|
||||||
}
|
|
||||||
|
|
||||||
PvaPutGetPtr PvaChannel::createPutGet(PVStructurePtr const & pvRequest)
|
|
||||||
{
|
|
||||||
if(connectState!=connected) connect(5.0);
|
|
||||||
if(connectState!=connected) throw std::runtime_error("PvaChannel::creatPutGet not connected");
|
|
||||||
PvaPtr yyy = pva.lock();
|
|
||||||
if(!yyy) throw std::runtime_error("Pva was destroyed");
|
|
||||||
return PvaPutGet::create(yyy,getPtrSelf(),channel,pvRequest);
|
|
||||||
}
|
|
||||||
|
|
||||||
PvaRPCPtr PvaChannel::createRPC()
|
|
||||||
{
|
|
||||||
return createRPC("");
|
|
||||||
}
|
|
||||||
|
|
||||||
PvaRPCPtr PvaChannel::createRPC(string const & request)
|
|
||||||
{
|
|
||||||
PVStructurePtr pvRequest = createRequest->createRequest(request);
|
|
||||||
if(!pvRequest) {
|
|
||||||
stringstream ss;
|
|
||||||
ss << "channel " << getChannelName();
|
|
||||||
ss << " PvaChannel::createRPC invalid pvRequest: " + createRequest->getMessage();
|
|
||||||
throw std::runtime_error(ss.str());
|
|
||||||
}
|
|
||||||
return createRPC(pvRequest);
|
|
||||||
}
|
|
||||||
|
|
||||||
PvaRPCPtr PvaChannel::createRPC(PVStructurePtr const & pvRequest)
|
|
||||||
{
|
|
||||||
throw std::runtime_error("PvaChannel::createRPC not implemented");
|
|
||||||
}
|
|
||||||
|
|
||||||
PvaArrayPtr PvaChannel::createArray()
|
|
||||||
{
|
|
||||||
return createArray("value");
|
|
||||||
}
|
|
||||||
|
|
||||||
PvaArrayPtr PvaChannel::createArray(string const & request)
|
|
||||||
{
|
|
||||||
PVStructurePtr pvRequest = createRequest->createRequest(request);
|
|
||||||
if(!pvRequest) {
|
|
||||||
stringstream ss;
|
|
||||||
ss << "channel " << getChannelName();
|
|
||||||
ss << " PvaChannel::createArray invalid pvRequest: " + createRequest->getMessage();
|
|
||||||
throw std::runtime_error(ss.str());
|
|
||||||
}
|
|
||||||
return createArray(pvRequest);
|
|
||||||
}
|
|
||||||
|
|
||||||
PvaArrayPtr PvaChannel::createArray(PVStructurePtr const & pvRequest)
|
|
||||||
{
|
|
||||||
throw std::runtime_error("PvaChannel::createArray not implemented");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
PvaMonitorPtr PvaChannel::monitor() {return monitor("value,alarm,timeStamp");}
|
|
||||||
|
|
||||||
PvaMonitorPtr PvaChannel::monitor(string const & request)
|
|
||||||
{
|
|
||||||
PvaMonitorPtr pvaMonitor = createMonitor(request);
|
|
||||||
pvaMonitor->connect();
|
|
||||||
pvaMonitor->start();
|
|
||||||
return pvaMonitor;
|
|
||||||
}
|
|
||||||
|
|
||||||
PvaMonitorPtr PvaChannel::monitor(PvaMonitorRequesterPtr const & pvaMonitorRequester)
|
|
||||||
{ return monitor("value,alarm,timeStamp",pvaMonitorRequester);
|
|
||||||
}
|
|
||||||
|
|
||||||
PvaMonitorPtr PvaChannel::monitor(string const & request,
|
|
||||||
PvaMonitorRequesterPtr const & pvaMonitorRequester)
|
|
||||||
{
|
|
||||||
PvaMonitorPtr pvaMonitor = createMonitor(request);
|
|
||||||
pvaMonitor->connect();
|
|
||||||
pvaMonitor->setRequester(pvaMonitorRequester);
|
|
||||||
pvaMonitor->start();
|
|
||||||
return pvaMonitor;
|
|
||||||
}
|
|
||||||
|
|
||||||
PvaMonitorPtr PvaChannel::createMonitor()
|
|
||||||
{
|
|
||||||
return createMonitor("value,alarm,timeStamp");
|
|
||||||
}
|
|
||||||
|
|
||||||
PvaMonitorPtr PvaChannel::createMonitor(string const & request)
|
|
||||||
{
|
|
||||||
PVStructurePtr pvRequest = createRequest->createRequest(request);
|
|
||||||
if(!pvRequest) {
|
|
||||||
stringstream ss;
|
|
||||||
ss << "channel " << getChannelName();
|
|
||||||
ss << " PvaChannel::createMonitor invalid pvRequest: " + createRequest->getMessage();
|
|
||||||
throw std::runtime_error(ss.str());
|
|
||||||
}
|
|
||||||
return createMonitor(pvRequest);
|
|
||||||
}
|
|
||||||
|
|
||||||
PvaMonitorPtr PvaChannel::createMonitor(PVStructurePtr const & pvRequest)
|
|
||||||
{
|
|
||||||
if(connectState!=connected) connect(5.0);
|
|
||||||
if(connectState!=connected) throw std::runtime_error("PvaChannel::createMonitor not connected");
|
|
||||||
PvaPtr yyy = pva.lock();
|
|
||||||
if(!yyy) throw std::runtime_error("Pva was destroyed");
|
|
||||||
return PvaMonitor::create(yyy,getPtrSelf(),channel,pvRequest);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
PvaChannelPtr PvaChannel::create(
|
|
||||||
PvaPtr const &pva,
|
|
||||||
string const & channelName,
|
|
||||||
string const & providerName)
|
|
||||||
{
|
|
||||||
PvaChannelPtr channel(new PvaChannel(pva,channelName,providerName));
|
|
||||||
return channel;
|
|
||||||
}
|
|
||||||
|
|
||||||
}}
|
|
@ -1,230 +0,0 @@
|
|||||||
/* pvaGet.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 2015.02
|
|
||||||
*/
|
|
||||||
#define epicsExportSharedSymbols
|
|
||||||
|
|
||||||
#include <sstream>
|
|
||||||
#include <pv/event.h>
|
|
||||||
#include <pv/pva.h>
|
|
||||||
|
|
||||||
using std::tr1::static_pointer_cast;
|
|
||||||
using namespace epics::pvData;
|
|
||||||
using namespace epics::pvAccess;
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
namespace epics { namespace pva {
|
|
||||||
|
|
||||||
|
|
||||||
class ChannelGetRequesterImpl : public ChannelGetRequester
|
|
||||||
{
|
|
||||||
PvaGet * pvaGet;
|
|
||||||
public:
|
|
||||||
ChannelGetRequesterImpl(PvaGet * pvaGet)
|
|
||||||
: pvaGet(pvaGet) {}
|
|
||||||
string getRequesterName()
|
|
||||||
{return pvaGet->getRequesterName();}
|
|
||||||
void message(string const & message,MessageType messageType)
|
|
||||||
{pvaGet->message(message,messageType);}
|
|
||||||
void channelGetConnect(
|
|
||||||
const Status& status,
|
|
||||||
ChannelGet::shared_pointer const & channelGet,
|
|
||||||
StructureConstPtr const & structure)
|
|
||||||
{pvaGet->channelGetConnect(status,channelGet,structure);}
|
|
||||||
void getDone(
|
|
||||||
const Status& status,
|
|
||||||
ChannelGet::shared_pointer const & channelGet,
|
|
||||||
PVStructurePtr const & pvStructure,
|
|
||||||
BitSetPtr const & bitSet)
|
|
||||||
{pvaGet->getDone(status,channelGet,pvStructure,bitSet);}
|
|
||||||
};
|
|
||||||
|
|
||||||
PvaGet::PvaGet(
|
|
||||||
PvaPtr const &pva,
|
|
||||||
PvaChannelPtr const & pvaChannel,
|
|
||||||
Channel::shared_pointer const & channel,
|
|
||||||
PVStructurePtr const &pvRequest)
|
|
||||||
: pva(pva),
|
|
||||||
pvaChannel(pvaChannel),
|
|
||||||
channel(channel),
|
|
||||||
pvRequest(pvRequest),
|
|
||||||
isDestroyed(false),
|
|
||||||
connectState(connectIdle),
|
|
||||||
getState(getIdle)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
PvaGet::~PvaGet()
|
|
||||||
{
|
|
||||||
destroy();
|
|
||||||
}
|
|
||||||
|
|
||||||
void PvaGet::checkGetState()
|
|
||||||
{
|
|
||||||
if(isDestroyed) throw std::runtime_error("pvaGet was destroyed");
|
|
||||||
if(connectState==connectIdle) connect();
|
|
||||||
if(getState==getIdle) get();
|
|
||||||
}
|
|
||||||
|
|
||||||
// from ChannelGetRequester
|
|
||||||
string PvaGet::getRequesterName()
|
|
||||||
{
|
|
||||||
PvaPtr yyy = pva.lock();
|
|
||||||
if(!yyy) throw std::runtime_error("pva was destroyed");
|
|
||||||
return yyy->getRequesterName();
|
|
||||||
}
|
|
||||||
|
|
||||||
void PvaGet::message(string const & message,MessageType messageType)
|
|
||||||
{
|
|
||||||
if(isDestroyed) throw std::runtime_error("pvaGet was destroyed");
|
|
||||||
PvaPtr yyy = pva.lock();
|
|
||||||
if(!yyy) throw std::runtime_error("pva was destroyed");
|
|
||||||
yyy->message(message, messageType);
|
|
||||||
}
|
|
||||||
|
|
||||||
void PvaGet::channelGetConnect(
|
|
||||||
const Status& status,
|
|
||||||
ChannelGet::shared_pointer const & channelGet,
|
|
||||||
StructureConstPtr const & structure)
|
|
||||||
{
|
|
||||||
if(isDestroyed) throw std::runtime_error("pvaGet was destroyed");
|
|
||||||
channelGetConnectStatus = status;
|
|
||||||
this->channelGet = channelGet;
|
|
||||||
if(status.isOK()) {
|
|
||||||
pvaData = PvaGetData::create(structure);
|
|
||||||
pvaData->setMessagePrefix(channel->getChannelName());
|
|
||||||
}
|
|
||||||
waitForConnect.signal();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void PvaGet::getDone(
|
|
||||||
const Status& status,
|
|
||||||
ChannelGet::shared_pointer const & channelGet,
|
|
||||||
PVStructurePtr const & pvStructure,
|
|
||||||
BitSetPtr const & bitSet)
|
|
||||||
{
|
|
||||||
if(isDestroyed) throw std::runtime_error("pvaGet was destroyed");
|
|
||||||
channelGetStatus = status;
|
|
||||||
if(status.isOK()) {
|
|
||||||
pvaData->setData(pvStructure,bitSet);
|
|
||||||
}
|
|
||||||
waitForGet.signal();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// from PvaGet
|
|
||||||
void PvaGet::destroy()
|
|
||||||
{
|
|
||||||
{
|
|
||||||
Lock xx(mutex);
|
|
||||||
if(isDestroyed) return;
|
|
||||||
isDestroyed = true;
|
|
||||||
}
|
|
||||||
if(channelGet) channelGet->destroy();
|
|
||||||
channelGet.reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
void PvaGet::connect()
|
|
||||||
{
|
|
||||||
if(isDestroyed) throw std::runtime_error("pvaGet was destroyed");
|
|
||||||
issueConnect();
|
|
||||||
Status status = waitConnect();
|
|
||||||
if(status.isOK()) return;
|
|
||||||
stringstream ss;
|
|
||||||
ss << "channel " << channel->getChannelName() << " PvaGet::connect " << status.getMessage();
|
|
||||||
throw std::runtime_error(ss.str());
|
|
||||||
}
|
|
||||||
|
|
||||||
void PvaGet::issueConnect()
|
|
||||||
{
|
|
||||||
if(isDestroyed) throw std::runtime_error("pvaGet was destroyed");
|
|
||||||
if(connectState!=connectIdle) {
|
|
||||||
stringstream ss;
|
|
||||||
ss << "channel " << channel->getChannelName() << " pvaGet already connected ";
|
|
||||||
throw std::runtime_error(ss.str());
|
|
||||||
}
|
|
||||||
getRequester = ChannelGetRequester::shared_pointer(new ChannelGetRequesterImpl(this));
|
|
||||||
connectState = connectActive;
|
|
||||||
channelGet = channel->createChannelGet(getRequester,pvRequest);
|
|
||||||
}
|
|
||||||
|
|
||||||
Status PvaGet::waitConnect()
|
|
||||||
{
|
|
||||||
if(isDestroyed) throw std::runtime_error("pvaGet was destroyed");
|
|
||||||
if(connectState!=connectActive) {
|
|
||||||
stringstream ss;
|
|
||||||
ss << "channel " << channel->getChannelName() << " pvaGet illegal connect state ";
|
|
||||||
throw std::runtime_error(ss.str());
|
|
||||||
}
|
|
||||||
waitForConnect.wait();
|
|
||||||
if(channelGetConnectStatus.isOK()){
|
|
||||||
connectState = connected;
|
|
||||||
return Status::Ok;
|
|
||||||
}
|
|
||||||
connectState = connectIdle;
|
|
||||||
return Status(Status::STATUSTYPE_ERROR,channelGetConnectStatus.getMessage());
|
|
||||||
}
|
|
||||||
|
|
||||||
void PvaGet::get()
|
|
||||||
{
|
|
||||||
if(isDestroyed) throw std::runtime_error("pvaGet was destroyed");
|
|
||||||
issueGet();
|
|
||||||
Status status = waitGet();
|
|
||||||
if(status.isOK()) return;
|
|
||||||
stringstream ss;
|
|
||||||
ss << "channel " << channel->getChannelName() << " PvaGet::get " << status.getMessage();
|
|
||||||
throw std::runtime_error(ss.str());
|
|
||||||
}
|
|
||||||
|
|
||||||
void PvaGet::issueGet()
|
|
||||||
{
|
|
||||||
if(isDestroyed) throw std::runtime_error("pvaGet was destroyed");
|
|
||||||
if(connectState==connectIdle) connect();
|
|
||||||
if(getState!=getIdle) {
|
|
||||||
stringstream ss;
|
|
||||||
ss << "channel " << channel->getChannelName() << " PvaGet::issueGet get aleady active ";
|
|
||||||
throw std::runtime_error(ss.str());
|
|
||||||
}
|
|
||||||
getState = getActive;
|
|
||||||
channelGet->get();
|
|
||||||
}
|
|
||||||
|
|
||||||
Status PvaGet::waitGet()
|
|
||||||
{
|
|
||||||
if(isDestroyed) throw std::runtime_error("pvaGet was destroyed");
|
|
||||||
if(getState!=getActive){
|
|
||||||
stringstream ss;
|
|
||||||
ss << "channel " << channel->getChannelName() << " PvaGet::waitGet llegal get state";
|
|
||||||
throw std::runtime_error(ss.str());
|
|
||||||
}
|
|
||||||
waitForGet.wait();
|
|
||||||
getState = getIdle;
|
|
||||||
if(channelGetStatus.isOK()) {
|
|
||||||
return Status::Ok;
|
|
||||||
}
|
|
||||||
return Status(Status::STATUSTYPE_ERROR,channelGetStatus.getMessage());
|
|
||||||
}
|
|
||||||
PvaGetDataPtr PvaGet::getData()
|
|
||||||
{
|
|
||||||
checkGetState();
|
|
||||||
return pvaData;
|
|
||||||
}
|
|
||||||
|
|
||||||
PvaGetPtr PvaGet::create(
|
|
||||||
PvaPtr const &pva,
|
|
||||||
PvaChannelPtr const & pvaChannel,
|
|
||||||
Channel::shared_pointer const & channel,
|
|
||||||
PVStructurePtr const &pvRequest)
|
|
||||||
{
|
|
||||||
PvaGetPtr epv(new PvaGet(pva,pvaChannel,channel,pvRequest));
|
|
||||||
return epv;
|
|
||||||
}
|
|
||||||
|
|
||||||
}}
|
|
@ -1,200 +0,0 @@
|
|||||||
/* pvaGetData.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 2015.02
|
|
||||||
*/
|
|
||||||
#define epicsExportSharedSymbols
|
|
||||||
|
|
||||||
#include <typeinfo>
|
|
||||||
|
|
||||||
#include <sstream>
|
|
||||||
#include <pv/pva.h>
|
|
||||||
#include <pv/createRequest.h>
|
|
||||||
#include <pv/convert.h>
|
|
||||||
|
|
||||||
|
|
||||||
using std::tr1::static_pointer_cast;
|
|
||||||
using namespace epics::pvData;
|
|
||||||
using namespace epics::pvAccess;
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
namespace epics { namespace pva {
|
|
||||||
|
|
||||||
|
|
||||||
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");
|
|
||||||
|
|
||||||
PvaGetDataPtr PvaGetData::create(StructureConstPtr const & structure)
|
|
||||||
{
|
|
||||||
PvaGetDataPtr epv(new PvaGetData(structure));
|
|
||||||
return epv;
|
|
||||||
}
|
|
||||||
|
|
||||||
PvaGetData::PvaGetData(StructureConstPtr const & structure)
|
|
||||||
: structure(structure)
|
|
||||||
{}
|
|
||||||
|
|
||||||
void PvaGetData::checkValue()
|
|
||||||
{
|
|
||||||
if(pvValue) return;
|
|
||||||
throw std::runtime_error(messagePrefix + noValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
void PvaGetData::setMessagePrefix(std::string const & value)
|
|
||||||
{
|
|
||||||
messagePrefix = value + " ";
|
|
||||||
}
|
|
||||||
|
|
||||||
StructureConstPtr PvaGetData::getStructure()
|
|
||||||
{return structure;}
|
|
||||||
|
|
||||||
PVStructurePtr PvaGetData::getPVStructure()
|
|
||||||
{
|
|
||||||
if(pvStructure) return pvStructure;
|
|
||||||
throw std::runtime_error(messagePrefix + noStructure);
|
|
||||||
}
|
|
||||||
|
|
||||||
BitSetPtr PvaGetData::getBitSet()
|
|
||||||
{
|
|
||||||
if(bitSet)return bitSet;
|
|
||||||
throw std::runtime_error(messagePrefix + noStructure);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::ostream & PvaGetData::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 PvaGetData::setData(
|
|
||||||
PVStructurePtr const & pvStructureFrom,
|
|
||||||
BitSetPtr const & bitSetFrom)
|
|
||||||
{
|
|
||||||
pvStructure = pvStructureFrom;
|
|
||||||
bitSet = bitSetFrom;
|
|
||||||
pvValue = pvStructure->getSubField("value");
|
|
||||||
}
|
|
||||||
|
|
||||||
bool PvaGetData::hasValue()
|
|
||||||
{
|
|
||||||
if(!pvValue) return false;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool PvaGetData::isValueScalar()
|
|
||||||
{
|
|
||||||
if(!pvValue) return false;
|
|
||||||
if(pvValue->getField()->getType()==scalar) return true;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool PvaGetData::isValueScalarArray()
|
|
||||||
{
|
|
||||||
if(!pvValue) return false;
|
|
||||||
if(pvValue->getField()->getType()==scalarArray) return true;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
PVFieldPtr PvaGetData::getValue()
|
|
||||||
{
|
|
||||||
checkValue();
|
|
||||||
return pvValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
PVScalarPtr PvaGetData::getScalarValue()
|
|
||||||
{
|
|
||||||
checkValue();
|
|
||||||
PVScalarPtr pv = pvStructure->getSubField<PVScalar>("value");
|
|
||||||
if(!pv) {
|
|
||||||
throw std::runtime_error(messagePrefix + noScalar);
|
|
||||||
}
|
|
||||||
return pv;
|
|
||||||
}
|
|
||||||
|
|
||||||
PVArrayPtr PvaGetData::getArrayValue()
|
|
||||||
{
|
|
||||||
checkValue();
|
|
||||||
PVArrayPtr pv = pvStructure->getSubField<PVArray>("value");
|
|
||||||
if(!pv) {
|
|
||||||
throw std::runtime_error(messagePrefix + noArray);
|
|
||||||
}
|
|
||||||
return pv;
|
|
||||||
}
|
|
||||||
|
|
||||||
PVScalarArrayPtr PvaGetData::getScalarArrayValue()
|
|
||||||
{
|
|
||||||
checkValue();
|
|
||||||
PVScalarArrayPtr pv = pvStructure->getSubField<PVScalarArray>("value");
|
|
||||||
if(!pv) {
|
|
||||||
throw std::runtime_error(messagePrefix + noScalarArray);
|
|
||||||
}
|
|
||||||
return pv;
|
|
||||||
}
|
|
||||||
|
|
||||||
double PvaGetData::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 PvaGetData::getString()
|
|
||||||
{
|
|
||||||
PVScalarPtr pvScalar = getScalarValue();
|
|
||||||
return convert->toString(pvScalar);
|
|
||||||
}
|
|
||||||
|
|
||||||
shared_vector<const double> PvaGetData::getDoubleArray()
|
|
||||||
{
|
|
||||||
checkValue();
|
|
||||||
PVDoubleArrayPtr pv = pvStructure->getSubField<PVDoubleArray>("value");
|
|
||||||
if(!pv) {
|
|
||||||
throw std::runtime_error(messagePrefix + notDoubleArray);
|
|
||||||
}
|
|
||||||
return pv->view();
|
|
||||||
}
|
|
||||||
|
|
||||||
shared_vector<const string> PvaGetData::getStringArray()
|
|
||||||
{
|
|
||||||
checkValue();
|
|
||||||
PVStringArrayPtr pv = pvStructure->getSubField<PVStringArray>("value");
|
|
||||||
if(!pv) {
|
|
||||||
throw std::runtime_error(messagePrefix + notStringArray);
|
|
||||||
}
|
|
||||||
return pv->view();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}}
|
|
@ -1,250 +0,0 @@
|
|||||||
/* pvaMonitor.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 2015.03
|
|
||||||
*/
|
|
||||||
#define epicsExportSharedSymbols
|
|
||||||
|
|
||||||
#include <sstream>
|
|
||||||
#include <pv/event.h>
|
|
||||||
#include <pv/pva.h>
|
|
||||||
#include <pv/bitSetUtil.h>
|
|
||||||
|
|
||||||
using std::tr1::static_pointer_cast;
|
|
||||||
using namespace epics::pvData;
|
|
||||||
using namespace epics::pvAccess;
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
namespace epics { namespace pva {
|
|
||||||
|
|
||||||
|
|
||||||
class ChannelMonitorRequester : public MonitorRequester
|
|
||||||
{
|
|
||||||
PvaMonitor * pvaMonitor;
|
|
||||||
public:
|
|
||||||
ChannelMonitorRequester(PvaMonitor * pvaMonitor)
|
|
||||||
: pvaMonitor(pvaMonitor) {}
|
|
||||||
string getRequesterName()
|
|
||||||
{return pvaMonitor->getRequesterName();}
|
|
||||||
void message(string const & message,MessageType messageType)
|
|
||||||
{pvaMonitor->message(message,messageType);}
|
|
||||||
void monitorConnect(
|
|
||||||
const Status& status,
|
|
||||||
Monitor::shared_pointer const & monitor,
|
|
||||||
StructureConstPtr const & structure)
|
|
||||||
{pvaMonitor->monitorConnect(status,monitor,structure);}
|
|
||||||
void monitorEvent(MonitorPtr const & monitor)
|
|
||||||
{
|
|
||||||
pvaMonitor->monitorEvent(monitor);
|
|
||||||
}
|
|
||||||
void unlisten(MonitorPtr const & monitor)
|
|
||||||
{pvaMonitor->unlisten();}
|
|
||||||
};
|
|
||||||
|
|
||||||
PvaMonitor::PvaMonitor(
|
|
||||||
PvaPtr const &pva,
|
|
||||||
PvaChannelPtr const & pvaChannel,
|
|
||||||
Channel::shared_pointer const & channel,
|
|
||||||
PVStructurePtr const &pvRequest)
|
|
||||||
: pva(pva),
|
|
||||||
pvaChannel(pvaChannel),
|
|
||||||
channel(channel),
|
|
||||||
pvRequest(pvRequest),
|
|
||||||
isDestroyed(false),
|
|
||||||
connectState(connectIdle),
|
|
||||||
userPoll(false),
|
|
||||||
userWait(false)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
PvaMonitor::~PvaMonitor()
|
|
||||||
{
|
|
||||||
destroy();
|
|
||||||
}
|
|
||||||
|
|
||||||
void PvaMonitor::checkMonitorState()
|
|
||||||
{
|
|
||||||
if(isDestroyed) throw std::runtime_error("pvaMonitor was destroyed");
|
|
||||||
if(connectState==connectIdle) connect();
|
|
||||||
if(connectState==connected) start();
|
|
||||||
}
|
|
||||||
|
|
||||||
// from MonitorRequester
|
|
||||||
string PvaMonitor::getRequesterName()
|
|
||||||
{
|
|
||||||
PvaPtr yyy = pva.lock();
|
|
||||||
if(!yyy) throw std::runtime_error("pva was destroyed");
|
|
||||||
return yyy->getRequesterName();
|
|
||||||
}
|
|
||||||
|
|
||||||
void PvaMonitor::message(string const & message,MessageType messageType)
|
|
||||||
{
|
|
||||||
if(isDestroyed) throw std::runtime_error("pvaMonitor was destroyed");
|
|
||||||
PvaPtr yyy = pva.lock();
|
|
||||||
if(!yyy) throw std::runtime_error("pva was destroyed");
|
|
||||||
yyy->message(message, messageType);
|
|
||||||
}
|
|
||||||
|
|
||||||
void PvaMonitor::monitorConnect(
|
|
||||||
const Status& status,
|
|
||||||
Monitor::shared_pointer const & monitor,
|
|
||||||
StructureConstPtr const & structure)
|
|
||||||
{
|
|
||||||
if(isDestroyed) throw std::runtime_error("pvaMonitor was destroyed");
|
|
||||||
connectStatus = status;
|
|
||||||
this->monitor = monitor;
|
|
||||||
if(status.isOK()) {
|
|
||||||
pvaData = PvaMonitorData::create(structure);
|
|
||||||
pvaData->setMessagePrefix(channel->getChannelName());
|
|
||||||
}
|
|
||||||
waitForConnect.signal();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void PvaMonitor::monitorEvent(MonitorPtr const & monitor)
|
|
||||||
{
|
|
||||||
PvaMonitorRequesterPtr req = pvaMonitorRequester.lock();
|
|
||||||
if(req) req->event(getPtrSelf());
|
|
||||||
if(userWait) waitForEvent.signal();
|
|
||||||
}
|
|
||||||
|
|
||||||
void PvaMonitor::unlisten()
|
|
||||||
{
|
|
||||||
destroy();
|
|
||||||
}
|
|
||||||
|
|
||||||
// from PvaMonitor
|
|
||||||
void PvaMonitor::destroy()
|
|
||||||
{
|
|
||||||
{
|
|
||||||
Lock xx(mutex);
|
|
||||||
if(isDestroyed) return;
|
|
||||||
isDestroyed = true;
|
|
||||||
}
|
|
||||||
if(monitor) monitor->destroy();
|
|
||||||
monitor.reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
void PvaMonitor::connect()
|
|
||||||
{
|
|
||||||
if(isDestroyed) throw std::runtime_error("pvaMonitor was destroyed");
|
|
||||||
issueConnect();
|
|
||||||
Status status = waitConnect();
|
|
||||||
if(status.isOK()) return;
|
|
||||||
stringstream ss;
|
|
||||||
ss << "channel " << channel->getChannelName() << " PvaMonitor::connect " << status.getMessage();
|
|
||||||
throw std::runtime_error(ss.str());
|
|
||||||
}
|
|
||||||
|
|
||||||
void PvaMonitor::issueConnect()
|
|
||||||
{
|
|
||||||
if(isDestroyed) throw std::runtime_error("pvaMonitor was destroyed");
|
|
||||||
if(connectState!=connectIdle) {
|
|
||||||
stringstream ss;
|
|
||||||
ss << "channel " << channel->getChannelName() << " pvaMonitor already connected ";
|
|
||||||
throw std::runtime_error(ss.str());
|
|
||||||
}
|
|
||||||
monitorRequester = ChannelMonitorRequester::shared_pointer(new ChannelMonitorRequester(this));
|
|
||||||
connectState = connectActive;
|
|
||||||
monitor = channel->createMonitor(monitorRequester,pvRequest);
|
|
||||||
}
|
|
||||||
|
|
||||||
Status PvaMonitor::waitConnect()
|
|
||||||
{
|
|
||||||
if(isDestroyed) throw std::runtime_error("pvaMonitor was destroyed");
|
|
||||||
if(connectState!=connectActive) {
|
|
||||||
stringstream ss;
|
|
||||||
ss << "channel " << channel->getChannelName() << " pvaMonitor illegal connect state ";
|
|
||||||
throw std::runtime_error(ss.str());
|
|
||||||
}
|
|
||||||
waitForConnect.wait();
|
|
||||||
if(connectStatus.isOK()){
|
|
||||||
connectState = connected;
|
|
||||||
return Status::Ok;
|
|
||||||
}
|
|
||||||
connectState = connectIdle;
|
|
||||||
return Status(Status::STATUSTYPE_ERROR,connectStatus.getMessage());
|
|
||||||
}
|
|
||||||
|
|
||||||
void PvaMonitor::setRequester(PvaMonitorRequesterPtr const & pvaMonitorrRequester)
|
|
||||||
{
|
|
||||||
this->pvaMonitorRequester = pvaMonitorrRequester;
|
|
||||||
}
|
|
||||||
|
|
||||||
void PvaMonitor::start()
|
|
||||||
{
|
|
||||||
if(isDestroyed) throw std::runtime_error("pvaMonitor was destroyed");
|
|
||||||
if(connectState==monitorStarted) return;
|
|
||||||
if(connectState==connectIdle) connect();
|
|
||||||
if(connectState!=connected) throw std::runtime_error("PvaMonitor::start illegal state");
|
|
||||||
connectState = monitorStarted;
|
|
||||||
monitor->start();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void PvaMonitor::stop()
|
|
||||||
{
|
|
||||||
if(isDestroyed) throw std::runtime_error("pvaMonitor was destroyed");
|
|
||||||
if(connectState!=monitorStarted) return;
|
|
||||||
connectState = connected;
|
|
||||||
monitor->stop();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool PvaMonitor::poll()
|
|
||||||
{
|
|
||||||
checkMonitorState();
|
|
||||||
if(connectState!=monitorStarted) throw std::runtime_error("PvaMonitor::poll illegal state");
|
|
||||||
if(userPoll) throw std::runtime_error("PvaMonitor::poll did not release last");
|
|
||||||
monitorElement = monitor->poll();
|
|
||||||
if(!monitorElement) return false;
|
|
||||||
userPoll = true;
|
|
||||||
pvaData->setData(monitorElement);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool PvaMonitor::waitEvent(double secondsToWait)
|
|
||||||
{
|
|
||||||
if(isDestroyed) throw std::runtime_error("pvaMonitor was destroyed");
|
|
||||||
if(connectState!=monitorStarted) throw std::runtime_error("PvaMonitor::poll illegal state");
|
|
||||||
if(poll()) return true;
|
|
||||||
userWait = true;
|
|
||||||
if(secondsToWait==0.0) {
|
|
||||||
waitForEvent.wait();
|
|
||||||
} else {
|
|
||||||
waitForEvent.wait(secondsToWait);
|
|
||||||
}
|
|
||||||
userWait = false;
|
|
||||||
return poll();
|
|
||||||
}
|
|
||||||
|
|
||||||
void PvaMonitor::releaseEvent()
|
|
||||||
{
|
|
||||||
if(isDestroyed) throw std::runtime_error("pvaMonitor was destroyed");
|
|
||||||
if(connectState!=monitorStarted) throw std::runtime_error("PvaMonitor::poll illegal state");
|
|
||||||
if(!userPoll) throw std::runtime_error("PvaMonitor::releaseEvent did not call poll");
|
|
||||||
userPoll = false;
|
|
||||||
monitor->release(monitorElement);
|
|
||||||
}
|
|
||||||
|
|
||||||
PvaMonitorDataPtr PvaMonitor::getData()
|
|
||||||
{
|
|
||||||
checkMonitorState();
|
|
||||||
return pvaData;
|
|
||||||
}
|
|
||||||
|
|
||||||
PvaMonitorPtr PvaMonitor::create(
|
|
||||||
PvaPtr const &pva,
|
|
||||||
PvaChannelPtr const & pvaChannel,
|
|
||||||
Channel::shared_pointer const & channel,
|
|
||||||
PVStructurePtr const &pvRequest)
|
|
||||||
{
|
|
||||||
PvaMonitorPtr epv(new PvaMonitor(pva,pvaChannel,channel,pvRequest));
|
|
||||||
return epv;
|
|
||||||
}
|
|
||||||
|
|
||||||
}}
|
|
@ -1,226 +0,0 @@
|
|||||||
/* pvaMonitorData.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 2015.02
|
|
||||||
*/
|
|
||||||
#define epicsExportSharedSymbols
|
|
||||||
|
|
||||||
#include <typeinfo>
|
|
||||||
|
|
||||||
#include <sstream>
|
|
||||||
#include <pv/pva.h>
|
|
||||||
#include <pv/createRequest.h>
|
|
||||||
#include <pv/convert.h>
|
|
||||||
|
|
||||||
|
|
||||||
using std::tr1::static_pointer_cast;
|
|
||||||
using namespace epics::pvData;
|
|
||||||
using namespace epics::pvAccess;
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
namespace epics { namespace pva {
|
|
||||||
|
|
||||||
|
|
||||||
typedef std::tr1::shared_ptr<PVArray> PVArrayPtr;
|
|
||||||
static StructureConstPtr nullStructure;
|
|
||||||
static PVStructurePtr nullPVStructure;
|
|
||||||
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");
|
|
||||||
|
|
||||||
PvaMonitorDataPtr PvaMonitorData::create(StructureConstPtr const & structure)
|
|
||||||
{
|
|
||||||
PvaMonitorDataPtr epv(new PvaMonitorData(structure));
|
|
||||||
return epv;
|
|
||||||
}
|
|
||||||
|
|
||||||
PvaMonitorData::PvaMonitorData(StructureConstPtr const & structure)
|
|
||||||
: structure(structure)
|
|
||||||
{}
|
|
||||||
|
|
||||||
|
|
||||||
void PvaMonitorData::checkValue()
|
|
||||||
{
|
|
||||||
if(pvValue) return;
|
|
||||||
throw std::runtime_error(messagePrefix + noValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
void PvaMonitorData::setMessagePrefix(std::string const & value)
|
|
||||||
{
|
|
||||||
messagePrefix = value + " ";
|
|
||||||
}
|
|
||||||
|
|
||||||
StructureConstPtr PvaMonitorData::getStructure()
|
|
||||||
{return structure;}
|
|
||||||
|
|
||||||
PVStructurePtr PvaMonitorData::getPVStructure()
|
|
||||||
{
|
|
||||||
if(pvStructure) return pvStructure;
|
|
||||||
throw std::runtime_error(messagePrefix + noStructure);
|
|
||||||
}
|
|
||||||
|
|
||||||
BitSetPtr PvaMonitorData::getChangedBitSet()
|
|
||||||
{
|
|
||||||
if(!changedBitSet) throw std::runtime_error(messagePrefix + noStructure);
|
|
||||||
return changedBitSet;
|
|
||||||
}
|
|
||||||
|
|
||||||
BitSetPtr PvaMonitorData::getOverrunBitSet()
|
|
||||||
{
|
|
||||||
if(!overrunBitSet) throw std::runtime_error(messagePrefix + noStructure);
|
|
||||||
return overrunBitSet;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::ostream & PvaMonitorData::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 & PvaMonitorData::showOverrun(std::ostream & out)
|
|
||||||
{
|
|
||||||
if(!overrunBitSet) throw std::runtime_error(messagePrefix + noStructure);
|
|
||||||
size_t nextSet = overrunBitSet->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 = overrunBitSet->nextSetBit(nextSet+1);
|
|
||||||
}
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
void PvaMonitorData::setData(MonitorElementPtr const & monitorElement)
|
|
||||||
{
|
|
||||||
pvStructure = monitorElement->pvStructurePtr;
|
|
||||||
changedBitSet = monitorElement->changedBitSet;
|
|
||||||
overrunBitSet = monitorElement->overrunBitSet;
|
|
||||||
pvValue = pvStructure->getSubField("value");
|
|
||||||
}
|
|
||||||
|
|
||||||
bool PvaMonitorData::hasValue()
|
|
||||||
{
|
|
||||||
if(!pvValue) return false;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool PvaMonitorData::isValueScalar()
|
|
||||||
{
|
|
||||||
if(!pvValue) return false;
|
|
||||||
if(pvValue->getField()->getType()==scalar) return true;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool PvaMonitorData::isValueScalarArray()
|
|
||||||
{
|
|
||||||
if(!pvValue) return false;
|
|
||||||
if(pvValue->getField()->getType()==scalarArray) return true;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
PVFieldPtr PvaMonitorData::getValue()
|
|
||||||
{
|
|
||||||
checkValue();
|
|
||||||
return pvValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
PVScalarPtr PvaMonitorData::getScalarValue()
|
|
||||||
{
|
|
||||||
checkValue();
|
|
||||||
PVScalarPtr pv = pvStructure->getSubField<PVScalar>("value");
|
|
||||||
if(!pv) {
|
|
||||||
throw std::runtime_error(messagePrefix + noScalar);
|
|
||||||
}
|
|
||||||
return pv;
|
|
||||||
}
|
|
||||||
|
|
||||||
PVArrayPtr PvaMonitorData::getArrayValue()
|
|
||||||
{
|
|
||||||
checkValue();
|
|
||||||
PVArrayPtr pv = pvStructure->getSubField<PVArray>("value");
|
|
||||||
if(!pv) {
|
|
||||||
throw std::runtime_error(messagePrefix + noArray);
|
|
||||||
}
|
|
||||||
return pv;
|
|
||||||
}
|
|
||||||
|
|
||||||
PVScalarArrayPtr PvaMonitorData::getScalarArrayValue()
|
|
||||||
{
|
|
||||||
checkValue();
|
|
||||||
PVScalarArrayPtr pv = pvStructure->getSubField<PVScalarArray>("value");
|
|
||||||
if(!pv) {
|
|
||||||
throw std::runtime_error(messagePrefix + noScalarArray);
|
|
||||||
}
|
|
||||||
return pv;
|
|
||||||
}
|
|
||||||
|
|
||||||
double PvaMonitorData::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 PvaMonitorData::getString()
|
|
||||||
{
|
|
||||||
PVScalarPtr pvScalar = getScalarValue();
|
|
||||||
return convert->toString(pvScalar);
|
|
||||||
}
|
|
||||||
|
|
||||||
shared_vector<const double> PvaMonitorData::getDoubleArray()
|
|
||||||
{
|
|
||||||
checkValue();
|
|
||||||
PVDoubleArrayPtr pv = pvStructure->getSubField<PVDoubleArray>("value");
|
|
||||||
if(!pv) {
|
|
||||||
throw std::runtime_error(messagePrefix + notDoubleArray);
|
|
||||||
}
|
|
||||||
return pv->view();
|
|
||||||
}
|
|
||||||
|
|
||||||
shared_vector<const string> PvaMonitorData::getStringArray()
|
|
||||||
{
|
|
||||||
checkValue();
|
|
||||||
PVStringArrayPtr pv = pvStructure->getSubField<PVStringArray>("value");
|
|
||||||
if(!pv) {
|
|
||||||
throw std::runtime_error(messagePrefix + notStringArray);
|
|
||||||
}
|
|
||||||
return pv->view();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}}
|
|
@ -1,165 +0,0 @@
|
|||||||
/* pvaMultiChannel.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 2015.02
|
|
||||||
*/
|
|
||||||
#define epicsExportSharedSymbols
|
|
||||||
|
|
||||||
#include <map>
|
|
||||||
#include <sstream>
|
|
||||||
#include <pv/event.h>
|
|
||||||
#include <pv/lock.h>
|
|
||||||
#include <pv/pva.h>
|
|
||||||
#include <pv/createRequest.h>
|
|
||||||
|
|
||||||
|
|
||||||
using std::tr1::static_pointer_cast;
|
|
||||||
using namespace epics::pvData;
|
|
||||||
using namespace epics::pvAccess;
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
namespace epics { namespace pva {
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
PvaMultiChannel::PvaMultiChannel(
|
|
||||||
PvaPtr const &pva,
|
|
||||||
PVStringArrayPtr const & channelName,
|
|
||||||
string const & providerName)
|
|
||||||
: pva(pva),
|
|
||||||
channelName(channelName),
|
|
||||||
providerName(providerName),
|
|
||||||
numChannel(channelName->getLength()),
|
|
||||||
isConnected(getPVDataCreate()->createPVScalarArray<PVBooleanArray>()),
|
|
||||||
isDestroyed(false)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
PvaMultiChannel::~PvaMultiChannel()
|
|
||||||
{
|
|
||||||
destroy();
|
|
||||||
}
|
|
||||||
|
|
||||||
void PvaMultiChannel::destroy()
|
|
||||||
{
|
|
||||||
{
|
|
||||||
Lock xx(mutex);
|
|
||||||
if(isDestroyed) return;
|
|
||||||
isDestroyed = true;
|
|
||||||
}
|
|
||||||
pvaChannelArray.reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
PVStringArrayPtr PvaMultiChannel::getChannelNames()
|
|
||||||
{
|
|
||||||
if(isDestroyed) throw std::runtime_error("pvaMultiChannel was destroyed");
|
|
||||||
return channelName;
|
|
||||||
}
|
|
||||||
|
|
||||||
Status PvaMultiChannel::connect(double timeout,size_t maxNotConnected)
|
|
||||||
{
|
|
||||||
if(isDestroyed) throw std::runtime_error("pvaMultiChannel was destroyed");
|
|
||||||
if(pvaChannelArray) throw std::runtime_error("pvaMultiChannel already connected");
|
|
||||||
PvaPtr pva = this->pva.lock();
|
|
||||||
if(!pva) return Status(Status::STATUSTYPE_ERROR,"pva is gone");
|
|
||||||
shared_vector<PvaChannelPtr> pvaChannel(numChannel,PvaChannelPtr());
|
|
||||||
PVStringArray::const_svector channelNames = channelName->view();
|
|
||||||
shared_vector<boolean> isConnected(numChannel,false);
|
|
||||||
for(size_t i=0; i< numChannel; ++i) {
|
|
||||||
pvaChannel[i] = pva->createChannel(channelNames[i],providerName);
|
|
||||||
pvaChannel[i]->issueConnect();
|
|
||||||
}
|
|
||||||
Status returnStatus = Status::Ok;
|
|
||||||
Status status = Status::Ok;
|
|
||||||
size_t numBad = 0;
|
|
||||||
for(size_t i=0; i< numChannel; ++i) {
|
|
||||||
if(numBad==0) {
|
|
||||||
status = pvaChannel[i]->waitConnect(timeout);
|
|
||||||
} else {
|
|
||||||
status = pvaChannel[i]->waitConnect(.001);
|
|
||||||
}
|
|
||||||
if(status.isOK()) {
|
|
||||||
++numConnected;
|
|
||||||
isConnected[i] = true;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if(returnStatus.isOK()) returnStatus = status;
|
|
||||||
++numBad;
|
|
||||||
if(numBad>maxNotConnected) break;
|
|
||||||
}
|
|
||||||
pvaChannelArray = PvaChannelArrayPtr(new PvaChannelArray(freeze(pvaChannel)));
|
|
||||||
this->isConnected->replace(freeze(isConnected));
|
|
||||||
return numBad>maxNotConnected ? returnStatus : Status::Ok;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool PvaMultiChannel::allConnected()
|
|
||||||
{
|
|
||||||
if(isDestroyed) throw std::runtime_error("pvaMultiChannel was destroyed");
|
|
||||||
if(!pvaChannelArray) throw std::runtime_error("pvaMultiChannel not connected");
|
|
||||||
if(numConnected==numChannel) return true;
|
|
||||||
return (numConnected==numChannel) ? true : false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool PvaMultiChannel::connectionChange()
|
|
||||||
{
|
|
||||||
if(isDestroyed) throw std::runtime_error("pvaMultiChannel was destroyed");
|
|
||||||
if(!pvaChannelArray) throw std::runtime_error("pvaMultiChannel not connected");
|
|
||||||
if(numConnected==numChannel) return true;
|
|
||||||
PVBooleanArray::const_svector isConnected = this->isConnected->view();
|
|
||||||
shared_vector<const PvaChannelPtr> channels = *pvaChannelArray.get();
|
|
||||||
for(size_t i=0; i<numChannel; ++i) {
|
|
||||||
const PvaChannelPtr pvaChannel = channels[i];
|
|
||||||
Channel::shared_pointer channel = pvaChannel->getChannel();
|
|
||||||
Channel::ConnectionState stateNow = channel->getConnectionState();
|
|
||||||
bool connectedNow = stateNow==Channel::CONNECTED ? true : false;
|
|
||||||
if(connectedNow!=isConnected[i]) return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
PVBooleanArrayPtr PvaMultiChannel::getIsConnected()
|
|
||||||
{
|
|
||||||
if(isDestroyed) throw std::runtime_error("pvaMultiChannel was destroyed");
|
|
||||||
if(!pvaChannelArray) throw std::runtime_error("pvaMultiChannel not connected");
|
|
||||||
if(!connectionChange()) return isConnected;
|
|
||||||
shared_vector<boolean> isConnected(numChannel,false);
|
|
||||||
shared_vector<const PvaChannelPtr> channels = *pvaChannelArray.get();
|
|
||||||
for(size_t i=0; i<numChannel; ++i) {
|
|
||||||
const PvaChannelPtr pvaChannel = channels[i];
|
|
||||||
Channel::shared_pointer channel = pvaChannel->getChannel();
|
|
||||||
Channel::ConnectionState stateNow = channel->getConnectionState();
|
|
||||||
if(stateNow==Channel::CONNECTED) isConnected[i] = true;
|
|
||||||
}
|
|
||||||
this->isConnected->replace(freeze(isConnected));
|
|
||||||
return this->isConnected;
|
|
||||||
}
|
|
||||||
|
|
||||||
PvaChannelArrayWPtr PvaMultiChannel::getPvaChannelArray()
|
|
||||||
{
|
|
||||||
if(isDestroyed) throw std::runtime_error("pvaMultiChannel was destroyed");
|
|
||||||
if(!pvaChannelArray) throw std::runtime_error("pvaMultiChannel not connected");
|
|
||||||
return pvaChannelArray;
|
|
||||||
}
|
|
||||||
|
|
||||||
Pva::weak_pointer PvaMultiChannel::getPva()
|
|
||||||
{
|
|
||||||
if(isDestroyed) throw std::runtime_error("pvaMultiChannel was destroyed");
|
|
||||||
return pva;
|
|
||||||
}
|
|
||||||
|
|
||||||
PvaMultiChannelPtr PvaMultiChannel::create(
|
|
||||||
PvaPtr const &pva,
|
|
||||||
PVStringArrayPtr const & channelNames,
|
|
||||||
string const & providerName)
|
|
||||||
{
|
|
||||||
PvaMultiChannelPtr channel(new PvaMultiChannel(pva,channelNames,providerName));
|
|
||||||
return channel;
|
|
||||||
}
|
|
||||||
|
|
||||||
}}
|
|
@ -1,139 +0,0 @@
|
|||||||
/* pvaMultiDouble.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 2015.03
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define epicsExportSharedSymbols
|
|
||||||
#include <pv/pvaMultiDouble.h>
|
|
||||||
|
|
||||||
using std::tr1::static_pointer_cast;
|
|
||||||
using namespace epics::pvData;
|
|
||||||
using namespace epics::pvAccess;
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
namespace epics { namespace pva {
|
|
||||||
|
|
||||||
PvaMultiDoublePtr PvaMultiDouble::create(
|
|
||||||
PvaPtr const & pva,
|
|
||||||
PVStringArrayPtr const & channelName,
|
|
||||||
double timeout,
|
|
||||||
std::string const & providerName)
|
|
||||||
{
|
|
||||||
PvaMultiChannelPtr pvaMultiChannel(
|
|
||||||
PvaMultiChannel::create(pva,channelName,providerName));
|
|
||||||
Status status = pvaMultiChannel->connect(timeout,0);
|
|
||||||
if(!status.isOK()) throw std::runtime_error(status.getMessage());
|
|
||||||
return PvaMultiDoublePtr(new PvaMultiDouble(pvaMultiChannel));
|
|
||||||
}
|
|
||||||
|
|
||||||
PvaMultiDouble::PvaMultiDouble(PvaMultiChannelPtr const &pvaMultiChannel)
|
|
||||||
:
|
|
||||||
pvaMultiChannel(pvaMultiChannel)
|
|
||||||
{}
|
|
||||||
|
|
||||||
PvaMultiDouble::~PvaMultiDouble()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void PvaMultiDouble::createGet()
|
|
||||||
{
|
|
||||||
PvaChannelArrayPtr pvaChannelArray = pvaMultiChannel->getPvaChannelArray().lock();
|
|
||||||
if(!pvaChannelArray) throw std::runtime_error("pvaChannelArray is gone");
|
|
||||||
shared_vector<const PvaChannelPtr> pvaChannels = *pvaChannelArray;
|
|
||||||
size_t numChannel = pvaChannels.size();
|
|
||||||
pvaGet = std::vector<PvaGetPtr>(numChannel,PvaGetPtr());
|
|
||||||
bool allOK = true;
|
|
||||||
string message;
|
|
||||||
for(size_t i=0; i<numChannel; ++i)
|
|
||||||
{
|
|
||||||
pvaGet[i] = pvaChannels[i]->createGet("value");
|
|
||||||
pvaGet[i]->issueConnect();
|
|
||||||
}
|
|
||||||
for(size_t i=0; i<numChannel; ++i)
|
|
||||||
{
|
|
||||||
Status status = pvaGet[i]->waitConnect();
|
|
||||||
if(!status.isOK()) {
|
|
||||||
message = "connect status " + status.getMessage();
|
|
||||||
allOK = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(!allOK) throw std::runtime_error(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
void PvaMultiDouble::createPut()
|
|
||||||
{
|
|
||||||
PvaChannelArrayPtr pvaChannelArray = pvaMultiChannel->getPvaChannelArray().lock();
|
|
||||||
if(!pvaChannelArray) throw std::runtime_error("pvaChannelArray is gone");
|
|
||||||
shared_vector<const PvaChannelPtr> pvaChannels = *pvaChannelArray;
|
|
||||||
size_t numChannel = pvaChannels.size();
|
|
||||||
pvaPut = std::vector<PvaPutPtr>(numChannel,PvaPutPtr());
|
|
||||||
bool allOK = true;
|
|
||||||
string message;
|
|
||||||
for(size_t i=0; i<numChannel; ++i)
|
|
||||||
{
|
|
||||||
pvaPut[i] = pvaChannels[i]->createPut("value");
|
|
||||||
pvaPut[i]->issueConnect();
|
|
||||||
}
|
|
||||||
for(size_t i=0; i<numChannel; ++i)
|
|
||||||
{
|
|
||||||
Status status = pvaPut[i]->waitConnect();
|
|
||||||
if(!status.isOK()) {
|
|
||||||
message = "connect status " + status.getMessage();
|
|
||||||
allOK = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(!allOK) throw std::runtime_error(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
epics::pvData::shared_vector<double> PvaMultiDouble::get()
|
|
||||||
{
|
|
||||||
if(pvaGet.empty()) createGet();
|
|
||||||
shared_vector<const string> channelNames = pvaMultiChannel->getChannelNames()->view();
|
|
||||||
size_t numChannel = channelNames.size();
|
|
||||||
epics::pvData::shared_vector<double> data(channelNames.size());
|
|
||||||
for(size_t i=0; i<numChannel; ++i)
|
|
||||||
{
|
|
||||||
pvaGet[i]->issueGet();
|
|
||||||
}
|
|
||||||
for(size_t i=0; i<numChannel; ++i)
|
|
||||||
{
|
|
||||||
Status status = pvaGet[i]->waitGet();
|
|
||||||
if(!status.isOK()) {
|
|
||||||
string message = channelNames[i] + " " + status.getMessage();
|
|
||||||
throw std::runtime_error(message);
|
|
||||||
}
|
|
||||||
data[i] = pvaGet[i]->getData()->getDouble();
|
|
||||||
}
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
void PvaMultiDouble::put(shared_vector<double> const &value)
|
|
||||||
{
|
|
||||||
if(pvaPut.empty()) createPut();
|
|
||||||
shared_vector<const string> channelNames = pvaMultiChannel->getChannelNames()->view();
|
|
||||||
size_t numChannel = channelNames.size();
|
|
||||||
for(size_t i=0; i<numChannel; ++i)
|
|
||||||
{
|
|
||||||
pvaPut[i]->getData()->putDouble(value[i]);
|
|
||||||
pvaPut[i]->issuePut();
|
|
||||||
}
|
|
||||||
for(size_t i=0; i<numChannel; ++i)
|
|
||||||
{
|
|
||||||
Status status = pvaPut[i]->waitPut();
|
|
||||||
if(!status.isOK()) {
|
|
||||||
string message = channelNames[i] + " " + status.getMessage();
|
|
||||||
throw std::runtime_error(message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}}
|
|
@ -1,81 +0,0 @@
|
|||||||
/* pvaMultiDouble.h */
|
|
||||||
/**
|
|
||||||
* 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 2015.02
|
|
||||||
*/
|
|
||||||
#ifndef PVAMULTIDOUBLE_H
|
|
||||||
#define PVAMULTIDOUBLE_H
|
|
||||||
|
|
||||||
#ifdef epicsExportSharedSymbols
|
|
||||||
# define pvaEpicsExportSharedSymbols
|
|
||||||
# undef epicsExportSharedSymbols
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <pv/pva.h>
|
|
||||||
|
|
||||||
namespace epics { namespace pva {
|
|
||||||
|
|
||||||
class PvaMultiDouble;
|
|
||||||
typedef std::tr1::shared_ptr<PvaMultiDouble> PvaMultiDoublePtr;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Support for multiple channels where each channel has a value field that is a scalar double.
|
|
||||||
* If any problems arise an exception is thrown.
|
|
||||||
*
|
|
||||||
* @author mrk
|
|
||||||
*/
|
|
||||||
class epicsShareClass PvaMultiDouble
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
POINTER_DEFINITIONS(PvaMultiDouble);
|
|
||||||
/**
|
|
||||||
* @brief Create a PvaMultiDouble.
|
|
||||||
* @param &pva Interface to Pva
|
|
||||||
* @param channelName PVStringArray of channelNames.
|
|
||||||
* @param timeout The timeout in seconds for connecting.
|
|
||||||
* @param providerName The name of the channelProvider for each channel.
|
|
||||||
* @return The interface to PvaMultiDouble.
|
|
||||||
*/
|
|
||||||
static PvaMultiDoublePtr create(
|
|
||||||
PvaPtr const & pva,
|
|
||||||
epics::pvData::PVStringArrayPtr const & channelName,
|
|
||||||
double timeout = 5.0,
|
|
||||||
std::string const & providerName = "pva");
|
|
||||||
/**
|
|
||||||
* @brief destructor
|
|
||||||
*/
|
|
||||||
~PvaMultiDouble();
|
|
||||||
/**
|
|
||||||
* @brief destroy any resources used.
|
|
||||||
*/
|
|
||||||
void destroy();
|
|
||||||
/**
|
|
||||||
* @brief get the value of all the channels.
|
|
||||||
* @return The data.
|
|
||||||
*/
|
|
||||||
epics::pvData::shared_vector<double> get();
|
|
||||||
/**
|
|
||||||
* @brief put a new value to each channel.
|
|
||||||
* @param value The data.
|
|
||||||
*/
|
|
||||||
void put(epics::pvData::shared_vector<double> const &value);
|
|
||||||
PvaMultiChannelPtr getPvaMultiChannel();
|
|
||||||
private:
|
|
||||||
PvaMultiDouble(
|
|
||||||
PvaMultiChannelPtr const & channelName);
|
|
||||||
void createGet();
|
|
||||||
void createPut();
|
|
||||||
|
|
||||||
PvaMultiChannelPtr pvaMultiChannel;
|
|
||||||
std::vector<PvaGetPtr> pvaGet;
|
|
||||||
std::vector<PvaPutPtr> pvaPut;
|
|
||||||
};
|
|
||||||
|
|
||||||
}}
|
|
||||||
|
|
||||||
#endif // PVAMULTIDOUBLE_H
|
|
@ -1,268 +0,0 @@
|
|||||||
/* pvaNTMultiChannel.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 2015.03
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define epicsExportSharedSymbols
|
|
||||||
#include <pv/pvaNTMultiChannel.h>
|
|
||||||
|
|
||||||
using std::tr1::static_pointer_cast;
|
|
||||||
using namespace epics::pvData;
|
|
||||||
using namespace epics::pvAccess;
|
|
||||||
using namespace epics::nt;
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
namespace epics { namespace pva {
|
|
||||||
|
|
||||||
PvaNTMultiChannelPtr PvaNTMultiChannel::create(
|
|
||||||
PvaPtr const & pva,
|
|
||||||
PVStringArrayPtr const & channelName,
|
|
||||||
StructureConstPtr const &structure,
|
|
||||||
double timeout,
|
|
||||||
std::string const & providerName)
|
|
||||||
{
|
|
||||||
PvaMultiChannelPtr pvaMultiChannel(
|
|
||||||
PvaMultiChannel::create(pva,channelName,providerName));
|
|
||||||
Status status = pvaMultiChannel->connect(timeout,0);
|
|
||||||
if(!status.isOK()) throw std::runtime_error(status.getMessage());
|
|
||||||
if(!NTMultiChannel::is_a(structure)) throw std::runtime_error("structure is not valid");
|
|
||||||
PVStructurePtr pvStructure = getPVDataCreate()->createPVStructure(structure);
|
|
||||||
pvStructure->getSubField<PVStringArray>("channelName")->
|
|
||||||
replace(pvaMultiChannel->getChannelNames()->view());
|
|
||||||
pvStructure->getSubField<PVBooleanArray>("isConnected")->
|
|
||||||
replace(pvaMultiChannel->getIsConnected()->view());
|
|
||||||
NTMultiChannelPtr ntMultiChannel(NTMultiChannel::wrap(pvStructure));
|
|
||||||
return PvaNTMultiChannelPtr(new PvaNTMultiChannel(pvaMultiChannel,ntMultiChannel));
|
|
||||||
}
|
|
||||||
|
|
||||||
PvaNTMultiChannel::PvaNTMultiChannel(
|
|
||||||
PvaMultiChannelPtr const &pvaMultiChannel,
|
|
||||||
NTMultiChannelPtr const &ntMultiChannel)
|
|
||||||
:
|
|
||||||
pvaMultiChannel(pvaMultiChannel),
|
|
||||||
ntMultiChannel(ntMultiChannel),
|
|
||||||
pvUnionArray(ntMultiChannel->getPVStructure()->getSubField<PVUnionArray>("value")),
|
|
||||||
pvDataCreate(getPVDataCreate())
|
|
||||||
{}
|
|
||||||
|
|
||||||
PvaNTMultiChannel::~PvaNTMultiChannel()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void PvaNTMultiChannel::createGet()
|
|
||||||
{
|
|
||||||
PVStructurePtr pvStructure = ntMultiChannel->getPVStructure();
|
|
||||||
bool getAlarm = false;
|
|
||||||
if(pvStructure->getSubField("severity")) getAlarm = true;
|
|
||||||
if(pvStructure->getSubField("status")) getAlarm = true;
|
|
||||||
if(pvStructure->getSubField("severity")) getAlarm = true;
|
|
||||||
bool getTimeStamp = false;
|
|
||||||
if(pvStructure->getSubField("secondsPastEpoch")) getTimeStamp = true;
|
|
||||||
if(pvStructure->getSubField("nanoseconds")) getTimeStamp = true;
|
|
||||||
if(pvStructure->getSubField("userTag")) getTimeStamp = true;
|
|
||||||
string request = "value";
|
|
||||||
if(getAlarm) request += ",alarm";
|
|
||||||
if(getTimeStamp) request += ",timeStamp";
|
|
||||||
PvaChannelArrayPtr pvaChannelArray = pvaMultiChannel->getPvaChannelArray().lock();
|
|
||||||
if(!pvaChannelArray) throw std::runtime_error("pvaChannelArray is gone");
|
|
||||||
shared_vector<const PvaChannelPtr> pvaChannels = *pvaChannelArray;
|
|
||||||
size_t numChannel = pvaChannels.size();
|
|
||||||
pvaGet = std::vector<PvaGetPtr>(numChannel,PvaGetPtr());
|
|
||||||
bool allOK = true;
|
|
||||||
string message;
|
|
||||||
for(size_t i=0; i<numChannel; ++i)
|
|
||||||
{
|
|
||||||
pvaGet[i] = pvaChannels[i]->createGet(request);
|
|
||||||
pvaGet[i]->issueConnect();
|
|
||||||
}
|
|
||||||
for(size_t i=0; i<numChannel; ++i)
|
|
||||||
{
|
|
||||||
Status status = pvaGet[i]->waitConnect();
|
|
||||||
if(!status.isOK()) {
|
|
||||||
message = "connect status " + status.getMessage();
|
|
||||||
allOK = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(!allOK) throw std::runtime_error(message);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void PvaNTMultiChannel::createPut()
|
|
||||||
{
|
|
||||||
PvaChannelArrayPtr pvaChannelArray = pvaMultiChannel->getPvaChannelArray().lock();
|
|
||||||
if(!pvaChannelArray) throw std::runtime_error("pvaChannelArray is gone");
|
|
||||||
shared_vector<const PvaChannelPtr> pvaChannels = *pvaChannelArray;
|
|
||||||
size_t numChannel = pvaChannels.size();
|
|
||||||
pvaPut = std::vector<PvaPutPtr>(numChannel,PvaPutPtr());
|
|
||||||
bool allOK = true;
|
|
||||||
string message;
|
|
||||||
for(size_t i=0; i<numChannel; ++i)
|
|
||||||
{
|
|
||||||
pvaPut[i] = pvaChannels[i]->createPut("value");
|
|
||||||
pvaPut[i]->issueConnect();
|
|
||||||
}
|
|
||||||
for(size_t i=0; i<numChannel; ++i)
|
|
||||||
{
|
|
||||||
Status status = pvaPut[i]->waitConnect();
|
|
||||||
if(!status.isOK()) {
|
|
||||||
message = "connect status " + status.getMessage();
|
|
||||||
allOK = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(!allOK) throw std::runtime_error(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
NTMultiChannelPtr PvaNTMultiChannel::get()
|
|
||||||
{
|
|
||||||
if(pvaGet.empty()) createGet();
|
|
||||||
PVStructurePtr pvStructure = ntMultiChannel->getPVStructure();
|
|
||||||
shared_vector<const string> channelNames = pvaMultiChannel->getChannelNames()->view();
|
|
||||||
size_t numChannel = channelNames.size();
|
|
||||||
bool severityExists = false;
|
|
||||||
bool statusExists = false;
|
|
||||||
bool messageExists = false;
|
|
||||||
bool secondsPastEpochExists = false;
|
|
||||||
bool nanosecondsExists = false;
|
|
||||||
bool userTagExists = false;
|
|
||||||
if(pvStructure->getSubField("severity")) {
|
|
||||||
severity.resize(numChannel);
|
|
||||||
severityExists = true;
|
|
||||||
}
|
|
||||||
if(pvStructure->getSubField("status")) {
|
|
||||||
status.resize(numChannel);
|
|
||||||
statusExists = true;
|
|
||||||
}
|
|
||||||
if(pvStructure->getSubField("message")) {
|
|
||||||
message.resize(numChannel);
|
|
||||||
messageExists = true;
|
|
||||||
}
|
|
||||||
if(pvStructure->getSubField("secondsPastEpoch")) {
|
|
||||||
secondsPastEpoch.resize(numChannel);
|
|
||||||
secondsPastEpochExists = true;
|
|
||||||
}
|
|
||||||
if(pvStructure->getSubField("nanoseconds")) {
|
|
||||||
nanoseconds.resize(numChannel);
|
|
||||||
nanosecondsExists = true;
|
|
||||||
}
|
|
||||||
if(pvStructure->getSubField("userTag")) {
|
|
||||||
userTag.resize(numChannel);
|
|
||||||
userTagExists = true;
|
|
||||||
}
|
|
||||||
shared_vector<PVUnionPtr> valueVector(numChannel);
|
|
||||||
for(size_t i=0; i<numChannel; ++i)
|
|
||||||
{
|
|
||||||
pvaGet[i]->issueGet();
|
|
||||||
}
|
|
||||||
for(size_t i=0; i<numChannel; ++i)
|
|
||||||
{
|
|
||||||
Status stat = pvaGet[i]->waitGet();
|
|
||||||
if(!stat.isOK()) {
|
|
||||||
string message = channelNames[i] + " " + stat.getMessage();
|
|
||||||
throw std::runtime_error(message);
|
|
||||||
}
|
|
||||||
PVStructurePtr pvStructure = pvaGet[i]->getData()->getPVStructure();
|
|
||||||
PVFieldPtr pvField = pvStructure->getSubField("value");
|
|
||||||
if(!pvField) {
|
|
||||||
string message = channelNames[i] + " no value field";
|
|
||||||
throw std::runtime_error(message);
|
|
||||||
}
|
|
||||||
UnionConstPtr u = pvUnionArray->getUnionArray()->getUnion();
|
|
||||||
if(u->isVariant()) {
|
|
||||||
PVUnionPtr pvUnion = pvDataCreate->createPVVariantUnion();
|
|
||||||
pvUnion->set(pvDataCreate->createPVField(pvField));
|
|
||||||
valueVector[i] = pvUnion;
|
|
||||||
} else {
|
|
||||||
PVUnionPtr pvUnion = pvDataCreate->createPVUnion(u);
|
|
||||||
pvUnion->set(pvField);
|
|
||||||
valueVector[i] = pvUnion;
|
|
||||||
}
|
|
||||||
pvField = pvStructure->getSubField("alarm");
|
|
||||||
if(pvField) {
|
|
||||||
if(pvAlarm.attach(pvField)) {
|
|
||||||
pvAlarm.get(alarm);
|
|
||||||
if(severityExists) severity[i] = alarm.getSeverity();
|
|
||||||
if(statusExists) status[i] = alarm.getStatus();
|
|
||||||
if(messageExists) message[i] = alarm.getMessage();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pvField = pvStructure->getSubField("timeStamp");
|
|
||||||
if(pvField) {
|
|
||||||
if(pvTimeStamp.attach(pvField)) {
|
|
||||||
pvTimeStamp.get(timeStamp);
|
|
||||||
if(secondsPastEpochExists) secondsPastEpoch[i] =
|
|
||||||
timeStamp.getSecondsPastEpoch();
|
|
||||||
if(nanosecondsExists) nanoseconds[i] =
|
|
||||||
timeStamp.getNanoseconds();
|
|
||||||
if(userTagExists) userTag[i] = timeStamp.getUserTag();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pvUnionArray->replace(freeze(valueVector));
|
|
||||||
if(severityExists) {
|
|
||||||
pvStructure->getSubField<PVIntArray>("severity")->replace(
|
|
||||||
freeze(severity));
|
|
||||||
}
|
|
||||||
if(statusExists) {
|
|
||||||
pvStructure->getSubField<PVIntArray>("status")->replace(
|
|
||||||
freeze(status));
|
|
||||||
}
|
|
||||||
if(messageExists) {
|
|
||||||
pvStructure->getSubField<PVStringArray>("message")->replace(freeze(message));
|
|
||||||
}
|
|
||||||
if(secondsPastEpochExists) {
|
|
||||||
pvStructure->getSubField<PVLongArray>("secondsPastEpoch")->replace(freeze(secondsPastEpoch));
|
|
||||||
}
|
|
||||||
if(nanosecondsExists) {
|
|
||||||
pvStructure->getSubField<PVIntArray>("nanoseconds")->replace(freeze(nanoseconds));
|
|
||||||
}
|
|
||||||
if(userTagExists) {
|
|
||||||
pvStructure->getSubField<PVIntArray>("userTag")->replace(freeze(userTag));
|
|
||||||
}
|
|
||||||
return ntMultiChannel;
|
|
||||||
}
|
|
||||||
|
|
||||||
void PvaNTMultiChannel::put(NTMultiChannelPtr const &value)
|
|
||||||
{
|
|
||||||
if(pvaPut.empty()) createPut();
|
|
||||||
shared_vector<const string> channelNames = pvaMultiChannel->getChannelNames()->view();
|
|
||||||
size_t numChannel = channelNames.size();
|
|
||||||
PVUnionArrayPtr pvValue = value->getPVStructure()->
|
|
||||||
getSubField<PVUnionArray>("value");
|
|
||||||
shared_vector<const PVUnionPtr> valueVector = pvValue->view();
|
|
||||||
for(size_t i=0; i<numChannel; ++i)
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
PVFieldPtr pvFrom = valueVector[i]->get();
|
|
||||||
PVFieldPtr pvTo = pvaPut[i]->getData()->getValue();
|
|
||||||
Type typeFrom = pvFrom->getField()->getType();
|
|
||||||
Type typeTo = pvTo->getField()->getType();
|
|
||||||
if(typeFrom==typeTo) {
|
|
||||||
if(typeFrom==scalar || typeFrom==scalarArray) {
|
|
||||||
pvTo->copy(*pvFrom);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pvaPut[i]->issuePut();
|
|
||||||
} catch (std::exception e) {
|
|
||||||
string message = channelNames[i] + " " + e.what();
|
|
||||||
throw std::runtime_error(message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for(size_t i=0; i<numChannel; ++i)
|
|
||||||
{
|
|
||||||
Status status = pvaPut[i]->waitPut();
|
|
||||||
if(!status.isOK()) {
|
|
||||||
string message = channelNames[i] + " " + status.getMessage();
|
|
||||||
throw std::runtime_error(message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}}
|
|
@ -1,103 +0,0 @@
|
|||||||
/* pvaNTMultiChannel.h */
|
|
||||||
/**
|
|
||||||
* 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 2015.02
|
|
||||||
*/
|
|
||||||
#ifndef PVANTMULTIChannel_H
|
|
||||||
#define PVANTMULTIChannel_H
|
|
||||||
|
|
||||||
#ifdef epicsExportSharedSymbols
|
|
||||||
# define pvaEpicsExportSharedSymbols
|
|
||||||
# undef epicsExportSharedSymbols
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <pv/pva.h>
|
|
||||||
|
|
||||||
namespace epics { namespace pva {
|
|
||||||
|
|
||||||
class PvaNTMultiChannel;
|
|
||||||
typedef std::tr1::shared_ptr<PvaNTMultiChannel> PvaNTMultiChannelPtr;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Support for multiple channels where each channel has a value field that
|
|
||||||
* is a scalar, scalarArray, or enumerated structure.
|
|
||||||
* The data is provided via normativeType NTMultiChannel.
|
|
||||||
* If any problems arise an exception is thrown.
|
|
||||||
*
|
|
||||||
* @author mrk
|
|
||||||
*/
|
|
||||||
class epicsShareClass PvaNTMultiChannel
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
POINTER_DEFINITIONS(PvaNTMultiChannel);
|
|
||||||
/**
|
|
||||||
* @brief Create a PvaNTMultiChannel.
|
|
||||||
* @param &pva Interface to Pva
|
|
||||||
* @param channelName PVStringArray of channelNames.
|
|
||||||
* @param structure valid NTMultiChannel structure.
|
|
||||||
* @param timeout Timeout for connecting.
|
|
||||||
* @param providerName The provider for each channel.
|
|
||||||
* @return The interface to PvaNTMultiChannel.
|
|
||||||
*/
|
|
||||||
static PvaNTMultiChannelPtr create(
|
|
||||||
PvaPtr const & pva,
|
|
||||||
epics::pvData::PVStringArrayPtr const & channelName,
|
|
||||||
epics::pvData::StructureConstPtr const & structure,
|
|
||||||
double timeout = 5.0,
|
|
||||||
std::string const & providerName = "pva");
|
|
||||||
/**
|
|
||||||
* @brief destructor
|
|
||||||
*/
|
|
||||||
~PvaNTMultiChannel();
|
|
||||||
/**
|
|
||||||
* @brief destroy any resources used.
|
|
||||||
*/
|
|
||||||
void destroy();
|
|
||||||
/**
|
|
||||||
* @brief get the value of all the channels.
|
|
||||||
* @return The data.
|
|
||||||
*/
|
|
||||||
epics::nt::NTMultiChannelPtr get();
|
|
||||||
/**
|
|
||||||
* @brief put a new value to each channel.
|
|
||||||
* @param value The data.
|
|
||||||
*/
|
|
||||||
void put(epics::nt::NTMultiChannelPtr const &value);
|
|
||||||
/**
|
|
||||||
* @brief Get the PvaMultiChannel.
|
|
||||||
* @return The interface.
|
|
||||||
*/
|
|
||||||
PvaMultiChannelPtr getPvaMultiChannel();
|
|
||||||
private:
|
|
||||||
PvaNTMultiChannel(
|
|
||||||
PvaMultiChannelPtr const & channelName,
|
|
||||||
epics::nt::NTMultiChannelPtr const &ntMultiChannel);
|
|
||||||
void createGet();
|
|
||||||
void createPut();
|
|
||||||
|
|
||||||
PvaMultiChannelPtr pvaMultiChannel;
|
|
||||||
epics::nt::NTMultiChannelPtr ntMultiChannel;
|
|
||||||
epics::pvData::PVUnionArrayPtr pvUnionArray;
|
|
||||||
epics::pvData::PVDataCreatePtr pvDataCreate;
|
|
||||||
std::vector<PvaGetPtr> pvaGet;
|
|
||||||
std::vector<PvaPutPtr> pvaPut;
|
|
||||||
epics::pvData::shared_vector<epics::pvData::int32> severity;
|
|
||||||
epics::pvData::shared_vector<epics::pvData::int32> status;
|
|
||||||
epics::pvData::shared_vector<std::string> message;
|
|
||||||
epics::pvData::shared_vector<epics::pvData::int64> secondsPastEpoch;
|
|
||||||
epics::pvData::shared_vector<epics::pvData::int32> nanoseconds;
|
|
||||||
epics::pvData::shared_vector<epics::pvData::int32> userTag;
|
|
||||||
epics::pvData::Alarm alarm;
|
|
||||||
epics::pvData::PVAlarm pvAlarm;
|
|
||||||
epics::pvData::TimeStamp timeStamp;;
|
|
||||||
epics::pvData::PVTimeStamp pvTimeStamp;
|
|
||||||
};
|
|
||||||
|
|
||||||
}}
|
|
||||||
|
|
||||||
#endif // PVANTMULTIChannel_H
|
|
@ -1,212 +0,0 @@
|
|||||||
/* pvaProcess.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 2015.02
|
|
||||||
*/
|
|
||||||
#define epicsExportSharedSymbols
|
|
||||||
|
|
||||||
#include <sstream>
|
|
||||||
#include <pv/event.h>
|
|
||||||
#include <pv/pva.h>
|
|
||||||
|
|
||||||
using std::tr1::static_pointer_cast;
|
|
||||||
using namespace epics::pvData;
|
|
||||||
using namespace epics::pvAccess;
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
namespace epics { namespace pva {
|
|
||||||
|
|
||||||
|
|
||||||
class ChannelProcessRequesterImpl : public ChannelProcessRequester
|
|
||||||
{
|
|
||||||
PvaProcess * pvaProcess;
|
|
||||||
public:
|
|
||||||
ChannelProcessRequesterImpl(PvaProcess * pvaProcess)
|
|
||||||
: pvaProcess(pvaProcess) {}
|
|
||||||
string getRequesterName()
|
|
||||||
{return pvaProcess->getRequesterName();}
|
|
||||||
void message(string const & message,MessageType messageType)
|
|
||||||
{pvaProcess->message(message,messageType);}
|
|
||||||
void channelProcessConnect(
|
|
||||||
const Status& status,
|
|
||||||
ChannelProcess::shared_pointer const & channelProcess)
|
|
||||||
{pvaProcess->channelProcessConnect(status,channelProcess);}
|
|
||||||
void processDone(
|
|
||||||
const Status& status,
|
|
||||||
ChannelProcess::shared_pointer const & channelProcess)
|
|
||||||
{pvaProcess->processDone(status,channelProcess);}
|
|
||||||
};
|
|
||||||
|
|
||||||
PvaProcess::PvaProcess(
|
|
||||||
PvaPtr const &pva,
|
|
||||||
PvaChannelPtr const & pvaChannel,
|
|
||||||
Channel::shared_pointer const & channel,
|
|
||||||
PVStructurePtr const &pvRequest)
|
|
||||||
: pva(pva),
|
|
||||||
pvaChannel(pvaChannel),
|
|
||||||
channel(channel),
|
|
||||||
pvRequest(pvRequest),
|
|
||||||
isDestroyed(false),
|
|
||||||
connectState(connectIdle),
|
|
||||||
processState(processIdle)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
PvaProcess::~PvaProcess()
|
|
||||||
{
|
|
||||||
destroy();
|
|
||||||
}
|
|
||||||
|
|
||||||
void PvaProcess::checkProcessState()
|
|
||||||
{
|
|
||||||
if(isDestroyed) throw std::runtime_error("pvaProcess was destroyed");
|
|
||||||
if(connectState==connectIdle) connect();
|
|
||||||
if(processState==processIdle) process();
|
|
||||||
}
|
|
||||||
|
|
||||||
// from ChannelProcessRequester
|
|
||||||
string PvaProcess::getRequesterName()
|
|
||||||
{
|
|
||||||
PvaPtr yyy = pva.lock();
|
|
||||||
if(!yyy) throw std::runtime_error("pva was destroyed");
|
|
||||||
return yyy->getRequesterName();
|
|
||||||
}
|
|
||||||
|
|
||||||
void PvaProcess::message(string const & message,MessageType messageType)
|
|
||||||
{
|
|
||||||
if(isDestroyed) throw std::runtime_error("pvaProcess was destroyed");
|
|
||||||
PvaPtr yyy = pva.lock();
|
|
||||||
if(!yyy) throw std::runtime_error("pva was destroyed");
|
|
||||||
yyy->message(message, messageType);
|
|
||||||
}
|
|
||||||
|
|
||||||
void PvaProcess::channelProcessConnect(
|
|
||||||
const Status& status,
|
|
||||||
ChannelProcess::shared_pointer const & channelProcess)
|
|
||||||
{
|
|
||||||
if(isDestroyed) throw std::runtime_error("pvaProcess was destroyed");
|
|
||||||
channelProcessConnectStatus = status;
|
|
||||||
this->channelProcess = channelProcess;
|
|
||||||
waitForConnect.signal();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void PvaProcess::processDone(
|
|
||||||
const Status& status,
|
|
||||||
ChannelProcess::shared_pointer const & channelProcess)
|
|
||||||
{
|
|
||||||
if(isDestroyed) throw std::runtime_error("pvaProcess was destroyed");
|
|
||||||
channelProcessStatus = status;
|
|
||||||
waitForProcess.signal();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// from PvaProcess
|
|
||||||
void PvaProcess::destroy()
|
|
||||||
{
|
|
||||||
{
|
|
||||||
Lock xx(mutex);
|
|
||||||
if(isDestroyed) return;
|
|
||||||
isDestroyed = true;
|
|
||||||
}
|
|
||||||
if(channelProcess) channelProcess->destroy();
|
|
||||||
channelProcess.reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
void PvaProcess::connect()
|
|
||||||
{
|
|
||||||
if(isDestroyed) throw std::runtime_error("pvaProcess was destroyed");
|
|
||||||
issueConnect();
|
|
||||||
Status status = waitConnect();
|
|
||||||
if(status.isOK()) return;
|
|
||||||
stringstream ss;
|
|
||||||
ss << "channel " << channel->getChannelName() << " PvaProcess::connect " << status.getMessage();
|
|
||||||
throw std::runtime_error(ss.str());
|
|
||||||
}
|
|
||||||
|
|
||||||
void PvaProcess::issueConnect()
|
|
||||||
{
|
|
||||||
if(isDestroyed) throw std::runtime_error("pvaProcess was destroyed");
|
|
||||||
if(connectState!=connectIdle) {
|
|
||||||
stringstream ss;
|
|
||||||
ss << "channel " << channel->getChannelName() << " pvaProcess already connected ";
|
|
||||||
throw std::runtime_error(ss.str());
|
|
||||||
}
|
|
||||||
processRequester = ChannelProcessRequester::shared_pointer(new ChannelProcessRequesterImpl(this));
|
|
||||||
connectState = connectActive;
|
|
||||||
channelProcess = channel->createChannelProcess(processRequester,pvRequest);
|
|
||||||
}
|
|
||||||
|
|
||||||
Status PvaProcess::waitConnect()
|
|
||||||
{
|
|
||||||
if(isDestroyed) throw std::runtime_error("pvaProcess was destroyed");
|
|
||||||
if(connectState!=connectActive) {
|
|
||||||
stringstream ss;
|
|
||||||
ss << "channel " << channel->getChannelName() << " pvaProcess illegal connect state ";
|
|
||||||
throw std::runtime_error(ss.str());
|
|
||||||
}
|
|
||||||
waitForConnect.wait();
|
|
||||||
if(channelProcessConnectStatus.isOK()){
|
|
||||||
connectState = connected;
|
|
||||||
return Status::Ok;
|
|
||||||
}
|
|
||||||
connectState = connectIdle;
|
|
||||||
return Status(Status::STATUSTYPE_ERROR,channelProcessConnectStatus.getMessage());
|
|
||||||
}
|
|
||||||
|
|
||||||
void PvaProcess::process()
|
|
||||||
{
|
|
||||||
if(isDestroyed) throw std::runtime_error("pvaProcess was destroyed");
|
|
||||||
issueProcess();
|
|
||||||
Status status = waitProcess();
|
|
||||||
if(status.isOK()) return;
|
|
||||||
stringstream ss;
|
|
||||||
ss << "channel " << channel->getChannelName() << " PvaProcess::process " << status.getMessage();
|
|
||||||
throw std::runtime_error(ss.str());
|
|
||||||
}
|
|
||||||
|
|
||||||
void PvaProcess::issueProcess()
|
|
||||||
{
|
|
||||||
if(isDestroyed) throw std::runtime_error("pvaProcess was destroyed");
|
|
||||||
if(connectState==connectIdle) connect();
|
|
||||||
if(processState!=processIdle) {
|
|
||||||
stringstream ss;
|
|
||||||
ss << "channel " << channel->getChannelName() << " PvaProcess::issueProcess process aleady active ";
|
|
||||||
throw std::runtime_error(ss.str());
|
|
||||||
}
|
|
||||||
processState = processActive;
|
|
||||||
channelProcess->process();
|
|
||||||
}
|
|
||||||
|
|
||||||
Status PvaProcess::waitProcess()
|
|
||||||
{
|
|
||||||
if(isDestroyed) throw std::runtime_error("pvaProcess was destroyed");
|
|
||||||
if(processState!=processActive){
|
|
||||||
stringstream ss;
|
|
||||||
ss << "channel " << channel->getChannelName() << " PvaProcess::waitProcess llegal process state";
|
|
||||||
throw std::runtime_error(ss.str());
|
|
||||||
}
|
|
||||||
waitForProcess.wait();
|
|
||||||
processState = processIdle;
|
|
||||||
if(channelProcessStatus.isOK()) {
|
|
||||||
return Status::Ok;
|
|
||||||
}
|
|
||||||
return Status(Status::STATUSTYPE_ERROR,channelProcessStatus.getMessage());
|
|
||||||
}
|
|
||||||
|
|
||||||
PvaProcessPtr PvaProcess::create(
|
|
||||||
PvaPtr const &pva,
|
|
||||||
PvaChannelPtr const & pvaChannel,
|
|
||||||
Channel::shared_pointer const & channel,
|
|
||||||
PVStructurePtr const &pvRequest)
|
|
||||||
{
|
|
||||||
PvaProcessPtr epv(new PvaProcess(pva,pvaChannel,channel,pvRequest));
|
|
||||||
return epv;
|
|
||||||
}
|
|
||||||
|
|
||||||
}}
|
|
@ -1,292 +0,0 @@
|
|||||||
/* pvaPut.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 2015.02
|
|
||||||
*/
|
|
||||||
#define epicsExportSharedSymbols
|
|
||||||
|
|
||||||
#include <sstream>
|
|
||||||
#include <pv/event.h>
|
|
||||||
#include <pv/pva.h>
|
|
||||||
|
|
||||||
using std::tr1::static_pointer_cast;
|
|
||||||
using namespace epics::pvData;
|
|
||||||
using namespace epics::pvAccess;
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
namespace epics { namespace pva {
|
|
||||||
|
|
||||||
class ChannelPutRequesterImpl : public ChannelPutRequester
|
|
||||||
{
|
|
||||||
PvaPut * pvaPut;
|
|
||||||
public:
|
|
||||||
ChannelPutRequesterImpl(PvaPut * pvaPut)
|
|
||||||
: pvaPut(pvaPut) {}
|
|
||||||
string getRequesterName()
|
|
||||||
{return pvaPut->getRequesterName();}
|
|
||||||
void message(string const & message,MessageType messageType)
|
|
||||||
{pvaPut->message(message,messageType);}
|
|
||||||
void channelPutConnect(
|
|
||||||
const Status& status,
|
|
||||||
ChannelPut::shared_pointer const & channelPut,
|
|
||||||
StructureConstPtr const & structure)
|
|
||||||
{pvaPut->channelPutConnect(status,channelPut,structure);}
|
|
||||||
void getDone(
|
|
||||||
const Status& status,
|
|
||||||
ChannelPut::shared_pointer const & channelPut,
|
|
||||||
PVStructurePtr const & pvStructure,
|
|
||||||
BitSetPtr const & bitSet)
|
|
||||||
{pvaPut->getDone(status,channelPut,pvStructure,bitSet);}
|
|
||||||
void putDone(
|
|
||||||
const Status& status,
|
|
||||||
ChannelPut::shared_pointer const & channelPut)
|
|
||||||
{pvaPut->putDone(status,channelPut);}
|
|
||||||
};
|
|
||||||
|
|
||||||
PvaPut::PvaPut(
|
|
||||||
PvaPtr const &pva,
|
|
||||||
PvaChannelPtr const & pvaChannel,
|
|
||||||
Channel::shared_pointer const & channel,
|
|
||||||
PVStructurePtr const &pvRequest)
|
|
||||||
: pva(pva),
|
|
||||||
pvaChannel(pvaChannel),
|
|
||||||
channel(channel),
|
|
||||||
pvRequest(pvRequest),
|
|
||||||
isDestroyed(false),
|
|
||||||
connectState(connectIdle),
|
|
||||||
putState(putIdle)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
PvaPut::~PvaPut()
|
|
||||||
{
|
|
||||||
destroy();
|
|
||||||
}
|
|
||||||
|
|
||||||
void PvaPut::checkPutState()
|
|
||||||
{
|
|
||||||
if(isDestroyed) throw std::runtime_error("pvaPut was destroyed");
|
|
||||||
if(connectState==connectIdle){
|
|
||||||
connect();
|
|
||||||
get();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// from ChannelPutRequester
|
|
||||||
string PvaPut::getRequesterName()
|
|
||||||
{
|
|
||||||
PvaPtr yyy = pva.lock();
|
|
||||||
if(!yyy) throw std::runtime_error("pva was destroyed");
|
|
||||||
return yyy->getRequesterName();
|
|
||||||
}
|
|
||||||
|
|
||||||
void PvaPut::message(string const & message,MessageType messageType)
|
|
||||||
{
|
|
||||||
if(isDestroyed) throw std::runtime_error("pvaPut was destroyed");
|
|
||||||
PvaPtr yyy = pva.lock();
|
|
||||||
if(!yyy) throw std::runtime_error("pva was destroyed");
|
|
||||||
yyy->message(message, messageType);
|
|
||||||
}
|
|
||||||
|
|
||||||
void PvaPut::channelPutConnect(
|
|
||||||
const Status& status,
|
|
||||||
ChannelPut::shared_pointer const & channelPut,
|
|
||||||
StructureConstPtr const & structure)
|
|
||||||
{
|
|
||||||
if(isDestroyed) throw std::runtime_error("pvaPut was destroyed");
|
|
||||||
channelPutConnectStatus = status;
|
|
||||||
this->channelPut = channelPut;
|
|
||||||
if(status.isOK()) {
|
|
||||||
pvaData = PvaPutData::create(structure);
|
|
||||||
pvaData->setMessagePrefix(pvaChannel.lock()->getChannelName());
|
|
||||||
}
|
|
||||||
waitForConnect.signal();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void PvaPut::getDone(
|
|
||||||
const Status& status,
|
|
||||||
ChannelPut::shared_pointer const & channelPut,
|
|
||||||
PVStructurePtr const & pvStructure,
|
|
||||||
BitSetPtr const & bitSet)
|
|
||||||
{
|
|
||||||
if(isDestroyed) throw std::runtime_error("pvaPut was destroyed");
|
|
||||||
channelGetPutStatus = status;
|
|
||||||
if(status.isOK()) {
|
|
||||||
PVStructurePtr pvs = pvaData->getPVStructure();
|
|
||||||
pvs->copyUnchecked(*pvStructure,*bitSet);
|
|
||||||
BitSetPtr bs = pvaData->getBitSet();
|
|
||||||
bs->clear();
|
|
||||||
*bs |= *bitSet;
|
|
||||||
}
|
|
||||||
waitForGetPut.signal();
|
|
||||||
}
|
|
||||||
|
|
||||||
void PvaPut::putDone(
|
|
||||||
const Status& status,
|
|
||||||
ChannelPut::shared_pointer const & channelPut)
|
|
||||||
{
|
|
||||||
if(isDestroyed) throw std::runtime_error("pvaPut was destroyed");
|
|
||||||
channelGetPutStatus = status;
|
|
||||||
waitForGetPut.signal();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// from PvaPut
|
|
||||||
void PvaPut::destroy()
|
|
||||||
{
|
|
||||||
{
|
|
||||||
Lock xx(mutex);
|
|
||||||
if(isDestroyed) return;
|
|
||||||
isDestroyed = true;
|
|
||||||
}
|
|
||||||
if(channelPut) channelPut->destroy();
|
|
||||||
channelPut.reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
void PvaPut::connect()
|
|
||||||
{
|
|
||||||
if(isDestroyed) throw std::runtime_error("pvaPut was destroyed");
|
|
||||||
issueConnect();
|
|
||||||
Status status = waitConnect();
|
|
||||||
if(status.isOK()) return;
|
|
||||||
stringstream ss;
|
|
||||||
ss << "channel " << channel->getChannelName() << " PvaPut::connect " << status.getMessage();
|
|
||||||
throw std::runtime_error(ss.str());
|
|
||||||
}
|
|
||||||
|
|
||||||
void PvaPut::issueConnect()
|
|
||||||
{
|
|
||||||
if(isDestroyed) throw std::runtime_error("pvaPut was destroyed");
|
|
||||||
if(connectState!=connectIdle) {
|
|
||||||
stringstream ss;
|
|
||||||
ss << "channel " << channel->getChannelName() << " pvaPut already connected ";
|
|
||||||
throw std::runtime_error(ss.str());
|
|
||||||
}
|
|
||||||
putRequester = ChannelPutRequester::shared_pointer(new ChannelPutRequesterImpl(this));
|
|
||||||
connectState = connectActive;
|
|
||||||
channelPut = channel->createChannelPut(putRequester,pvRequest);
|
|
||||||
}
|
|
||||||
|
|
||||||
Status PvaPut::waitConnect()
|
|
||||||
{
|
|
||||||
if(isDestroyed) throw std::runtime_error("pvaPut was destroyed");
|
|
||||||
if(connectState!=connectActive) {
|
|
||||||
stringstream ss;
|
|
||||||
ss << "channel " << channel->getChannelName() << " pvaPut illegal connect state ";
|
|
||||||
throw std::runtime_error(ss.str());
|
|
||||||
}
|
|
||||||
waitForConnect.wait();
|
|
||||||
if(channelPutConnectStatus.isOK()) {
|
|
||||||
connectState = connected;
|
|
||||||
return Status::Ok;
|
|
||||||
}
|
|
||||||
connectState = connectIdle;
|
|
||||||
return Status(Status::STATUSTYPE_ERROR,channelPutConnectStatus.getMessage());
|
|
||||||
}
|
|
||||||
|
|
||||||
void PvaPut::get()
|
|
||||||
{
|
|
||||||
if(isDestroyed) throw std::runtime_error("pvaPut was destroyed");
|
|
||||||
issueGet();
|
|
||||||
Status status = waitGet();
|
|
||||||
if(status.isOK()) return;
|
|
||||||
stringstream ss;
|
|
||||||
ss << "channel " << channel->getChannelName() << " PvaPut::get " << status.getMessage();
|
|
||||||
throw std::runtime_error(ss.str());
|
|
||||||
}
|
|
||||||
|
|
||||||
void PvaPut::issueGet()
|
|
||||||
{
|
|
||||||
if(isDestroyed) throw std::runtime_error("pvaPut was destroyed");
|
|
||||||
if(connectState==connectIdle) connect();
|
|
||||||
if(putState!=putIdle) {
|
|
||||||
stringstream ss;
|
|
||||||
ss << "channel " << channel->getChannelName() << " PvaPut::issueGet get or put aleady active ";
|
|
||||||
throw std::runtime_error(ss.str());
|
|
||||||
}
|
|
||||||
putState = getActive;
|
|
||||||
pvaData->getBitSet()->clear();
|
|
||||||
channelPut->get();
|
|
||||||
}
|
|
||||||
|
|
||||||
Status PvaPut::waitGet()
|
|
||||||
{
|
|
||||||
if(isDestroyed) throw std::runtime_error("pvaPut was destroyed");
|
|
||||||
if(putState!=getActive){
|
|
||||||
stringstream ss;
|
|
||||||
ss << "channel " << channel->getChannelName() << " PvaPut::waitGet llegal put state";
|
|
||||||
throw std::runtime_error(ss.str());
|
|
||||||
}
|
|
||||||
waitForGetPut.wait();
|
|
||||||
putState = putIdle;
|
|
||||||
if(channelGetPutStatus.isOK()) {
|
|
||||||
return Status::Ok;
|
|
||||||
}
|
|
||||||
return Status(Status::STATUSTYPE_ERROR,channelGetPutStatus.getMessage());
|
|
||||||
}
|
|
||||||
|
|
||||||
void PvaPut::put()
|
|
||||||
{
|
|
||||||
if(isDestroyed) throw std::runtime_error("pvaPut was destroyed");
|
|
||||||
issuePut();
|
|
||||||
Status status = waitPut();
|
|
||||||
if(status.isOK()) return;
|
|
||||||
stringstream ss;
|
|
||||||
ss << "channel " << channel->getChannelName() << " PvaPut::put " << status.getMessage();
|
|
||||||
throw std::runtime_error(ss.str());
|
|
||||||
}
|
|
||||||
|
|
||||||
void PvaPut::issuePut()
|
|
||||||
{
|
|
||||||
if(isDestroyed) throw std::runtime_error("pvaPut was destroyed");
|
|
||||||
if(connectState==connectIdle) connect();
|
|
||||||
if(putState!=putIdle) {
|
|
||||||
stringstream ss;
|
|
||||||
ss << "channel " << channel->getChannelName() << " PvaPut::issueGet get or put aleady active ";
|
|
||||||
throw std::runtime_error(ss.str());
|
|
||||||
}
|
|
||||||
putState = putActive;
|
|
||||||
channelPut->put(pvaData->getPVStructure(),pvaData->getBitSet());
|
|
||||||
}
|
|
||||||
|
|
||||||
Status PvaPut::waitPut()
|
|
||||||
{
|
|
||||||
if(isDestroyed) throw std::runtime_error("pvaPut was destroyed");
|
|
||||||
if(putState!=putActive){
|
|
||||||
stringstream ss;
|
|
||||||
ss << "channel " << channel->getChannelName() << " PvaPut::waitPut llegal put state";
|
|
||||||
throw std::runtime_error(ss.str());
|
|
||||||
}
|
|
||||||
waitForGetPut.wait();
|
|
||||||
putState = putIdle;
|
|
||||||
if(channelGetPutStatus.isOK()) {
|
|
||||||
pvaData->getBitSet()->clear();
|
|
||||||
return Status::Ok;
|
|
||||||
}
|
|
||||||
return Status(Status::STATUSTYPE_ERROR,channelGetPutStatus.getMessage());
|
|
||||||
}
|
|
||||||
|
|
||||||
PvaPutDataPtr PvaPut::getData()
|
|
||||||
{
|
|
||||||
checkPutState();
|
|
||||||
return pvaData;
|
|
||||||
}
|
|
||||||
|
|
||||||
PvaPutPtr PvaPut::create(
|
|
||||||
PvaPtr const &pva,
|
|
||||||
PvaChannelPtr const & pvaChannel,
|
|
||||||
Channel::shared_pointer const & channel,
|
|
||||||
PVStructurePtr const &pvRequest)
|
|
||||||
{
|
|
||||||
PvaPutPtr epv(new PvaPut(pva,pvaChannel,channel,pvRequest));
|
|
||||||
return epv;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}}
|
|
@ -1,267 +0,0 @@
|
|||||||
/* easyPutData.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 2015.02
|
|
||||||
*/
|
|
||||||
#define epicsExportSharedSymbols
|
|
||||||
|
|
||||||
#include <typeinfo>
|
|
||||||
|
|
||||||
#include <sstream>
|
|
||||||
#include <pv/pva.h>
|
|
||||||
#include <pv/createRequest.h>
|
|
||||||
#include <pv/convert.h>
|
|
||||||
|
|
||||||
|
|
||||||
using std::tr1::static_pointer_cast;
|
|
||||||
using namespace epics::pvData;
|
|
||||||
using namespace epics::pvAccess;
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
namespace epics { namespace pva {
|
|
||||||
|
|
||||||
class PvaPostHandlerPvt: public PostHandler
|
|
||||||
{
|
|
||||||
PvaPutData * easyData;
|
|
||||||
size_t fieldNumber;
|
|
||||||
public:
|
|
||||||
PvaPostHandlerPvt(PvaPutData *easyData,size_t fieldNumber)
|
|
||||||
: easyData(easyData),fieldNumber(fieldNumber){}
|
|
||||||
void postPut() { easyData->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");
|
|
||||||
|
|
||||||
PvaPutDataPtr PvaPutData::create(StructureConstPtr const & structure)
|
|
||||||
{
|
|
||||||
PvaPutDataPtr epv(new PvaPutData(structure));
|
|
||||||
return epv;
|
|
||||||
}
|
|
||||||
|
|
||||||
PvaPutData::PvaPutData(StructureConstPtr const & structure)
|
|
||||||
: structure(structure),
|
|
||||||
pvStructure(getPVDataCreate()->createPVStructure(structure)),
|
|
||||||
bitSet(BitSetPtr(new BitSet(pvStructure->getNumberFields())))
|
|
||||||
{
|
|
||||||
size_t nfields = pvStructure->getNumberFields();
|
|
||||||
postHandler.resize(nfields);
|
|
||||||
PVFieldPtr pvField;
|
|
||||||
for(size_t i =0; i<nfields; ++i)
|
|
||||||
{
|
|
||||||
postHandler[i] = PostHandlerPtr(new PvaPostHandlerPvt(this, i));
|
|
||||||
if(i==0) {
|
|
||||||
pvField = pvStructure;
|
|
||||||
} else {
|
|
||||||
pvField = pvStructure->getSubField(i);
|
|
||||||
}
|
|
||||||
pvField->setPostHandler(postHandler[i]);
|
|
||||||
}
|
|
||||||
pvValue = pvStructure->getSubField("value");
|
|
||||||
}
|
|
||||||
|
|
||||||
void PvaPutData::checkValue()
|
|
||||||
{
|
|
||||||
if(pvValue) return;
|
|
||||||
throw std::runtime_error(messagePrefix + noValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
void PvaPutData::postPut(size_t fieldNumber)
|
|
||||||
{
|
|
||||||
bitSet->set(fieldNumber);
|
|
||||||
}
|
|
||||||
|
|
||||||
void PvaPutData::setMessagePrefix(std::string const & value)
|
|
||||||
{
|
|
||||||
messagePrefix = value + " ";
|
|
||||||
}
|
|
||||||
|
|
||||||
StructureConstPtr PvaPutData::getStructure()
|
|
||||||
{return structure;}
|
|
||||||
|
|
||||||
PVStructurePtr PvaPutData::getPVStructure()
|
|
||||||
{return pvStructure;}
|
|
||||||
|
|
||||||
BitSetPtr PvaPutData::getBitSet()
|
|
||||||
{return bitSet;}
|
|
||||||
|
|
||||||
std::ostream & PvaPutData::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 PvaPutData::hasValue()
|
|
||||||
{
|
|
||||||
if(!pvValue) return false;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool PvaPutData::isValueScalar()
|
|
||||||
{
|
|
||||||
if(!pvValue) return false;
|
|
||||||
if(pvValue->getField()->getType()==scalar) return true;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool PvaPutData::isValueScalarArray()
|
|
||||||
{
|
|
||||||
if(!pvValue) return false;
|
|
||||||
if(pvValue->getField()->getType()==scalarArray) return true;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
PVFieldPtr PvaPutData::getValue()
|
|
||||||
{
|
|
||||||
checkValue();
|
|
||||||
return pvValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
PVScalarPtr PvaPutData::getScalarValue()
|
|
||||||
{
|
|
||||||
checkValue();
|
|
||||||
PVScalarPtr pv = pvStructure->getSubField<PVScalar>("value");
|
|
||||||
if(!pv) {
|
|
||||||
throw std::runtime_error(messagePrefix + notScalar);
|
|
||||||
}
|
|
||||||
return pv;
|
|
||||||
}
|
|
||||||
|
|
||||||
PVArrayPtr PvaPutData::getArrayValue()
|
|
||||||
{
|
|
||||||
checkValue();
|
|
||||||
PVArrayPtr pv = pvStructure->getSubField<PVArray>("value");
|
|
||||||
if(!pv) {
|
|
||||||
throw std::runtime_error(messagePrefix + notArray);
|
|
||||||
}
|
|
||||||
return pv;
|
|
||||||
}
|
|
||||||
|
|
||||||
PVScalarArrayPtr PvaPutData::getScalarArrayValue()
|
|
||||||
{
|
|
||||||
checkValue();
|
|
||||||
PVScalarArrayPtr pv = pvStructure->getSubField<PVScalarArray>("value");
|
|
||||||
if(!pv) {
|
|
||||||
throw std::runtime_error(messagePrefix + notScalarArray);
|
|
||||||
}
|
|
||||||
return pv;
|
|
||||||
}
|
|
||||||
|
|
||||||
double PvaPutData::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(notCompatibleScalar);
|
|
||||||
}
|
|
||||||
return convert->toDouble(pvScalar);
|
|
||||||
}
|
|
||||||
|
|
||||||
string PvaPutData::getString()
|
|
||||||
{
|
|
||||||
PVScalarPtr pvScalar = getScalarValue();
|
|
||||||
return convert->toString(pvScalar);
|
|
||||||
}
|
|
||||||
|
|
||||||
shared_vector<const double> PvaPutData::getDoubleArray()
|
|
||||||
{
|
|
||||||
checkValue();
|
|
||||||
PVDoubleArrayPtr pv = pvStructure->getSubField<PVDoubleArray>("value");
|
|
||||||
if(!pv) {
|
|
||||||
throw std::runtime_error(messagePrefix + notDoubleArray);
|
|
||||||
}
|
|
||||||
return pv->view();
|
|
||||||
}
|
|
||||||
|
|
||||||
shared_vector<const string> PvaPutData::getStringArray()
|
|
||||||
{
|
|
||||||
checkValue();
|
|
||||||
PVStringArrayPtr pv = pvStructure->getSubField<PVStringArray>("value");
|
|
||||||
if(!pv) {
|
|
||||||
throw std::runtime_error(messagePrefix + notStringArray);
|
|
||||||
}
|
|
||||||
return pv->view();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void PvaPutData::putDouble(double value)
|
|
||||||
{
|
|
||||||
PVScalarPtr pvScalar = getScalarValue();
|
|
||||||
ScalarType scalarType = pvScalar->getScalar()->getScalarType();
|
|
||||||
if(scalarType==pvDouble) {
|
|
||||||
PVDoublePtr pvDouble = static_pointer_cast<PVDouble>(pvScalar);
|
|
||||||
pvDouble->put(value);
|
|
||||||
}
|
|
||||||
if(!ScalarTypeFunc::isNumeric(scalarType)) {
|
|
||||||
throw std::runtime_error(messagePrefix + notCompatibleScalar);
|
|
||||||
}
|
|
||||||
convert->fromDouble(pvScalar,value);
|
|
||||||
}
|
|
||||||
|
|
||||||
void PvaPutData::putString(std::string const & value)
|
|
||||||
{
|
|
||||||
PVScalarPtr pvScalar = getScalarValue();
|
|
||||||
convert->fromString(pvScalar,value);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void PvaPutData::putDoubleArray(shared_vector<const double> const & value)
|
|
||||||
{
|
|
||||||
checkValue();
|
|
||||||
PVDoubleArrayPtr pv = pvStructure->getSubField<PVDoubleArray>("value");
|
|
||||||
if(!pv) {
|
|
||||||
throw std::runtime_error(messagePrefix + notDoubleArray);
|
|
||||||
}
|
|
||||||
pv->replace(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
void PvaPutData::putStringArray(shared_vector<const std::string> const & value)
|
|
||||||
{
|
|
||||||
checkValue();
|
|
||||||
PVStringArrayPtr pv = pvStructure->getSubField<PVStringArray>("value");
|
|
||||||
if(!pv) {
|
|
||||||
throw std::runtime_error(messagePrefix + notStringArray);
|
|
||||||
}
|
|
||||||
pv->replace(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
void PvaPutData::putStringArray(std::vector<std::string> const & value)
|
|
||||||
{
|
|
||||||
checkValue();
|
|
||||||
PVScalarArrayPtr pv = pvStructure->getSubField<PVScalarArray>("value");
|
|
||||||
if(!pv) {
|
|
||||||
throw std::runtime_error(messagePrefix + notScalarArray);
|
|
||||||
}
|
|
||||||
convert->fromStringArray(pv,0,value.size(),value,0);
|
|
||||||
}
|
|
||||||
|
|
||||||
}}
|
|
@ -1,378 +0,0 @@
|
|||||||
/* pvaPutGet.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 2015.02
|
|
||||||
*/
|
|
||||||
#define epicsExportSharedSymbols
|
|
||||||
|
|
||||||
#include <sstream>
|
|
||||||
#include <pv/event.h>
|
|
||||||
#include <pv/pva.h>
|
|
||||||
|
|
||||||
using std::tr1::static_pointer_cast;
|
|
||||||
using namespace epics::pvData;
|
|
||||||
using namespace epics::pvAccess;
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
namespace epics { namespace pva {
|
|
||||||
|
|
||||||
class ChannelPutGetRequesterImpl : public ChannelPutGetRequester
|
|
||||||
{
|
|
||||||
PvaPutGet * pvaPutGet;
|
|
||||||
public:
|
|
||||||
ChannelPutGetRequesterImpl(PvaPutGet * pvaPutGet)
|
|
||||||
: pvaPutGet(pvaPutGet) {}
|
|
||||||
string getRequesterName()
|
|
||||||
{return pvaPutGet->getRequesterName();}
|
|
||||||
void message(string const & message,MessageType messageType)
|
|
||||||
{pvaPutGet->message(message,messageType);}
|
|
||||||
void channelPutGetConnect(
|
|
||||||
const epics::pvData::Status& status,
|
|
||||||
epics::pvAccess::ChannelPutGet::shared_pointer const & channelPutGet,
|
|
||||||
epics::pvData::StructureConstPtr const & putStructure,
|
|
||||||
epics::pvData::StructureConstPtr const & getStructure)
|
|
||||||
{
|
|
||||||
pvaPutGet->channelPutGetConnect(status,channelPutGet,putStructure,getStructure);
|
|
||||||
}
|
|
||||||
void putGetDone(
|
|
||||||
const epics::pvData::Status& status,
|
|
||||||
epics::pvAccess::ChannelPutGet::shared_pointer const & channelPutGet,
|
|
||||||
epics::pvData::PVStructurePtr const & getPVStructure,
|
|
||||||
epics::pvData::BitSetPtr const & getBitSet)
|
|
||||||
{
|
|
||||||
pvaPutGet->putGetDone(status,channelPutGet,getPVStructure,getBitSet);
|
|
||||||
}
|
|
||||||
void getPutDone(
|
|
||||||
const epics::pvData::Status& status,
|
|
||||||
epics::pvAccess::ChannelPutGet::shared_pointer const & channelPutGet,
|
|
||||||
epics::pvData::PVStructurePtr const & putPVStructure,
|
|
||||||
epics::pvData::BitSet::shared_pointer const & putBitSet)
|
|
||||||
{
|
|
||||||
pvaPutGet->getPutDone(status,channelPutGet,putPVStructure,putBitSet);
|
|
||||||
}
|
|
||||||
void getGetDone(
|
|
||||||
const epics::pvData::Status& status,
|
|
||||||
epics::pvAccess::ChannelPutGet::shared_pointer const & channelPutGet,
|
|
||||||
epics::pvData::PVStructurePtr const & getPVStructure,
|
|
||||||
epics::pvData::BitSet::shared_pointer const & getBitSet)
|
|
||||||
{
|
|
||||||
pvaPutGet->getGetDone(status,channelPutGet,getPVStructure,getBitSet);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
PvaPutGet::PvaPutGet(
|
|
||||||
PvaPtr const &pva,
|
|
||||||
PvaChannelPtr const & pvaChannel,
|
|
||||||
Channel::shared_pointer const & channel,
|
|
||||||
PVStructurePtr const &pvRequest)
|
|
||||||
: pva(pva),
|
|
||||||
pvaChannel(pvaChannel),
|
|
||||||
channel(channel),
|
|
||||||
pvRequest(pvRequest),
|
|
||||||
isDestroyed(false),
|
|
||||||
connectState(connectIdle),
|
|
||||||
putGetState(putGetIdle)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
PvaPutGet::~PvaPutGet()
|
|
||||||
{
|
|
||||||
destroy();
|
|
||||||
}
|
|
||||||
|
|
||||||
void PvaPutGet::checkPutGetState()
|
|
||||||
{
|
|
||||||
if(isDestroyed) throw std::runtime_error("pvaPutGet was destroyed");
|
|
||||||
if(connectState==connectIdle){
|
|
||||||
connect();
|
|
||||||
getPut();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// from ChannelPutGetRequester
|
|
||||||
string PvaPutGet::getRequesterName()
|
|
||||||
{
|
|
||||||
PvaPtr yyy = pva.lock();
|
|
||||||
if(!yyy) throw std::runtime_error("pva was destroyed");
|
|
||||||
return yyy->getRequesterName();
|
|
||||||
}
|
|
||||||
|
|
||||||
void PvaPutGet::message(string const & message,MessageType messageType)
|
|
||||||
{
|
|
||||||
if(isDestroyed) throw std::runtime_error("pvaPutGet was destroyed");
|
|
||||||
PvaPtr yyy = pva.lock();
|
|
||||||
if(!yyy) throw std::runtime_error("pva was destroyed");
|
|
||||||
yyy->message(message, messageType);
|
|
||||||
}
|
|
||||||
|
|
||||||
void PvaPutGet::channelPutGetConnect(
|
|
||||||
const Status& status,
|
|
||||||
ChannelPutGet::shared_pointer const & channelPutGet,
|
|
||||||
StructureConstPtr const & putStructure,
|
|
||||||
StructureConstPtr const & getStructure)
|
|
||||||
{
|
|
||||||
if(isDestroyed) throw std::runtime_error("pvaPutGet was destroyed");
|
|
||||||
channelPutGetConnectStatus = status;
|
|
||||||
this->channelPutGet = channelPutGet;
|
|
||||||
if(status.isOK()) {
|
|
||||||
pvaPutData = PvaPutData::create(putStructure);
|
|
||||||
pvaPutData->setMessagePrefix(pvaChannel.lock()->getChannelName());
|
|
||||||
pvaGetData = PvaGetData::create(getStructure);
|
|
||||||
pvaGetData->setMessagePrefix(pvaChannel.lock()->getChannelName());
|
|
||||||
}
|
|
||||||
waitForConnect.signal();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void PvaPutGet::putGetDone(
|
|
||||||
const Status& status,
|
|
||||||
ChannelPutGet::shared_pointer const & channelPutGet,
|
|
||||||
PVStructurePtr const & getPVStructure,
|
|
||||||
BitSetPtr const & getBitSet)
|
|
||||||
{
|
|
||||||
if(isDestroyed) throw std::runtime_error("pvaPutGet was destroyed");
|
|
||||||
channelPutGetStatus = status;
|
|
||||||
if(status.isOK()) {
|
|
||||||
pvaGetData->setData(getPVStructure,getBitSet);
|
|
||||||
}
|
|
||||||
waitForPutGet.signal();
|
|
||||||
}
|
|
||||||
|
|
||||||
void PvaPutGet::getPutDone(
|
|
||||||
const Status& status,
|
|
||||||
ChannelPutGet::shared_pointer const & channelPutGet,
|
|
||||||
PVStructurePtr const & putPVStructure,
|
|
||||||
BitSetPtr const & putBitSet)
|
|
||||||
{
|
|
||||||
if(isDestroyed) throw std::runtime_error("pvaPutGet was destroyed");
|
|
||||||
channelGetPutGetStatus = status;
|
|
||||||
if(status.isOK()) {
|
|
||||||
PVStructurePtr pvs = pvaPutData->getPVStructure();
|
|
||||||
pvs->copyUnchecked(*putPVStructure,*putBitSet);
|
|
||||||
BitSetPtr bs = pvaPutData->getBitSet();
|
|
||||||
bs->clear();
|
|
||||||
*bs |= *putBitSet;
|
|
||||||
}
|
|
||||||
waitForPutGet.signal();
|
|
||||||
}
|
|
||||||
|
|
||||||
void PvaPutGet::getGetDone(
|
|
||||||
const Status& status,
|
|
||||||
ChannelPutGet::shared_pointer const & channelPutGet,
|
|
||||||
PVStructurePtr const & getPVStructure,
|
|
||||||
BitSetPtr const & getBitSet)
|
|
||||||
{
|
|
||||||
if(isDestroyed) throw std::runtime_error("pvaPutGet was destroyed");
|
|
||||||
channelPutGetStatus = status;
|
|
||||||
if(status.isOK()) {
|
|
||||||
pvaGetData->setData(getPVStructure,getBitSet);
|
|
||||||
}
|
|
||||||
waitForPutGet.signal();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// from PvaPutGet
|
|
||||||
void PvaPutGet::destroy()
|
|
||||||
{
|
|
||||||
{
|
|
||||||
Lock xx(mutex);
|
|
||||||
if(isDestroyed) return;
|
|
||||||
isDestroyed = true;
|
|
||||||
}
|
|
||||||
if(channelPutGet) channelPutGet->destroy();
|
|
||||||
channelPutGet.reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
void PvaPutGet::connect()
|
|
||||||
{
|
|
||||||
if(isDestroyed) throw std::runtime_error("pvaPutGet was destroyed");
|
|
||||||
issueConnect();
|
|
||||||
Status status = waitConnect();
|
|
||||||
if(status.isOK()) return;
|
|
||||||
stringstream ss;
|
|
||||||
ss << "channel " << channel->getChannelName() << " PvaPutGet::connect " << status.getMessage();
|
|
||||||
throw std::runtime_error(ss.str());
|
|
||||||
}
|
|
||||||
|
|
||||||
void PvaPutGet::issueConnect()
|
|
||||||
{
|
|
||||||
if(isDestroyed) throw std::runtime_error("pvaPutGet was destroyed");
|
|
||||||
if(connectState!=connectIdle) {
|
|
||||||
stringstream ss;
|
|
||||||
ss << "channel " << channel->getChannelName() << " pvaPutGet already connected ";
|
|
||||||
throw std::runtime_error(ss.str());
|
|
||||||
}
|
|
||||||
putGetRequester = ChannelPutGetRequester::shared_pointer(new ChannelPutGetRequesterImpl(this));
|
|
||||||
connectState = connectActive;
|
|
||||||
channelPutGet = channel->createChannelPutGet(putGetRequester,pvRequest);
|
|
||||||
}
|
|
||||||
|
|
||||||
Status PvaPutGet::waitConnect()
|
|
||||||
{
|
|
||||||
if(isDestroyed) throw std::runtime_error("pvaPutGet was destroyed");
|
|
||||||
if(connectState!=connectActive) {
|
|
||||||
stringstream ss;
|
|
||||||
ss << "channel " << channel->getChannelName() << " pvaPutGet illegal connect state ";
|
|
||||||
throw std::runtime_error(ss.str());
|
|
||||||
}
|
|
||||||
waitForConnect.wait();
|
|
||||||
if(channelPutGetConnectStatus.isOK()) {
|
|
||||||
connectState = connected;
|
|
||||||
return Status::Ok;
|
|
||||||
}
|
|
||||||
connectState = connectIdle;
|
|
||||||
return Status(Status::STATUSTYPE_ERROR,channelPutGetConnectStatus.getMessage());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void PvaPutGet::putGet()
|
|
||||||
{
|
|
||||||
if(isDestroyed) throw std::runtime_error("pvaPutGet was destroyed");
|
|
||||||
issuePutGet();
|
|
||||||
Status status = waitPutGet();
|
|
||||||
if(status.isOK()) return;
|
|
||||||
stringstream ss;
|
|
||||||
ss << "channel " << channel->getChannelName() << " PvaPutGet::putGet " << status.getMessage();
|
|
||||||
throw std::runtime_error(ss.str());
|
|
||||||
}
|
|
||||||
|
|
||||||
void PvaPutGet::issuePutGet()
|
|
||||||
{
|
|
||||||
if(isDestroyed) throw std::runtime_error("pvaPutGet was destroyed");
|
|
||||||
if(connectState==connectIdle) connect();
|
|
||||||
if(putGetState!=putGetIdle) {
|
|
||||||
stringstream ss;
|
|
||||||
ss << "channel " << channel->getChannelName() << " PvaPutGet::issueGet get or put aleady active ";
|
|
||||||
throw std::runtime_error(ss.str());
|
|
||||||
}
|
|
||||||
putGetState = putGetActive;
|
|
||||||
channelPutGet->putGet(pvaPutData->getPVStructure(),pvaPutData->getBitSet());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Status PvaPutGet::waitPutGet()
|
|
||||||
{
|
|
||||||
if(isDestroyed) throw std::runtime_error("pvaPutGet was destroyed");
|
|
||||||
if(putGetState!=putGetActive){
|
|
||||||
stringstream ss;
|
|
||||||
ss << "channel " << channel->getChannelName() << " PvaPutGet::waitPutGet llegal put state";
|
|
||||||
throw std::runtime_error(ss.str());
|
|
||||||
}
|
|
||||||
waitForPutGet.wait();
|
|
||||||
putGetState = putGetIdle;
|
|
||||||
if(channelGetPutGetStatus.isOK()) {
|
|
||||||
return Status::Ok;
|
|
||||||
}
|
|
||||||
return Status(Status::STATUSTYPE_ERROR,channelGetPutGetStatus.getMessage());
|
|
||||||
}
|
|
||||||
|
|
||||||
void PvaPutGet::getGet()
|
|
||||||
{
|
|
||||||
if(isDestroyed) throw std::runtime_error("pvaPutGet was destroyed");
|
|
||||||
issueGetGet();
|
|
||||||
Status status = waitGetGet();
|
|
||||||
if(status.isOK()) return;
|
|
||||||
stringstream ss;
|
|
||||||
ss << "channel " << channel->getChannelName() << " PvaPutGet::getGet " << status.getMessage();
|
|
||||||
throw std::runtime_error(ss.str());
|
|
||||||
}
|
|
||||||
|
|
||||||
void PvaPutGet::issueGetGet()
|
|
||||||
{
|
|
||||||
if(isDestroyed) throw std::runtime_error("pvaPutGet was destroyed");
|
|
||||||
if(connectState==connectIdle) connect();
|
|
||||||
if(putGetState!=putGetIdle) {
|
|
||||||
stringstream ss;
|
|
||||||
ss << "channel " << channel->getChannelName() << " PvaPutGet::issueGetGet aleady active ";
|
|
||||||
throw std::runtime_error(ss.str());
|
|
||||||
}
|
|
||||||
putGetState = putGetActive;
|
|
||||||
channelPutGet->getGet();
|
|
||||||
}
|
|
||||||
|
|
||||||
Status PvaPutGet::waitGetGet()
|
|
||||||
{
|
|
||||||
if(isDestroyed) throw std::runtime_error("pvaPutGet was destroyed");
|
|
||||||
if(putGetState!=putGetActive){
|
|
||||||
stringstream ss;
|
|
||||||
ss << "channel " << channel->getChannelName() << " PvaPutGet::waitGetGet illegal state";
|
|
||||||
throw std::runtime_error(ss.str());
|
|
||||||
}
|
|
||||||
waitForPutGet.wait();
|
|
||||||
putGetState = putGetIdle;
|
|
||||||
if(channelGetPutGetStatus.isOK()) {
|
|
||||||
return Status::Ok;
|
|
||||||
}
|
|
||||||
return Status(Status::STATUSTYPE_ERROR,channelGetPutGetStatus.getMessage());
|
|
||||||
}
|
|
||||||
|
|
||||||
void PvaPutGet::getPut()
|
|
||||||
{
|
|
||||||
if(isDestroyed) throw std::runtime_error("pvaPutGet was destroyed");
|
|
||||||
issueGetPut();
|
|
||||||
Status status = waitGetPut();
|
|
||||||
if(status.isOK()) return;
|
|
||||||
stringstream ss;
|
|
||||||
ss << "channel " << channel->getChannelName() << " PvaPutGet::getPut " << status.getMessage();
|
|
||||||
throw std::runtime_error(ss.str());
|
|
||||||
}
|
|
||||||
|
|
||||||
void PvaPutGet::issueGetPut()
|
|
||||||
{
|
|
||||||
if(isDestroyed) throw std::runtime_error("pvaPutGet was destroyed");
|
|
||||||
if(connectState==connectIdle) connect();
|
|
||||||
if(putGetState!=putGetIdle) {
|
|
||||||
stringstream ss;
|
|
||||||
ss << "channel " << channel->getChannelName() << " PvaPutGet::issueGetPut aleady active ";
|
|
||||||
throw std::runtime_error(ss.str());
|
|
||||||
}
|
|
||||||
putGetState = putGetActive;
|
|
||||||
channelPutGet->getPut();
|
|
||||||
}
|
|
||||||
|
|
||||||
Status PvaPutGet::waitGetPut()
|
|
||||||
{
|
|
||||||
if(isDestroyed) throw std::runtime_error("pvaPutGet was destroyed");
|
|
||||||
if(putGetState!=putGetActive){
|
|
||||||
stringstream ss;
|
|
||||||
ss << "channel " << channel->getChannelName() << " PvaPutGet::waitGetPut illegal state";
|
|
||||||
throw std::runtime_error(ss.str());
|
|
||||||
}
|
|
||||||
waitForPutGet.wait();
|
|
||||||
putGetState = putGetIdle;
|
|
||||||
if(channelGetPutGetStatus.isOK()) {
|
|
||||||
return Status::Ok;
|
|
||||||
}
|
|
||||||
return Status(Status::STATUSTYPE_ERROR,channelGetPutGetStatus.getMessage());
|
|
||||||
}
|
|
||||||
|
|
||||||
PvaGetDataPtr PvaPutGet::getGetData()
|
|
||||||
{
|
|
||||||
checkPutGetState();
|
|
||||||
return pvaGetData;
|
|
||||||
}
|
|
||||||
|
|
||||||
PvaPutDataPtr PvaPutGet::getPutData()
|
|
||||||
{
|
|
||||||
checkPutGetState();
|
|
||||||
return pvaPutData;
|
|
||||||
}
|
|
||||||
|
|
||||||
PvaPutGetPtr PvaPutGet::create(
|
|
||||||
PvaPtr const &pva,
|
|
||||||
PvaChannelPtr const & pvaChannel,
|
|
||||||
Channel::shared_pointer const & channel,
|
|
||||||
PVStructurePtr const &pvRequest)
|
|
||||||
{
|
|
||||||
PvaPutGetPtr epv(new PvaPutGet(pva,pvaChannel,channel,pvRequest));
|
|
||||||
return epv;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}}
|
|
120
pvaSrc/temp
120
pvaSrc/temp
@ -1,120 +0,0 @@
|
|||||||
make -C O.linux-x86_64 -f ../Makefile TOP=../.. T_A=linux-x86_64 install
|
|
||||||
make[1]: Entering directory `/home/epicsv4/pvAccessCPP/pvaSrc/O.linux-x86_64'
|
|
||||||
|
|
||||||
/usr/bin/g++ -c -D_POSIX_C_SOURCE=199506L -D_POSIX_THREADS -D_XOPEN_SOURCE=500 -g -ggdb -D_X86_64_ -DUNIX -D_BSD_SOURCE -Dlinux -D_REENTRANT -O3 -g -Wall -m64 -fPIC -MMD -I. -I../O.Common -I. -I.. -I../../include/pv/os/Linux -I../../include/pv -I/home/install/epics/base/include/os/Linux -I/home/install/epics/base/include -I/home/epicsv4/pvCommonCPP/include -I/home/epicsv4/pvDataCPP/include -I/home/epicsv4/pvAccessCPP/include -I/home/epicsv4/pvaSrv/include -I/home/epicsv4/normativeTypesCPP/include -I../../include ../pvaNTMultiChannel.cpp
|
|
||||||
In file included from ../pvaNTMultiChannel.cpp:13:0:
|
|
||||||
/home/epicsv4/pvAccessCPP/include/pv/pvaNTMultiChannel.h:75:5: error: ‘PVAMultiChannelPtr’ does not name a type
|
|
||||||
PVAMultiChannelPtr getPVAMultiChannel();
|
|
||||||
^
|
|
||||||
/home/epicsv4/pvAccessCPP/include/pv/pvaNTMultiChannel.h:78:28: error: expected ‘)’ before ‘const’
|
|
||||||
PVAMultiChannelPtr const & channelName,
|
|
||||||
^
|
|
||||||
/home/epicsv4/pvAccessCPP/include/pv/pvaNTMultiChannel.h:83:5: error: ‘PVAMultiChannelPtr’ does not name a type
|
|
||||||
PVAMultiChannelPtr pvaMultiChannel;
|
|
||||||
^
|
|
||||||
/home/epicsv4/pvAccessCPP/include/pv/pvaNTMultiChannel.h:87:17: error: ‘PVAGetPtr’ was not declared in this scope
|
|
||||||
std::vector<PVAGetPtr> pvaGet;
|
|
||||||
^
|
|
||||||
/home/epicsv4/pvAccessCPP/include/pv/pvaNTMultiChannel.h:87:26: error: template argument 1 is invalid
|
|
||||||
std::vector<PVAGetPtr> pvaGet;
|
|
||||||
^
|
|
||||||
/home/epicsv4/pvAccessCPP/include/pv/pvaNTMultiChannel.h:87:26: error: template argument 2 is invalid
|
|
||||||
/home/epicsv4/pvAccessCPP/include/pv/pvaNTMultiChannel.h:88:17: error: ‘PVAPutPtr’ was not declared in this scope
|
|
||||||
std::vector<PVAPutPtr> pvaPut;
|
|
||||||
^
|
|
||||||
/home/epicsv4/pvAccessCPP/include/pv/pvaNTMultiChannel.h:88:26: error: template argument 1 is invalid
|
|
||||||
std::vector<PVAPutPtr> pvaPut;
|
|
||||||
^
|
|
||||||
/home/epicsv4/pvAccessCPP/include/pv/pvaNTMultiChannel.h:88:26: error: template argument 2 is invalid
|
|
||||||
../pvaNTMultiChannel.cpp: In static member function ‘static epics::pva::PvaNTMultiChannelPtr epics::pva::PvaNTMultiChannel::create(const PvaPtr&, const PVStringArrayPtr&, const StructureConstPtr&, double, const string&)’:
|
|
||||||
../pvaNTMultiChannel.cpp:41:85: error: no matching function for call to ‘epics::pva::PvaNTMultiChannel::PvaNTMultiChannel(epics::pva::PvaMultiChannelPtr&, epics::nt::NTMultiChannelPtr&)’
|
|
||||||
return PvaNTMultiChannelPtr(new PvaNTMultiChannel(pvaMultiChannel,ntMultiChannel));
|
|
||||||
^
|
|
||||||
../pvaNTMultiChannel.cpp:41:85: note: candidates are:
|
|
||||||
In file included from ../pvaNTMultiChannel.cpp:13:0:
|
|
||||||
/home/epicsv4/pvAccessCPP/include/pv/pvaNTMultiChannel.h:34:23: note: epics::pva::PvaNTMultiChannel::PvaNTMultiChannel()
|
|
||||||
class epicsShareClass PvaNTMultiChannel
|
|
||||||
^
|
|
||||||
/home/epicsv4/pvAccessCPP/include/pv/pvaNTMultiChannel.h:34:23: note: candidate expects 0 arguments, 2 provided
|
|
||||||
/home/epicsv4/pvAccessCPP/include/pv/pvaNTMultiChannel.h:34:23: note: epics::pva::PvaNTMultiChannel::PvaNTMultiChannel(const epics::pva::PvaNTMultiChannel&)
|
|
||||||
/home/epicsv4/pvAccessCPP/include/pv/pvaNTMultiChannel.h:34:23: note: candidate expects 1 argument, 2 provided
|
|
||||||
../pvaNTMultiChannel.cpp: At global scope:
|
|
||||||
../pvaNTMultiChannel.cpp:44:1: error: prototype for ‘epics::pva::PvaNTMultiChannel::PvaNTMultiChannel(const PvaMultiChannelPtr&, const NTMultiChannelPtr&)’ does not match any in class ‘epics::pva::PvaNTMultiChannel’
|
|
||||||
PvaNTMultiChannel::PvaNTMultiChannel(
|
|
||||||
^
|
|
||||||
In file included from ../pvaNTMultiChannel.cpp:13:0:
|
|
||||||
/home/epicsv4/pvAccessCPP/include/pv/pvaNTMultiChannel.h:34:23: error: candidates are: epics::pva::PvaNTMultiChannel::PvaNTMultiChannel(const epics::pva::PvaNTMultiChannel&)
|
|
||||||
class epicsShareClass PvaNTMultiChannel
|
|
||||||
^
|
|
||||||
/home/epicsv4/pvAccessCPP/include/pv/pvaNTMultiChannel.h:34:23: error: epics::pva::PvaNTMultiChannel::PvaNTMultiChannel()
|
|
||||||
../pvaNTMultiChannel.cpp: In member function ‘void epics::pva::PvaNTMultiChannel::createGet()’:
|
|
||||||
../pvaNTMultiChannel.cpp:72:42: error: ‘pvaMultiChannel’ was not declared in this scope
|
|
||||||
PvaChannelArrayPtr pvaChannelArray = pvaMultiChannel->getPvaChannelArray().lock();
|
|
||||||
^
|
|
||||||
../pvaNTMultiChannel.cpp:76:12: error: cannot convert ‘std::vector<std::tr1::shared_ptr<epics::pva::PvaGet> >’ to ‘int’ in assignment
|
|
||||||
pvaGet = std::vector<PvaGetPtr>(numChannel,PvaGetPtr());
|
|
||||||
^
|
|
||||||
../pvaNTMultiChannel.cpp:81:17: error: invalid types ‘int[size_t {aka long unsigned int}]’ for array subscript
|
|
||||||
pvaGet[i] = pvaChannels[i]->createGet(request);
|
|
||||||
^
|
|
||||||
../pvaNTMultiChannel.cpp:82:17: error: invalid types ‘int[size_t {aka long unsigned int}]’ for array subscript
|
|
||||||
pvaGet[i]->issueConnect();
|
|
||||||
^
|
|
||||||
../pvaNTMultiChannel.cpp:86:34: error: invalid types ‘int[size_t {aka long unsigned int}]’ for array subscript
|
|
||||||
Status status = pvaGet[i]->waitConnect();
|
|
||||||
^
|
|
||||||
../pvaNTMultiChannel.cpp: In member function ‘void epics::pva::PvaNTMultiChannel::createPut()’:
|
|
||||||
../pvaNTMultiChannel.cpp:99:42: error: ‘pvaMultiChannel’ was not declared in this scope
|
|
||||||
PvaChannelArrayPtr pvaChannelArray = pvaMultiChannel->getPvaChannelArray().lock();
|
|
||||||
^
|
|
||||||
../pvaNTMultiChannel.cpp:103:12: error: cannot convert ‘std::vector<std::tr1::shared_ptr<epics::pva::PvaPut> >’ to ‘int’ in assignment
|
|
||||||
pvaPut = std::vector<PvaPutPtr>(numChannel,PvaPutPtr());
|
|
||||||
^
|
|
||||||
../pvaNTMultiChannel.cpp:108:17: error: invalid types ‘int[size_t {aka long unsigned int}]’ for array subscript
|
|
||||||
pvaPut[i] = pvaChannels[i]->createPut("value");
|
|
||||||
^
|
|
||||||
../pvaNTMultiChannel.cpp:109:17: error: invalid types ‘int[size_t {aka long unsigned int}]’ for array subscript
|
|
||||||
pvaPut[i]->issueConnect();
|
|
||||||
^
|
|
||||||
../pvaNTMultiChannel.cpp:113:34: error: invalid types ‘int[size_t {aka long unsigned int}]’ for array subscript
|
|
||||||
Status status = pvaPut[i]->waitConnect();
|
|
||||||
^
|
|
||||||
../pvaNTMultiChannel.cpp: In member function ‘epics::nt::NTMultiChannelPtr epics::pva::PvaNTMultiChannel::get()’:
|
|
||||||
../pvaNTMultiChannel.cpp:125:15: error: request for member ‘empty’ in ‘((epics::pva::PvaNTMultiChannel*)this)->epics::pva::PvaNTMultiChannel::pvaGet’, which is of non-class type ‘int’
|
|
||||||
if(pvaGet.empty()) createGet();
|
|
||||||
^
|
|
||||||
../pvaNTMultiChannel.cpp:127:48: error: ‘pvaMultiChannel’ was not declared in this scope
|
|
||||||
shared_vector<const string> channelNames = pvaMultiChannel->getChannelNames()->view();
|
|
||||||
^
|
|
||||||
../pvaNTMultiChannel.cpp:162:17: error: invalid types ‘int[size_t {aka long unsigned int}]’ for array subscript
|
|
||||||
pvaGet[i]->issueGet();
|
|
||||||
^
|
|
||||||
../pvaNTMultiChannel.cpp:166:31: error: invalid types ‘int[size_t {aka long unsigned int}]’ for array subscript
|
|
||||||
Status stat = pvaGet[i]->waitGet();
|
|
||||||
^
|
|
||||||
../pvaNTMultiChannel.cpp:171:46: error: invalid types ‘int[size_t {aka long unsigned int}]’ for array subscript
|
|
||||||
PVStructurePtr pvStructure = pvaGet[i]->getData()->getPVStructure();
|
|
||||||
^
|
|
||||||
../pvaNTMultiChannel.cpp: In member function ‘void epics::pva::PvaNTMultiChannel::put(const NTMultiChannelPtr&)’:
|
|
||||||
../pvaNTMultiChannel.cpp:234:15: error: request for member ‘empty’ in ‘((epics::pva::PvaNTMultiChannel*)this)->epics::pva::PvaNTMultiChannel::pvaPut’, which is of non-class type ‘int’
|
|
||||||
if(pvaPut.empty()) createPut();
|
|
||||||
^
|
|
||||||
../pvaNTMultiChannel.cpp:235:48: error: ‘pvaMultiChannel’ was not declared in this scope
|
|
||||||
shared_vector<const string> channelNames = pvaMultiChannel->getChannelNames()->view();
|
|
||||||
^
|
|
||||||
../pvaNTMultiChannel.cpp:244:39: error: invalid types ‘int[size_t {aka long unsigned int}]’ for array subscript
|
|
||||||
PVFieldPtr pvTo = pvaPut[i]->getData()->getValue();
|
|
||||||
^
|
|
||||||
../pvaNTMultiChannel.cpp:252:21: error: invalid types ‘int[size_t {aka long unsigned int}]’ for array subscript
|
|
||||||
pvaPut[i]->issuePut();
|
|
||||||
^
|
|
||||||
../pvaNTMultiChannel.cpp:260:33: error: invalid types ‘int[size_t {aka long unsigned int}]’ for array subscript
|
|
||||||
Status status = pvaPut[i]->waitPut();
|
|
||||||
^
|
|
||||||
../pvaNTMultiChannel.cpp: In static member function ‘static epics::pva::PvaNTMultiChannelPtr epics::pva::PvaNTMultiChannel::create(const PvaPtr&, const PVStringArrayPtr&, const StructureConstPtr&, double, const string&)’:
|
|
||||||
../pvaNTMultiChannel.cpp:42:1: warning: control reaches end of non-void function [-Wreturn-type]
|
|
||||||
}
|
|
||||||
^
|
|
||||||
make[1]: *** [pvaNTMultiChannel.o] Error 1
|
|
||||||
make[1]: Leaving directory `/home/epicsv4/pvAccessCPP/pvaSrc/O.linux-x86_64'
|
|
||||||
make: *** [install.linux-x86_64] Error 2
|
|
@ -1,13 +0,0 @@
|
|||||||
# Makefile at top of application tree
|
|
||||||
|
|
||||||
TOP = .
|
|
||||||
include $(TOP)/configure/CONFIG
|
|
||||||
|
|
||||||
DIRS += configure
|
|
||||||
|
|
||||||
DIRS += src
|
|
||||||
src_DEPEND_DIRS = configure
|
|
||||||
|
|
||||||
include $(TOP)/configure/RULES_TOP
|
|
||||||
|
|
||||||
|
|
@ -1,29 +0,0 @@
|
|||||||
# CONFIG - Load build configuration data
|
|
||||||
#
|
|
||||||
# Do not make changes to this file!
|
|
||||||
|
|
||||||
# Allow user to override where the build rules come from
|
|
||||||
RULES = $(EPICS_BASE)
|
|
||||||
|
|
||||||
# RELEASE files point to other application tops
|
|
||||||
include $(TOP)/configure/RELEASE
|
|
||||||
-include $(TOP)/configure/RELEASE.$(EPICS_HOST_ARCH).Common
|
|
||||||
ifdef T_A
|
|
||||||
-include $(TOP)/configure/RELEASE.Common.$(T_A)
|
|
||||||
-include $(TOP)/configure/RELEASE.$(EPICS_HOST_ARCH).$(T_A)
|
|
||||||
endif
|
|
||||||
|
|
||||||
CONFIG = $(RULES)/configure
|
|
||||||
include $(CONFIG)/CONFIG
|
|
||||||
|
|
||||||
# Override the Base definition:
|
|
||||||
INSTALL_LOCATION = $(TOP)
|
|
||||||
|
|
||||||
# CONFIG_SITE files contain other build configuration settings
|
|
||||||
include $(TOP)/configure/CONFIG_SITE
|
|
||||||
-include $(TOP)/configure/CONFIG_SITE.$(EPICS_HOST_ARCH).Common
|
|
||||||
ifdef T_A
|
|
||||||
-include $(TOP)/configure/CONFIG_SITE.Common.$(T_A)
|
|
||||||
-include $(TOP)/configure/CONFIG_SITE.$(EPICS_HOST_ARCH).$(T_A)
|
|
||||||
endif
|
|
||||||
|
|
@ -1,27 +0,0 @@
|
|||||||
# CONFIG_SITE
|
|
||||||
|
|
||||||
# Make any application-specific changes to the EPICS build
|
|
||||||
# configuration variables in this file.
|
|
||||||
#
|
|
||||||
# Host/target specific settings can be specified in files named
|
|
||||||
# CONFIG_SITE.$(EPICS_HOST_ARCH).Common
|
|
||||||
# CONFIG_SITE.Common.$(T_A)
|
|
||||||
# CONFIG_SITE.$(EPICS_HOST_ARCH).$(T_A)
|
|
||||||
|
|
||||||
# CHECK_RELEASE controls the consistency checking of the support
|
|
||||||
# applications pointed to by the RELEASE* files.
|
|
||||||
# Normally CHECK_RELEASE should be set to YES.
|
|
||||||
# Set CHECK_RELEASE to NO to disable checking completely.
|
|
||||||
# Set CHECK_RELEASE to WARN to perform consistency checking but
|
|
||||||
# continue building anyway if conflicts are found.
|
|
||||||
CHECK_RELEASE = WARN
|
|
||||||
|
|
||||||
# To install files into a location other than $(TOP) define
|
|
||||||
# INSTALL_LOCATION here.
|
|
||||||
#INSTALL_LOCATION=</path/name/to/install/top>
|
|
||||||
|
|
||||||
INSTALL_INCLUDE = $(INSTALL_LOCATION)/include/pv
|
|
||||||
USR_INCLUDES += -I $(INSTALL_LOCATION)/include
|
|
||||||
|
|
||||||
-include $(TOP)/../../CONFIG_SITE.local
|
|
||||||
-include $(TOP)/../configure/CONFIG_SITE.local
|
|
@ -1,6 +0,0 @@
|
|||||||
EPICS_BASE=/home/install/epics/base
|
|
||||||
TEMPLATE_TOP=$(EPICS_BASE)/templates/makeBaseApp/top
|
|
||||||
EPICSV4HOME=/home/epicsv4
|
|
||||||
PVCOMMON=${EPICSV4HOME}/pvCommonCPP
|
|
||||||
PVDATA=${EPICSV4HOME}/pvDataCPP
|
|
||||||
PVACCESS=${EPICSV4HOME}/pvAccessCPP
|
|
@ -1,8 +0,0 @@
|
|||||||
TOP=..
|
|
||||||
|
|
||||||
include $(TOP)/configure/CONFIG
|
|
||||||
|
|
||||||
TARGETS = $(CONFIG_TARGETS)
|
|
||||||
CONFIGS += $(subst ../,,$(wildcard $(CONFIG_INSTALLS)))
|
|
||||||
|
|
||||||
include $(TOP)/configure/RULES
|
|
@ -1,41 +0,0 @@
|
|||||||
# pvDatabaseCPP/example RELEASE - Location of external support modules
|
|
||||||
#
|
|
||||||
# IF YOU CHANGE this file or any file it includes you must
|
|
||||||
# subsequently do a "gnumake rebuild" in the application's
|
|
||||||
# top level directory.
|
|
||||||
#
|
|
||||||
# The build process does not check dependencies against files
|
|
||||||
# that are outside this application, thus you should also do a
|
|
||||||
# "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
|
|
||||||
# RELEASE.$(EPICS_HOST_ARCH).Common
|
|
||||||
# RELEASE.Common.$(T_A)
|
|
||||||
# RELEASE.$(EPICS_HOST_ARCH).$(T_A)
|
|
||||||
|
|
||||||
# EPICS V4 Developers: Do not edit the locations in this file!
|
|
||||||
#
|
|
||||||
# Create a file RELEASE.local pointing to your PVASRV, PVACCESS,
|
|
||||||
# PVDATA, PVCOMMON and EPICS_BASE build directories, e.g.
|
|
||||||
# PVASRV = /path/to/epics/pvaSrvCPP
|
|
||||||
# PVACCESS = /path/to/epics/pvAccessCPP
|
|
||||||
# PVDATA = /path/to/epics/pvDataCPP
|
|
||||||
# PVCOMMON = /path/to/epics/pvCommonCPP
|
|
||||||
# EPICS_BASE = /path/to/epics/base
|
|
||||||
|
|
||||||
# If this example is built in a directory under pvDatabaseCPP,
|
|
||||||
# use the following definitions:
|
|
||||||
|
|
||||||
EASYPVA = $(TOP)/..
|
|
||||||
|
|
||||||
-include $(TOP)/../configure/RELEASE.local
|
|
||||||
-include $(TOP)/../../RELEASE.local
|
|
||||||
|
|
||||||
# If you copied this example from pvDatabaseCPP to be built as a
|
|
||||||
# standalone TOP, adjust and use the following definitions:
|
|
||||||
|
|
||||||
#EASYPVA = /path/to/epics/easyPVACPP
|
|
||||||
|
|
||||||
#-include $(TOP)/../RELEASE.local
|
|
||||||
#-include $(TOP)/configure/RELEASE.local
|
|
@ -1,6 +0,0 @@
|
|||||||
# RULES
|
|
||||||
|
|
||||||
include $(CONFIG)/RULES
|
|
||||||
|
|
||||||
# Library should be rebuilt because LIBOBJS may have changed.
|
|
||||||
$(LIBNAME): ../Makefile
|
|
@ -1,2 +0,0 @@
|
|||||||
#RULES.ioc
|
|
||||||
include $(CONFIG)/RULES.ioc
|
|
@ -1,2 +0,0 @@
|
|||||||
#RULES_DIRS
|
|
||||||
include $(CONFIG)/RULES_DIRS
|
|
@ -1,3 +0,0 @@
|
|||||||
#RULES_TOP
|
|
||||||
include $(CONFIG)/RULES_TOP
|
|
||||||
|
|
@ -1,57 +0,0 @@
|
|||||||
# Makefile for the pvAccess tests
|
|
||||||
|
|
||||||
TOP = ..
|
|
||||||
include $(TOP)/configure/CONFIG
|
|
||||||
|
|
||||||
TESTPROD_HOST += testPvaPutData
|
|
||||||
testPvaPutData_SRCS = testPvaPutData
|
|
||||||
testHarness_SRCS += testPvaPutData.cpp
|
|
||||||
TESTS += testPvaPutData
|
|
||||||
|
|
||||||
TESTPROD_HOST += testPvaGetData
|
|
||||||
testPvaGetData_SRCS = testPvaGetData
|
|
||||||
testHarness_SRCS += testPvaGetData.cpp
|
|
||||||
TESTS += testPvaGetData
|
|
||||||
|
|
||||||
TESTPROD_HOST += testPvaMonitorData
|
|
||||||
testPvaMonitorData_SRCS = testPvaMonitorData
|
|
||||||
testHarness_SRCS += testPvaMonitorData.cpp
|
|
||||||
TESTS += testPvaMonitorData
|
|
||||||
|
|
||||||
TESTPROD_HOST += testPvaPutGetMonitor
|
|
||||||
testPvaPutGetMonitor_SRCS = testPvaPutGetMonitor
|
|
||||||
testHarness_SRCS += testPvaPutGetMonitor.cpp
|
|
||||||
TESTS += testPvaPutGetMonitor
|
|
||||||
|
|
||||||
TESTPROD_HOST += testPvaPutGet
|
|
||||||
testPvaPutGet_SRCS = testPvaPutGet
|
|
||||||
testHarness_SRCS += testPvaPutGet.cpp
|
|
||||||
TESTS += testPvaPutGet
|
|
||||||
|
|
||||||
TESTPROD_HOST += testPvaMultiDouble
|
|
||||||
testPvaMultiDouble_SRCS = testPvaMultiDouble
|
|
||||||
testHarness_SRCS += testPvaMultiDouble.cpp
|
|
||||||
TESTS += testPvaMultiDouble
|
|
||||||
|
|
||||||
TESTPROD_HOST += testPvaNTMultiChannel
|
|
||||||
testPvaNTMultiChannel_SRCS = testPvaNTMultiChannel
|
|
||||||
testHarness_SRCS += testPvaNTMultiChannel.cpp
|
|
||||||
TESTS += testPvaNTMultiChannel
|
|
||||||
|
|
||||||
|
|
||||||
PROD_LIBS += pva pvAccess pvData nt Com
|
|
||||||
|
|
||||||
testHarness_SRCS += easyAllTests.c
|
|
||||||
|
|
||||||
PROD_vxWorks = vxTestHarness
|
|
||||||
vxTestHarness_SRCS += $(testHarness_SRCS)
|
|
||||||
TESTSPEC_vxWorks = vxTestHarness.$(MUNCH_SUFFIX); easyAllTests
|
|
||||||
|
|
||||||
PROD_RTEMS += rtemsTestHarness
|
|
||||||
rtemsTestHarness_SRCS += rtemsTestHarness.c rtemsConfig.c
|
|
||||||
rtemsTestHarness_SRCS += $(testHarness_SRCS)
|
|
||||||
TESTSPEC_RTEMS = rtemsTestHarness.$(MUNCH_SUFFIX); easyAllTests
|
|
||||||
|
|
||||||
TESTSCRIPTS_HOST += $(TESTS:%=%.t)
|
|
||||||
|
|
||||||
include $(TOP)/configure/RULES
|
|
@ -1,31 +0,0 @@
|
|||||||
/*
|
|
||||||
* Run PvaPVA tests as a batch.
|
|
||||||
*
|
|
||||||
* Do *not* include performance measurements here, they don't help to
|
|
||||||
* prove functionality (which is the point of this convenience routine).
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <epicsThread.h>
|
|
||||||
#include <epicsUnitTest.h>
|
|
||||||
|
|
||||||
int testPvaGetData(void);
|
|
||||||
int testPvaPutData(void);
|
|
||||||
int testPvaMonitorData(void);
|
|
||||||
int testPvaPutGetMonitor(void);
|
|
||||||
int testPvaPutGet(void);
|
|
||||||
int testPvaMultiDouble(void);
|
|
||||||
int testPvaNTMultiChannel(void);
|
|
||||||
|
|
||||||
void easyAllTests(void)
|
|
||||||
{
|
|
||||||
testHarness();
|
|
||||||
runTest(testPvaGetData);
|
|
||||||
runTest(testPvaPutData);
|
|
||||||
runTest(testPvaMonitorData);
|
|
||||||
runTest(testPvaPutMonitor);
|
|
||||||
runTest(testPvaPut);
|
|
||||||
runTest(testPvaMultiDouble);
|
|
||||||
runTest(testPvaNTMultiChannel);
|
|
||||||
}
|
|
||||||
|
|
@ -1,155 +0,0 @@
|
|||||||
/*testPvaGetData.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
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Author: Marty Kraimer */
|
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
#include <epicsUnitTest.h>
|
|
||||||
#include <testMain.h>
|
|
||||||
|
|
||||||
#include <pv/pva.h>
|
|
||||||
#include <pv/bitSet.h>
|
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
using namespace epics::pvData;
|
|
||||||
using namespace epics::pvAccess;
|
|
||||||
using namespace epics::pva;
|
|
||||||
|
|
||||||
static PvaPtr pva = Pva::create();
|
|
||||||
static FieldCreatePtr fieldCreate = getFieldCreate();
|
|
||||||
static StandardFieldPtr standardField = getStandardField();
|
|
||||||
static PVDataCreatePtr pvDataCreate = getPVDataCreate();
|
|
||||||
|
|
||||||
|
|
||||||
void testDouble()
|
|
||||||
{
|
|
||||||
cout << "\nstarting testDouble\n";
|
|
||||||
StructureConstPtr structure =
|
|
||||||
fieldCreate->createFieldBuilder()->
|
|
||||||
add("alarm",standardField->alarm()) ->
|
|
||||||
add("timeStamp",standardField->timeStamp()) ->
|
|
||||||
add("value",pvDouble) ->
|
|
||||||
createStructure();
|
|
||||||
|
|
||||||
PvaGetDataPtr pvaData = PvaGetData::create(structure);
|
|
||||||
PVStructurePtr pvStructure = pvDataCreate->createPVStructure(pvaData->getStructure());
|
|
||||||
BitSetPtr bitSet = BitSetPtr(new BitSet(pvStructure->getNumberFields()));
|
|
||||||
pvaData->setData(pvStructure,bitSet);
|
|
||||||
PVDoublePtr pvDouble = pvStructure->getSubField<PVDouble>("value");
|
|
||||||
size_t valueOffset = pvDouble->getFieldOffset();
|
|
||||||
BitSetPtr change = pvaData->getBitSet();
|
|
||||||
pvDouble->put(5.0);
|
|
||||||
change->set(pvDouble->getFieldOffset());
|
|
||||||
testOk(change->cardinality()==1,"num set bits 1");
|
|
||||||
testOk(change->get(valueOffset)==true,"value changed");
|
|
||||||
testOk(pvaData->hasValue()==true,"hasValue");
|
|
||||||
testOk(pvaData->isValueScalar()==true,"isValueScalar");
|
|
||||||
testOk(pvaData->isValueScalarArray()==false,"isValueScalarArray");
|
|
||||||
bool result;
|
|
||||||
result = false;
|
|
||||||
if(pvaData->getValue()) result = true;
|
|
||||||
testOk(result==true,"getValue");
|
|
||||||
result = false;
|
|
||||||
if(pvaData->getScalarValue()) result = true;
|
|
||||||
testOk(result==true,"getScalarValue");
|
|
||||||
try {
|
|
||||||
pvaData->getArrayValue();
|
|
||||||
} catch (std::runtime_error e) {
|
|
||||||
cout << "getArrayValue " << e.what() << endl;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
pvaData->getScalarArrayValue();
|
|
||||||
} catch (std::runtime_error e) {
|
|
||||||
cout << " getScalarArrayValue " << e.what() << endl;
|
|
||||||
}
|
|
||||||
cout << "as double " << pvaData->getDouble() << endl;
|
|
||||||
cout << "as string " << pvaData->getString() << endl;
|
|
||||||
try {
|
|
||||||
shared_vector<const double> value = pvaData->getDoubleArray();
|
|
||||||
} catch (std::runtime_error e) {
|
|
||||||
cout << " getDoubleArray " << e.what() << endl;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
shared_vector<const string> value = pvaData->getStringArray();
|
|
||||||
} catch (std::runtime_error e) {
|
|
||||||
cout << " getStringArray " << e.what() << endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void testDoubleArray()
|
|
||||||
{
|
|
||||||
cout << "\nstarting testDoubleArray\n";
|
|
||||||
StructureConstPtr structure =
|
|
||||||
fieldCreate->createFieldBuilder()->
|
|
||||||
add("alarm",standardField->alarm()) ->
|
|
||||||
add("timeStamp",standardField->timeStamp()) ->
|
|
||||||
addArray("value",pvDouble) ->
|
|
||||||
createStructure();
|
|
||||||
|
|
||||||
PvaGetDataPtr pvaData = PvaGetData::create(structure);
|
|
||||||
PVStructurePtr pvStructure = pvDataCreate->createPVStructure(pvaData->getStructure());
|
|
||||||
BitSetPtr bitSet = BitSetPtr(new BitSet(pvStructure->getNumberFields()));
|
|
||||||
pvaData->setData(pvStructure,bitSet);
|
|
||||||
PVDoubleArrayPtr pvalue = pvaData->getPVStructure()->getSubField<PVDoubleArray>("value");
|
|
||||||
BitSetPtr change = pvaData->getBitSet();
|
|
||||||
size_t valueOffset = pvalue->getFieldOffset();
|
|
||||||
size_t len = 5;
|
|
||||||
shared_vector<double> value(len);
|
|
||||||
for(size_t i=0; i<len; ++i) value[i] = i*10.0;
|
|
||||||
pvalue->replace(freeze(value));
|
|
||||||
change->set(valueOffset);
|
|
||||||
testOk(change->cardinality()==1,"num set bits 1");
|
|
||||||
testOk(change->get(valueOffset)==true,"value changed");
|
|
||||||
testOk(pvaData->hasValue()==true,"hasValue");
|
|
||||||
testOk(pvaData->isValueScalar()==false,"isValueScalar");
|
|
||||||
testOk(pvaData->isValueScalarArray()==true,"isValueScalarArray");
|
|
||||||
bool result;
|
|
||||||
result = false;
|
|
||||||
if(pvaData->getValue()) result = true;
|
|
||||||
testOk(result==true,"getValue");
|
|
||||||
result = false;
|
|
||||||
if(pvaData->getArrayValue()) result = true;
|
|
||||||
testOk(result==true,"getArrayValue");
|
|
||||||
result = false;
|
|
||||||
if(pvaData->getScalarArrayValue()) result = true;
|
|
||||||
testOk(result==true,"getScalarValue");
|
|
||||||
try {
|
|
||||||
pvaData->getScalarValue();
|
|
||||||
} catch (std::runtime_error e) {
|
|
||||||
cout << " getScalarValue " << e.what() << endl;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
cout << "as double " << pvaData->getDouble() << endl;
|
|
||||||
} catch (std::runtime_error e) {
|
|
||||||
cout << " getDouble " << e.what() << endl;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
string val = pvaData->getString();
|
|
||||||
} catch (std::runtime_error e) {
|
|
||||||
cout << " getString " << e.what() << endl;
|
|
||||||
}
|
|
||||||
cout << "as doubleArray " << pvaData->getDoubleArray() << endl;
|
|
||||||
try {
|
|
||||||
shared_vector<const string> value = pvaData->getStringArray();
|
|
||||||
} catch (std::runtime_error e) {
|
|
||||||
cout << " getStringArray " << e.what() << endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
MAIN(testPvaGetData)
|
|
||||||
{
|
|
||||||
cout << "\nstarting testPvaGetData\n";
|
|
||||||
testPlan(15);
|
|
||||||
testDouble();
|
|
||||||
testDoubleArray();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
@ -1,153 +0,0 @@
|
|||||||
/*testPvaMonitorData.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
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Author: Marty Kraimer */
|
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
#include <epicsUnitTest.h>
|
|
||||||
#include <testMain.h>
|
|
||||||
|
|
||||||
#include <pv/pva.h>
|
|
||||||
#include <pv/bitSet.h>
|
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
using namespace epics::pvData;
|
|
||||||
using namespace epics::pvAccess;
|
|
||||||
using namespace epics::pva;
|
|
||||||
|
|
||||||
static PvaPtr pva = Pva::create();
|
|
||||||
static FieldCreatePtr fieldCreate = getFieldCreate();
|
|
||||||
static StandardFieldPtr standardField = getStandardField();
|
|
||||||
static PVDataCreatePtr pvDataCreate = getPVDataCreate();
|
|
||||||
|
|
||||||
|
|
||||||
void testDouble()
|
|
||||||
{
|
|
||||||
cout << "\nstarting testDouble\n";
|
|
||||||
StructureConstPtr structure =
|
|
||||||
fieldCreate->createFieldBuilder()->
|
|
||||||
add("alarm",standardField->alarm()) ->
|
|
||||||
add("timeStamp",standardField->timeStamp()) ->
|
|
||||||
add("value",pvDouble) ->
|
|
||||||
createStructure();
|
|
||||||
|
|
||||||
PvaMonitorDataPtr pvaData = PvaMonitorData::create(structure);
|
|
||||||
MonitorElementPtr monitorElement(new MonitorElement(pvDataCreate->createPVStructure(pvaData->getStructure())));
|
|
||||||
pvaData->setData(monitorElement);
|
|
||||||
PVDoublePtr pvDouble = pvaData->getPVStructure()->getSubField<PVDouble>("value");
|
|
||||||
size_t valueOffset = pvDouble->getFieldOffset();
|
|
||||||
BitSetPtr change = pvaData->getChangedBitSet();
|
|
||||||
pvDouble->put(5.0);
|
|
||||||
change->set(pvDouble->getFieldOffset());
|
|
||||||
testOk(change->cardinality()==1,"num set bits 1");
|
|
||||||
testOk(change->get(valueOffset)==true,"value changed");
|
|
||||||
testOk(pvaData->hasValue()==true,"hasValue");
|
|
||||||
testOk(pvaData->isValueScalar()==true,"isValueScalar");
|
|
||||||
testOk(pvaData->isValueScalarArray()==false,"isValueScalarArray");
|
|
||||||
bool result;
|
|
||||||
result = false;
|
|
||||||
if(pvaData->getValue()) result = true;
|
|
||||||
testOk(result==true,"getValue");
|
|
||||||
result = false;
|
|
||||||
if(pvaData->getScalarValue()) result = true;
|
|
||||||
testOk(result==true,"getScalarValue");
|
|
||||||
try {
|
|
||||||
pvaData->getArrayValue();
|
|
||||||
} catch (std::runtime_error e) {
|
|
||||||
cout << "getArrayValue " << e.what() << endl;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
pvaData->getScalarArrayValue();
|
|
||||||
} catch (std::runtime_error e) {
|
|
||||||
cout << " getScalarArrayValue " << e.what() << endl;
|
|
||||||
}
|
|
||||||
cout << "as double " << pvaData->getDouble() << endl;
|
|
||||||
cout << "as string " << pvaData->getString() << endl;
|
|
||||||
try {
|
|
||||||
shared_vector<const double> value = pvaData->getDoubleArray();
|
|
||||||
} catch (std::runtime_error e) {
|
|
||||||
cout << " getDoubleArray " << e.what() << endl;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
shared_vector<const string> value = pvaData->getStringArray();
|
|
||||||
} catch (std::runtime_error e) {
|
|
||||||
cout << " getStringArray " << e.what() << endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void testDoubleArray()
|
|
||||||
{
|
|
||||||
cout << "\nstarting testDoubleArray\n";
|
|
||||||
StructureConstPtr structure =
|
|
||||||
fieldCreate->createFieldBuilder()->
|
|
||||||
add("alarm",standardField->alarm()) ->
|
|
||||||
add("timeStamp",standardField->timeStamp()) ->
|
|
||||||
addArray("value",pvDouble) ->
|
|
||||||
createStructure();
|
|
||||||
|
|
||||||
PvaMonitorDataPtr pvaData = PvaMonitorData::create(structure);
|
|
||||||
MonitorElementPtr monitorElement(new MonitorElement(pvDataCreate->createPVStructure(pvaData->getStructure())));
|
|
||||||
pvaData->setData(monitorElement);
|
|
||||||
PVDoubleArrayPtr pvalue = pvaData->getPVStructure()->getSubField<PVDoubleArray>("value");
|
|
||||||
BitSetPtr change = pvaData->getChangedBitSet();
|
|
||||||
size_t valueOffset = pvalue->getFieldOffset();
|
|
||||||
size_t len = 5;
|
|
||||||
shared_vector<double> value(len);
|
|
||||||
for(size_t i=0; i<len; ++i) value[i] = i*10.0;
|
|
||||||
pvalue->replace(freeze(value));
|
|
||||||
change->set(valueOffset);
|
|
||||||
testOk(change->cardinality()==1,"num set bits 1");
|
|
||||||
testOk(change->get(valueOffset)==true,"value changed");
|
|
||||||
testOk(pvaData->hasValue()==true,"hasValue");
|
|
||||||
testOk(pvaData->isValueScalar()==false,"isValueScalar");
|
|
||||||
testOk(pvaData->isValueScalarArray()==true,"isValueScalarArray");
|
|
||||||
bool result;
|
|
||||||
result = false;
|
|
||||||
if(pvaData->getValue()) result = true;
|
|
||||||
testOk(result==true,"getValue");
|
|
||||||
result = false;
|
|
||||||
if(pvaData->getArrayValue()) result = true;
|
|
||||||
testOk(result==true,"getArrayValue");
|
|
||||||
result = false;
|
|
||||||
if(pvaData->getScalarArrayValue()) result = true;
|
|
||||||
testOk(result==true,"getScalarValue");
|
|
||||||
try {
|
|
||||||
pvaData->getScalarValue();
|
|
||||||
} catch (std::runtime_error e) {
|
|
||||||
cout << " getScalarValue " << e.what() << endl;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
cout << "as double " << pvaData->getDouble() << endl;
|
|
||||||
} catch (std::runtime_error e) {
|
|
||||||
cout << " getDouble " << e.what() << endl;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
string val = pvaData->getString();
|
|
||||||
} catch (std::runtime_error e) {
|
|
||||||
cout << " getString " << e.what() << endl;
|
|
||||||
}
|
|
||||||
cout << "as doubleArray " << pvaData->getDoubleArray() << endl;
|
|
||||||
try {
|
|
||||||
shared_vector<const string> value = pvaData->getStringArray();
|
|
||||||
} catch (std::runtime_error e) {
|
|
||||||
cout << " getStringArray " << e.what() << endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
MAIN(testPvaMonitorData)
|
|
||||||
{
|
|
||||||
cout << "\nstarting testPvaMonitorData\n";
|
|
||||||
testPlan(15);
|
|
||||||
testDouble();
|
|
||||||
testDoubleArray();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
@ -1,156 +0,0 @@
|
|||||||
/*testPvaMultiDouble.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
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Author: Marty Kraimer */
|
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
#include <pv/pvaMultiDouble.h>
|
|
||||||
#include <epicsUnitTest.h>
|
|
||||||
#include <testMain.h>
|
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
using namespace epics::pvData;
|
|
||||||
using namespace epics::pvAccess;
|
|
||||||
using namespace epics::pva;
|
|
||||||
|
|
||||||
|
|
||||||
static void testGood(PvaPtr const &pva)
|
|
||||||
{
|
|
||||||
bool isOk = true;
|
|
||||||
cout << "\nstarting testGood\n";
|
|
||||||
try {
|
|
||||||
PvaPtr pva(Pva::create());
|
|
||||||
size_t num = 5;
|
|
||||||
shared_vector<string> channelNames(num);
|
|
||||||
channelNames[0] = "exampleDouble01";
|
|
||||||
channelNames[1] = "exampleDouble02";
|
|
||||||
channelNames[2] = "exampleDouble03";
|
|
||||||
channelNames[3] = "exampleDouble04";
|
|
||||||
channelNames[4] = "exampleDouble05";
|
|
||||||
PVStringArrayPtr pvNames =
|
|
||||||
getPVDataCreate()->createPVScalarArray<PVStringArray>();
|
|
||||||
pvNames->replace(freeze(channelNames));
|
|
||||||
PvaMultiDoublePtr multiDouble(PvaMultiDouble::create(pva,pvNames));
|
|
||||||
shared_vector<double> data = multiDouble->get();
|
|
||||||
cout << "initial " << data << endl;
|
|
||||||
for(size_t i=0; i<num; ++i) data[i] = data[i] + 1.1;
|
|
||||||
multiDouble->put(data);
|
|
||||||
data = multiDouble->get();
|
|
||||||
cout << "final " << data << endl;
|
|
||||||
} catch (std::runtime_error e) {
|
|
||||||
cout << "exception " << e.what() << endl;
|
|
||||||
isOk = false;
|
|
||||||
}
|
|
||||||
testOk(isOk==true,"all channels double");
|
|
||||||
}
|
|
||||||
|
|
||||||
static void testGoodMixed(PvaPtr const &pva)
|
|
||||||
{
|
|
||||||
bool isOk = true;
|
|
||||||
cout << "\nstarting testGoodMixed\n";
|
|
||||||
try {
|
|
||||||
PvaPtr pva(Pva::create());
|
|
||||||
size_t num = 5;
|
|
||||||
shared_vector<string> channelNames(num);
|
|
||||||
channelNames[0] = "exampleByte";
|
|
||||||
channelNames[1] = "exampleShort";
|
|
||||||
channelNames[2] = "exampleInt";
|
|
||||||
channelNames[3] = "exampleFloat";
|
|
||||||
channelNames[4] = "exampleDouble";
|
|
||||||
PVStringArrayPtr pvNames =
|
|
||||||
getPVDataCreate()->createPVScalarArray<PVStringArray>();
|
|
||||||
pvNames->replace(freeze(channelNames));
|
|
||||||
PvaMultiDoublePtr multiDouble(PvaMultiDouble::create(pva,pvNames));
|
|
||||||
shared_vector<double> data = multiDouble->get();
|
|
||||||
cout << "initial " << data << endl;
|
|
||||||
for(size_t i=0; i<num; ++i) data[i] = data[i] + 1.1;
|
|
||||||
multiDouble->put(data);
|
|
||||||
data = multiDouble->get();
|
|
||||||
cout << "final " << data << endl;
|
|
||||||
} catch (std::runtime_error e) {
|
|
||||||
cout << "exception " << e.what() << endl;
|
|
||||||
isOk = false;
|
|
||||||
}
|
|
||||||
testOk(isOk==true,"channels mixed type");
|
|
||||||
}
|
|
||||||
|
|
||||||
static void testChannelNotExist(PvaPtr const &pva)
|
|
||||||
{
|
|
||||||
bool isOk = true;
|
|
||||||
cout << "\nstarting testChannelNotExist\n";
|
|
||||||
try {
|
|
||||||
PvaPtr pva(Pva::create());
|
|
||||||
size_t num = 5;
|
|
||||||
shared_vector<string> channelNames(num);
|
|
||||||
channelNames[0] = "exampleDouble01";
|
|
||||||
channelNames[1] = "exampleDouble02";
|
|
||||||
channelNames[2] = "exampleDouble03";
|
|
||||||
channelNames[3] = "NoneExistChannel";
|
|
||||||
channelNames[4] = "exampleDouble05";
|
|
||||||
PVStringArrayPtr pvNames =
|
|
||||||
getPVDataCreate()->createPVScalarArray<PVStringArray>();
|
|
||||||
pvNames->replace(freeze(channelNames));
|
|
||||||
PvaMultiDoublePtr multiDouble(PvaMultiDouble::create(pva,pvNames));
|
|
||||||
shared_vector<double> data = multiDouble->get();
|
|
||||||
cout << "initial " << data << endl;
|
|
||||||
for(size_t i=0; i<num; ++i) data[i] = data[i] + 1.1;
|
|
||||||
multiDouble->put(data);
|
|
||||||
data = multiDouble->get();
|
|
||||||
cout << "final " << data << endl;
|
|
||||||
} catch (std::runtime_error e) {
|
|
||||||
cout << "exception " << e.what() << endl;
|
|
||||||
isOk = false;
|
|
||||||
}
|
|
||||||
testOk(isOk==false,"channel not exist");
|
|
||||||
}
|
|
||||||
|
|
||||||
static void testNonNumeric(PvaPtr const &pva)
|
|
||||||
{
|
|
||||||
bool isOk = true;
|
|
||||||
cout << "\nstarting testNonNumeric\n";
|
|
||||||
try {
|
|
||||||
PvaPtr pva(Pva::create());
|
|
||||||
size_t num = 5;
|
|
||||||
shared_vector<string> channelNames(num);
|
|
||||||
channelNames[0] = "exampleDouble01";
|
|
||||||
channelNames[1] = "exampleDouble02";
|
|
||||||
channelNames[2] = "exampleDouble03";
|
|
||||||
channelNames[3] = "exampleDouble04";
|
|
||||||
channelNames[4] = "exampleDouble05Array";
|
|
||||||
PVStringArrayPtr pvNames =
|
|
||||||
getPVDataCreate()->createPVScalarArray<PVStringArray>();
|
|
||||||
pvNames->replace(freeze(channelNames));
|
|
||||||
PvaMultiDoublePtr multiDouble(PvaMultiDouble::create(pva,pvNames));
|
|
||||||
shared_vector<double> data = multiDouble->get();
|
|
||||||
cout << "initial " << data << endl;
|
|
||||||
for(size_t i=0; i<num; ++i) data[i] = data[i] + 1.1;
|
|
||||||
multiDouble->put(data);
|
|
||||||
data = multiDouble->get();
|
|
||||||
cout << "final " << data << endl;
|
|
||||||
} catch (std::runtime_error e) {
|
|
||||||
cout << "exception " << e.what() << endl;
|
|
||||||
isOk = false;
|
|
||||||
}
|
|
||||||
testOk(isOk==false,"channel not numeric");
|
|
||||||
}
|
|
||||||
|
|
||||||
MAIN(testPvaMultiDouble)
|
|
||||||
{
|
|
||||||
cout << "\nstarting testPvaMultiDouble\n";
|
|
||||||
testPlan(4);
|
|
||||||
PvaPtr pva = Pva::create();
|
|
||||||
testGood(pva);
|
|
||||||
testGoodMixed(pva);
|
|
||||||
testChannelNotExist(pva);
|
|
||||||
testNonNumeric(pva);
|
|
||||||
cout << "done\n";
|
|
||||||
return 0;
|
|
||||||
}
|
|
@ -1,132 +0,0 @@
|
|||||||
/*testPvaNTMultiChannel.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
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Author: Marty Kraimer */
|
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
#include <pv/pvaNTMultiChannel.h>
|
|
||||||
#include <epicsUnitTest.h>
|
|
||||||
#include <testMain.h>
|
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
using namespace epics::pvData;
|
|
||||||
using namespace epics::pvAccess;
|
|
||||||
using namespace epics::pva;
|
|
||||||
using namespace epics::nt;
|
|
||||||
using std::tr1::static_pointer_cast;
|
|
||||||
|
|
||||||
|
|
||||||
static void testGood(PvaPtr const &pva)
|
|
||||||
{
|
|
||||||
PVDataCreatePtr pvDataCreate(getPVDataCreate());
|
|
||||||
bool isOk = true;
|
|
||||||
cout << "\nstarting testGood\n";
|
|
||||||
try {
|
|
||||||
PvaPtr pva(Pva::create());
|
|
||||||
size_t num = 5;
|
|
||||||
shared_vector<string> channelNames(num);
|
|
||||||
channelNames[0] = "exampleDouble";
|
|
||||||
channelNames[1] = "exampleDoubleArray";
|
|
||||||
channelNames[2] = "exampleString";
|
|
||||||
channelNames[3] = "exampleBoolean";
|
|
||||||
channelNames[4] = "exampleEnum";
|
|
||||||
PVStringArrayPtr pvNames = pvDataCreate->
|
|
||||||
createPVScalarArray<PVStringArray>();
|
|
||||||
pvNames->replace(freeze(channelNames));
|
|
||||||
NTMultiChannelBuilderPtr builder = NTMultiChannel::createBuilder();
|
|
||||||
StructureConstPtr structure = builder->
|
|
||||||
addTimeStamp()->
|
|
||||||
addSeverity() ->
|
|
||||||
addStatus() ->
|
|
||||||
addMessage() ->
|
|
||||||
addSecondsPastEpoch() ->
|
|
||||||
addNanoseconds() ->
|
|
||||||
addUserTag() ->
|
|
||||||
createStructure();
|
|
||||||
PvaNTMultiChannelPtr multi = PvaNTMultiChannel::create(
|
|
||||||
pva,pvNames,structure);
|
|
||||||
NTMultiChannelPtr nt = multi->get();
|
|
||||||
for(size_t numtimes=0; numtimes<3; ++numtimes) {
|
|
||||||
PVUnionArrayPtr pvValue = nt->getPVStructure()->
|
|
||||||
getSubField<PVUnionArray>("value");
|
|
||||||
cout << "initial\n" << nt->getPVStructure() << endl;
|
|
||||||
shared_vector<PVUnionPtr> valueVector = pvValue->reuse();
|
|
||||||
for(size_t i=0; i<num; ++i)
|
|
||||||
{
|
|
||||||
PVFieldPtr pvField = valueVector[i]->get();
|
|
||||||
Type type = pvField->getField()->getType();
|
|
||||||
if(type==scalar) {
|
|
||||||
PVScalarPtr pvScalar = static_pointer_cast<PVScalar>(pvField);
|
|
||||||
ScalarType scalarType = pvScalar->getScalar()->getScalarType();
|
|
||||||
if(ScalarTypeFunc::isNumeric(scalarType)) {
|
|
||||||
double oldValue = pvScalar->getAs<double>();
|
|
||||||
oldValue++;
|
|
||||||
pvScalar->putFrom<double>(oldValue);
|
|
||||||
} else if(scalarType==pvString) {
|
|
||||||
PVStringPtr pv = static_pointer_cast<PVString>(pvField);
|
|
||||||
string val = pv->get();
|
|
||||||
val += " added";
|
|
||||||
pv->put(val);
|
|
||||||
} else if(scalarType==pvBoolean) {
|
|
||||||
PVBooleanPtr pv = static_pointer_cast<PVBoolean>(pvField);
|
|
||||||
bool val = pv->get();
|
|
||||||
pv->put(!val);
|
|
||||||
}
|
|
||||||
} else if(type==scalarArray) {
|
|
||||||
PVScalarArrayPtr pv =
|
|
||||||
static_pointer_cast<PVScalarArray>(pvField);
|
|
||||||
ScalarType scalarType = pv->getScalarArray()->getElementType();
|
|
||||||
if(scalarType==pvDouble) {
|
|
||||||
PVDoubleArrayPtr pvd = static_pointer_cast<PVDoubleArray>(pv);
|
|
||||||
shared_vector<double> valvec = pvd->reuse();
|
|
||||||
if(valvec.capacity()==0) {
|
|
||||||
valvec.resize(4);
|
|
||||||
for(size_t i=0; i<valvec.size(); ++i) valvec[i] = i;
|
|
||||||
}
|
|
||||||
for(size_t i=0; i<valvec.size(); ++i) valvec[i] = valvec[i] + 1.0;
|
|
||||||
pvd->replace(freeze(valvec));
|
|
||||||
}
|
|
||||||
} else if(type==epics::pvData::structure) {
|
|
||||||
PVStructurePtr pvStructure = static_pointer_cast<PVStructure>(pvField);
|
|
||||||
PVIntPtr pv = pvStructure->getSubField<PVInt>("index");
|
|
||||||
if(pv) {
|
|
||||||
PVStringArrayPtr choices = pvStructure->getSubField<PVStringArray>("choices");
|
|
||||||
if(choices) {
|
|
||||||
int32 nchoices = choices->getLength();
|
|
||||||
int32 oldval = pv->get();
|
|
||||||
int32 newval = (oldval==nchoices) ? 0 : ++oldval;
|
|
||||||
pv->put(newval);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pvValue->replace(freeze(valueVector));
|
|
||||||
multi->put(nt);
|
|
||||||
nt = multi->get();
|
|
||||||
}
|
|
||||||
cout << "final\n" << nt->getPVStructure() << endl;
|
|
||||||
} catch (std::runtime_error e) {
|
|
||||||
cout << "exception " << e.what() << endl;
|
|
||||||
isOk = false;
|
|
||||||
}
|
|
||||||
testOk(isOk==true,"no problems");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
MAIN(testPvaNTMultiChannel)
|
|
||||||
{
|
|
||||||
cout << "\nstarting testPvaNTMultiChannel\n";
|
|
||||||
testPlan(1);
|
|
||||||
PvaPtr pva = Pva::create();
|
|
||||||
testGood(pva);
|
|
||||||
cout << "done\n";
|
|
||||||
return 0;
|
|
||||||
}
|
|
@ -1,229 +0,0 @@
|
|||||||
/*testPvaPutData.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
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Author: Marty Kraimer */
|
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
#include <epicsUnitTest.h>
|
|
||||||
#include <testMain.h>
|
|
||||||
|
|
||||||
#include <pv/pva.h>
|
|
||||||
#include <pv/bitSet.h>
|
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
using namespace epics::pvData;
|
|
||||||
using namespace epics::pvAccess;
|
|
||||||
using namespace epics::pva;
|
|
||||||
|
|
||||||
static PvaPtr pva = Pva::create();
|
|
||||||
static FieldCreatePtr fieldCreate = getFieldCreate();
|
|
||||||
static StandardFieldPtr standardField = getStandardField();
|
|
||||||
static PVDataCreatePtr pvDataCreate = getPVDataCreate();
|
|
||||||
|
|
||||||
static void testPostPut()
|
|
||||||
{
|
|
||||||
cout << "\nstarting testPostPut\n";
|
|
||||||
StructureConstPtr structure =
|
|
||||||
fieldCreate->createFieldBuilder()->
|
|
||||||
add("alarm",standardField->alarm()) ->
|
|
||||||
add("timeStamp",standardField->timeStamp()) ->
|
|
||||||
addNestedStructure("power") ->
|
|
||||||
add("value",pvDouble) ->
|
|
||||||
add("alarm",standardField->alarm()) ->
|
|
||||||
endNested()->
|
|
||||||
addNestedStructure("voltage") ->
|
|
||||||
add("value",pvDouble) ->
|
|
||||||
add("alarm",standardField->alarm()) ->
|
|
||||||
endNested()->
|
|
||||||
addNestedStructure("current") ->
|
|
||||||
add("value",pvDouble) ->
|
|
||||||
add("alarm",standardField->alarm()) ->
|
|
||||||
endNested()->
|
|
||||||
createStructure();
|
|
||||||
|
|
||||||
PvaPutDataPtr pvaData = PvaPutData::create(structure);
|
|
||||||
PVStructurePtr pvStructure = pvaData->getPVStructure();
|
|
||||||
BitSetPtr change = pvaData->getBitSet();
|
|
||||||
PVDoublePtr powerValue = pvStructure->getSubField<PVDouble>("power.value");
|
|
||||||
PVDoublePtr voltageValue = pvStructure->getSubField<PVDouble>("voltage.value");
|
|
||||||
PVDoublePtr currentValue = pvStructure->getSubField<PVDouble>("current.value");
|
|
||||||
size_t powerOffset = powerValue->getFieldOffset();
|
|
||||||
size_t voltageOffset = voltageValue->getFieldOffset();
|
|
||||||
size_t currentOffset = currentValue->getFieldOffset();
|
|
||||||
change->clear();
|
|
||||||
powerValue->put(1.0);
|
|
||||||
voltageValue->put(2.0);
|
|
||||||
currentValue->put(.5);
|
|
||||||
cout << "changed\n";
|
|
||||||
cout << pvaData->showChanged(cout) << endl;
|
|
||||||
testOk(change->cardinality()==3,"num set bits 3");
|
|
||||||
testOk(change->get(powerOffset)==true,"power changed");
|
|
||||||
testOk(change->get(voltageOffset)==true,"voltage changed");
|
|
||||||
testOk(change->get(currentOffset)==true,"current changed");
|
|
||||||
}
|
|
||||||
|
|
||||||
void testDouble()
|
|
||||||
{
|
|
||||||
cout << "\nstarting testDouble\n";
|
|
||||||
StructureConstPtr structure =
|
|
||||||
fieldCreate->createFieldBuilder()->
|
|
||||||
add("alarm",standardField->alarm()) ->
|
|
||||||
add("timeStamp",standardField->timeStamp()) ->
|
|
||||||
add("value",pvDouble) ->
|
|
||||||
createStructure();
|
|
||||||
|
|
||||||
PvaPutDataPtr pvaData = PvaPutData::create(structure);
|
|
||||||
PVDoublePtr pvDouble = pvaData->getPVStructure()->getSubField<PVDouble>("value");
|
|
||||||
pvDouble->put(5.0);
|
|
||||||
BitSetPtr change = pvaData->getBitSet();
|
|
||||||
size_t valueOffset = pvDouble->getFieldOffset();
|
|
||||||
testOk(change->cardinality()==1,"num set bits 1");
|
|
||||||
testOk(change->get(valueOffset)==true,"value changed");
|
|
||||||
testOk(pvaData->hasValue()==true,"hasValue");
|
|
||||||
testOk(pvaData->isValueScalar()==true,"isValueScalar");
|
|
||||||
testOk(pvaData->isValueScalarArray()==false,"isValueScalarArray");
|
|
||||||
bool result;
|
|
||||||
result = false;
|
|
||||||
if(pvaData->getValue()) result = true;
|
|
||||||
testOk(result==true,"getValue");
|
|
||||||
result = false;
|
|
||||||
if(pvaData->getScalarValue()) result = true;
|
|
||||||
testOk(result==true,"getScalarValue");
|
|
||||||
try {
|
|
||||||
pvaData->getArrayValue();
|
|
||||||
} catch (std::runtime_error e) {
|
|
||||||
cout << "getArrayValue " << e.what() << endl;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
pvaData->getScalarArrayValue();
|
|
||||||
} catch (std::runtime_error e) {
|
|
||||||
cout << " getScalarArrayValue " << e.what() << endl;
|
|
||||||
}
|
|
||||||
cout << "as double " << pvaData->getDouble() << endl;
|
|
||||||
cout << "as string " << pvaData->getString() << endl;
|
|
||||||
try {
|
|
||||||
shared_vector<const double> value = pvaData->getDoubleArray();
|
|
||||||
} catch (std::runtime_error e) {
|
|
||||||
cout << " getDoubleArray " << e.what() << endl;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
shared_vector<const string> value = pvaData->getStringArray();
|
|
||||||
} catch (std::runtime_error e) {
|
|
||||||
cout << " getStringArray " << e.what() << endl;
|
|
||||||
}
|
|
||||||
pvaData->putDouble(5.0);
|
|
||||||
pvaData->putString("1e5");
|
|
||||||
try {
|
|
||||||
size_t len = 2;
|
|
||||||
shared_vector<double> val(len);
|
|
||||||
for(size_t i=0; i<len; ++i) val[i] = (i+1)*10.0;
|
|
||||||
pvaData->putDoubleArray(freeze(val));
|
|
||||||
} catch (std::runtime_error e) {
|
|
||||||
cout << " putDoubleArray " << e.what() << endl;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
size_t len = 2;
|
|
||||||
shared_vector<string> val(len);
|
|
||||||
val[0] = "one"; val[1] = "two";
|
|
||||||
pvaData->putStringArray(freeze(val));
|
|
||||||
} catch (std::runtime_error e) {
|
|
||||||
cout << " putStringArray " << e.what() << endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void testDoubleArray()
|
|
||||||
{
|
|
||||||
cout << "\nstarting testDoubleArray\n";
|
|
||||||
StructureConstPtr structure =
|
|
||||||
fieldCreate->createFieldBuilder()->
|
|
||||||
add("alarm",standardField->alarm()) ->
|
|
||||||
add("timeStamp",standardField->timeStamp()) ->
|
|
||||||
addArray("value",pvDouble) ->
|
|
||||||
createStructure();
|
|
||||||
|
|
||||||
PvaPutDataPtr pvaData = PvaPutData::create(structure);
|
|
||||||
PVDoubleArrayPtr pvalue = pvaData->getPVStructure()->getSubField<PVDoubleArray>("value");
|
|
||||||
size_t len = 5;
|
|
||||||
shared_vector<double> value(len);
|
|
||||||
for(size_t i=0; i<len; ++i) value[i] = i*10.0;
|
|
||||||
pvalue->replace(freeze(value));
|
|
||||||
BitSetPtr change = pvaData->getBitSet();
|
|
||||||
size_t valueOffset = pvalue->getFieldOffset();
|
|
||||||
testOk(change->cardinality()==1,"num set bits 1");
|
|
||||||
testOk(change->get(valueOffset)==true,"value changed");
|
|
||||||
testOk(pvaData->hasValue()==true,"hasValue");
|
|
||||||
testOk(pvaData->isValueScalar()==false,"isValueScalar");
|
|
||||||
testOk(pvaData->isValueScalarArray()==true,"isValueScalarArray");
|
|
||||||
bool result;
|
|
||||||
result = false;
|
|
||||||
if(pvaData->getValue()) result = true;
|
|
||||||
testOk(result==true,"getValue");
|
|
||||||
result = false;
|
|
||||||
if(pvaData->getArrayValue()) result = true;
|
|
||||||
testOk(result==true,"getArrayValue");
|
|
||||||
result = false;
|
|
||||||
if(pvaData->getScalarArrayValue()) result = true;
|
|
||||||
testOk(result==true,"getScalarValue");
|
|
||||||
try {
|
|
||||||
pvaData->getScalarValue();
|
|
||||||
} catch (std::runtime_error e) {
|
|
||||||
cout << " getScalarValue " << e.what() << endl;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
cout << "as double " << pvaData->getDouble() << endl;
|
|
||||||
} catch (std::runtime_error e) {
|
|
||||||
cout << " getDouble " << e.what() << endl;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
string val = pvaData->getString();
|
|
||||||
} catch (std::runtime_error e) {
|
|
||||||
cout << " getString " << e.what() << endl;
|
|
||||||
}
|
|
||||||
cout << "as doubleArray " << pvaData->getDoubleArray() << endl;
|
|
||||||
try {
|
|
||||||
shared_vector<const string> value = pvaData->getStringArray();
|
|
||||||
} catch (std::runtime_error e) {
|
|
||||||
cout << " getStringArray " << e.what() << endl;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
pvaData->putDouble(5.0);
|
|
||||||
} catch (std::runtime_error e) {
|
|
||||||
cout << " putDouble " << e.what() << endl;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
pvaData->putString("1e5");
|
|
||||||
} catch (std::runtime_error e) {
|
|
||||||
cout << " putString " << e.what() << endl;
|
|
||||||
}
|
|
||||||
value = shared_vector<double>(len);
|
|
||||||
for(size_t i=0; i<len; ++i) value[i] = (i+1)* 2;
|
|
||||||
pvaData->putDoubleArray(freeze(value));
|
|
||||||
cout << "as doubleArray " << pvaData->getDoubleArray() << endl;
|
|
||||||
try {
|
|
||||||
size_t len = 2;
|
|
||||||
shared_vector<string> val(len);
|
|
||||||
val[0] = "one"; val[1] = "two";
|
|
||||||
pvaData->putStringArray(freeze(val));
|
|
||||||
cout << "as stringArray " << val << endl;
|
|
||||||
} catch (std::runtime_error e) {
|
|
||||||
cout << " putStringArray " << e.what() << endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
MAIN(testPvaPutData)
|
|
||||||
{
|
|
||||||
cout << "\nstarting testPvaPutData\n";
|
|
||||||
testPlan(19);
|
|
||||||
testPostPut();
|
|
||||||
testDouble();
|
|
||||||
testDoubleArray();
|
|
||||||
return 0;
|
|
||||||
}
|
|
@ -1,66 +0,0 @@
|
|||||||
/*examplePvaPutGet.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
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Author: Marty Kraimer */
|
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
#include <pv/pva.h>
|
|
||||||
#include <epicsUnitTest.h>
|
|
||||||
#include <testMain.h>
|
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
using namespace epics::pvData;
|
|
||||||
using namespace epics::pvAccess;
|
|
||||||
using namespace epics::pva;
|
|
||||||
|
|
||||||
|
|
||||||
static void example(PvaPtr const &pva)
|
|
||||||
{
|
|
||||||
cout << "\nstarting channelPutGet example\n";
|
|
||||||
try {
|
|
||||||
PvaChannelPtr pvaChannel = pva->createChannel("examplePowerSupply");
|
|
||||||
pvaChannel->connect(2.0);
|
|
||||||
testOk(true==true,"connected");
|
|
||||||
PvaPutGetPtr putGet = pvaChannel->createPutGet(
|
|
||||||
"putField(power.value,voltage.value)getField()");
|
|
||||||
PvaPutDataPtr putData = putGet->getPutData();
|
|
||||||
testOk(true==true,"put connected");
|
|
||||||
PVStructurePtr pvStructure = putData->getPVStructure();
|
|
||||||
PVDoublePtr power = pvStructure->getSubField<PVDouble>("power.value");
|
|
||||||
PVDoublePtr voltage = pvStructure->getSubField<PVDouble>("voltage.value");
|
|
||||||
power->put(5.0);
|
|
||||||
voltage->put(5.0);
|
|
||||||
putGet->putGet();
|
|
||||||
PvaGetDataPtr getData = putGet->getGetData();
|
|
||||||
pvStructure = getData->getPVStructure();
|
|
||||||
BitSetPtr bitSet = getData->getBitSet();
|
|
||||||
cout << "changed " << getData->showChanged(cout) << endl;
|
|
||||||
cout << "bitSet " << *bitSet << endl;
|
|
||||||
power->put(6.0);
|
|
||||||
putGet->putGet();
|
|
||||||
pvStructure = getData->getPVStructure();
|
|
||||||
bitSet = getData->getBitSet();
|
|
||||||
cout << "changed " << getData->showChanged(cout) << endl;
|
|
||||||
} catch (std::runtime_error e) {
|
|
||||||
cout << "exception " << e.what() << endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
MAIN(testPvaPutGet)
|
|
||||||
{
|
|
||||||
cout << "\nstarting testPvaPutGet\n";
|
|
||||||
testPlan(2);
|
|
||||||
PvaPtr pva = Pva::create();
|
|
||||||
example(pva);
|
|
||||||
cout << "done\n";
|
|
||||||
return 0;
|
|
||||||
}
|
|
@ -1,89 +0,0 @@
|
|||||||
/*testPvaPutGetMonitor.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
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Author: Marty Kraimer */
|
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
#include <pv/pva.h>
|
|
||||||
#include <epicsUnitTest.h>
|
|
||||||
#include <testMain.h>
|
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
using namespace epics::pvData;
|
|
||||||
using namespace epics::pvAccess;
|
|
||||||
using namespace epics::pva;
|
|
||||||
|
|
||||||
|
|
||||||
class MyMonitor : public PvaMonitorRequester
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
MyMonitor() {}
|
|
||||||
virtual ~MyMonitor() {}
|
|
||||||
virtual void event(PvaMonitorPtr monitor)
|
|
||||||
{
|
|
||||||
while(true) {
|
|
||||||
if(!monitor->poll()) return;
|
|
||||||
PvaMonitorDataPtr pvaData = monitor->getData();
|
|
||||||
cout << "changed\n";
|
|
||||||
pvaData->showChanged(cout);
|
|
||||||
cout << "overrun\n";
|
|
||||||
pvaData->showOverrun(cout);
|
|
||||||
monitor->releaseEvent();
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
static void exampleDouble(PvaPtr const &pva)
|
|
||||||
{
|
|
||||||
cout << "\nstarting exampleDouble\n";
|
|
||||||
try {
|
|
||||||
cout << "long way\n";
|
|
||||||
PvaChannelPtr pvaChannel = pva->createChannel("exampleDouble");
|
|
||||||
pvaChannel->connect(2.0);
|
|
||||||
testOk(true==true,"connected");
|
|
||||||
PvaPutPtr put = pvaChannel->createPut();
|
|
||||||
PvaPutDataPtr putData = put->getData();
|
|
||||||
testOk(true==true,"put connected");
|
|
||||||
PvaGetPtr get = pvaChannel->createGet();
|
|
||||||
PvaGetDataPtr getData = get->getData();
|
|
||||||
testOk(true==true,"get connected");
|
|
||||||
PvaMonitorRequesterPtr requester(new MyMonitor());
|
|
||||||
PvaMonitorPtr monitor = pvaChannel->monitor(requester);
|
|
||||||
testOk(true==true,"monitor connected");
|
|
||||||
double out;
|
|
||||||
double in;
|
|
||||||
for(size_t i=0 ; i< 5; ++i) {
|
|
||||||
out = i;
|
|
||||||
putData->putDouble(out);
|
|
||||||
put->put();
|
|
||||||
get->get();
|
|
||||||
in = getData->getDouble();
|
|
||||||
cout << "out " << out << " in " << in << endl;
|
|
||||||
}
|
|
||||||
PvaProcessPtr process = pvaChannel->createProcess();
|
|
||||||
process->connect();
|
|
||||||
process->process();
|
|
||||||
} catch (std::runtime_error e) {
|
|
||||||
cout << "exception " << e.what() << endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
MAIN(testPvaPutGetMonitor)
|
|
||||||
{
|
|
||||||
cout << "\nstarting testPvaPutGetMonitor\n";
|
|
||||||
testPlan(4);
|
|
||||||
PvaPtr pva = Pva::create();
|
|
||||||
exampleDouble(pva);
|
|
||||||
cout << "done\n";
|
|
||||||
return 0;
|
|
||||||
}
|
|
@ -944,10 +944,3 @@ namespace pvAccess {
|
|||||||
}}
|
}}
|
||||||
|
|
||||||
#endif /* PVACCESS_H */
|
#endif /* PVACCESS_H */
|
||||||
|
|
||||||
/** @page Overview Documentation
|
|
||||||
*
|
|
||||||
*<a href = "pvAccessOverview.html">pvAccessOverview.html</a>
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user