From 4b3e6c641b7b11253d3ca717d9b5676551093f2c Mon Sep 17 00:00:00 2001
From: mrkraimer
Date: Fri, 31 Jul 2015 15:46:22 -0400
Subject: [PATCH 1/2] added support for multi channel double
---
example/src/Makefile | 7 +
example/src/examplePvaClientMonitor.cpp | 29 +-
example/src/examplePvaClientMultiDouble.cpp | 79 +++++
example/src/examplePvaClientPut.cpp | 9 +
src/Makefile | 5 +
src/pvaClientMultiChannel.cpp | 185 +++++++++++
src/pvaClientMultiChannel.h | 331 ++++++++++++++++++++
src/pvaClientMultiGetDouble.cpp | 130 ++++++++
src/pvaClientMultiMonitorDouble.cpp | 142 +++++++++
src/pvaClientMultiPutDouble.cpp | 121 +++++++
10 files changed, 1027 insertions(+), 11 deletions(-)
create mode 100644 example/src/examplePvaClientMultiDouble.cpp
create mode 100644 src/pvaClientMultiChannel.cpp
create mode 100644 src/pvaClientMultiChannel.h
create mode 100644 src/pvaClientMultiGetDouble.cpp
create mode 100644 src/pvaClientMultiMonitorDouble.cpp
create mode 100644 src/pvaClientMultiPutDouble.cpp
diff --git a/example/src/Makefile b/example/src/Makefile
index d80136b..4f48aaf 100644
--- a/example/src/Makefile
+++ b/example/src/Makefile
@@ -33,6 +33,13 @@ examplePvaClientMonitor_LIBS += pvAccess
examplePvaClientMonitor_LIBS += pvData
examplePvaClientMonitor_LIBS += Com
+PROD_HOST += examplePvaClientMultiDouble
+examplePvaClientMultiDouble_SRCS += examplePvaClientMultiDouble.cpp
+examplePvaClientMultiDouble_LIBS += pvaClient
+examplePvaClientMultiDouble_LIBS += pvAccess
+examplePvaClientMultiDouble_LIBS += pvData
+examplePvaClientMultiDouble_LIBS += Com
+
PROD_HOST += helloWorldRPC
helloWorldRPC_SRCS += helloWorldRPC.cpp
helloWorldRPC_LIBS += pvaClient
diff --git a/example/src/examplePvaClientMonitor.cpp b/example/src/examplePvaClientMonitor.cpp
index 1d60295..5e996c3 100644
--- a/example/src/examplePvaClientMonitor.cpp
+++ b/example/src/examplePvaClientMonitor.cpp
@@ -22,25 +22,29 @@ using namespace epics::pvAccess;
using namespace epics::pvaClient;
-static void exampleMonitor(PvaClientPtr const &pva)
+static void exampleMonitor(PvaClientPtr const &pva,string provider)
{
- PvaClientMonitorPtr monitor = pva->channel("exampleDouble")->monitor("");
- PvaClientMonitorDataPtr pvaData = monitor->getData();
- PvaClientPutPtr put = pva->channel("exampleDouble")->put("");
+ PvaClientMonitorPtr monitor = pva->channel("double00",provider,2.0)->monitor("");
+ PvaClientMonitorDataPtr monitorData = monitor->getData();
+ PvaClientPutPtr put = pva->channel("double00",provider,2.0)->put("");
PvaClientPutDataPtr putData = put->getData();
for(size_t ntimes=0; ntimes<5; ++ntimes)
{
double value = ntimes;
+ cout << "put " << value << endl;
putData->putDouble(value); put->put();
- if(!monitor->waitEvent()) {
+ if(!monitor->waitEvent(.1)) {
cout << "waitEvent returned false. Why???";
continue;
+ } else while(true) {
+ cout << "monitor " << monitorData->getDouble() << endl;
+ cout << "changed\n";
+ monitorData->showChanged(cout);
+ cout << "overrun\n";
+ monitorData->showOverrun(cout);
+ monitor->releaseEvent();
+ if(!monitor->poll()) break;
}
- cout << "changed\n";
- pvaData->showChanged(cout);
- cout << "overrun\n";
- pvaData->showOverrun(cout);
- monitor->releaseEvent();
}
}
@@ -48,7 +52,10 @@ static void exampleMonitor(PvaClientPtr const &pva)
int main(int argc,char *argv[])
{
PvaClientPtr pva = PvaClient::create();
- exampleMonitor(pva);
+ cout << "exampleMonitor pva\n";
+ exampleMonitor(pva,"pva");
+ cout << "exampleMonitor ca\n";
+ exampleMonitor(pva,"ca");
cout << "done\n";
return 0;
}
diff --git a/example/src/examplePvaClientMultiDouble.cpp b/example/src/examplePvaClientMultiDouble.cpp
new file mode 100644
index 0000000..2c5b986
--- /dev/null
+++ b/example/src/examplePvaClientMultiDouble.cpp
@@ -0,0 +1,79 @@
+/*examplePvaClientMultiDouble.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
+
+#include
+
+using namespace std;
+using namespace epics::pvData;
+using namespace epics::pvAccess;
+using namespace epics::pvaClient;
+
+static void example(
+ PvaClientPtr const &pva,
+ string provider,
+ shared_vector const &channelNames)
+{
+
+ size_t num = channelNames.size();
+cout << "num " << num << " names " << channelNames << endl;
+ PvaClientMultiChannelPtr multiChannel(
+ PvaClientMultiChannel::create(pva,channelNames,provider));
+ PvaClientMultiGetDoublePtr multiGet(multiChannel->createGet());
+ PvaClientMultiPutDoublePtr multiPut(multiChannel->createPut());
+ PvaClientMultiMonitorDoublePtr multiMonitor(multiChannel->createMonitor());
+ shared_vector data(num,0);
+ for(double value = 0.0; value< 1.0; value+= .2) {
+ try {
+ for(size_t i=0; iput(data);
+ data = multiGet->get();
+ cout << "get " << data << endl;
+ bool result = multiMonitor->waitEvent(.1);
+ while(result) {
+ cout << "monitor data " << multiMonitor->get() << endl;
+ result = multiMonitor->poll();
+ }
+ } catch (std::runtime_error e) {
+ cout << "exception " << e.what() << endl;
+ }
+ }
+}
+
+int main(int argc,char *argv[])
+{
+ PvaClientPtr pva = PvaClient::create();
+ size_t num = 5;
+ shared_vector channelNames(num);
+ channelNames[0] = "double01";
+ channelNames[1] = "double02";
+ channelNames[2] = "double03";
+ channelNames[3] = "double04";
+ channelNames[4] = "double05";
+ cout << "double pva\n";
+ shared_vector names(freeze(channelNames));
+ example(pva,"pva",names);
+ cout << "double ca\n";
+ example(pva,"ca",names);
+ channelNames = shared_vector(num);
+ channelNames[0] = "exampleDouble01";
+ channelNames[1] = "exampleDouble02";
+ channelNames[2] = "exampleDouble03";
+ channelNames[3] = "exampleDouble04";
+ channelNames[4] = "exampleDouble05";
+ names = freeze(channelNames);
+ cout << "exampleDouble pva\n";
+ example(pva,"pva",names);
+ return 0;
+}
diff --git a/example/src/examplePvaClientPut.cpp b/example/src/examplePvaClientPut.cpp
index a7f87e1..c6202be 100644
--- a/example/src/examplePvaClientPut.cpp
+++ b/example/src/examplePvaClientPut.cpp
@@ -26,11 +26,20 @@ static void examplePut(PvaClientPtr const &pva)
PvaClientChannelPtr channel = pva->channel("exampleDouble");
PvaClientPutPtr put = channel->put();
PvaClientPutDataPtr putData = put->getData();
+ PvaClientMonitorPtr monitor = pva->channel("exampleDouble")->monitor("");
+ PvaClientMonitorDataPtr monitorData = monitor->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;
+ if(!monitor->waitEvent()) {
+ cout << "waitEvent returned false. Why???";
+ } else while(true) {
+ cout << "monitor changed\n" << monitorData->showChanged(cout);
+ monitor->releaseEvent();
+ if(!monitor->poll()) break;
+ }
} catch (std::runtime_error e) {
cout << "exception " << e.what() << endl;
}
diff --git a/src/Makefile b/src/Makefile
index 8249b7d..8a23f7a 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -6,6 +6,7 @@ include $(TOP)/configure/CONFIG
LIBRARY += pvaClient
INC += pvaClient.h
+INC += pvaClientMultiChannel.h
LIBSRCS += pvaClient.cpp
LIBSRCS += pvaClientPutData.cpp
@@ -17,6 +18,10 @@ LIBSRCS += pvaClientGet.cpp
LIBSRCS += pvaClientPut.cpp
LIBSRCS += pvaClientMonitor.cpp
LIBSRCS += pvaClientPutGet.cpp
+LIBSRCS += pvaClientMultiChannel.cpp
+LIBSRCS += pvaClientMultiGetDouble.cpp
+LIBSRCS += pvaClientMultiPutDouble.cpp
+LIBSRCS += pvaClientMultiMonitorDouble.cpp
pvaClient_LIBS += pvAccess pvData nt Com
pvaClient_LIBS += $(EPICS_BASE_IOC_LIBS)
diff --git a/src/pvaClientMultiChannel.cpp b/src/pvaClientMultiChannel.cpp
new file mode 100644
index 0000000..3e3f2e7
--- /dev/null
+++ b/src/pvaClientMultiChannel.cpp
@@ -0,0 +1,185 @@
+/* pvaClientMultiChannel.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
+
pvaClientChannel provides many "convenience" methods to directly get and put
scalar and scalarArray data types.
Additional methods provide access to the full features of pvAccess.
@@ -111,26 +112,13 @@ href="./html/index.html">doxygenDoc
Example Database
-The examples require that an example pvAccess server is runnimg.
-To get the test database go to:
-pvaClientTestCPP/database.zip
-
-Then select "raw file" and You will be able to download the zip file.
-
-When unzipped this is used to create an example IOC database.
-
-
-After unzipping the file:
-
+The examples require that the database provided by project pvaClientTestCPP
+is running.
+For example:
-cd database/configure
-cp ExampleRELEASE.local RELEASE.local
-edit RELEASE.local
-cd ..
-make
-cd iocBoot/exampleDatabase
-../../bin/<arch:>/exampleDatabase st.cmd
+mrk> pwd
+/home/epicsv4/pvaClientTestCPP/database/iocBoot/exampleDatabase
+mrk> ../../bin/linux-x86_64/exampleDatabase st.cmd
Examples
Examples are in directory example/src.
@@ -172,24 +160,19 @@ helps to also look at the source for the example.
examplePvaClientMonitor
This is an example of creating a monitor on a channel.
-It monitors a channel that models a powerSupply, i. e. it is not a "standard" record.
-It does not have a value field.
+It monitors a scalar double field.
+It also issues puts to the same channel so that it can make the monitors occur.
-After starting the example a change can be made to the powerSupply by issuing:
-
-pvput -r "power.value,voltage.value" examplePowerSupply 6 6
-
examplePvaClientPut
-This example gets and puts to channel exampleDouble.
+This example gets and puts to channels exampleDouble
+and exampleDoubleArray.
examplePvaClientProcess
This example makes a process request to channel exampleDouble.
helloWorldPutGet
This is an example of issuing a channelPutGet.
examplePvaClientMultiDouble
-This is an example of issuing gets and puts to multiple channels where each
-channel has a numeric scalar value field.
-examplePvaClientNTMultiChannel
-This is an example of using NDMultiChannel to obtain data from multiple channels.
+
This is an example of using pvaClientMultiChannel,
+pvaClientMultiGetDouble, pvaClientMultiPutDouble, and pvaClientMultiMonitorDouble.
helloWorldRPC
This is an example of issuing a channelRPC request.
diff --git a/documentation/pvaClientOverview.html b/documentation/pvaClientOverview.html
index 76c1a1b..9b2cc01 100644
--- a/documentation/pvaClientOverview.html
+++ b/documentation/pvaClientOverview.html
@@ -297,23 +297,15 @@ It has methods:
PvaClientMultiChannel - Wrapper For Multiple Channels
PvaClientMultiChannel
This provides methods for connecting to multiple channels.
-A client can either use PvaClientMultiChannel directly or use PvaClientMultiDouble or PvaClientNTMultiChannel.
-But both impose restrictions on what can be accessed.
-PvaClientMultiDouble
-This provides support for gets and puts to the value field of multiple channels.
-Each channel must have a value field that is a numeric scalar.
-The client always sees the data as a PVDoubleArray.
-All channels must connect.
-If any problems occur an exception is thrown.
+
PvaClientMultiGetDouble
+This provides support for channelGet to multiple channels.
-PvaClientNTMultiChannel
-This provides support for gets and puts to the value field of multiple channels.
-Each channel must have a value field.
-The client always sees the data as a NTMultiChannel, which is one
-of the types provided by normativeTypesCPP.
-All channels must connect.
-If any problems occur an exception is thrown.
+
PvaClientMultiPutDouble
+This provides support for channelPut to multiple channels.
+
+PvaClientMultiMonitorDouble
+This provides support for monitoring changes to multiple channels.