NTField::createAlarmLimit removed; NTNameValue names,values changed to name,value

This commit is contained in:
Marty Kraimer
2014-09-23 08:50:49 -04:00
parent 9c7cd05437
commit dbc5c434cb
8 changed files with 106 additions and 97 deletions

View File

@ -37,7 +37,7 @@
<h1>EPICS ntCPP</h1>
<!-- Maturity: Working Draft or Request for Comments, or Recommendation, and date. -->
<h2 class="nocount">EPICS v4 Working Group, Working Draft, 19-Sept-2014</h2>
<h2 class="nocount">EPICS v4 Working Group, Working Draft, 22-Sept-2014</h2>
<dl>
<dt>Latest version:</dt>
@ -80,7 +80,7 @@ V4 control system programming environment:<br />
<h2 class="nocount">Status of this Document</h2>
<p>This is the 19-Sept-2014 version of the C++ implementation of pvData.
<p>This is the 22-Sept-2014 version of the C++ implementation of pvData.
</p>
@ -138,7 +138,7 @@ The extra fields are for specialized tools.
A helper class NTField is provided to enforce the proper implementation of property fields
as defined by pvData.
A property field is normally associated with a field that has the name "value".
The property fields currently used are alarm, timeStamp, display, control, and valueAlarm.
The property fields currently used are alarm, timeStamp, display, control, and alarmLimit.
In addition pvData defines a standard structure for a value field that represents
enumerated values.
NTField has methods associated with each of these.
@ -172,7 +172,6 @@ public:
StructureConstPtr createTimeStamp();
StructureConstPtr createAlarm();
StructureConstPtr createDisplay();
StructureConstPtr createAlarmLimit();
StructureConstPtr createControl();
StructureArrayConstPtr createEnumeratedArray();
@ -202,8 +201,6 @@ public:
<dd>Create an interspection interface for an alarm structure.</dd>
<dt>createDisplay</dt>
<dd>Create an introsepecion interface for a display structure.</dd>
<dt>createAlarmLimit</dt>
<dd>Create an introspection interface for an alarm limit structure.</dd>
<dt>createControl</dt>
<dd>Create an introspection interface for a control structure.</dd>
<dt>createEnumeratedArray</dt>
@ -344,9 +341,18 @@ structure display
</pre>
<p>Note that the format should be a simplifed version of the standard
C formattimg conventions.</p>
<h3>enumerated</h3>
<p>This is used to specify a set of choices and an index that selects one
of the choices.
For readers familiar with EPICS core this is like the ENUM types.</p>
<pre>
structure
int index
string[] choices
</pre>
<h3>alarmLimit</h3>
<p>This is used to specify alarm limits for a numeric scalar value field.
It can be used by plotting tools to show alarm limits and asociated severities.
<p>This is used to specify alarm limits for a double scalar value field.
It can be used by plotting tools to show alarm limits and associated severities.
</p>
<pre>
structure
@ -361,15 +367,23 @@ structure
int highAlarmSeverity
double hysteresis
</pre>
<h3>enumerated</h3>
<p>This is used to specify a set of choices and an index that selects one
of the choices.
For readers familiar with EPICS core this is like the ENUM types.</p>
<pre>
structure
int index
string[] choices
</pre>
<p><b>NOTE:</b> NTField, described above, has support for checking to see if
a structure is an alarmLimit structure but no other support for alarmLimit.</p>
PVData has support named <b>valueAlarm</b> instead of <b>alarmLimit</b>
(alarmLimit is identical to valueAlarm for type double).
For numeric types the field names are the same but the type
for lowAlarmLimit, lowWarningLimit, highWarningLimit, and highAlarmLimit
is based on the scalarType.
PVData also defines valueAlarm for a scalar boolean value field
and for an enumerated structure.
For these completely different field names are defined.
valueAlarm is more for use by servers than for clients.
Thus normative types only defines alarmLimit since this is what
clients like plot tools use.
If the valueAlarm fields, including alarmLimit, are desired than the standardField support from
PVData can be used to generate a valueAlarm field as an extra field.
</p>
<h2>Normative Type Common Features</h2>
<p>Each normative type has two classes: a builder and a class for the normative type itself.</p>
@ -391,13 +405,13 @@ and a method to add extra fields.</p>
This has methods to do the following:</p>
<dl>
<dt>Create instance</dt>
<dd>A instance of a object can be created via a builder of from an existing PVStructure</dd>
<dd>A instance of a object can be created via a builder or from an existing PVStructure</dd>
<dt>Attach a Property</dt>
<dd>For the following optional fields an object to manipulate the fields can be attached:
alarm, timeStamp, display, and control.</dd>
<dt>Get Data Interfaces</dt>
<dd>Each type has a method getPVStructure to get the entire data structure.
In addition there is a method to get the data interface for each manditory
In addition there is a method to get the data interface for each mandatory
and optional field.</dd>
</dl>
<h2>Normative Type NTScalar</h2>
@ -477,7 +491,7 @@ where
<dd>create an PVScalar instance.</dd>
<dt>add</dt>
<dd>Add an extra field. As many fields as desired can be added but each must have
a unique name that is not the name of any manditory or possible optional field.</dd>
a unique name that is not the name of any mandatory or possible optional field.</dd>
</dl>
<p>An NTScalaBuilder can be used to create multiple PVStructure and/or NTScalar instances.
Each time createPVScalar is called it clears all interval data after the PVStructure
@ -719,7 +733,7 @@ where
<dd>create an PVScalar instance.</dd>
<dt>add</dt>
<dd>Add an extra field. As many fields as desired can be added but each must have
a unique name that is not the name of any manditory or possible optional field.</dd>
a unique name that is not the name of any mandatory or possible optional field.</dd>
</dl>
<h3>NTScalarArray</h3>
<p><b>ntscalarArray.h</b> defines the following:</p>
@ -878,7 +892,7 @@ where
<dd>create an PVScalar instance.</dd>
<dt>add</dt>
<dd>Add an extra field. As many fields as desired can be added but each must have
a unique name that is not the name of any manditory or possible optional field.</dd>
a unique name that is not the name of any mandatory or possible optional field.</dd>
</dl>
<h3>NTNameValue</h3>
@ -1019,7 +1033,7 @@ where
<dd>create an PVScalar instance.</dd>
<dt>add</dt>
<dd>Add an extra field. As many fields as desired can be added but each must have
a unique name that is not the name of any manditory or possible optional field.</dd>
a unique name that is not the name of any mandatory or possible optional field.</dd>
</dl>
<h3>NTTable</h3>
<pre>
@ -1174,7 +1188,7 @@ where
<dd>create an PVScalar instance.</dd>
<dt>add</dt>
<dd>Add an extra field. As many fields as desired can be added but each must have
a unique name that is not the name of any manditory or possible optional field.</dd>
a unique name that is not the name of any mandatory or possible optional field.</dd>
</dl>
<h3>NTMultiChannel</h3>
<pre>
@ -1363,7 +1377,7 @@ where
<dd>create an PVScalar instance.</dd>
<dt>add</dt>
<dd>Add an extra field. As many fields as desired can be added but each must have
a unique name that is not the name of any manditory or possible optional field.</dd>
a unique name that is not the name of any mandatory or possible optional field.</dd>
</dl>
<h3>NTNDArray</h3>
<pre>

View File

@ -154,15 +154,23 @@ bool NTField::isAlarmLimit(FieldConstPtr const & field)
f = fields[1];
if(names[1].compare("lowAlarmLimit")!=0) return false;
if(f->getType()!=scalar) return false;
s = static_pointer_cast<const Scalar>(f);
if(s->getScalarType()!=pvDouble) return false;
f = fields[2];
if(names[2].compare("lowWarningLimit")!=0) return false;
if(f->getType()!=scalar) return false;
s = static_pointer_cast<const Scalar>(f);
if(s->getScalarType()!=pvDouble) return false;
f = fields[3];
if(names[3].compare("highWarningLimit")!=0) return false;
if(f->getType()!=scalar) return false;
s = static_pointer_cast<const Scalar>(f);
if(s->getScalarType()!=pvDouble) return false;
f = fields[4];
if(names[4].compare("highAlarmLimit")!=0) return false;
if(f->getType()!=scalar) return false;
s = static_pointer_cast<const Scalar>(f);
if(s->getScalarType()!=pvDouble) return false;
f = fields[5];
if(names[5].compare("lowAlarmSeverity")!=0) return false;
if(f->getType()!=scalar) return false;
@ -235,11 +243,6 @@ StructureConstPtr NTField::createDisplay()
return standardField->display();
}
StructureConstPtr NTField::createAlarmLimit()
{
return standardField->doubleAlarm();
}
StructureConstPtr NTField::createControl()
{
return standardField->control();
@ -306,12 +309,6 @@ PVStructurePtr PVNTField::createDisplay()
return pvDataCreate->createPVStructure(display);
}
PVStructurePtr PVNTField::createAlarmLimit()
{
StructureConstPtr structure = NTField::get()->createAlarmLimit();
return pvDataCreate->createPVStructure(structure);
}
PVStructurePtr PVNTField::createControl()
{

View File

@ -99,11 +99,6 @@ public:
* @return a displayalarm structure.
*/
StructureConstPtr createDisplay();
/**
* Create an alarmLimit structure.
* @return an alarmLimit structure.
*/
StructureConstPtr createAlarmLimit();
/**
* Create a control structure.
* @return a control structure.

View File

@ -34,8 +34,8 @@ StructureConstPtr NTNameValueBuilder::createStructure()
FieldBuilderPtr builder =
getFieldCreate()->createFieldBuilder()->
setId(NTNameValue::URI)->
addArray("names", pvString)->
addArray("values", valueType);
addArray("name", pvString)->
addArray("value", valueType);
if (descriptor)
builder->add("descriptor", pvString);
@ -130,10 +130,10 @@ bool NTNameValue::is_a(StructureConstPtr const & structure)
bool NTNameValue::is_compatible(PVStructurePtr const & pvStructure)
{
PVStringArrayPtr pvNames = pvStructure->getSubField<PVStringArray>("names");
if(!pvNames) return false;
PVFieldPtr pvValues = pvStructure->getSubField("values");
if(!pvValues) return false;
PVStringArrayPtr pvName = pvStructure->getSubField<PVStringArray>("name");
if(!pvName) return false;
PVFieldPtr pvValue = pvStructure->getSubField("value");
if(!pvValue) return false;
PVFieldPtr pvField = pvStructure->getSubField("descriptor");
if(pvField && !pvStructure->getSubField<PVString>("descriptor")) return false;
pvField = pvStructure->getSubField("alarm");
@ -186,14 +186,14 @@ PVStructurePtr NTNameValue::getAlarm() const
return pvNTNameValue->getSubField<PVStructure>("alarm");
}
PVStringArrayPtr NTNameValue::getNames() const
PVStringArrayPtr NTNameValue::getName() const
{
return pvNTNameValue->getSubField<PVStringArray>("names");
return pvNTNameValue->getSubField<PVStringArray>("name");
}
PVFieldPtr NTNameValue::getValues() const
PVFieldPtr NTNameValue::getValue() const
{
return pvNTNameValue->getSubField("values");
return pvNTNameValue->getSubField("value");
}
NTNameValue::NTNameValue(PVStructurePtr const & pvStructure) :

View File

@ -200,25 +200,25 @@ public:
epics::pvData::PVStructurePtr getAlarm() const;
/**
* Get the names array field.
* @return The PVStringArray for the names.
* Get the name array field.
* @return The PVStringArray for the name.
*/
epics::pvData::PVStringArrayPtr getNames() const;
epics::pvData::PVStringArrayPtr getName() const;
/**
* Get the value array field.
* @return The PVField for the values.
* @return The PVField for the value.
*/
epics::pvData::PVFieldPtr getValues() const;
epics::pvData::PVFieldPtr getValue() const;
/**
* Get the value array field of a specified type (e.g. PVDoubleArray).
* @return The <PVT> array for the values.
* @return The <PVT> array for the value.
*/
template<typename PVT>
std::tr1::shared_ptr<PVT> getValues() const
std::tr1::shared_ptr<PVT> getValue() const
{
epics::pvData::PVFieldPtr pvField = getValues();
epics::pvData::PVFieldPtr pvField = getValue();
if (pvField.get())
return std::tr1::dynamic_pointer_cast<PVT>(pvField);
else

View File

@ -47,7 +47,7 @@ void testNTField()
cout << *structureConstPtr << endl;
testOk1(ntField->isDisplay(structureConstPtr));
structureConstPtr = ntField->createAlarmLimit();
structureConstPtr = standardField->doubleAlarm();
cout << *structureConstPtr << endl;
testOk1(ntField->isAlarmLimit(structureConstPtr));
@ -92,7 +92,7 @@ void testPVNTField()
cout << *pvStructure << endl;
testOk1(ntField->isDisplay(pvStructure->getStructure()));
pvStructure = PVStructurePtr(pvntField->createAlarmLimit());
pvStructure = PVStructurePtr(pvDataCreate->createPVStructure(standardField->doubleAlarm()));
cout << *pvStructure << endl;
testOk1(ntField->isAlarmLimit(pvStructure->getStructure()));

View File

@ -37,14 +37,14 @@ void test_builder()
testOk1(NTNameValue::is_a(structure));
testOk1(structure->getID() == NTNameValue::URI);
testOk1(structure->getNumberFields() == 7);
testOk1(structure->getField("names").get() != 0);
testOk1(structure->getField("values").get() != 0);
testOk1(structure->getField("name").get() != 0);
testOk1(structure->getField("value").get() != 0);
testOk1(structure->getField("descriptor").get() != 0);
testOk1(structure->getField("alarm").get() != 0);
testOk1(structure->getField("timeStamp").get() != 0);
testOk(dynamic_pointer_cast<const ScalarArray>(structure->getField("values")).get() != 0 &&
dynamic_pointer_cast<const ScalarArray>(structure->getField("values"))->getElementType() == pvDouble, "value array element type");
testOk(dynamic_pointer_cast<const ScalarArray>(structure->getField("value")).get() != 0 &&
dynamic_pointer_cast<const ScalarArray>(structure->getField("value"))->getElementType() == pvDouble, "value array element type");
std::cout << *structure << std::endl;
@ -85,50 +85,50 @@ void test_ntnameValue()
testOk1(ntNameValue->getDescriptor().get() != 0);
testOk1(ntNameValue->getAlarm().get() != 0);
testOk1(ntNameValue->getTimeStamp().get() != 0);
testOk1(ntNameValue->getNames().get() != 0);
testOk1(ntNameValue->getValues().get() != 0);
testOk1(ntNameValue->getName().get() != 0);
testOk1(ntNameValue->getValue().get() != 0);
//
// example how to set names
// example how to set name
//
PVStringArray::svector newNames;
newNames.push_back("name1");
newNames.push_back("name2");
newNames.push_back("name3");
PVStringArray::svector newName;
newName.push_back("name1");
newName.push_back("name2");
newName.push_back("name3");
PVStringArrayPtr pvNamesField = ntNameValue->getNames();
pvNamesField->replace(freeze(newNames));
PVStringArrayPtr pvNameField = ntNameValue->getName();
pvNameField->replace(freeze(newName));
//
// example how to get names
// example how to get name
//
PVStringArray::const_svector names(pvNamesField->view());
PVStringArray::const_svector name(pvNameField->view());
testOk1(names.size() == 3);
testOk1(names[0] == "name1");
testOk1(names[1] == "name2");
testOk1(names[2] == "name3");
testOk1(name.size() == 3);
testOk1(name[0] == "name1");
testOk1(name[1] == "name2");
testOk1(name[2] == "name3");
//
// example how to set values
// example how to set value
//
PVIntArray::svector newValues;
newValues.push_back(1);
newValues.push_back(2);
newValues.push_back(8);
PVIntArray::svector newValue;
newValue.push_back(1);
newValue.push_back(2);
newValue.push_back(8);
PVIntArrayPtr pvValueField = ntNameValue->getValues<PVIntArray>();
pvValueField->replace(freeze(newValues));
PVIntArrayPtr pvValueField = ntNameValue->getValue<PVIntArray>();
pvValueField->replace(freeze(newValue));
//
// example how to get column values
// example how to get column value
//
PVIntArray::const_svector values(pvValueField->view());
PVIntArray::const_svector value(pvValueField->view());
testOk1(values.size() == 3);
testOk1(values[0] == 1);
testOk1(values[1] == 2);
testOk1(values[2] == 8);
testOk1(value.size() == 3);
testOk1(value[0] == 1);
testOk1(value[1] == 2);
testOk1(value[2] == 8);
//
// timeStamp ops
@ -232,8 +232,8 @@ void test_extra()
testOk1(NTNameValue::is_a(structure));
testOk1(structure->getID() == NTNameValue::URI);
testOk1(structure->getNumberFields() == 4);
testOk1(structure->getField("names").get() != 0);
testOk1(structure->getField("values").get() != 0);
testOk1(structure->getField("name").get() != 0);
testOk1(structure->getField("value").get() != 0);
testOk1(structure->getField("timeStamp").get() != 0);
testOk1(structure->getField("function").get() != 0);

View File

@ -9,11 +9,13 @@
#include <pv/nt.h>
using namespace epics::nt;
using namespace epics::pvData;
using std::tr1::dynamic_pointer_cast;
static FieldCreatePtr fieldCreate = getFieldCreate();
static StandardFieldPtr standardField = getStandardField();
void test_builder()
{
testDiag("test_builder");
@ -28,8 +30,8 @@ void test_builder()
addTimeStamp()->
addDisplay()->
addControl()->
add("extra1",fieldCreate->createScalar(pvString)) ->
add("extra2",fieldCreate->createScalarArray(pvString)) ->
add("valueAlarm",standardField->doubleAlarm()) ->
add("extra",fieldCreate->createScalarArray(pvString)) ->
createStructure();
testOk1(structure.get() != 0);
if (!structure)
@ -80,6 +82,7 @@ void test_ntscalar()
addTimeStamp()->
addDisplay()->
addControl()->
add("valueAlarm",standardField->intAlarm()) ->
create();
testOk1(ntScalar.get() != 0);