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 #include "Node.h" 21 22 #include "CollectionUtils.h" 23 #include "Model/Issue.h" 24 #include "Model/IssueGenerator.h" 25 26 #include <algorithm> 27 #include <cassert> 28 29 namespace TrenchBroom { 30 namespace Model { Node()31 Node::Node() : 32 m_parent(NULL), 33 m_descendantCount(0), 34 m_selected(false), 35 m_childSelectionCount(0), 36 m_descendantSelectionCount(0), 37 m_visibilityState(Visibility_Inherited), 38 m_lockState(Lock_Inherited), 39 m_lineNumber(0), 40 m_lineCount(0), 41 m_issuesValid(false), 42 m_hiddenIssues(0) {} 43 ~Node()44 Node::~Node() { 45 clearChildren(); 46 clearIssues(); 47 } 48 name() const49 const String& Node::name() const { 50 return doGetName(); 51 } 52 bounds() const53 const BBox3& Node::bounds() const { 54 return doGetBounds(); 55 } 56 clone(const BBox3 & worldBounds) const57 Node* Node::clone(const BBox3& worldBounds) const { 58 return doClone(worldBounds); 59 } 60 cloneRecursively(const BBox3 & worldBounds) const61 Node* Node::cloneRecursively(const BBox3& worldBounds) const { 62 return doCloneRecursively(worldBounds); 63 } 64 takeSnapshot()65 NodeSnapshot* Node::takeSnapshot() { 66 return doTakeSnapshot(); 67 } 68 cloneAttributes(Node * node) const69 void Node::cloneAttributes(Node* node) const { 70 node->setVisiblityState(m_visibilityState); 71 node->setLockState(m_lockState); 72 } 73 clone(const BBox3 & worldBounds,const NodeList & nodes)74 NodeList Node::clone(const BBox3& worldBounds, const NodeList& nodes) { 75 NodeList clones; 76 clones.reserve(nodes.size()); 77 clone(worldBounds, nodes.begin(), nodes.end(), std::back_inserter(clones)); 78 return clones; 79 } 80 cloneRecursively(const BBox3 & worldBounds,const NodeList & nodes)81 NodeList Node::cloneRecursively(const BBox3& worldBounds, const NodeList& nodes) { 82 NodeList clones; 83 clones.reserve(nodes.size()); 84 cloneRecursively(worldBounds, nodes.begin(), nodes.end(), std::back_inserter(clones)); 85 return clones; 86 } 87 depth() const88 size_t Node::depth() const { 89 if (m_parent == NULL) 90 return 0; 91 return m_parent->depth() + 1; 92 } 93 parent() const94 Node* Node::parent() const { 95 return m_parent; 96 } 97 isAncestorOf(const Node * node) const98 bool Node::isAncestorOf(const Node* node) const { 99 return node->isDescendantOf(this); 100 } 101 isDescendantOf(const Node * node) const102 bool Node::isDescendantOf(const Node* node) const { 103 Node* parent = m_parent; 104 while (parent != NULL) { 105 if (parent == node) 106 return true; 107 parent = parent->parent(); 108 } 109 return false; 110 } 111 removeIfEmpty() const112 bool Node::removeIfEmpty() const { 113 return doRemoveIfEmpty(); 114 } 115 hasChildren() const116 bool Node::hasChildren() const { 117 return !m_children.empty(); 118 } 119 childCount() const120 size_t Node::childCount() const { 121 return m_children.size(); 122 } 123 children() const124 const NodeList& Node::children() const { 125 return m_children; 126 } 127 descendantCount() const128 size_t Node::descendantCount() const { 129 return m_descendantCount; 130 } 131 familySize() const132 size_t Node::familySize() const { 133 return m_descendantCount + 1; 134 } 135 addChildren(const NodeList & children)136 void Node::addChildren(const NodeList& children) { 137 addChildren(children.begin(), children.end(), children.size()); 138 } 139 addChild(Node * child)140 void Node::addChild(Node* child) { 141 doAddChild(child); 142 incDescendantCount(child->descendantCount() + 1); 143 incChildSelectionCount(child->selected() ? 1 : 0); 144 incDescendantSelectionCount(child->descendantSelectionCount()); 145 } 146 removeChild(Node * child)147 void Node::removeChild(Node* child) { 148 doRemoveChild(child); 149 decDescendantCount(child->descendantCount() + 1); 150 decChildSelectionCount(child->selected() ? 1 : 0); 151 decDescendantSelectionCount(child->descendantSelectionCount()); 152 } 153 canAddChild(Node * child) const154 bool Node::canAddChild(Node* child) const { 155 return doCanAddChild(child); 156 } 157 canRemoveChild(Node * child) const158 bool Node::canRemoveChild(Node* child) const { 159 return doCanRemoveChild(child); 160 } 161 doAddChild(Node * child)162 void Node::doAddChild(Node* child) { 163 assert(child != NULL); 164 assert(!VectorUtils::contains(m_children, child)); 165 assert(child->parent() == NULL); 166 assert(canAddChild(child)); 167 168 childWillBeAdded(child); 169 // nodeWillChange(); 170 m_children.push_back(child); 171 child->setParent(this); 172 childWasAdded(child); 173 // nodeDidChange(); 174 } 175 doRemoveChild(Node * child)176 void Node::doRemoveChild(Node* child) { 177 assert(child != NULL); 178 assert(child->parent() == this); 179 assert(canRemoveChild(child)); 180 181 childWillBeRemoved(child); 182 // nodeWillChange(); 183 child->setParent(NULL); 184 VectorUtils::erase(m_children, child); 185 childWasRemoved(child); 186 // nodeDidChange(); 187 } 188 clearChildren()189 void Node::clearChildren() { 190 VectorUtils::clearAndDelete(m_children); 191 } 192 childWillBeAdded(Node * node)193 void Node::childWillBeAdded(Node* node) { 194 doChildWillBeAdded(node); 195 descendantWillBeAdded(this, node); 196 } 197 childWasAdded(Node * node)198 void Node::childWasAdded(Node* node) { 199 doChildWasAdded(node); 200 descendantWasAdded(node); 201 } 202 childWillBeRemoved(Node * node)203 void Node::childWillBeRemoved(Node* node) { 204 doChildWillBeRemoved(node); 205 descendantWillBeRemoved(node); 206 } 207 childWasRemoved(Node * node)208 void Node::childWasRemoved(Node* node) { 209 doChildWasRemoved(node); 210 descendantWasRemoved(this, node); 211 } 212 descendantWillBeAdded(Node * newParent,Node * node)213 void Node::descendantWillBeAdded(Node* newParent, Node* node) { 214 doDescendantWillBeAdded(newParent, node); 215 if (shouldPropagateDescendantEvents() && m_parent != NULL) 216 m_parent->descendantWillBeAdded(newParent, node); 217 } 218 descendantWasAdded(Node * node)219 void Node::descendantWasAdded(Node* node) { 220 doDescendantWasAdded(node); 221 if (shouldPropagateDescendantEvents() && m_parent != NULL) 222 m_parent->descendantWasAdded(node); 223 invalidateIssues(); 224 } 225 descendantWillBeRemoved(Node * node)226 void Node::descendantWillBeRemoved(Node* node) { 227 doDescendantWillBeRemoved(node); 228 if (shouldPropagateDescendantEvents() && m_parent != NULL) 229 m_parent->descendantWillBeRemoved(node); 230 } 231 descendantWasRemoved(Node * oldParent,Node * node)232 void Node::descendantWasRemoved(Node* oldParent, Node* node) { 233 doDescendantWasRemoved(oldParent, node); 234 if (shouldPropagateDescendantEvents() && m_parent != NULL) 235 m_parent->descendantWasRemoved(oldParent, node); 236 invalidateIssues(); 237 } 238 shouldPropagateDescendantEvents() const239 bool Node::shouldPropagateDescendantEvents() const { 240 return doShouldPropagateDescendantEvents(); 241 } 242 incDescendantCount(const size_t delta)243 void Node::incDescendantCount(const size_t delta) { 244 if (delta == 0) 245 return; 246 m_descendantCount += delta; 247 if (m_parent != NULL) 248 m_parent->incDescendantCount(delta); 249 } 250 decDescendantCount(const size_t delta)251 void Node::decDescendantCount(const size_t delta) { 252 if (delta == 0) 253 return; 254 assert(m_descendantCount >= delta); 255 m_descendantCount -= delta; 256 if (m_parent != NULL) 257 m_parent->decDescendantCount(delta); 258 } 259 setParent(Node * parent)260 void Node::setParent(Node* parent) { 261 assert((m_parent == NULL) ^ (parent == NULL)); 262 assert(parent != this); 263 if (parent == m_parent) 264 return; 265 266 parentWillChange(); 267 m_parent = parent; 268 parentDidChange(); 269 } 270 parentWillChange()271 void Node::parentWillChange() { 272 doParentWillChange(); 273 ancestorWillChange(); 274 } 275 parentDidChange()276 void Node::parentDidChange() { 277 doParentDidChange(); 278 ancestorDidChange(); 279 } 280 ancestorWillChange()281 void Node::ancestorWillChange() { 282 doAncestorWillChange(); 283 NodeList::const_iterator it, end; 284 for (it = m_children.begin(), end = m_children.end(); it != end; ++it) { 285 Node* child = *it; 286 child->ancestorWillChange(); 287 } 288 invalidateIssues(); 289 } 290 ancestorDidChange()291 void Node::ancestorDidChange() { 292 doAncestorDidChange(); 293 NodeList::const_iterator it, end; 294 for (it = m_children.begin(), end = m_children.end(); it != end; ++it) { 295 Node* child = *it; 296 child->ancestorDidChange(); 297 } 298 invalidateIssues(); 299 } 300 nodeWillChange()301 void Node::nodeWillChange() { 302 if (m_parent != NULL) 303 m_parent->childWillChange(this); 304 invalidateIssues(); 305 } 306 nodeDidChange()307 void Node::nodeDidChange() { 308 if (m_parent != NULL) 309 m_parent->childDidChange(this); 310 invalidateIssues(); 311 } 312 NotifyNodeChange(Node * node)313 Node::NotifyNodeChange::NotifyNodeChange(Node* node) : 314 m_node(node) { 315 assert(m_node != NULL); 316 m_node->nodeWillChange(); 317 } 318 ~NotifyNodeChange()319 Node::NotifyNodeChange::~NotifyNodeChange() { 320 m_node->nodeDidChange(); 321 } 322 nodeBoundsDidChange()323 void Node::nodeBoundsDidChange() { 324 doNodeBoundsDidChange(); 325 if (m_parent != NULL) 326 m_parent->childBoundsDidChange(this); 327 } 328 childWillChange(Node * node)329 void Node::childWillChange(Node* node) { 330 doChildWillChange(node); 331 descendantWillChange(node); 332 } 333 childDidChange(Node * node)334 void Node::childDidChange(Node* node) { 335 doChildDidChange(node); 336 descendantDidChange(node); 337 } 338 descendantWillChange(Node * node)339 void Node::descendantWillChange(Node* node) { 340 doDescendantWillChange(node); 341 if (shouldPropagateDescendantEvents() && m_parent != NULL) 342 m_parent->descendantWillChange(node); 343 invalidateIssues(); 344 } 345 descendantDidChange(Node * node)346 void Node::descendantDidChange(Node* node) { 347 doDescendantDidChange(node); 348 if (shouldPropagateDescendantEvents() && m_parent != NULL) 349 m_parent->descendantDidChange(node); 350 invalidateIssues(); 351 } 352 childBoundsDidChange(Node * node)353 void Node::childBoundsDidChange(Node* node) { 354 doChildBoundsDidChange(node); 355 } 356 selected() const357 bool Node::selected() const { 358 return m_selected; 359 } 360 select()361 void Node::select() { 362 if (!selectable()) 363 return; 364 assert(!m_selected); 365 m_selected = true; 366 if (m_parent != NULL) 367 m_parent->childWasSelected(); 368 } 369 deselect()370 void Node::deselect() { 371 if (!selectable()) 372 return; 373 assert(m_selected); 374 m_selected = false; 375 if (m_parent != NULL) 376 m_parent->childWasDeselected(); 377 } 378 transitivelySelected() const379 bool Node::transitivelySelected() const { 380 return selected() || parentSelected(); 381 } 382 parentSelected() const383 bool Node::parentSelected() const { 384 if (m_parent == NULL) 385 return false; 386 if (m_parent->selected()) 387 return true; 388 return m_parent->parentSelected(); 389 } 390 childSelected() const391 bool Node::childSelected() const { 392 return m_childSelectionCount > 0; 393 } 394 childSelectionCount() const395 size_t Node::childSelectionCount() const { 396 return m_childSelectionCount; 397 } 398 399 descendantSelected() const400 bool Node::descendantSelected() const { 401 return m_descendantSelectionCount > 0; 402 } 403 descendantSelectionCount() const404 size_t Node::descendantSelectionCount() const { 405 return m_descendantSelectionCount; 406 } 407 childWasSelected()408 void Node::childWasSelected() { 409 incChildSelectionCount(1); 410 } 411 childWasDeselected()412 void Node::childWasDeselected() { 413 decChildSelectionCount(1); 414 } 415 incChildSelectionCount(const size_t delta)416 void Node::incChildSelectionCount(const size_t delta) { 417 if (delta == 0) 418 return; 419 m_childSelectionCount += delta; 420 incDescendantSelectionCount(delta); 421 } 422 decChildSelectionCount(const size_t delta)423 void Node::decChildSelectionCount(const size_t delta) { 424 if (delta == 0) 425 return; 426 assert(m_childSelectionCount >= delta); 427 m_childSelectionCount -= delta; 428 decDescendantSelectionCount(delta); 429 } 430 incDescendantSelectionCount(const size_t delta)431 void Node::incDescendantSelectionCount(const size_t delta) { 432 if (delta == 0) 433 return; 434 m_descendantSelectionCount += delta; 435 if (m_parent != NULL) 436 m_parent->incDescendantSelectionCount(delta); 437 } 438 decDescendantSelectionCount(const size_t delta)439 void Node::decDescendantSelectionCount(const size_t delta) { 440 if (delta == 0) 441 return; 442 assert(m_descendantSelectionCount >= delta); 443 m_descendantSelectionCount -= delta; 444 if (m_parent != NULL) 445 m_parent->decDescendantSelectionCount(delta); 446 } 447 selectable() const448 bool Node::selectable() const { 449 return doSelectable(); 450 } 451 visible() const452 bool Node::visible() const { 453 switch (m_visibilityState) { 454 case Visibility_Inherited: 455 return m_parent == NULL || m_parent->visible(); 456 case Visibility_Hidden: 457 return false; 458 case Visibility_Shown: 459 return true; 460 switchDefault() 461 } 462 } 463 shown() const464 bool Node::shown() const { 465 return m_visibilityState == Visibility_Shown; 466 } 467 hidden() const468 bool Node::hidden() const { 469 return m_visibilityState == Visibility_Hidden; 470 } 471 visibilityState() const472 VisibilityState Node::visibilityState() const { 473 return m_visibilityState; 474 } 475 setVisiblityState(const VisibilityState visibility)476 bool Node::setVisiblityState(const VisibilityState visibility) { 477 if (visibility != m_visibilityState) { 478 m_visibilityState = visibility; 479 return true; 480 } 481 return false; 482 } 483 ensureVisible()484 bool Node::ensureVisible() { 485 if (!visible()) 486 return setVisiblityState(Visibility_Shown); 487 return false; 488 } 489 editable() const490 bool Node::editable() const { 491 switch (m_lockState) { 492 case Lock_Inherited: 493 return m_parent == NULL || m_parent->editable(); 494 case Lock_Locked: 495 return false; 496 case Lock_Unlocked: 497 return true; 498 switchDefault() 499 } 500 } 501 locked() const502 bool Node::locked() const { 503 return !editable(); 504 } 505 lockState() const506 LockState Node::lockState() const { 507 return m_lockState; 508 } 509 setLockState(const LockState lockState)510 bool Node::setLockState(const LockState lockState) { 511 if (lockState != m_lockState) { 512 m_lockState = lockState; 513 return true; 514 } 515 return false; 516 517 } 518 pick(const Ray3 & ray,PickResult & pickResult) const519 void Node::pick(const Ray3& ray, PickResult& pickResult) const { 520 doPick(ray, pickResult); 521 } 522 findNodesContaining(const Vec3 & point,NodeList & result)523 void Node::findNodesContaining(const Vec3& point, NodeList& result) { 524 doFindNodesContaining(point, result); 525 } 526 intersectWithRay(const Ray3 & ray) const527 FloatType Node::intersectWithRay(const Ray3& ray) const { 528 return doIntersectWithRay(ray); 529 } 530 lineNumber() const531 size_t Node::lineNumber() const { 532 return m_lineNumber; 533 } 534 setFilePosition(const size_t lineNumber,const size_t lineCount)535 void Node::setFilePosition(const size_t lineNumber, const size_t lineCount) { 536 m_lineNumber = lineNumber; 537 m_lineCount = lineCount; 538 } 539 containsLine(const size_t lineNumber) const540 bool Node::containsLine(const size_t lineNumber) const { 541 return lineNumber >= m_lineNumber && lineNumber < m_lineNumber + m_lineCount; 542 } 543 issues(const IssueGeneratorList & issueGenerators)544 const IssueList& Node::issues(const IssueGeneratorList& issueGenerators) { 545 validateIssues(issueGenerators); 546 return m_issues; 547 } 548 issueHidden(const IssueType type) const549 bool Node::issueHidden(const IssueType type) const { 550 return (type & m_hiddenIssues) != 0; 551 } 552 setIssueHidden(const IssueType type,const bool hidden)553 void Node::setIssueHidden(const IssueType type, const bool hidden) { 554 if (hidden) 555 m_hiddenIssues |= type; 556 else 557 m_hiddenIssues &= ~type; 558 } 559 validateIssues(const IssueGeneratorList & issueGenerators)560 void Node::validateIssues(const IssueGeneratorList& issueGenerators) { 561 if (!m_issuesValid) { 562 IssueGeneratorList::const_iterator it, end; 563 for (it = issueGenerators.begin(), end = issueGenerators.end(); it != end; ++it) { 564 const IssueGenerator* generator = *it; 565 doGenerateIssues(generator, m_issues); 566 } 567 m_issuesValid = true; 568 } 569 } 570 invalidateIssues() const571 void Node::invalidateIssues() const { 572 clearIssues(); 573 m_issuesValid = false; 574 } 575 clearIssues() const576 void Node::clearIssues() const { 577 VectorUtils::clearAndDelete(m_issues); 578 } 579 findAttributableNodesWithAttribute(const AttributeName & name,const AttributeValue & value,AttributableNodeList & result) const580 void Node::findAttributableNodesWithAttribute(const AttributeName& name, const AttributeValue& value, AttributableNodeList& result) const { 581 return doFindAttributableNodesWithAttribute(name, value, result); 582 } 583 findAttributableNodesWithNumberedAttribute(const AttributeName & prefix,const AttributeValue & value,AttributableNodeList & result) const584 void Node::findAttributableNodesWithNumberedAttribute(const AttributeName& prefix, const AttributeValue& value, AttributableNodeList& result) const { 585 return doFindAttributableNodesWithNumberedAttribute(prefix, value, result); 586 } 587 addToIndex(AttributableNode * attributable,const AttributeName & name,const AttributeValue & value)588 void Node::addToIndex(AttributableNode* attributable, const AttributeName& name, const AttributeValue& value) { 589 doAddToIndex(attributable, name, value); 590 } 591 removeFromIndex(AttributableNode * attributable,const AttributeName & name,const AttributeValue & value)592 void Node::removeFromIndex(AttributableNode* attributable, const AttributeName& name, const AttributeValue& value) { 593 doRemoveFromIndex(attributable, name, value); 594 } 595 doCloneRecursively(const BBox3 & worldBounds) const596 Node* Node::doCloneRecursively(const BBox3& worldBounds) const { 597 Node* clone = Node::clone(worldBounds); 598 clone->addChildren(Node::cloneRecursively(worldBounds, children())); 599 return clone; 600 } 601 doTakeSnapshot()602 NodeSnapshot* Node::doTakeSnapshot() { 603 return NULL; 604 } 605 doChildWillBeAdded(Node * node)606 void Node::doChildWillBeAdded(Node* node) {} doChildWasAdded(Node * node)607 void Node::doChildWasAdded(Node* node) {} doChildWillBeRemoved(Node * node)608 void Node::doChildWillBeRemoved(Node* node) {} doChildWasRemoved(Node * node)609 void Node::doChildWasRemoved(Node* node) {} 610 doDescendantWillBeAdded(Node * newParent,Node * node)611 void Node::doDescendantWillBeAdded(Node* newParent, Node* node) {} doDescendantWasAdded(Node * node)612 void Node::doDescendantWasAdded(Node* node) {} doDescendantWillBeRemoved(Node * node)613 void Node::doDescendantWillBeRemoved(Node* node) {} doDescendantWasRemoved(Node * oldParent,Node * node)614 void Node::doDescendantWasRemoved(Node* oldParent, Node* node) {} doShouldPropagateDescendantEvents() const615 bool Node::doShouldPropagateDescendantEvents() const { return true; } 616 doParentWillChange()617 void Node::doParentWillChange() {} doParentDidChange()618 void Node::doParentDidChange() {} doAncestorWillChange()619 void Node::doAncestorWillChange() {} doAncestorDidChange()620 void Node::doAncestorDidChange() {} 621 doNodeBoundsDidChange()622 void Node::doNodeBoundsDidChange() {} doChildBoundsDidChange(Node * node)623 void Node::doChildBoundsDidChange(Node* node) {} 624 doChildWillChange(Node * node)625 void Node::doChildWillChange(Node* node) {} doChildDidChange(Node * node)626 void Node::doChildDidChange(Node* node) {} doDescendantWillChange(Node * node)627 void Node::doDescendantWillChange(Node* node) {} doDescendantDidChange(Node * node)628 void Node::doDescendantDidChange(Node* node) {} 629 doFindAttributableNodesWithAttribute(const AttributeName & name,const AttributeValue & value,AttributableNodeList & result) const630 void Node::doFindAttributableNodesWithAttribute(const AttributeName& name, const AttributeValue& value, AttributableNodeList& result) const { 631 if (m_parent != NULL) 632 m_parent->findAttributableNodesWithAttribute(name, value, result); 633 } 634 doFindAttributableNodesWithNumberedAttribute(const AttributeName & prefix,const AttributeValue & value,AttributableNodeList & result) const635 void Node::doFindAttributableNodesWithNumberedAttribute(const AttributeName& prefix, const AttributeValue& value, AttributableNodeList& result) const { 636 if (m_parent != NULL) 637 m_parent->findAttributableNodesWithNumberedAttribute(prefix, value, result); 638 } 639 doAddToIndex(AttributableNode * attributable,const AttributeName & name,const AttributeValue & value)640 void Node::doAddToIndex(AttributableNode* attributable, const AttributeName& name, const AttributeValue& value) { 641 if (m_parent != NULL) 642 m_parent->addToIndex(attributable, name, value); 643 } 644 doRemoveFromIndex(AttributableNode * attributable,const AttributeName & name,const AttributeValue & value)645 void Node::doRemoveFromIndex(AttributableNode* attributable, const AttributeName& name, const AttributeValue& value) { 646 if (m_parent != NULL) 647 m_parent->removeFromIndex(attributable, name, value); 648 } 649 } 650 } 651