Jamoma API  0.6.0.a19
TTAddressItem.cpp
1 /*
2  * TTAddressItem
3  * Copyright © 2012, Théo de la Hogue
4  *
5  * License: This code is licensed under the terms of the "New BSD License"
6  * http://creativecommons.org/licenses/BSD/
7  */
8 
9 #ifndef DISABLE_NODELIB
10 
11 #include "TTFoundationAPI.h"
12 #include "TTAddressItem.h"
13 
14 TTAddressItem::TTAddressItem(TTSymbol aSymbol, TTAddressItemPtr aParent, TTBoolean aSelection):
15  symbol(kTTSymEmpty),
16  parent(NULL),
17  options(NULL),
18  selection(NO)
19 {
20  if (aSymbol)
21  this->symbol = aSymbol;
22  else
23  this->symbol = kTTSymEmpty;
24 
25  this->parent = aParent;
26  this->options = new TTList();
27  this->selection = aSelection;
28 }
29 
30 TTAddressItem::~TTAddressItem()
31 {
32  this->clear();
33  delete this->options;
34 }
35 
36 void TTAddressItem::setSelection(const TTBoolean newSelectionState, TTBoolean recursively)
37 {
38  // filter repetitions
39  if (newSelectionState != this->selection)
40  this->selection = newSelectionState;
41 
42  // propagate below if needed (not to option)
43  if (recursively)
44  for (this->begin(); this->end(); this->next())
45  this->current()->setSelection(newSelectionState, recursively);
46 
47  // propagate to parent if selection is YES
48  if (newSelectionState && this->parent)
49  this->parent->setSelection(newSelectionState, NO);
50 }
51 
52 void TTAddressItem::setParent(const TTAddressItemPtr newParent)
53 {
54  this->parent = newParent;
55 }
56 
57 TTSymbol& TTAddressItem::getSymbol()
58 {
59  return this->symbol;
60 }
61 
62 TTAddressItemPtr TTAddressItem::getParent()
63 {
64  return this->parent;
65 }
66 
67 TTListPtr TTAddressItem::getOptions()
68 {
69  return this->options;
70 }
71 
72 TTBoolean TTAddressItem::getSelection()
73 {
74  return this->selection;
75 }
76 
77 TTAddressItemPtr TTAddressItem::getItem(TTSymbol aSymbol)
78 {
79  TTAddressItemPtr anItem = NULL;
80  TTValue found;
81 
82  TTErr err = ((TTListPtr)this)->find(&TTAddressItemFind, aSymbol.rawpointer(), found);
83 
84  if (!err)
85  anItem = TTAddressItemPtr((TTPtr)found[0]);
86 
87  return anItem;
88 }
89 
90 void TTAddressItem::clear()
91 {
92  // delete all items below
93  for (this->begin(); this->end(); this->next())
94  delete this->current();
95 
96  ((TTListPtr)this)->clear();
97 
98  this->options->clear();
99 }
100 
101 TTErr TTAddressItem::append(TTAddress addressToAppend, TTAddressItemPtr *returnedItem)
102 {
103  TTAddressItemPtr anItem = this;
104  TTAddressItemPtr nextItem;
105  TTList nameInstanceList;
106  TTSymbol nameInstance(kTTSymEmpty);
107 
108  addressToAppend.listNameInstance(nameInstanceList);
109 
110  for (nameInstanceList.begin(); nameInstanceList.end(); nameInstanceList.next()) {
111  nameInstance = nameInstanceList.current()[0];
112 
113  nextItem = anItem->getItem(nameInstance);
114 
115  if (!nextItem) {
116  nextItem = new TTAddressItem(nameInstance, anItem);
117  ((TTListPtr)anItem)->append((TTPtr)nextItem);
118  }
119 
120  anItem = nextItem;
121  }
122 
123  anItem->options->appendUnique(addressToAppend.getAttribute());
124 
125  *returnedItem = anItem;
126  return kTTErrNone;
127 }
128 
129 TTErr TTAddressItem::remove(TTAddress addressToRemove)
130 {
131  TTAddressItemPtr anItem, parentItem;
132 
133  // if the item exist
134  if (!this->find(addressToRemove, &anItem)) {
135 
136  // remove option (even empty option)
137  anItem->options->remove(addressToRemove.getAttribute());
138 
139  // if there no more options
140  if (anItem->options->isEmpty()) {
141 
142  // destroy upper parents if there are empty after removing the item
143  do {
144 
145  parentItem = anItem->getParent();
146  ((TTListPtr)parentItem)->remove((TTPtr)anItem);
147  destroy(anItem);
148 
149  anItem = parentItem;
150 
151  } while (anItem->isEmpty()) ;
152  }
153 
154  return kTTErrNone;
155  }
156 
157  return kTTErrValueNotFound;
158 }
159 
160 TTErr TTAddressItem::find(TTAddress addressToFind, TTAddressItemPtr *returnedItem)
161 {
162  TTAddressItemPtr anItem = this;
163  TTAddressItemPtr nextItem;
164  TTList nameInstanceList;
165  TTSymbol nameInstance(kTTSymEmpty);
166  TTValue v;
167 
168  addressToFind.listNameInstance(nameInstanceList);
169 
170  if (nameInstanceList.isEmpty())
171  return kTTErrGeneric;
172 
173  for (nameInstanceList.begin(); nameInstanceList.end(); nameInstanceList.next()) {
174 
175  nameInstance = nameInstanceList.current()[0];
176 
177  nextItem = anItem->getItem(nameInstance);
178 
179  if (!nextItem)
180  return kTTErrValueNotFound;
181  else
182  anItem = nextItem;
183  }
184 
185  if (anItem->options->isEmpty() && addressToFind.getAttribute() == NO_ATTRIBUTE) {
186  *returnedItem = anItem;
187  return kTTErrNone;
188  }
189 
190  if (!anItem->options->findEquals(addressToFind.getAttribute(), v)) {
191 
192  *returnedItem = anItem;
193  return kTTErrNone;
194  }
195 
196  return kTTErrValueNotFound;
197 }
198 
199 TTAddressItemPtr TTAddressItem::current()
200 {
201  TTAddressItemPtr anItem;
202 
203  anItem = TTAddressItemPtr((TTPtr) ((TTListPtr)this)->current()[0]);
204 
205  return anItem;
206 }
207 
208 TTErr TTAddressItem::merge(const TTAddressItemPtr anItemToMerge)
209 {
210  TTAddressItemPtr anItem;
211 
212  if (!anItemToMerge)
213  return kTTErrGeneric;
214 
215  // check if the item exists
216  anItem = this->getItem(anItemToMerge->symbol);
217 
218  if (!anItem) {
219  anItemToMerge->copy(&anItem);
220  ((TTListPtr)this)->append((TTPtr)anItem);
221  anItem->setParent(this);
222  anItem->options->merge(*this->options);
223  }
224  else
225  for (anItemToMerge->begin(); anItemToMerge->end(); anItemToMerge->next())
226  anItem->merge(anItemToMerge->current());
227 
228  return kTTErrNone;
229 }
230 
231 TTErr TTAddressItem::destroy(const TTAddressItemPtr anItemToRemove)
232 {
233  TTAddressItemPtr anItem;
234 
235  if (!anItemToRemove)
236  return kTTErrGeneric;
237 
238  // check if the item exists
239  anItem = this->getItem(anItemToRemove->symbol);
240 
241  if (anItem) {
242 
243  for (anItem->begin(); anItem->end(); anItem->next())
244  anItem->destroy(anItem->current());
245 
246  if (anItem->isEmpty()) {
247  ((TTListPtr)this)->remove((TTPtr)anItem);
248  delete anItem;
249  }
250 
251  return kTTErrNone;
252  }
253 
254  return kTTErrValueNotFound;
255 }
256 
257 TTBoolean TTAddressItem::exist(TTAddressItemPtr anItemToCheck, TTAddressItemPtr *returnedItem)
258 {
259  TTAddressItemPtr anItem;
260  TTBoolean same = anItemToCheck->getSymbol() == this->symbol;
261 
262  if (same) {
263 
264  if (anItemToCheck->isEmpty()) {
265  *returnedItem = this;
266  return kTTErrNone;
267  }
268 
269  *returnedItem = NULL;
270  for (anItemToCheck->begin(); anItemToCheck->end(); anItemToCheck->next()) {
271  for (this->begin(); this->end(); this->next()) {
272 
273  same = this->current()->exist(anItemToCheck->current(), &anItem);
274 
275  if (!same)
276  break;
277  }
278  }
279 
280  if (same) {
281  *returnedItem = anItem;
282  return kTTErrNone;
283  }
284  }
285 
286  return same;
287 }
288 
289 TTErr TTAddressItem::copy(TTAddressItemPtr *anItemCopy)
290 {
291  TTAddressItemPtr anItem;
292 
293  if (!(*anItemCopy))
294  *anItemCopy = new TTAddressItem(this->symbol, NULL, this->selection);
295 
296  for (this->begin(); this->end(); this->next()) {
297 
298  anItem = NULL;
299  this->current()->copy(&anItem);
300 
301  anItem->setParent(*anItemCopy);
302 
303  (*anItemCopy)->merge(anItem);
304  }
305  return kTTErrNone;
306 }
307 
308 void TTAddressItem::registerHandler(TTObject& anObject)
309 {
310  this->handlers.appendUnique(anObject);
311 }
312 
313 void TTAddressItem::unregisterHandler(TTObject& anObject)
314 {
315  this->handlers.remove(anObject);
316 }
317 
318 void TTAddressItem::iterateHandlersSendingMessage(TTSymbol& messageName)
319 {
320  this->handlers.iterateObjectsSendingMessage(messageName);
321 }
322 
323 void TTAddressItem::iterateHandlersSendingMessage(TTSymbol& messageName, TTValue& aValue)
324 {
325  this->handlers.iterateObjectsSendingMessage(messageName, aValue);
326 }
327 
328 #if 0
329 #pragma mark -
330 #pragma mark Some Methods
331 #endif
332 
333 ///void TTAddressItemFind(const TTValue& itemValue, TTPtr aSymbolToMatch, TTBoolean& found)
334 void TTAddressItemFind(const TTValue& itemValue, TTPtr aSymbolBaseToMatch, TTBoolean& found)
335 {
336  TTAddressItemPtr anItem;
337 
338  anItem = TTAddressItemPtr((TTPtr)itemValue[0]);
339 
340  found = anItem->getSymbol() == TTSymbol(aSymbolBaseToMatch);
341 }
342 
343 #endif
bool TTBoolean
Boolean flag, same as Boolean on the Mac.
Definition: TTBase.h:167
The TTAddress class is used to represent a string and efficiently pass and compare that string...
Definition: TTAddress.h:29
Create and use Jamoma object instances.
Definition: TTObject.h:29
void * TTPtr
A generic pointer.
Definition: TTBase.h:248
TTPtr rawpointer() const
Get the value of the raw pointer into the symbol table.
Definition: TTSymbol.h:134
The TTSymbol class is used to represent a string and efficiently pass and compare that string...
Definition: TTSymbol.h:26
TTErr listNameInstance(TTList &nameInstanceList)
A parsing tool : return a list containing all name.instance part (without any S_SEPARATOR) ...
Definition: TTAddress.h:213
TTSymbol & getAttribute()
Get the attribute part.
Definition: TTAddress.h:130
A value was not found when doing a look up for it (in a TTHash, TTList, or other class).
Definition: TTBase.h:352
Something went wrong, but what exactly is not known. Typically used for context-specific problems...
Definition: TTBase.h:344
TTErr
Jamoma Error Codes Enumeration of error codes that might be returned by any of the TTBlue functions a...
Definition: TTBase.h:342
No Error.
Definition: TTBase.h:343
[doxygenAppendixC_copyExample]
Definition: TTValue.h:34