Logo ROOT   6.14/05
Reference Guide
TDrawable.hxx
Go to the documentation of this file.
1 /// \file ROOT/TDrawable.h
2 /// \ingroup Base ROOT7
3 /// \author Axel Naumann <axel@cern.ch>
4 /// \date 2015-08-07
5 /// \warning This is part of the ROOT 7 prototype! It will change without notice. It might trigger earthquakes. Feedback
6 /// is welcome!
7 
8 /*************************************************************************
9  * Copyright (C) 1995-2015, Rene Brun and Fons Rademakers. *
10  * All rights reserved. *
11  * *
12  * For the licensing terms see $ROOTSYS/LICENSE. *
13  * For the list of contributors see $ROOTSYS/README/CREDITS. *
14  *************************************************************************/
15 
16 #ifndef ROOT7_TDrawable
17 #define ROOT7_TDrawable
18 
19 #include <memory>
20 #include <string>
21 
22 namespace ROOT {
23 namespace Experimental {
24 
25 class TDrawingOptsBase;
26 class TMenuItems;
27 class TPadBase;
28 
29 namespace Internal {
30 class TPadPainter;
31 }
32 
33 /** \class TDrawable
34  Base class for drawable entities: objects that can be painted on a `TPad`.
35  */
36 
37 class TDrawable {
38 friend class TPadBase;
39 private:
40  std::string fId; ///< object identifier, unique inside TCanvas
41 
42 public:
43  virtual ~TDrawable();
44 
45  virtual void Paint(Internal::TPadPainter &onPad) = 0;
46 
47  /** Method can be used to provide menu items for the drawn object */
48  virtual void PopulateMenu(TMenuItems &){};
49 
50  virtual void Execute(const std::string &);
51 
52  /// Get the reference to the drawing options as TDrawingOptsBase. Used e.g. to identify the TDrawable in
53  /// the list of primitives.
54  virtual TDrawingOptsBase& GetOptionsBase() = 0;
55 
56  std::string GetId() const { return fId; }
57 
58 };
59 
60 template <class DERIVED>
61 class TDrawableBase: public TDrawable {
62 public:
63  TDrawingOptsBase& GetOptionsBase() override { return static_cast<DERIVED*>(this)->GetOptions(); }
64 };
65 
66 namespace Internal {
67 
68 /// \class TAnyPtr
69 /// Models a shared pointer or a unique pointer.
70 
71 template <class T>
72 class TUniWeakPtr {
73  // Needs I/O support for union (or variant, actually) {
74  std::unique_ptr<T> fUnique;
75  std::weak_ptr<T> fWeak; //! Cannot save for now :-(
76  T* fWeakForIO = nullptr; // Hack to allow streaming *out* of fWeak (reading is still broken because we don't set fWeak)
77  // };
78  bool fIsWeak = false; ///< fUnique or fWeak?
79 
80 public:
81  /// \class Accessor
82  /// Gives transparent access to the shared or unique pointer.
83  /// Locks if needed.
84  class Accessor {
85  union {
86  T *fRaw; ///< The raw, non-owning pointer accessing a TUniWeak's unique_ptr
87  std::shared_ptr<T> fShared; ///< The shared_ptr accessing a TUniWeak's weak_ptr
88  };
89  bool fIsShared; ///< fRaw or fShared?
90 
91  public:
92  Accessor(const TUniWeakPtr &uniweak): fIsShared(uniweak.fIsWeak)
93  {
94  if (fIsShared)
95  new (&fShared) std::shared_ptr<T>(uniweak.fWeak.lock());
96  else
97  fRaw = uniweak.fUnique.get();
98  }
99 
100  Accessor(Accessor &&rhs): fIsShared(rhs.fIsShared)
101  {
102  if (fIsShared)
103  new (&fShared) std::shared_ptr<T>(std::move(rhs.fShared));
104  else
105  fRaw = rhs.fRaw;
106  }
107 
108  T *operator->() const { return fIsShared ? fRaw : fShared.get(); }
109  T &operator*() const { return *operator->(); }
110  operator bool() const { return fIsShared ? (bool)fRaw : (bool)fShared; }
111 
113  {
114  if (fIsShared)
115  fShared.~shared_ptr();
116  }
117  };
118 
119  TUniWeakPtr() = default;
120  TUniWeakPtr(const std::shared_ptr<T> &ptr): fWeak(ptr), fWeakForIO(ptr.get()), fIsWeak(true) {}
121  TUniWeakPtr(std::unique_ptr<T> &&ptr): fUnique(std::move(ptr)), fIsWeak(false) {}
122  TUniWeakPtr(TUniWeakPtr &&rhs): fIsWeak(rhs.fIsWeak)
123  {
124  if (rhs.fIsWeak) {
125  fWeak = std::move(rhs.fWeak);
126  auto shptr = rhs.fWeak.lock();
127  fWeakForIO = shptr.get();
128  } else {
129  fUnique = std::move(rhs.fUnique);
130  }
131  }
132 
134  {
135  }
136 
137  Accessor Get() const { return Accessor(*this); }
138  void Reset()
139  {
140  if (fIsWeak)
141  fWeak.reset();
142  else
143  fUnique.reset();
144  }
145 };
146 
147 } // namespace Internal
148 } // namespace Experimental
149 } // namespace ROOT
150 
151 #endif
Base class for drawable entities: objects that can be painted on a TPad.
Definition: TDrawable.hxx:37
Namespace for new ROOT classes and functions.
Definition: StringConv.hxx:21
double T(double x)
Definition: ChebyshevPol.h:34
STL namespace.
Base class for graphic containers for TDrawable-s.
Definition: TPad.hxx:41
TDrawingOptsBase & GetOptionsBase() override
Get the reference to the drawing options as TDrawingOptsBase.
Definition: TDrawable.hxx:63
Gives transparent access to the shared or unique pointer.
Definition: TDrawable.hxx:84
std::shared_ptr< T > fShared
The shared_ptr accessing a TUniWeak&#39;s weak_ptr.
Definition: TDrawable.hxx:87
T * fRaw
The raw, non-owning pointer accessing a TUniWeak&#39;s unique_ptr.
Definition: TDrawable.hxx:86
TUniWeakPtr(std::unique_ptr< T > &&ptr)
Definition: TDrawable.hxx:121
Abstract interface for object painting on the pad/canvas.
Definition: TPadPainter.hxx:37
TUniWeakPtr(const std::shared_ptr< T > &ptr)
Definition: TDrawable.hxx:120
std::string GetId() const
Definition: TDrawable.hxx:56
Implement TVirtualPadPainter which abstracts painting operations.
Definition: TPadPainter.h:26
virtual void PopulateMenu(TMenuItems &)
Method can be used to provide menu items for the drawn object.
Definition: TDrawable.hxx:48
std::string fId
object identifier, unique inside TCanvas
Definition: TDrawable.hxx:40