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 SoNodeSensor SoNodeSensor.h Inventor/sensors/SoNodeSensor.h
35   \brief The SoNodeSensor class detects changes to nodes.
36 
37   \ingroup sensors
38 
39   Attach a node to a sensor of this type to put it under surveillance,
40   so you can act upon changes to the node.
41 
42   Any modification to the node's fields will trigger the sensor, as
43   will changes to node's children (if any), including if nodes are
44   added or removed as children below the node in the subgraph.
45 
46   An SoNodeSensor can also act for delete-callback purposes alone and
47   does not need a regular notification-based callback.
48 */
49 
50 #include <Inventor/sensors/SoNodeSensor.h>
51 #include <Inventor/nodes/SoNode.h>
52 #include <Inventor/errors/SoDebugError.h>
53 
54 /*!
55   Default constructor.
56 */
SoNodeSensor(void)57 SoNodeSensor::SoNodeSensor(void)
58 {
59   this->convict = NULL;
60 }
61 
62 /*!
63   Constructor taking as parameters the sensor callback function and
64   the userdata which will be passed the callback.
65 
66   \sa setFunction(), setData()
67 */
SoNodeSensor(SoSensorCB * func,void * data)68 SoNodeSensor::SoNodeSensor(SoSensorCB * func, void * data)
69   : inherited(func, data)
70 {
71   this->convict = NULL;
72 }
73 
74 /*!
75   Destructor.
76 */
~SoNodeSensor(void)77 SoNodeSensor::~SoNodeSensor(void)
78 {
79   if (this->convict) this->detach();
80 }
81 
82 /*!
83   Attach sensor to a node. Whenever any data in the node (or its
84   children, if it's an SoGroup or SoGroup derived node) changes, the
85   sensor will be triggered and call the callback function.
86 
87   Attaching a node sensor to a node will \e not increase the node's
88   reference count (and conversely, detach()'ing the node sensor will
89   not decrease the reference count, either).
90 
91   When the attached node is deleted, the sensor will be automatically
92   detached().
93 
94   \sa detach()
95 */
96 void
attach(SoNode * node)97 SoNodeSensor::attach(SoNode * node)
98 {
99   if (this->convict != NULL) {
100     this->detach();
101     SoDebugError::postWarning("SoNodeSensor::attach",
102                               "Attaching node sensor that is already attached.",
103                               this);
104   }
105   this->convict = node;
106   node->addAuditor(this, SoNotRec::SENSOR);
107 }
108 
109 /*!
110   Detach sensor from node. As long as an SoNodeSensor is detached, it
111   will never call its callback function.
112 
113   \sa attach()
114 */
115 void
detach(void)116 SoNodeSensor::detach(void)
117 {
118   if (this->convict) this->convict->removeAuditor(this, SoNotRec::SENSOR);
119   this->convict = NULL;
120 }
121 
122 /*!
123   Returns a pointer to the node connected to the sensor.
124 
125   \sa attach(), detach()
126 */
127 SoNode *
getAttachedNode(void) const128 SoNodeSensor::getAttachedNode(void) const
129 {
130   return this->convict;
131 }
132 
133 // Doc from superclass.
134 void
dyingReference(void)135 SoNodeSensor::dyingReference(void)
136 {
137   SoNode * dyingnode = this->getAttachedNode();
138   this->invokeDeleteCallback();
139   if (dyingnode == this->getAttachedNode()) {
140     this->detach();
141   }
142 }
143