1 /*
2 * Copyright 2015, Rene Gollent, rene@gollent.com.
3 * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
4 * Distributed under the terms of the MIT License.
5 */
6
7
8 #include "ValueNode.h"
9
10 #include "Value.h"
11 #include "ValueLocation.h"
12 #include "ValueNodeContainer.h"
13
14
15 // #pragma mark - ValueNode
16
17
ValueNode(ValueNodeChild * nodeChild)18 ValueNode::ValueNode(ValueNodeChild* nodeChild)
19 :
20 fContainer(NULL),
21 fNodeChild(nodeChild),
22 fLocation(NULL),
23 fValue(NULL),
24 fLocationResolutionState(VALUE_NODE_UNRESOLVED),
25 fChildrenCreated(false)
26 {
27 fNodeChild->AcquireReference();
28 }
29
30
~ValueNode()31 ValueNode::~ValueNode()
32 {
33 SetLocationAndValue(NULL, NULL, VALUE_NODE_UNRESOLVED);
34 SetContainer(NULL);
35 fNodeChild->ReleaseReference();
36 }
37
38
39 const BString&
Name() const40 ValueNode::Name() const
41 {
42 return fNodeChild->Name();
43 }
44
45
46 void
SetContainer(ValueNodeContainer * container)47 ValueNode::SetContainer(ValueNodeContainer* container)
48 {
49 if (container == fContainer)
50 return;
51
52 if (fContainer != NULL)
53 fContainer->ReleaseReference();
54
55 fContainer = container;
56
57 if (fContainer != NULL)
58 fContainer->AcquireReference();
59
60 // propagate to children
61 int32 childCount = CountChildren();
62 for (int32 i = 0; i < childCount; i++)
63 ChildAt(i)->SetContainer(fContainer);
64 }
65
66
67 bool
IsRangedContainer() const68 ValueNode::IsRangedContainer() const
69 {
70 return false;
71 }
72
73
74 bool
IsContainerRangeFixed() const75 ValueNode::IsContainerRangeFixed() const
76 {
77 return false;
78 }
79
80
81 void
ClearChildren()82 ValueNode::ClearChildren()
83 {
84 // do nothing
85 }
86
87
88 status_t
CreateChildrenInRange(TeamTypeInformation * info,int32 lowIndex,int32 highIndex)89 ValueNode::CreateChildrenInRange(TeamTypeInformation* info, int32 lowIndex,
90 int32 highIndex)
91 {
92 return B_NOT_SUPPORTED;
93 }
94
95
96 status_t
SupportedChildRange(int32 & lowIndex,int32 & highIndex) const97 ValueNode::SupportedChildRange(int32& lowIndex, int32& highIndex) const
98 {
99 return B_NOT_SUPPORTED;
100 }
101
102
103 void
SetLocationAndValue(ValueLocation * location,Value * value,status_t resolutionState)104 ValueNode::SetLocationAndValue(ValueLocation* location, Value* value,
105 status_t resolutionState)
106 {
107 if (fLocation != location) {
108 if (fLocation != NULL)
109 fLocation->ReleaseReference();
110
111 fLocation = location;
112
113 if (fLocation != NULL)
114 fLocation->AcquireReference();
115 }
116
117 if (fValue != value) {
118 if (fValue != NULL)
119 fValue->ReleaseReference();
120
121 fValue = value;
122
123 if (fValue != NULL)
124 fValue->AcquireReference();
125 }
126
127 fLocationResolutionState = resolutionState;
128
129 // notify listeners
130 if (fContainer != NULL)
131 fContainer->NotifyValueNodeValueChanged(this);
132 }
133
134
135 // #pragma mark - ValueNodeChild
136
137
ValueNodeChild()138 ValueNodeChild::ValueNodeChild()
139 :
140 fContainer(NULL),
141 fNode(NULL),
142 fLocation(NULL),
143 fLocationResolutionState(VALUE_NODE_UNRESOLVED)
144 {
145 }
146
147
~ValueNodeChild()148 ValueNodeChild::~ValueNodeChild()
149 {
150 SetLocation(NULL, VALUE_NODE_UNRESOLVED);
151 SetNode(NULL);
152 SetContainer(NULL);
153 }
154
155
156 bool
IsInternal() const157 ValueNodeChild::IsInternal() const
158 {
159 return false;
160 }
161
162
163 status_t
CreateInternalNode(ValueNode * & _node)164 ValueNodeChild::CreateInternalNode(ValueNode*& _node)
165 {
166 return B_BAD_VALUE;
167 }
168
169
170 void
SetContainer(ValueNodeContainer * container)171 ValueNodeChild::SetContainer(ValueNodeContainer* container)
172 {
173 if (container == fContainer)
174 return;
175
176 if (fContainer != NULL)
177 fContainer->ReleaseReference();
178
179 fContainer = container;
180
181 if (fContainer != NULL)
182 fContainer->AcquireReference();
183
184 // propagate to node
185 if (fNode != NULL)
186 fNode->SetContainer(fContainer);
187 }
188
189
190 void
SetNode(ValueNode * node)191 ValueNodeChild::SetNode(ValueNode* node)
192 {
193 if (node == fNode)
194 return;
195
196 ValueNode* oldNode = fNode;
197 BReference<ValueNode> oldNodeReference(oldNode, true);
198
199 if (fNode != NULL)
200 fNode->SetContainer(NULL);
201
202 fNode = node;
203
204 if (fNode != NULL) {
205 fNode->AcquireReference();
206 fNode->SetContainer(fContainer);
207 }
208
209 if (fContainer != NULL)
210 fContainer->NotifyValueNodeChanged(this, oldNode, fNode);
211 }
212
213
214 ValueLocation*
Location() const215 ValueNodeChild::Location() const
216 {
217 return fLocation;
218 }
219
220
221 void
SetLocation(ValueLocation * location,status_t resolutionState)222 ValueNodeChild::SetLocation(ValueLocation* location, status_t resolutionState)
223 {
224 if (fLocation != location) {
225 if (fLocation != NULL)
226 fLocation->ReleaseReference();
227
228 fLocation = location;
229
230 if (fLocation != NULL)
231 fLocation->AcquireReference();
232 }
233
234 fLocationResolutionState = resolutionState;
235 }
236
237
238 // #pragma mark - ChildlessValueNode
239
240
ChildlessValueNode(ValueNodeChild * nodeChild)241 ChildlessValueNode::ChildlessValueNode(ValueNodeChild* nodeChild)
242 :
243 ValueNode(nodeChild)
244 {
245 fChildrenCreated = true;
246 }
247
248
249 status_t
CreateChildren(TeamTypeInformation * info)250 ChildlessValueNode::CreateChildren(TeamTypeInformation* info)
251 {
252 return B_OK;
253 }
254
255 int32
CountChildren() const256 ChildlessValueNode::CountChildren() const
257 {
258 return 0;
259 }
260
261
262 ValueNodeChild*
ChildAt(int32 index) const263 ChildlessValueNode::ChildAt(int32 index) const
264 {
265 return NULL;
266 }
267