1 /**************************************************************************\
2  * Copyright (c) Kongsberg Oil & Gas Technologies AS
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are
7  * met:
8  *
9  * Redistributions of source code must retain the above copyright notice,
10  * this list of conditions and the following disclaimer.
11  *
12  * Redistributions in binary form must reproduce the above copyright
13  * notice, this list of conditions and the following disclaimer in the
14  * documentation and/or other materials provided with the distribution.
15  *
16  * Neither the name of the copyright holder nor the names of its
17  * contributors may be used to endorse or promote products derived from
18  * this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24  * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 \**************************************************************************/
32 
33 /*!
34   \class SoReplacedElement Inventor/elements/SoReplacedElement.h
35   \brief The SoReplacedElement class is an abstract element superclass.
36 
37   \ingroup elements
38 
39   This is the superclass of all elements where the new element data \e
40   replaces the old data, and where the data the element stores is not
41   just a simple float or integer value.
42 
43   Apart from this conceptual difference from its superclass, the
44   SoReplacedElement class also overloads the default getElement()
45   method to include a node reference. This reference is used to fetch
46   the unique node identification number of the node that last changed
47   the element.
48 
49   The identifier values of nodes in the scenegraph is updated upon \e
50   any kind of change to a node, so this technique plays an important
51   role in the construction, validation and destruction of internal
52   scenegraph caches.
53 
54   \sa SoAccumulatedElement
55 */
56 
57 #include <Inventor/elements/SoReplacedElement.h>
58 
59 #include "SbBasicP.h"
60 
61 #include <Inventor/nodes/SoNode.h>
62 #include <cassert>
63 
64 /*!
65   \var uint32_t SoReplacedElement::nodeId
66   \COININTERNAL
67 */
68 
69 
70 SO_ELEMENT_ABSTRACT_SOURCE(SoReplacedElement);
71 
72 
73 // Documented in superclass.
74 void
initClass(void)75 SoReplacedElement::initClass(void)
76 {
77   SO_ELEMENT_INIT_ABSTRACT_CLASS(SoReplacedElement, inherited);
78 }
79 
80 /*!
81   Destructor.
82 */
~SoReplacedElement(void)83 SoReplacedElement::~SoReplacedElement(void)
84 {
85 }
86 
87 // Documented in superclass.
88 void
init(SoState * state)89 SoReplacedElement::init(SoState * state)
90 {
91   inherited::init(state);
92   this->nodeId = 0;
93 }
94 
95 // Documented in superclass.
96 SbBool
matches(const SoElement * element) const97 SoReplacedElement::matches(const SoElement * element) const
98 {
99   if ((coin_assert_cast<const SoReplacedElement *>(element))->nodeId ==
100       this->nodeId)
101     return TRUE;
102   return FALSE;
103 }
104 
105 // Documented in superclass.
106 SoElement *
copyMatchInfo(void) const107 SoReplacedElement::copyMatchInfo(void) const
108 {
109   assert(getTypeId().canCreateInstance());
110   SoReplacedElement * element =
111     static_cast<SoReplacedElement *>(getTypeId().createInstance());
112   element->nodeId = this->nodeId;
113   return element;
114 }
115 
116 // Documented in superclass.
117 void
print(FILE * file) const118 SoReplacedElement::print(FILE * file) const
119 {
120   const char * typen = this->getTypeId().getName().getString();
121   (void)fprintf(file, "%s[%p]\n", typen, this);
122 }
123 
124 /*!
125   This function overloads SoElement::getElement() with an extra \a
126   node parameter, to let us set the SoReplacedElement::nodeId in the
127   element instance before returning.
128 
129   SoReplacedElement subclasses should use this method to get writable
130   instances.
131 
132   The identifier values of nodes in the scenegraph is updated upon \e
133   any kind of change to a node, so this technique plays an important
134   role in the construction, validation and destruction of internal
135   scenegraph caches.
136 
137   \sa SoElement::getElement()
138 */
139 SoElement *
getElement(SoState * const state,const int stackIndex,SoNode * const node)140 SoReplacedElement::getElement(SoState * const state, const int stackIndex,
141                                      SoNode * const node)
142 {
143   SoReplacedElement * elem =
144     coin_safe_cast<SoReplacedElement *>(SoElement::getElement(state, stackIndex));
145   if (elem) {
146     if (node) { elem->nodeId = node->getNodeId(); }
147     else { elem->nodeId = 0; }
148     return elem;
149   }
150   return NULL;
151 }
152 
153 /*!
154   Returns the node identifier for the node that previously updated the
155   SoReplacedElement.
156 */
157 SbUniqueId
getNodeId(void) const158 SoReplacedElement::getNodeId(void) const
159 {
160   return this->nodeId;
161 }
162