interim commit. pvCopy how works
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
TOP = ..
|
||||
include $(TOP)/configure/CONFIG
|
||||
DIRS += record
|
||||
DIRS += pvCopy
|
||||
include $(TOP)/configure/RULES_DIRS
|
||||
|
||||
|
||||
12
test/pvCopy/Makefile
Normal file
12
test/pvCopy/Makefile
Normal file
@@ -0,0 +1,12 @@
|
||||
TOP=../..
|
||||
|
||||
include $(TOP)/configure/CONFIG
|
||||
|
||||
PROD_HOST += testPVCopy
|
||||
testPVCopy_SRCS += testPVCopy.cpp
|
||||
testPVCopy_LIBS += pvDatabase pvAccess pvData Com
|
||||
|
||||
include $(TOP)/configure/RULES
|
||||
#----------------------------------------
|
||||
# ADD RULES AFTER THIS LINE
|
||||
|
||||
409
test/pvCopy/testPVCopy.cpp
Normal file
409
test/pvCopy/testPVCopy.cpp
Normal file
@@ -0,0 +1,409 @@
|
||||
/*testPVCopyMain.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 <cstddef>
|
||||
#include <cstdlib>
|
||||
#include <cstddef>
|
||||
#include <string>
|
||||
#include <cstdio>
|
||||
#include <memory>
|
||||
#include <iostream>
|
||||
|
||||
#include <epicsStdio.h>
|
||||
#include <epicsMutex.h>
|
||||
#include <epicsEvent.h>
|
||||
#include <epicsThread.h>
|
||||
|
||||
#include <pv/standardField.h>
|
||||
#include <pv/standardPVField.h>
|
||||
#include <pv/pvData.h>
|
||||
#include <pv/pvAccess.h>
|
||||
#include <pv/pvCopy.h>
|
||||
#include <pv/powerSupplyRecordTest.h>
|
||||
|
||||
|
||||
using namespace std;
|
||||
using std::tr1::static_pointer_cast;
|
||||
using namespace epics::pvData;
|
||||
using namespace epics::pvAccess;
|
||||
using namespace epics::pvDatabase;
|
||||
|
||||
|
||||
class MyRequester;
|
||||
typedef std::tr1::shared_ptr<MyRequester> MyRequesterPtr;
|
||||
|
||||
class MyRequester : public Requester {
|
||||
public:
|
||||
POINTER_DEFINITIONS(MyRequester);
|
||||
MyRequester(String const &requesterName)
|
||||
: requesterName(requesterName)
|
||||
{}
|
||||
virtual ~MyRequester() {}
|
||||
virtual String getRequesterName() { return requesterName;}
|
||||
virtual void message(String const & message,MessageType messageType)
|
||||
{
|
||||
cout << message << endl;
|
||||
}
|
||||
private:
|
||||
String requesterName;
|
||||
};
|
||||
|
||||
static PVRecordPtr createScalar(
|
||||
String const & recordName,
|
||||
ScalarType scalarType,
|
||||
String const & properties)
|
||||
{
|
||||
PVStructurePtr pvStructure = getStandardPVField()->scalar(scalarType,properties);
|
||||
return PVRecord::create(recordName,pvStructure);
|
||||
}
|
||||
|
||||
static PVRecordPtr createScalarArray(
|
||||
String const & recordName,
|
||||
ScalarType scalarType,
|
||||
String const & properties)
|
||||
{
|
||||
PVStructurePtr pvStructure = getStandardPVField()->scalarArray(scalarType,properties);
|
||||
return PVRecord::create(recordName,pvStructure);
|
||||
}
|
||||
|
||||
static PowerSupplyRecordTestPtr createPowerSupply(String const & recordName)
|
||||
{
|
||||
FieldCreatePtr fieldCreate = getFieldCreate();
|
||||
StandardFieldPtr standardField = getStandardField();
|
||||
PVDataCreatePtr pvDataCreate = getPVDataCreate();
|
||||
size_t nfields = 5;
|
||||
StringArray names;
|
||||
names.reserve(nfields);
|
||||
FieldConstPtrArray powerSupply;
|
||||
powerSupply.reserve(nfields);
|
||||
names.push_back("alarm");
|
||||
powerSupply.push_back(standardField->alarm());
|
||||
names.push_back("timeStamp");
|
||||
powerSupply.push_back(standardField->timeStamp());
|
||||
String properties("alarm,display");
|
||||
names.push_back("voltage");
|
||||
powerSupply.push_back(standardField->scalar(pvDouble,properties));
|
||||
names.push_back("power");
|
||||
powerSupply.push_back(standardField->scalar(pvDouble,properties));
|
||||
names.push_back("current");
|
||||
powerSupply.push_back(standardField->scalar(pvDouble,properties));
|
||||
return PowerSupplyRecordTest::create(recordName,
|
||||
pvDataCreate->createPVStructure(
|
||||
fieldCreate->createStructure(names,powerSupply)));
|
||||
}
|
||||
|
||||
static void testPVScalar(
|
||||
String const & valueNameRecord,
|
||||
String const & valueNameCopy,
|
||||
PVRecordPtr const & pvRecord,
|
||||
PVCopyPtr const & pvCopy)
|
||||
{
|
||||
PVRecordFieldPtr pvRecordField;
|
||||
PVStructurePtr pvStructureRecord;
|
||||
PVStructurePtr pvStructureCopy;
|
||||
PVFieldPtr pvField;
|
||||
PVScalarPtr pvValueRecord;
|
||||
PVScalarPtr pvValueCopy;
|
||||
BitSetPtr bitSet;
|
||||
String builder;
|
||||
size_t offset;
|
||||
ConvertPtr convert = getConvert();
|
||||
|
||||
pvRecord->lock_guard();
|
||||
cout << endl;
|
||||
pvStructureRecord = pvRecord->getPVRecordStructure()->getPVStructure();
|
||||
pvField = pvStructureRecord->getSubField(valueNameRecord);
|
||||
pvValueRecord = static_pointer_cast<PVScalar>(pvField);
|
||||
convert->fromDouble(pvValueRecord,.04);
|
||||
StructureConstPtr structure = pvCopy->getStructure();
|
||||
builder.clear(); structure->toString(&builder);
|
||||
cout << "structure from copy" << endl << builder << endl;
|
||||
pvStructureCopy = pvCopy->createPVStructure();
|
||||
pvField = pvStructureCopy->getSubField(valueNameCopy);
|
||||
pvValueCopy = static_pointer_cast<PVScalar>(pvField);
|
||||
bitSet = BitSetPtr(new BitSet(pvStructureCopy->getNumberFields()));
|
||||
pvCopy->initCopy(pvStructureCopy, bitSet, true);
|
||||
cout << "after initCopy pvValueCopy " << convert->toDouble(pvValueCopy);
|
||||
cout << endl;
|
||||
convert->fromDouble(pvValueRecord,.06);
|
||||
pvCopy->updateCopySetBitSet(pvStructureCopy,bitSet,true);
|
||||
cout << "after put(.06) pvValueCopy " << convert->toDouble(pvValueCopy);
|
||||
builder.clear();
|
||||
bitSet->toString(&builder);
|
||||
cout << " bitSet " << builder;
|
||||
cout << endl;
|
||||
pvRecordField = pvRecord->findPVRecordField(pvValueRecord);
|
||||
offset = pvCopy->getCopyOffset(pvRecordField);
|
||||
cout << "getCopyOffset() " << offset;
|
||||
cout << " pvValueCopy->getOffset() " << pvValueCopy->getFieldOffset();
|
||||
cout << " pvValueRecord->getOffset() " << pvValueRecord->getFieldOffset();
|
||||
cout << " bitSet " << builder;
|
||||
cout << endl;
|
||||
bitSet->clear();
|
||||
convert->fromDouble(pvValueRecord,1.0);
|
||||
builder.clear();
|
||||
bitSet->toString(&builder);
|
||||
cout << "before updateCopyFromBitSet";
|
||||
cout << " recordValue " << convert->toDouble(pvValueRecord);
|
||||
cout << " copyValue " << convert->toDouble(pvValueCopy);
|
||||
cout << " bitSet " << builder;
|
||||
cout << endl;
|
||||
bitSet->set(0);
|
||||
pvCopy->updateCopyFromBitSet(pvStructureCopy,bitSet,true);
|
||||
cout << "after updateCopyFromBitSet";
|
||||
cout << " recordValue " << convert->toDouble(pvValueRecord);
|
||||
cout << " copyValue " << convert->toDouble(pvValueCopy);
|
||||
cout << " bitSet " << builder;
|
||||
cout << endl;
|
||||
convert->fromDouble(pvValueCopy,2.0);
|
||||
bitSet->set(0);
|
||||
cout << "before updateRecord";
|
||||
cout << " recordValue " << convert->toDouble(pvValueRecord);
|
||||
cout << " copyValue " << convert->toDouble(pvValueCopy);
|
||||
cout << " bitSet " << builder;
|
||||
cout << endl;
|
||||
pvCopy->updateRecord(pvStructureCopy,bitSet,true);
|
||||
cout << "after updateRecord";
|
||||
cout << " recordValue " << convert->toDouble(pvValueRecord);
|
||||
cout << " copyValue " << convert->toDouble(pvValueCopy);
|
||||
cout << " bitSet " << builder;
|
||||
cout << endl;
|
||||
}
|
||||
|
||||
static void testPVScalarArray(
|
||||
ScalarType scalarType,
|
||||
String const & valueNameRecord,
|
||||
String const & valueNameCopy,
|
||||
PVRecordPtr const & pvRecord,
|
||||
PVCopyPtr const & pvCopy)
|
||||
{
|
||||
PVRecordFieldPtr pvRecordField;
|
||||
PVStructurePtr pvStructureRecord;
|
||||
PVStructurePtr pvStructureCopy;
|
||||
PVScalarArrayPtr pvValueRecord;
|
||||
PVScalarArrayPtr pvValueCopy;
|
||||
BitSetPtr bitSet;
|
||||
String builder;
|
||||
size_t offset;
|
||||
ConvertPtr convert = getConvert();
|
||||
size_t n = 5;
|
||||
DoubleArray values(n);
|
||||
|
||||
pvRecord->lock_guard();
|
||||
cout << endl;
|
||||
pvStructureRecord = pvRecord->getPVRecordStructure()->getPVStructure();
|
||||
pvValueRecord = pvStructureRecord->getScalarArrayField(valueNameRecord,scalarType);
|
||||
for(size_t i=0; i<n; i++) values[i] = i;
|
||||
convert->fromDoubleArray(pvValueRecord,0,n,get(values),0);
|
||||
StructureConstPtr structure = pvCopy->getStructure();
|
||||
builder.clear(); structure->toString(&builder);
|
||||
cout << "structure from copy" << endl << builder << endl;
|
||||
pvStructureCopy = pvCopy->createPVStructure();
|
||||
pvValueCopy = pvStructureCopy->getScalarArrayField(valueNameCopy,scalarType);
|
||||
bitSet = BitSetPtr(new BitSet(pvStructureCopy->getNumberFields()));
|
||||
pvCopy->initCopy(pvStructureCopy, bitSet, true);
|
||||
builder.clear(); pvValueCopy->toString(&builder);
|
||||
cout << "after initCopy pvValueCopy " << builder << endl;
|
||||
cout << endl;
|
||||
for(size_t i=0; i<n; i++) values[i] = i + .06;
|
||||
convert->fromDoubleArray(pvValueRecord,0,n,get(values),0);
|
||||
pvCopy->updateCopySetBitSet(pvStructureCopy,bitSet,true);
|
||||
builder.clear(); pvValueCopy->toString(&builder);
|
||||
cout << "after put(i+ .06) pvValueCopy " << builder << endl;
|
||||
builder.clear();
|
||||
bitSet->toString(&builder);
|
||||
cout << " bitSet " << builder;
|
||||
cout << endl;
|
||||
pvRecordField = pvRecord->findPVRecordField(pvValueRecord);
|
||||
offset = pvCopy->getCopyOffset(pvRecordField);
|
||||
cout << "getCopyOffset() " << offset;
|
||||
cout << " pvValueCopy->getOffset() " << pvValueCopy->getFieldOffset();
|
||||
cout << " pvValueRecord->getOffset() " << pvValueRecord->getFieldOffset();
|
||||
cout << " bitSet " << builder;
|
||||
cout << endl;
|
||||
bitSet->clear();
|
||||
for(size_t i=0; i<n; i++) values[i] = i + 1.0;
|
||||
convert->fromDoubleArray(pvValueRecord,0,n,get(values),0);
|
||||
builder.clear();
|
||||
bitSet->toString(&builder);
|
||||
cout << "before updateCopyFromBitSet";
|
||||
builder.clear(); pvValueRecord->toString(&builder);
|
||||
cout << " recordValue " << builder << endl;
|
||||
builder.clear(); pvValueCopy->toString(&builder);
|
||||
cout << " copyValue " << builder << endl;
|
||||
cout << " bitSet " << builder;
|
||||
cout << endl;
|
||||
bitSet->set(0);
|
||||
pvCopy->updateCopyFromBitSet(pvStructureCopy,bitSet,true);
|
||||
cout << "after updateCopyFromBitSet";
|
||||
builder.clear(); pvValueRecord->toString(&builder);
|
||||
cout << " recordValue " << builder << endl;
|
||||
builder.clear(); pvValueCopy->toString(&builder);
|
||||
cout << " copyValue " << builder << endl;
|
||||
cout << " bitSet " << builder;
|
||||
cout << endl;
|
||||
for(size_t i=0; i<n; i++) values[i] = i + 2.0;
|
||||
convert->fromDoubleArray(pvValueRecord,0,n,get(values),0);
|
||||
bitSet->set(0);
|
||||
cout << "before updateRecord";
|
||||
builder.clear(); pvValueRecord->toString(&builder);
|
||||
cout << " recordValue " << builder << endl;
|
||||
builder.clear(); pvValueCopy->toString(&builder);
|
||||
cout << " copyValue " << builder << endl;
|
||||
cout << " bitSet " << builder;
|
||||
cout << endl;
|
||||
pvCopy->updateRecord(pvStructureCopy,bitSet,true);
|
||||
cout << "after updateRecord";
|
||||
builder.clear(); pvValueRecord->toString(&builder);
|
||||
cout << " recordValue " << builder << endl;
|
||||
builder.clear(); pvValueCopy->toString(&builder);
|
||||
cout << " copyValue " << builder << endl;
|
||||
cout << " bitSet " << builder;
|
||||
cout << endl;
|
||||
}
|
||||
|
||||
static void scalarTest()
|
||||
{
|
||||
cout << endl << endl << "****scalarTest****" << endl;
|
||||
RequesterPtr requester(new MyRequester("exampleTest"));
|
||||
PVRecordPtr pvRecord;
|
||||
String request;
|
||||
PVStructurePtr pvRequest;
|
||||
PVRecordFieldPtr pvRecordField;
|
||||
PVCopyPtr pvCopy;
|
||||
String builder;
|
||||
String valueNameRecord;
|
||||
String valueNameCopy;
|
||||
|
||||
pvRecord = createScalar("doubleRecord",pvDouble,"alarm,timeStamp,display");
|
||||
valueNameRecord = request = "value";
|
||||
pvRequest = getCreateRequest()->createRequest(request,requester);
|
||||
builder.clear(); pvRequest->toString(&builder);
|
||||
cout << "request " << request << endl;
|
||||
cout << "pvRequest" << endl << builder;
|
||||
pvCopy = PVCopy::create(pvRecord,pvRequest,"");
|
||||
valueNameCopy = "value";
|
||||
testPVScalar(valueNameRecord,valueNameCopy,pvRecord,pvCopy);
|
||||
request = "";
|
||||
valueNameRecord = "value";
|
||||
pvRequest = getCreateRequest()->createRequest(request,requester);
|
||||
builder.clear(); pvRequest->toString(&builder);
|
||||
cout << "request " << request << endl << "pvRequest" << endl << builder << endl;
|
||||
pvCopy = PVCopy::create(pvRecord,pvRequest,"");
|
||||
valueNameCopy = "value";
|
||||
testPVScalar(valueNameRecord,valueNameCopy,pvRecord,pvCopy);
|
||||
request = "alarm,timeStamp,value";
|
||||
valueNameRecord = "value";
|
||||
pvRequest = getCreateRequest()->createRequest(request,requester);
|
||||
builder.clear(); pvRequest->toString(&builder);
|
||||
cout << "request " << request << endl << "pvRequest" << endl << builder << endl;
|
||||
pvCopy = PVCopy::create(pvRecord,pvRequest,"");
|
||||
valueNameCopy = "value";
|
||||
testPVScalar(valueNameRecord,valueNameCopy,pvRecord,pvCopy);
|
||||
}
|
||||
|
||||
static void arrayTest()
|
||||
{
|
||||
cout << endl << endl << "****arrayTest****" << endl;
|
||||
RequesterPtr requester(new MyRequester("exampleTest"));
|
||||
PVRecordPtr pvRecord;
|
||||
String request;
|
||||
PVStructurePtr pvRequest;
|
||||
PVRecordFieldPtr pvRecordField;
|
||||
PVCopyPtr pvCopy;
|
||||
String builder;
|
||||
String valueNameRecord;
|
||||
String valueNameCopy;
|
||||
|
||||
pvRecord = createScalarArray("doubleArrayRecord",pvDouble,"alarm,timeStamp");
|
||||
valueNameRecord = request = "value";
|
||||
pvRequest = getCreateRequest()->createRequest(request,requester);
|
||||
builder.clear(); pvRequest->toString(&builder);
|
||||
cout << "request " << request << endl;
|
||||
cout << "pvRequest" << endl << builder;
|
||||
pvCopy = PVCopy::create(pvRecord,pvRequest,"");
|
||||
valueNameCopy = "value";
|
||||
testPVScalarArray(pvDouble,valueNameRecord,valueNameCopy,pvRecord,pvCopy);
|
||||
request = "";
|
||||
valueNameRecord = "value";
|
||||
pvRequest = getCreateRequest()->createRequest(request,requester);
|
||||
builder.clear(); pvRequest->toString(&builder);
|
||||
cout << "request " << request << endl << "pvRequest" << endl << builder << endl;
|
||||
pvCopy = PVCopy::create(pvRecord,pvRequest,"");
|
||||
valueNameCopy = "value";
|
||||
testPVScalarArray(pvDouble,valueNameRecord,valueNameCopy,pvRecord,pvCopy);
|
||||
request = "alarm,timeStamp,value";
|
||||
valueNameRecord = "value";
|
||||
pvRequest = getCreateRequest()->createRequest(request,requester);
|
||||
builder.clear(); pvRequest->toString(&builder);
|
||||
cout << "request " << request << endl << "pvRequest" << endl << builder << endl;
|
||||
pvCopy = PVCopy::create(pvRecord,pvRequest,"");
|
||||
valueNameCopy = "value";
|
||||
testPVScalarArray(pvDouble,valueNameRecord,valueNameCopy,pvRecord,pvCopy);
|
||||
}
|
||||
|
||||
static void powerSupplyTest()
|
||||
{
|
||||
cout << endl << endl << "****powerSupplyTest****" << endl;
|
||||
RequesterPtr requester(new MyRequester("exampleTest"));
|
||||
PowerSupplyRecordTestPtr pvRecord;
|
||||
String request;
|
||||
PVStructurePtr pvRequest;
|
||||
PVRecordFieldPtr pvRecordField;
|
||||
PVCopyPtr pvCopy;
|
||||
String builder;
|
||||
String valueNameRecord;
|
||||
String valueNameCopy;
|
||||
|
||||
pvRecord = createPowerSupply("powerSupply");
|
||||
valueNameRecord = request = "power.value";
|
||||
pvRequest = getCreateRequest()->createRequest(request,requester);
|
||||
builder.clear(); pvRequest->toString(&builder);
|
||||
cout << "request " << request << endl;
|
||||
cout << "pvRequest" << endl << builder;
|
||||
pvCopy = PVCopy::create(pvRecord,pvRequest,"");
|
||||
valueNameCopy = "value";
|
||||
testPVScalar(valueNameRecord,valueNameCopy,pvRecord,pvCopy);
|
||||
request = "";
|
||||
valueNameRecord = "power.value";
|
||||
pvRequest = getCreateRequest()->createRequest(request,requester);
|
||||
builder.clear(); pvRequest->toString(&builder);
|
||||
cout << "request " << request << endl << "pvRequest" << endl << builder << endl;
|
||||
pvCopy = PVCopy::create(pvRecord,pvRequest,"");
|
||||
valueNameCopy = "power.value";
|
||||
testPVScalar(valueNameRecord,valueNameCopy,pvRecord,pvCopy);
|
||||
request = "alarm,timeStamp,voltage.value,power.value,current.value";
|
||||
valueNameRecord = "power.value";
|
||||
pvRequest = getCreateRequest()->createRequest(request,requester);
|
||||
builder.clear(); pvRequest->toString(&builder);
|
||||
cout << "request " << request << endl << "pvRequest" << endl << builder << endl;
|
||||
pvCopy = PVCopy::create(pvRecord,pvRequest,"");
|
||||
valueNameCopy = "power";
|
||||
testPVScalar(valueNameRecord,valueNameCopy,pvRecord,pvCopy);
|
||||
request = "alarm,timeStamp,voltage{value,alarm},power{value,alarm,display},current.value";
|
||||
valueNameRecord = "power.value";
|
||||
pvRequest = getCreateRequest()->createRequest(request,requester);
|
||||
builder.clear(); pvRequest->toString(&builder);
|
||||
cout << "request " << request << endl << "pvRequest" << endl << builder << endl;
|
||||
pvCopy = PVCopy::create(pvRecord,pvRequest,"");
|
||||
valueNameCopy = "power.value";
|
||||
testPVScalar(valueNameRecord,valueNameCopy,pvRecord,pvCopy);
|
||||
}
|
||||
|
||||
int main(int argc,char *argv[])
|
||||
{
|
||||
scalarTest();
|
||||
arrayTest();
|
||||
powerSupplyTest();
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -2,10 +2,10 @@ TOP=../..
|
||||
|
||||
include $(TOP)/configure/CONFIG
|
||||
|
||||
PROD_HOST += testRecord
|
||||
testRecord_SRCS += testRecord.cpp
|
||||
testRecord_SRCS += testRecordMain.cpp
|
||||
testRecord_LIBS += pvDatabase pvAccess pvData Com
|
||||
PROD_HOST += testExampleRecord
|
||||
testExampleRecord_SRCS += testExampleRecordMain.cpp
|
||||
testExampleRecord_LIBS += pvDatabase pvAccess pvData Com
|
||||
|
||||
|
||||
include $(TOP)/configure/RULES
|
||||
#----------------------------------------
|
||||
|
||||
126
test/record/testExampleRecordMain.cpp
Normal file
126
test/record/testExampleRecordMain.cpp
Normal file
@@ -0,0 +1,126 @@
|
||||
/*testExampleRecordMain.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 <cstddef>
|
||||
#include <cstdlib>
|
||||
#include <cstddef>
|
||||
#include <string>
|
||||
#include <cstdio>
|
||||
#include <memory>
|
||||
#include <iostream>
|
||||
|
||||
#include <epicsStdio.h>
|
||||
#include <epicsMutex.h>
|
||||
#include <epicsEvent.h>
|
||||
#include <epicsThread.h>
|
||||
|
||||
#include <epicsExport.h>
|
||||
|
||||
#include <pv/standardField.h>
|
||||
#include <pv/standardPVField.h>
|
||||
#include <pv/pvData.h>
|
||||
#include <pv/pvAccess.h>
|
||||
#include <pv/powerSupplyRecordTest.h>
|
||||
|
||||
using namespace std;
|
||||
using std::tr1::static_pointer_cast;
|
||||
using namespace epics::pvData;
|
||||
using namespace epics::pvAccess;
|
||||
using namespace epics::pvDatabase;
|
||||
|
||||
|
||||
static PVStructurePtr createPowerSupply()
|
||||
{
|
||||
FieldCreatePtr fieldCreate = getFieldCreate();
|
||||
StandardFieldPtr standardField = getStandardField();
|
||||
PVDataCreatePtr pvDataCreate = getPVDataCreate();
|
||||
size_t nfields = 5;
|
||||
StringArray names;
|
||||
names.reserve(nfields);
|
||||
FieldConstPtrArray powerSupply;
|
||||
powerSupply.reserve(nfields);
|
||||
names.push_back("alarm");
|
||||
powerSupply.push_back(standardField->alarm());
|
||||
names.push_back("timeStamp");
|
||||
powerSupply.push_back(standardField->timeStamp());
|
||||
String properties("alarm,display");
|
||||
names.push_back("voltage");
|
||||
powerSupply.push_back(standardField->scalar(pvDouble,properties));
|
||||
names.push_back("power");
|
||||
powerSupply.push_back(standardField->scalar(pvDouble,properties));
|
||||
names.push_back("current");
|
||||
powerSupply.push_back(standardField->scalar(pvDouble,properties));
|
||||
return pvDataCreate->createPVStructure(
|
||||
fieldCreate->createStructure(names,powerSupply));
|
||||
}
|
||||
|
||||
|
||||
int main(int argc,char *argv[])
|
||||
{
|
||||
StandardPVFieldPtr standardPVField = getStandardPVField();
|
||||
String properties;
|
||||
ScalarType scalarType;
|
||||
String recordName;
|
||||
properties = "alarm,timeStamp";
|
||||
scalarType = pvDouble;
|
||||
recordName = "exampleDouble";
|
||||
PVStructurePtr pvStructure;
|
||||
pvStructure = standardPVField->scalar(scalarType,properties);
|
||||
PVRecordPtr pvRecord = PVRecord::create(recordName,pvStructure);
|
||||
{
|
||||
pvRecord->lock_guard();
|
||||
pvRecord->process();
|
||||
}
|
||||
cout << "processed exampleDouble " << endl;
|
||||
recordName = "powerSupplyExample";
|
||||
pvStructure.reset();
|
||||
pvStructure = createPowerSupply();
|
||||
PowerSupplyRecordTestPtr psr =
|
||||
PowerSupplyRecordTest::create(recordName,pvStructure);
|
||||
if(psr.get()==NULL) {
|
||||
cout << "PowerSupplyRecordTest::create failed" << endl;
|
||||
return 1;
|
||||
}
|
||||
double voltage,power,current;
|
||||
{
|
||||
psr->lock_guard();
|
||||
voltage = psr->getVoltage();
|
||||
power = psr->getPower();
|
||||
current = psr->getCurrent();
|
||||
}
|
||||
cout << "initial ";
|
||||
cout << " voltage " << voltage ;
|
||||
cout << " power " << power;
|
||||
cout << " current " << current;
|
||||
cout << endl;
|
||||
voltage = 1.0;
|
||||
power = 1.0;
|
||||
cout << "before put ";
|
||||
cout << " voltage " << voltage ;
|
||||
cout << " power " << power;
|
||||
cout << endl;
|
||||
{
|
||||
psr->lock_guard();
|
||||
psr->put(power,voltage);
|
||||
psr->process();
|
||||
}
|
||||
{
|
||||
psr->lock_guard();
|
||||
cout << "after put ";
|
||||
cout << " voltage " << psr->getVoltage() ;
|
||||
cout << " power " << psr->getPower();
|
||||
cout << " current " << psr->getCurrent();
|
||||
cout << endl;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,90 +0,0 @@
|
||||
/* testRecord.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
|
||||
*/
|
||||
/* Marty Kraimer 2011.03 */
|
||||
/* This connects to a V3 record and presents the data as a PVStructure
|
||||
* It provides access to value, alarm, display, and control.
|
||||
*/
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdlib>
|
||||
#include <cstddef>
|
||||
#include <string>
|
||||
#include <cstdio>
|
||||
#include <stdexcept>
|
||||
#include <memory>
|
||||
|
||||
#include <pv/standardPVField.h>
|
||||
#include "testRecord.h"
|
||||
|
||||
|
||||
namespace epics { namespace pvDatabase {
|
||||
|
||||
using namespace epics::pvData;
|
||||
using namespace epics::pvAccess;
|
||||
using std::tr1::static_pointer_cast;
|
||||
|
||||
TestRecord::~TestRecord(){}
|
||||
|
||||
PVRecordPtr TestRecord::create(
|
||||
String const & recordName)
|
||||
{
|
||||
String properties("alarm,timeStamp,display,control,valueAlarm");
|
||||
PVStructurePtr pvStructure = getStandardPVField()->scalar(pvLong,properties);
|
||||
PVLongPtr pvValue = pvStructure->getLongField("value");
|
||||
TestRecordPtr pvRecord(
|
||||
new TestRecord(recordName,pvStructure,pvValue));
|
||||
pvRecord->init();
|
||||
PVFieldPtr pvField = pvStructure->getSubField("display.description");
|
||||
pvRecord->immediatePutOK = pvField;
|
||||
return pvRecord;
|
||||
}
|
||||
|
||||
TestRecord::TestRecord(
|
||||
String const & recordName,
|
||||
PVStructurePtr const & pvStructure,
|
||||
PVLongPtr const &pvValue)
|
||||
: PVRecord(recordName,pvStructure),
|
||||
pvValue(pvValue)
|
||||
{}
|
||||
|
||||
void TestRecord::process(
|
||||
RecordProcessRequesterPtr const &processRequester,bool alreadyLocked)
|
||||
{
|
||||
if(!alreadyLocked) lock();
|
||||
pvValue->put(pvValue->get() + 1);
|
||||
processRequester->recordProcessResult(Status::Ok);
|
||||
unlock();
|
||||
processRequester->recordProcessComplete();
|
||||
dequeueProcessRequest(processRequester);
|
||||
}
|
||||
|
||||
bool TestRecord::isSynchronous() {return true;}
|
||||
|
||||
void TestRecord::destroy()
|
||||
{
|
||||
PVRecord::destroy();
|
||||
pvValue.reset();
|
||||
immediatePutOK.reset();
|
||||
}
|
||||
|
||||
bool TestRecord::requestImmediatePut(PVFieldPtr const &pvField)
|
||||
{
|
||||
if(pvField!=immediatePutOK) return false;
|
||||
lock();
|
||||
return true;
|
||||
}
|
||||
|
||||
void TestRecord::immediatePutDone()
|
||||
{
|
||||
unlock();
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
/* testRecord.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
|
||||
*/
|
||||
#ifndef TEST_RECORD_H
|
||||
#define TEST_RECORD_H
|
||||
#include <string>
|
||||
#include <cstring>
|
||||
#include <stdexcept>
|
||||
#include <memory>
|
||||
|
||||
#include <pv/pvDatabase.h>
|
||||
|
||||
namespace epics { namespace pvDatabase {
|
||||
|
||||
class TestRecord;
|
||||
typedef std::tr1::shared_ptr<TestRecord> TestRecordPtr;
|
||||
|
||||
class TestRecord :
|
||||
public virtual PVRecord
|
||||
{
|
||||
public:
|
||||
POINTER_DEFINITIONS(TestRecord);
|
||||
static PVRecordPtr create(
|
||||
epics::pvData::String const & recordName);
|
||||
virtual ~TestRecord();
|
||||
virtual void process(
|
||||
epics::pvDatabase::RecordProcessRequesterPtr const &processRequester,
|
||||
bool alreadyLocked);
|
||||
virtual bool isSynchronous();
|
||||
virtual void destroy();
|
||||
virtual bool requestImmediatePut(epics::pvData::PVFieldPtr const &pvField);
|
||||
virtual void immediatePutDone();
|
||||
private:
|
||||
TestRecord(epics::pvData::String const & recordName,
|
||||
epics::pvData::PVStructurePtr const & pvStructure,
|
||||
epics::pvData::PVLongPtr const &pvValue);
|
||||
|
||||
epics::pvData::PVLongPtr pvValue;
|
||||
epics::pvData::PVFieldPtr immediatePutOK;
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif /* TEST_RECORD_H */
|
||||
@@ -1,378 +0,0 @@
|
||||
/*testRecordMain.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 <cstddef>
|
||||
#include <cstdlib>
|
||||
#include <cstddef>
|
||||
#include <string>
|
||||
#include <cstdio>
|
||||
#include <memory>
|
||||
#include <iostream>
|
||||
|
||||
#include <epicsStdio.h>
|
||||
#include <epicsMutex.h>
|
||||
#include <epicsEvent.h>
|
||||
#include <epicsThread.h>
|
||||
|
||||
#include <epicsExport.h>
|
||||
|
||||
#include <pv/pvIntrospect.h>
|
||||
#include <pv/pvData.h>
|
||||
#include <pv/pvAccess.h>
|
||||
#include <pv/event.h>
|
||||
|
||||
#include "testRecord.h"
|
||||
|
||||
using namespace std;
|
||||
using std::tr1::static_pointer_cast;
|
||||
using namespace epics::pvData;
|
||||
using namespace epics::pvAccess;
|
||||
using namespace epics::pvDatabase;
|
||||
|
||||
class MyPVListener;
|
||||
typedef std::tr1::shared_ptr<MyPVListener> MyPVListenerPtr;
|
||||
|
||||
class MyProcessRequester;
|
||||
typedef std::tr1::shared_ptr<MyProcessRequester> MyProcessRequesterPtr;
|
||||
|
||||
class MyPutRequester;
|
||||
typedef std::tr1::shared_ptr<MyPutRequester> MyPutRequesterPtr;
|
||||
|
||||
class MyPVListener :
|
||||
public PVListener,
|
||||
public std::tr1::enable_shared_from_this<MyPVListener>
|
||||
{
|
||||
public:
|
||||
POINTER_DEFINITIONS(PVListener);
|
||||
static MyPVListenerPtr create(
|
||||
String const & requesterName,
|
||||
PVRecordPtr const & pvRecord,
|
||||
PVRecordFieldPtr const &pvRecordField)
|
||||
{
|
||||
MyPVListenerPtr pvPVListener(
|
||||
new MyPVListener(requesterName,pvRecord,pvRecordField));
|
||||
pvPVListener->init();
|
||||
return pvPVListener;
|
||||
}
|
||||
virtual ~MyPVListener() {}
|
||||
virtual void detach(PVRecordPtr const & pvRecord)
|
||||
{
|
||||
printf("%s MyPVListener::detach\n",requesterName.c_str());
|
||||
}
|
||||
virtual void dataPut(PVRecordFieldPtr const & pvRecordField)
|
||||
{
|
||||
String fieldName = pvRecordField->getFullFieldName();
|
||||
printf("%s dataPut(requested(%s))\n",
|
||||
requesterName.c_str(),
|
||||
fieldName.c_str());
|
||||
}
|
||||
virtual void dataPut(
|
||||
PVRecordStructurePtr const & requested,
|
||||
PVRecordFieldPtr const & pvRecordField)
|
||||
{
|
||||
String requestedName = requested->getFullFieldName();
|
||||
String fieldName = pvRecordField->getFullFieldName();
|
||||
printf("%s dataPut(requested(%s),pvRecordField(%s))\n",
|
||||
requesterName.c_str(),
|
||||
requestedName.c_str(),
|
||||
fieldName.c_str());
|
||||
}
|
||||
virtual void beginGroupPut(PVRecordPtr const & pvRecord)
|
||||
{
|
||||
printf("beginGroupPut\n");
|
||||
}
|
||||
virtual void endGroupPut(PVRecordPtr const & pvRecord)
|
||||
{
|
||||
printf("endGroupPut\n");
|
||||
}
|
||||
virtual void unlisten(PVRecordPtr const & pvRecord)
|
||||
{
|
||||
printf("unlisten\n");
|
||||
}
|
||||
private:
|
||||
MyPVListenerPtr getPtrSelf()
|
||||
{
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
MyPVListener(
|
||||
String const & requesterName,
|
||||
PVRecordPtr const & pvRecord,
|
||||
PVRecordFieldPtr const &pvRecordField)
|
||||
: isDetached(false),
|
||||
requesterName(requesterName),
|
||||
pvRecord(pvRecord),
|
||||
pvRecordField(pvRecordField)
|
||||
{}
|
||||
void init() {
|
||||
pvRecord->addPVRecordClient(getPtrSelf());
|
||||
pvRecord->addListener(getPtrSelf());
|
||||
pvRecordField->addListener(getPtrSelf());
|
||||
}
|
||||
|
||||
bool isDetached;
|
||||
String requesterName;
|
||||
PVRecordPtr pvRecord;
|
||||
PVRecordFieldPtr pvRecordField;
|
||||
};
|
||||
|
||||
class MyProcessRequester :
|
||||
public virtual Requester,
|
||||
public virtual RecordProcessRequester,
|
||||
public std::tr1::enable_shared_from_this<MyProcessRequester>
|
||||
{
|
||||
public:
|
||||
static MyProcessRequesterPtr create(
|
||||
String const &requesterName,
|
||||
PVRecordPtr const & pvRecord)
|
||||
{
|
||||
MyProcessRequesterPtr pvProcessRequester(
|
||||
new MyProcessRequester(requesterName,pvRecord));
|
||||
pvProcessRequester->init();
|
||||
return pvProcessRequester;
|
||||
}
|
||||
bool process()
|
||||
{
|
||||
if(isDetached) {
|
||||
message("process request but detached",errorMessage);
|
||||
return false;
|
||||
}
|
||||
pvRecord->queueProcessRequest(getPtrSelf());
|
||||
event.wait();
|
||||
return true;
|
||||
}
|
||||
virtual ~MyProcessRequester() {}
|
||||
virtual void detach(PVRecordPtr const & pvRecord)
|
||||
{
|
||||
isDetached = true;
|
||||
message("detached",infoMessage);
|
||||
}
|
||||
virtual String getRequesterName() {return requesterName;}
|
||||
virtual void message(
|
||||
String const & message,
|
||||
MessageType messageType)
|
||||
{
|
||||
String messageTypeName = getMessageTypeName(messageType);
|
||||
printf("%s %s %s\n",
|
||||
requesterName.c_str(),
|
||||
message.c_str(),
|
||||
messageTypeName.c_str());
|
||||
}
|
||||
virtual void recordDestroyed()
|
||||
{
|
||||
printf("%s MyProcessRequester::recordDestroyed\n",
|
||||
requesterName.c_str());
|
||||
}
|
||||
virtual void becomeProcessor()
|
||||
{
|
||||
pvRecord->process(getPtrSelf(),false);
|
||||
}
|
||||
virtual void recordProcessResult(epics::pvData::Status status)
|
||||
{
|
||||
String xxx("recordProcessResult ");
|
||||
message( xxx + status.getMessage(),infoMessage);
|
||||
}
|
||||
virtual void recordProcessComplete()
|
||||
{
|
||||
message("recordProcessComplete",infoMessage);
|
||||
event.signal();
|
||||
}
|
||||
private:
|
||||
MyProcessRequesterPtr getPtrSelf()
|
||||
{
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
MyProcessRequester(
|
||||
String const &requesterName,
|
||||
PVRecordPtr const & pvRecord)
|
||||
: isDetached(false),
|
||||
requesterName(requesterName),
|
||||
pvRecord(pvRecord)
|
||||
{}
|
||||
void init() {
|
||||
pvRecord->addPVRecordClient(getPtrSelf());
|
||||
pvRecord->addRequester(getPtrSelf());
|
||||
}
|
||||
|
||||
Event event;
|
||||
bool isDetached;
|
||||
String requesterName;
|
||||
PVRecordPtr pvRecord;
|
||||
};
|
||||
|
||||
class MyPutRequester :
|
||||
public virtual RecordPutRequester,
|
||||
public std::tr1::enable_shared_from_this<MyPutRequester>
|
||||
{
|
||||
public:
|
||||
MyPutRequester(PVRecordPtr const & pvRecord)
|
||||
: pvRecord(pvRecord),
|
||||
result(false)
|
||||
{}
|
||||
virtual ~MyPutRequester() {}
|
||||
virtual void requestResult(bool result)
|
||||
{
|
||||
this->result = result;
|
||||
event.signal();
|
||||
}
|
||||
bool makeRequest()
|
||||
{
|
||||
pvRecord->queuePutRequest(getPtrSelf());
|
||||
event.wait();
|
||||
return result;
|
||||
}
|
||||
private:
|
||||
MyPutRequesterPtr getPtrSelf()
|
||||
{
|
||||
return shared_from_this();
|
||||
}
|
||||
Event event;
|
||||
PVRecordPtr pvRecord;
|
||||
bool result;
|
||||
};
|
||||
|
||||
|
||||
|
||||
void dumpPVRecordField(PVRecordFieldPtr pvRecordField)
|
||||
{
|
||||
PVRecordStructurePtr pvRecordStructure = pvRecordField->getParent();
|
||||
PVFieldPtr pvField = pvRecordField->getPVField();
|
||||
String fieldName = pvField->getFieldName();
|
||||
String fullFieldName = pvRecordField->getFullFieldName();
|
||||
String fullName = pvRecordField->getFullName();
|
||||
PVRecordPtr pvRecord = pvRecordField->getPVRecord();
|
||||
String recordName = pvRecord->getRecordName();
|
||||
printf("recordName %s fullName %s fullFieldName %s fieldName %s\n",
|
||||
recordName.c_str(),
|
||||
fullName.c_str(),
|
||||
fullFieldName.c_str(),
|
||||
fieldName.c_str());
|
||||
}
|
||||
|
||||
void dumpPVRecordStructure(PVRecordStructurePtr pvRecordStructure)
|
||||
{
|
||||
dumpPVRecordField(pvRecordStructure);
|
||||
PVRecordFieldPtrArrayPtr pvRecordFields =
|
||||
pvRecordStructure->getPVRecordFields();
|
||||
size_t num = pvRecordFields->size();
|
||||
for(size_t i=0; i<num; i++) {
|
||||
PVRecordFieldPtr pvRecordField = (*pvRecordFields.get())[i];
|
||||
if(pvRecordField->getPVField()->getField()->getType()==structure) {
|
||||
PVRecordStructurePtr xxx =
|
||||
static_pointer_cast<PVRecordStructure>(pvRecordField);
|
||||
dumpPVRecordStructure(xxx);
|
||||
} else {
|
||||
dumpPVRecordField(pvRecordField);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc,char *argv[])
|
||||
{
|
||||
String recordName("testRecord");
|
||||
PVRecordPtr pvRecord = TestRecord::create(recordName);
|
||||
dumpPVRecordStructure(pvRecord->getPVRecordStructure());
|
||||
PVStructurePtr pvStructure =
|
||||
pvRecord->getPVRecordStructure()->getPVStructure();
|
||||
PVLongPtr pvValue = pvStructure->getLongField("value");
|
||||
String builder;
|
||||
pvStructure->toString(&builder);
|
||||
printf("pvStructure\n%s\n",builder.c_str());
|
||||
builder.clear();
|
||||
pvValue->toString(&builder);
|
||||
printf("value\n%s\n",builder.c_str());
|
||||
PVRecordFieldPtr recordFieldValue = pvRecord->findPVRecordField(pvValue);
|
||||
MyPVListenerPtr listenTop = MyPVListener::create(
|
||||
"listenTop", pvRecord, pvRecord->getPVRecordStructure());
|
||||
MyPVListenerPtr listenValue = MyPVListener::create(
|
||||
"listenValue", pvRecord,recordFieldValue);
|
||||
|
||||
PVFieldPtr pvDisplay = pvStructure->getSubField("display");
|
||||
PVRecordFieldPtr recordFieldDisplay =
|
||||
pvRecord->findPVRecordField(pvDisplay);
|
||||
MyPVListenerPtr listenDisplay = MyPVListener::create(
|
||||
"listenDisplay", pvRecord,recordFieldDisplay);
|
||||
|
||||
PVStringPtr pvDisplayDescription =
|
||||
pvStructure->getStringField("display.description");
|
||||
PVRecordFieldPtr recordFieldDisplayDescription =
|
||||
pvRecord->findPVRecordField(pvDisplayDescription);
|
||||
MyPVListenerPtr listenDisplayDescription = MyPVListener::create(
|
||||
"listenDisplayDescription", pvRecord,recordFieldDisplayDescription);
|
||||
|
||||
recordFieldDisplayDescription->message("test message",infoMessage);
|
||||
|
||||
MyProcessRequesterPtr process1 =
|
||||
MyProcessRequester::create("process1",pvRecord);
|
||||
MyProcessRequesterPtr process2 =
|
||||
MyProcessRequester::create("process2",pvRecord);
|
||||
process1->process();
|
||||
builder.clear();
|
||||
pvValue->toString(&builder);
|
||||
printf("%s\n",builder.c_str());
|
||||
process2->process();
|
||||
builder.clear();
|
||||
pvValue->toString(&builder);
|
||||
printf("%s\n",builder.c_str());
|
||||
bool requestResult;
|
||||
requestResult = pvRecord->requestImmediatePut(pvValue);
|
||||
if(requestResult) {
|
||||
printf("error requestImmediatePut for pvValue returned true");
|
||||
pvRecord->immediatePutDone();
|
||||
}
|
||||
requestResult = pvRecord->requestImmediatePut(pvDisplayDescription);
|
||||
if(!requestResult) {
|
||||
printf("error requestImmediatePut for pvDisplayDescription returned false");
|
||||
} else {
|
||||
pvDisplayDescription->put("this is description");
|
||||
pvRecord->immediatePutDone();
|
||||
}
|
||||
|
||||
MyPutRequesterPtr myPut(new MyPutRequester(pvRecord));
|
||||
requestResult = myPut->makeRequest();
|
||||
if(!requestResult) {
|
||||
printf("error myPut->makeRequest() returned false");
|
||||
} else {
|
||||
pvDisplayDescription->put("this is new description");
|
||||
pvValue->put(1000);
|
||||
PVIntPtr pvSeverity = pvStructure->getIntField("alarm.severity");
|
||||
pvSeverity->put(3);
|
||||
PVIntPtr pvStatus = pvStructure->getIntField("alarm.status");
|
||||
pvStatus->put(2);
|
||||
PVStringPtr pvMessage = pvStructure->getStringField("alarm.message");
|
||||
pvMessage->put("alarmMessage");
|
||||
pvRecord->putDone(myPut);
|
||||
}
|
||||
|
||||
builder.clear();
|
||||
pvStructure->toString(&builder);
|
||||
printf("pvStructure\n%s\n",builder.c_str());
|
||||
builder.clear();
|
||||
|
||||
pvRecord->destroy();
|
||||
printf("all done\n");
|
||||
#ifdef XXXXXX
|
||||
PVDatabasePtr pvDatabase = PVDatabase::getMaster();
|
||||
pvDatabase->addRecord(pvRecord);
|
||||
cout << recordName << "\n";
|
||||
string str;
|
||||
while(true) {
|
||||
cout << "Type exit to stop: \n";
|
||||
getline(cin,str);
|
||||
if(str.compare("exit")==0) break;
|
||||
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user