all EasyChannel methods are implemented except channelArray; EasyMultiChannel not started.
This commit is contained in:
2
Doxyfile
2
Doxyfile
@ -1078,7 +1078,7 @@ HTML_EXTRA_STYLESHEET =
|
||||
# files will be copied as-is; there are no commands or markers available.
|
||||
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||
|
||||
HTML_EXTRA_FILES = documentation/easyPVACPP.html
|
||||
#HTML_EXTRA_FILES = documentation/overview.html
|
||||
|
||||
# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen
|
||||
# will adjust the colors in the stylesheet and background images according to
|
||||
|
9
README.txt
Normal file
9
README.txt
Normal file
@ -0,0 +1,9 @@
|
||||
To build do the following:
|
||||
|
||||
cd configure
|
||||
cp ExampleRELEASE.local RELEASE.local
|
||||
edit RELEASE.local
|
||||
cd ..
|
||||
make
|
||||
|
||||
Now read documentation/easyPVA.html
|
@ -28,7 +28,7 @@
|
||||
<h1>EPICS easyPVA</h1>
|
||||
<!-- Maturity: Working Draft or Request for Comments, or Recommendation, and date. -->
|
||||
<h2 class="nocount">EPICS V4 Working Group, Working Draft,
|
||||
02-Mar-2015</h2>
|
||||
13-Mar-2015</h2>
|
||||
<dl>
|
||||
<dt>This version:</dt>
|
||||
<dd><a
|
||||
@ -68,8 +68,6 @@ The first is as an NTMultiChannel. The second is as a double array.
|
||||
The double array can be used if the value field of every channel is a numeric scalar.
|
||||
There is code for NTMultiChannel that helps with access to more complicated data types.
|
||||
</p>
|
||||
<p>EasyPVA will become part of pvAccess when it is ready. </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
|
||||
@ -96,159 +94,35 @@ There is code for NTMultiChannel that helps with access to more complicated data
|
||||
<p>EasyPVA 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>The EasyPVA API has the following features:</p>
|
||||
<ol>
|
||||
<li>Makes common requests easy to program</li>
|
||||
<li>Provides full access to the pvAccess API for more demanding
|
||||
applications</li>
|
||||
<li>Allows efficient client side programs.</li>
|
||||
</ol>
|
||||
|
||||
<p>This document briefly describes the CPP version of EasyPVA.
|
||||
Doxygen documentation is available at <a
|
||||
href="./html/index.html">doxygenDoc</a></p>
|
||||
<h3>EasyPVA Interfaces</h3>
|
||||
<h4>Simple</h4>
|
||||
<p>The following</p>
|
||||
<pre>
|
||||
EasyPVAPtr easyPVA = EasyPVA::create();
|
||||
double value = easyPVA->channel("exampleDouble")->get()->getDouble();
|
||||
cout << "as double " << value << endl;
|
||||
</pre>
|
||||
produces:
|
||||
<pre>
|
||||
as double 5
|
||||
</pre>
|
||||
<p>This is an example of the simplest way to use EasyPVA.
|
||||
An important feature is that,
|
||||
when the simple interface is used,
|
||||
EasyPva caches Channels, ChannelGets, etc.
|
||||
This if the above code is replaced by:</p>
|
||||
<pre>
|
||||
EasyPVAPtr easyPVA = EasyPVA::create();
|
||||
double value = easyPVA->channel("exampleDouble")->get()->getDouble();
|
||||
cout << "as double " << value << endl;
|
||||
value = easyPVA->channel("exampleDouble")->get()->getDouble();
|
||||
cout << "as double " << value << endl;
|
||||
</pre>
|
||||
The second call will reuse the channel and channelGet created by the first call.
|
||||
<p>But if any problems occur using the simple interface an exception is thrown.</p>
|
||||
|
||||
<h4>More Complex But No Exceptions.</h4>
|
||||
<p>The following</p>
|
||||
<pre>
|
||||
EasyPVAPtr easyPVA = EasyPVA::create();
|
||||
EasyChannelPtr easyChannel = easyPVA->createChannel("exampleDouble");
|
||||
easyChannel->issueConnect();
|
||||
Status status = easyChannel->waitConnect(2.0);
|
||||
if(!status.isOK()) {cout << " connect failed\n"; return;}
|
||||
EasyGetPtr easyGet = easyChannel->createGet();
|
||||
easyGet->issueConnect();
|
||||
status = easyGet->waitConnect();
|
||||
if(!status.isOK()) {cout << " createGet failed\n"; return;}
|
||||
value = easyGet->getDouble();
|
||||
cout << "as double " << value << endl;
|
||||
</pre>
|
||||
also produces:
|
||||
<pre>
|
||||
as double 5
|
||||
</pre>
|
||||
<p>The main feature of this over the simple way is that no exceptions will be thrown.</p>
|
||||
|
||||
<h3>Initialization</h3>
|
||||
|
||||
<p>A client obtains the interface to EasyPVA via the call:</p>
|
||||
<pre>EasyPVAPtr easyPVA = EasyPVAFactorys->create();</pre>
|
||||
|
||||
<p>The client can call this an arbitrary number of times.
|
||||
On the first call the PVAccess client factory is started.
|
||||
When the last EasyPVA is destroyed the PVAccess client factory is stopped.
|
||||
</p>This document describes the layout of the source files in this project.</p>
|
||||
<p>
|
||||
A user overview is available via
|
||||
<a
|
||||
href="./overiew.html">overview.html
|
||||
</a>
|
||||
</p>
|
||||
|
||||
<h3>EasyPVA Overview</h3>
|
||||
|
||||
<p>EasyPVA creates interfaces to one of the following:</p>
|
||||
<dl>
|
||||
<dt>EasyChannel</dt>
|
||||
<dd>This creates an interface for accessing a single channel.<br />
|
||||
There are two methods for creating an EasyChannel,
|
||||
with the difference being that the second
|
||||
specifiers the name of the provider.
|
||||
The other assumes that the provider is "pva" (pvAccess).
|
||||
</dd>
|
||||
<dt>EasyMultiChannel</dt>
|
||||
<dd>This creates an interface for accessing a set of channels.<br />
|
||||
There are multiple methods for creating an EasyMultiChannel.
|
||||
The provider can be supplied or use a default of "pva".
|
||||
A union for the UnionArray for accessing the value fields of each channel
|
||||
can be provided or a default of variant union will be used.
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
<h3>EasyChannel Overview</h3>
|
||||
|
||||
<p>This interface creates Easy support for each PVAccess::Channel create
|
||||
method:</p>
|
||||
<dl>
|
||||
<dt>EasyField</dt>
|
||||
<dd>This gets the introspection interface from a channel. The
|
||||
implementation provides full access to the features of
|
||||
Channel::getField.</dd>
|
||||
<dt>EasyProcess</dt>
|
||||
<dd>This is used to process a channel. The implementation provides full
|
||||
access to the features of ChannelProcess.</dd>
|
||||
<dt>EasyGet</dt>
|
||||
<dd>This is used to get values from a channel. The implementation allows
|
||||
full access to all the features of ChannelGet. By default it asks for the
|
||||
fields value, alarm, and timeStamp. If the channel has a value field then
|
||||
EasyGet provides convenience methods for a scalar value and for an array
|
||||
value. </dd>
|
||||
<dt>EasyPut</dt>
|
||||
<dd>This is used to get the current value of a channel and to put values to
|
||||
a channel. The implementation allows full access to all the features of
|
||||
ChannelPut. By default it asks for the field value, alarm, and timeStamp.
|
||||
If the channel has a value field then EasyPut provides convenience
|
||||
methods for a scalar value and for an array value. </dd>
|
||||
<dt>EasyRPC</dt>
|
||||
<dd>This is an interface to ChannelRPC.
|
||||
The implementation allows full access to all the features of ChannelRPC.
|
||||
</dd>
|
||||
<dt>EasyPutGet</dt>
|
||||
<dd>This is an interface to ChannelPutGet. Details TBD.</dd>
|
||||
<dt>EasyMonitor</dt>
|
||||
<dd>This is an interface to Monitor.
|
||||
The implementation allows full access to all the features of pvAccess Monitor.
|
||||
</dd>
|
||||
<dt>EasyArray</dt>
|
||||
<dd>This is an interface to ChannelArray. Details TBD.</dd>
|
||||
<dt>EasyProcess</dt>
|
||||
<dd>This is an interface to ChannelProcess. Details TBD.</dd>
|
||||
</dl>
|
||||
|
||||
<h3>EasyMultiChannel Overview</h3>
|
||||
<p>This interface creates Easy support for accessing a set of channels.
|
||||
The only requirement of the channels is that each must have a top level field named value.
|
||||
<p>
|
||||
Doxygen documentation is available at
|
||||
<a
|
||||
href="./html/index.html">doxygenDoc
|
||||
</a>
|
||||
</p>
|
||||
<dl>
|
||||
<dt>EasyMultiGet</dt>
|
||||
<dd>This is used to get values from a a set of channels.
|
||||
The result can either be an NTMultiChannel structure or a <b>double[]</b> array.
|
||||
The createGet method determines the result type.
|
||||
</dd>
|
||||
<dt>EasyMultiPut</dt>
|
||||
<dd>This is used to get and put values from/to a set of channels.
|
||||
The data supplied can either be an NTMultiChannel structure or a <b>double[]</b> array.
|
||||
The createPut method determines the type.
|
||||
</dd>
|
||||
<dt>EasyMonitor</dt>
|
||||
<dd>This is used to monitor values from a set of channels.
|
||||
Each event can either be an NTMultiChannel structure or a <b>double[]</b> array.
|
||||
The createMonitor method determines the data type.
|
||||
</dd>
|
||||
</dl>
|
||||
<h2>Building</h2>
|
||||
<p>After obtaining the source:</p>
|
||||
<pre>
|
||||
cd configure
|
||||
cp ExampleRELEASE.local RELEASE.local
|
||||
</pre>
|
||||
<p>Edit <b>RELEASE.local</b> so that all path names are correct for you environment.
|
||||
</p>
|
||||
<p>
|
||||
Then:</p>
|
||||
<pre>
|
||||
cd ..
|
||||
make
|
||||
</pre>
|
||||
|
||||
<h2>example source code</h2>
|
||||
<h3>Example Database</h3>
|
||||
<h2>Example and Test Database</h2>
|
||||
<p>The examples require that an example pvAccess server is runnimg.
|
||||
This distribution has a file <b>exampleDatabaseEasyPVA.zip</b>.
|
||||
When unzipped this is used to create an example IOC database.
|
||||
@ -267,8 +141,14 @@ make
|
||||
cd iocBoot/exampleDatabase
|
||||
../../bin/<arch:>/exampleDatabase st.cmd
|
||||
</pre>
|
||||
<h3>Examples</h3>
|
||||
<p>These are examples in directory <b>example/src</b>.
|
||||
<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>example/src</b>.
|
||||
An example of how to run them is:</p>
|
||||
<pre>
|
||||
mrk> pwd
|
||||
@ -279,8 +159,6 @@ mrk> bin/linux-x86_64/exampleEasyGet
|
||||
See the source code for each example.
|
||||
</p>
|
||||
|
||||
|
||||
|
||||
</div> <!-- class="contents" -->
|
||||
</body>
|
||||
</html>
|
||||
|
294
documentation/overview.html
Normal file
294
documentation/overview.html
Normal file
@ -0,0 +1,294 @@
|
||||
<?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>easyPVA 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>easyPVA 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>EasyPVA is a synchronous API for accessing PVData via PVAccess.
|
||||
It also provides a number of convience methods.
|
||||
It allows the client to request access without checking for failure,
|
||||
but throws an exception when a reuest fails.
|
||||
A client can also check for failues and thus prevent failures.</p>
|
||||
|
||||
<p>The EasyPVA 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 easy.</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 easyPVA:</p>
|
||||
<pre>
|
||||
// easyGet
|
||||
EasyPVAPtr easyPVA = EasyPVA::create();
|
||||
double value = easyPVA->channel("exampleDouble")->get()->getData()->getDouble();
|
||||
|
||||
// easyPut
|
||||
EasyChannelPtr channel = easyPVA->channel("exampleDouble");
|
||||
EasyPutPtr put = channel->put();
|
||||
EasyPutDataPtr putData = put->getData();
|
||||
putData->putDouble(3.0); put->put();
|
||||
|
||||
// easyMonitor
|
||||
EasyMonitorPtr monitor = easyPVA->channel("examplePowerSupply")->monitor("");
|
||||
EasyMonitorDataPtr easyData = monitor->getData();
|
||||
while(true) {
|
||||
monitor->waitEvent();
|
||||
cout << "changed\n";
|
||||
easyData->showChanged(cout);
|
||||
cout << "overrun\n";
|
||||
easyData->showOverrun(cout);
|
||||
monitor->releaseEvent();
|
||||
}
|
||||
|
||||
// easyProcess
|
||||
EasyChannelPtr channel = easyPVA->channel("exampleDouble");
|
||||
EasyProcessPtr process = channel->createProcess();
|
||||
process->process();
|
||||
|
||||
</pre>
|
||||
|
||||
<h2>EasyPVA</h2>
|
||||
<p>An instance of EasyPVA is obtained via the call:</p>
|
||||
<pre>
|
||||
EasyPVAPtr easyPVA = EasyPVA::create();
|
||||
</pre>
|
||||
|
||||
<p>EasyPVA has methods to create instances of <b>EasyChannel</b>.
|
||||
The client can specify the provider name or use the default provider.
|
||||
The client can manage it's own channels or can let easyPVA cache channels.
|
||||
An example of using the cache method is:</p>
|
||||
<pre>
|
||||
string channelName("exampleDouble");
|
||||
EasyChannelPtr easyChannel = easyPVA->channel(channelName);
|
||||
</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, easyPVA caches the easyChannel 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>
|
||||
string channelName("exampleDouble");
|
||||
EasyChannelPtr easyChannel = easyPVA->createChannel(channelName);
|
||||
</pre>
|
||||
<p>This will create an EasyChannel 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>EasyChannel - Wrapper For Single Channel</h2>
|
||||
<h3>EasyChannel</h3>
|
||||
<p>This provides methods for connecting to a channel and for creating instances of
|
||||
EasyField, EasyProcess, ..., EasyRPC.</p>
|
||||
<p>Connection must be made before any crete method is called or
|
||||
an exception is raised.
|
||||
The following is a synchronous connection request:</p>
|
||||
<pre>
|
||||
easyChannel->connect(5.0); // BLOCKS
|
||||
</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>
|
||||
easyChannel->issueConnect(); // DOES NOT BLOCK
|
||||
.....
|
||||
Status status =easyChannel->waitConnect(5.0); // BLOCKS
|
||||
if(!status.isOK()) {
|
||||
// failure do something
|
||||
}
|
||||
</pre>
|
||||
<p>Once the channel is connected other Easy objects can be created.
|
||||
For example:</p>
|
||||
<pre>
|
||||
EasyGetPtr easyGet = easyChannel->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 easyGet 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>
|
||||
EasyGetPtr easyGet = easyChannel->createGet(); // DOES NOT BLOCK
|
||||
</pre>
|
||||
<p>The client must connect the easyGet.</p>
|
||||
|
||||
<h3>EasyGetData</h3>
|
||||
<p>This provides the data returned by easyGet and easyPutGet.
|
||||
It is obtained via:</p>
|
||||
<pre>
|
||||
EasyGetDataPtr easyData = easyGet->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 = easyData->getDouble();
|
||||
</pre>
|
||||
<p>It also keeps a bitSet showing which fields have changed since the last channelGet or channelPutGet.</p>
|
||||
|
||||
<h3>EasyMonitorData</h3>
|
||||
<p>To the client this looks identical to EasyGetData except that
|
||||
it provides two BitSets: changedBitSet and overrrunBitSet.
|
||||
It is used by easyMonitor.
|
||||
</p>
|
||||
<h3>EasyPutData</h3>
|
||||
<p>This is used to provided data for easyPut and easyPutGet.
|
||||
It has many of the same methods as easyGetData.
|
||||
It does not have a bitSet.
|
||||
It also has put methods like:</p>
|
||||
<pre>
|
||||
void easyData->putDouble(5.0);
|
||||
</pre>
|
||||
<h3>EasyGet</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
|
||||
</pre>
|
||||
<p>This can also be done in two steps:</p>
|
||||
<pre>
|
||||
easyGet->issueConnect(); // DOES NOT BLOCK
|
||||
...
|
||||
Status status = easyGet->waitConnect(); // BLOCKS
|
||||
</pre>
|
||||
<p>Once connected gets are issued via either:</p>
|
||||
<pre>
|
||||
void easyGet->get();
|
||||
</pre>
|
||||
or
|
||||
<pre>
|
||||
easyGet->issueGet(); // DOES NOT BLOCK
|
||||
...
|
||||
Status status = easyGet->waitGet(); // BLOCKS
|
||||
</pre>
|
||||
<h3>EasyPut</h3>
|
||||
<p>This is similar to easyGet except that it wraps channelPut instead of channelGet.
|
||||
</p>
|
||||
<p>Once connected puts are issued via either:</p>
|
||||
<pre>
|
||||
void easyPut->put();
|
||||
</pre>
|
||||
or
|
||||
<pre>
|
||||
easyPut->issuePut(); // DOES NOT BLOCK
|
||||
...
|
||||
Status status = easyPut->waitPut(); // BLOCKS
|
||||
</pre>
|
||||
<h3>EasyMonitor</h3>
|
||||
<p>Connecting is similar to easyGet and easyPut.
|
||||
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 easyMonitorData.
|
||||
</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>EasyProcess</h3>
|
||||
<p>Connecting is similar to easyGet.
|
||||
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>EasyPutGet</h3>
|
||||
<p>Connecting is similar to easyGet.
|
||||
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 EasyData for the put part of channelPutGet.
|
||||
</dd>
|
||||
<dt>getGetData</dt>
|
||||
<dd>
|
||||
Returns the EasyData for the get part of channelPutGet.
|
||||
</dd>
|
||||
</dl>
|
||||
<p>Look at javaDoc for details.</p>
|
||||
|
||||
<h2>EasyMultiChannel - Wrapper For Multiple Channels</h2>
|
||||
<p>TBD</p>
|
||||
|
||||
</div> <!-- class="contents" -->
|
||||
</body>
|
||||
</html>
|
@ -5,6 +5,13 @@ include $(TOP)/configure/CONFIG
|
||||
# ADD MACRO DEFINITIONS AFTER THIS LINE
|
||||
|
||||
|
||||
PROD_HOST += exampleEasyProcess
|
||||
exampleEasyProcess_SRCS += exampleEasyProcess.cpp
|
||||
exampleEasyProcess_LIBS += easyPVA
|
||||
exampleEasyProcess_LIBS += pvAccess
|
||||
exampleEasyProcess_LIBS += pvData
|
||||
exampleEasyProcess_LIBS += Com
|
||||
|
||||
PROD_HOST += exampleEasyGet
|
||||
exampleEasyGet_SRCS += exampleEasyGet.cpp
|
||||
exampleEasyGet_LIBS += easyPVA
|
||||
@ -12,6 +19,20 @@ exampleEasyGet_LIBS += pvAccess
|
||||
exampleEasyGet_LIBS += pvData
|
||||
exampleEasyGet_LIBS += Com
|
||||
|
||||
PROD_HOST += exampleEasyPut
|
||||
exampleEasyPut_SRCS += exampleEasyPut.cpp
|
||||
exampleEasyPut_LIBS += easyPVA
|
||||
exampleEasyPut_LIBS += pvAccess
|
||||
exampleEasyPut_LIBS += pvData
|
||||
exampleEasyPut_LIBS += Com
|
||||
|
||||
PROD_HOST += exampleEasyMonitor
|
||||
exampleEasyMonitor_SRCS += exampleEasyMonitor.cpp
|
||||
exampleEasyMonitor_LIBS += easyPVA
|
||||
exampleEasyMonitor_LIBS += pvAccess
|
||||
exampleEasyMonitor_LIBS += pvData
|
||||
exampleEasyMonitor_LIBS += Com
|
||||
|
||||
#===========================
|
||||
|
||||
include $(TOP)/configure/RULES
|
||||
|
@ -26,7 +26,7 @@ static void exampleDouble(EasyPVAPtr const &easyPVA)
|
||||
double value;
|
||||
try {
|
||||
cout << "short way\n";
|
||||
value = easyPVA->channel("exampleDouble")->get()->getDouble();
|
||||
value = easyPVA->channel("exampleDouble")->get()->getData()->getDouble();
|
||||
cout << "as double " << value << endl;
|
||||
} catch (std::runtime_error e) {
|
||||
cout << "exception " << e.what() << endl;
|
||||
@ -40,17 +40,18 @@ static void exampleDouble(EasyPVAPtr const &easyPVA)
|
||||
easyGet->issueConnect();
|
||||
status = easyGet->waitConnect();
|
||||
if(!status.isOK()) {cout << " createGet failed\n"; return;}
|
||||
value = easyGet->getDouble();
|
||||
EasyGetDataPtr easyData = easyGet->getData();
|
||||
value = easyData->getDouble();
|
||||
cout << "as double " << value << endl;
|
||||
}
|
||||
|
||||
static void exampleDoubleArray(EasyPVAPtr const &easyPVA)
|
||||
{
|
||||
cout << "example double array\n";
|
||||
shared_vector<double> value;
|
||||
shared_vector<const double> value;
|
||||
try {
|
||||
cout << "short way\n";
|
||||
value = easyPVA->createChannel("exampleDoubleArray")->createGet()->getDoubleArray();
|
||||
value = easyPVA->channel("exampleDoubleArray")->get()->getData()->getDoubleArray();
|
||||
cout << "as doubleArray " << value << endl;
|
||||
} catch (std::runtime_error e) {
|
||||
cout << "exception " << e.what() << endl;
|
||||
@ -60,7 +61,8 @@ static void exampleDoubleArray(EasyPVAPtr const &easyPVA)
|
||||
EasyChannelPtr easyChannel = easyPVA->createChannel("exampleDoubleArray");
|
||||
easyChannel->connect(2.0);
|
||||
EasyGetPtr easyGet = easyChannel->createGet();
|
||||
value = easyGet->getDoubleArray();
|
||||
EasyGetDataPtr easyData = easyGet->getData();
|
||||
value = easyData->getDoubleArray();
|
||||
cout << "as doubleArray " << value << endl;
|
||||
} catch (std::runtime_error e) {
|
||||
cout << "exception " << e.what() << endl;
|
||||
@ -73,7 +75,8 @@ static void examplePowerSupply(EasyPVAPtr const &easyPVA)
|
||||
PVStructurePtr pvStructure;
|
||||
try {
|
||||
cout << "short way\n";
|
||||
pvStructure = easyPVA->createChannel("examplePowerSupply")->createGet("field()")->getPVStructure();
|
||||
pvStructure = easyPVA->channel("examplePowerSupply")->
|
||||
get("field()")->getData()->getPVStructure();
|
||||
cout << pvStructure << endl;
|
||||
} catch (std::runtime_error e) {
|
||||
cout << "exception " << e.what() << endl;
|
||||
|
46
example/src/exampleEasyMonitor.cpp
Normal file
46
example/src/exampleEasyMonitor.cpp
Normal file
@ -0,0 +1,46 @@
|
||||
/*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/easyPVA.h>
|
||||
|
||||
using namespace std;
|
||||
using namespace epics::pvData;
|
||||
using namespace epics::pvAccess;
|
||||
using namespace epics::easyPVA;
|
||||
|
||||
|
||||
static void exampleMonitor(EasyPVAPtr const &easyPVA)
|
||||
{
|
||||
EasyMonitorPtr monitor = easyPVA->channel("examplePowerSupply")->monitor("");
|
||||
EasyMonitorDataPtr easyData = monitor->getData();
|
||||
while(true) {
|
||||
monitor->waitEvent();
|
||||
cout << "changed\n";
|
||||
easyData->showChanged(cout);
|
||||
cout << "overrun\n";
|
||||
easyData->showOverrun(cout);
|
||||
monitor->releaseEvent();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int main(int argc,char *argv[])
|
||||
{
|
||||
EasyPVAPtr easyPVA = EasyPVA::create();
|
||||
exampleMonitor(easyPVA);
|
||||
cout << "done\n";
|
||||
return 0;
|
||||
}
|
44
example/src/exampleEasyProcess.cpp
Normal file
44
example/src/exampleEasyProcess.cpp
Normal file
@ -0,0 +1,44 @@
|
||||
/*exampleEasyProcess.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/easyPVA.h>
|
||||
|
||||
using namespace std;
|
||||
using namespace epics::pvData;
|
||||
using namespace epics::pvAccess;
|
||||
using namespace epics::easyPVA;
|
||||
|
||||
|
||||
static void exampleProcess(EasyPVAPtr const &easyPVA)
|
||||
{
|
||||
cout << "example process\n";
|
||||
EasyChannelPtr channel = easyPVA->channel("exampleDouble");
|
||||
EasyProcessPtr 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[])
|
||||
{
|
||||
EasyPVAPtr easyPVA = EasyPVA::create();
|
||||
exampleProcess(easyPVA);
|
||||
return 0;
|
||||
}
|
45
example/src/exampleEasyPut.cpp
Normal file
45
example/src/exampleEasyPut.cpp
Normal file
@ -0,0 +1,45 @@
|
||||
/*exampleEasyProcess.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/easyPVA.h>
|
||||
|
||||
using namespace std;
|
||||
using namespace epics::pvData;
|
||||
using namespace epics::pvAccess;
|
||||
using namespace epics::easyPVA;
|
||||
|
||||
|
||||
static void examplePut(EasyPVAPtr const &easyPVA)
|
||||
{
|
||||
cout << "example process\n";
|
||||
EasyChannelPtr channel = easyPVA->channel("exampleDouble");
|
||||
EasyPutPtr put = channel->put();
|
||||
EasyPutDataPtr 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[])
|
||||
{
|
||||
EasyPVAPtr easyPVA = EasyPVA::create();
|
||||
examplePut(easyPVA);
|
||||
return 0;
|
||||
}
|
10
src/Makefile
10
src/Makefile
@ -8,11 +8,15 @@ LIBRARY += easyPVA
|
||||
INC += easyPVA.h
|
||||
|
||||
LIBSRCS += easyPVA.cpp
|
||||
LIBSRCS += easyPVStructure.cpp
|
||||
LIBSRCS += easyPutData.cpp
|
||||
LIBSRCS += easyGetData.cpp
|
||||
LIBSRCS += easyMonitorData.cpp
|
||||
LIBSRCS += easyChannel.cpp
|
||||
LIBSRCS += easyProcess.cpp
|
||||
LIBSRCS += easyGet.cpp
|
||||
#LIBSRCS += easyPut.cpp
|
||||
#LIBSRCS += easyMonitor.cpp
|
||||
LIBSRCS += easyPut.cpp
|
||||
LIBSRCS += easyMonitor.cpp
|
||||
LIBSRCS += easyPutGet.cpp
|
||||
#LIBSRCS += easyRPC.cpp
|
||||
|
||||
easyPVA_LIBS += pvAccess pvData Com
|
||||
|
@ -25,8 +25,6 @@ using namespace std;
|
||||
|
||||
namespace epics { namespace easyPVA {
|
||||
|
||||
class EasyGetCache;
|
||||
typedef std::tr1::shared_ptr<EasyGetCache> EasyGetCachePtr;
|
||||
|
||||
class EasyGetCache
|
||||
{
|
||||
@ -60,109 +58,65 @@ void EasyGetCache::addGet(string const & request,EasyGetPtr const & easyGet)
|
||||
request,easyGet));
|
||||
}
|
||||
|
||||
class epicsShareClass EasyChannelImpl :
|
||||
public EasyChannel,
|
||||
public std::tr1::enable_shared_from_this<EasyChannelImpl>
|
||||
|
||||
class EasyPutCache
|
||||
{
|
||||
public:
|
||||
EasyChannelImpl(
|
||||
EasyPVAPtr const &pva,
|
||||
string const & channelName,
|
||||
string const & providerName);
|
||||
virtual ~EasyChannelImpl();
|
||||
// from EasyChannel
|
||||
void channelCreated(const Status& status, Channel::shared_pointer const & channel);
|
||||
void channelStateChange(
|
||||
Channel::shared_pointer const & channel,
|
||||
Channel::ConnectionState connectionState);
|
||||
tr1::shared_ptr<Channel> getChannel();
|
||||
string getRequesterName();
|
||||
void message(
|
||||
string const & message,
|
||||
MessageType messageType);
|
||||
virtual void destroy();
|
||||
virtual string getChannelName();
|
||||
virtual void connect(double timeout);
|
||||
virtual void issueConnect();
|
||||
virtual Status waitConnect(double timeout);
|
||||
virtual EasyFieldPtr createField();
|
||||
virtual EasyFieldPtr createField(string const & subField);
|
||||
virtual EasyProcessPtr createProcess();
|
||||
virtual EasyProcessPtr createProcess(string const & request);
|
||||
virtual EasyProcessPtr createProcess(PVStructurePtr const & pvRequest);
|
||||
virtual EasyGetPtr get() {return get("value,alarm,timeStamp");}
|
||||
virtual EasyGetPtr get(string const & request);
|
||||
virtual EasyGetPtr createGet();
|
||||
virtual EasyGetPtr createGet(string const & request);
|
||||
virtual EasyGetPtr createGet(PVStructurePtr const & pvRequest);
|
||||
virtual EasyPutPtr createPut();
|
||||
virtual EasyPutPtr createPut(string const & request);
|
||||
virtual EasyPutPtr createPut(PVStructurePtr const & pvRequest);
|
||||
virtual EasyPutGetPtr createPutGet();
|
||||
virtual EasyPutGetPtr createPutGet(string const & request);
|
||||
virtual EasyPutGetPtr createPutGet(PVStructurePtr const & pvRequest);
|
||||
virtual EasyRPCPtr createRPC();
|
||||
virtual EasyRPCPtr createRPC(string const & request);
|
||||
virtual EasyRPCPtr createRPC(PVStructurePtr const & pvRequest);
|
||||
virtual EasyArrayPtr createArray();
|
||||
virtual EasyArrayPtr createArray(string const & request);
|
||||
virtual EasyArrayPtr createArray(PVStructurePtr const & pvRequest);
|
||||
virtual EasyMonitorPtr createMonitor();
|
||||
virtual EasyMonitorPtr createMonitor(string const & request);
|
||||
virtual EasyMonitorPtr createMonitor(PVStructurePtr const & pvRequest);
|
||||
|
||||
EasyChannelPtr getPtrSelf()
|
||||
{
|
||||
return shared_from_this();
|
||||
EasyPutCache(){}
|
||||
~EasyPutCache();
|
||||
void destroy() {
|
||||
easyPutMap.clear();
|
||||
}
|
||||
EasyPutPtr getPut(string const & request);
|
||||
void addPut(string const & request,EasyPutPtr const & easyPut);
|
||||
private:
|
||||
enum ConnectState {connectIdle,connectActive,notConnected,connected};
|
||||
|
||||
EasyPVA::weak_pointer easyPVA;
|
||||
string channelName;
|
||||
string providerName;
|
||||
ConnectState connectState;
|
||||
bool isDestroyed;
|
||||
CreateRequest::shared_pointer createRequest;
|
||||
EasyGetCachePtr easyGetCache;
|
||||
|
||||
Status channelConnectStatus;
|
||||
Mutex mutex;
|
||||
Event waitForConnect;
|
||||
Channel::shared_pointer channel;
|
||||
ChannelRequester::shared_pointer channelRequester;
|
||||
|
||||
map<string,EasyPutPtr> easyPutMap;
|
||||
};
|
||||
|
||||
namespace easyChannel {
|
||||
EasyPutCache::~EasyPutCache()
|
||||
{
|
||||
destroy();
|
||||
}
|
||||
|
||||
EasyPutPtr EasyPutCache::getPut(string const & request)
|
||||
{
|
||||
map<string,EasyPutPtr>::iterator iter = easyPutMap.find(request);
|
||||
if(iter!=easyPutMap.end()) return iter->second;
|
||||
return EasyPutPtr();
|
||||
}
|
||||
|
||||
void EasyPutCache::addPut(string const & request,EasyPutPtr const & easyPut)
|
||||
{
|
||||
easyPutMap.insert(std::pair<string,EasyPutPtr>(
|
||||
request,easyPut));
|
||||
}
|
||||
|
||||
class ChannelRequesterImpl : public ChannelRequester
|
||||
{
|
||||
EasyChannelImpl *easyChannel;
|
||||
EasyChannel *easyChannel;
|
||||
public:
|
||||
ChannelRequesterImpl(EasyChannelImpl *easyChannel)
|
||||
ChannelRequesterImpl(EasyChannel *easyChannel)
|
||||
: easyChannel(easyChannel) {}
|
||||
virtual void channelCreated(
|
||||
void channelCreated(
|
||||
const Status& status,
|
||||
Channel::shared_pointer const & channel)
|
||||
{ easyChannel->channelCreated(status,channel); }
|
||||
virtual void channelStateChange(
|
||||
void channelStateChange(
|
||||
Channel::shared_pointer const & channel,
|
||||
Channel::ConnectionState connectionState)
|
||||
{easyChannel->channelStateChange(channel,connectionState);}
|
||||
virtual tr1::shared_ptr<Channel> getChannel() {return easyChannel->getChannel();}
|
||||
virtual string getRequesterName()
|
||||
tr1::shared_ptr<Channel> getChannel() {return easyChannel->getChannel();}
|
||||
string getRequesterName()
|
||||
{return easyChannel->getRequesterName();}
|
||||
virtual void message(
|
||||
void message(
|
||||
string const & message,
|
||||
MessageType messageType)
|
||||
{ easyChannel->message(message,messageType); }
|
||||
virtual void destroy() {easyChannel->destroy();}
|
||||
void destroy() {easyChannel->destroy();}
|
||||
};
|
||||
} //end namespace easyChannel`
|
||||
|
||||
using namespace epics::easyPVA::easyChannel;
|
||||
|
||||
EasyChannelImpl::EasyChannelImpl(
|
||||
EasyChannel::EasyChannel(
|
||||
EasyPVAPtr const &easyPVA,
|
||||
string const & channelName,
|
||||
string const & providerName)
|
||||
@ -172,25 +126,26 @@ EasyChannelImpl::EasyChannelImpl(
|
||||
connectState(connectIdle),
|
||||
isDestroyed(false),
|
||||
createRequest(CreateRequest::create()),
|
||||
easyGetCache(new EasyGetCache())
|
||||
easyGetCache(new EasyGetCache()),
|
||||
easyPutCache(new EasyPutCache())
|
||||
{}
|
||||
|
||||
EasyChannelImpl::~EasyChannelImpl()
|
||||
EasyChannel::~EasyChannel()
|
||||
{
|
||||
destroy();
|
||||
}
|
||||
|
||||
void EasyChannelImpl::channelCreated(const Status& status, Channel::shared_pointer const & channel)
|
||||
void EasyChannel::channelCreated(const Status& status, Channel::shared_pointer const & channel)
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyChannel was destroyed");
|
||||
if(status.isOK()) {
|
||||
this->channel = channel;
|
||||
return;
|
||||
}
|
||||
cout << "EasyChannelImpl::channelCreated status " << status.getMessage() << " why??\n";
|
||||
cout << "EasyChannel::channelCreated status " << status.getMessage() << " why??\n";
|
||||
}
|
||||
|
||||
void EasyChannelImpl::channelStateChange(
|
||||
void EasyChannel::channelStateChange(
|
||||
Channel::shared_pointer const & channel,
|
||||
Channel::ConnectionState connectionState)
|
||||
{
|
||||
@ -209,20 +164,20 @@ void EasyChannelImpl::channelStateChange(
|
||||
if(waitingForConnect) waitForConnect.signal();
|
||||
}
|
||||
|
||||
tr1::shared_ptr<Channel> EasyChannelImpl::getChannel()
|
||||
tr1::shared_ptr<Channel> EasyChannel::getChannel()
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyChannel was destroyed");
|
||||
return channel;
|
||||
}
|
||||
|
||||
string EasyChannelImpl::getRequesterName()
|
||||
string EasyChannel::getRequesterName()
|
||||
{
|
||||
EasyPVAPtr yyy = easyPVA.lock();
|
||||
if(!yyy) throw std::runtime_error("EasyPVA was destroyed");
|
||||
return yyy->getRequesterName();
|
||||
}
|
||||
|
||||
void EasyChannelImpl::message(
|
||||
void EasyChannel::message(
|
||||
string const & message,
|
||||
MessageType messageType)
|
||||
{
|
||||
@ -232,7 +187,7 @@ void EasyChannelImpl::message(
|
||||
yyy->message(message, messageType);
|
||||
}
|
||||
|
||||
void EasyChannelImpl::destroy()
|
||||
void EasyChannel::destroy()
|
||||
{
|
||||
{
|
||||
Lock xx(mutex);
|
||||
@ -242,15 +197,16 @@ void EasyChannelImpl::destroy()
|
||||
if(channel) channel->destroy();
|
||||
channel.reset();
|
||||
easyGetCache.reset();
|
||||
easyPutCache.reset();
|
||||
}
|
||||
|
||||
string EasyChannelImpl::getChannelName()
|
||||
string EasyChannel::getChannelName()
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyChannel was destroyed");
|
||||
return channelName;
|
||||
}
|
||||
|
||||
void EasyChannelImpl::connect(double timeout)
|
||||
void EasyChannel::connect(double timeout)
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyChannel was destroyed");
|
||||
issueConnect();
|
||||
@ -261,7 +217,7 @@ void EasyChannelImpl::connect(double timeout)
|
||||
throw std::runtime_error(ss.str());
|
||||
}
|
||||
|
||||
void EasyChannelImpl::issueConnect()
|
||||
void EasyChannel::issueConnect()
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyChannel was destroyed");
|
||||
if(connectState!=connectIdle) {
|
||||
@ -279,7 +235,7 @@ void EasyChannelImpl::issueConnect()
|
||||
}
|
||||
}
|
||||
|
||||
Status EasyChannelImpl::waitConnect(double timeout)
|
||||
Status EasyChannel::waitConnect(double timeout)
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyChannel was destroyed");
|
||||
waitForConnect.wait(timeout);
|
||||
@ -287,22 +243,22 @@ Status EasyChannelImpl::waitConnect(double timeout)
|
||||
return Status(Status::STATUSTYPE_ERROR,channelConnectStatus.getMessage());
|
||||
}
|
||||
|
||||
EasyFieldPtr EasyChannelImpl::createField()
|
||||
EasyFieldPtr EasyChannel::createField()
|
||||
{
|
||||
return createField("");
|
||||
}
|
||||
|
||||
EasyFieldPtr EasyChannelImpl::createField(string const & subField)
|
||||
EasyFieldPtr EasyChannel::createField(string const & subField)
|
||||
{
|
||||
throw std::runtime_error("EasyChannel::createField not implemented");
|
||||
}
|
||||
|
||||
EasyProcessPtr EasyChannelImpl::createProcess()
|
||||
EasyProcessPtr EasyChannel::createProcess()
|
||||
{
|
||||
return createProcess("");
|
||||
}
|
||||
|
||||
EasyProcessPtr EasyChannelImpl::createProcess(string const & request)
|
||||
EasyProcessPtr EasyChannel::createProcess(string const & request)
|
||||
{
|
||||
PVStructurePtr pvRequest = createRequest->createRequest(request);
|
||||
if(!pvRequest) {
|
||||
@ -314,28 +270,33 @@ EasyProcessPtr EasyChannelImpl::createProcess(string const & request)
|
||||
return createProcess(pvRequest);
|
||||
}
|
||||
|
||||
EasyProcessPtr EasyChannelImpl::createProcess(PVStructurePtr const & pvRequest)
|
||||
EasyProcessPtr EasyChannel::createProcess(PVStructurePtr const & pvRequest)
|
||||
{
|
||||
throw std::runtime_error("EasyChannel::createProcess not implemented");
|
||||
if(connectState!=connected) connect(5.0);
|
||||
if(connectState!=connected) throw std::runtime_error("EasyChannel::creatProcess not connected");
|
||||
EasyPVAPtr yyy = easyPVA.lock();
|
||||
if(!yyy) throw std::runtime_error("EasyPVA was destroyed");
|
||||
return EasyProcess::create(yyy,getPtrSelf(),channel,pvRequest);
|
||||
}
|
||||
|
||||
EasyGetPtr EasyChannelImpl::get(string const & request)
|
||||
EasyGetPtr EasyChannel::get() {return get("value,alarm,timeStamp");}
|
||||
|
||||
EasyGetPtr EasyChannel::get(string const & request)
|
||||
{
|
||||
EasyGetPtr easyGet = easyGetCache->getGet(request);
|
||||
if(easyGet) return easyGet;
|
||||
easyGet = createGet(request);
|
||||
easyGet->connect();
|
||||
easyGet->get();
|
||||
easyGetCache->addGet(request,easyGet);
|
||||
return easyGet;
|
||||
}
|
||||
|
||||
EasyGetPtr EasyChannelImpl::createGet()
|
||||
EasyGetPtr EasyChannel::createGet()
|
||||
{
|
||||
return EasyChannelImpl::createGet("value,alarm,timeStamp");
|
||||
return EasyChannel::createGet("value,alarm,timeStamp");
|
||||
}
|
||||
|
||||
EasyGetPtr EasyChannelImpl::createGet(string const & request)
|
||||
EasyGetPtr EasyChannel::createGet(string const & request)
|
||||
{
|
||||
PVStructurePtr pvRequest = createRequest->createRequest(request);
|
||||
if(!pvRequest) {
|
||||
@ -347,21 +308,34 @@ EasyGetPtr EasyChannelImpl::createGet(string const & request)
|
||||
return createGet(pvRequest);
|
||||
}
|
||||
|
||||
EasyGetPtr EasyChannelImpl::createGet(PVStructurePtr const & pvRequest)
|
||||
EasyGetPtr EasyChannel::createGet(PVStructurePtr const & pvRequest)
|
||||
{
|
||||
if(connectState!=connected) connect(5.0);
|
||||
if(connectState!=connected) throw std::runtime_error("EasyChannel::creatGet not connected");
|
||||
EasyPVAPtr yyy = easyPVA.lock();
|
||||
if(!yyy) throw std::runtime_error("EasyPVA was destroyed");
|
||||
return EasyGetFactory::createEasyGet(yyy,getPtrSelf(),channel,pvRequest);
|
||||
return EasyGet::create(yyy,getPtrSelf(),channel,pvRequest);
|
||||
}
|
||||
|
||||
EasyPutPtr EasyChannelImpl::createPut()
|
||||
EasyPutPtr EasyChannel::put() {return put("value");}
|
||||
|
||||
EasyPutPtr EasyChannel::put(string const & request)
|
||||
{
|
||||
EasyPutPtr easyPut = easyPutCache->getPut(request);
|
||||
if(easyPut) return easyPut;
|
||||
easyPut = createPut(request);
|
||||
easyPut->connect();
|
||||
easyPut->get();
|
||||
easyPutCache->addPut(request,easyPut);
|
||||
return easyPut;
|
||||
}
|
||||
|
||||
EasyPutPtr EasyChannel::createPut()
|
||||
{
|
||||
return createPut("value");
|
||||
}
|
||||
|
||||
EasyPutPtr EasyChannelImpl::createPut(string const & request)
|
||||
EasyPutPtr EasyChannel::createPut(string const & request)
|
||||
{
|
||||
PVStructurePtr pvRequest = createRequest->createRequest(request);
|
||||
if(!pvRequest) {
|
||||
@ -373,17 +347,21 @@ EasyPutPtr EasyChannelImpl::createPut(string const & request)
|
||||
return createPut(pvRequest);
|
||||
}
|
||||
|
||||
EasyPutPtr EasyChannelImpl::createPut(PVStructurePtr const & pvRequest)
|
||||
EasyPutPtr EasyChannel::createPut(PVStructurePtr const & pvRequest)
|
||||
{
|
||||
throw std::runtime_error("EasyChannel::createPut not implemented");
|
||||
if(connectState!=connected) connect(5.0);
|
||||
if(connectState!=connected) throw std::runtime_error("EasyChannel::creatPut not connected");
|
||||
EasyPVAPtr yyy = easyPVA.lock();
|
||||
if(!yyy) throw std::runtime_error("EasyPVA was destroyed");
|
||||
return EasyPut::create(yyy,getPtrSelf(),channel,pvRequest);
|
||||
}
|
||||
|
||||
EasyPutGetPtr EasyChannelImpl::createPutGet()
|
||||
EasyPutGetPtr EasyChannel::createPutGet()
|
||||
{
|
||||
return createPutGet("putField(argument)getField(result)");
|
||||
}
|
||||
|
||||
EasyPutGetPtr EasyChannelImpl::createPutGet(string const & request)
|
||||
EasyPutGetPtr EasyChannel::createPutGet(string const & request)
|
||||
{
|
||||
PVStructurePtr pvRequest = createRequest->createRequest(request);
|
||||
if(!pvRequest) {
|
||||
@ -395,17 +373,21 @@ EasyPutGetPtr EasyChannelImpl::createPutGet(string const & request)
|
||||
return createPutGet(pvRequest);
|
||||
}
|
||||
|
||||
EasyPutGetPtr EasyChannelImpl::createPutGet(PVStructurePtr const & pvRequest)
|
||||
EasyPutGetPtr EasyChannel::createPutGet(PVStructurePtr const & pvRequest)
|
||||
{
|
||||
throw std::runtime_error("EasyChannel::createPutGet not implemented");
|
||||
if(connectState!=connected) connect(5.0);
|
||||
if(connectState!=connected) throw std::runtime_error("EasyChannel::creatPutGet not connected");
|
||||
EasyPVAPtr yyy = easyPVA.lock();
|
||||
if(!yyy) throw std::runtime_error("EasyPVA was destroyed");
|
||||
return EasyPutGet::create(yyy,getPtrSelf(),channel,pvRequest);
|
||||
}
|
||||
|
||||
EasyRPCPtr EasyChannelImpl::createRPC()
|
||||
EasyRPCPtr EasyChannel::createRPC()
|
||||
{
|
||||
return createRPC("");
|
||||
}
|
||||
|
||||
EasyRPCPtr EasyChannelImpl::createRPC(string const & request)
|
||||
EasyRPCPtr EasyChannel::createRPC(string const & request)
|
||||
{
|
||||
PVStructurePtr pvRequest = createRequest->createRequest(request);
|
||||
if(!pvRequest) {
|
||||
@ -417,17 +399,17 @@ EasyRPCPtr EasyChannelImpl::createRPC(string const & request)
|
||||
return createRPC(pvRequest);
|
||||
}
|
||||
|
||||
EasyRPCPtr EasyChannelImpl::createRPC(PVStructurePtr const & pvRequest)
|
||||
EasyRPCPtr EasyChannel::createRPC(PVStructurePtr const & pvRequest)
|
||||
{
|
||||
throw std::runtime_error("EasyChannel::createRPC not implemented");
|
||||
}
|
||||
|
||||
EasyArrayPtr EasyChannelImpl::createArray()
|
||||
EasyArrayPtr EasyChannel::createArray()
|
||||
{
|
||||
return createArray("value");
|
||||
}
|
||||
|
||||
EasyArrayPtr EasyChannelImpl::createArray(string const & request)
|
||||
EasyArrayPtr EasyChannel::createArray(string const & request)
|
||||
{
|
||||
PVStructurePtr pvRequest = createRequest->createRequest(request);
|
||||
if(!pvRequest) {
|
||||
@ -439,17 +421,42 @@ EasyArrayPtr EasyChannelImpl::createArray(string const & request)
|
||||
return createArray(pvRequest);
|
||||
}
|
||||
|
||||
EasyArrayPtr EasyChannelImpl::createArray(PVStructurePtr const & pvRequest)
|
||||
EasyArrayPtr EasyChannel::createArray(PVStructurePtr const & pvRequest)
|
||||
{
|
||||
throw std::runtime_error("EasyChannel::createArray not implemented");
|
||||
}
|
||||
|
||||
EasyMonitorPtr EasyChannelImpl::createMonitor()
|
||||
|
||||
EasyMonitorPtr EasyChannel::monitor() {return monitor("value,alarm,timeStamp");}
|
||||
|
||||
EasyMonitorPtr EasyChannel::monitor(string const & request)
|
||||
{
|
||||
EasyMonitorPtr easyMonitor = createMonitor(request);
|
||||
easyMonitor->connect();
|
||||
easyMonitor->start();
|
||||
return easyMonitor;
|
||||
}
|
||||
|
||||
EasyMonitorPtr EasyChannel::monitor(EasyMonitorRequesterPtr const & easyMonitorRequester)
|
||||
{ return monitor("value,alarm,timeStamp",easyMonitorRequester);
|
||||
}
|
||||
|
||||
EasyMonitorPtr EasyChannel::monitor(string const & request,
|
||||
EasyMonitorRequesterPtr const & easyMonitorRequester)
|
||||
{
|
||||
EasyMonitorPtr easyMonitor = createMonitor(request);
|
||||
easyMonitor->connect();
|
||||
easyMonitor->setRequester(easyMonitorRequester);
|
||||
easyMonitor->start();
|
||||
return easyMonitor;
|
||||
}
|
||||
|
||||
EasyMonitorPtr EasyChannel::createMonitor()
|
||||
{
|
||||
return createMonitor("value,alarm,timeStamp");
|
||||
}
|
||||
|
||||
EasyMonitorPtr EasyChannelImpl::createMonitor(string const & request)
|
||||
EasyMonitorPtr EasyChannel::createMonitor(string const & request)
|
||||
{
|
||||
PVStructurePtr pvRequest = createRequest->createRequest(request);
|
||||
if(!pvRequest) {
|
||||
@ -461,25 +468,22 @@ EasyMonitorPtr EasyChannelImpl::createMonitor(string const & request)
|
||||
return createMonitor(pvRequest);
|
||||
}
|
||||
|
||||
EasyMonitorPtr EasyChannelImpl::createMonitor(PVStructurePtr const & pvRequest)
|
||||
EasyMonitorPtr EasyChannel::createMonitor(PVStructurePtr const & pvRequest)
|
||||
{
|
||||
throw std::runtime_error("EasyChannel::createMonitor not implemented");
|
||||
if(connectState!=connected) connect(5.0);
|
||||
if(connectState!=connected) throw std::runtime_error("EasyChannel::createMonitor not connected");
|
||||
EasyPVAPtr yyy = easyPVA.lock();
|
||||
if(!yyy) throw std::runtime_error("EasyPVA was destroyed");
|
||||
return EasyMonitor::create(yyy,getPtrSelf(),channel,pvRequest);
|
||||
}
|
||||
|
||||
|
||||
EasyChannelPtr EasyChannelFactory::createEasyChannel(
|
||||
EasyPVAPtr const &easyPVA,
|
||||
string const & channelName)
|
||||
{
|
||||
return EasyChannelFactory::createEasyChannel(easyPVA,channelName,"pva");
|
||||
}
|
||||
|
||||
EasyChannelPtr EasyChannelFactory::createEasyChannel(
|
||||
EasyChannelPtr EasyChannel::create(
|
||||
EasyPVAPtr const &easyPVA,
|
||||
string const & channelName,
|
||||
string const & providerName)
|
||||
{
|
||||
EasyChannelPtr channel(new EasyChannelImpl(easyPVA,channelName,providerName));
|
||||
EasyChannelPtr channel(new EasyChannel(easyPVA,channelName,providerName));
|
||||
return channel;
|
||||
}
|
||||
|
||||
|
411
src/easyGet.cpp
411
src/easyGet.cpp
@ -12,9 +12,7 @@
|
||||
|
||||
#include <sstream>
|
||||
#include <pv/event.h>
|
||||
#include <pv/lock.h>
|
||||
#include <pv/easyPVA.h>
|
||||
#include <pv/createRequest.h>
|
||||
|
||||
using std::tr1::static_pointer_cast;
|
||||
using namespace epics::pvData;
|
||||
@ -23,139 +21,31 @@ using namespace std;
|
||||
|
||||
namespace epics { namespace easyPVA {
|
||||
|
||||
|
||||
|
||||
class epicsShareClass EasyGetImpl :
|
||||
public EasyGet,
|
||||
public std::tr1::enable_shared_from_this<EasyGetImpl>
|
||||
class ChannelGetRequesterImpl : public ChannelGetRequester
|
||||
{
|
||||
EasyGet * easyGet;
|
||||
public:
|
||||
EasyGetImpl(
|
||||
EasyPVAPtr const &pva,
|
||||
EasyChannelPtr const & easyChannel,
|
||||
Channel::shared_pointer const & channel,
|
||||
PVStructurePtr const &pvRequest);
|
||||
~EasyGetImpl();
|
||||
// from ChannelGetRequester
|
||||
string getRequesterName();
|
||||
void message(string const & message,MessageType messageType);
|
||||
ChannelGetRequesterImpl(EasyGet * easyGet)
|
||||
: easyGet(easyGet) {}
|
||||
string getRequesterName()
|
||||
{return easyGet->getRequesterName();}
|
||||
void message(string const & message,MessageType messageType)
|
||||
{easyGet->message(message,messageType);}
|
||||
void channelGetConnect(
|
||||
const Status& status,
|
||||
ChannelGet::shared_pointer const & channelGet,
|
||||
StructureConstPtr const & structure);
|
||||
StructureConstPtr const & structure)
|
||||
{easyGet->channelGetConnect(status,channelGet,structure);}
|
||||
void getDone(
|
||||
const Status& status,
|
||||
ChannelGet::shared_pointer const & channelGet,
|
||||
PVStructurePtr const & pvStructure,
|
||||
BitSetPtr const & bitSet);
|
||||
|
||||
// from EasyGet
|
||||
virtual void destroy();
|
||||
virtual void connect();
|
||||
virtual void issueConnect();
|
||||
virtual Status waitConnect();
|
||||
virtual void get();
|
||||
virtual void issueGet();
|
||||
virtual Status waitGet();
|
||||
virtual BitSetPtr getBitSet();
|
||||
// from EasyPVStructure
|
||||
virtual void setMessagePrefix(std::string const & value);
|
||||
virtual void setPVStructure(epics::pvData::PVStructurePtr const & pvStructure);
|
||||
virtual Alarm getAlarm();
|
||||
virtual TimeStamp getTimeStamp();
|
||||
virtual bool hasValue();
|
||||
virtual bool isValueScalar();
|
||||
virtual bool isValueScalarArray();
|
||||
virtual PVFieldPtr getValue();
|
||||
virtual PVScalarPtr getScalarValue();
|
||||
virtual std::tr1::shared_ptr<PVArray> getArrayValue();
|
||||
virtual std::tr1::shared_ptr<PVScalarArray> getScalarArrayValue();
|
||||
virtual bool getBoolean();
|
||||
virtual int8 getByte();
|
||||
virtual int16 getShort();
|
||||
virtual int32 getInt();
|
||||
virtual int64 getLong();
|
||||
virtual uint8 getUByte();
|
||||
virtual uint16 getUShort();
|
||||
virtual uint32 getUInt();
|
||||
virtual uint64 getULong();
|
||||
virtual float getFloat();
|
||||
virtual double getDouble();
|
||||
virtual std::string getString();
|
||||
|
||||
virtual shared_vector<boolean> getBooleanArray();
|
||||
virtual shared_vector<int8> getByteArray();
|
||||
virtual shared_vector<int16> getShortArray();
|
||||
virtual shared_vector<int32> getIntArray();
|
||||
virtual shared_vector<int64> getLongArray();
|
||||
virtual shared_vector<uint8> getUByteArray();
|
||||
virtual shared_vector<uint16> getUShortArray();
|
||||
virtual shared_vector<uint32> getUIntArray();
|
||||
virtual shared_vector<uint64> getULongArray();
|
||||
virtual shared_vector<float> getFloatArray();
|
||||
virtual shared_vector<double> getDoubleArray();
|
||||
virtual shared_vector<std::string> getStringArray();
|
||||
virtual PVStructurePtr getPVStructure();
|
||||
EasyGetPtr getPtrSelf()
|
||||
{
|
||||
return shared_from_this();
|
||||
}
|
||||
private:
|
||||
void checkGetState();
|
||||
enum GetConnectState {connectIdle,connectActive,connected};
|
||||
|
||||
EasyPVA::weak_pointer easyPVA;
|
||||
EasyChannel::weak_pointer easyChannel;
|
||||
Channel::shared_pointer channel;
|
||||
ChannelGetRequester::shared_pointer getRequester;
|
||||
PVStructurePtr pvRequest;
|
||||
Mutex mutex;
|
||||
Event waitForConnect;
|
||||
Event waitForGet;
|
||||
EasyPVStructurePtr easyPVStructure;
|
||||
string messagePrefix;
|
||||
|
||||
bool isDestroyed;
|
||||
Status channelGetConnectStatus;
|
||||
Status channelGetStatus;
|
||||
ChannelGet::shared_pointer channelGet;
|
||||
BitSet::shared_pointer bitSet;
|
||||
|
||||
GetConnectState connectState;
|
||||
|
||||
enum GetState {getIdle,getActive,getComplete};
|
||||
GetState getState;
|
||||
bool getSuccess;
|
||||
BitSetPtr const & bitSet)
|
||||
{easyGet->getDone(status,channelGet,pvStructure,bitSet);}
|
||||
};
|
||||
|
||||
namespace easyGet {
|
||||
class ChannelGetRequesterImpl : public ChannelGetRequester
|
||||
{
|
||||
EasyGetImpl * easyGet;
|
||||
public:
|
||||
ChannelGetRequesterImpl(EasyGetImpl * easyGet)
|
||||
: easyGet(easyGet) {}
|
||||
virtual string getRequesterName()
|
||||
{return easyGet->getRequesterName();}
|
||||
virtual void message(string const & message,MessageType messageType)
|
||||
{easyGet->message(message,messageType);}
|
||||
virtual void channelGetConnect(
|
||||
const Status& status,
|
||||
ChannelGet::shared_pointer const & channelGet,
|
||||
StructureConstPtr const & structure)
|
||||
{easyGet->channelGetConnect(status,channelGet,structure);}
|
||||
virtual void getDone(
|
||||
const Status& status,
|
||||
ChannelGet::shared_pointer const & channelGet,
|
||||
PVStructurePtr const & pvStructure,
|
||||
BitSetPtr const & bitSet)
|
||||
{easyGet->getDone(status,channelGet,pvStructure,bitSet);}
|
||||
};
|
||||
} // namespace easyGet
|
||||
|
||||
using namespace epics::easyPVA::easyGet;
|
||||
|
||||
EasyGetImpl::EasyGetImpl(
|
||||
EasyGet::EasyGet(
|
||||
EasyPVAPtr const &pva,
|
||||
EasyChannelPtr const & easyChannel,
|
||||
Channel::shared_pointer const & channel,
|
||||
@ -164,20 +54,18 @@ EasyGetImpl::EasyGetImpl(
|
||||
easyChannel(easyChannel),
|
||||
channel(channel),
|
||||
pvRequest(pvRequest),
|
||||
easyPVStructure(pva->createEasyPVStructure()),
|
||||
isDestroyed(false),
|
||||
connectState(connectIdle),
|
||||
getState(getIdle)
|
||||
{
|
||||
easyPVStructure->setMessagePrefix("channel " + channel->getChannelName() + " EasyGet");
|
||||
}
|
||||
|
||||
EasyGetImpl::~EasyGetImpl()
|
||||
EasyGet::~EasyGet()
|
||||
{
|
||||
destroy();
|
||||
}
|
||||
|
||||
void EasyGetImpl::checkGetState()
|
||||
void EasyGet::checkGetState()
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
|
||||
if(connectState==connectIdle) connect();
|
||||
@ -185,14 +73,14 @@ void EasyGetImpl::checkGetState()
|
||||
}
|
||||
|
||||
// from ChannelGetRequester
|
||||
string EasyGetImpl::getRequesterName()
|
||||
string EasyGet::getRequesterName()
|
||||
{
|
||||
EasyPVAPtr yyy = easyPVA.lock();
|
||||
if(!yyy) throw std::runtime_error("easyPVA was destroyed");
|
||||
return yyy->getRequesterName();
|
||||
}
|
||||
|
||||
void EasyGetImpl::message(string const & message,MessageType messageType)
|
||||
void EasyGet::message(string const & message,MessageType messageType)
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
|
||||
EasyPVAPtr yyy = easyPVA.lock();
|
||||
@ -200,7 +88,7 @@ void EasyGetImpl::message(string const & message,MessageType messageType)
|
||||
yyy->message(message, messageType);
|
||||
}
|
||||
|
||||
void EasyGetImpl::channelGetConnect(
|
||||
void EasyGet::channelGetConnect(
|
||||
const Status& status,
|
||||
ChannelGet::shared_pointer const & channelGet,
|
||||
StructureConstPtr const & structure)
|
||||
@ -209,35 +97,30 @@ void EasyGetImpl::channelGetConnect(
|
||||
channelGetConnectStatus = status;
|
||||
this->channelGet = channelGet;
|
||||
if(status.isOK()) {
|
||||
connectState = connected;
|
||||
} else {
|
||||
connectState = connectIdle;
|
||||
easyData = EasyGetData::create(structure);
|
||||
easyData->setMessagePrefix(channel->getChannelName());
|
||||
}
|
||||
waitForConnect.signal();
|
||||
|
||||
}
|
||||
|
||||
void EasyGetImpl::getDone(
|
||||
void EasyGet::getDone(
|
||||
const Status& status,
|
||||
ChannelGet::shared_pointer const & channelGet,
|
||||
PVStructurePtr const & pvStructure,
|
||||
BitSetPtr const & bitSet)
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
|
||||
easyPVStructure->setPVStructure(pvStructure);
|
||||
this->bitSet = bitSet;
|
||||
channelGetStatus = status;
|
||||
if(status.isOK()) {
|
||||
getState = getComplete;
|
||||
} else {
|
||||
getState = getIdle;
|
||||
easyData->setData(pvStructure,bitSet);
|
||||
}
|
||||
waitForGet.signal();
|
||||
}
|
||||
|
||||
|
||||
// from EasyGet
|
||||
void EasyGetImpl::destroy()
|
||||
void EasyGet::destroy()
|
||||
{
|
||||
{
|
||||
Lock xx(mutex);
|
||||
@ -248,7 +131,7 @@ void EasyGetImpl::destroy()
|
||||
channelGet.reset();
|
||||
}
|
||||
|
||||
void EasyGetImpl::connect()
|
||||
void EasyGet::connect()
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
|
||||
issueConnect();
|
||||
@ -259,7 +142,7 @@ void EasyGetImpl::connect()
|
||||
throw std::runtime_error(ss.str());
|
||||
}
|
||||
|
||||
void EasyGetImpl::issueConnect()
|
||||
void EasyGet::issueConnect()
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
|
||||
if(connectState!=connectIdle) {
|
||||
@ -272,7 +155,7 @@ void EasyGetImpl::issueConnect()
|
||||
channelGet = channel->createChannelGet(getRequester,pvRequest);
|
||||
}
|
||||
|
||||
Status EasyGetImpl::waitConnect()
|
||||
Status EasyGet::waitConnect()
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
|
||||
if(connectState!=connectActive) {
|
||||
@ -281,11 +164,15 @@ Status EasyGetImpl::waitConnect()
|
||||
throw std::runtime_error(ss.str());
|
||||
}
|
||||
waitForConnect.wait();
|
||||
if(connectState==connected) return Status::Ok;
|
||||
if(channelGetConnectStatus.isOK()){
|
||||
connectState = connected;
|
||||
return Status::Ok;
|
||||
}
|
||||
connectState = connectIdle;
|
||||
return Status(Status::STATUSTYPE_ERROR,channelGetConnectStatus.getMessage());
|
||||
}
|
||||
|
||||
void EasyGetImpl::get()
|
||||
void EasyGet::get()
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
|
||||
issueGet();
|
||||
@ -296,7 +183,7 @@ void EasyGetImpl::get()
|
||||
throw std::runtime_error(ss.str());
|
||||
}
|
||||
|
||||
void EasyGetImpl::issueGet()
|
||||
void EasyGet::issueGet()
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
|
||||
if(connectState==connectIdle) connect();
|
||||
@ -309,7 +196,7 @@ void EasyGetImpl::issueGet()
|
||||
channelGet->get();
|
||||
}
|
||||
|
||||
Status EasyGetImpl::waitGet()
|
||||
Status EasyGet::waitGet()
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
|
||||
if(getState!=getActive){
|
||||
@ -318,243 +205,25 @@ Status EasyGetImpl::waitGet()
|
||||
throw std::runtime_error(ss.str());
|
||||
}
|
||||
waitForGet.wait();
|
||||
if(getState==getComplete) {
|
||||
getState = getIdle;
|
||||
getState = getIdle;
|
||||
if(channelGetStatus.isOK()) {
|
||||
return Status::Ok;
|
||||
}
|
||||
return Status(Status::STATUSTYPE_ERROR,channelGetStatus.getMessage());
|
||||
}
|
||||
|
||||
BitSetPtr EasyGetImpl::getBitSet()
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
|
||||
return bitSet;
|
||||
}
|
||||
|
||||
void EasyGetImpl::setMessagePrefix(string const & value)
|
||||
{
|
||||
messagePrefix = value;
|
||||
if(value.size()>0) messagePrefix += " ";
|
||||
}
|
||||
|
||||
void EasyGetImpl::setPVStructure(epics::pvData::PVStructurePtr const & pvStructure)
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
|
||||
throw std::runtime_error("easyGet does not implement setPVStructure");
|
||||
}
|
||||
|
||||
Alarm EasyGetImpl::getAlarm()
|
||||
EasyGetDataPtr EasyGet::getData()
|
||||
{
|
||||
checkGetState();
|
||||
return easyPVStructure->getAlarm();
|
||||
return easyData;
|
||||
}
|
||||
|
||||
TimeStamp EasyGetImpl::getTimeStamp()
|
||||
{
|
||||
checkGetState();
|
||||
return easyPVStructure->getTimeStamp();
|
||||
}
|
||||
|
||||
bool EasyGetImpl::hasValue()
|
||||
{
|
||||
checkGetState();
|
||||
return easyPVStructure->hasValue();
|
||||
}
|
||||
|
||||
bool EasyGetImpl::isValueScalar()
|
||||
{
|
||||
checkGetState();
|
||||
return easyPVStructure->isValueScalar();
|
||||
}
|
||||
|
||||
bool EasyGetImpl::isValueScalarArray()
|
||||
{
|
||||
checkGetState();
|
||||
return easyPVStructure->isValueScalarArray();
|
||||
}
|
||||
|
||||
PVFieldPtr EasyGetImpl::getValue()
|
||||
{
|
||||
checkGetState();
|
||||
return easyPVStructure->getValue();
|
||||
}
|
||||
|
||||
PVScalarPtr EasyGetImpl::getScalarValue()
|
||||
{
|
||||
checkGetState();
|
||||
return easyPVStructure->getScalarValue();
|
||||
}
|
||||
|
||||
std::tr1::shared_ptr<PVArray> EasyGetImpl::getArrayValue()
|
||||
{
|
||||
checkGetState();
|
||||
return easyPVStructure->getArrayValue();
|
||||
}
|
||||
|
||||
std::tr1::shared_ptr<PVScalarArray> EasyGetImpl::getScalarArrayValue()
|
||||
{
|
||||
checkGetState();
|
||||
return easyPVStructure->getScalarArrayValue();
|
||||
}
|
||||
|
||||
bool EasyGetImpl::getBoolean()
|
||||
{
|
||||
checkGetState();
|
||||
return easyPVStructure->getBoolean();
|
||||
}
|
||||
|
||||
int8 EasyGetImpl::getByte()
|
||||
{
|
||||
checkGetState();
|
||||
return easyPVStructure->getByte();
|
||||
}
|
||||
|
||||
int16 EasyGetImpl::getShort()
|
||||
{
|
||||
checkGetState();
|
||||
return easyPVStructure->getShort();
|
||||
}
|
||||
|
||||
int32 EasyGetImpl::getInt()
|
||||
{
|
||||
checkGetState();
|
||||
return easyPVStructure->getInt();
|
||||
}
|
||||
|
||||
int64 EasyGetImpl::getLong()
|
||||
{
|
||||
checkGetState();
|
||||
return easyPVStructure->getLong();
|
||||
}
|
||||
|
||||
uint8 EasyGetImpl::getUByte()
|
||||
{
|
||||
checkGetState();
|
||||
return easyPVStructure->getUByte();
|
||||
}
|
||||
|
||||
uint16 EasyGetImpl::getUShort()
|
||||
{
|
||||
checkGetState();
|
||||
return easyPVStructure->getUShort();
|
||||
}
|
||||
|
||||
uint32 EasyGetImpl::getUInt()
|
||||
{
|
||||
checkGetState();
|
||||
return easyPVStructure->getUInt();
|
||||
}
|
||||
|
||||
uint64 EasyGetImpl::getULong()
|
||||
{
|
||||
checkGetState();
|
||||
return easyPVStructure->getULong();
|
||||
}
|
||||
|
||||
float EasyGetImpl::getFloat()
|
||||
{
|
||||
checkGetState();
|
||||
return easyPVStructure->getFloat();
|
||||
}
|
||||
|
||||
double EasyGetImpl::getDouble()
|
||||
{
|
||||
checkGetState();
|
||||
return easyPVStructure->getDouble();
|
||||
}
|
||||
|
||||
std::string EasyGetImpl::getString()
|
||||
{
|
||||
checkGetState();
|
||||
return easyPVStructure->getString();
|
||||
}
|
||||
|
||||
|
||||
shared_vector<boolean> EasyGetImpl::getBooleanArray()
|
||||
{
|
||||
checkGetState();
|
||||
return easyPVStructure->getBooleanArray();
|
||||
}
|
||||
|
||||
shared_vector<int8> EasyGetImpl::getByteArray()
|
||||
{
|
||||
checkGetState();
|
||||
return easyPVStructure->getByteArray();
|
||||
}
|
||||
|
||||
shared_vector<int16> EasyGetImpl::getShortArray()
|
||||
{
|
||||
checkGetState();
|
||||
return easyPVStructure->getShortArray();
|
||||
}
|
||||
|
||||
shared_vector<int32> EasyGetImpl::getIntArray()
|
||||
{
|
||||
checkGetState();
|
||||
return easyPVStructure->getIntArray();
|
||||
}
|
||||
|
||||
shared_vector<int64> EasyGetImpl::getLongArray()
|
||||
{
|
||||
checkGetState();
|
||||
return easyPVStructure->getLongArray();
|
||||
}
|
||||
|
||||
shared_vector<uint8> EasyGetImpl::getUByteArray()
|
||||
{
|
||||
checkGetState();
|
||||
return easyPVStructure->getUByteArray();
|
||||
}
|
||||
|
||||
shared_vector<uint16> EasyGetImpl::getUShortArray()
|
||||
{
|
||||
checkGetState();
|
||||
return easyPVStructure->getUShortArray();
|
||||
}
|
||||
|
||||
shared_vector<uint32> EasyGetImpl::getUIntArray()
|
||||
{
|
||||
checkGetState();
|
||||
return easyPVStructure->getUIntArray();
|
||||
}
|
||||
|
||||
shared_vector<uint64> EasyGetImpl::getULongArray()
|
||||
{
|
||||
checkGetState();
|
||||
return easyPVStructure->getULongArray();
|
||||
}
|
||||
|
||||
shared_vector<float> EasyGetImpl::getFloatArray()
|
||||
{
|
||||
checkGetState();
|
||||
return easyPVStructure->getFloatArray();
|
||||
}
|
||||
|
||||
shared_vector<double> EasyGetImpl::getDoubleArray()
|
||||
{
|
||||
checkGetState();
|
||||
return easyPVStructure->getDoubleArray();
|
||||
}
|
||||
|
||||
shared_vector<std::string> EasyGetImpl::getStringArray()
|
||||
{
|
||||
checkGetState();
|
||||
return easyPVStructure->getStringArray();
|
||||
}
|
||||
|
||||
PVStructurePtr EasyGetImpl::getPVStructure()
|
||||
{
|
||||
checkGetState();
|
||||
return easyPVStructure->getPVStructure();
|
||||
}
|
||||
|
||||
EasyGetPtr EasyGetFactory::createEasyGet(
|
||||
EasyGetPtr EasyGet::create(
|
||||
EasyPVAPtr const &pva,
|
||||
EasyChannelPtr const & easyChannel,
|
||||
Channel::shared_pointer const & channel,
|
||||
PVStructurePtr const &pvRequest)
|
||||
{
|
||||
EasyGetPtr epv(new EasyGetImpl(pva,easyChannel,channel,pvRequest));
|
||||
EasyGetPtr epv(new EasyGet(pva,easyChannel,channel,pvRequest));
|
||||
return epv;
|
||||
}
|
||||
|
||||
|
200
src/easyGetData.cpp
Normal file
200
src/easyGetData.cpp
Normal file
@ -0,0 +1,200 @@
|
||||
/* easyGetData.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/easyPVA.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 easyPVA {
|
||||
|
||||
|
||||
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");
|
||||
|
||||
EasyGetDataPtr EasyGetData::create(StructureConstPtr const & structure)
|
||||
{
|
||||
EasyGetDataPtr epv(new EasyGetData(structure));
|
||||
return epv;
|
||||
}
|
||||
|
||||
EasyGetData::EasyGetData(StructureConstPtr const & structure)
|
||||
: structure(structure)
|
||||
{}
|
||||
|
||||
void EasyGetData::checkValue()
|
||||
{
|
||||
if(pvValue) return;
|
||||
throw std::runtime_error(messagePrefix + noValue);
|
||||
}
|
||||
|
||||
void EasyGetData::setMessagePrefix(std::string const & value)
|
||||
{
|
||||
messagePrefix = value;
|
||||
}
|
||||
|
||||
StructureConstPtr EasyGetData::getStructure()
|
||||
{return structure;}
|
||||
|
||||
PVStructurePtr EasyGetData::getPVStructure()
|
||||
{
|
||||
if(pvStructure) return pvStructure;
|
||||
throw std::runtime_error(messagePrefix + noStructure);
|
||||
}
|
||||
|
||||
BitSetPtr EasyGetData::getBitSet()
|
||||
{
|
||||
if(bitSet)return bitSet;
|
||||
throw std::runtime_error(messagePrefix + noStructure);
|
||||
}
|
||||
|
||||
std::ostream & EasyGetData::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 EasyGetData::setData(
|
||||
PVStructurePtr const & pvStructureFrom,
|
||||
BitSetPtr const & bitSetFrom)
|
||||
{
|
||||
pvStructure = pvStructureFrom;
|
||||
bitSet = bitSetFrom;
|
||||
pvValue = pvStructure->getSubField("value");
|
||||
}
|
||||
|
||||
bool EasyGetData::hasValue()
|
||||
{
|
||||
if(!pvValue) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool EasyGetData::isValueScalar()
|
||||
{
|
||||
if(!pvValue) return false;
|
||||
if(pvValue->getField()->getType()==scalar) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool EasyGetData::isValueScalarArray()
|
||||
{
|
||||
if(!pvValue) return false;
|
||||
if(pvValue->getField()->getType()==scalarArray) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
PVFieldPtr EasyGetData::getValue()
|
||||
{
|
||||
checkValue();
|
||||
return pvValue;
|
||||
}
|
||||
|
||||
PVScalarPtr EasyGetData::getScalarValue()
|
||||
{
|
||||
checkValue();
|
||||
PVScalarPtr pv = pvStructure->getSubField<PVScalar>("value");
|
||||
if(!pv) {
|
||||
throw std::runtime_error(messagePrefix + noScalar);
|
||||
}
|
||||
return pv;
|
||||
}
|
||||
|
||||
PVArrayPtr EasyGetData::getArrayValue()
|
||||
{
|
||||
checkValue();
|
||||
PVArrayPtr pv = pvStructure->getSubField<PVArray>("value");
|
||||
if(!pv) {
|
||||
throw std::runtime_error(messagePrefix + noArray);
|
||||
}
|
||||
return pv;
|
||||
}
|
||||
|
||||
PVScalarArrayPtr EasyGetData::getScalarArrayValue()
|
||||
{
|
||||
checkValue();
|
||||
PVScalarArrayPtr pv = pvStructure->getSubField<PVScalarArray>("value");
|
||||
if(!pv) {
|
||||
throw std::runtime_error(messagePrefix + noScalarArray);
|
||||
}
|
||||
return pv;
|
||||
}
|
||||
|
||||
double EasyGetData::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 EasyGetData::getString()
|
||||
{
|
||||
PVScalarPtr pvScalar = getScalarValue();
|
||||
return convert->toString(pvScalar);
|
||||
}
|
||||
|
||||
shared_vector<const double> EasyGetData::getDoubleArray()
|
||||
{
|
||||
checkValue();
|
||||
PVDoubleArrayPtr pv = pvStructure->getSubField<PVDoubleArray>("value");
|
||||
if(!pv) {
|
||||
throw std::runtime_error(messagePrefix + notDoubleArray);
|
||||
}
|
||||
return pv->view();
|
||||
}
|
||||
|
||||
shared_vector<const string> EasyGetData::getStringArray()
|
||||
{
|
||||
checkValue();
|
||||
PVStringArrayPtr pv = pvStructure->getSubField<PVStringArray>("value");
|
||||
if(!pv) {
|
||||
throw std::runtime_error(messagePrefix + notStringArray);
|
||||
}
|
||||
return pv->view();
|
||||
|
||||
}
|
||||
|
||||
}}
|
250
src/easyMonitor.cpp
Normal file
250
src/easyMonitor.cpp
Normal file
@ -0,0 +1,250 @@
|
||||
/* easyMonitor.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/easyPVA.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 easyPVA {
|
||||
|
||||
|
||||
class ChannelMonitorRequester : public MonitorRequester
|
||||
{
|
||||
EasyMonitor * easyMonitor;
|
||||
public:
|
||||
ChannelMonitorRequester(EasyMonitor * easyMonitor)
|
||||
: easyMonitor(easyMonitor) {}
|
||||
string getRequesterName()
|
||||
{return easyMonitor->getRequesterName();}
|
||||
void message(string const & message,MessageType messageType)
|
||||
{easyMonitor->message(message,messageType);}
|
||||
void monitorConnect(
|
||||
const Status& status,
|
||||
Monitor::shared_pointer const & monitor,
|
||||
StructureConstPtr const & structure)
|
||||
{easyMonitor->monitorConnect(status,monitor,structure);}
|
||||
void monitorEvent(MonitorPtr const & monitor)
|
||||
{
|
||||
easyMonitor->monitorEvent(monitor);
|
||||
}
|
||||
void unlisten(MonitorPtr const & monitor)
|
||||
{easyMonitor->unlisten();}
|
||||
};
|
||||
|
||||
EasyMonitor::EasyMonitor(
|
||||
EasyPVAPtr const &pva,
|
||||
EasyChannelPtr const & easyChannel,
|
||||
Channel::shared_pointer const & channel,
|
||||
PVStructurePtr const &pvRequest)
|
||||
: easyPVA(pva),
|
||||
easyChannel(easyChannel),
|
||||
channel(channel),
|
||||
pvRequest(pvRequest),
|
||||
isDestroyed(false),
|
||||
connectState(connectIdle),
|
||||
userPoll(false),
|
||||
userWait(false)
|
||||
{
|
||||
}
|
||||
|
||||
EasyMonitor::~EasyMonitor()
|
||||
{
|
||||
destroy();
|
||||
}
|
||||
|
||||
void EasyMonitor::checkMonitorState()
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyMonitor was destroyed");
|
||||
if(connectState==connectIdle) connect();
|
||||
if(connectState==connected) start();
|
||||
}
|
||||
|
||||
// from MonitorRequester
|
||||
string EasyMonitor::getRequesterName()
|
||||
{
|
||||
EasyPVAPtr yyy = easyPVA.lock();
|
||||
if(!yyy) throw std::runtime_error("easyPVA was destroyed");
|
||||
return yyy->getRequesterName();
|
||||
}
|
||||
|
||||
void EasyMonitor::message(string const & message,MessageType messageType)
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyMonitor was destroyed");
|
||||
EasyPVAPtr yyy = easyPVA.lock();
|
||||
if(!yyy) throw std::runtime_error("easyPVA was destroyed");
|
||||
yyy->message(message, messageType);
|
||||
}
|
||||
|
||||
void EasyMonitor::monitorConnect(
|
||||
const Status& status,
|
||||
Monitor::shared_pointer const & monitor,
|
||||
StructureConstPtr const & structure)
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyMonitor was destroyed");
|
||||
connectStatus = status;
|
||||
this->monitor = monitor;
|
||||
if(status.isOK()) {
|
||||
easyData = EasyMonitorData::create(structure);
|
||||
easyData->setMessagePrefix(channel->getChannelName());
|
||||
}
|
||||
waitForConnect.signal();
|
||||
|
||||
}
|
||||
|
||||
void EasyMonitor::monitorEvent(MonitorPtr const & monitor)
|
||||
{
|
||||
EasyMonitorRequesterPtr req = easyMonitorRequester.lock();
|
||||
if(req) req->event(getPtrSelf());
|
||||
if(userWait) waitForEvent.signal();
|
||||
}
|
||||
|
||||
void EasyMonitor::unlisten()
|
||||
{
|
||||
destroy();
|
||||
}
|
||||
|
||||
// from EasyMonitor
|
||||
void EasyMonitor::destroy()
|
||||
{
|
||||
{
|
||||
Lock xx(mutex);
|
||||
if(isDestroyed) return;
|
||||
isDestroyed = true;
|
||||
}
|
||||
if(monitor) monitor->destroy();
|
||||
monitor.reset();
|
||||
}
|
||||
|
||||
void EasyMonitor::connect()
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyMonitor was destroyed");
|
||||
issueConnect();
|
||||
Status status = waitConnect();
|
||||
if(status.isOK()) return;
|
||||
stringstream ss;
|
||||
ss << "channel " << channel->getChannelName() << " EasyMonitor::connect " << status.getMessage();
|
||||
throw std::runtime_error(ss.str());
|
||||
}
|
||||
|
||||
void EasyMonitor::issueConnect()
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyMonitor was destroyed");
|
||||
if(connectState!=connectIdle) {
|
||||
stringstream ss;
|
||||
ss << "channel " << channel->getChannelName() << " easyMonitor already connected ";
|
||||
throw std::runtime_error(ss.str());
|
||||
}
|
||||
monitorRequester = ChannelMonitorRequester::shared_pointer(new ChannelMonitorRequester(this));
|
||||
connectState = connectActive;
|
||||
monitor = channel->createMonitor(monitorRequester,pvRequest);
|
||||
}
|
||||
|
||||
Status EasyMonitor::waitConnect()
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyMonitor was destroyed");
|
||||
if(connectState!=connectActive) {
|
||||
stringstream ss;
|
||||
ss << "channel " << channel->getChannelName() << " easyMonitor 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 EasyMonitor::setRequester(EasyMonitorRequesterPtr const & easyMonitorrRequester)
|
||||
{
|
||||
this->easyMonitorRequester = easyMonitorrRequester;
|
||||
}
|
||||
|
||||
void EasyMonitor::start()
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyMonitor was destroyed");
|
||||
if(connectState==monitorStarted) return;
|
||||
if(connectState==connectIdle) connect();
|
||||
if(connectState!=connected) throw std::runtime_error("EasyMonitor::start illegal state");
|
||||
connectState = monitorStarted;
|
||||
monitor->start();
|
||||
}
|
||||
|
||||
|
||||
void EasyMonitor::stop()
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyMonitor was destroyed");
|
||||
if(connectState!=monitorStarted) return;
|
||||
connectState = connected;
|
||||
monitor->stop();
|
||||
}
|
||||
|
||||
bool EasyMonitor::poll()
|
||||
{
|
||||
checkMonitorState();
|
||||
if(connectState!=monitorStarted) throw std::runtime_error("EasyMonitor::poll illegal state");
|
||||
if(userPoll) throw std::runtime_error("EasyMonitor::poll did not release last");
|
||||
monitorElement = monitor->poll();
|
||||
if(!monitorElement) return false;
|
||||
userPoll = true;
|
||||
easyData->setData(monitorElement);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool EasyMonitor::waitEvent(double secondsToWait)
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyMonitor was destroyed");
|
||||
if(connectState!=monitorStarted) throw std::runtime_error("EasyMonitor::poll illegal state");
|
||||
if(poll()) return true;
|
||||
userWait = true;
|
||||
if(secondsToWait==0.0) {
|
||||
waitForEvent.wait();
|
||||
} else {
|
||||
waitForEvent.wait(secondsToWait);
|
||||
}
|
||||
userWait = false;
|
||||
return poll();
|
||||
}
|
||||
|
||||
void EasyMonitor::releaseEvent()
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyMonitor was destroyed");
|
||||
if(connectState!=monitorStarted) throw std::runtime_error("EasyMonitor::poll illegal state");
|
||||
if(!userPoll) throw std::runtime_error("EasyMonitor::releaseEvent did not call poll");
|
||||
userPoll = false;
|
||||
monitor->release(monitorElement);
|
||||
}
|
||||
|
||||
EasyMonitorDataPtr EasyMonitor::getData()
|
||||
{
|
||||
checkMonitorState();
|
||||
return easyData;
|
||||
}
|
||||
|
||||
EasyMonitorPtr EasyMonitor::create(
|
||||
EasyPVAPtr const &pva,
|
||||
EasyChannelPtr const & easyChannel,
|
||||
Channel::shared_pointer const & channel,
|
||||
PVStructurePtr const &pvRequest)
|
||||
{
|
||||
EasyMonitorPtr epv(new EasyMonitor(pva,easyChannel,channel,pvRequest));
|
||||
return epv;
|
||||
}
|
||||
|
||||
}}
|
226
src/easyMonitorData.cpp
Normal file
226
src/easyMonitorData.cpp
Normal file
@ -0,0 +1,226 @@
|
||||
/* easyMonitorData.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/easyPVA.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 easyPVA {
|
||||
|
||||
|
||||
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");
|
||||
|
||||
EasyMonitorDataPtr EasyMonitorData::create(StructureConstPtr const & structure)
|
||||
{
|
||||
EasyMonitorDataPtr epv(new EasyMonitorData(structure));
|
||||
return epv;
|
||||
}
|
||||
|
||||
EasyMonitorData::EasyMonitorData(StructureConstPtr const & structure)
|
||||
: structure(structure)
|
||||
{}
|
||||
|
||||
|
||||
void EasyMonitorData::checkValue()
|
||||
{
|
||||
if(pvValue) return;
|
||||
throw std::runtime_error(messagePrefix + noValue);
|
||||
}
|
||||
|
||||
void EasyMonitorData::setMessagePrefix(std::string const & value)
|
||||
{
|
||||
messagePrefix = value;
|
||||
}
|
||||
|
||||
StructureConstPtr EasyMonitorData::getStructure()
|
||||
{return structure;}
|
||||
|
||||
PVStructurePtr EasyMonitorData::getPVStructure()
|
||||
{
|
||||
if(pvStructure) return pvStructure;
|
||||
throw std::runtime_error(messagePrefix + noStructure);
|
||||
}
|
||||
|
||||
BitSetPtr EasyMonitorData::getChangedBitSet()
|
||||
{
|
||||
if(!changedBitSet) throw std::runtime_error(messagePrefix + noStructure);
|
||||
return changedBitSet;
|
||||
}
|
||||
|
||||
BitSetPtr EasyMonitorData::getOverrunBitSet()
|
||||
{
|
||||
if(!overrunBitSet) throw std::runtime_error(messagePrefix + noStructure);
|
||||
return overrunBitSet;
|
||||
}
|
||||
|
||||
std::ostream & EasyMonitorData::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 & EasyMonitorData::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 EasyMonitorData::setData(MonitorElementPtr const & monitorElement)
|
||||
{
|
||||
pvStructure = monitorElement->pvStructurePtr;
|
||||
changedBitSet = monitorElement->changedBitSet;
|
||||
overrunBitSet = monitorElement->overrunBitSet;
|
||||
pvValue = pvStructure->getSubField("value");
|
||||
}
|
||||
|
||||
bool EasyMonitorData::hasValue()
|
||||
{
|
||||
if(!pvValue) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool EasyMonitorData::isValueScalar()
|
||||
{
|
||||
if(!pvValue) return false;
|
||||
if(pvValue->getField()->getType()==scalar) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool EasyMonitorData::isValueScalarArray()
|
||||
{
|
||||
if(!pvValue) return false;
|
||||
if(pvValue->getField()->getType()==scalarArray) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
PVFieldPtr EasyMonitorData::getValue()
|
||||
{
|
||||
checkValue();
|
||||
return pvValue;
|
||||
}
|
||||
|
||||
PVScalarPtr EasyMonitorData::getScalarValue()
|
||||
{
|
||||
checkValue();
|
||||
PVScalarPtr pv = pvStructure->getSubField<PVScalar>("value");
|
||||
if(!pv) {
|
||||
throw std::runtime_error(messagePrefix + noScalar);
|
||||
}
|
||||
return pv;
|
||||
}
|
||||
|
||||
PVArrayPtr EasyMonitorData::getArrayValue()
|
||||
{
|
||||
checkValue();
|
||||
PVArrayPtr pv = pvStructure->getSubField<PVArray>("value");
|
||||
if(!pv) {
|
||||
throw std::runtime_error(messagePrefix + noArray);
|
||||
}
|
||||
return pv;
|
||||
}
|
||||
|
||||
PVScalarArrayPtr EasyMonitorData::getScalarArrayValue()
|
||||
{
|
||||
checkValue();
|
||||
PVScalarArrayPtr pv = pvStructure->getSubField<PVScalarArray>("value");
|
||||
if(!pv) {
|
||||
throw std::runtime_error(messagePrefix + noScalarArray);
|
||||
}
|
||||
return pv;
|
||||
}
|
||||
|
||||
double EasyMonitorData::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 EasyMonitorData::getString()
|
||||
{
|
||||
PVScalarPtr pvScalar = getScalarValue();
|
||||
return convert->toString(pvScalar);
|
||||
}
|
||||
|
||||
shared_vector<const double> EasyMonitorData::getDoubleArray()
|
||||
{
|
||||
checkValue();
|
||||
PVDoubleArrayPtr pv = pvStructure->getSubField<PVDoubleArray>("value");
|
||||
if(!pv) {
|
||||
throw std::runtime_error(messagePrefix + notDoubleArray);
|
||||
}
|
||||
return pv->view();
|
||||
}
|
||||
|
||||
shared_vector<const string> EasyMonitorData::getStringArray()
|
||||
{
|
||||
checkValue();
|
||||
PVStringArrayPtr pv = pvStructure->getSubField<PVStringArray>("value");
|
||||
if(!pv) {
|
||||
throw std::runtime_error(messagePrefix + notStringArray);
|
||||
}
|
||||
return pv->view();
|
||||
|
||||
}
|
||||
|
||||
}}
|
@ -98,7 +98,6 @@ void EasyChannelCache::removeChannel(string const & channelName)
|
||||
|
||||
using namespace epics::easyPVA::easyPVAPvt;
|
||||
|
||||
|
||||
EasyPVAPtr EasyPVA::create()
|
||||
{
|
||||
EasyPVAPtr xx(new EasyPVA());
|
||||
@ -152,11 +151,6 @@ void EasyPVA::message(
|
||||
cout << getMessageTypeName(messageType) << " " << message << endl;
|
||||
}
|
||||
|
||||
EasyPVStructurePtr EasyPVA::createEasyPVStructure()
|
||||
{
|
||||
return EasyPVStructureFactory::createEasyPVStructure();
|
||||
}
|
||||
|
||||
EasyChannelPtr EasyPVA::channel(
|
||||
std::string const & channelName,
|
||||
std::string const & providerName,
|
||||
@ -172,12 +166,12 @@ EasyChannelPtr EasyPVA::channel(
|
||||
|
||||
EasyChannelPtr EasyPVA::createChannel(string const & channelName)
|
||||
{
|
||||
return EasyChannelFactory::createEasyChannel(getPtrSelf(),channelName);
|
||||
return EasyChannel::create(getPtrSelf(),channelName);
|
||||
}
|
||||
|
||||
EasyChannelPtr EasyPVA::createChannel(string const & channelName, string const & providerName)
|
||||
{
|
||||
return EasyChannelFactory::createEasyChannel(getPtrSelf(),channelName,providerName);
|
||||
return EasyChannel::create(getPtrSelf(),channelName,providerName);
|
||||
}
|
||||
|
||||
}}
|
||||
|
1391
src/easyPVA.h
1391
src/easyPVA.h
File diff suppressed because it is too large
Load Diff
@ -1,597 +0,0 @@
|
||||
/* easyPVStructure.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/easyPVA.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 easyPVA {
|
||||
|
||||
typedef std::tr1::shared_ptr<epics::pvData::PVArray> PVArrayPtr;
|
||||
static StructureConstPtr nullStructure;
|
||||
static PVStructurePtr nullPVStructure;
|
||||
static ConvertPtr convert = getConvert();
|
||||
static Status statusOK(Status::Ok);
|
||||
static Status statusDestroyed(Status::STATUSTYPE_ERROR,"was destroyed");
|
||||
static Status statusNoPVStructure(Status::STATUSTYPE_ERROR,"setPVStructure not called");
|
||||
static Status statusNoValue(Status::STATUSTYPE_ERROR,"no value field");
|
||||
static Status statusNoScalar(Status::STATUSTYPE_ERROR,"value is not a scalar");
|
||||
static Status statusMismatchedScalar(Status::STATUSTYPE_ERROR,"value is not a compatible scalar");
|
||||
static Status statusNoArray(Status::STATUSTYPE_ERROR,"value is not a array");
|
||||
static Status statusNoScalarArray(Status::STATUSTYPE_ERROR,"value is not a scalarArray");
|
||||
static Status statusMismatchedScalarArray(Status::STATUSTYPE_ERROR,"value is not a compatible scalarArray");
|
||||
static Status statusNoAlarm(Status::STATUSTYPE_ERROR,"no alarm field");
|
||||
static Status statusNoTimeStamp(Status::STATUSTYPE_ERROR,"no timeStamp field");
|
||||
|
||||
class epicsShareClass EasyPVStructureImpl :
|
||||
public EasyPVStructure,
|
||||
public std::tr1::enable_shared_from_this<EasyPVStructureImpl>
|
||||
{
|
||||
public:
|
||||
EasyPVStructureImpl();
|
||||
~EasyPVStructureImpl(){}
|
||||
virtual void setMessagePrefix(std::string const & value);
|
||||
virtual void setPVStructure(PVStructurePtr const & pvStructure);
|
||||
virtual PVStructurePtr getPVStructure();
|
||||
virtual Alarm getAlarm();
|
||||
virtual TimeStamp getTimeStamp();
|
||||
virtual bool hasValue();
|
||||
virtual bool isValueScalar();
|
||||
virtual bool isValueScalarArray() ;
|
||||
virtual PVFieldPtr getValue();
|
||||
virtual PVScalarPtr getScalarValue();
|
||||
virtual std::tr1::shared_ptr<PVArray> getArrayValue();
|
||||
virtual std::tr1::shared_ptr<PVScalarArray> getScalarArrayValue();
|
||||
virtual bool getBoolean();
|
||||
virtual int8 getByte();
|
||||
virtual int16 getShort();
|
||||
virtual int32 getInt();
|
||||
virtual int64 getLong();
|
||||
virtual uint8 getUByte();
|
||||
virtual uint16 getUShort();
|
||||
virtual uint32 getUInt();
|
||||
virtual uint64 getULong();
|
||||
virtual float getFloat();
|
||||
virtual double getDouble();
|
||||
virtual std::string getString();
|
||||
|
||||
virtual shared_vector<boolean> getBooleanArray();
|
||||
virtual shared_vector<int8> getByteArray();
|
||||
virtual shared_vector<int16> getShortArray();
|
||||
virtual shared_vector<int32> getIntArray();
|
||||
virtual shared_vector<int64> getLongArray();
|
||||
virtual shared_vector<uint8> getUByteArray();
|
||||
virtual shared_vector<uint16> getUShortArray();
|
||||
virtual shared_vector<uint32> getUIntArray();
|
||||
virtual shared_vector<uint64> getULongArray();
|
||||
virtual shared_vector<float> getFloatArray();
|
||||
virtual shared_vector<double> getDoubleArray();
|
||||
virtual shared_vector<string> getStringArray();
|
||||
|
||||
EasyPVStructurePtr getPtrSelf()
|
||||
{
|
||||
return shared_from_this();
|
||||
}
|
||||
private:
|
||||
void checkPVStructure();
|
||||
void checkValue();
|
||||
bool checkOverflow(ScalarType source,ScalarType dest);
|
||||
PVScalarPtr checkScalar(ScalarType scalarType);
|
||||
PVScalarArrayPtr checkScalarArray(ScalarType elementType);
|
||||
|
||||
string messagePrefix;
|
||||
PVStructurePtr pvStructure;
|
||||
PVFieldPtr pvValue;
|
||||
PVAlarm pvAlarm;
|
||||
Alarm alarm;
|
||||
PVTimeStamp pvTimeStamp;
|
||||
TimeStamp timeStamp;
|
||||
};
|
||||
|
||||
EasyPVStructureImpl::EasyPVStructureImpl()
|
||||
{}
|
||||
|
||||
EasyPVStructurePtr EasyPVStructureFactory::createEasyPVStructure()
|
||||
{
|
||||
EasyPVStructurePtr epv(new EasyPVStructureImpl());
|
||||
return epv;
|
||||
}
|
||||
|
||||
void EasyPVStructureImpl::checkPVStructure()
|
||||
{
|
||||
if(pvStructure) return;
|
||||
throw std::runtime_error(messagePrefix + statusNoPVStructure.getMessage());
|
||||
|
||||
}
|
||||
|
||||
void EasyPVStructureImpl::checkValue()
|
||||
{
|
||||
if(pvValue) return;
|
||||
throw std::runtime_error(messagePrefix + statusNoValue.getMessage());
|
||||
}
|
||||
|
||||
bool EasyPVStructureImpl::checkOverflow(ScalarType source,ScalarType dest)
|
||||
{
|
||||
if(dest==pvFloat||dest==pvDouble) return true;
|
||||
if(!ScalarTypeFunc::isInteger(source) && !ScalarTypeFunc::isUInteger(source)) return false;
|
||||
if(ScalarTypeFunc::isUInteger(dest)) {
|
||||
if(ScalarTypeFunc::isUInteger(source)) {
|
||||
if(dest>=source) return true;
|
||||
return false;
|
||||
}
|
||||
if(ScalarTypeFunc::isInteger(source)) {
|
||||
if(dest>=(source+4)) return true;
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
if(ScalarTypeFunc::isInteger(dest)) {
|
||||
if(ScalarTypeFunc::isUInteger(source)) {
|
||||
if(dest>(source-4)) return true;
|
||||
return false;
|
||||
}
|
||||
if(ScalarTypeFunc::isInteger(source)) {
|
||||
if(dest>=source) return true;
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
PVScalarPtr EasyPVStructureImpl::checkScalar(ScalarType scalarType)
|
||||
{
|
||||
checkPVStructure();
|
||||
checkValue();
|
||||
PVScalarPtr pv = pvStructure->getSubField<PVScalar>("value");
|
||||
if(!pv) {
|
||||
throw std::runtime_error(messagePrefix + statusNoScalar.getMessage());
|
||||
}
|
||||
ScalarType type = pv->getScalar()->getScalarType();
|
||||
if((scalarType==pvBoolean && type==pvBoolean)
|
||||
|| (scalarType==pvString && type==pvString)) return pv;
|
||||
if((ScalarTypeFunc::isNumeric(type) && ScalarTypeFunc::isNumeric(scalarType))
|
||||
&& checkOverflow(type,scalarType)) return pv;
|
||||
stringstream ss;
|
||||
ss << messagePrefix << statusMismatchedScalar.getMessage();
|
||||
ss << " source " << type << " dest " << scalarType;
|
||||
throw std::runtime_error(ss.str());
|
||||
}
|
||||
|
||||
PVScalarArrayPtr EasyPVStructureImpl::checkScalarArray(ScalarType elementType)
|
||||
{
|
||||
checkPVStructure();
|
||||
checkValue();
|
||||
PVScalarArrayPtr pv = pvStructure->getSubField<PVScalarArray>("value");
|
||||
if(!pv) {
|
||||
throw std::runtime_error(messagePrefix + statusNoScalarArray.getMessage());
|
||||
}
|
||||
ScalarType type = pv->getScalarArray()->getElementType();
|
||||
if((elementType==pvBoolean && type==pvBoolean)
|
||||
|| (elementType==pvBoolean && type==pvBoolean)) return pv;
|
||||
if((ScalarTypeFunc::isNumeric(type) && ScalarTypeFunc::isNumeric(elementType))
|
||||
&& checkOverflow(type,elementType)) return pv;
|
||||
throw std::runtime_error(messagePrefix + statusMismatchedScalarArray.getMessage());
|
||||
}
|
||||
|
||||
void EasyPVStructureImpl::setMessagePrefix(string const & value)
|
||||
{
|
||||
messagePrefix = value;
|
||||
if(value.size()>0) messagePrefix += " ";
|
||||
}
|
||||
|
||||
void EasyPVStructureImpl::setPVStructure(PVStructurePtr const & pvStructure)
|
||||
{
|
||||
this->pvStructure = pvStructure;
|
||||
pvValue = pvStructure->getSubField("value");
|
||||
}
|
||||
|
||||
PVStructurePtr EasyPVStructureImpl::getPVStructure()
|
||||
{
|
||||
checkPVStructure();
|
||||
return pvStructure;
|
||||
}
|
||||
|
||||
PVFieldPtr EasyPVStructureImpl::getValue()
|
||||
{
|
||||
checkValue();
|
||||
return pvValue;
|
||||
}
|
||||
|
||||
PVScalarPtr EasyPVStructureImpl::getScalarValue()
|
||||
{
|
||||
checkValue();
|
||||
PVScalarPtr pv = pvStructure->getSubField<PVScalar>("value");
|
||||
if(!pv) {
|
||||
throw std::runtime_error(messagePrefix + statusNoScalar.getMessage());
|
||||
}
|
||||
return pv;
|
||||
}
|
||||
|
||||
PVArrayPtr EasyPVStructureImpl::getArrayValue()
|
||||
{
|
||||
checkValue();
|
||||
PVArrayPtr pv = pvStructure->getSubField<PVArray>("value");
|
||||
if(!pv) {
|
||||
throw std::runtime_error(messagePrefix + statusNoArray.getMessage());
|
||||
}
|
||||
return pv;
|
||||
}
|
||||
|
||||
PVScalarArrayPtr EasyPVStructureImpl::getScalarArrayValue()
|
||||
{
|
||||
checkValue();
|
||||
PVScalarArrayPtr pv = pvStructure->getSubField<PVScalarArray>("value");
|
||||
if(!pv) {
|
||||
throw std::runtime_error(messagePrefix + statusNoScalarArray.getMessage());
|
||||
}
|
||||
return pv;
|
||||
}
|
||||
|
||||
Alarm EasyPVStructureImpl::getAlarm()
|
||||
{
|
||||
Alarm alarm;
|
||||
alarm.setSeverity(undefinedAlarm);
|
||||
alarm.setStatus(undefinedStatus);
|
||||
alarm.setMessage("no alarm field");
|
||||
if(!pvStructure) return alarm;
|
||||
PVStructurePtr xxx = pvStructure->getSubField<PVStructure>("alarm");
|
||||
if(xxx) {
|
||||
pvAlarm.attach(xxx);
|
||||
if(pvAlarm.isAttached()) {
|
||||
pvAlarm.get(alarm);
|
||||
pvAlarm.detach();
|
||||
}
|
||||
}
|
||||
return alarm;;
|
||||
}
|
||||
|
||||
TimeStamp EasyPVStructureImpl::getTimeStamp()
|
||||
{
|
||||
TimeStamp timeStamp;
|
||||
if(!pvStructure) return timeStamp;
|
||||
PVStructurePtr xxx = pvStructure->getSubField<PVStructure>("timeStamp");
|
||||
if(xxx) {
|
||||
pvTimeStamp.attach(xxx);
|
||||
if(pvTimeStamp.isAttached()) {
|
||||
pvTimeStamp.get(timeStamp);
|
||||
pvTimeStamp.detach();
|
||||
}
|
||||
}
|
||||
return timeStamp;;
|
||||
}
|
||||
|
||||
bool EasyPVStructureImpl::hasValue()
|
||||
{
|
||||
if(!pvValue) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool EasyPVStructureImpl::isValueScalar()
|
||||
{
|
||||
if(!pvValue) return false;
|
||||
if(pvValue->getField()->getType()==scalar) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool EasyPVStructureImpl::isValueScalarArray()
|
||||
{
|
||||
if(!pvValue) return false;
|
||||
if(pvValue->getField()->getType()==scalarArray) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool EasyPVStructureImpl::getBoolean()
|
||||
{
|
||||
PVScalarPtr pvScalar = checkScalar(pvBoolean);
|
||||
PVBooleanPtr pv = static_pointer_cast<PVBoolean>(pvScalar);
|
||||
return pv->get();
|
||||
}
|
||||
|
||||
int8 EasyPVStructureImpl::getByte()
|
||||
{
|
||||
PVScalarPtr pvScalar = checkScalar(pvByte);
|
||||
return convert->toByte(pvScalar);
|
||||
}
|
||||
|
||||
uint8 EasyPVStructureImpl::getUByte()
|
||||
{
|
||||
PVScalarPtr pvScalar = checkScalar(pvUByte);
|
||||
return convert->toUByte(pvScalar);
|
||||
}
|
||||
|
||||
int16 EasyPVStructureImpl::getShort()
|
||||
{
|
||||
PVScalarPtr pvScalar = checkScalar(pvShort);
|
||||
return convert->toShort(pvScalar);
|
||||
}
|
||||
|
||||
uint16 EasyPVStructureImpl::getUShort()
|
||||
{
|
||||
PVScalarPtr pvScalar = checkScalar(pvUShort);
|
||||
return convert->toUShort(pvScalar);
|
||||
}
|
||||
|
||||
int32 EasyPVStructureImpl::getInt()
|
||||
{
|
||||
PVScalarPtr pvScalar = checkScalar(pvInt);
|
||||
return convert->toInt(pvScalar);
|
||||
}
|
||||
|
||||
uint32 EasyPVStructureImpl::getUInt()
|
||||
{
|
||||
PVScalarPtr pvScalar = checkScalar(pvUInt);
|
||||
return convert->toUInt(pvScalar);
|
||||
}
|
||||
|
||||
int64 EasyPVStructureImpl::getLong()
|
||||
{
|
||||
PVScalarPtr pvScalar = checkScalar(pvLong);
|
||||
return convert->toLong(pvScalar);
|
||||
}
|
||||
|
||||
uint64 EasyPVStructureImpl::getULong()
|
||||
{
|
||||
PVScalarPtr pvScalar = checkScalar(pvULong);
|
||||
return convert->toULong(pvScalar);
|
||||
}
|
||||
|
||||
float EasyPVStructureImpl::getFloat()
|
||||
{
|
||||
PVScalarPtr pvScalar = checkScalar(pvFloat);
|
||||
return convert->toFloat(pvScalar);
|
||||
}
|
||||
|
||||
double EasyPVStructureImpl::getDouble()
|
||||
{
|
||||
PVScalarPtr pvScalar = checkScalar(pvDouble);
|
||||
return convert->toDouble(pvScalar);
|
||||
}
|
||||
|
||||
string EasyPVStructureImpl::getString()
|
||||
{
|
||||
PVScalarPtr pvScalar = checkScalar(pvString);
|
||||
PVStringPtr pv = static_pointer_cast<PVString>(pvScalar);
|
||||
return pv->get();
|
||||
}
|
||||
|
||||
shared_vector<boolean> EasyPVStructureImpl::getBooleanArray()
|
||||
{
|
||||
checkScalarArray(pvBoolean);
|
||||
PVBooleanArrayPtr pv = static_pointer_cast<PVBooleanArray>(pvValue);
|
||||
return pv->reuse();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
shared_vector<T> copy(PVScalarArrayPtr const & pvScalarArray)
|
||||
{
|
||||
ScalarType elementType = pvScalarArray->getScalarArray()->getElementType();
|
||||
switch(elementType) {
|
||||
case pvBoolean :
|
||||
break;
|
||||
case pvByte :
|
||||
{
|
||||
PVByteArrayPtr pv = static_pointer_cast<PVByteArray>(pvScalarArray);
|
||||
shared_vector<int8> data = pv->reuse();
|
||||
shared_vector<T> to = shared_vector_convert<T,int8>(data);
|
||||
return to;
|
||||
}
|
||||
case pvShort :
|
||||
{
|
||||
PVShortArrayPtr pv = static_pointer_cast<PVShortArray>(pvScalarArray);
|
||||
shared_vector<int16> data = pv->reuse();
|
||||
shared_vector<T> to = shared_vector_convert<T,int16>(data);
|
||||
return to;
|
||||
}
|
||||
case pvInt :
|
||||
{
|
||||
PVIntArrayPtr pv = static_pointer_cast<PVIntArray>(pvScalarArray);
|
||||
shared_vector<int32> data = pv->reuse();
|
||||
shared_vector<T> to = shared_vector_convert<T,int32>(data);
|
||||
return to;
|
||||
}
|
||||
case pvLong :
|
||||
{
|
||||
PVLongArrayPtr pv = static_pointer_cast<PVLongArray>(pvScalarArray);
|
||||
shared_vector<int64> data = pv->reuse();
|
||||
shared_vector<T> to = shared_vector_convert<T,int64>(data);
|
||||
return to;
|
||||
}
|
||||
case pvUByte :
|
||||
{
|
||||
PVUByteArrayPtr pv = static_pointer_cast<PVUByteArray>(pvScalarArray);
|
||||
shared_vector<uint8> data = pv->reuse();
|
||||
shared_vector<T> to = shared_vector_convert<T,uint8>(data);
|
||||
return to;
|
||||
}
|
||||
case pvUShort :
|
||||
{
|
||||
PVUShortArrayPtr pv = static_pointer_cast<PVUShortArray>(pvScalarArray);
|
||||
shared_vector<uint16> data = pv->reuse();
|
||||
shared_vector<T> to = shared_vector_convert<T,uint16>(data);
|
||||
return to;
|
||||
}
|
||||
case pvUInt :
|
||||
{
|
||||
PVUIntArrayPtr pv = static_pointer_cast<PVUIntArray>(pvScalarArray);
|
||||
shared_vector<uint32> data = pv->reuse();
|
||||
shared_vector<T> to = shared_vector_convert<T,uint32>(data);
|
||||
return to;
|
||||
}
|
||||
case pvULong :
|
||||
{
|
||||
PVULongArrayPtr pv = static_pointer_cast<PVULongArray>(pvScalarArray);
|
||||
shared_vector<uint64> data = pv->reuse();
|
||||
shared_vector<T> to = shared_vector_convert<T,uint64>(data);
|
||||
return to;
|
||||
}
|
||||
case pvFloat :
|
||||
{
|
||||
PVFloatArrayPtr pv = static_pointer_cast<PVFloatArray>(pvScalarArray);
|
||||
shared_vector<float> data = pv->reuse();
|
||||
shared_vector<T> to = shared_vector_convert<T,float>(data);
|
||||
return to;
|
||||
}
|
||||
case pvDouble :
|
||||
{
|
||||
PVDoubleArrayPtr pv = static_pointer_cast<PVDoubleArray>(pvScalarArray);
|
||||
shared_vector<double> data = pv->reuse();
|
||||
shared_vector<T> to = shared_vector_convert<T,double>(data);
|
||||
return to;
|
||||
}
|
||||
case pvString :
|
||||
break;
|
||||
}
|
||||
return shared_vector<T>();
|
||||
}
|
||||
|
||||
shared_vector<int8> EasyPVStructureImpl::getByteArray()
|
||||
{
|
||||
PVScalarArrayPtr pvScalarArray = checkScalarArray(pvByte);
|
||||
ScalarType scalarType = pvScalarArray->getScalarArray()->getElementType();
|
||||
if(scalarType==pvByte) {
|
||||
PVByteArrayPtr pv = static_pointer_cast<PVByteArray>(pvValue);
|
||||
return pv->reuse();
|
||||
}
|
||||
shared_vector<int8> xx = copy<int8>(pvScalarArray);
|
||||
return xx;
|
||||
}
|
||||
|
||||
shared_vector<int16> EasyPVStructureImpl::getShortArray()
|
||||
{
|
||||
PVScalarArrayPtr pvScalarArray = checkScalarArray(pvShort);
|
||||
ScalarType scalarType = pvScalarArray->getScalarArray()->getElementType();
|
||||
if(scalarType==pvShort) {
|
||||
PVShortArrayPtr pv = static_pointer_cast<PVShortArray>(pvValue);
|
||||
return pv->reuse();
|
||||
}
|
||||
shared_vector<int16> xx = copy<int16>(pvScalarArray);
|
||||
return xx;
|
||||
}
|
||||
|
||||
shared_vector<int32> EasyPVStructureImpl::getIntArray()
|
||||
{
|
||||
PVScalarArrayPtr pvScalarArray = checkScalarArray(pvInt);
|
||||
ScalarType scalarType = pvScalarArray->getScalarArray()->getElementType();
|
||||
if(scalarType==pvInt) {
|
||||
PVIntArrayPtr pv = static_pointer_cast<PVIntArray>(pvValue);
|
||||
return pv->reuse();
|
||||
}
|
||||
shared_vector<int32> xx = copy<int32>(pvScalarArray);
|
||||
return xx;
|
||||
}
|
||||
|
||||
shared_vector<int64> EasyPVStructureImpl::getLongArray()
|
||||
{
|
||||
PVScalarArrayPtr pvScalarArray = checkScalarArray(pvLong);
|
||||
ScalarType scalarType = pvScalarArray->getScalarArray()->getElementType();
|
||||
if(scalarType==pvLong) {
|
||||
PVLongArrayPtr pv = static_pointer_cast<PVLongArray>(pvValue);
|
||||
return pv->reuse();
|
||||
}
|
||||
shared_vector<int64> xx = copy<int64>(pvScalarArray);
|
||||
return xx;
|
||||
}
|
||||
|
||||
shared_vector<uint8> EasyPVStructureImpl::getUByteArray()
|
||||
{
|
||||
PVScalarArrayPtr pvScalarArray = checkScalarArray(pvUByte);
|
||||
ScalarType scalarType = pvScalarArray->getScalarArray()->getElementType();
|
||||
if(scalarType==pvUByte) {
|
||||
PVUByteArrayPtr pv = static_pointer_cast<PVUByteArray>(pvValue);
|
||||
return pv->reuse();
|
||||
}
|
||||
shared_vector<uint8> xx = copy<uint8>(pvScalarArray);
|
||||
return xx;
|
||||
}
|
||||
|
||||
shared_vector<uint16> EasyPVStructureImpl::getUShortArray()
|
||||
{
|
||||
PVScalarArrayPtr pvScalarArray = checkScalarArray(pvUShort);
|
||||
ScalarType scalarType = pvScalarArray->getScalarArray()->getElementType();
|
||||
if(scalarType==pvUShort) {
|
||||
PVUShortArrayPtr pv = static_pointer_cast<PVUShortArray>(pvValue);
|
||||
return pv->reuse();
|
||||
}
|
||||
shared_vector<uint16> xx = copy<uint16>(pvScalarArray);
|
||||
return xx;
|
||||
}
|
||||
|
||||
shared_vector<uint32> EasyPVStructureImpl::getUIntArray()
|
||||
{
|
||||
PVScalarArrayPtr pvScalarArray = checkScalarArray(pvUInt);
|
||||
ScalarType scalarType = pvScalarArray->getScalarArray()->getElementType();
|
||||
if(scalarType==pvUInt) {
|
||||
PVUIntArrayPtr pv = static_pointer_cast<PVUIntArray>(pvValue);
|
||||
return pv->reuse();
|
||||
}
|
||||
shared_vector<uint32> xx = copy<uint32>(pvScalarArray);
|
||||
return xx;
|
||||
}
|
||||
|
||||
shared_vector<uint64> EasyPVStructureImpl::getULongArray()
|
||||
{
|
||||
PVScalarArrayPtr pvScalarArray = checkScalarArray(pvULong);
|
||||
ScalarType scalarType = pvScalarArray->getScalarArray()->getElementType();
|
||||
if(scalarType==pvULong) {
|
||||
PVULongArrayPtr pv = static_pointer_cast<PVULongArray>(pvValue);
|
||||
return pv->reuse();
|
||||
}
|
||||
shared_vector<uint64> xx = copy<uint64>(pvScalarArray);
|
||||
return xx;
|
||||
}
|
||||
|
||||
shared_vector<float> EasyPVStructureImpl::getFloatArray()
|
||||
{
|
||||
checkScalarArray(pvFloat);
|
||||
PVFloatArrayPtr pv = static_pointer_cast<PVFloatArray>(pvValue);
|
||||
return pv->reuse();
|
||||
PVScalarArrayPtr pvScalarArray = checkScalarArray(pvFloat);
|
||||
ScalarType scalarType = pvScalarArray->getScalarArray()->getElementType();
|
||||
if(scalarType==pvFloat) {
|
||||
PVFloatArrayPtr pv = static_pointer_cast<PVFloatArray>(pvValue);
|
||||
return pv->reuse();
|
||||
}
|
||||
shared_vector<float> xx = copy<float>(pvScalarArray);
|
||||
return xx;
|
||||
}
|
||||
|
||||
shared_vector<double> EasyPVStructureImpl::getDoubleArray()
|
||||
{
|
||||
PVScalarArrayPtr pvScalarArray = checkScalarArray(pvDouble);
|
||||
ScalarType scalarType = pvScalarArray->getScalarArray()->getElementType();
|
||||
if(scalarType==pvDouble) {
|
||||
PVDoubleArrayPtr pv = static_pointer_cast<PVDoubleArray>(pvValue);
|
||||
return pv->reuse();
|
||||
}
|
||||
shared_vector<double> xx = copy<double>(pvScalarArray);
|
||||
return xx;
|
||||
}
|
||||
|
||||
shared_vector<string> EasyPVStructureImpl::getStringArray()
|
||||
{
|
||||
checkScalarArray(pvString);
|
||||
PVStringArrayPtr pv = static_pointer_cast<PVStringArray>(pvValue);
|
||||
return pv->reuse();
|
||||
}
|
||||
|
||||
|
||||
}}
|
212
src/easyProcess.cpp
Normal file
212
src/easyProcess.cpp
Normal file
@ -0,0 +1,212 @@
|
||||
/* easyProcess.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/easyPVA.h>
|
||||
|
||||
using std::tr1::static_pointer_cast;
|
||||
using namespace epics::pvData;
|
||||
using namespace epics::pvAccess;
|
||||
using namespace std;
|
||||
|
||||
namespace epics { namespace easyPVA {
|
||||
|
||||
|
||||
class ChannelProcessRequesterImpl : public ChannelProcessRequester
|
||||
{
|
||||
EasyProcess * easyProcess;
|
||||
public:
|
||||
ChannelProcessRequesterImpl(EasyProcess * easyProcess)
|
||||
: easyProcess(easyProcess) {}
|
||||
string getRequesterName()
|
||||
{return easyProcess->getRequesterName();}
|
||||
void message(string const & message,MessageType messageType)
|
||||
{easyProcess->message(message,messageType);}
|
||||
void channelProcessConnect(
|
||||
const Status& status,
|
||||
ChannelProcess::shared_pointer const & channelProcess)
|
||||
{easyProcess->channelProcessConnect(status,channelProcess);}
|
||||
void processDone(
|
||||
const Status& status,
|
||||
ChannelProcess::shared_pointer const & channelProcess)
|
||||
{easyProcess->processDone(status,channelProcess);}
|
||||
};
|
||||
|
||||
EasyProcess::EasyProcess(
|
||||
EasyPVAPtr const &pva,
|
||||
EasyChannelPtr const & easyChannel,
|
||||
Channel::shared_pointer const & channel,
|
||||
PVStructurePtr const &pvRequest)
|
||||
: easyPVA(pva),
|
||||
easyChannel(easyChannel),
|
||||
channel(channel),
|
||||
pvRequest(pvRequest),
|
||||
isDestroyed(false),
|
||||
connectState(connectIdle),
|
||||
processState(processIdle)
|
||||
{
|
||||
}
|
||||
|
||||
EasyProcess::~EasyProcess()
|
||||
{
|
||||
destroy();
|
||||
}
|
||||
|
||||
void EasyProcess::checkProcessState()
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyProcess was destroyed");
|
||||
if(connectState==connectIdle) connect();
|
||||
if(processState==processIdle) process();
|
||||
}
|
||||
|
||||
// from ChannelProcessRequester
|
||||
string EasyProcess::getRequesterName()
|
||||
{
|
||||
EasyPVAPtr yyy = easyPVA.lock();
|
||||
if(!yyy) throw std::runtime_error("easyPVA was destroyed");
|
||||
return yyy->getRequesterName();
|
||||
}
|
||||
|
||||
void EasyProcess::message(string const & message,MessageType messageType)
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyProcess was destroyed");
|
||||
EasyPVAPtr yyy = easyPVA.lock();
|
||||
if(!yyy) throw std::runtime_error("easyPVA was destroyed");
|
||||
yyy->message(message, messageType);
|
||||
}
|
||||
|
||||
void EasyProcess::channelProcessConnect(
|
||||
const Status& status,
|
||||
ChannelProcess::shared_pointer const & channelProcess)
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyProcess was destroyed");
|
||||
channelProcessConnectStatus = status;
|
||||
this->channelProcess = channelProcess;
|
||||
waitForConnect.signal();
|
||||
|
||||
}
|
||||
|
||||
void EasyProcess::processDone(
|
||||
const Status& status,
|
||||
ChannelProcess::shared_pointer const & channelProcess)
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyProcess was destroyed");
|
||||
channelProcessStatus = status;
|
||||
waitForProcess.signal();
|
||||
}
|
||||
|
||||
|
||||
// from EasyProcess
|
||||
void EasyProcess::destroy()
|
||||
{
|
||||
{
|
||||
Lock xx(mutex);
|
||||
if(isDestroyed) return;
|
||||
isDestroyed = true;
|
||||
}
|
||||
if(channelProcess) channelProcess->destroy();
|
||||
channelProcess.reset();
|
||||
}
|
||||
|
||||
void EasyProcess::connect()
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyProcess was destroyed");
|
||||
issueConnect();
|
||||
Status status = waitConnect();
|
||||
if(status.isOK()) return;
|
||||
stringstream ss;
|
||||
ss << "channel " << channel->getChannelName() << " EasyProcess::connect " << status.getMessage();
|
||||
throw std::runtime_error(ss.str());
|
||||
}
|
||||
|
||||
void EasyProcess::issueConnect()
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyProcess was destroyed");
|
||||
if(connectState!=connectIdle) {
|
||||
stringstream ss;
|
||||
ss << "channel " << channel->getChannelName() << " easyProcess already connected ";
|
||||
throw std::runtime_error(ss.str());
|
||||
}
|
||||
processRequester = ChannelProcessRequester::shared_pointer(new ChannelProcessRequesterImpl(this));
|
||||
connectState = connectActive;
|
||||
channelProcess = channel->createChannelProcess(processRequester,pvRequest);
|
||||
}
|
||||
|
||||
Status EasyProcess::waitConnect()
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyProcess was destroyed");
|
||||
if(connectState!=connectActive) {
|
||||
stringstream ss;
|
||||
ss << "channel " << channel->getChannelName() << " easyProcess 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 EasyProcess::process()
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyProcess was destroyed");
|
||||
issueProcess();
|
||||
Status status = waitProcess();
|
||||
if(status.isOK()) return;
|
||||
stringstream ss;
|
||||
ss << "channel " << channel->getChannelName() << " EasyProcess::process " << status.getMessage();
|
||||
throw std::runtime_error(ss.str());
|
||||
}
|
||||
|
||||
void EasyProcess::issueProcess()
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyProcess was destroyed");
|
||||
if(connectState==connectIdle) connect();
|
||||
if(processState!=processIdle) {
|
||||
stringstream ss;
|
||||
ss << "channel " << channel->getChannelName() << " EasyProcess::issueProcess process aleady active ";
|
||||
throw std::runtime_error(ss.str());
|
||||
}
|
||||
processState = processActive;
|
||||
channelProcess->process();
|
||||
}
|
||||
|
||||
Status EasyProcess::waitProcess()
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyProcess was destroyed");
|
||||
if(processState!=processActive){
|
||||
stringstream ss;
|
||||
ss << "channel " << channel->getChannelName() << " EasyProcess::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());
|
||||
}
|
||||
|
||||
EasyProcessPtr EasyProcess::create(
|
||||
EasyPVAPtr const &pva,
|
||||
EasyChannelPtr const & easyChannel,
|
||||
Channel::shared_pointer const & channel,
|
||||
PVStructurePtr const &pvRequest)
|
||||
{
|
||||
EasyProcessPtr epv(new EasyProcess(pva,easyChannel,channel,pvRequest));
|
||||
return epv;
|
||||
}
|
||||
|
||||
}}
|
292
src/easyPut.cpp
Normal file
292
src/easyPut.cpp
Normal file
@ -0,0 +1,292 @@
|
||||
/* easyPut.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/easyPVA.h>
|
||||
|
||||
using std::tr1::static_pointer_cast;
|
||||
using namespace epics::pvData;
|
||||
using namespace epics::pvAccess;
|
||||
using namespace std;
|
||||
|
||||
namespace epics { namespace easyPVA {
|
||||
|
||||
class ChannelPutRequesterImpl : public ChannelPutRequester
|
||||
{
|
||||
EasyPut * easyPut;
|
||||
public:
|
||||
ChannelPutRequesterImpl(EasyPut * easyPut)
|
||||
: easyPut(easyPut) {}
|
||||
string getRequesterName()
|
||||
{return easyPut->getRequesterName();}
|
||||
void message(string const & message,MessageType messageType)
|
||||
{easyPut->message(message,messageType);}
|
||||
void channelPutConnect(
|
||||
const Status& status,
|
||||
ChannelPut::shared_pointer const & channelPut,
|
||||
StructureConstPtr const & structure)
|
||||
{easyPut->channelPutConnect(status,channelPut,structure);}
|
||||
void getDone(
|
||||
const Status& status,
|
||||
ChannelPut::shared_pointer const & channelPut,
|
||||
PVStructurePtr const & pvStructure,
|
||||
BitSetPtr const & bitSet)
|
||||
{easyPut->getDone(status,channelPut,pvStructure,bitSet);}
|
||||
void putDone(
|
||||
const Status& status,
|
||||
ChannelPut::shared_pointer const & channelPut)
|
||||
{easyPut->putDone(status,channelPut);}
|
||||
};
|
||||
|
||||
EasyPut::EasyPut(
|
||||
EasyPVAPtr const &pva,
|
||||
EasyChannelPtr const & easyChannel,
|
||||
Channel::shared_pointer const & channel,
|
||||
PVStructurePtr const &pvRequest)
|
||||
: easyPVA(pva),
|
||||
easyChannel(easyChannel),
|
||||
channel(channel),
|
||||
pvRequest(pvRequest),
|
||||
isDestroyed(false),
|
||||
connectState(connectIdle),
|
||||
putState(putIdle)
|
||||
{
|
||||
}
|
||||
|
||||
EasyPut::~EasyPut()
|
||||
{
|
||||
destroy();
|
||||
}
|
||||
|
||||
void EasyPut::checkPutState()
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyPut was destroyed");
|
||||
if(connectState==connectIdle){
|
||||
connect();
|
||||
get();
|
||||
}
|
||||
}
|
||||
|
||||
// from ChannelPutRequester
|
||||
string EasyPut::getRequesterName()
|
||||
{
|
||||
EasyPVAPtr yyy = easyPVA.lock();
|
||||
if(!yyy) throw std::runtime_error("easyPVA was destroyed");
|
||||
return yyy->getRequesterName();
|
||||
}
|
||||
|
||||
void EasyPut::message(string const & message,MessageType messageType)
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyPut was destroyed");
|
||||
EasyPVAPtr yyy = easyPVA.lock();
|
||||
if(!yyy) throw std::runtime_error("easyPVA was destroyed");
|
||||
yyy->message(message, messageType);
|
||||
}
|
||||
|
||||
void EasyPut::channelPutConnect(
|
||||
const Status& status,
|
||||
ChannelPut::shared_pointer const & channelPut,
|
||||
StructureConstPtr const & structure)
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyPut was destroyed");
|
||||
channelPutConnectStatus = status;
|
||||
this->channelPut = channelPut;
|
||||
if(status.isOK()) {
|
||||
easyData = EasyPutData::create(structure);
|
||||
easyData->setMessagePrefix(easyChannel.lock()->getChannelName());
|
||||
}
|
||||
waitForConnect.signal();
|
||||
|
||||
}
|
||||
|
||||
void EasyPut::getDone(
|
||||
const Status& status,
|
||||
ChannelPut::shared_pointer const & channelPut,
|
||||
PVStructurePtr const & pvStructure,
|
||||
BitSetPtr const & bitSet)
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyPut was destroyed");
|
||||
channelGetPutStatus = status;
|
||||
if(status.isOK()) {
|
||||
PVStructurePtr pvs = easyData->getPVStructure();
|
||||
pvs->copyUnchecked(*pvStructure,*bitSet);
|
||||
BitSetPtr bs = easyData->getBitSet();
|
||||
bs->clear();
|
||||
*bs |= *bitSet;
|
||||
}
|
||||
waitForGetPut.signal();
|
||||
}
|
||||
|
||||
void EasyPut::putDone(
|
||||
const Status& status,
|
||||
ChannelPut::shared_pointer const & channelPut)
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyPut was destroyed");
|
||||
channelGetPutStatus = status;
|
||||
waitForGetPut.signal();
|
||||
}
|
||||
|
||||
|
||||
// from EasyPut
|
||||
void EasyPut::destroy()
|
||||
{
|
||||
{
|
||||
Lock xx(mutex);
|
||||
if(isDestroyed) return;
|
||||
isDestroyed = true;
|
||||
}
|
||||
if(channelPut) channelPut->destroy();
|
||||
channelPut.reset();
|
||||
}
|
||||
|
||||
void EasyPut::connect()
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyPut was destroyed");
|
||||
issueConnect();
|
||||
Status status = waitConnect();
|
||||
if(status.isOK()) return;
|
||||
stringstream ss;
|
||||
ss << "channel " << channel->getChannelName() << " EasyPut::connect " << status.getMessage();
|
||||
throw std::runtime_error(ss.str());
|
||||
}
|
||||
|
||||
void EasyPut::issueConnect()
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyPut was destroyed");
|
||||
if(connectState!=connectIdle) {
|
||||
stringstream ss;
|
||||
ss << "channel " << channel->getChannelName() << " easyPut already connected ";
|
||||
throw std::runtime_error(ss.str());
|
||||
}
|
||||
putRequester = ChannelPutRequester::shared_pointer(new ChannelPutRequesterImpl(this));
|
||||
connectState = connectActive;
|
||||
channelPut = channel->createChannelPut(putRequester,pvRequest);
|
||||
}
|
||||
|
||||
Status EasyPut::waitConnect()
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyPut was destroyed");
|
||||
if(connectState!=connectActive) {
|
||||
stringstream ss;
|
||||
ss << "channel " << channel->getChannelName() << " easyPut 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 EasyPut::get()
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyPut was destroyed");
|
||||
issueGet();
|
||||
Status status = waitGet();
|
||||
if(status.isOK()) return;
|
||||
stringstream ss;
|
||||
ss << "channel " << channel->getChannelName() << " EasyPut::get " << status.getMessage();
|
||||
throw std::runtime_error(ss.str());
|
||||
}
|
||||
|
||||
void EasyPut::issueGet()
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyPut was destroyed");
|
||||
if(connectState==connectIdle) connect();
|
||||
if(putState!=putIdle) {
|
||||
stringstream ss;
|
||||
ss << "channel " << channel->getChannelName() << " EasyPut::issueGet get or put aleady active ";
|
||||
throw std::runtime_error(ss.str());
|
||||
}
|
||||
putState = getActive;
|
||||
easyData->getBitSet()->clear();
|
||||
channelPut->get();
|
||||
}
|
||||
|
||||
Status EasyPut::waitGet()
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyPut was destroyed");
|
||||
if(putState!=getActive){
|
||||
stringstream ss;
|
||||
ss << "channel " << channel->getChannelName() << " EasyPut::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 EasyPut::put()
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyPut was destroyed");
|
||||
issuePut();
|
||||
Status status = waitPut();
|
||||
if(status.isOK()) return;
|
||||
stringstream ss;
|
||||
ss << "channel " << channel->getChannelName() << " EasyPut::put " << status.getMessage();
|
||||
throw std::runtime_error(ss.str());
|
||||
}
|
||||
|
||||
void EasyPut::issuePut()
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyPut was destroyed");
|
||||
if(connectState==connectIdle) connect();
|
||||
if(putState!=putIdle) {
|
||||
stringstream ss;
|
||||
ss << "channel " << channel->getChannelName() << " EasyPut::issueGet get or put aleady active ";
|
||||
throw std::runtime_error(ss.str());
|
||||
}
|
||||
putState = putActive;
|
||||
channelPut->put(easyData->getPVStructure(),easyData->getBitSet());
|
||||
}
|
||||
|
||||
Status EasyPut::waitPut()
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyPut was destroyed");
|
||||
if(putState!=putActive){
|
||||
stringstream ss;
|
||||
ss << "channel " << channel->getChannelName() << " EasyPut::waitPut llegal put state";
|
||||
throw std::runtime_error(ss.str());
|
||||
}
|
||||
waitForGetPut.wait();
|
||||
putState = putIdle;
|
||||
if(channelGetPutStatus.isOK()) {
|
||||
easyData->getBitSet()->clear();
|
||||
return Status::Ok;
|
||||
}
|
||||
return Status(Status::STATUSTYPE_ERROR,channelGetPutStatus.getMessage());
|
||||
}
|
||||
|
||||
EasyPutDataPtr EasyPut::getData()
|
||||
{
|
||||
checkPutState();
|
||||
return easyData;
|
||||
}
|
||||
|
||||
EasyPutPtr EasyPut::create(
|
||||
EasyPVAPtr const &pva,
|
||||
EasyChannelPtr const & easyChannel,
|
||||
Channel::shared_pointer const & channel,
|
||||
PVStructurePtr const &pvRequest)
|
||||
{
|
||||
EasyPutPtr epv(new EasyPut(pva,easyChannel,channel,pvRequest));
|
||||
return epv;
|
||||
}
|
||||
|
||||
|
||||
}}
|
257
src/easyPutData.cpp
Normal file
257
src/easyPutData.cpp
Normal file
@ -0,0 +1,257 @@
|
||||
/* 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/easyPVA.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 easyPVA {
|
||||
|
||||
class EasyPostHandlerPvt: public PostHandler
|
||||
{
|
||||
EasyPutData * easyData;
|
||||
size_t fieldNumber;
|
||||
public:
|
||||
EasyPostHandlerPvt(EasyPutData *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 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");
|
||||
|
||||
EasyPutDataPtr EasyPutData::create(StructureConstPtr const & structure)
|
||||
{
|
||||
EasyPutDataPtr epv(new EasyPutData(structure));
|
||||
return epv;
|
||||
}
|
||||
|
||||
EasyPutData::EasyPutData(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 EasyPostHandlerPvt(this, i));
|
||||
if(i==0) {
|
||||
pvField = pvStructure;
|
||||
} else {
|
||||
pvField = pvStructure->getSubField(i);
|
||||
}
|
||||
pvField->setPostHandler(postHandler[i]);
|
||||
}
|
||||
pvValue = pvStructure->getSubField("value");
|
||||
}
|
||||
|
||||
void EasyPutData::checkValue()
|
||||
{
|
||||
if(pvValue) return;
|
||||
throw std::runtime_error(messagePrefix + noValue);
|
||||
}
|
||||
|
||||
void EasyPutData::postPut(size_t fieldNumber)
|
||||
{
|
||||
bitSet->set(fieldNumber);
|
||||
}
|
||||
|
||||
void EasyPutData::setMessagePrefix(std::string const & value)
|
||||
{
|
||||
messagePrefix = value;
|
||||
}
|
||||
|
||||
StructureConstPtr EasyPutData::getStructure()
|
||||
{return structure;}
|
||||
|
||||
PVStructurePtr EasyPutData::getPVStructure()
|
||||
{return pvStructure;}
|
||||
|
||||
BitSetPtr EasyPutData::getBitSet()
|
||||
{return bitSet;}
|
||||
|
||||
std::ostream & EasyPutData::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 EasyPutData::hasValue()
|
||||
{
|
||||
if(!pvValue) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool EasyPutData::isValueScalar()
|
||||
{
|
||||
if(!pvValue) return false;
|
||||
if(pvValue->getField()->getType()==scalar) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool EasyPutData::isValueScalarArray()
|
||||
{
|
||||
if(!pvValue) return false;
|
||||
if(pvValue->getField()->getType()==scalarArray) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
PVFieldPtr EasyPutData::getValue()
|
||||
{
|
||||
checkValue();
|
||||
return pvValue;
|
||||
}
|
||||
|
||||
PVScalarPtr EasyPutData::getScalarValue()
|
||||
{
|
||||
checkValue();
|
||||
PVScalarPtr pv = pvStructure->getSubField<PVScalar>("value");
|
||||
if(!pv) {
|
||||
throw std::runtime_error(messagePrefix + noScalar);
|
||||
}
|
||||
return pv;
|
||||
}
|
||||
|
||||
PVArrayPtr EasyPutData::getArrayValue()
|
||||
{
|
||||
checkValue();
|
||||
PVArrayPtr pv = pvStructure->getSubField<PVArray>("value");
|
||||
if(!pv) {
|
||||
throw std::runtime_error(messagePrefix + noArray);
|
||||
}
|
||||
return pv;
|
||||
}
|
||||
|
||||
PVScalarArrayPtr EasyPutData::getScalarArrayValue()
|
||||
{
|
||||
checkValue();
|
||||
PVScalarArrayPtr pv = pvStructure->getSubField<PVScalarArray>("value");
|
||||
if(!pv) {
|
||||
throw std::runtime_error(messagePrefix + noScalarArray);
|
||||
}
|
||||
return pv;
|
||||
}
|
||||
|
||||
double EasyPutData::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 EasyPutData::getString()
|
||||
{
|
||||
PVScalarPtr pvScalar = getScalarValue();
|
||||
return convert->toString(pvScalar);
|
||||
}
|
||||
|
||||
shared_vector<const double> EasyPutData::getDoubleArray()
|
||||
{
|
||||
checkValue();
|
||||
PVDoubleArrayPtr pv = pvStructure->getSubField<PVDoubleArray>("value");
|
||||
if(!pv) {
|
||||
throw std::runtime_error(messagePrefix + notDoubleArray);
|
||||
}
|
||||
return pv->view();
|
||||
}
|
||||
|
||||
shared_vector<const string> EasyPutData::getStringArray()
|
||||
{
|
||||
checkValue();
|
||||
PVStringArrayPtr pv = pvStructure->getSubField<PVStringArray>("value");
|
||||
if(!pv) {
|
||||
throw std::runtime_error(messagePrefix + notStringArray);
|
||||
}
|
||||
return pv->view();
|
||||
|
||||
}
|
||||
|
||||
void EasyPutData::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(notCompatibleScalar);
|
||||
}
|
||||
convert->fromDouble(pvScalar,value);
|
||||
}
|
||||
|
||||
void EasyPutData::putString(std::string const & value)
|
||||
{
|
||||
PVScalarPtr pvScalar = getScalarValue();
|
||||
convert->fromString(pvScalar,value);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void EasyPutData::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 EasyPutData::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);
|
||||
}
|
||||
|
||||
}}
|
378
src/easyPutGet.cpp
Normal file
378
src/easyPutGet.cpp
Normal file
@ -0,0 +1,378 @@
|
||||
/* easyPutGet.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/easyPVA.h>
|
||||
|
||||
using std::tr1::static_pointer_cast;
|
||||
using namespace epics::pvData;
|
||||
using namespace epics::pvAccess;
|
||||
using namespace std;
|
||||
|
||||
namespace epics { namespace easyPVA {
|
||||
|
||||
class ChannelPutGetRequesterImpl : public ChannelPutGetRequester
|
||||
{
|
||||
EasyPutGet * easyPutGet;
|
||||
public:
|
||||
ChannelPutGetRequesterImpl(EasyPutGet * easyPutGet)
|
||||
: easyPutGet(easyPutGet) {}
|
||||
string getRequesterName()
|
||||
{return easyPutGet->getRequesterName();}
|
||||
void message(string const & message,MessageType messageType)
|
||||
{easyPutGet->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)
|
||||
{
|
||||
easyPutGet->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)
|
||||
{
|
||||
easyPutGet->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)
|
||||
{
|
||||
easyPutGet->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)
|
||||
{
|
||||
easyPutGet->getGetDone(status,channelPutGet,getPVStructure,getBitSet);
|
||||
}
|
||||
};
|
||||
|
||||
EasyPutGet::EasyPutGet(
|
||||
EasyPVAPtr const &pva,
|
||||
EasyChannelPtr const & easyChannel,
|
||||
Channel::shared_pointer const & channel,
|
||||
PVStructurePtr const &pvRequest)
|
||||
: easyPVA(pva),
|
||||
easyChannel(easyChannel),
|
||||
channel(channel),
|
||||
pvRequest(pvRequest),
|
||||
isDestroyed(false),
|
||||
connectState(connectIdle),
|
||||
putGetState(putGetIdle)
|
||||
{
|
||||
}
|
||||
|
||||
EasyPutGet::~EasyPutGet()
|
||||
{
|
||||
destroy();
|
||||
}
|
||||
|
||||
void EasyPutGet::checkPutGetState()
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyPutGet was destroyed");
|
||||
if(connectState==connectIdle){
|
||||
connect();
|
||||
getPut();
|
||||
}
|
||||
}
|
||||
|
||||
// from ChannelPutGetRequester
|
||||
string EasyPutGet::getRequesterName()
|
||||
{
|
||||
EasyPVAPtr yyy = easyPVA.lock();
|
||||
if(!yyy) throw std::runtime_error("easyPVA was destroyed");
|
||||
return yyy->getRequesterName();
|
||||
}
|
||||
|
||||
void EasyPutGet::message(string const & message,MessageType messageType)
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyPutGet was destroyed");
|
||||
EasyPVAPtr yyy = easyPVA.lock();
|
||||
if(!yyy) throw std::runtime_error("easyPVA was destroyed");
|
||||
yyy->message(message, messageType);
|
||||
}
|
||||
|
||||
void EasyPutGet::channelPutGetConnect(
|
||||
const Status& status,
|
||||
ChannelPutGet::shared_pointer const & channelPutGet,
|
||||
StructureConstPtr const & putStructure,
|
||||
StructureConstPtr const & getStructure)
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyPutGet was destroyed");
|
||||
channelPutGetConnectStatus = status;
|
||||
this->channelPutGet = channelPutGet;
|
||||
if(status.isOK()) {
|
||||
easyPutData = EasyPutData::create(putStructure);
|
||||
easyPutData->setMessagePrefix(easyChannel.lock()->getChannelName());
|
||||
easyGetData = EasyGetData::create(getStructure);
|
||||
easyGetData->setMessagePrefix(easyChannel.lock()->getChannelName());
|
||||
}
|
||||
waitForConnect.signal();
|
||||
|
||||
}
|
||||
|
||||
void EasyPutGet::putGetDone(
|
||||
const Status& status,
|
||||
ChannelPutGet::shared_pointer const & channelPutGet,
|
||||
PVStructurePtr const & getPVStructure,
|
||||
BitSetPtr const & getBitSet)
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyPutGet was destroyed");
|
||||
channelPutGetStatus = status;
|
||||
if(status.isOK()) {
|
||||
easyGetData->setData(getPVStructure,getBitSet);
|
||||
}
|
||||
waitForPutGet.signal();
|
||||
}
|
||||
|
||||
void EasyPutGet::getPutDone(
|
||||
const Status& status,
|
||||
ChannelPutGet::shared_pointer const & channelPutGet,
|
||||
PVStructurePtr const & putPVStructure,
|
||||
BitSetPtr const & putBitSet)
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyPutGet was destroyed");
|
||||
channelGetPutGetStatus = status;
|
||||
if(status.isOK()) {
|
||||
PVStructurePtr pvs = easyPutData->getPVStructure();
|
||||
pvs->copyUnchecked(*putPVStructure,*putBitSet);
|
||||
BitSetPtr bs = easyPutData->getBitSet();
|
||||
bs->clear();
|
||||
*bs |= *putBitSet;
|
||||
}
|
||||
waitForPutGet.signal();
|
||||
}
|
||||
|
||||
void EasyPutGet::getGetDone(
|
||||
const Status& status,
|
||||
ChannelPutGet::shared_pointer const & channelPutGet,
|
||||
PVStructurePtr const & getPVStructure,
|
||||
BitSetPtr const & getBitSet)
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyPutGet was destroyed");
|
||||
channelPutGetStatus = status;
|
||||
if(status.isOK()) {
|
||||
easyGetData->setData(getPVStructure,getBitSet);
|
||||
}
|
||||
waitForPutGet.signal();
|
||||
}
|
||||
|
||||
|
||||
|
||||
// from EasyPutGet
|
||||
void EasyPutGet::destroy()
|
||||
{
|
||||
{
|
||||
Lock xx(mutex);
|
||||
if(isDestroyed) return;
|
||||
isDestroyed = true;
|
||||
}
|
||||
if(channelPutGet) channelPutGet->destroy();
|
||||
channelPutGet.reset();
|
||||
}
|
||||
|
||||
void EasyPutGet::connect()
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyPutGet was destroyed");
|
||||
issueConnect();
|
||||
Status status = waitConnect();
|
||||
if(status.isOK()) return;
|
||||
stringstream ss;
|
||||
ss << "channel " << channel->getChannelName() << " EasyPutGet::connect " << status.getMessage();
|
||||
throw std::runtime_error(ss.str());
|
||||
}
|
||||
|
||||
void EasyPutGet::issueConnect()
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyPutGet was destroyed");
|
||||
if(connectState!=connectIdle) {
|
||||
stringstream ss;
|
||||
ss << "channel " << channel->getChannelName() << " easyPutGet already connected ";
|
||||
throw std::runtime_error(ss.str());
|
||||
}
|
||||
putGetRequester = ChannelPutGetRequester::shared_pointer(new ChannelPutGetRequesterImpl(this));
|
||||
connectState = connectActive;
|
||||
channelPutGet = channel->createChannelPutGet(putGetRequester,pvRequest);
|
||||
}
|
||||
|
||||
Status EasyPutGet::waitConnect()
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyPutGet was destroyed");
|
||||
if(connectState!=connectActive) {
|
||||
stringstream ss;
|
||||
ss << "channel " << channel->getChannelName() << " easyPutGet 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 EasyPutGet::putGet()
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyPutGet was destroyed");
|
||||
issuePutGet();
|
||||
Status status = waitPutGet();
|
||||
if(status.isOK()) return;
|
||||
stringstream ss;
|
||||
ss << "channel " << channel->getChannelName() << " EasyPutGet::putGet " << status.getMessage();
|
||||
throw std::runtime_error(ss.str());
|
||||
}
|
||||
|
||||
void EasyPutGet::issuePutGet()
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyPutGet was destroyed");
|
||||
if(connectState==connectIdle) connect();
|
||||
if(putGetState!=putGetIdle) {
|
||||
stringstream ss;
|
||||
ss << "channel " << channel->getChannelName() << " EasyPutGet::issueGet get or put aleady active ";
|
||||
throw std::runtime_error(ss.str());
|
||||
}
|
||||
putGetState = putGetActive;
|
||||
channelPutGet->putGet(easyPutData->getPVStructure(),easyPutData->getBitSet());
|
||||
}
|
||||
|
||||
|
||||
Status EasyPutGet::waitPutGet()
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyPutGet was destroyed");
|
||||
if(putGetState!=putGetActive){
|
||||
stringstream ss;
|
||||
ss << "channel " << channel->getChannelName() << " EasyPutGet::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 EasyPutGet::getGet()
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyPutGet was destroyed");
|
||||
issueGetGet();
|
||||
Status status = waitGetGet();
|
||||
if(status.isOK()) return;
|
||||
stringstream ss;
|
||||
ss << "channel " << channel->getChannelName() << " EasyPutGet::getGet " << status.getMessage();
|
||||
throw std::runtime_error(ss.str());
|
||||
}
|
||||
|
||||
void EasyPutGet::issueGetGet()
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyPutGet was destroyed");
|
||||
if(connectState==connectIdle) connect();
|
||||
if(putGetState!=putGetIdle) {
|
||||
stringstream ss;
|
||||
ss << "channel " << channel->getChannelName() << " EasyPutGet::issueGetGet aleady active ";
|
||||
throw std::runtime_error(ss.str());
|
||||
}
|
||||
putGetState = putGetActive;
|
||||
channelPutGet->getGet();
|
||||
}
|
||||
|
||||
Status EasyPutGet::waitGetGet()
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyPutGet was destroyed");
|
||||
if(putGetState!=putGetActive){
|
||||
stringstream ss;
|
||||
ss << "channel " << channel->getChannelName() << " EasyPutGet::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 EasyPutGet::getPut()
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyPutGet was destroyed");
|
||||
issueGetPut();
|
||||
Status status = waitGetPut();
|
||||
if(status.isOK()) return;
|
||||
stringstream ss;
|
||||
ss << "channel " << channel->getChannelName() << " EasyPutGet::getPut " << status.getMessage();
|
||||
throw std::runtime_error(ss.str());
|
||||
}
|
||||
|
||||
void EasyPutGet::issueGetPut()
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyPutGet was destroyed");
|
||||
if(connectState==connectIdle) connect();
|
||||
if(putGetState!=putGetIdle) {
|
||||
stringstream ss;
|
||||
ss << "channel " << channel->getChannelName() << " EasyPutGet::issueGetPut aleady active ";
|
||||
throw std::runtime_error(ss.str());
|
||||
}
|
||||
putGetState = putGetActive;
|
||||
channelPutGet->getPut();
|
||||
}
|
||||
|
||||
Status EasyPutGet::waitGetPut()
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyPutGet was destroyed");
|
||||
if(putGetState!=putGetActive){
|
||||
stringstream ss;
|
||||
ss << "channel " << channel->getChannelName() << " EasyPutGet::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());
|
||||
}
|
||||
|
||||
EasyGetDataPtr EasyPutGet::getGetData()
|
||||
{
|
||||
checkPutGetState();
|
||||
return easyGetData;
|
||||
}
|
||||
|
||||
EasyPutDataPtr EasyPutGet::getPutData()
|
||||
{
|
||||
checkPutGetState();
|
||||
return easyPutData;
|
||||
}
|
||||
|
||||
EasyPutGetPtr EasyPutGet::create(
|
||||
EasyPVAPtr const &pva,
|
||||
EasyChannelPtr const & easyChannel,
|
||||
Channel::shared_pointer const & channel,
|
||||
PVStructurePtr const &pvRequest)
|
||||
{
|
||||
EasyPutGetPtr epv(new EasyPutGet(pva,easyChannel,channel,pvRequest));
|
||||
return epv;
|
||||
}
|
||||
|
||||
|
||||
}}
|
@ -1,27 +1,47 @@
|
||||
TOP=..
|
||||
# Makefile for the pvAccess tests
|
||||
|
||||
TOP = ..
|
||||
include $(TOP)/configure/CONFIG
|
||||
#----------------------------------------
|
||||
# ADD MACRO DEFINITIONS AFTER THIS LINE
|
||||
|
||||
TESTPROD_HOST += testEasyPutData
|
||||
testEasyPutData_SRCS = testEasyPutData
|
||||
testHarness_SRCS += testEasyPutData.cpp
|
||||
TESTS += testEasyPutData
|
||||
|
||||
TESTPROD_HOST += testEasyGetData
|
||||
testEasyGetData_SRCS = testEasyGetData
|
||||
testHarness_SRCS += testEasyGetData.cpp
|
||||
TESTS += testEasyGetData
|
||||
|
||||
TESTPROD_HOST += testEasyMonitorData
|
||||
testEasyMonitorData_SRCS = testEasyMonitorData
|
||||
testHarness_SRCS += testEasyMonitorData.cpp
|
||||
TESTS += testEasyMonitorData
|
||||
|
||||
TESTPROD_HOST += testEasyPutGetMonitor
|
||||
testEasyPutGetMonitor_SRCS = testEasyPutGetMonitor
|
||||
testHarness_SRCS += testEasyPutGetMonitor.cpp
|
||||
TESTS += testEasyPutGetMonitor
|
||||
|
||||
TESTPROD_HOST += testEasyPutGet
|
||||
testEasyPutGet_SRCS = testEasyPutGet
|
||||
testHarness_SRCS += testEasyPutGet.cpp
|
||||
TESTS += testEasyPutGet
|
||||
|
||||
|
||||
PROD_HOST += exampleEasyPVStructure
|
||||
exampleEasyPVStructure_SRCS += exampleEasyPVStructure.cpp
|
||||
exampleEasyPVStructure_LIBS += easyPVA
|
||||
exampleEasyPVStructure_LIBS += pvAccess
|
||||
exampleEasyPVStructure_LIBS += pvData
|
||||
exampleEasyPVStructure_LIBS += Com
|
||||
PROD_LIBS += easyPVA pvAccess pvData Com
|
||||
|
||||
PROD_HOST += exampleEasyGet
|
||||
exampleEasyGet_SRCS += exampleEasyGet.cpp
|
||||
exampleEasyGet_LIBS += easyPVA
|
||||
exampleEasyGet_LIBS += pvAccess
|
||||
exampleEasyGet_LIBS += pvData
|
||||
exampleEasyGet_LIBS += 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
|
||||
#----------------------------------------
|
||||
# ADD RULES AFTER THIS LINE
|
||||
|
||||
|
27
test/src/easyAllTests.c
Normal file
27
test/src/easyAllTests.c
Normal file
@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Run EasyPVA 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 testEasyGetData(void);
|
||||
int testEasyPutData(void);
|
||||
int testEasyMonitorData(void);
|
||||
int testEasyPutGetMonitor(void);
|
||||
int testEasyPutGet(void);
|
||||
|
||||
void easyAllTests(void)
|
||||
{
|
||||
testHarness();
|
||||
runTest(testEasyGetData);
|
||||
runTest(testEasyPutData);
|
||||
runTest(testEasyMonitorData);
|
||||
runTest(testEasyPutMonitor);
|
||||
runTest(testEasyPut);
|
||||
}
|
||||
|
@ -1,91 +0,0 @@
|
||||
/*exampleEasyGet.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/easyPVA.h>
|
||||
|
||||
using namespace std;
|
||||
using namespace epics::pvData;
|
||||
using namespace epics::pvAccess;
|
||||
using namespace epics::easyPVA;
|
||||
|
||||
|
||||
static void exampleDouble(EasyPVAPtr const &easyPVA)
|
||||
{
|
||||
cout << "example double scalar\n";
|
||||
double value;
|
||||
try {
|
||||
cout << "short way\n";
|
||||
value = easyPVA->channel("exampleDouble")->get()->getDouble();
|
||||
cout << "as double " << value << endl;
|
||||
} catch (std::runtime_error e) {
|
||||
cout << "exception " << e.what() << endl;
|
||||
}
|
||||
try {
|
||||
cout << "long way\n";
|
||||
EasyChannelPtr easyChannel = easyPVA->createChannel("exampleDouble");
|
||||
easyChannel->connect(2.0);
|
||||
EasyGetPtr easyGet = easyChannel->createGet();
|
||||
value = easyGet->getDouble();
|
||||
cout << "as double " << value << endl;
|
||||
} catch (std::runtime_error e) {
|
||||
cout << "exception " << e.what() << endl;
|
||||
}
|
||||
}
|
||||
|
||||
static void exampleDoubleArray(EasyPVAPtr const &easyPVA)
|
||||
{
|
||||
cout << "example double array\n";
|
||||
shared_vector<double> value;
|
||||
try {
|
||||
cout << "short way\n";
|
||||
value = easyPVA->createChannel("exampleDoubleArray")->createGet()->getDoubleArray();
|
||||
cout << "as doubleArray " << value << endl;
|
||||
} catch (std::runtime_error e) {
|
||||
cout << "exception " << e.what() << endl;
|
||||
}
|
||||
try {
|
||||
cout << "long way\n";
|
||||
EasyChannelPtr easyChannel = easyPVA->createChannel("exampleDoubleArray");
|
||||
easyChannel->connect(2.0);
|
||||
EasyGetPtr easyGet = easyChannel->createGet();
|
||||
value = easyGet->getDoubleArray();
|
||||
cout << "as doubleArray " << value << endl;
|
||||
} catch (std::runtime_error e) {
|
||||
cout << "exception " << e.what() << endl;
|
||||
}
|
||||
}
|
||||
|
||||
static void examplePowerSupply(EasyPVAPtr const &easyPVA)
|
||||
{
|
||||
cout << "example powerSupply\n";
|
||||
PVStructurePtr pvStructure;
|
||||
try {
|
||||
cout << "short way\n";
|
||||
pvStructure = easyPVA->createChannel("examplePowerSupply")->createGet("field()")->getPVStructure();
|
||||
cout << pvStructure << endl;
|
||||
} catch (std::runtime_error e) {
|
||||
cout << "exception " << e.what() << endl;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int main(int argc,char *argv[])
|
||||
{
|
||||
EasyPVAPtr easyPVA = EasyPVA::create();
|
||||
exampleDouble(easyPVA);
|
||||
exampleDoubleArray(easyPVA);
|
||||
examplePowerSupply(easyPVA);
|
||||
cout << "done\n";
|
||||
return 0;
|
||||
}
|
@ -1,69 +0,0 @@
|
||||
/*exampleEasyPVStructure.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/easyPVA.h>
|
||||
|
||||
using namespace std;
|
||||
using namespace epics::pvData;
|
||||
using namespace epics::pvAccess;
|
||||
using namespace epics::easyPVA;
|
||||
|
||||
int main(int argc,char *argv[])
|
||||
{
|
||||
EasyPVAPtr easyPVA = EasyPVA::create();
|
||||
|
||||
StandardPVFieldPtr standardPVField = getStandardPVField();
|
||||
EasyPVStructurePtr easyStruct = easyPVA->createEasyPVStructure();
|
||||
PVStructurePtr pvStructure = standardPVField->scalar(pvDouble,"alarm,timeStamp");
|
||||
easyStruct->setPVStructure(pvStructure);
|
||||
cout << easyStruct->getPVStructure() << endl;
|
||||
cout << "as double " << easyStruct->getDouble() << endl;
|
||||
cout << "as float " << easyStruct->getFloat() << endl;
|
||||
try {
|
||||
cout << "as ubyte " << easyStruct->getUByte() << endl;
|
||||
} catch (std::runtime_error e) {
|
||||
cout << "exception " << e.what() << endl;
|
||||
}
|
||||
pvStructure = standardPVField->scalar(pvInt,"alarm,timeStamp");
|
||||
easyStruct->setPVStructure(pvStructure);
|
||||
cout << easyStruct->getPVStructure() << endl;
|
||||
cout << "as double " << easyStruct->getDouble() << endl;
|
||||
cout << "as float " << easyStruct->getFloat() << endl;
|
||||
cout << "as int " << easyStruct->getInt() << endl;
|
||||
cout << "as uint " << easyStruct->getUInt() << endl;
|
||||
cout << "as long " << easyStruct->getLong() << endl;
|
||||
cout << "as ulong " << easyStruct->getULong() << endl;
|
||||
try {
|
||||
cout << "as byte " << easyStruct->getByte() << endl;
|
||||
} catch (std::runtime_error e) {
|
||||
cout << "exception " << e.what() << endl;
|
||||
}
|
||||
try {
|
||||
cout << "as ubyte " << easyStruct->getUByte() << endl;
|
||||
} catch (std::runtime_error e) {
|
||||
cout << "exception " << e.what() << endl;
|
||||
}
|
||||
try {
|
||||
cout << "as short " << easyStruct->getShort() << endl;
|
||||
} catch (std::runtime_error e) {
|
||||
cout << "exception " << e.what() << endl;
|
||||
}
|
||||
try {
|
||||
cout << "as ushort " << easyStruct->getUShort() << endl;
|
||||
} catch (std::runtime_error e) {
|
||||
cout << "exception " << e.what() << endl;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
155
test/src/testEasyGetData.cpp
Normal file
155
test/src/testEasyGetData.cpp
Normal file
@ -0,0 +1,155 @@
|
||||
/*testEasyGetData.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/easyPVA.h>
|
||||
#include <pv/bitSet.h>
|
||||
|
||||
using namespace std;
|
||||
using namespace epics::pvData;
|
||||
using namespace epics::pvAccess;
|
||||
using namespace epics::easyPVA;
|
||||
|
||||
static EasyPVAPtr easyPVA = EasyPVA::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();
|
||||
|
||||
EasyGetDataPtr easyData = EasyGetData::create(structure);
|
||||
PVStructurePtr pvStructure = pvDataCreate->createPVStructure(easyData->getStructure());
|
||||
BitSetPtr bitSet = BitSetPtr(new BitSet(pvStructure->getNumberFields()));
|
||||
easyData->setData(pvStructure,bitSet);
|
||||
PVDoublePtr pvDouble = pvStructure->getSubField<PVDouble>("value");
|
||||
size_t valueOffset = pvDouble->getFieldOffset();
|
||||
BitSetPtr change = easyData->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(easyData->hasValue()==true,"hasValue");
|
||||
testOk(easyData->isValueScalar()==true,"isValueScalar");
|
||||
testOk(easyData->isValueScalarArray()==false,"isValueScalarArray");
|
||||
bool result;
|
||||
result = false;
|
||||
if(easyData->getValue()) result = true;
|
||||
testOk(result==true,"getValue");
|
||||
result = false;
|
||||
if(easyData->getScalarValue()) result = true;
|
||||
testOk(result==true,"getScalarValue");
|
||||
try {
|
||||
easyData->getArrayValue();
|
||||
} catch (std::runtime_error e) {
|
||||
cout << "getArrayValue " << e.what() << endl;
|
||||
}
|
||||
try {
|
||||
easyData->getScalarArrayValue();
|
||||
} catch (std::runtime_error e) {
|
||||
cout << " getScalarArrayValue " << e.what() << endl;
|
||||
}
|
||||
cout << "as double " << easyData->getDouble() << endl;
|
||||
cout << "as string " << easyData->getString() << endl;
|
||||
try {
|
||||
shared_vector<const double> value = easyData->getDoubleArray();
|
||||
} catch (std::runtime_error e) {
|
||||
cout << " getDoubleArray " << e.what() << endl;
|
||||
}
|
||||
try {
|
||||
shared_vector<const string> value = easyData->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();
|
||||
|
||||
EasyGetDataPtr easyData = EasyGetData::create(structure);
|
||||
PVStructurePtr pvStructure = pvDataCreate->createPVStructure(easyData->getStructure());
|
||||
BitSetPtr bitSet = BitSetPtr(new BitSet(pvStructure->getNumberFields()));
|
||||
easyData->setData(pvStructure,bitSet);
|
||||
PVDoubleArrayPtr pvalue = easyData->getPVStructure()->getSubField<PVDoubleArray>("value");
|
||||
BitSetPtr change = easyData->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(easyData->hasValue()==true,"hasValue");
|
||||
testOk(easyData->isValueScalar()==false,"isValueScalar");
|
||||
testOk(easyData->isValueScalarArray()==true,"isValueScalarArray");
|
||||
bool result;
|
||||
result = false;
|
||||
if(easyData->getValue()) result = true;
|
||||
testOk(result==true,"getValue");
|
||||
result = false;
|
||||
if(easyData->getArrayValue()) result = true;
|
||||
testOk(result==true,"getArrayValue");
|
||||
result = false;
|
||||
if(easyData->getScalarArrayValue()) result = true;
|
||||
testOk(result==true,"getScalarValue");
|
||||
try {
|
||||
easyData->getScalarValue();
|
||||
} catch (std::runtime_error e) {
|
||||
cout << " getScalarValue " << e.what() << endl;
|
||||
}
|
||||
try {
|
||||
cout << "as double " << easyData->getDouble() << endl;
|
||||
} catch (std::runtime_error e) {
|
||||
cout << " getDouble " << e.what() << endl;
|
||||
}
|
||||
try {
|
||||
string val = easyData->getString();
|
||||
} catch (std::runtime_error e) {
|
||||
cout << " getString " << e.what() << endl;
|
||||
}
|
||||
cout << "as doubleArray " << easyData->getDoubleArray() << endl;
|
||||
try {
|
||||
shared_vector<const string> value = easyData->getStringArray();
|
||||
} catch (std::runtime_error e) {
|
||||
cout << " getStringArray " << e.what() << endl;
|
||||
}
|
||||
}
|
||||
|
||||
MAIN(testEasyGetData)
|
||||
{
|
||||
cout << "\nstarting testEasyGetData\n";
|
||||
testPlan(15);
|
||||
testDouble();
|
||||
testDoubleArray();
|
||||
return 0;
|
||||
}
|
||||
|
153
test/src/testEasyMonitorData.cpp
Normal file
153
test/src/testEasyMonitorData.cpp
Normal file
@ -0,0 +1,153 @@
|
||||
/*testEasyMonitorData.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/easyPVA.h>
|
||||
#include <pv/bitSet.h>
|
||||
|
||||
using namespace std;
|
||||
using namespace epics::pvData;
|
||||
using namespace epics::pvAccess;
|
||||
using namespace epics::easyPVA;
|
||||
|
||||
static EasyPVAPtr easyPVA = EasyPVA::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();
|
||||
|
||||
EasyMonitorDataPtr easyData = EasyMonitorData::create(structure);
|
||||
MonitorElementPtr monitorElement(new MonitorElement(pvDataCreate->createPVStructure(easyData->getStructure())));
|
||||
easyData->setData(monitorElement);
|
||||
PVDoublePtr pvDouble = easyData->getPVStructure()->getSubField<PVDouble>("value");
|
||||
size_t valueOffset = pvDouble->getFieldOffset();
|
||||
BitSetPtr change = easyData->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(easyData->hasValue()==true,"hasValue");
|
||||
testOk(easyData->isValueScalar()==true,"isValueScalar");
|
||||
testOk(easyData->isValueScalarArray()==false,"isValueScalarArray");
|
||||
bool result;
|
||||
result = false;
|
||||
if(easyData->getValue()) result = true;
|
||||
testOk(result==true,"getValue");
|
||||
result = false;
|
||||
if(easyData->getScalarValue()) result = true;
|
||||
testOk(result==true,"getScalarValue");
|
||||
try {
|
||||
easyData->getArrayValue();
|
||||
} catch (std::runtime_error e) {
|
||||
cout << "getArrayValue " << e.what() << endl;
|
||||
}
|
||||
try {
|
||||
easyData->getScalarArrayValue();
|
||||
} catch (std::runtime_error e) {
|
||||
cout << " getScalarArrayValue " << e.what() << endl;
|
||||
}
|
||||
cout << "as double " << easyData->getDouble() << endl;
|
||||
cout << "as string " << easyData->getString() << endl;
|
||||
try {
|
||||
shared_vector<const double> value = easyData->getDoubleArray();
|
||||
} catch (std::runtime_error e) {
|
||||
cout << " getDoubleArray " << e.what() << endl;
|
||||
}
|
||||
try {
|
||||
shared_vector<const string> value = easyData->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();
|
||||
|
||||
EasyMonitorDataPtr easyData = EasyMonitorData::create(structure);
|
||||
MonitorElementPtr monitorElement(new MonitorElement(pvDataCreate->createPVStructure(easyData->getStructure())));
|
||||
easyData->setData(monitorElement);
|
||||
PVDoubleArrayPtr pvalue = easyData->getPVStructure()->getSubField<PVDoubleArray>("value");
|
||||
BitSetPtr change = easyData->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(easyData->hasValue()==true,"hasValue");
|
||||
testOk(easyData->isValueScalar()==false,"isValueScalar");
|
||||
testOk(easyData->isValueScalarArray()==true,"isValueScalarArray");
|
||||
bool result;
|
||||
result = false;
|
||||
if(easyData->getValue()) result = true;
|
||||
testOk(result==true,"getValue");
|
||||
result = false;
|
||||
if(easyData->getArrayValue()) result = true;
|
||||
testOk(result==true,"getArrayValue");
|
||||
result = false;
|
||||
if(easyData->getScalarArrayValue()) result = true;
|
||||
testOk(result==true,"getScalarValue");
|
||||
try {
|
||||
easyData->getScalarValue();
|
||||
} catch (std::runtime_error e) {
|
||||
cout << " getScalarValue " << e.what() << endl;
|
||||
}
|
||||
try {
|
||||
cout << "as double " << easyData->getDouble() << endl;
|
||||
} catch (std::runtime_error e) {
|
||||
cout << " getDouble " << e.what() << endl;
|
||||
}
|
||||
try {
|
||||
string val = easyData->getString();
|
||||
} catch (std::runtime_error e) {
|
||||
cout << " getString " << e.what() << endl;
|
||||
}
|
||||
cout << "as doubleArray " << easyData->getDoubleArray() << endl;
|
||||
try {
|
||||
shared_vector<const string> value = easyData->getStringArray();
|
||||
} catch (std::runtime_error e) {
|
||||
cout << " getStringArray " << e.what() << endl;
|
||||
}
|
||||
}
|
||||
|
||||
MAIN(testEasyMonitorData)
|
||||
{
|
||||
cout << "\nstarting testEasyMonitorData\n";
|
||||
testPlan(15);
|
||||
testDouble();
|
||||
testDoubleArray();
|
||||
return 0;
|
||||
}
|
||||
|
229
test/src/testEasyPutData.cpp
Normal file
229
test/src/testEasyPutData.cpp
Normal file
@ -0,0 +1,229 @@
|
||||
/*testEasyData.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/easyPVA.h>
|
||||
#include <pv/bitSet.h>
|
||||
|
||||
using namespace std;
|
||||
using namespace epics::pvData;
|
||||
using namespace epics::pvAccess;
|
||||
using namespace epics::easyPVA;
|
||||
|
||||
static EasyPVAPtr easyPVA = EasyPVA::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();
|
||||
|
||||
EasyPutDataPtr easyData = EasyPutData::create(structure);
|
||||
PVStructurePtr pvStructure = easyData->getPVStructure();
|
||||
BitSetPtr change = easyData->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 << easyData->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();
|
||||
|
||||
EasyPutDataPtr easyData = EasyPutData::create(structure);
|
||||
PVDoublePtr pvDouble = easyData->getPVStructure()->getSubField<PVDouble>("value");
|
||||
pvDouble->put(5.0);
|
||||
BitSetPtr change = easyData->getBitSet();
|
||||
size_t valueOffset = pvDouble->getFieldOffset();
|
||||
testOk(change->cardinality()==1,"num set bits 1");
|
||||
testOk(change->get(valueOffset)==true,"value changed");
|
||||
testOk(easyData->hasValue()==true,"hasValue");
|
||||
testOk(easyData->isValueScalar()==true,"isValueScalar");
|
||||
testOk(easyData->isValueScalarArray()==false,"isValueScalarArray");
|
||||
bool result;
|
||||
result = false;
|
||||
if(easyData->getValue()) result = true;
|
||||
testOk(result==true,"getValue");
|
||||
result = false;
|
||||
if(easyData->getScalarValue()) result = true;
|
||||
testOk(result==true,"getScalarValue");
|
||||
try {
|
||||
easyData->getArrayValue();
|
||||
} catch (std::runtime_error e) {
|
||||
cout << "getArrayValue " << e.what() << endl;
|
||||
}
|
||||
try {
|
||||
easyData->getScalarArrayValue();
|
||||
} catch (std::runtime_error e) {
|
||||
cout << " getScalarArrayValue " << e.what() << endl;
|
||||
}
|
||||
cout << "as double " << easyData->getDouble() << endl;
|
||||
cout << "as string " << easyData->getString() << endl;
|
||||
try {
|
||||
shared_vector<const double> value = easyData->getDoubleArray();
|
||||
} catch (std::runtime_error e) {
|
||||
cout << " getDoubleArray " << e.what() << endl;
|
||||
}
|
||||
try {
|
||||
shared_vector<const string> value = easyData->getStringArray();
|
||||
} catch (std::runtime_error e) {
|
||||
cout << " getStringArray " << e.what() << endl;
|
||||
}
|
||||
easyData->putDouble(5.0);
|
||||
easyData->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;
|
||||
easyData->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";
|
||||
easyData->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();
|
||||
|
||||
EasyPutDataPtr easyData = EasyPutData::create(structure);
|
||||
PVDoubleArrayPtr pvalue = easyData->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 = easyData->getBitSet();
|
||||
size_t valueOffset = pvalue->getFieldOffset();
|
||||
testOk(change->cardinality()==1,"num set bits 1");
|
||||
testOk(change->get(valueOffset)==true,"value changed");
|
||||
testOk(easyData->hasValue()==true,"hasValue");
|
||||
testOk(easyData->isValueScalar()==false,"isValueScalar");
|
||||
testOk(easyData->isValueScalarArray()==true,"isValueScalarArray");
|
||||
bool result;
|
||||
result = false;
|
||||
if(easyData->getValue()) result = true;
|
||||
testOk(result==true,"getValue");
|
||||
result = false;
|
||||
if(easyData->getArrayValue()) result = true;
|
||||
testOk(result==true,"getArrayValue");
|
||||
result = false;
|
||||
if(easyData->getScalarArrayValue()) result = true;
|
||||
testOk(result==true,"getScalarValue");
|
||||
try {
|
||||
easyData->getScalarValue();
|
||||
} catch (std::runtime_error e) {
|
||||
cout << " getScalarValue " << e.what() << endl;
|
||||
}
|
||||
try {
|
||||
cout << "as double " << easyData->getDouble() << endl;
|
||||
} catch (std::runtime_error e) {
|
||||
cout << " getDouble " << e.what() << endl;
|
||||
}
|
||||
try {
|
||||
string val = easyData->getString();
|
||||
} catch (std::runtime_error e) {
|
||||
cout << " getString " << e.what() << endl;
|
||||
}
|
||||
cout << "as doubleArray " << easyData->getDoubleArray() << endl;
|
||||
try {
|
||||
shared_vector<const string> value = easyData->getStringArray();
|
||||
} catch (std::runtime_error e) {
|
||||
cout << " getStringArray " << e.what() << endl;
|
||||
}
|
||||
try {
|
||||
easyData->putDouble(5.0);
|
||||
} catch (std::runtime_error e) {
|
||||
cout << " putDouble " << e.what() << endl;
|
||||
}
|
||||
try {
|
||||
easyData->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;
|
||||
easyData->putDoubleArray(freeze(value));
|
||||
cout << "as doubleArray " << easyData->getDoubleArray() << endl;
|
||||
try {
|
||||
size_t len = 2;
|
||||
shared_vector<string> val(len);
|
||||
val[0] = "one"; val[1] = "two";
|
||||
easyData->putStringArray(freeze(val));
|
||||
cout << "as stringArray " << val << endl;
|
||||
} catch (std::runtime_error e) {
|
||||
cout << " putStringArray " << e.what() << endl;
|
||||
}
|
||||
}
|
||||
|
||||
MAIN(testEasyPutData)
|
||||
{
|
||||
cout << "\nstarting testEasyPutData\n";
|
||||
testPlan(19);
|
||||
testPostPut();
|
||||
testDouble();
|
||||
testDoubleArray();
|
||||
return 0;
|
||||
}
|
66
test/src/testEasyPutGet.cpp
Normal file
66
test/src/testEasyPutGet.cpp
Normal file
@ -0,0 +1,66 @@
|
||||
/*exampleEasyPutGet.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/easyPVA.h>
|
||||
#include <epicsUnitTest.h>
|
||||
#include <testMain.h>
|
||||
|
||||
using namespace std;
|
||||
using namespace epics::pvData;
|
||||
using namespace epics::pvAccess;
|
||||
using namespace epics::easyPVA;
|
||||
|
||||
|
||||
static void example(EasyPVAPtr const &easyPVA)
|
||||
{
|
||||
cout << "\nstarting channelPutGet example\n";
|
||||
try {
|
||||
EasyChannelPtr easyChannel = easyPVA->createChannel("examplePowerSupply");
|
||||
easyChannel->connect(2.0);
|
||||
testOk(true==true,"connected");
|
||||
EasyPutGetPtr putGet = easyChannel->createPutGet(
|
||||
"putField(power.value,voltage.value)getField()");
|
||||
EasyPutDataPtr 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();
|
||||
EasyGetDataPtr 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(testEasyPutGet)
|
||||
{
|
||||
cout << "\nstarting testEasyPutGet\n";
|
||||
testPlan(2);
|
||||
EasyPVAPtr easyPVA = EasyPVA::create();
|
||||
example(easyPVA);
|
||||
cout << "done\n";
|
||||
return 0;
|
||||
}
|
89
test/src/testEasyPutGetMonitor.cpp
Normal file
89
test/src/testEasyPutGetMonitor.cpp
Normal file
@ -0,0 +1,89 @@
|
||||
/*exampleEasyPutGetMonitor.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/easyPVA.h>
|
||||
#include <epicsUnitTest.h>
|
||||
#include <testMain.h>
|
||||
|
||||
using namespace std;
|
||||
using namespace epics::pvData;
|
||||
using namespace epics::pvAccess;
|
||||
using namespace epics::easyPVA;
|
||||
|
||||
|
||||
class MyMonitor : public EasyMonitorRequester
|
||||
{
|
||||
public:
|
||||
MyMonitor() {}
|
||||
virtual ~MyMonitor() {}
|
||||
virtual void event(EasyMonitorPtr monitor)
|
||||
{
|
||||
while(true) {
|
||||
if(!monitor->poll()) return;
|
||||
EasyMonitorDataPtr easyData = monitor->getData();
|
||||
cout << "changed\n";
|
||||
easyData->showChanged(cout);
|
||||
cout << "overrun\n";
|
||||
easyData->showOverrun(cout);
|
||||
monitor->releaseEvent();
|
||||
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
static void exampleDouble(EasyPVAPtr const &easyPVA)
|
||||
{
|
||||
cout << "\nstarting exampleDouble\n";
|
||||
try {
|
||||
cout << "long way\n";
|
||||
EasyChannelPtr easyChannel = easyPVA->createChannel("exampleDouble");
|
||||
easyChannel->connect(2.0);
|
||||
testOk(true==true,"connected");
|
||||
EasyPutPtr put = easyChannel->createPut();
|
||||
EasyPutDataPtr putData = put->getData();
|
||||
testOk(true==true,"put connected");
|
||||
EasyGetPtr get = easyChannel->createGet();
|
||||
EasyGetDataPtr getData = get->getData();
|
||||
testOk(true==true,"get connected");
|
||||
EasyMonitorRequesterPtr requester(new MyMonitor());
|
||||
EasyMonitorPtr monitor = easyChannel->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;
|
||||
}
|
||||
EasyProcessPtr process = easyChannel->createProcess();
|
||||
process->connect();
|
||||
process->process();
|
||||
} catch (std::runtime_error e) {
|
||||
cout << "exception " << e.what() << endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
MAIN(testEasyPutGetMonitor)
|
||||
{
|
||||
cout << "\nstarting testEasyPutGetMonitor\n";
|
||||
testPlan(4);
|
||||
EasyPVAPtr easyPVA = EasyPVA::create();
|
||||
exampleDouble(easyPVA);
|
||||
cout << "done\n";
|
||||
return 0;
|
||||
}
|
Reference in New Issue
Block a user