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