Compare commits
9 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ee3027f641 | ||
|
|
6cd0a1bdb0 | ||
|
|
0d85561481 | ||
|
|
05d54c61e1 | ||
|
|
182eee57e2 | ||
|
|
8daf322025 | ||
|
|
a68ef61a10 | ||
|
|
9dfebf1897 | ||
|
|
0cf706511e |
2
Doxyfile
2
Doxyfile
@@ -38,7 +38,7 @@ PROJECT_NAME = pvDatabaseCPP
|
||||
# could be handy for archiving the generated documentation or if some version
|
||||
# control system is used.
|
||||
|
||||
PROJECT_NUMBER = 4.6.0
|
||||
PROJECT_NUMBER = 4.7.0
|
||||
|
||||
# Using the PROJECT_BRIEF tag one can provide an optional one line description
|
||||
# for a project that appears at the top of each page and should give viewer a
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# Version number for the PV Database API and shared library
|
||||
|
||||
EPICS_PVDATABASE_MAJOR_VERSION = 4
|
||||
EPICS_PVDATABASE_MINOR_VERSION = 6
|
||||
EPICS_PVDATABASE_MINOR_VERSION = 7
|
||||
EPICS_PVDATABASE_MAINTENANCE_VERSION = 0
|
||||
|
||||
# Development flag, set to zero for release versions
|
||||
|
||||
@@ -2,6 +2,17 @@
|
||||
|
||||
This document summarizes the changes to the module between releases.
|
||||
|
||||
## Release 4.7.0 (EPICS 7.0.7, Sep 2022)
|
||||
|
||||
* Added support for the whole structure (master field) server side plugins.
|
||||
The whole structure is identified as the `_` string, and a pvRequest string
|
||||
that applies a plugin to it takes the form:
|
||||
|
||||
`field(_[XYZ=A:3;B:uniqueId])`
|
||||
|
||||
where `XYZ` is the name of a specific filter plugin that takes parameters
|
||||
`A` and `B` with values `3` and `uniqueId` respectively.
|
||||
|
||||
## Release 4.6.0 (EPICS 7.0.6, Jul 2021)
|
||||
|
||||
* Access Security is now supported.
|
||||
|
||||
@@ -88,7 +88,6 @@ PVCopyPtr PVCopy::create(
|
||||
bool result = pvCopy->init(pvStructure);
|
||||
if(!result) return PVCopyPtr();
|
||||
pvCopy->traverseMasterInitPlugin();
|
||||
//cout << pvCopy->dump() << endl;
|
||||
return pvCopy;
|
||||
}
|
||||
|
||||
@@ -433,10 +432,19 @@ bool PVCopy::init(epics::pvData::PVStructurePtr const &pvRequest)
|
||||
PVStructurePtr pvMasterStructure = pvMaster;
|
||||
size_t len = pvRequest->getPVFields().size();
|
||||
bool entireMaster = false;
|
||||
if(len==0) entireMaster = true;
|
||||
PVStructurePtr pvOptions;
|
||||
if(len==1) {
|
||||
pvOptions = pvRequest->getSubField<PVStructure>("_options");
|
||||
if(len==0) {
|
||||
entireMaster = true;
|
||||
}
|
||||
else {
|
||||
// If "_" is in the request, but not in the master structure,
|
||||
// then assume the top level PV structure is requested
|
||||
PVStructurePtr masterFieldPtr = pvMaster->getSubField<PVStructure>("_");
|
||||
PVStructurePtr requestFieldPtr = pvRequest->getSubField<PVStructure>("_");
|
||||
if (!masterFieldPtr && requestFieldPtr) {
|
||||
entireMaster = true;
|
||||
pvOptions = requestFieldPtr->getSubField<PVStructure>("_options");
|
||||
}
|
||||
}
|
||||
if(entireMaster) {
|
||||
structure = pvMasterStructure->getStructure();
|
||||
|
||||
@@ -332,6 +332,7 @@ PVRecordField::PVRecordField(
|
||||
PVRecordPtr const & pvRecord)
|
||||
: pvField(pvField),
|
||||
isStructure(pvField->getField()->getType()==structure ? true : false),
|
||||
master(),
|
||||
parent(parent),
|
||||
pvRecord(pvRecord)
|
||||
{
|
||||
@@ -418,11 +419,18 @@ void PVRecordField::postParent(PVRecordFieldPtr const & subField)
|
||||
listener->dataPut(pvrs,subField);
|
||||
}
|
||||
PVRecordStructurePtr parent(this->parent.lock());
|
||||
if(parent) parent->postParent(subField);
|
||||
if(parent) {
|
||||
parent->postParent(subField);
|
||||
}
|
||||
}
|
||||
|
||||
void PVRecordField::postSubField()
|
||||
{
|
||||
// Master field pointer will be set in only one subfield
|
||||
PVRecordStructurePtr master(this->master.lock());
|
||||
if(master) {
|
||||
master->callListener();
|
||||
}
|
||||
callListener();
|
||||
if(isStructure) {
|
||||
PVRecordStructurePtr pvrs =
|
||||
@@ -465,6 +473,11 @@ void PVRecordStructure::init()
|
||||
PVRecordStructurePtr self =
|
||||
static_pointer_cast<PVRecordStructure>(shared_from_this());
|
||||
PVRecordPtr pvRecord = getPVRecord();
|
||||
static bool masterFieldCallbackSet = false;
|
||||
bool isMasterField = (!getFullFieldName().size());
|
||||
if (isMasterField) {
|
||||
masterFieldCallbackSet = false;
|
||||
}
|
||||
for(size_t i=0; i<numFields; i++) {
|
||||
PVFieldPtr pvField = pvFields[i];
|
||||
if(pvField->getField()->getType()==structure) {
|
||||
@@ -478,6 +491,17 @@ void PVRecordStructure::init()
|
||||
new PVRecordField(pvField,self,pvRecord));
|
||||
pvRecordFields->push_back(pvRecordField);
|
||||
pvRecordField->init();
|
||||
// Master field listeners will be called before
|
||||
// calling listeners for the first subfield
|
||||
if (!masterFieldCallbackSet) {
|
||||
masterFieldCallbackSet = true;
|
||||
// Find master field
|
||||
PVRecordStructurePtr p = pvRecordField->parent.lock();
|
||||
while (p) {
|
||||
pvRecordField->master = p;
|
||||
p = p->parent.lock();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -376,6 +376,7 @@ private:
|
||||
std::list<PVListenerWPtr> pvListenerList;
|
||||
epics::pvData::PVField::weak_pointer pvField;
|
||||
bool isStructure;
|
||||
PVRecordStructureWPtr master;
|
||||
PVRecordStructureWPtr parent;
|
||||
PVRecordWPtr pvRecord;
|
||||
std::string fullName;
|
||||
|
||||
@@ -274,6 +274,33 @@ static void testPVScalarArray(
|
||||
}
|
||||
}
|
||||
|
||||
static void testMasterField(PVRecordPtr const& pvRecord)
|
||||
{
|
||||
CreateRequest::shared_pointer createRequest = CreateRequest::create();
|
||||
PVStructurePtr pvRequest = createRequest->createRequest("field(_)");
|
||||
if(debug) {
|
||||
cout << "pvRequest" << *pvRequest << endl ;
|
||||
}
|
||||
PVStructurePtr pvStructureRecord = pvRecord->getPVRecordStructure()->getPVStructure();
|
||||
PVCopyPtr pvCopy = PVCopy::create(pvStructureRecord,pvRequest,"");
|
||||
PVStructurePtr pvMasterField = pvCopy->getPVMaster();
|
||||
if(debug) {
|
||||
cout << "PV structure from record" << endl << *pvStructureRecord << endl;
|
||||
cout << "Master PV structure from copy" << endl << *pvMasterField << endl;
|
||||
cout << "Master PV structure from copy offset " << pvMasterField->getFieldOffset() << endl;
|
||||
}
|
||||
testOk1(pvMasterField->getNumberFields() == pvStructureRecord->getNumberFields());
|
||||
testOk1(pvMasterField->getFieldOffset() == 0);
|
||||
PVStructurePtr pvStructureCopy = pvCopy->createPVStructure();
|
||||
BitSetPtr bitSet = BitSetPtr(new BitSet(pvStructureCopy->getNumberFields()));
|
||||
pvCopy->initCopy(pvStructureCopy, bitSet);
|
||||
if(debug) {
|
||||
cout << "PV structure from copy" << endl << *pvStructureCopy << endl;
|
||||
cout << "PV structure from copy offset " << pvStructureCopy->getFieldOffset() << endl;
|
||||
}
|
||||
testOk1(pvMasterField->getNumberFields() == pvStructureCopy->getNumberFields());
|
||||
}
|
||||
|
||||
static void scalarTest()
|
||||
{
|
||||
if(debug) {cout << endl << endl << "****scalarTest****" << endl;}
|
||||
@@ -393,11 +420,21 @@ static void powerSupplyTest()
|
||||
testPVScalar(valueNameRecord,valueNameCopy,pvRecord,pvCopy);
|
||||
}
|
||||
|
||||
static void masterFieldTest()
|
||||
{
|
||||
if(debug) {
|
||||
cout << endl << endl << "****masterFieldTest****" << endl;
|
||||
}
|
||||
PVRecordPtr pvRecord = createScalar("doubleRecord",pvDouble,"alarm,timeStamp,display");
|
||||
testMasterField(pvRecord);
|
||||
}
|
||||
|
||||
MAIN(testPVCopy)
|
||||
{
|
||||
testPlan(67);
|
||||
testPlan(70);
|
||||
scalarTest();
|
||||
arrayTest();
|
||||
powerSupplyTest();
|
||||
masterFieldTest();
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user