1 /**
2  *  \file RMF/NodeHandle.h
3  *  \brief Declaration of NodeHandle.
4  *
5  *  Copyright 2007-2021 IMP Inventors. All rights reserved.
6  *
7  */
8 
9 #ifndef RMF_NODE_HANDLE_H
10 #define RMF_NODE_HANDLE_H
11 
12 #include <boost/shared_ptr.hpp>
13 #include <string>
14 #include <vector>
15 
16 #include "ID.h"
17 #include "NodeConstHandle.h"
18 #include "RMF/Nullable.h"
19 #include "RMF/config.h"
20 #include "RMF/enums.h"
21 #include "RMF/exceptions.h"
22 #include "RMF/infrastructure_macros.h"
23 #include "RMF/internal/SharedData.h"
24 #include "internal/SharedData.h"
25 #include "types.h"
26 
27 namespace RMF {
28 class NodeHandle;
29 }  // namespace RMF
30 
31 RMF_ENABLE_WARNINGS
32 
33 #ifndef SWIG
34 #define RMF_HDF5_NODE_KEY_TYPE_METHODS(Traits, UCName)
35 #else
36 // otherwise swig gets confused
37 #define RMF_HDF5_NODE_KEY_TYPE_METHODS(Traits, UCName) \
38   void set_frame_value(UCName##Key k, UCName v) const; \
39   void set_value(UCName##Key k, UCName v) const;       \
40   void set_static_value(UCName##Key k, UCName v) const;
41 
42 #endif
43 
44 namespace RMF {
45 
46 class NodeHandle;
47 
48 //! Pass a list of them
49 typedef std::vector<NodeHandle> NodeHandles;
50 
51 class FileHandle;
52 
53 //! A handle for a particular node in the hierarchy.
54 /** Use these handles to access and modify parts of the
55     hierarchy.
56 
57     Make sure to check out the base class for the const
58     methods.
59  */
60 class RMFEXPORT NodeHandle : public NodeConstHandle {
61   friend class FileHandle;
62   template <class Tag>
set_value_impl(ID<Tag> k,typename Tag::ArgumentType v)63   void set_value_impl(ID<Tag> k, typename Tag::ArgumentType v) const {
64     Nullable<typename Tag::Type> sv = get_static_value(k);
65     if (sv.get_is_null()) {
66       set_static_value(k, v);
67       return;
68     }
69     if (Tag::get_are_equal(sv.get(), v)) return;
70     set_frame_value(k, v);
71   }
72 #if !defined(SWIG) && !defined(RMF_DOXYGEN)
73  public:
74   NodeHandle(NodeID node, boost::shared_ptr<internal::SharedData> shared);
75 #endif
76 
77  public:
NodeHandle()78   NodeHandle() {}
79   /** Create a new node as a child of this one.
80    */
81   NodeHandle add_child(std::string name, NodeType t) const;
82 
83   /** Add an existing node as a child.*/
84   void add_child(NodeConstHandle nh) const;
85 
86   /** Create a new node that replaces an existing child of this one.
87       The new node will take the place of the existing child, and the
88       existing child will be moved to become the only child of the new node. */
89   NodeHandle replace_child(NodeHandle child, std::string name,
90 		           NodeType t) const;
91 
92   NodeHandles get_children() const;
93 
94   /** \name Functions to access attributes
95 
96       @{
97    */
98 
99   /** \brief  set the value of the attribute k for this node on the
100       current frame.
101   */
102   template <class Tag>
set_frame_value(ID<Tag> k,typename Tag::ArgumentType v)103   void set_frame_value(ID<Tag> k, typename Tag::ArgumentType v) const {
104     RMF_USAGE_CHECK(shared_->get_loaded_frame() != FrameID(),
105                     "Need to set a current frame before setting values.");
106     shared_->set_loaded_value(node_, k, v);
107   }
108   /** Set the value
109       - if the attribute has a static value and it is equal to the current one
110         do nothing.
111       - if the attribute doesn't have a static value, set it,
112       - otherwise set the frame value.
113   */
114   template <class Tag>
set_value(ID<Tag> k,typename Tag::ArgumentType v)115   void set_value(ID<Tag> k, typename Tag::ArgumentType v) const {
116     set_value_impl(k, v);
117   }
118   /** \brief  set the value of the attribute k for all frames.
119    *
120   */
121   template <class Tag>
set_static_value(ID<Tag> k,typename Tag::ArgumentType v)122   void set_static_value(ID<Tag> k, typename Tag::ArgumentType v) const {
123     shared_->set_static_value(node_, k, v);
124   }
125   /** @} */
126 
127   RMF_FOREACH_TYPE(RMF_HDF5_NODE_KEY_TYPE_METHODS);
128 
129   FileHandle get_file() const;
130 };
131 } /* namespace RMF */
132 
133 RMF_DISABLE_WARNINGS
134 
135 #endif /* RMF_NODE_HANDLE_H */
136