ARB
gb_cb.h
Go to the documentation of this file.
1 // =============================================================== //
2 // //
3 // File : gb_cb.h //
4 // Purpose : database callback types //
5 // //
6 // Institute of Microbiology (Technical University Munich) //
7 // http://www.arb-home.de/ //
8 // //
9 // =============================================================== //
10 
11 #ifndef GB_CB_H
12 #define GB_CB_H
13 
14 #ifndef ARBDB_H
15 #include <arbdb.h>
16 #endif
17 #ifndef CB_H
18 #include <cb.h>
19 #endif
20 #ifndef _GLIBCXX_LIST
21 #include <list>
22 #endif
23 
25  DatabaseCallback dbcb;
26  GB_CB_TYPE type;
27 
28  static DatabaseCallback MARKED_DELETED;
29 
30 public:
31  TypedDatabaseCallback(const DatabaseCallback& cb, GB_CB_TYPE type_)
32  : dbcb(cb),
33  type(type_)
34  {}
35 
37 
38  GB_CB_TYPE get_type() const { return type; }
39 
40  void operator()(GBDATA *gbd, GB_CB_TYPE type_) const {
41  GB_CB_TYPE effType = GB_CB_TYPE(type&type_);
42  gb_assert(effType);
44  dbcb(gbd, effType);
45  }
46 
47  bool sig_is_equal_to(const TypedDatabaseCallback& other) const { // ignores 'clientdata'
48  return type == other.type && dbcb.same_function_as(other.dbcb);
49  }
50  bool is_equal_to(const TypedDatabaseCallback& other) const {
51  return type == other.type && dbcb == other.dbcb;
52  }
53 
54  void mark_for_removal() { dbcb = MARKED_DELETED; }
55  bool is_marked_for_removal() const { return dbcb == MARKED_DELETED; }
56 
57  char *get_info() const;
58 };
59 
60 template<typename CB>
61 struct CallbackList {
62  typedef CB cbtype;
63  typedef typename std::list<cbtype> listtype; // (when you change container, see also arbdb.cxx@CBLISTNODE_TYPE)
64  typedef typename listtype::iterator itertype;
65  typedef typename listtype::const_iterator const_itertype;
66 
67  listtype callbacks;
68 
69 #if defined(ASSERTION_USED)
70  bool contains_unremoved_callback(const CB& like) const;
71 #endif
72 
73  bool empty() const { return callbacks.empty(); }
74  void add_unchecked(const CB& cb) { callbacks.push_back(cb); }
75  void add(const CB& newcb) {
77  add_unchecked(newcb);
78  }
79 
80  const CB *get_tail() const { return empty() ? NULp : &callbacks.back(); }
81 
82  template <typename PRED>
83  void remove_callbacks_that(PRED shallRemove) {
84  bool prev_running = false;
85 
86  for (itertype cb = callbacks.begin(); cb != callbacks.end(); ) {
87  bool this_running = cb->running;
88 
89  if (shallRemove(*cb)) {
90  if (prev_running || this_running) {
91  cb->spec.mark_for_removal();
92  ++cb;
93  }
94  else {
95  cb = callbacks.erase(cb);
96  }
97  }
98  else {
99  ++cb;
100  }
101  prev_running = this_running;
102  }
103  }
104 };
105 
106 struct gb_callback {
107  // @@@ make members private
109  short running; // only used in no-transaction mode
110 
111  explicit gb_callback(const TypedDatabaseCallback& spec_)
112  : spec(spec_),
113  running(0)
114  {}
115  gb_callback(const gb_callback& other)
116  : spec(other.spec),
117  running(other.running)
118  {
119  gb_assert(!running); // appears pathological - does it ever happen?
120  }
122 
123  bool may_be_removed() const { return !running && spec.is_marked_for_removal(); }
124 
125  bool call(GBDATA *with, GB_CB_TYPE typemask) {
131  {
132  GB_CB_TYPE matchingType = GB_CB_TYPE(spec.get_type() & typemask);
133  if (matchingType && !spec.is_marked_for_removal()) {
134  ++running;
135  spec(with, matchingType);
136  --running;
137  }
138  }
139  return may_be_removed();
140  }
141 };
142 
143 struct gb_callback_list : public CallbackList<gb_callback> {
144  bool call(GBDATA *with, GB_CB_TYPE typemask) {
151  bool need_del = false;
152  for (itertype cb = callbacks.begin(); cb != callbacks.end(); ) {
153  itertype next = cb; advance(next, 1);
154  need_del = cb->call(with, typemask) || need_del;
155  cb = next;
156  }
157  return need_del;
158  }
159 };
160 
161 struct gb_transaction_save;
162 
163 struct gb_triggered_callback { // callbacks that will be called during commit
164  // @@@ make members private
168 
170  : spec(spec_),
171  old(old_),
172  gbd(gbd_)
173  {
175  }
177  : spec(other.spec),
178  old(other.old),
179  gbd(other.gbd)
180  {
182  }
186  }
187 };
188 
189 struct gb_pending_callbacks : public CallbackList<gb_triggered_callback> {
190  bool pending() const { return !empty(); }
191  void call_and_forget(GB_CB_TYPE allowedTypes);
192 };
193 
194 #else
195 #error gb_cb.h included twice
196 #endif // GB_CB_H
char * get_info() const
Definition: ad_cb.cxx:215
listtype::iterator itertype
Definition: gb_cb.h:64
const CB * get_tail() const
Definition: gb_cb.h:80
void add_unchecked(const CB &cb)
Definition: gb_cb.h:74
bool contains_unremoved_callback(const CB &like) const
Definition: ad_cb.cxx:252
bool is_marked_for_removal() const
Definition: gb_cb.h:55
bool empty() const
Definition: gb_cb.h:73
void gb_add_ref_gb_transaction_save(gb_transaction_save *ts)
Definition: ad_core.cxx:586
bool call(GBDATA *with, GB_CB_TYPE typemask)
Definition: gb_cb.h:144
bool is_equal_to(const TypedDatabaseCallback &other) const
Definition: gb_cb.h:50
gb_transaction_save * old
Definition: gb_cb.h:166
CB cbtype
Definition: gb_cb.h:62
#define cb(action)
bool pending() const
Definition: gb_cb.h:190
gb_callback(const gb_callback &other)
Definition: gb_cb.h:115
TypedDatabaseCallback spec
Definition: gb_cb.h:165
bool may_be_removed() const
Definition: gb_cb.h:123
void mark_for_removal()
Definition: gb_cb.h:54
TypedDatabaseCallback(const DatabaseCallback &cb, GB_CB_TYPE type_)
Definition: gb_cb.h:31
bool sig_is_equal_to(const TypedDatabaseCallback &other) const
Definition: gb_cb.h:47
void call_and_forget(GB_CB_TYPE allowedTypes)
Definition: ad_cb.cxx:69
void remove_callbacks_that(PRED shallRemove)
Definition: gb_cb.h:83
DECLARE_ASSIGNMENT_OPERATOR(gb_callback)
GB_CB_TYPE get_type() const
Definition: gb_cb.h:38
DECLARE_ASSIGNMENT_OPERATOR(gb_triggered_callback)
short running
Definition: gb_cb.h:109
gb_triggered_callback(const gb_triggered_callback &other)
Definition: gb_cb.h:176
TypedDatabaseCallback with_type_changed_to(GB_CB_TYPE type_) const
Definition: gb_cb.h:36
bool call(GBDATA *with, GB_CB_TYPE typemask)
Definition: gb_cb.h:125
void operator()(GBDATA *gbd, GB_CB_TYPE type_) const
Definition: gb_cb.h:40
#define gb_assert(cond)
Definition: arbdbt.h:11
gb_callback(const TypedDatabaseCallback &spec_)
Definition: gb_cb.h:111
listtype callbacks
Definition: gb_cb.h:67
listtype::const_iterator const_itertype
Definition: gb_cb.h:65
gb_triggered_callback(GBDATA *gbd_, gb_transaction_save *old_, const TypedDatabaseCallback &spec_)
Definition: gb_cb.h:169
#define NULp
Definition: cxxforward.h:116
void gb_del_ref_gb_transaction_save(gb_transaction_save *ts)
Definition: ad_core.cxx:591
GB_CB_TYPE
Definition: arbdb_base.h:46
TypedDatabaseCallback spec
Definition: gb_cb.h:108
void add(const CB &newcb)
Definition: gb_cb.h:75
std::list< cbtype > listtype
Definition: gb_cb.h:63