major changes to monitor. Bug in Convert::copyScalar (change every break to rerurn); minor change to StandardPVField and queueVoid

This commit is contained in:
Marty Kraimer
2011-04-05 08:37:16 -04:00
parent 617871ece9
commit 323a2d7321
8 changed files with 230 additions and 88 deletions

View File

@@ -13,7 +13,7 @@
<p>TODO</p>
<ul>
<li>rename epicsException to exception. Do we want assert under pvData? I
<li>rename epicsException to Exception. Do we want assert under pvData? I
think yes. Can it generate stack trace?</li>
<li>pvMiscBitSetUtil has not been tested.</li>
<li>Change all throw statements so that they generated stack trace.</li>

View File

@@ -89,6 +89,8 @@ LIBSRCS += bitSetUtil.cpp
SRC_DIRS += $(PVDATA)/monitor
INC += monitor.h
INC += monitorQueue.h
LIBSRCS += monitorQueue.cpp
LIBRARY=pvData

View File

@@ -315,49 +315,49 @@ void Convert::copyScalar(PVScalar *from, PVScalar *to)
PVBoolean *dataTo = static_cast<PVBoolean*>(to);
dataTo->put(value);
}
break;
return;
}
case pvByte : {
PVByte *data = static_cast<PVByte*>(from);
int8 value = data->get();
convert->fromByte(to,value);
break;
return;
}
case pvShort : {
PVShort *data = static_cast<PVShort*>(from);
short value = data->get();
convert->fromShort(to,value);
break;
return;
}
case pvInt :{
PVInt *data = static_cast<PVInt*>(from);
int value = data->get();
convert->fromInt(to,value);
break;
return;
}
case pvLong : {
PVLong *data = static_cast<PVLong*>(from);
long value = data->get();
convert->fromLong(to,value);
break;
return;
}
case pvFloat : {
PVFloat *data = static_cast<PVFloat*>(from);
float value = data->get();
convert->fromFloat(to,value);
break;
return;
}
case pvDouble : {
PVDouble *data = static_cast<PVDouble*>(from);
double value = data->get();
convert->fromDouble(to,value);
break;
return;
}
case pvString: {
PVString *data = static_cast<PVString*>(from);
String value = data->get();
convert->fromString(to,value);
break;
return;
}
}
String message("Convert::copyScalar should never get here");

View File

@@ -223,7 +223,6 @@ PVStructure * StandardPVField::enumeratedValue(PVStructure *parent,
PVStringArray *pvChoices = static_cast<PVStringArray *>(pvScalarArray);
pvChoices->put(0,number,choices,0);
return pvStructure;
return pvDataCreate->createPVStructure(parent,field);
}
PVStructure * StandardPVField::alarm(PVStructure *parent)

View File

@@ -92,7 +92,7 @@ QueueElementVoid * QueueVoid::getFree()
void QueueVoid::setUsed(QueueElementVoid *queueElement)
{
if(queueElement!=array[nextSetUsed++]) {
throw std::logic_error(String("not correcect queueElement"));
throw std::logic_error(String("not correct queueElement"));
}
numberUsed++;
if(nextSetUsed>=number) nextSetUsed = 0;

View File

@@ -9,86 +9,39 @@
#include <status.h>
#include <destroyable.h>
#include <sharedPtr.h>
#include <pvData.h>
namespace epics { namespace pvData {
/**
* Class instance representing monitor element.
* @author mrk
*/
class MonitorElement {
public:
/**
* Get the PVStructure.
* @return The PVStructure.
*/
virtual PVStructure* getPVStructure() = 0;
/**
* Get the bitSet showing which fields have changed.
* @return The bitSet.
*/
virtual BitSet* getChangedBitSet() = 0;
/**
* Get the bitSet showing which fields have been changed more than once.
* @return The bitSet.
*/
virtual BitSet* getOverrunBitSet() = 0;
};
/**
* Interface for Monitor.
* @author mrk
*/
class Monitor : public Destroyable, private NoDefaultMethods {
public:
/**
* Start monitoring.
* @return completion status.
*/
virtual Status start() = 0;
/**
* Stop Monitoring.
* @return completion status.
*/
virtual Status stop() = 0;
/**
* If monitor has occurred return data.
* @return monitorElement for modified data on null if no monitors have occurred.
*/
virtual MonitorElement* poll() = 0;
/**
* Release a MonitorElement that was returned by poll.
* @param monitorElement
*/
virtual void release(MonitorElement* monitorElement) = 0;
};
/**
* Requester for ChannelMonitor.
* @author mrk
*/
class MonitorRequester : public virtual Requester {
public:
/**
* The client and server have both completed the createMonitor request.
* @param status Completion status.
* @param monitor The monitor
* @param structure The structure defining the data.
*/
virtual void monitorConnect(const Status &status, Monitor* monitor, Structure* structure) = 0;
/**
* A monitor event has occurred. The requester must call Monitor.poll to get data.
* @param monitor The monitor.
*/
virtual void monitorEvent(Monitor* monitor) = 0;
/**
* The data source is no longer available.
* @param monitor The monitor.
*/
virtual void unlisten(Monitor* monitor) = 0;
};
class MonitorElement {
public:
MonitorElement(){}
virtual ~MonitorElement(){}
virtual PVStructure* getPVStructure() = 0;
virtual BitSet* getChangedBitSet() = 0;
virtual BitSet* getOverrunBitSet() = 0;
};
class Monitor : public virtual Destroyable{
public:
Monitor(){}
virtual ~Monitor(){}
virtual Status start() = 0;
virtual Status stop() = 0;
virtual MonitorElement* poll() = 0;
virtual void release(MonitorElement* monitorElement) = 0;
};
class MonitorRequester : public virtual Requester {
public:
MonitorRequester() {}
virtual ~MonitorRequester() {}
virtual void monitorConnect(
const Status &status, Monitor* monitor, StructureConstPtr structure) = 0;
virtual void monitorEvent(Monitor* monitor) = 0;
virtual void unlisten(Monitor* monitor) = 0;
};
}}
#endif /* MONITOR_H */

View File

@@ -0,0 +1,146 @@
/* monitorQueue.cpp */
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
/* Marty Kraimer 2011.03 */
#include <bitSet.h>
#include "monitorQueue.h"
namespace epics { namespace pvData {
typedef QueueElement<MonitorElement> MonitorQueueElement;
class MonitorElementImpl : public MonitorElement {
public:
MonitorElementImpl(PVStructure *pvStructure);
~MonitorElementImpl(){}
virtual PVStructure* getPVStructure();
virtual BitSet* getChangedBitSet();
virtual BitSet* getOverrunBitSet();
void setQueueElement(MonitorQueueElement *queueElement);
MonitorQueueElement *getQueueElement();
private:
PVStructure *pvStructure;
std::auto_ptr<BitSet> changedBitSet;
std::auto_ptr<BitSet> overrunBitSet;
MonitorQueueElement *queueElement;
};
MonitorElementImpl::MonitorElementImpl(PVStructure *pvStructure)
: pvStructure(pvStructure),
changedBitSet(std::auto_ptr<BitSet>(new BitSet(pvStructure->getNumberFields()))),
overrunBitSet(std::auto_ptr<BitSet>(new BitSet(pvStructure->getNumberFields()))),
queueElement(0)
{}
PVStructure* MonitorElementImpl::getPVStructure()
{
return pvStructure;
}
BitSet* MonitorElementImpl::getChangedBitSet()
{
return changedBitSet.get();
}
BitSet* MonitorElementImpl::getOverrunBitSet()
{
return overrunBitSet.get();
}
void MonitorElementImpl::setQueueElement(MonitorQueueElement *queueElement)
{
this->queueElement = queueElement;
}
MonitorQueueElement *MonitorElementImpl::getQueueElement()
{
return queueElement;
}
MonitorQueue::MonitorQueue(MonitorElement** elements,int number)
: number(number),
elements(elements),
queue(new Queue<MonitorElement>(elements,number))
{
if(number<2) {
throw std::logic_error(String("queueSize must be >=2"));
}
MonitorQueueElement *queueElement;
for(int i=0; i<number;i++) {
queueElement = queue->getFree();
MonitorElementImpl *temp =
static_cast<MonitorElementImpl*>(queueElement->getObject());
temp->setQueueElement(queueElement);
queue->setUsed(queueElement);
queue->releaseUsed(queueElement);
}
}
MonitorQueue::~MonitorQueue()
{
delete queue;
for(int i=0; i<number; i++) {
delete elements[i];
}
delete[] elements;
}
MonitorElement** MonitorQueue::createElements(PVStructurePtrArray array,int number)
{
MonitorElement** elements = new MonitorElement*[number];
for(int i=0; i<number; i++) {
elements[i] = new MonitorElementImpl(array[i]);
}
return elements;
}
void MonitorQueue::clear()
{
queue->clear();
}
int MonitorQueue::getNumberFree()
{
return queue->getNumberFree();
}
int MonitorQueue::capacity()
{
return number;
}
MonitorElement * MonitorQueue::getFree()
{
MonitorQueueElement *queueElement = queue->getFree();
if(queueElement==0) return 0;
return queueElement->getObject();
}
void MonitorQueue::setUsed(MonitorElement * element)
{
MonitorElementImpl *temp = static_cast<MonitorElementImpl*>(element);
MonitorQueueElement *queueElement = temp->getQueueElement();
queue->setUsed(temp->getQueueElement());
}
MonitorElement * MonitorQueue::getUsed()
{
MonitorQueueElement *queueElement = queue->getUsed();
if(queueElement==0) return 0;
return queueElement->getObject();
}
void MonitorQueue::releaseUsed(MonitorElement * element)
{
MonitorElementImpl *temp = static_cast<MonitorElementImpl*>(element);
queue->releaseUsed(temp->getQueueElement());
}
}}

View File

@@ -0,0 +1,42 @@
/* monitorQueue.h */
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
/* Marty Kraimer 2011.03 */
#ifndef MONITORQUEUE_H
#define MONITORQUEUE_H
#include <string>
#include <stdexcept>
#include <memory>
#include <vector>
#include <pvData.h>
#include <monitor.h>
#include <queue.h>
#include <sharedPtr.h>
namespace epics { namespace pvData {
class MonitorQueue {
public:
MonitorQueue(MonitorElement** elements,int number);
~MonitorQueue();
static MonitorElement** createElements(PVStructurePtrArray array,int number);
void clear();
int getNumberFree();
int capacity();
MonitorElement *getFree();
void setUsed(MonitorElement * element);
MonitorElement * getUsed();
void releaseUsed(MonitorElement * element);
private:
int number;
MonitorElement ** elements;
Queue<MonitorElement> *queue;
};
}}
#endif /* MONITORQUEUE_H */