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
|
||||
# the files will be copied as-is; there are no commands or markers available.
|
||||
|
||||
HTML_EXTRA_FILES = documentation/pvAccessOverview.html
|
||||
HTML_EXTRA_FILES = documentation/pvaOverview.html
|
||||
HTML_EXTRA_FILES =
|
||||
|
||||
# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output.
|
||||
# Doxygen will adjust the colors in the style sheet and background images
|
||||
|
25
Makefile
25
Makefile
@ -2,25 +2,16 @@
|
||||
|
||||
TOP = .
|
||||
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)
|
||||
EMBEDDED_TOPS := $(EMBEDDED_TOPS) $(filter-out $(EMBEDDED_TOPS), pvaTest)
|
||||
DIRS := configure
|
||||
|
||||
define DIR_template
|
||||
$(1)_DEPEND_DIRS = configure
|
||||
endef
|
||||
$(foreach dir, $(filter-out configure,$(DIRS)),$(eval $(call DIR_template,$(dir))))
|
||||
DIRS += src
|
||||
src_DEPEND_DIRS = configure
|
||||
|
||||
define EMB_template
|
||||
$(1)_DEPEND_DIRS = src pvaSrc
|
||||
endef
|
||||
$(foreach dir, $(EMBEDDED_TOPS),$(eval $(call EMB_template,$(dir))))
|
||||
DIRS += pvtoolsSrc
|
||||
pvtoolsSrc_DEPEND_DIRS = src
|
||||
|
||||
DIRS += testApp
|
||||
testApp_DEPEND_DIRS = src
|
||||
|
||||
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>
|
||||
<!-- 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>
|
||||
<dt>Latest version:</dt>
|
||||
<dd><a
|
||||
@ -46,11 +46,11 @@
|
||||
</a></dd>
|
||||
<dt>This version:</dt>
|
||||
<dd><a
|
||||
href="pvAccessCPP_20150505.html">pvAccessCPP_20150505.html
|
||||
href="pvAccessCPP_20140709.html">pvAccessCPP_20140709.html
|
||||
</a></dd>
|
||||
<dt>Previous version:</dt>
|
||||
<dd><a
|
||||
href="pvAccessCPP_20140709.html">pvAccessCPP_20140709.html
|
||||
href="pvAccessCPP_20111220.html">pvAccessCPP_20111220.html
|
||||
</a></dd>
|
||||
<dt>Editors:</dt>
|
||||
<dd>Marty Kraimer, BNL<br />
|
||||
@ -59,77 +59,40 @@
|
||||
<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:
|
||||
<p>pvAccessCPP is the C++ implementation of pvAccess, which is one of a related
|
||||
set of products:</br >
|
||||
<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>
|
||||
<p>This is the 09-July-2011 version of the C++ implementation of pvAccess. The
|
||||
code is a complete implementation of pvAccess as currently defined. This
|
||||
overview is NOT written.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div id="toc">
|
||||
<h2 class="nocount">Table of Contents</h2>
|
||||
<h2 class="nocount" style="page-break-before: always">Table of Contents</h2>
|
||||
</div>
|
||||
|
||||
<!-- Place what you would like in the Table of Contents, inside the contents div -->
|
||||
<div id="contents" class="contents">
|
||||
|
||||
|
||||
|
||||
<h2 id="L88">Introduction</h2>
|
||||
<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>
|
||||
<p>This product is available via an <a
|
||||
href="http://epics-pvdata.sourceforge.net/LICENSE.html">open source
|
||||
license</a></p>
|
||||
|
||||
<p>This overview for pvAccessCPP. Doxygen documentation is available at <a
|
||||
href="./html/index.html">doxygenDoc</a></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>
|
||||
<p><b>THIS IS NOT WRITTEN</b> For now please consult pvAccessJava.html.
|
||||
In addition look at the Doxygen documentation for this project.</p>
|
||||
|
||||
</div>
|
||||
</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 */
|
||||
|
||||
/** @page Overview Documentation
|
||||
*
|
||||
*<a href = "pvAccessOverview.html">pvAccessOverview.html</a>
|
||||
*
|
||||
*/
|
||||
|
||||
|
Reference in New Issue
Block a user