Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:10:36

0001 /*************************************************************************
0002  * Copyright (C) 1995-2021, Rene Brun and Fons Rademakers.               *
0003  * All rights reserved.                                                  *
0004  *                                                                       *
0005  * For the licensing terms see $ROOTSYS/LICENSE.                         *
0006  * For the list of contributors see $ROOTSYS/README/CREDITS.             *
0007  *************************************************************************/
0008 
0009 #ifndef ROOT7_RAttrBase
0010 #define ROOT7_RAttrBase
0011 
0012 #include <ROOT/RAttrMap.hxx>
0013 #include <ROOT/RStyle.hxx>
0014 #include <ROOT/RDrawable.hxx>
0015 
0016 namespace ROOT {
0017 namespace Experimental {
0018 
0019 class RLogChannel;
0020 /// Log channel for GPad diagnostics.
0021 RLogChannel &GPadLog();
0022 
0023 /** \class RAttrBase
0024 \ingroup GpadROOT7
0025 \author Sergey Linev <s.linev@gsi.de>
0026 \date 2019-09-17
0027 \brief Base class for all attributes, used with RDrawable
0028 \warning This is part of the ROOT 7 prototype! It will change without notice. It might trigger earthquakes. Feedback is welcome!
0029 */
0030 
0031 class RAttrBase {
0032 
0033    friend class RAttrMap;
0034 
0035    enum {kDrawable, kParent, kOwnAttr} fKind{kDrawable}; ///<!  kind of data
0036 
0037    union {
0038       RDrawable *drawable;  // either drawable to which attributes belongs to
0039       RAttrBase *parent;    // or aggregation of attributes
0040       RAttrMap  *ownattr;   // or just own container with values
0041    } fD{nullptr};  ///<!  data
0042 
0043    const char *fPrefix{nullptr}; ///<! name prefix for all attributes values
0044 
0045    void ClearData();
0046    RAttrMap *CreateOwnAttr();
0047 
0048 protected:
0049 
0050    RDrawable *GetDrawable() const { return fKind == kDrawable ? fD.drawable : nullptr; }
0051    RAttrBase *GetParent() const { return fKind == kParent ? fD.parent : nullptr; }
0052    RAttrMap *GetOwnAttr() const { return fKind == kOwnAttr ? fD.ownattr : nullptr; }
0053 
0054    virtual RAttrMap CollectDefaults() const = 0;
0055 
0056    virtual bool IsAggregation() const { return false; }
0057 
0058    ///////////////////////////////////////////////////////////////////////////////
0059 
0060    struct Rec_t {
0061       RAttrMap *attr{nullptr};
0062       std::string fullname;
0063       RDrawable *drawable{nullptr};
0064       operator bool() const { return !!attr; }
0065    };
0066 
0067    /// Find attributes container and full-qualified name for value
0068    const Rec_t AccessAttr(const std::string &name) const
0069    {
0070       const RAttrBase *prnt = this;
0071       std::string fullname = name;
0072       while (prnt) {
0073          if (prnt->IsAggregation() && prnt->fPrefix) {
0074             fullname.insert(0, "_");        // fullname = prnt->fPrefix + _ + fullname
0075             fullname.insert(0, prnt->fPrefix);
0076          }
0077          if (auto dr = prnt->GetDrawable())
0078             return { &dr->fAttr, fullname, dr };
0079          if (auto attr = prnt->GetOwnAttr())
0080             return { attr, fullname, nullptr };
0081          prnt = prnt->GetParent();
0082       }
0083       return {nullptr, fullname, nullptr};
0084    }
0085 
0086    struct Val_t {
0087       const RAttrMap::Value_t *value{nullptr};
0088       std::shared_ptr<RStyle> style;
0089       operator bool() const { return !!value; }
0090    };
0091 
0092    /** Search value with given name in attributes */
0093    const Val_t AccessValue(const std::string &name, bool use_style = true) const
0094    {
0095       if (auto access = AccessAttr(name)) {
0096          if (auto rec = access.attr->Find(access.fullname))
0097             return {rec, nullptr};
0098          if (access.drawable && use_style)
0099             if (auto observe = access.drawable->fStyle.lock()) {
0100                if (auto rec = observe->Eval(access.fullname, *access.drawable))
0101                   return {rec, observe};
0102             }
0103       }
0104 
0105       return {nullptr, nullptr};
0106    }
0107 
0108    /// Ensure attribute with give name exists - creates container for attributes if required
0109 
0110    Rec_t EnsureAttr(const std::string &name)
0111    {
0112       auto prnt = this;
0113       std::string fullname = name;
0114       while (prnt) {
0115          if (prnt->IsAggregation() && prnt->fPrefix) {
0116             fullname.insert(0, "_");        // fullname = prnt->fPrefix + _ + fullname
0117             fullname.insert(0, prnt->fPrefix);
0118          }
0119          if (auto dr = prnt->GetDrawable())
0120             return { &dr->fAttr, fullname, dr };
0121          if (prnt->fKind != kParent)
0122             return { prnt->CreateOwnAttr(), fullname, nullptr };
0123          prnt = prnt->GetParent();
0124       }
0125       return {nullptr, fullname, nullptr};
0126    }
0127 
0128    RAttrBase(const char *prefix)
0129    {
0130       fKind = kOwnAttr;
0131       fD.ownattr = nullptr;
0132       fPrefix = prefix;
0133    }
0134 
0135    RAttrBase(RDrawable *drawable, const char *prefix = nullptr)
0136    {
0137       fKind = kDrawable;
0138       fD.drawable = drawable;
0139       fPrefix = prefix;
0140    }
0141 
0142    RAttrBase(RAttrBase *parent, const char *prefix = nullptr)
0143    {
0144       fKind = kParent;
0145       fD.parent = parent;
0146       fPrefix = prefix;
0147    }
0148 
0149    void SetNoValue(const std::string &name);
0150 
0151    const char *GetPrefix() const { return fPrefix; }
0152 
0153    void ClearValue(const std::string &name);
0154 
0155    void MoveTo(RAttrBase &tgt);
0156 
0157 public:
0158    RAttrBase() = default;
0159 
0160    virtual ~RAttrBase() { ClearData(); }
0161 
0162    virtual void Clear() = 0;
0163 
0164 };
0165 
0166 } // namespace Experimental
0167 } // namespace ROOT
0168 
0169 #endif