Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
TNotifyLink.h
Go to the documentation of this file.
1// @(#)root/base:$Id$
2// Author: Philippe Canal 2019
3
4/*************************************************************************
5 * Copyright (C) 1995-2019, Rene Brun and Fons Rademakers. *
6 * All rights reserved. *
7 * *
8 * For the licensing terms see $ROOTSYS/LICENSE. *
9 * For the list of contributors see $ROOTSYS/README/CREDITS. *
10 *************************************************************************/
11
12#ifndef ROOT_TNotifyLink
13#define ROOT_TNotifyLink
14
15#include <TObject.h>
16#include <TError.h> // for R__ASSERT
17
18/** \class TNotifyLink
19\ingroup Base
20
21A node in a doubly linked list of subscribers to TChain notifications.
22
23TObject has a virtual TObject::Notify() method that takes no parameters and returns a boolean.
24By default the method does nothing, and different objects in ROOT use this method for different purposes.
25
26`TChain` uses `Notify` to implement a callback mechanism that notifies interested parties (subscribers) when
27the chain switches to a new sub-tree.
28In practice it calls the Notify() method of its fNotify data member from TChain::LoadTree().
29However there could be several different objects interested in knowing that a given TChain switched to a new tree.
30TNotifyLink can be used to build a linked list of subscribers: calling TNotifyLink::Notify() on the head
31node of the list propagates the call to all subscribers in the list.
32
33Example usage:
34~~~{.cpp}
35TNotifyLink l(subscriber); // subscriber must implement `Notify()`
36l.PrependLink(chain); // prepends `l` to the list of notify links of the chain
37~~~
38
39\note TChain does not explicitly enforce that its fNotify data member be the head node of a list of
40TNotifyLinks, but that is the case in practice at least when using TTreeReader or RDataFrame to process the chain.
41
42\note TChain does not take ownership of the TNotifyLink and the TNotifyLink does not take ownership of the
43 subscriber object.
44**/
45
46/// See TNotifyLink.
47class TNotifyLinkBase : public TObject {
48protected:
49 /// Previous node in a TChain's list of subscribers to its notification.
50 /// If null, this TNotifyLink is the head node of the list and the TChain::GetNotify() for the corresponding
51 /// chain is expected to return `this`.
53 /// Next node in a TChain's list of subscribers.
54 /// For generality, it might be a generic TObject rather than another TNotifyLink: this makes it possible
55 /// to call TChain::SetNotify() with a generic notifier exactly once before more TNotifyLinks are added.
56 /// Null if this is the tail of the list.
57 TObject *fNext = nullptr;
58
59public:
60 // TTree status bits
62 kLinked = BIT(11) // Used when the TNotifyLink is connected to a TTree.
63 };
64
65 void Clear(Option_t * /*option*/ ="") override
66 {
67 auto current = this;
68 do {
69 auto next = dynamic_cast<TNotifyLinkBase*>(fNext);
70 current->ResetBit(kLinked);
71 current->fPrevious = nullptr;
72 current->fNext = nullptr;
73 current = next;
74 } while(current);
75 }
76
77 /// Set this link as the head of the chain's list of notify subscribers.
78 /// Templated only to remove an include dependency from TChain: it expects
79 /// a TChain as input (in practice anything that implements SetNotify and
80 /// GetNotify will work, but in ROOT that is only TTree and its sub-classes).
81 template <class Chain>
82 void PrependLink(Chain &chain)
83 {
85
86 fNext = chain.GetNotify();
87 chain.SetNotify(this);
88 if (auto next = dynamic_cast<TNotifyLinkBase *>(fNext))
89 next->fPrevious = this;
90 }
91
92 /// Remove this link from a chain's list of notify subscribers.
93 /// Templated only to remove an include dependency from TChain: it expects
94 /// a TChain as input (in practice anything that implements SetNotify and
95 /// GetNotify will work, but in ROOT that is only TTree and its sub-classes).
96 /// \note No error is emitted if the TNotifyLink is not part of the linked list
97 /// for the chain passed as argument. The TNotifyLink will still remove itself
98 /// from the doubly linked list.
99 template <class Chain>
100 void RemoveLink(Chain &chain)
101 {
103
104 if (chain.GetNotify() == this) { // this notify link is the first in the list
105 R__ASSERT(fPrevious == nullptr && "The TNotifyLink head node should not have a previous element.");
106 chain.SetNotify(fNext);
107 } else if (fPrevious) {
109 }
110 if (auto next = dynamic_cast<TNotifyLinkBase *>(fNext))
111 next->fPrevious = fPrevious;
112 fPrevious = nullptr;
113 fNext = nullptr;
114 }
115
117 {
118 return TestBit(kLinked);
119 }
120
121 TObject *GetNext() const { return fNext; }
122
124};
125
126template <class Type>
128private:
130
131public:
132 TNotifyLink(Type *subscriber) : fSubscriber(subscriber) {}
133
134 /// Call Notify on our subscriber and propagate the call to the next link.
135 Bool_t Notify() override
136 {
137 bool result = true;
138 if (fSubscriber)
139 result &= fSubscriber->Notify();
140 if (fNext)
141 result &= fNext->Notify();
142 return result;
143 }
144
146};
147
148#endif // ROOT_TNotifyLink
const char Option_t
Definition RtypesCore.h:66
#define BIT(n)
Definition Rtypes.h:90
#define ClassDefOverride(name, id)
Definition Rtypes.h:346
#define R__ASSERT(e)
Checks condition e and reports a fatal error if it's false.
Definition TError.h:125
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t result
See TNotifyLink.
Definition TNotifyLink.h:47
TNotifyLinkBase * fPrevious
Previous node in a TChain's list of subscribers to its notification.
Definition TNotifyLink.h:52
TObject * fNext
Next node in a TChain's list of subscribers.
Definition TNotifyLink.h:57
void PrependLink(Chain &chain)
Set this link as the head of the chain's list of notify subscribers.
Definition TNotifyLink.h:82
TObject * GetNext() const
void RemoveLink(Chain &chain)
Remove this link from a chain's list of notify subscribers.
void Clear(Option_t *="") override
Definition TNotifyLink.h:65
Bool_t IsLinked()
Mother of all ROOT objects.
Definition TObject.h:41
virtual Bool_t Notify()
This method must be overridden to handle object notification (the base implementation is no-op).
Definition TObject.cxx:611
R__ALWAYS_INLINE Bool_t TestBit(UInt_t f) const
Definition TObject.h:199
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition TObject.cxx:798
void ResetBit(UInt_t f)
Definition TObject.h:198