18 #include <pv/pvaVersionNum.h> 27 #define epicsExportSharedSymbols 36 namespace epics {
namespace pvDatabase {
39 string const &recordName,
43 if(!pvRecord->init()) {
51 string const & recordName,
53 : recordName(recordName),
54 pvStructure(pvStructure),
64 cout <<
"~PVRecord() " << recordName << endl;
68 void PVRecord::unlistenClients()
71 for(std::list<PVListenerWPtr>::iterator iter = pvListenerList.begin();
72 iter!=pvListenerList.end();
76 if(!listener)
continue;
78 cout <<
"PVRecord::remove() calling listener->unlisten " << recordName << endl;
80 listener->unlisten(shared_from_this());
82 pvListenerList.clear();
83 for (std::list<PVRecordClientWPtr>::iterator iter = clientList.begin();
84 iter!=clientList.end();
90 cout <<
"PVRecord::remove() calling client->detach " << recordName << endl;
92 client->detach(shared_from_this());
101 cout <<
"PVRecord::remove() " << recordName << endl;
106 if(pvDatabase) pvDatabase->removeFromMap(shared_from_this());
115 pvRecordStructure->init();
116 PVFieldPtr pvField = pvStructure->getSubField(
"timeStamp");
117 if(pvField) pvTimeStamp.
attach(pvField);
123 cout <<
"PVRecord::process() " << recordName << endl;
126 pvTimeStamp.
get(timeStamp);
128 pvTimeStamp.
set(timeStamp);
142 size_t desiredOffset = pvField->getFieldOffset();
144 size_t offset = pvf->getFieldOffset();
145 if(offset==desiredOffset)
return pvrs;
147 PVRecordFieldPtrArray::iterator iter;
148 for (iter = pvrfpap.get()->begin(); iter!=pvrfpap.get()->end(); iter++ ) {
150 pvf = pvrf->getPVField();
151 offset = pvf->getFieldOffset();
152 if(offset==desiredOffset)
return pvrf;
153 size_t nextOffset = pvf->getNextFieldOffset();
154 if(nextOffset<=desiredOffset)
continue;
156 static_pointer_cast<PVRecordStructure>(pvrf),
159 throw std::logic_error(
160 recordName +
" pvField " 161 + pvField->getFieldName() +
" not in PVRecord");
166 cout <<
"PVRecord::lock() " << recordName << endl;
173 cout <<
"PVRecord::unlock() " << recordName << endl;
180 cout <<
"PVRecord::tryLock() " << recordName << endl;
182 return mutex.tryLock();
188 cout <<
"PVRecord::lockOtherRecord() " << recordName << endl;
190 if(
this<otherRecord.get()) {
202 cout <<
"PVRecord::addPVRecordClient() " << recordName << endl;
206 bool clientListClean =
false;
207 while(!clientListClean) {
208 if(clientList.empty())
break;
209 clientListClean =
true;
210 std::list<PVRecordClientWPtr>::iterator iter;
211 for (iter = clientList.begin();
212 iter!=clientList.end();
218 cout <<
"PVRecord::addPVRecordClient() erasing client" 219 << recordName << endl;
221 clientList.erase(iter);
222 clientListClean =
false;
226 clientList.push_back(pvRecordClient);
235 cout <<
"PVRecord::addListener() " << recordName << endl;
238 pvListenerList.push_back(pvListener);
239 this->pvListener = pvListener;
240 isAddListener =
true;
241 pvCopy->traverseMaster(shared_from_this());
250 if(!listener.get())
return;
252 pvRecordField->addListener(listener);
254 pvRecordField->removeListener(listener);
263 cout <<
"PVRecord::removeListener() " << recordName << endl;
266 std::list<PVListenerWPtr>::iterator iter;
267 for (iter = pvListenerList.begin(); iter!=pvListenerList.end(); iter++ )
270 if(!listener.get())
continue;
271 if(listener.get()==pvListener.get()) {
272 pvListenerList.erase(iter);
273 this->pvListener = pvListener;
274 isAddListener =
false;
275 pvCopy->traverseMaster(shared_from_this());
285 if(++depthGroupPut>1)
return;
287 cout <<
"PVRecord::beginGroupPut() " << recordName << endl;
289 std::list<PVListenerWPtr>::iterator iter;
290 for (iter = pvListenerList.begin(); iter!=pvListenerList.end(); iter++)
293 if(!listener.get())
continue;
294 listener->beginGroupPut(shared_from_this());
300 if(--depthGroupPut>0)
return;
302 cout <<
"PVRecord::endGroupPut() " << recordName << endl;
304 std::list<PVListenerWPtr>::iterator iter;
305 for (iter = pvListenerList.begin(); iter!=pvListenerList.end(); iter++)
308 if(!listener.get())
continue;
309 listener->endGroupPut(shared_from_this());
336 fullFieldName = pvField.lock()->getFieldName();
339 string parentName = pvParent->getPVField()->getFieldName();
340 if(parentName.size()>0) {
341 fullFieldName = pvParent->getPVField()->getFieldName()
342 +
'.' + fullFieldName;
344 pvParent = pvParent->getParent();
347 if(fullFieldName.size()>0) {
348 fullName = pvRecord->getRecordName() +
'.' + fullFieldName;
350 fullName = pvRecord->getRecordName();
352 pvField.lock()->setPostHandler(shared_from_this());
357 return parent.lock();
368 bool PVRecordField::addListener(
PVListenerPtr const & pvListener)
371 if(pvRecord && pvRecord->getTraceLevel()>1) {
372 cout <<
"PVRecordField::addListener() " <<
getFullName() << endl;
374 pvListenerList.push_back(pvListener);
378 void PVRecordField::removeListener(
PVListenerPtr const & pvListener)
381 if(pvRecord && pvRecord->getTraceLevel()>1) {
382 cout <<
"PVRecordField::removeListener() " <<
getFullName() << endl;
384 std::list<PVListenerWPtr>::iterator iter;
385 for (iter = pvListenerList.begin(); iter!=pvListenerList.end(); iter++ ) {
387 if(!listener.get())
continue;
388 if(listener.get()==pvListener.get()) {
389 pvListenerList.erase(iter);
399 parent->postParent(shared_from_this());
407 std::list<PVListenerWPtr>::iterator iter;
408 for(iter = pvListenerList.begin(); iter != pvListenerList.end(); ++iter)
411 if(!listener.get())
continue;
412 listener->dataPut(pvrs,subField);
415 if(parent) parent->postParent(subField);
425 PVRecordFieldPtrArray::iterator iter;
426 for(iter = pvRecordFields->begin() ; iter !=pvRecordFields->end(); iter++) {
427 (*iter)->postSubField();
432 void PVRecordField::callListener()
434 std::list<PVListenerWPtr>::iterator iter;
435 for (iter = pvListenerList.begin(); iter!=pvListenerList.end(); iter++ ) {
437 if(!listener.get())
continue;
438 listener->dataPut(shared_from_this());
448 pvStructure(pvStructure),
457 size_t numFields = pvFields.size();
458 pvRecordFields->reserve( numFields);
462 for(
size_t i=0;
i<numFields;
i++) {
464 if(pvField->getField()->getType()==
structure) {
468 pvRecordFields->push_back(pvRecordStructure);
469 pvRecordStructure->init();
473 pvRecordFields->push_back(pvRecordField);
474 pvRecordField->init();
481 return pvRecordFields;
bool removeListener(PVListenerPtr const &pvListener, epics::pvCopy::PVCopyPtr const &pvCopy)
Remove a listener.
bool addPVRecordClient(PVRecordClientPtr const &pvRecordClient)
Add a client that wants to access the record.
PVRecordStructurePtr getPVRecordStructure() const
Get the top level PVRecordStructure.
virtual void process()
Optional method for derived class.
epics::pvData::PVStructurePtr getPVStructure()
Get the data structure/.
std::tr1::shared_ptr< PVListener > PVListenerPtr
std::tr1::shared_ptr< PVCopy > PVCopyPtr
shared_ptr< T > static_pointer_cast(shared_ptr< U > const &r) BOOST_NOEXCEPT
void lockOtherRecord(PVRecordPtr const &otherRecord)
Lock another record.
virtual void remove()
remove record from database.
TODO only here because of the Lockable.
void lock()
Lock the record.
std::tr1::shared_ptr< PVRecordClient > PVRecordClientPtr
PVRecordField(epics::pvData::PVFieldPtr const &pvField, PVRecordStructurePtr const &parent, PVRecordPtr const &pvRecord)
Constructor.
void get(TimeStamp &timeStamp) const
void nextMasterPVField(epics::pvData::PVFieldPtr const &pvField)
PVCopyTraverseMasterCallback method.
epics::pvData::PVFieldPtr getPVField()
Get the PVField.
Base interface for a PVRecord.
bool tryLock()
Try to lock the record.
PVRecordFieldPtrArrayPtr getPVRecordFields()
Get the sub fields.
std::tr1::shared_ptr< PVDatabase > PVDatabasePtr
PVRecordPtr getPVRecord()
Return the PVRecord to which this field belongs.
void endGroupPut()
Ends a group of puts.
PVRecordStructure(epics::pvData::PVStructurePtr const &pvStructure, PVRecordStructurePtr const &parent, PVRecordPtr const &pvRecord)
Constructor.
std::string getFullName()
Get the recordName plus the full name of the field, i.e. recordName.field,field,..
void beginGroupPut()
Begins a group of puts.
virtual void postSubField()
Interface for a field of a record.
std::string getFullFieldName()
Get the full name of the field, i.e. field,field,..
PVRecordStructurePtr getParent()
Get the parent.
std::vector< PVFieldPtr > PVFieldPtrArray
Data interface for a structure,.
static PVDatabasePtr getMaster()
Get the master database.
bool addListener(PVListenerPtr const &pvListener, epics::pvCopy::PVCopyPtr const &pvCopy)
Add a PVListener.
std::tr1::shared_ptr< PVRecord > PVRecordPtr
std::tr1::shared_ptr< PVStructure > PVStructurePtr
virtual void postPut()
This is called by the code that implements the data interface. It is called whenever the put method i...
std::vector< PVRecordFieldPtr > PVRecordFieldPtrArray
void initPVRecord()
Initializes the base class.
void unlock()
Unlock the record.
std::string getRecordName() const
Get the name of the record.
std::tr1::shared_ptr< PVRecordStructure > PVRecordStructurePtr
std::tr1::shared_ptr< PVField > PVFieldPtr
std::tr1::shared_ptr< PVRecordField > PVRecordFieldPtr
Interface for a field that is a structure.
PVRecordFieldPtr findPVRecordField(epics::pvData::PVFieldPtr const &pvField)
Find the PVRecordField for the PVField.
std::tr1::shared_ptr< PVRecordFieldPtrArray > PVRecordFieldPtrArrayPtr
C++ and C descriptions for a thread.
std::ostream & operator<<(std::ostream &o, const PVRecord &record)
bool attach(PVFieldPtr const &pvField)
virtual void init()
Called by implementation code of PVRecord.
virtual void postParent(PVRecordFieldPtr const &subField)
bool set(TimeStamp const &timeStamp)