Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-16 09:08:27

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