addded caching of EasyChannel and EasyGet; more work on lifecycle; EasyPut next
This commit is contained in:
5
Makefile
5
Makefile
@ -3,7 +3,10 @@ TOP = .
|
||||
include $(TOP)/configure/CONFIG
|
||||
DIRS := $(DIRS) $(filter-out $(DIRS), configure)
|
||||
DIRS := $(DIRS) $(filter-out $(DIRS), src)
|
||||
DIRS := $(DIRS) $(filter-out $(DIRS), test)
|
||||
DIRS := $(DIRS) $(filter-out $(DIRS), example)
|
||||
|
||||
EMBEDDED_TOPS := $(EMBEDDED_TOPS) $(filter-out $(EMBEDDED_TOPS), test)
|
||||
EMBEDDED_TOPS := $(EMBEDDED_TOPS) $(filter-out $(EMBEDDED_TOPS), example)
|
||||
|
||||
define DIR_template
|
||||
@ -16,5 +19,7 @@ define EMB_template
|
||||
endef
|
||||
$(foreach dir, $(EMBEDDED_TOPS),$(eval $(call EMB_template,$(dir))))
|
||||
|
||||
#exampleDatabase_DEPEND_DIRS += test
|
||||
#examplePowerSupply_DEPEND_DIRS += test
|
||||
|
||||
include $(TOP)/configure/RULES_TOP
|
||||
|
@ -107,7 +107,53 @@ an interface to many of the features provided by pvData and pvAccess.</p>
|
||||
<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>
|
||||
|
||||
@ -233,6 +279,8 @@ mrk> bin/linux-x86_64/exampleEasyGet
|
||||
See the source code for each example.
|
||||
</p>
|
||||
|
||||
|
||||
|
||||
</div> <!-- class="contents" -->
|
||||
</body>
|
||||
</html>
|
||||
|
@ -5,13 +5,6 @@ include $(TOP)/configure/CONFIG
|
||||
# ADD MACRO DEFINITIONS AFTER THIS LINE
|
||||
|
||||
|
||||
PROD_HOST += exampleEasyPVStructure
|
||||
exampleEasyPVStructure_SRCS += exampleEasyPVStructure.cpp
|
||||
exampleEasyPVStructure_LIBS += easyPVA
|
||||
exampleEasyPVStructure_LIBS += pvAccess
|
||||
exampleEasyPVStructure_LIBS += pvData
|
||||
exampleEasyPVStructure_LIBS += Com
|
||||
|
||||
PROD_HOST += exampleEasyGet
|
||||
exampleEasyGet_SRCS += exampleEasyGet.cpp
|
||||
exampleEasyGet_LIBS += easyPVA
|
||||
|
@ -19,32 +19,32 @@ using namespace epics::pvData;
|
||||
using namespace epics::pvAccess;
|
||||
using namespace epics::easyPVA;
|
||||
|
||||
static EasyPVAPtr easyPVA;
|
||||
|
||||
static void exampleDouble()
|
||||
static void exampleDouble(EasyPVAPtr const &easyPVA)
|
||||
{
|
||||
cout << "example double scalar\n";
|
||||
double value;
|
||||
try {
|
||||
cout << "short way\n";
|
||||
value = easyPVA->createChannel("exampleDouble")->createGet()->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();
|
||||
value = easyPVA->channel("exampleDouble")->get()->getDouble();
|
||||
cout << "as double " << value << endl;
|
||||
} catch (std::runtime_error e) {
|
||||
cout << "exception " << e.what() << endl;
|
||||
}
|
||||
cout << "long way\n";
|
||||
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;
|
||||
}
|
||||
|
||||
static void exampleDoubleArray()
|
||||
static void exampleDoubleArray(EasyPVAPtr const &easyPVA)
|
||||
{
|
||||
cout << "example double array\n";
|
||||
shared_vector<double> value;
|
||||
@ -67,7 +67,7 @@ static void exampleDoubleArray()
|
||||
}
|
||||
}
|
||||
|
||||
static void examplePowerSupply()
|
||||
static void examplePowerSupply(EasyPVAPtr const &easyPVA)
|
||||
{
|
||||
cout << "example powerSupply\n";
|
||||
PVStructurePtr pvStructure;
|
||||
@ -83,11 +83,10 @@ static void examplePowerSupply()
|
||||
|
||||
int main(int argc,char *argv[])
|
||||
{
|
||||
easyPVA = EasyPVA::create();
|
||||
exampleDouble();
|
||||
exampleDoubleArray();
|
||||
examplePowerSupply();
|
||||
EasyPVAPtr easyPVA = EasyPVA::create();
|
||||
exampleDouble(easyPVA);
|
||||
exampleDoubleArray(easyPVA);
|
||||
examplePowerSupply(easyPVA);
|
||||
cout << "done\n";
|
||||
easyPVA->destroy();
|
||||
return 0;
|
||||
}
|
||||
|
@ -10,6 +10,7 @@
|
||||
*/
|
||||
#define epicsExportSharedSymbols
|
||||
|
||||
#include <map>
|
||||
#include <sstream>
|
||||
#include <pv/event.h>
|
||||
#include <pv/lock.h>
|
||||
@ -24,6 +25,41 @@ using namespace std;
|
||||
|
||||
namespace epics { namespace easyPVA {
|
||||
|
||||
class EasyGetCache;
|
||||
typedef std::tr1::shared_ptr<EasyGetCache> EasyGetCachePtr;
|
||||
|
||||
class EasyGetCache
|
||||
{
|
||||
public:
|
||||
EasyGetCache(){}
|
||||
~EasyGetCache();
|
||||
void destroy() {
|
||||
easyGetMap.clear();
|
||||
}
|
||||
EasyGetPtr getGet(string const & request);
|
||||
void addGet(string const & request,EasyGetPtr const & easyGet);
|
||||
private:
|
||||
map<string,EasyGetPtr> easyGetMap;
|
||||
};
|
||||
|
||||
EasyGetCache::~EasyGetCache()
|
||||
{
|
||||
destroy();
|
||||
}
|
||||
|
||||
EasyGetPtr EasyGetCache::getGet(string const & request)
|
||||
{
|
||||
map<string,EasyGetPtr>::iterator iter = easyGetMap.find(request);
|
||||
if(iter!=easyGetMap.end()) return iter->second;
|
||||
return EasyGetPtr();
|
||||
}
|
||||
|
||||
void EasyGetCache::addGet(string const & request,EasyGetPtr const & easyGet)
|
||||
{
|
||||
easyGetMap.insert(std::pair<string,EasyGetPtr>(
|
||||
request,easyGet));
|
||||
}
|
||||
|
||||
class epicsShareClass EasyChannelImpl :
|
||||
public EasyChannel,
|
||||
public std::tr1::enable_shared_from_this<EasyChannelImpl>
|
||||
@ -33,7 +69,7 @@ public:
|
||||
EasyPVAPtr const &pva,
|
||||
string const & channelName,
|
||||
string const & providerName);
|
||||
~EasyChannelImpl();
|
||||
virtual ~EasyChannelImpl();
|
||||
// from EasyChannel
|
||||
void channelCreated(const Status& status, Channel::shared_pointer const & channel);
|
||||
void channelStateChange(
|
||||
@ -54,6 +90,8 @@ public:
|
||||
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);
|
||||
@ -79,13 +117,14 @@ public:
|
||||
}
|
||||
private:
|
||||
enum ConnectState {connectIdle,connectActive,notConnected,connected};
|
||||
|
||||
EasyPVAPtr easyPVA;
|
||||
|
||||
EasyPVA::weak_pointer easyPVA;
|
||||
string channelName;
|
||||
string providerName;
|
||||
ConnectState connectState;
|
||||
bool isDestroyed;
|
||||
CreateRequest::shared_pointer createRequest;
|
||||
EasyGetCachePtr easyGetCache;
|
||||
|
||||
Status channelConnectStatus;
|
||||
Mutex mutex;
|
||||
@ -132,7 +171,8 @@ EasyChannelImpl::EasyChannelImpl(
|
||||
providerName(providerName),
|
||||
connectState(connectIdle),
|
||||
isDestroyed(false),
|
||||
createRequest(CreateRequest::create())
|
||||
createRequest(CreateRequest::create()),
|
||||
easyGetCache(new EasyGetCache())
|
||||
{}
|
||||
|
||||
EasyChannelImpl::~EasyChannelImpl()
|
||||
@ -177,7 +217,9 @@ tr1::shared_ptr<Channel> EasyChannelImpl::getChannel()
|
||||
|
||||
string EasyChannelImpl::getRequesterName()
|
||||
{
|
||||
return easyPVA->getRequesterName();
|
||||
EasyPVAPtr yyy = easyPVA.lock();
|
||||
if(!yyy) throw std::runtime_error("EasyPVA was destroyed");
|
||||
return yyy->getRequesterName();
|
||||
}
|
||||
|
||||
void EasyChannelImpl::message(
|
||||
@ -185,7 +227,9 @@ void EasyChannelImpl::message(
|
||||
MessageType messageType)
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyChannel was destroyed");
|
||||
easyPVA->message(message, messageType);
|
||||
EasyPVAPtr yyy = easyPVA.lock();
|
||||
if(!yyy) throw std::runtime_error("EasyPVA was destroyed");
|
||||
yyy->message(message, messageType);
|
||||
}
|
||||
|
||||
void EasyChannelImpl::destroy()
|
||||
@ -197,6 +241,7 @@ void EasyChannelImpl::destroy()
|
||||
}
|
||||
if(channel) channel->destroy();
|
||||
channel.reset();
|
||||
easyGetCache.reset();
|
||||
}
|
||||
|
||||
string EasyChannelImpl::getChannelName()
|
||||
@ -274,6 +319,17 @@ EasyProcessPtr EasyChannelImpl::createProcess(PVStructurePtr const & pvRequest)
|
||||
throw std::runtime_error("EasyChannel::createProcess not implemented");
|
||||
}
|
||||
|
||||
EasyGetPtr EasyChannelImpl::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()
|
||||
{
|
||||
return EasyChannelImpl::createGet("value,alarm,timeStamp");
|
||||
@ -295,7 +351,9 @@ EasyGetPtr EasyChannelImpl::createGet(PVStructurePtr const & pvRequest)
|
||||
{
|
||||
if(connectState!=connected) connect(5.0);
|
||||
if(connectState!=connected) throw std::runtime_error("EasyChannel::creatGet not connected");
|
||||
return EasyGetFactory::createEasyGet(easyPVA,getPtrSelf(),channel,pvRequest);
|
||||
EasyPVAPtr yyy = easyPVA.lock();
|
||||
if(!yyy) throw std::runtime_error("EasyPVA was destroyed");
|
||||
return EasyGetFactory::createEasyGet(yyy,getPtrSelf(),channel,pvRequest);
|
||||
}
|
||||
|
||||
EasyPutPtr EasyChannelImpl::createPut()
|
||||
|
@ -104,8 +104,8 @@ private:
|
||||
void checkGetState();
|
||||
enum GetConnectState {connectIdle,connectActive,connected};
|
||||
|
||||
EasyPVAPtr easyPVA;
|
||||
EasyChannelPtr easyChannel;
|
||||
EasyPVA::weak_pointer easyPVA;
|
||||
EasyChannel::weak_pointer easyChannel;
|
||||
Channel::shared_pointer channel;
|
||||
ChannelGetRequester::shared_pointer getRequester;
|
||||
PVStructurePtr pvRequest;
|
||||
@ -129,28 +129,28 @@ private:
|
||||
};
|
||||
|
||||
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);}
|
||||
};
|
||||
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;
|
||||
@ -187,13 +187,17 @@ void EasyGetImpl::checkGetState()
|
||||
// from ChannelGetRequester
|
||||
string EasyGetImpl::getRequesterName()
|
||||
{
|
||||
return easyPVA->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)
|
||||
{
|
||||
if(isDestroyed) throw std::runtime_error("easyGet was destroyed");
|
||||
easyPVA->message(message, messageType);
|
||||
EasyPVAPtr yyy = easyPVA.lock();
|
||||
if(!yyy) throw std::runtime_error("easyPVA was destroyed");
|
||||
yyy->message(message, messageType);
|
||||
}
|
||||
|
||||
void EasyGetImpl::channelGetConnect(
|
||||
|
125
src/easyPVA.cpp
125
src/easyPVA.cpp
@ -8,7 +8,9 @@
|
||||
* @author mrk
|
||||
* @date 2015.02
|
||||
*/
|
||||
#define epicsExportSharedSymbols
|
||||
|
||||
#define epicsExportSharedSymbols
|
||||
#include <map>
|
||||
#include <pv/easyPVA.h>
|
||||
#include <pv/createRequest.h>
|
||||
#include <pv/clientFactory.h>
|
||||
@ -27,35 +29,71 @@ static UnionConstPtr variantUnion = fieldCreate->createVariantUnion();
|
||||
|
||||
namespace easyPVAPvt {
|
||||
|
||||
static size_t numberEasyPVA = 0;
|
||||
static bool firstTime = true;
|
||||
static Mutex mutex;
|
||||
|
||||
class StartStopClientFactory {
|
||||
|
||||
public:
|
||||
static void EasyPVABeingConstructed()
|
||||
{
|
||||
bool saveFirst = false;
|
||||
{
|
||||
Lock xx(mutex);
|
||||
++numberEasyPVA;
|
||||
saveFirst = firstTime;
|
||||
firstTime = false;
|
||||
}
|
||||
if(saveFirst) ClientFactory::start();
|
||||
}
|
||||
|
||||
static void EasyPVABeingDestroyed() {
|
||||
size_t numLeft = 0;
|
||||
static size_t numberEasyPVA = 0;
|
||||
static bool firstTime = true;
|
||||
static Mutex mutex;
|
||||
|
||||
class StartStopClientFactory {
|
||||
public:
|
||||
static void EasyPVABeingConstructed()
|
||||
{
|
||||
Lock xx(mutex);
|
||||
--numberEasyPVA;
|
||||
numLeft = numberEasyPVA;
|
||||
bool saveFirst = false;
|
||||
{
|
||||
Lock xx(mutex);
|
||||
++numberEasyPVA;
|
||||
saveFirst = firstTime;
|
||||
firstTime = false;
|
||||
}
|
||||
if(saveFirst) ClientFactory::start();
|
||||
}
|
||||
if(numLeft<=0) ClientFactory::stop();
|
||||
|
||||
static void EasyPVABeingDestroyed() {
|
||||
size_t numLeft = 0;
|
||||
{
|
||||
Lock xx(mutex);
|
||||
--numberEasyPVA;
|
||||
numLeft = numberEasyPVA;
|
||||
}
|
||||
if(numLeft<=0) ClientFactory::stop();
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace easyPVAPvt
|
||||
|
||||
class EasyChannelCache
|
||||
{
|
||||
public:
|
||||
EasyChannelCache(){}
|
||||
~EasyChannelCache(){
|
||||
destroy();
|
||||
}
|
||||
void destroy() {
|
||||
easyChannelMap.clear();
|
||||
}
|
||||
EasyChannelPtr getChannel(string const & channelName);
|
||||
void addChannel(EasyChannelPtr const & easyChannel);
|
||||
void removeChannel(string const & channelName);
|
||||
private:
|
||||
map<string,EasyChannelPtr> easyChannelMap;
|
||||
};
|
||||
|
||||
EasyChannelPtr EasyChannelCache::getChannel(string const & channelName)
|
||||
{
|
||||
map<string,EasyChannelPtr>::iterator iter = easyChannelMap.find(channelName);
|
||||
if(iter!=easyChannelMap.end()) return iter->second;
|
||||
return EasyChannelPtr();
|
||||
}
|
||||
|
||||
void EasyChannelCache::addChannel(EasyChannelPtr const & easyChannel)
|
||||
{
|
||||
easyChannelMap.insert(std::pair<string,EasyChannelPtr>(
|
||||
easyChannel->getChannelName(),easyChannel));
|
||||
}
|
||||
|
||||
void EasyChannelCache::removeChannel(string const & channelName)
|
||||
{
|
||||
map<string,EasyChannelPtr>::iterator iter = easyChannelMap.find(channelName);
|
||||
if(iter!=easyChannelMap.end()) easyChannelMap.erase(iter);
|
||||
}
|
||||
|
||||
using namespace epics::easyPVA::easyPVAPvt;
|
||||
@ -79,7 +117,8 @@ PVStructurePtr EasyPVA::createRequest(string const &request)
|
||||
}
|
||||
|
||||
EasyPVA::EasyPVA()
|
||||
: isDestroyed(false)
|
||||
: easyChannelCache(new EasyChannelCache()),
|
||||
isDestroyed(false)
|
||||
{
|
||||
}
|
||||
|
||||
@ -94,22 +133,9 @@ void EasyPVA::destroy()
|
||||
if(isDestroyed) return;
|
||||
isDestroyed = true;
|
||||
}
|
||||
std::list<EasyChannelPtr>::iterator channelIter;
|
||||
while(true) {
|
||||
channelIter = channelList.begin();
|
||||
if(channelIter==channelList.end()) break;
|
||||
channelList.erase(channelIter);
|
||||
(*channelIter)->destroy();
|
||||
}
|
||||
#ifdef NOTDONE
|
||||
std::list<EasyMultiChannelPtr>::iterator multiChannelIter;
|
||||
while(true) {
|
||||
multiChannelIter = multiChannelList.begin();
|
||||
if(multiChannelIter==multiChannelList.end()) break;
|
||||
multiChannelList.erase(multiChannelIter);
|
||||
(*multiChannelIter)->destroy();
|
||||
}
|
||||
#endif
|
||||
easyChannelCache.reset();
|
||||
channelList.clear();
|
||||
multiChannelList.clear();
|
||||
StartStopClientFactory::EasyPVABeingDestroyed();
|
||||
}
|
||||
|
||||
@ -131,6 +157,19 @@ EasyPVStructurePtr EasyPVA::createEasyPVStructure()
|
||||
return EasyPVStructureFactory::createEasyPVStructure();
|
||||
}
|
||||
|
||||
EasyChannelPtr EasyPVA::channel(
|
||||
std::string const & channelName,
|
||||
std::string const & providerName,
|
||||
double timeOut)
|
||||
{
|
||||
EasyChannelPtr easyChannel = easyChannelCache->getChannel(channelName);
|
||||
if(easyChannel) return easyChannel;
|
||||
easyChannel = createChannel(channelName,providerName);
|
||||
easyChannel->connect(timeOut);
|
||||
easyChannelCache->addChannel(easyChannel);
|
||||
return easyChannel;
|
||||
}
|
||||
|
||||
EasyChannelPtr EasyPVA::createChannel(string const & channelName)
|
||||
{
|
||||
return EasyChannelFactory::createEasyChannel(getPtrSelf(),channelName);
|
||||
|
@ -74,6 +74,10 @@ typedef std::tr1::shared_ptr<EasyMultiPut> EasyMultiPutPtr;
|
||||
class EasyMultiMonitor;
|
||||
typedef std::tr1::shared_ptr<EasyMultiMonitor> EasyMultiMonitorPtr;
|
||||
|
||||
// following are private to easyPVA
|
||||
class EasyChannelCache;
|
||||
typedef std::tr1::shared_ptr<EasyChannelCache> EasyChannelCachePtr;
|
||||
|
||||
/**
|
||||
* @brief EasyPVA is an easy to use interface to pvAccess.
|
||||
*
|
||||
@ -89,7 +93,7 @@ public:
|
||||
/**
|
||||
* Destructor
|
||||
*/
|
||||
~EasyPVA();
|
||||
virtual ~EasyPVA();
|
||||
/**
|
||||
* @brief Create an instance of EasyPVA
|
||||
* @return shared_ptr to new instance.
|
||||
@ -119,8 +123,27 @@ public:
|
||||
* @return The interface to the EasyPVStructure.
|
||||
*/
|
||||
EasyPVStructurePtr createEasyPVStructure();
|
||||
/**
|
||||
* @brief get a cached channel or create and connect to a new channel.
|
||||
* The provider is pva. The timeout is 5 seconds.
|
||||
* If connection can not be made an exception is thrown.
|
||||
* @param channelName The channelName.
|
||||
* @return The interface.
|
||||
*/
|
||||
EasyChannelPtr channel(std::string const & channelName)
|
||||
{ return channel(channelName,"pva", 5.0); }
|
||||
/**
|
||||
* @brief Create an EasyChannel. The provider is pvAccess.
|
||||
* @brief get a cached channel or create and connect to a new channel.
|
||||
* If connection can not be made an exception is thrown.
|
||||
* @param channelName The channelName.
|
||||
* @return The interface.
|
||||
*/
|
||||
EasyChannelPtr channel(
|
||||
std::string const & channelName,
|
||||
std::string const &providerName,
|
||||
double timeOut);
|
||||
/**
|
||||
* @brief Create an EasyChannel. The provider is pva.
|
||||
* @param channelName The channelName.
|
||||
* @return The interface.
|
||||
*/
|
||||
@ -179,11 +202,12 @@ public:
|
||||
}
|
||||
private:
|
||||
EasyPVA();
|
||||
epics::pvData::PVStructurePtr createRequest(std::string const &request);
|
||||
EasyChannelCachePtr easyChannelCache;
|
||||
|
||||
epics::pvData::PVStructurePtr createRequest(std::string const &request);
|
||||
std::list<EasyChannelPtr> channelList;
|
||||
std::list<EasyMultiChannelPtr> multiChannelList;
|
||||
epics::pvData::RequesterPtr requester;
|
||||
epics::pvData::Requester::weak_pointer requester;
|
||||
bool isDestroyed;
|
||||
epics::pvData::Mutex mutex;
|
||||
};
|
||||
@ -197,6 +221,7 @@ class epicsShareClass EasyChannel
|
||||
{
|
||||
public:
|
||||
POINTER_DEFINITIONS(EasyChannel);
|
||||
virtual ~EasyChannel() { }
|
||||
/**
|
||||
* @brief Destroy the pvAccess connection.
|
||||
*/
|
||||
@ -251,6 +276,19 @@ public:
|
||||
* @return The interface.
|
||||
*/
|
||||
virtual EasyProcessPtr createProcess(epics::pvData::PVStructurePtr const & pvRequest) = 0;
|
||||
/**
|
||||
* @brief Call the next method with request = "field(value,alarm,timeStamp)"
|
||||
* @return The interface.
|
||||
*/
|
||||
virtual EasyGetPtr get() = 0;
|
||||
/**
|
||||
* @brief get a cached EasyGet or create and connect to a new EasyGet.
|
||||
* Then call it's get method.
|
||||
* If connection can not be made an exception is thrown.
|
||||
* @param request The request as described in package org.epics.pvdata.copy
|
||||
* @return The interface.
|
||||
*/
|
||||
virtual EasyGetPtr get(std::string const & request) = 0;
|
||||
/**
|
||||
* @brief Call the next method with request = "field(value,alarm,timeStamp)"
|
||||
* @return The interface.
|
||||
|
13
test/Makefile
Normal file
13
test/Makefile
Normal file
@ -0,0 +1,13 @@
|
||||
# Makefile at top of application tree
|
||||
|
||||
TOP = .
|
||||
include $(TOP)/configure/CONFIG
|
||||
|
||||
DIRS += configure
|
||||
|
||||
DIRS += src
|
||||
src_DEPEND_DIRS = configure
|
||||
|
||||
include $(TOP)/configure/RULES_TOP
|
||||
|
||||
|
29
test/configure/CONFIG
Normal file
29
test/configure/CONFIG
Normal file
@ -0,0 +1,29 @@
|
||||
# CONFIG - Load build configuration data
|
||||
#
|
||||
# Do not make changes to this file!
|
||||
|
||||
# Allow user to override where the build rules come from
|
||||
RULES = $(EPICS_BASE)
|
||||
|
||||
# RELEASE files point to other application tops
|
||||
include $(TOP)/configure/RELEASE
|
||||
-include $(TOP)/configure/RELEASE.$(EPICS_HOST_ARCH).Common
|
||||
ifdef T_A
|
||||
-include $(TOP)/configure/RELEASE.Common.$(T_A)
|
||||
-include $(TOP)/configure/RELEASE.$(EPICS_HOST_ARCH).$(T_A)
|
||||
endif
|
||||
|
||||
CONFIG = $(RULES)/configure
|
||||
include $(CONFIG)/CONFIG
|
||||
|
||||
# Override the Base definition:
|
||||
INSTALL_LOCATION = $(TOP)
|
||||
|
||||
# CONFIG_SITE files contain other build configuration settings
|
||||
include $(TOP)/configure/CONFIG_SITE
|
||||
-include $(TOP)/configure/CONFIG_SITE.$(EPICS_HOST_ARCH).Common
|
||||
ifdef T_A
|
||||
-include $(TOP)/configure/CONFIG_SITE.Common.$(T_A)
|
||||
-include $(TOP)/configure/CONFIG_SITE.$(EPICS_HOST_ARCH).$(T_A)
|
||||
endif
|
||||
|
27
test/configure/CONFIG_SITE
Normal file
27
test/configure/CONFIG_SITE
Normal file
@ -0,0 +1,27 @@
|
||||
# CONFIG_SITE
|
||||
|
||||
# Make any application-specific changes to the EPICS build
|
||||
# configuration variables in this file.
|
||||
#
|
||||
# Host/target specific settings can be specified in files named
|
||||
# CONFIG_SITE.$(EPICS_HOST_ARCH).Common
|
||||
# CONFIG_SITE.Common.$(T_A)
|
||||
# CONFIG_SITE.$(EPICS_HOST_ARCH).$(T_A)
|
||||
|
||||
# CHECK_RELEASE controls the consistency checking of the support
|
||||
# applications pointed to by the RELEASE* files.
|
||||
# Normally CHECK_RELEASE should be set to YES.
|
||||
# Set CHECK_RELEASE to NO to disable checking completely.
|
||||
# Set CHECK_RELEASE to WARN to perform consistency checking but
|
||||
# continue building anyway if conflicts are found.
|
||||
CHECK_RELEASE = WARN
|
||||
|
||||
# To install files into a location other than $(TOP) define
|
||||
# INSTALL_LOCATION here.
|
||||
#INSTALL_LOCATION=</path/name/to/install/top>
|
||||
|
||||
INSTALL_INCLUDE = $(INSTALL_LOCATION)/include/pv
|
||||
USR_INCLUDES += -I $(INSTALL_LOCATION)/include
|
||||
|
||||
-include $(TOP)/../../CONFIG_SITE.local
|
||||
-include $(TOP)/../configure/CONFIG_SITE.local
|
7
test/configure/ExampleRELEASE.local
Normal file
7
test/configure/ExampleRELEASE.local
Normal file
@ -0,0 +1,7 @@
|
||||
EPICS_BASE=/home/install/epics/base
|
||||
TEMPLATE_TOP=$(EPICS_BASE)/templates/makeBaseApp/top
|
||||
EPICSV4HOME=/home/hg
|
||||
PVCOMMON=${EPICSV4HOME}/pvCommonCPP
|
||||
PVDATA=${EPICSV4HOME}/pvDataCPP
|
||||
PVACCESS=${EPICSV4HOME}/pvAccessCPP
|
||||
EASYPVA==${EPICSV4HOME}/easyPVACPP
|
8
test/configure/Makefile
Normal file
8
test/configure/Makefile
Normal file
@ -0,0 +1,8 @@
|
||||
TOP=..
|
||||
|
||||
include $(TOP)/configure/CONFIG
|
||||
|
||||
TARGETS = $(CONFIG_TARGETS)
|
||||
CONFIGS += $(subst ../,,$(wildcard $(CONFIG_INSTALLS)))
|
||||
|
||||
include $(TOP)/configure/RULES
|
41
test/configure/RELEASE
Normal file
41
test/configure/RELEASE
Normal file
@ -0,0 +1,41 @@
|
||||
# pvDatabaseCPP/example RELEASE - Location of external support modules
|
||||
#
|
||||
# IF YOU CHANGE this file or any file it includes you must
|
||||
# subsequently do a "gnumake rebuild" in the application's
|
||||
# top level directory.
|
||||
#
|
||||
# The build process does not check dependencies against files
|
||||
# that are outside this application, thus you should also do a
|
||||
# "gnumake rebuild" in the top level directory after EPICS_BASE
|
||||
# or any other external module pointed to below is rebuilt.
|
||||
#
|
||||
# Host- or target-specific settings can be given in files named
|
||||
# RELEASE.$(EPICS_HOST_ARCH).Common
|
||||
# RELEASE.Common.$(T_A)
|
||||
# RELEASE.$(EPICS_HOST_ARCH).$(T_A)
|
||||
|
||||
# EPICS V4 Developers: Do not edit the locations in this file!
|
||||
#
|
||||
# Create a file RELEASE.local pointing to your PVASRV, PVACCESS,
|
||||
# PVDATA, PVCOMMON and EPICS_BASE build directories, e.g.
|
||||
# PVASRV = /path/to/epics/pvaSrvCPP
|
||||
# PVACCESS = /path/to/epics/pvAccessCPP
|
||||
# PVDATA = /path/to/epics/pvDataCPP
|
||||
# PVCOMMON = /path/to/epics/pvCommonCPP
|
||||
# EPICS_BASE = /path/to/epics/base
|
||||
|
||||
# If this example is built in a directory under pvDatabaseCPP,
|
||||
# use the following definitions:
|
||||
|
||||
EASYPVA = $(TOP)/..
|
||||
|
||||
-include $(TOP)/../configure/RELEASE.local
|
||||
-include $(TOP)/../../RELEASE.local
|
||||
|
||||
# If you copied this example from pvDatabaseCPP to be built as a
|
||||
# standalone TOP, adjust and use the following definitions:
|
||||
|
||||
#EASYPVA = /path/to/epics/easyPVACPP
|
||||
|
||||
#-include $(TOP)/../RELEASE.local
|
||||
#-include $(TOP)/configure/RELEASE.local
|
6
test/configure/RULES
Normal file
6
test/configure/RULES
Normal file
@ -0,0 +1,6 @@
|
||||
# RULES
|
||||
|
||||
include $(CONFIG)/RULES
|
||||
|
||||
# Library should be rebuilt because LIBOBJS may have changed.
|
||||
$(LIBNAME): ../Makefile
|
2
test/configure/RULES.ioc
Normal file
2
test/configure/RULES.ioc
Normal file
@ -0,0 +1,2 @@
|
||||
#RULES.ioc
|
||||
include $(CONFIG)/RULES.ioc
|
2
test/configure/RULES_DIRS
Normal file
2
test/configure/RULES_DIRS
Normal file
@ -0,0 +1,2 @@
|
||||
#RULES_DIRS
|
||||
include $(CONFIG)/RULES_DIRS
|
3
test/configure/RULES_TOP
Normal file
3
test/configure/RULES_TOP
Normal file
@ -0,0 +1,3 @@
|
||||
#RULES_TOP
|
||||
include $(CONFIG)/RULES_TOP
|
||||
|
27
test/src/Makefile
Normal file
27
test/src/Makefile
Normal file
@ -0,0 +1,27 @@
|
||||
TOP=..
|
||||
|
||||
include $(TOP)/configure/CONFIG
|
||||
#----------------------------------------
|
||||
# ADD MACRO DEFINITIONS AFTER THIS LINE
|
||||
|
||||
|
||||
PROD_HOST += exampleEasyPVStructure
|
||||
exampleEasyPVStructure_SRCS += exampleEasyPVStructure.cpp
|
||||
exampleEasyPVStructure_LIBS += easyPVA
|
||||
exampleEasyPVStructure_LIBS += pvAccess
|
||||
exampleEasyPVStructure_LIBS += pvData
|
||||
exampleEasyPVStructure_LIBS += Com
|
||||
|
||||
PROD_HOST += exampleEasyGet
|
||||
exampleEasyGet_SRCS += exampleEasyGet.cpp
|
||||
exampleEasyGet_LIBS += easyPVA
|
||||
exampleEasyGet_LIBS += pvAccess
|
||||
exampleEasyGet_LIBS += pvData
|
||||
exampleEasyGet_LIBS += Com
|
||||
|
||||
#===========================
|
||||
|
||||
include $(TOP)/configure/RULES
|
||||
#----------------------------------------
|
||||
# ADD RULES AFTER THIS LINE
|
||||
|
91
test/src/exampleEasyGet.cpp
Normal file
91
test/src/exampleEasyGet.cpp
Normal file
@ -0,0 +1,91 @@
|
||||
/*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;
|
||||
}
|
Reference in New Issue
Block a user