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