more getme.cpp
This commit is contained in:
@@ -877,7 +877,7 @@ EXCLUDE_SYMBOLS =
|
||||
# that contain example code fragments that are included (see the \include
|
||||
# command).
|
||||
|
||||
EXAMPLE_PATH =
|
||||
EXAMPLE_PATH = ../examples
|
||||
|
||||
# If the value of the EXAMPLE_PATH tag contains directories, you can use the
|
||||
# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
|
||||
all: gen commit
|
||||
all: gen
|
||||
|
||||
clean:
|
||||
rm -rf doxygen_sqlite3.db html
|
||||
@@ -7,7 +7,7 @@ clean:
|
||||
gen:
|
||||
doxygen
|
||||
|
||||
commit:
|
||||
commit: gen
|
||||
touch html/.nojekyll
|
||||
./commit-gh.sh documentation/html/ html/.nojekyll html/*.* html/search/*.*
|
||||
|
||||
|
||||
10
documentation/examples.h
Normal file
10
documentation/examples.h
Normal file
@@ -0,0 +1,10 @@
|
||||
/**
|
||||
|
||||
@page examples_getme Client Get Example
|
||||
|
||||
This example demonstrates a client which issues a Get operation on startup,
|
||||
and again each time a channel becomes Connected.
|
||||
|
||||
@include getme.cpp
|
||||
|
||||
*/
|
||||
@@ -12,6 +12,10 @@ See pv/pvAccess.h
|
||||
|
||||
See the @ref providers page.
|
||||
|
||||
Examples
|
||||
|
||||
- @ref examples_getme
|
||||
|
||||
*/
|
||||
|
||||
#endif /* MAINPAGE_H */
|
||||
|
||||
@@ -1,12 +1,23 @@
|
||||
|
||||
#include <set>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <exception>
|
||||
|
||||
#if !defined(_WIN32)
|
||||
#include <signal.h>
|
||||
#define USE_SIGNAL
|
||||
#endif
|
||||
|
||||
#include <epicsExit.h>
|
||||
#include <epicsEvent.h>
|
||||
|
||||
//! [Headers]
|
||||
#include <pv/configuration.h>
|
||||
#include <pv/pvAccess.h>
|
||||
#include <pv/clientFactory.h>
|
||||
#include <pv/caProvider.h>
|
||||
//! [Headers]
|
||||
|
||||
namespace pvd = epics::pvData;
|
||||
namespace pva = epics::pvAccess;
|
||||
@@ -15,6 +26,19 @@ namespace {
|
||||
|
||||
epicsEvent done;
|
||||
|
||||
#ifdef USE_SIGNAL
|
||||
void alldone(int num)
|
||||
{
|
||||
(void)num;
|
||||
done.signal();
|
||||
}
|
||||
#endif
|
||||
|
||||
void onthewayout(void* arg) {
|
||||
(void)arg;
|
||||
std::cout<<"Done\n";
|
||||
}
|
||||
|
||||
struct ChanReq : public pva::ChannelRequester
|
||||
{
|
||||
virtual ~ChanReq() {}
|
||||
@@ -22,7 +46,9 @@ struct ChanReq : public pva::ChannelRequester
|
||||
virtual std::string getRequesterName() { return "ChanReq"; }
|
||||
|
||||
virtual void channelCreated(const epics::pvData::Status& status,
|
||||
pva::Channel::shared_pointer const & channel) {
|
||||
pva::Channel::shared_pointer const & channel)
|
||||
{
|
||||
// called once, recursively during ChannelProvider::createChannel()
|
||||
if(!status.isSuccess()) {
|
||||
std::cout<<"Oops Connect: "<<status<<"\n";
|
||||
} else {
|
||||
@@ -31,13 +57,15 @@ struct ChanReq : public pva::ChannelRequester
|
||||
}
|
||||
|
||||
virtual void channelStateChange(pva::Channel::shared_pointer const & channel,
|
||||
pva::Channel::ConnectionState connectionState) {
|
||||
pva::Channel::ConnectionState connectionState)
|
||||
{
|
||||
// Called for each connect/disconnect event, and on shutdown (destroy)
|
||||
switch(connectionState) {
|
||||
case pva::Channel::NEVER_CONNECTED:
|
||||
case pva::Channel::CONNECTED:
|
||||
case pva::Channel::DISCONNECTED:
|
||||
case pva::Channel::DESTROYED:
|
||||
std::cout<<channel->getChannelName()<<" "<<pva::Channel::ConnectionStateNames[connectionState]<<"\n";
|
||||
std::cout<<"CHANNEL "<<channel->getChannelName()<<" "<<pva::Channel::ConnectionStateNames[connectionState]<<"\n";
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -57,20 +85,29 @@ struct GetReq : public pva::ChannelGetRequester
|
||||
pva::ChannelGet::shared_pointer const & channelGet,
|
||||
pvd::Structure::const_shared_pointer const & structure)
|
||||
{
|
||||
// Called each time get operation becomes "ready" (channel connected)
|
||||
if(status.isSuccess()) {
|
||||
std::cout<<"Get request"<<channelGet->getChannel()->getChannelName()<<"\n";
|
||||
std::cout<<"Get execute "<<channelGet->getChannel()->getChannelName()<<"\n";
|
||||
// can now execute the get operation
|
||||
channelGet->get();
|
||||
} else {
|
||||
std::cout<<"Oops GetConnect: "<<channelGet->getChannel()->getChannelName()<<" "<<status<<"\n";
|
||||
}
|
||||
}
|
||||
|
||||
virtual void channelDisconnect(bool destroy) {
|
||||
// Called each time operation becomes no "ready" (channel disconnected)
|
||||
// same as channelStateChange() for DISCONNECTED and DESTROYED
|
||||
std::cout<<"Get disconnected\n";
|
||||
}
|
||||
|
||||
virtual void getDone(
|
||||
const epics::pvData::Status& status,
|
||||
pva::ChannelGet::shared_pointer const & channelGet,
|
||||
pvd::PVStructure::shared_pointer const & pvStructure,
|
||||
pvd::BitSet::shared_pointer const & bitSet)
|
||||
{
|
||||
// when execution completes
|
||||
if(status.isSuccess()) {
|
||||
pvd::PVFieldPtr valfld(pvStructure->getSubField("value"));
|
||||
if(!valfld)
|
||||
@@ -86,33 +123,75 @@ struct GetReq : public pva::ChannelGetRequester
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
try {
|
||||
// an empty structure
|
||||
pvd::PVStructurePtr pvReq(pvd::getPVDataCreate()->createPVStructure(
|
||||
pvd::getFieldCreate()->createFieldBuilder()->createStructure()
|
||||
));
|
||||
std::string providerName("pva");
|
||||
typedef std::vector<std::string> pvs_t;
|
||||
pvs_t pvs;
|
||||
|
||||
for(int i=1; i<argc; i++) {
|
||||
if(argv[i][0]=='-') {
|
||||
if(strcmp(argv[i], "-P")==0 || strcmp(argv[i], "--provider")==0) {
|
||||
if(i<argc-1) {
|
||||
providerName = argv[i+1];
|
||||
} else {
|
||||
std::cerr << "--provider requires value\n";
|
||||
return 1;
|
||||
}
|
||||
} else {
|
||||
std::cerr<<"Unknown argument: "<<argv[i]<<"\n";
|
||||
}
|
||||
|
||||
} else {
|
||||
pvs.push_back(argv[i]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
epicsAtExit(&onthewayout, 0);
|
||||
|
||||
#ifdef USE_SIGNAL
|
||||
signal(SIGINT, alldone);
|
||||
signal(SIGTERM, alldone);
|
||||
signal(SIGQUIT, alldone);
|
||||
#endif
|
||||
|
||||
// build "pvRequest" which asks for all fields
|
||||
pvd::PVStructure::shared_pointer pvReq(pvd::createRequest("field()"));
|
||||
|
||||
// explicitly select configuration from process environment
|
||||
pva::Configuration::shared_pointer conf(pva::ConfigurationBuilder()
|
||||
.push_env()
|
||||
.build());
|
||||
|
||||
// add "pva" provider to registry
|
||||
pva::ClientFactory::start();
|
||||
// add "ca" provider to registry
|
||||
pva::ca::CAClientFactory::start();
|
||||
|
||||
pva::ChannelProvider::shared_pointer provider(pva::getChannelProviderRegistry()->createProvider("pva", conf));
|
||||
std::cout<<"Use provider: "<<providerName<<"\n";
|
||||
pva::ChannelProvider::shared_pointer provider(pva::getChannelProviderRegistry()->createProvider(providerName, conf));
|
||||
if(!provider)
|
||||
throw std::logic_error("pva provider not registered");
|
||||
|
||||
// need to store references to keep get (and channel) from being closed
|
||||
typedef std::set<pva::ChannelGet::shared_pointer> gets_t;
|
||||
gets_t gets;
|
||||
|
||||
// as we have no channel or operation specific data,
|
||||
// use the same requesters for all PVs
|
||||
pva::ChannelRequester::shared_pointer chanreq(new ChanReq);
|
||||
pva::ChannelGetRequester::shared_pointer getreq(new GetReq);
|
||||
|
||||
for(int i=1; i<argc; i++) {
|
||||
if(argv[i][0]=='-') continue;
|
||||
pva::Channel::shared_pointer chan(provider->createChannel(argv[i], chanreq));
|
||||
for(pvs_t::const_iterator it=pvs.begin(); it!=pvs.end(); ++it) {
|
||||
const std::string& pv = *it;
|
||||
|
||||
pva::Channel::shared_pointer chan(provider->createChannel(pv, chanreq));
|
||||
// if !chan then channelCreated() called with error status
|
||||
if(!chan) continue;
|
||||
|
||||
// no need to wait for connection
|
||||
|
||||
pva::ChannelGet::shared_pointer op(chan->createChannelGet(getreq, pvReq));
|
||||
// if !op then channelGetConnect() called with error status
|
||||
if(!op) continue;
|
||||
|
||||
gets.insert(op);
|
||||
|
||||
Reference in New Issue
Block a user