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
18ValueNode::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
31ValueNode::~ValueNode()
32{
33	SetLocationAndValue(NULL, NULL, VALUE_NODE_UNRESOLVED);
34	SetContainer(NULL);
35	fNodeChild->ReleaseReference();
36}
37
38
39const BString&
40ValueNode::Name() const
41{
42	return fNodeChild->Name();
43}
44
45
46void
47ValueNode::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
67bool
68ValueNode::IsRangedContainer() const
69{
70	return false;
71}
72
73
74bool
75ValueNode::IsContainerRangeFixed() const
76{
77	return false;
78}
79
80
81void
82ValueNode::ClearChildren()
83{
84	// do nothing
85}
86
87
88status_t
89ValueNode::CreateChildrenInRange(TeamTypeInformation* info, int32 lowIndex,
90	int32 highIndex)
91{
92	return B_NOT_SUPPORTED;
93}
94
95
96status_t
97ValueNode::SupportedChildRange(int32& lowIndex, int32& highIndex) const
98{
99	return B_NOT_SUPPORTED;
100}
101
102
103void
104ValueNode::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
138ValueNodeChild::ValueNodeChild()
139	:
140	fContainer(NULL),
141	fNode(NULL),
142	fLocation(NULL),
143	fLocationResolutionState(VALUE_NODE_UNRESOLVED)
144{
145}
146
147
148ValueNodeChild::~ValueNodeChild()
149{
150	SetLocation(NULL, VALUE_NODE_UNRESOLVED);
151	SetNode(NULL);
152	SetContainer(NULL);
153}
154
155
156bool
157ValueNodeChild::IsInternal() const
158{
159	return false;
160}
161
162
163status_t
164ValueNodeChild::CreateInternalNode(ValueNode*& _node)
165{
166	return B_BAD_VALUE;
167}
168
169
170void
171ValueNodeChild::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
190void
191ValueNodeChild::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
214ValueLocation*
215ValueNodeChild::Location() const
216{
217	return fLocation;
218}
219
220
221void
222ValueNodeChild::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
241ChildlessValueNode::ChildlessValueNode(ValueNodeChild* nodeChild)
242	:
243	ValueNode(nodeChild)
244{
245	fChildrenCreated = true;
246}
247
248
249status_t
250ChildlessValueNode::CreateChildren(TeamTypeInformation* info)
251{
252	return B_OK;
253}
254
255int32
256ChildlessValueNode::CountChildren() const
257{
258	return 0;
259}
260
261
262ValueNodeChild*
263ChildlessValueNode::ChildAt(int32 index) const
264{
265	return NULL;
266}
267