From 9dfebf1897f25ba59e7f7ce0e6440871f6befcfd Mon Sep 17 00:00:00 2001 From: Sinisa Veseli Date: Tue, 30 Nov 2021 08:54:57 -0600 Subject: [PATCH 1/4] allow writing pvCopy plugins for the master field --- src/copy/pvCopy.cpp | 16 ++++++++++++---- src/database/pvRecord.cpp | 5 ++++- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/src/copy/pvCopy.cpp b/src/copy/pvCopy.cpp index fd98a24..6458c3a 100644 --- a/src/copy/pvCopy.cpp +++ b/src/copy/pvCopy.cpp @@ -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("_options"); + if(len==0) { + entireMaster = true; + } + else { + // If masterField is in the request, but not in the master structure, + // then assume entire master is requested + PVStructurePtr masterFieldPtr = pvMaster->getSubField("masterField"); + PVStructurePtr requestFieldPtr = pvRequest->getSubField("masterField"); + if (!masterFieldPtr && requestFieldPtr) { + entireMaster = true; + pvOptions = requestFieldPtr->getSubField("_options"); + } } if(entireMaster) { structure = pvMasterStructure->getStructure(); diff --git a/src/database/pvRecord.cpp b/src/database/pvRecord.cpp index ed2b2be..d343b6c 100644 --- a/src/database/pvRecord.cpp +++ b/src/database/pvRecord.cpp @@ -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() From a68ef61a1024a050e03d12cc7740dbc6e5175480 Mon Sep 17 00:00:00 2001 From: Sinisa Veseli Date: Tue, 30 Nov 2021 10:32:38 -0600 Subject: [PATCH 2/4] use _ instead of masterField to designate top level structure in the request --- src/copy/pvCopy.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/copy/pvCopy.cpp b/src/copy/pvCopy.cpp index 6458c3a..7694ecf 100644 --- a/src/copy/pvCopy.cpp +++ b/src/copy/pvCopy.cpp @@ -437,10 +437,10 @@ bool PVCopy::init(epics::pvData::PVStructurePtr const &pvRequest) entireMaster = true; } else { - // If masterField is in the request, but not in the master structure, - // then assume entire master is requested - PVStructurePtr masterFieldPtr = pvMaster->getSubField("masterField"); - PVStructurePtr requestFieldPtr = pvRequest->getSubField("masterField"); + // If "_" is in the request, but not in the master structure, + // then assume the top level PV structure is requested + PVStructurePtr masterFieldPtr = pvMaster->getSubField("_"); + PVStructurePtr requestFieldPtr = pvRequest->getSubField("_"); if (!masterFieldPtr && requestFieldPtr) { entireMaster = true; pvOptions = requestFieldPtr->getSubField("_options"); From 8daf322025d0d87b2c2746282817788f88e00106 Mon Sep 17 00:00:00 2001 From: Sinisa Veseli Date: Wed, 1 Dec 2021 14:36:20 -0600 Subject: [PATCH 3/4] update module release notes --- documentation/RELEASE_NOTES.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/documentation/RELEASE_NOTES.md b/documentation/RELEASE_NOTES.md index b5c1fe5..105ae6f 100644 --- a/documentation/RELEASE_NOTES.md +++ b/documentation/RELEASE_NOTES.md @@ -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. From 182eee57e223fb711a862ec41f2b047e1fc344d3 Mon Sep 17 00:00:00 2001 From: Sinisa Veseli Date: Wed, 1 Dec 2021 14:36:50 -0600 Subject: [PATCH 4/4] add tests for whole structure request --- test/src/testPVCopy.cpp | 39 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/test/src/testPVCopy.cpp b/test/src/testPVCopy.cpp index b39eeda..a86493f 100644 --- a/test/src/testPVCopy.cpp +++ b/test/src/testPVCopy.cpp @@ -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; }