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