1 /* 2 Copyright (C) 2010-2014 Kristian Duske 3 4 This file is part of TrenchBroom. 5 6 TrenchBroom is free software: you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation, either version 3 of the License, or 9 (at your option) any later version. 10 11 TrenchBroom is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 GNU General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with TrenchBroom. If not, see <http://www.gnu.org/licenses/>. 18 */ 19 20 #ifndef TrenchBroom_AttributableNode 21 #define TrenchBroom_AttributableNode 22 23 #include "Assets/AssetTypes.h" 24 #include "Assets/EntityDefinition.h" 25 #include "Model/EntityAttributes.h" 26 #include "Model/ModelTypes.h" 27 #include "Model/Node.h" 28 29 namespace TrenchBroom { 30 namespace Model { 31 class AttributableNode : public Node { 32 public: // some helper methods 33 static Assets::EntityDefinition* selectEntityDefinition(const AttributableNodeList& attributables); 34 static const Assets::AttributeDefinition* selectAttributeDefinition(const AttributeName& name, const AttributableNodeList& attributables); 35 static AttributeValue selectAttributeValue(const AttributeName& name, const AttributableNodeList& attributables); 36 protected: 37 static const String DefaultAttributeValue; 38 39 Assets::EntityDefinition* m_definition; 40 EntityAttributes m_attributes; 41 42 AttributableNodeList m_linkSources; 43 AttributableNodeList m_linkTargets; 44 AttributableNodeList m_killSources; 45 AttributableNodeList m_killTargets; 46 47 // cache the classname for faster access 48 AttributeValue m_classname; 49 public: 50 virtual ~AttributableNode(); 51 52 Assets::EntityDefinition* definition() const; 53 void setDefinition(Assets::EntityDefinition* definition); 54 public: // attribute management 55 const Assets::AttributeDefinition* attributeDefinition(const AttributeName& name) const; 56 57 const EntityAttribute::List& attributes() const; 58 void setAttributes(const EntityAttribute::List& attributes); 59 60 bool hasAttribute(const AttributeName& name) const; 61 bool hasAttribute(const AttributeName& name, const AttributeValue& value) const; 62 bool hasAttributeWithPrefix(const AttributeName& prefix, const AttributeValue& value) const; 63 bool hasNumberedAttribute(const AttributeName& prefix, const AttributeValue& value) const; 64 65 const AttributeValue& attribute(const AttributeName& name, const AttributeValue& defaultValue = DefaultAttributeValue) const; 66 const AttributeValue& classname(const AttributeValue& defaultClassname = AttributeValues::NoClassname) const; 67 68 EntityAttributeSnapshot attributeSnapshot(const AttributeName& name) const; 69 70 template <typename T> addOrUpdateAttribute(const AttributeName & name,const T & value)71 void addOrUpdateAttribute(const AttributeName& name, const T& value) { 72 addOrUpdateAttribute(name, convertValue(value)); 73 } 74 75 template <typename T, size_t S> addOrUpdateAttribute(const AttributeName & name,const Vec<T,S> & value)76 void addOrUpdateAttribute(const AttributeName& name, const Vec<T,S>& value) { 77 addOrUpdateAttribute(name, value.asString()); 78 } 79 80 bool canAddOrUpdateAttribute(const AttributeName& name, const AttributeValue& value) const; 81 void addOrUpdateAttribute(const AttributeName& name, const AttributeValue& value); 82 83 bool canRenameAttribute(const AttributeName& name, const AttributeName& newName) const; 84 void renameAttribute(const AttributeName& name, const AttributeName& newName); 85 86 bool canRemoveAttribute(const AttributeName& name) const; 87 void removeAttribute(const AttributeName& name); 88 89 bool isAttributeNameMutable(const AttributeName& name) const; 90 bool isAttributeValueMutable(const AttributeName& name) const; 91 private: // attribute management internals 92 template <typename T> convertValue(const T & value)93 AttributeValue convertValue(const T& value) const { 94 static StringStream str; 95 str.str(""); 96 str << value; 97 return str.str(); 98 } 99 100 class NotifyAttributeChange { 101 private: 102 NotifyNodeChange m_nodeChange; 103 AttributableNode* m_node; 104 public: 105 NotifyAttributeChange(AttributableNode* node); 106 ~NotifyAttributeChange(); 107 }; 108 109 void attributesWillChange(); 110 void attributesDidChange(); 111 112 void updateClassname(); 113 private: // search index management 114 void addAttributesToIndex(); 115 void removeAttributesFromIndex(); 116 void updateAttributeIndex(const EntityAttribute::List& newAttributes); 117 118 void addAttributeToIndex(const AttributeName& name, const AttributeValue& value); 119 void removeAttributeFromIndex(const AttributeName& name, const AttributeValue& value); 120 void updateAttributeIndex(const AttributeName& oldName, const AttributeValue& oldValue, const AttributeName& newName, const AttributeValue& newValue); 121 public: // link management 122 const AttributableNodeList& linkSources() const; 123 const AttributableNodeList& linkTargets() const; 124 const AttributableNodeList& killSources() const; 125 const AttributableNodeList& killTargets() const; 126 127 Vec3 linkSourceAnchor() const; 128 Vec3 linkTargetAnchor() const; 129 130 bool hasMissingSources() const; 131 AttributeNameList findMissingLinkTargets() const; 132 AttributeNameList findMissingKillTargets() const; 133 private: // link management internals 134 void findMissingTargets(const AttributeName& prefix, AttributeNameList& result) const; 135 136 void addLinks(const AttributeName& name, const AttributeValue& value); 137 void removeLinks(const AttributeName& name, const AttributeValue& value); 138 void updateLinks(const AttributeName& oldName, const AttributeName& oldValue, const AttributeName& newName, const AttributeValue& newValue); 139 140 void addLinkTargets(const AttributeValue& targetname); 141 void addKillTargets(const AttributeValue& targetname); 142 143 void removeLinkTargets(const AttributeValue& targetname); 144 void removeKillTargets(const AttributeValue& targetname); 145 146 void addAllLinkSources(const AttributeValue& targetname); 147 void addAllLinkTargets(); 148 void addAllKillSources(const AttributeValue& targetname); 149 void addAllKillTargets(); 150 151 void addLinkTargets(const AttributableNodeList& targets); 152 void addKillTargets(const AttributableNodeList& targets); 153 void addLinkSources(const AttributableNodeList& sources); 154 void addKillSources(const AttributableNodeList& sources); 155 156 void removeAllLinkSources(); 157 void removeAllLinkTargets(); 158 void removeAllKillSources(); 159 void removeAllKillTargets(); 160 161 void removeAllLinks(); 162 void addAllLinks(); 163 164 void addLinkSource(AttributableNode* attributable); 165 void addLinkTarget(AttributableNode* attributable); 166 void addKillSource(AttributableNode* attributable); 167 void addKillTarget(AttributableNode* attributable); 168 169 void removeLinkSource(AttributableNode* attributable); 170 void removeLinkTarget(AttributableNode* attributable); 171 void removeKillSource(AttributableNode* attributable); 172 void removeKillTarget(AttributableNode* attributable); 173 protected: 174 AttributableNode(); 175 private: // implemenation of node interface 176 const String& doGetName() const; 177 virtual void doAncestorWillChange(); 178 virtual void doAncestorDidChange(); 179 private: // subclassing interface 180 virtual void doAttributesDidChange() = 0; 181 virtual bool doIsAttributeNameMutable(const AttributeName& name) const = 0; 182 virtual bool doIsAttributeValueMutable(const AttributeName& name) const = 0; 183 virtual Vec3 doGetLinkSourceAnchor() const = 0; 184 virtual Vec3 doGetLinkTargetAnchor() const = 0; 185 private: // hide copy constructor and assignment operator 186 AttributableNode(const AttributableNode&); 187 AttributableNode& operator=(const AttributableNode&); 188 }; 189 } 190 } 191 192 #endif /* defined(TrenchBroom_AttributableNode) */ 193