secondarydriverinterface.h
1 /***************************************************************************
2  Copyright (C) 2002-2015 Kentaro Kitagawa
3  kitagawa@phys.s.u-tokyo.ac.jp
4 
5  This program is free software; you can redistribute it and/or
6  modify it under the terms of the GNU Library General Public
7  License as published by the Free Software Foundation; either
8  version 2 of the License, or (at your option) any later version.
9 
10  You should have received a copy of the GNU Library General
11  Public License and a list of authors along with this program;
12  see the files COPYING and AUTHORS.
13 ***************************************************************************/
14 #ifndef SECONDARYDRIVERINTERFACE_H_
15 #define SECONDARYDRIVERINTERFACE_H_
16 
17 #include "secondarydriver.h"
18 
19 template <class T>
20 XSecondaryDriverInterface<T>::XSecondaryDriverInterface(const char *name, bool runtime,
21  Transaction &tr_meas, const shared_ptr<XMeasure> &meas) :
22  T(name, runtime, ref(tr_meas), meas),
23  m_drivers(meas->drivers()) {
24 }
25 template <class T>
27 }
28 
29 template <class T>
30 void
32  Snapshot shot( *this);
33  onConnectedRecorded(shot, this);
34 }
35 template <class T>
36 void
38  Snapshot shot_all_drivers( *m_drivers.lock());
39  if( !shot_all_drivers.isUpperOf( *this))
40  return;
41  Snapshot shot_this( *this, shot_all_drivers);
42  Transaction tr(shot_this);
43  bool firsttime = true;
44  for(;;) {
45  if( !firsttime) {
46  try {
47  shot_all_drivers = tr.newTransactionUsingSnapshotFor( *m_drivers.lock());
48  shot_this = tr;
49  }
50  catch (typename T::NodeNotFoundError &) {
51  return; //has been freed from the list.
52  }
53  }
54  firsttime = false;
55  if( !shot_all_drivers.isUpperOf( *driver))
56  return; //driver has been freed from the list.
57 
58  if(driver != this) {
59  //checking if emitter has already connected unless self-emitted.
60  bool found = false;
61  for(auto it = shot_this[ *this].m_connections.begin(); it != shot_this[ *this].m_connections.end(); ++it) {
62  if((shared_ptr<XNode>(shot_this[ *it->m_selecter]).get() == driver) &&
63  (shot_emitter[ *driver].time())) {
64  found = true;
65  break;
66  }
67  }
68  if( !found)
69  return;
70  }
71  //checking if the selecters point to existing drivers.
72  for(auto it = shot_this[ *this].m_connections.begin();
73  it != shot_this[ *this].m_connections.end(); ++it) {
74  shared_ptr<XNode> node = shot_this[ *it->m_selecter];
75  if(node) {
76  if( !shot_all_drivers.isUpperOf( *node))
77  return;
78  if((node.get() != driver) &&
79  !shot_all_drivers[ *static_pointer_cast<XDriver>(node)].time())
80  return; //Record is invalid.
81  }
82  }
83 
84  //driver-side dependency check
85  if( !checkDependency(tr, shot_emitter, shot_all_drivers, driver))
86  return;
87 
88  bool skipped = false;
89  XKameError err;
90  XTime time_recorded = shot_emitter[ *driver].time();
91  try {
92  analyze(tr, shot_emitter, shot_all_drivers, driver);
93  }
94  catch (typename T::XSkippedRecordError& e) {
95  skipped = true;
96  err = e;
97  }
98  catch (typename T::XRecordError& e) {
99  time_recorded = XTime(); //record is invalid
100  err = e;
101  }
102  if( !skipped)
103  this->record(tr, shot_emitter[ *driver].timeAwared(), time_recorded);
104  if(tr.commit()) {
105  if(err.msg().length())
106  err.print(this->getLabel() + ": ");
107  this->visualize(tr);
108  break;
109  }
110  }
111 }
112 template <class T>
113 void
115  this->iterate_commit([=](Transaction &tr){
116  typename Payload::Connection con;
117  con.m_selecter = selecter;
118  tr[ *this].m_connections.push_back(con);
119  });
120 
121  selecter->iterate_commit([=](Transaction &tr){
122  if(m_lsnOnItemChanged)
123  tr[ *selecter].onValueChanged().connect(m_lsnOnItemChanged);
124  else
125  m_lsnOnItemChanged = tr[ *selecter].onValueChanged().connectWeakly(this->shared_from_this(),
127  });
128 }
129 template <class T>
130 void
132  auto *item = static_cast<XPointerItemNode<XDriverList>*>(node);
133  shared_ptr<XNode> nd = shot[ *item];
134  auto driver = static_pointer_cast<XDriver>(nd);
135 
136  shared_ptr<XListener> lsnonrecord;
137  if(driver) {
138  driver->iterate_commit([=, &lsnonrecord](Transaction &tr){
139  lsnonrecord = tr[ *driver].onRecord().connectWeakly(
140  this->shared_from_this(), &XSecondaryDriverInterface<T>::onConnectedRecorded);
141  });
142  }
143  this->iterate_commit([=](Transaction &tr){
144  auto it = std::find(tr[ *this].m_connections.begin(), tr[ *this].m_connections.end(), item);
145  it->m_lsnOnRecord = lsnonrecord;
146  });
147 }
148 
149 #endif /*SECONDARYDRIVERINTERFACE_H_*/

Generated for KAME4 by  doxygen 1.8.3