major changes to monitor. Bug in Convert::copyScalar (change every break to rerurn); minor change to StandardPVField and queueVoid
This commit is contained in:
@@ -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>
|
||||
|
||||
@@ -89,6 +89,8 @@ LIBSRCS += bitSetUtil.cpp
|
||||
|
||||
SRC_DIRS += $(PVDATA)/monitor
|
||||
INC += monitor.h
|
||||
INC += monitorQueue.h
|
||||
LIBSRCS += monitorQueue.cpp
|
||||
|
||||
|
||||
LIBRARY=pvData
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 */
|
||||
|
||||
146
pvDataApp/monitor/monitorQueue.cpp
Normal file
146
pvDataApp/monitor/monitorQueue.cpp
Normal 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());
|
||||
}
|
||||
|
||||
|
||||
}}
|
||||
|
||||
42
pvDataApp/monitor/monitorQueue.h
Normal file
42
pvDataApp/monitor/monitorQueue.h
Normal 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 */
|
||||
Reference in New Issue
Block a user