Merge pull request #75 from sveseli/master

Support requests to apply a pvCopy filter plugin to a whole PVRecord structure by using a field name `_` in the pvRequest.
This commit is contained in:
Andrew Johnson
2021-12-06 11:28:22 -06:00
committed by GitHub
4 changed files with 60 additions and 6 deletions

View File

@ -2,6 +2,12 @@
This document summarizes the changes to the module between releases.
## Release 4.X.Y (EPICS 7.X.Y, MMM 20YY)
* Added support for the whole structure (master field) server side plugins. The whole structure
is identified as the `_` string, and the pvRequest string that applies a plugin to it
has the form `field(_[pluginXYZ=optionA:3;optionB:uniqueId])`.
## Release 4.6.0 (EPICS 7.0.6, Jul 2021)
* Access Security is now supported.

View File

@ -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();

View File

@ -418,7 +418,10 @@ 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);
parent->callListener();
}
}
void PVRecordField::postSubField()

View File

@ -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;
}