more code implemented. See pvDatabaseCPP.html for details
This commit is contained in:
@@ -13,6 +13,8 @@
|
||||
|
||||
#include <pv/pvDatabase.h>
|
||||
#include <pv/standardPVField.h>
|
||||
#include <pv/timeStamp.h>
|
||||
#include <pv/pvTimeStamp.h>
|
||||
|
||||
namespace epics { namespace pvDatabase {
|
||||
|
||||
@@ -27,20 +29,23 @@ public:
|
||||
POINTER_DEFINITIONS(ExampleCounter);
|
||||
static ExampleCounterPtr create(
|
||||
epics::pvData::String const & recordName);
|
||||
virtual ~ExampleCounter(){}
|
||||
virtual ~ExampleCounter();
|
||||
virtual void destroy();
|
||||
virtual bool init();
|
||||
virtual void process();
|
||||
private:
|
||||
ExampleCounter(epics::pvData::String const & recordName,
|
||||
epics::pvData::PVStructurePtr const & pvStructure);
|
||||
epics::pvData::PVLongPtr pvValue;
|
||||
epics::pvData::PVTimeStamp pvTimeStamp;
|
||||
epics::pvData::TimeStamp timeStamp;
|
||||
};
|
||||
|
||||
ExampleCounterPtr ExampleCounter::create(
|
||||
epics::pvData::String const & recordName)
|
||||
{
|
||||
epics::pvData::PVStructurePtr pvStructure =
|
||||
epics::pvData::getStandardPVField()->scalar(epics::pvData::pvLong,"timeStamp");
|
||||
epics::pvData::getStandardPVField()->scalar(epics::pvData::pvLong,"timeStamp,alarm");
|
||||
ExampleCounterPtr pvRecord(
|
||||
new ExampleCounter(recordName,pvStructure));
|
||||
if(!pvRecord->init()) pvRecord.reset();
|
||||
@@ -52,6 +57,17 @@ ExampleCounter::ExampleCounter(
|
||||
epics::pvData::PVStructurePtr const & pvStructure)
|
||||
: PVRecord(recordName,pvStructure)
|
||||
{
|
||||
pvTimeStamp.attach(pvStructure->getSubField("timeStamp"));
|
||||
}
|
||||
|
||||
ExampleCounter::~ExampleCounter()
|
||||
{
|
||||
destroy();
|
||||
}
|
||||
|
||||
void ExampleCounter::destroy()
|
||||
{
|
||||
PVRecord::destroy();
|
||||
}
|
||||
|
||||
bool ExampleCounter::init()
|
||||
@@ -67,6 +83,8 @@ bool ExampleCounter::init()
|
||||
void ExampleCounter::process()
|
||||
{
|
||||
pvValue->put(pvValue->get() + 1.0);
|
||||
timeStamp.getCurrent();
|
||||
pvTimeStamp.set(timeStamp);
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
@@ -32,6 +32,7 @@ public:
|
||||
epics::pvData::String const & recordName,
|
||||
epics::pvData::PVStructurePtr const & pvStructure);
|
||||
virtual ~PowerSupplyRecordTest();
|
||||
virtual void destroy();
|
||||
virtual bool init();
|
||||
virtual void process();
|
||||
void put(double power,double voltage);
|
||||
@@ -72,6 +73,11 @@ PowerSupplyRecordTest::~PowerSupplyRecordTest()
|
||||
destroy();
|
||||
}
|
||||
|
||||
void PowerSupplyRecordTest::destroy()
|
||||
{
|
||||
PVRecord::destroy();
|
||||
}
|
||||
|
||||
bool PowerSupplyRecordTest::init()
|
||||
{
|
||||
initPVRecord();
|
||||
|
||||
@@ -18,8 +18,6 @@ using namespace std;
|
||||
|
||||
namespace epics { namespace pvDatabase {
|
||||
|
||||
PVDatabase::~PVDatabase() {}
|
||||
|
||||
PVDatabasePtr PVDatabase::getMaster()
|
||||
{
|
||||
static PVDatabasePtr master;
|
||||
@@ -31,36 +29,98 @@ PVDatabasePtr PVDatabase::getMaster()
|
||||
return master;
|
||||
}
|
||||
|
||||
PVDatabase::PVDatabase() {}
|
||||
PVDatabase::PVDatabase()
|
||||
: thelock(mutex),
|
||||
isDestroyed(false)
|
||||
{
|
||||
thelock.unlock();
|
||||
}
|
||||
|
||||
PVDatabase::~PVDatabase()
|
||||
{
|
||||
destroy();
|
||||
}
|
||||
|
||||
void PVDatabase::destroy()
|
||||
{
|
||||
lock();
|
||||
if(isDestroyed) {
|
||||
unlock();
|
||||
return;
|
||||
}
|
||||
isDestroyed = true;
|
||||
PVRecordMap::iterator iter;
|
||||
while(true) {
|
||||
iter = recordMap.begin();
|
||||
if(iter==recordMap.end()) break;
|
||||
PVRecordPtr pvRecord = (*iter).second;
|
||||
recordMap.erase(iter);
|
||||
unlock();
|
||||
if(pvRecord.get()!=NULL) pvRecord->destroy();
|
||||
lock();
|
||||
}
|
||||
}
|
||||
|
||||
void PVDatabase::lock() {thelock.lock();}
|
||||
|
||||
void PVDatabase::unlock() {thelock.unlock();}
|
||||
|
||||
PVRecordPtr PVDatabase::findRecord(String const& recordName)
|
||||
{
|
||||
PVRecordMap::iterator iter = recordMap.find(recordName);
|
||||
if(iter!=recordMap.end()) {
|
||||
lock_guard();
|
||||
PVRecordPtr xxx;
|
||||
if(isDestroyed) return xxx;
|
||||
PVRecordMap::iterator iter = recordMap.find(recordName);
|
||||
if(iter!=recordMap.end()) {
|
||||
return (*iter).second;
|
||||
}
|
||||
PVRecordPtr xxx;
|
||||
return xxx;
|
||||
}
|
||||
return xxx;
|
||||
}
|
||||
|
||||
PVStringArrayPtr PVDatabase::getRecordNames()
|
||||
{
|
||||
lock_guard();
|
||||
PVStringArrayPtr pvStringArray = static_pointer_cast<PVStringArray>
|
||||
(getPVDataCreate()->createPVScalarArray(pvString));
|
||||
size_t len = recordMap.size();
|
||||
std::vector<String> names(len);
|
||||
PVRecordMap::iterator iter;
|
||||
size_t i = 0;
|
||||
for(iter = recordMap.begin(); iter!=recordMap.end(); ++iter) {
|
||||
names[i++] = (*iter).first;
|
||||
}
|
||||
pvStringArray->put(0,len,names,0);
|
||||
return pvStringArray;
|
||||
}
|
||||
|
||||
bool PVDatabase::addRecord(PVRecordPtr const & record)
|
||||
{
|
||||
String recordName = record->getRecordName();
|
||||
PVRecordMap::iterator iter = recordMap.find(recordName);
|
||||
if(iter!=recordMap.end()) return false;
|
||||
recordMap.insert(PVRecordMap::value_type(recordName,record));
|
||||
return true;
|
||||
lock_guard();
|
||||
if(isDestroyed) return false;
|
||||
String recordName = record->getRecordName();
|
||||
PVRecordMap::iterator iter = recordMap.find(recordName);
|
||||
if(iter!=recordMap.end()) {
|
||||
return false;
|
||||
}
|
||||
recordMap.insert(PVRecordMap::value_type(recordName,record));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PVDatabase::removeRecord(PVRecordPtr const & record)
|
||||
{
|
||||
String recordName = record->getRecordName();
|
||||
PVRecordMap::iterator iter = recordMap.find(recordName);
|
||||
if(iter!=recordMap.end()) {
|
||||
recordMap.erase(iter);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
lock();
|
||||
if(isDestroyed) return false;
|
||||
String recordName = record->getRecordName();
|
||||
PVRecordMap::iterator iter = recordMap.find(recordName);
|
||||
if(iter!=recordMap.end()) {
|
||||
PVRecordPtr pvRecord = (*iter).second;
|
||||
recordMap.erase(iter);
|
||||
unlock();
|
||||
if(pvRecord.get()!=NULL) pvRecord->destroy();
|
||||
return true;
|
||||
}
|
||||
unlock();
|
||||
return false;
|
||||
}
|
||||
|
||||
String PVDatabase::getRequesterName()
|
||||
|
||||
@@ -118,7 +118,7 @@ public:
|
||||
* The record will automatically
|
||||
* be unlocked when control leaves the block that has the call.
|
||||
*/
|
||||
inline void lock_guard() { epics::pvData::Lock theLock(mutex); }
|
||||
inline void lock_guard() { epics::pvData::Lock thelock(mutex); }
|
||||
/**
|
||||
* Lock the record.
|
||||
* Any code must lock while accessing a record.
|
||||
@@ -488,6 +488,10 @@ public:
|
||||
* Destructor
|
||||
*/
|
||||
virtual ~PVDatabase();
|
||||
/**
|
||||
* Destroy the PVDatabase.
|
||||
*/
|
||||
virtual void destroy();
|
||||
/**
|
||||
* Find a record.
|
||||
* An empty pointer is returned if the record is not in the database.
|
||||
@@ -507,6 +511,11 @@ public:
|
||||
* @return <b>true</b> if record was removed.
|
||||
*/
|
||||
bool removeRecord(PVRecordPtr const & record);
|
||||
/**
|
||||
* Get the names of all the records in the database.
|
||||
* @return The names.
|
||||
*/
|
||||
epics::pvData::PVStringArrayPtr getRecordNames();
|
||||
/**
|
||||
* Virtual method of Requester.
|
||||
* @return The name.
|
||||
@@ -523,7 +532,13 @@ public:
|
||||
epics::pvData::MessageType messageType);
|
||||
private:
|
||||
PVDatabase();
|
||||
void lock();
|
||||
void unlock();
|
||||
inline void lock_guard() { epics::pvData::Lock thelock(mutex); }
|
||||
PVRecordMap recordMap;
|
||||
epics::pvData::Mutex mutex;
|
||||
epics::pvData::Lock thelock;
|
||||
bool isDestroyed;
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -68,29 +68,29 @@ void PVRecord::destroy()
|
||||
isDestroyed = true;
|
||||
|
||||
std::list<RequesterPtr>::iterator requesterIter;
|
||||
for (
|
||||
requesterIter = requesterList.begin();
|
||||
requesterIter!=requesterList.end();
|
||||
requesterIter++ ) {
|
||||
while(true) {
|
||||
requesterIter = requesterList.begin();
|
||||
if(requesterIter==requesterList.end()) break;
|
||||
requesterList.erase(requesterIter);
|
||||
unlock();
|
||||
(*requesterIter)->message("record destroyed",fatalErrorMessage);
|
||||
lock();
|
||||
}
|
||||
requesterList.clear();
|
||||
|
||||
std::list<PVRecordClientPtr>::iterator clientIter;
|
||||
for (clientIter = pvRecordClientList.begin();
|
||||
clientIter!=pvRecordClientList.end();
|
||||
clientIter++ )
|
||||
{
|
||||
while(true) {
|
||||
clientIter = pvRecordClientList.begin();
|
||||
if(clientIter==pvRecordClientList.end()) break;
|
||||
pvRecordClientList.erase(clientIter);
|
||||
unlock();
|
||||
(*clientIter)->detach(getPtrSelf());
|
||||
lock();
|
||||
}
|
||||
pvRecordClientList.clear();
|
||||
|
||||
pvListenerList.clear();
|
||||
pvRecordStructure->destroy();
|
||||
pvRecordStructure.reset();
|
||||
convert.reset();
|
||||
pvStructure.reset();
|
||||
|
||||
unlock();
|
||||
}
|
||||
|
||||
@@ -211,6 +211,10 @@ bool PVRecord::addPVRecordClient(PVRecordClientPtr const & pvRecordClient)
|
||||
bool PVRecord::removePVRecordClient(PVRecordClientPtr const & pvRecordClient)
|
||||
{
|
||||
lock();
|
||||
if(isDestroyed) {
|
||||
unlock();
|
||||
return false;
|
||||
}
|
||||
std::list<PVRecordClientPtr>::iterator iter;
|
||||
for (iter = pvRecordClientList.begin();
|
||||
iter!=pvRecordClientList.end();
|
||||
|
||||
111
src/database/recordList.cpp
Normal file
111
src/database/recordList.cpp
Normal file
@@ -0,0 +1,111 @@
|
||||
/* recordListTest.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 2013.04.18
|
||||
*/
|
||||
|
||||
#include <pv/recordList.h>
|
||||
|
||||
using std::tr1::static_pointer_cast;
|
||||
using namespace epics::pvData;
|
||||
using namespace epics::pvAccess;
|
||||
using namespace std;
|
||||
|
||||
namespace epics { namespace pvDatabase {
|
||||
|
||||
RecordListRecordPtr RecordListRecord::create(
|
||||
epics::pvData::String const & recordName)
|
||||
{
|
||||
FieldCreatePtr fieldCreate = getFieldCreate();
|
||||
PVDataCreatePtr pvDataCreate = getPVDataCreate();
|
||||
StringArray argNames(2);
|
||||
FieldConstPtrArray argFields(2);
|
||||
argNames[0] = "database";
|
||||
argFields[0] = fieldCreate->createScalar(pvString);
|
||||
argNames[1] = "regularExpression";
|
||||
argFields[1] = fieldCreate->createScalar(pvString);
|
||||
StringArray resNames(2);
|
||||
FieldConstPtrArray resFields(2);
|
||||
resNames[0] = "status";
|
||||
resFields[0] = fieldCreate->createScalar(pvString);
|
||||
resNames[1] = "names";
|
||||
resFields[1] = fieldCreate->createScalarArray(pvString);
|
||||
StringArray topNames(2);
|
||||
FieldConstPtrArray topFields(2);
|
||||
topNames[0] = "arguments";
|
||||
topFields[0] = fieldCreate->createStructure(argNames,argFields);
|
||||
topNames[1] = "result";
|
||||
topFields[1] = fieldCreate->createStructure(resNames,resFields);
|
||||
StructureConstPtr topStructure =
|
||||
fieldCreate->createStructure(topNames,topFields);
|
||||
PVStructurePtr pvStructure = pvDataCreate->createPVStructure(topStructure);
|
||||
RecordListRecordPtr pvRecord(
|
||||
new RecordListRecord(recordName,pvStructure));
|
||||
if(!pvRecord->init()) pvRecord.reset();
|
||||
return pvRecord;
|
||||
}
|
||||
|
||||
RecordListRecord::RecordListRecord(
|
||||
epics::pvData::String const & recordName,
|
||||
epics::pvData::PVStructurePtr const & pvStructure)
|
||||
: PVRecord(recordName,pvStructure)
|
||||
{
|
||||
}
|
||||
|
||||
RecordListRecord::~RecordListRecord()
|
||||
{
|
||||
destroy();
|
||||
}
|
||||
|
||||
void RecordListRecord::destroy()
|
||||
{
|
||||
PVRecord::destroy();
|
||||
}
|
||||
|
||||
bool RecordListRecord::init()
|
||||
{
|
||||
initPVRecord();
|
||||
PVStructurePtr pvStructure = getPVStructure();
|
||||
database = pvStructure->getStringField("arguments.database");
|
||||
if(database.get()==NULL) return false;
|
||||
regularExpression = pvStructure->getStringField(
|
||||
"arguments.regularExpression");
|
||||
if(regularExpression.get()==NULL) return false;
|
||||
status = pvStructure->getStringField("result.status");
|
||||
if(status.get()==NULL) return false;
|
||||
PVFieldPtr pvField = pvStructure->getSubField("result.names");
|
||||
if(pvField.get()==NULL) {
|
||||
std::cerr << "no result.names" << std::endl;
|
||||
return false;
|
||||
}
|
||||
names = static_pointer_cast<PVStringArray>(
|
||||
pvStructure->getScalarArrayField("result.names",pvString));
|
||||
if(names.get()==NULL) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void RecordListRecord::process()
|
||||
{
|
||||
PVStringArrayPtr pvNames = PVDatabase::getMaster()->getRecordNames();
|
||||
std::vector<String> const & xxx = pvNames->getVector();
|
||||
size_t n = xxx.size();
|
||||
names->put(0,n,xxx,0);
|
||||
String message("");
|
||||
if(database->get().compare("master")!=0) {
|
||||
message += " can only access master ";
|
||||
}
|
||||
String regEx = regularExpression->get();
|
||||
if(regEx.compare("")!=0 && regEx.compare(".*")!=0) {
|
||||
message += " regularExpression not implemented ";
|
||||
}
|
||||
status->put(message);
|
||||
}
|
||||
|
||||
|
||||
}}
|
||||
|
||||
44
src/database/recordList.h
Normal file
44
src/database/recordList.h
Normal file
@@ -0,0 +1,44 @@
|
||||
/* recordListTest.h */
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* EPICS pvData is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
/**
|
||||
* @author mrk
|
||||
* @date 2013.04.18
|
||||
*/
|
||||
#ifndef RECORDLIST_H
|
||||
#define RECORDLIST_H
|
||||
|
||||
#include <pv/pvDatabase.h>
|
||||
|
||||
namespace epics { namespace pvDatabase {
|
||||
|
||||
|
||||
class RecordListRecord;
|
||||
typedef std::tr1::shared_ptr<RecordListRecord> RecordListRecordPtr;
|
||||
|
||||
class RecordListRecord :
|
||||
public PVRecord
|
||||
{
|
||||
public:
|
||||
POINTER_DEFINITIONS(RecordListRecord);
|
||||
static RecordListRecordPtr create(
|
||||
epics::pvData::String const & recordName);
|
||||
virtual ~RecordListRecord();
|
||||
virtual void destroy();
|
||||
virtual bool init();
|
||||
virtual void process();
|
||||
private:
|
||||
RecordListRecord(epics::pvData::String const & recordName,
|
||||
epics::pvData::PVStructurePtr const & pvStructure);
|
||||
epics::pvData::PVStringPtr database;
|
||||
epics::pvData::PVStringPtr regularExpression;
|
||||
epics::pvData::PVStringPtr status;
|
||||
epics::pvData::PVStringArrayPtr names;
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif /* RECORDLIST_H */
|
||||
Reference in New Issue
Block a user