Jamoma API  0.6.0.a19
TTApplication.cpp
Go to the documentation of this file.
1 /** @file
2  *
3  * @ingroup modularLibrary
4  *
5  * @brief TTObjectBase to handle application data structure like a TTNodeDirectory and a hash tables of names
6  *
7  * @details
8  *
9  * @authors Théo de la Hogue
10  *
11  * @copyright © 2010, Théo de la Hogue @n
12  * This code is licensed under the terms of the "New BSD License" @n
13  * http://creativecommons.org/licenses/BSD/
14  */
15 
16 
17 #include "TTApplication.h"
18 #include <libxml/encoding.h>
19 #include <libxml/xmlwriter.h>
20 #include <libxml/xmlreader.h>
21 
22 #define thisTTClass TTApplication
23 #define thisTTClassName "Application"
24 #define thisTTClassTags "modularLibrary, application"
25 
26 TT_MODULAR_CONSTRUCTOR,
27 mDirectory(NULL),
28 mName(kTTSymEmpty),
29 mType(kTTSym_local),
30 mVersion(kTTSymEmpty),
31 mAuthor(kTTSymEmpty),
32 mActivity(NO),
33 mDebug(NO),
34 mLearn(NO),
35 mTempAddress(kTTAdrsRoot)
36 {
39  addAttribute(Version, kTypeSymbol);
40  addAttribute(Author, kTypeSymbol);
41  addAttribute(Debug, kTypeBoolean);
43 
44  addAttribute(Learn, kTypeBoolean);
45 
46  TTAttributePtr anAttribute;
47 
48  registerAttribute(TTSymbol("activityIn"), kTypeLocalValue, NULL, (TTGetterMethod)& TTApplication::getActivityIn, (TTSetterMethod)& TTApplication::setActivityIn);
49  this->findAttribute(TTSymbol("activityIn"), &anAttribute);
50  anAttribute->sethidden(YES);
51 
52  registerAttribute(TTSymbol("activityOut"), kTypeLocalValue, NULL, (TTGetterMethod)& TTApplication::getActivityOut, (TTSetterMethod)& TTApplication::setActivityOut);
53  this->findAttribute(TTSymbol("activityOut"), &anAttribute);
54  anAttribute->sethidden(YES);
55 
56  registerAttribute(TTSymbol("cachedAttributes"), kTypeLocalValue, NULL, (TTGetterMethod)& TTApplication::getCachedAttributes, (TTSetterMethod)& TTApplication::setCachedAttributes);
57  this->findAttribute(TTSymbol("cachedAttributes"), &anAttribute);
58  anAttribute->sethidden(YES);
59 
60  addAttribute(Directory, kTypePointer);
61  addAttributeProperty(Directory, hidden, YES);
62  addAttributeProperty(Directory, readOnly, YES);
63 
64  addMessage(Init);
65 
66  addMessage(DirectoryClear);
67  addMessage(DirectoryBuild);
68  addMessageWithArguments(DirectoryObserve);
69 
70  // directory and attribute listening
71  addMessageWithArguments(AddDirectoryListener);
72  addMessageProperty(AddDirectoryListener, hidden, YES);
73 
74  addMessageWithArguments(AddAttributeListener);
75  addMessageProperty(AddAttributeListener, hidden, YES);
76 
77  addMessageWithArguments(RemoveDirectoryListener);
78  addMessageProperty(RemoveDirectoryListener, hidden, YES);
79 
80  addMessageWithArguments(RemoveAttributeListener);
81  addMessageProperty(RemoveAttributeListener, hidden, YES);
82 
83  addMessageWithArguments(UpdateDirectory);
84  addMessageProperty(UpdateDirectory, hidden, YES);
85 
86  addMessageWithArguments(UpdateAttribute);
87  addMessageProperty(UpdateAttribute, hidden, YES);
88 
89  addMessageWithArguments(ObjectRegister);
90  addMessageProperty(RegisterObject, hidden, YES);
91 
92  addMessageWithArguments(ObjectUnregister);
93  addMessageProperty(UnregisterObject, hidden, YES);
94 
95  addMessageWithArguments(ObjectRename);
96  addMessageProperty(ObjectRename, hidden, YES);
97 
98  addMessageWithArguments(ObjectRetreive);
99  addMessageProperty(RetreiveObject, hidden, YES);
100 
101  addMessageWithArguments(ObjectSend);
102  addMessageProperty(RetreiveObject, hidden, YES);
103 
104  // symbol conversion
106  addAttributeProperty(AllAppNames, hidden, YES);
107  addAttributeProperty(AllAppNames, readOnly, YES);
108 
110  addAttributeProperty(AllTTNames, hidden, YES);
111  addAttributeProperty(AllTTNames, readOnly, YES);
112 
113  addMessageWithArguments(ConvertToAppName);
114  addMessageProperty(ConvertToAppName, hidden, YES);
115 
116  addMessageWithArguments(ConvertToTTName);
117  addMessageProperty(ConvertToTTName, hidden, YES);
118 
119  // needed to be handled by a TTXmlHandler
120  addMessageWithArguments(WriteAsXml);
121  addMessageProperty(WriteAsXml, hidden, YES);
122 
123  addMessageWithArguments(ReadFromXml);
124  addMessageProperty(ReadFromXml, hidden, YES);
125 
126  // note : this a temporary message to allow proxy data creation
127  addMessageWithArguments(ProxyDataInstantiate);
128  addMessageProperty(ProxyDataInstantiate, hidden, YES);
129 
130  // create a TTNodeDirectory to handle the application namespace
131  mDirectory = new TTNodeDirectory(mName);
132 
133  TT_ASSERT("NodeDirectory created successfully", (mDirectory != NULL));
134 }
135 
136 #if 0
137 #pragma mark -
138 #pragma mark Destructor
139 #endif
140 
141 TTApplication::~TTApplication()
142 {
143  // TODO : delete observers
144  if (mDirectory)
145  delete mDirectory;
146 }
147 
148 #if 0
149 #pragma mark -
150 #pragma mark Attribute accesors
151 #endif
152 
153 TTErr TTApplication::setName(const TTValue& value)
154 {
155  TTValue none, args = mName;
156  args.append(value[0]);
157 
158  mName = value;
159  mDirectory->setName(mName);
160 
161  TTModularApplicationManager->sendMessage("ApplicationRename", args, none);
162 
163  return kTTErrNone;
164 }
165 
166 TTErr TTApplication::setActivity(const TTValue& value)
167 {
168  TTValue protocols = accessApplicationProtocolNames(mName);
169  TTSymbol protocolName;
170 
171  mActivity = value;
172 
173  for (TTUInt32 i = 0; i < protocols.size(); i++) {
174 
175  protocolName = protocols[i];
176  accessProtocol(protocolName)->setAttributeValue(kTTSym_activity, mActivity);
177  }
178 
179  return kTTErrNone;
180 }
181 
182 TTErr TTApplication::getActivityIn(TTValue& value)
183 {
184  // we don't store the activity in
185  // TODO : create a notification for this !
186  return kTTErrNone;
187 }
188 
189 TTErr TTApplication::setActivityIn(const TTValue& value)
190 {
191  TTAttributePtr anAttribute;
192  TTErr err = kTTErrNone;
193 
194  err = this->findAttribute(kTTSym_activityIn, &anAttribute);
195  if (!err)
196  anAttribute->sendNotification(kTTSym_notify, value); // we use kTTSym_notify because we know that observers are TTCallback
197 
198  return kTTErrNone;
199 }
200 
201 TTErr TTApplication::getActivityOut(TTValue& value)
202 {
203  // we don't store the activity out
204  // TODO : create a notification for this !
205  return kTTErrNone;
206 }
207 
208 TTErr TTApplication::setActivityOut(const TTValue& value)
209 {
210  TTAttributePtr anAttribute;
211  TTErr err = kTTErrNone;
212 
213  err = this->findAttribute(kTTSym_activityOut, &anAttribute);
214  if (!err)
215  anAttribute->sendNotification(kTTSym_notify, value); // we use kTTSym_notify because we know that observers are TTCallback
216 
217  return kTTErrNone;
218 }
219 
220 TTErr TTApplication::getCachedAttributes(TTValue& value)
221 {
222  // this accessor is only available for a mirror application
223  if (mType != kTTSym_mirror)
224  return kTTErrGeneric;
225 
226  mCachedAttributes.getKeys(value);
227 
228  return kTTErrNone;
229 }
230 
231 TTErr TTApplication::setCachedAttributes(const TTValue& value)
232 {
233  // this accessor is only available for a mirror application
234  if (mType != kTTSym_mirror)
235  return kTTErrGeneric;
236 
237  // update each node of the directory
238  if (mDirectory) {
239 
240  TTUInt32 i;
241  TTValue v, none;
242  TTHash lastCachedAttributes;
243  TTSymbol name;
244 
245  // keep the last cached attributes
246  mCachedAttributes.getKeys(v);
247  for (i = 0; i < v.size(); i++) {
248 
249  name = v[i];
250  lastCachedAttributes.append(name, none);
251  }
252 
253  // cache the new attributes that are not already cached
254  mCachedAttributes.clear();
255  for (i = 0; i < value.size(); i++) {
256 
257  name = value[i];
258  mCachedAttributes.append(name, none);
259 
260  // if the attribute wasn't already cached
261  if (lastCachedAttributes.lookup(name, none))
262  cacheAttributeNode(mDirectory->getRoot(), name, YES);
263  }
264 
265  // uncache the last cached attributes that are not cached anymore
266  lastCachedAttributes.getKeys(v);
267  for (i = 0; i < v.size(); i++) {
268 
269  name = v[i];
270 
271  // if the attribute is not cached anymore
272  if (mCachedAttributes.lookup(name, none))
273  cacheAttributeNode(mDirectory->getRoot(), name, NO);
274  }
275  }
276 
277  return kTTErrNone;
278 }
279 
280 TTErr TTApplication::cacheAttributeNode(TTNodePtr aNode, TTSymbol attributeName, TTBoolean cacheOrUncache)
281 {
282  TTObject anObject;
283  TTList nodeList;
284  TTNodePtr aChild;
285  TTValue none;
286 
287  // Send AttributeCache message to the mirror's node
288  anObject = aNode->getObject();
289  if (anObject.valid()) {
290 
291  if (cacheOrUncache)
292  anObject.send("AttributeCache", attributeName);
293  else
294  anObject.send("AttributeUncache", attributeName);
295  }
296 
297  // Cache attribute of node's object below
298  aNode->getChildren(S_WILDCARD, S_WILDCARD, nodeList);
299 
300  for (nodeList.begin(); nodeList.end(); nodeList.next())
301  {
302  aChild = TTNodePtr((TTPtr)nodeList.current()[0]);
303  cacheAttributeNode(aChild, attributeName, cacheOrUncache);
304  }
305 
306  return kTTErrNone;
307 }
308 
309 TTErr TTApplication::Init()
310 {
311  return initNode(mDirectory->getRoot());
312 }
313 
314 TTErr TTApplication::initNode(TTNodePtr aNode)
315 {
316  TTObject anObject;
317  TTList nodeList;
318  TTNodePtr aChild;
319 
320  // Send Init message to node's object
321  anObject = aNode->getObject();
322  if (anObject.valid() && anObject.instance() != this)
323  anObject.send(kTTSym_Init);
324 
325  // Init nodes below
326  aNode->getChildren(S_WILDCARD, S_WILDCARD, nodeList);
327 
328  // Sort children by priority order
329  nodeList.sort(&compareNodePriorityThenNameThenInstance);
330 
331  for (nodeList.begin(); nodeList.end(); nodeList.next())
332  {
333  aChild = TTNodePtr((TTPtr)nodeList.current()[0]);
334  initNode(aChild);
335  }
336 
337  return kTTErrNone;
338 }
339 
340 TTErr TTApplication::DirectoryClear()
341 {
342  // only for distant application
343  if (this == accessApplicationLocal)
344  return kTTErrGeneric;
345 
346  mDirectory->init();
347  mDirectory->getRoot()->setObject(TTObject(this));
348 
349  return kTTErrNone;
350 }
351 
352 TTErr TTApplication::DirectoryBuild()
353 {
354  TTSymbol protocolName;
355  TTProtocolPtr aProtocol;
356  TTValue v, protocolNames;
357 
358  // only for distant application
359  if (this == accessApplicationLocal)
360  return kTTErrGeneric;
361 
362  // clear the directory before to not duplicate nodes
363  DirectoryClear();
364 
365  // a distant application should have one protocol
366  protocolNames = accessApplicationProtocolNames(mName);
367  protocolName = protocolNames[0];
368 
369  aProtocol = accessProtocol(protocolName);
370  if (aProtocol)
371  return buildNode(aProtocol, kTTAdrsRoot);
372 
373  return kTTErrGeneric;
374 }
375 
376 TTErr TTApplication::buildNode(TTProtocolPtr aProtocol, TTAddress anAddress)
377 {
378  TTAddress nextAddress, childAddress;
379  TTSymbol returnedType, service;
380  TTValue returnedChildren;
381  TTValue returnedAttributes;
382  TTValue returnedValue;
383  TTObject anObject;
384  TTErr err;
385 
386  err = aProtocol->SendDiscoverRequest(mName, anAddress, returnedType, returnedChildren, returnedAttributes);
387 
388  if (!err) {
389 
390  if (anAddress != kTTAdrsRoot) {
391 
392  if (mType == kTTSym_mirror) {
393 
394  TTSymbol cachedAttribute;
395  TTValue attributesToCache, v, args, none;
396 
397  anObject = appendMirrorObject(aProtocol, anAddress, returnedType, returnedAttributes);
398 
399  if (anObject.valid()) {
400 
401  // cache attributes value
402  mCachedAttributes.getKeys(attributesToCache);
403  for (TTUInt32 i = 0; i < attributesToCache.size(); i++) {
404 
405  cachedAttribute = attributesToCache[i];
406 
407  // if the attribute exist
408  if (anObject.get(cachedAttribute, v) != kTTErrInvalidAttribute) {
409 
410  // cache the attribute value
411  args = cachedAttribute;
412  args.append((TTPtr)&v);
413  anObject.send("AttributeCache", args);
414  }
415  }
416  }
417  }
418 
419  else if (mType == kTTSym_proxy) {
420 
421  // DATA case
422  if (returnedType == kTTSym_Data) {
423 
424  // get the service attribute
425  err = aProtocol->SendGetRequest(mName, anAddress.appendAttribute(kTTSym_service), returnedValue);
426 
427  if (!err) {
428 
429  service = returnedValue[0];
430 
431  anObject = appendProxyData(aProtocol, anAddress, service);
432  }
433  }
434 
435  // other case ?
436  }
437  }
438 
439 
440  for (TTUInt32 i = 0; i < returnedChildren.size(); i++) {
441 
442  childAddress = returnedChildren[i];
443  nextAddress = anAddress.appendAddress(childAddress);
444 
445  // build child nodes (and report any error)
446  if (buildNode(aProtocol, nextAddress))
447  err = kTTErrGeneric;
448  }
449  }
450 
451  return err;
452 }
453 
454 TTErr TTApplication::DirectoryObserve(const TTValue& inputValue, TTValue& outputValue)
455 {
456  if (inputValue.size() == 1)
457  {
458  if (inputValue[0].type() == kTypeBoolean || inputValue[0].type() == kTypeInt32)
459  {
460  TTBoolean enable = inputValue[0];
461 
462  // only for distant application
463  if (this == accessApplicationLocal)
464  return kTTErrGeneric;
465 
466  // a distant application should have one protocol
467  TTSymbol protocolName = accessApplicationProtocolNames(mName)[0];
468 
469  TTProtocolPtr aProtocol = accessProtocol(protocolName);
470  if (aProtocol)
471  return aProtocol->SendListenRequest(mName, kTTAdrsRoot.appendAttribute(TTSymbol("life")), enable);
472  }
473  }
474 
475  return kTTErrGeneric;
476 }
477 
478 TTErr TTApplication::AddDirectoryListener(const TTValue& inputValue, TTValue& outputValue)
479 {
480  TTString editKey;
481  TTSymbol appToNotify, key;
482  TTAddress whereToListen;
483  TTObject returnValueCallback;
484  TTValue cacheElement, none;
485  TTErr err;
486 
487  appToNotify = inputValue[1];
488  whereToListen = inputValue[2];
489 
490  editKey = appToNotify.c_str();
491  editKey += "<>";
492  editKey += whereToListen.c_str();
493  key = TTSymbol(editKey);
494 
495  // if this listener doesn't exist yet
496  if (mDirectoryListenersCache.lookup(key, cacheElement)) {
497 
498  // prepare a callback based on ProtocolDirectoryCallback
499  returnValueCallback = TTObject("callback");
500 
501  returnValueCallback.set(kTTSym_baton, inputValue);
502  returnValueCallback.set(kTTSym_function, TTPtr(&TTProtocolDirectoryCallback));
503 
504  err = mDirectory->addObserverForNotifications(whereToListen, returnValueCallback); // ask to be notified for any address below
505 
506  if (!err) {
507 
508  // cache the observer in the directoryListenersCache
509  cacheElement.append(returnValueCallback);
510  return mDirectoryListenersCache.append(key, cacheElement);
511  }
512  else
513  ; // TODO : observe the directory in order to add the listener later
514  }
515 
516  return kTTErrGeneric;
517 }
518 
519 TTErr TTApplication::RemoveDirectoryListener(const TTValue& inputValue, TTValue& outputValue)
520 {
521  TTString editKey;
522  TTSymbol appToNotify, key;
523  TTAddress whereToListen;
524  TTObject returnValueCallback;
525  TTValue cacheElement;
526 
527  appToNotify = inputValue[0];
528  whereToListen = inputValue[1];
529 
530  editKey = appToNotify.c_str();
531  editKey += "<>";
532  editKey += whereToListen.c_str();
533  key = TTSymbol(editKey);
534 
535  // if this listener exists
536  if (!mDirectoryListenersCache.lookup(key, cacheElement)) {
537 
538  returnValueCallback = cacheElement[0];
539  mDirectory->removeObserverForNotifications(whereToListen, returnValueCallback);
540 
541  return mDirectoryListenersCache.remove(key);
542  }
543 
544  return kTTErrGeneric;
545 }
546 
547 TTErr TTApplication::AddAttributeListener(const TTValue& inputValue, TTValue& outputValue)
548 {
549  TTString editKey;
550  TTSymbol appToNotify, key;
551  TTAddress whereToListen;
552  TTList aNodeList;
553  TTNodePtr nodeToListen;
554  TTObject anObject;
555  TTAttributePtr anAttribute;
556  TTValue cacheElement, none;
557  TTErr err;
558 
559  appToNotify = inputValue[1];
560  whereToListen = inputValue[2];
561 
562  editKey = appToNotify.c_str();
563  editKey += "<>";
564  editKey += whereToListen.c_str();
565  key = TTSymbol(editKey);
566 
567  // if this listener doesn't exist yet
568  if (mAttributeListenersCache.lookup(key, cacheElement)) {
569 
570  err = mDirectory->Lookup(whereToListen, aNodeList, &nodeToListen);
571 
572  if (!err) {
573 
574  for (aNodeList.begin(); aNodeList.end(); aNodeList.next())
575  {
576  // get a node from the selection
577  nodeToListen = TTNodePtr((TTPtr)aNodeList.current()[0]);
578 
579  anObject = nodeToListen->getObject();
580  if (anObject.valid()) {
581 
582  // create an Attribute observer
583  anAttribute = NULL;
584  err = anObject.instance()->findAttribute(whereToListen.getAttribute(), &anAttribute);
585 
586  if (!err) {
587  // prepare a callback based on ProtocolAttributeCallback
588  TTObject returnValueCallback = TTObject("callback");
589 
590  returnValueCallback.set(kTTSym_baton, inputValue);
591  returnValueCallback.set(kTTSym_function, TTPtr(&TTProtocolAttributeCallback));
592 
593  anAttribute->registerObserverForNotifications(returnValueCallback);
594 
595  // we have now passed the returnValueCallback pointer to the callback
596  // it will be fetched back out to free the object in removeAttributeListener()
597 
598  // cache the listener in the attributeListenersCache
599  cacheElement.append(returnValueCallback);
600  }
601  }
602  }
603 
604  return mAttributeListenersCache.append(key, cacheElement);
605  }
606  else
607  ; // TODO : observe the directory in order to add the listener later
608  }
609 
610  // don't return an error if the listening is already enabled
611  return kTTErrNone;
612 }
613 
614 TTErr TTApplication::RemoveAttributeListener(const TTValue& inputValue, TTValue& outputValue)
615 {
616  TTString editKey;
617  TTSymbol appToNotify, key;
618  TTAddress whereToListen;
619  TTList aNodeList;
620  TTNodePtr nodeToListen;
621  TTObject anObject;
622  TTAttributePtr anAttribute;
623  TTValue cacheElement;
624  TTUInt32 i;
625  TTErr err;
626 
627  appToNotify = inputValue[0];
628  whereToListen = inputValue[1];
629 
630  editKey = appToNotify.c_str();
631  editKey += "<>";
632  editKey += whereToListen.c_str();
633  key = TTSymbol(editKey);
634 
635  // if this listener exists
636  if (!mAttributeListenersCache.lookup(key, cacheElement)) {
637 
638  err = mDirectory->Lookup(whereToListen, aNodeList, &nodeToListen);
639 
640  if (!err) {
641 
642  i = 0;
643  for (aNodeList.begin(); aNodeList.end(); aNodeList.next())
644  {
645  // get a node from the selection
646  nodeToListen = TTNodePtr((TTPtr)aNodeList.current()[0]);
647 
648  anObject = nodeToListen->getObject();
649  if (anObject.valid()) {
650 
651  // delete Attribute observer
652  anAttribute = NULL;
653  err = anObject.instance()->findAttribute(whereToListen.getAttribute(), &anAttribute);
654 
655  if (!err) {
656 
657  TTObject returnValueCallback = cacheElement[i];
658 
659  anAttribute->unregisterObserverForNotifications(returnValueCallback);
660 
661  i++;
662  }
663  }
664  }
665 
666  return mAttributeListenersCache.remove(key);
667  }
668  }
669 
670  return kTTErrGeneric;
671 }
672 
673 TTErr TTApplication::UpdateDirectory(const TTValue& inputValue, TTValue& outputValue)
674 {
675  TTAddress whereComesFrom;
676  TTValuePtr newValue;
677  TTValue none;
678  TTSymbol type, protocolName;;
679  TTList aNodeList;
680  TTNodePtr aNode;
681  TTProtocolPtr aProtocol;
682  TTErr err;
683 
684  whereComesFrom = inputValue[0];
685  newValue = TTValuePtr((TTPtr)inputValue[1]);
686 
687  // in learn mode we can only create Data
688  if (mLearn)
689  type = kTTSym_Data;
690  else
691  type = newValue[0];
692 
693  err = mDirectory->Lookup(whereComesFrom, aNodeList, &aNode);
694 
695  // if the node doesn't exist already
696  if (type != TTSymbol("delete") && err) {
697 
698  // a distant application should have one protocol
699  protocolName = accessApplicationProtocolNames(mName)[0];
700 
701  aProtocol = accessProtocol(protocolName);
702  if (aProtocol) {
703 
704  if (mType == kTTSym_mirror)
705  // instantiate Mirror object for distant application
706  appendMirrorObject(aProtocol, whereComesFrom, type, none);
707 
708  if (mType == kTTSym_proxy) {
709 
710  // instantiate proxy Data object for distant application
711  TTObject aData = appendProxyData(aProtocol, whereComesFrom, kTTSym_parameter);
712 
713  // TODO : how to allow to choose what to create when learning ?
714 
715  // initialize the value with the incoming value
716  aData.set("value", *newValue);
717  }
718 
719  return kTTErrNone;
720  }
721  }
722 
723  // if the node exists : remove it
724  else if (!err && type == TTSymbol("delete"))
725  return mDirectory->TTNodeRemove(whereComesFrom);
726 
727  return kTTErrGeneric;
728 }
729 
730 TTErr TTApplication::UpdateAttribute(const TTValue& inputValue, TTValue& outputValue)
731 {
732  TTNodePtr nodeToUpdate;
733  TTAddress whereComesFrom;
734  TTValuePtr newValue;
735  TTObject anObject;
736  TTErr err;
737 
738  if (mLearn)
739  UpdateDirectory(inputValue, outputValue);
740 
741  whereComesFrom = inputValue[0];
742  newValue = TTValuePtr((TTPtr)inputValue[1]);
743 
744  err = mDirectory->getTTNode(whereComesFrom, &nodeToUpdate);
745 
746  if (!err) {
747 
748  anObject = nodeToUpdate->getObject();
749  if (anObject.valid()) {
750 
751  if (anObject.name() == kTTSym_Mirror)
752  return TTMirrorPtr(anObject.instance())->updateAttributeValue(whereComesFrom.getAttribute(), *newValue);
753  else
754  return anObject.set(whereComesFrom.getAttribute(), *newValue);
755  }
756  }
757 
758  return kTTErrGeneric;
759 }
760 
761 TTErr TTApplication::ObjectRegister(const TTValue& inputValue, TTValue& outputValue)
762 {
763  // get address and object
764  if (inputValue.size() >= 2) {
765 
766  if (inputValue[0].type() == kTypeSymbol && inputValue[1].type() == kTypeObject) {
767 
768  TTAddress address = inputValue[0];
769  TTObject object = inputValue[1];
770 
771  // get optional context
772  TTPtr context = NULL;
773  if (inputValue.size() == 3)
774  if (inputValue[2].type() == kTypePointer)
775  context = inputValue[2];
776 
777  // register the object
778  TTNodePtr node;
779  TTBoolean newInstanceCreated;
780 
781  if (address == kTTAdrsRoot)
782  return mDirectory->getRoot()->setObject(object);
783 
784  else {
785  TTErr err = mDirectory->TTNodeCreate(address, object, context, &node, &newInstanceCreated);
786 
787  // return the effective address
788  if (!err) {
789 
790  if (newInstanceCreated)
791  node->getAddress(address);
792 
793  outputValue = address;
794  }
795 
796  return err;
797  }
798  }
799  }
800 
801  return kTTErrGeneric;
802 }
803 
804 TTErr TTApplication::ObjectUnregister(const TTValue& inputValue, TTValue& outputValue)
805 {
806  // get address
807  if (inputValue.size() == 1) {
808 
809  if (inputValue[0].type() == kTypeSymbol) {
810 
811  TTAddress address = inputValue[0];
812 
813  // retreive the node
814  TTNodePtr node;
815 
816  if (!mDirectory->getTTNode(address, &node)) {
817 
818  // return the object
819  outputValue = node->getObject();
820 
821  // unregister it
822  if (address == kTTAdrsRoot) {
823  TTObject empty;
824  return node->setObject(empty);
825  }
826  else
827  return mDirectory->TTNodeRemove(address);
828  }
829  }
830  }
831 
832  return kTTErrGeneric;
833 }
834 
835 TTErr TTApplication::ObjectRename(const TTValue& inputValue, TTValue& outputValue)
836 {
837  if (inputValue.size() == 2) {
838 
839  if (inputValue[0].type() == kTypeObject && inputValue[1].type() == kTypeSymbol) {
840 
841  TTObject anObject = inputValue[0];
842  TTAddress newNameInstance = inputValue[1];
843 
844  // check it is name.instance only
845  if (newNameInstance.getType() == kAddressRelative && newNameInstance.getParent() == kTTAdrsEmpty) {
846 
847  TTList aNodeList;
848  TTBoolean isThere;
849  TTNodePtr aNode;
850 
851  // search the object from the root
852  aNodeList.append(mDirectory->getRoot());
853 
854  TTErr err = mDirectory->IsThere(&aNodeList, &testNodeObject, anObject.instance(), &isThere, &aNode);
855 
856  if (!err && isThere) {
857 
858  TTBoolean newInstanceCreated;
859  TTSymbol newInstance, effectiveNameInstance;
860  TTAddress effectiveAddress;
861 
862  aNode->setNameInstance(newNameInstance, newInstance, &newInstanceCreated);
863 
864  aNode->getAddress(effectiveAddress);
865 
866  outputValue = effectiveAddress.getNameInstance();
867 
868  return kTTErrNone;
869  }
870  }
871  }
872  }
873 
874  return kTTErrGeneric;
875 }
876 
877 TTErr TTApplication::ObjectRetreive(const TTValue& inputValue, TTValue& outputValue)
878 {
879  // get address
880  if (inputValue.size() == 1) {
881 
882  if (inputValue[0].type() == kTypeSymbol) {
883 
884  TTAddress address = inputValue[0];
885  TTList aNodeList;
886  TTNodePtr aNode;
887 
888  // allow to use wilcards
889  TTErr err = mDirectory->Lookup(address, aNodeList, &aNode);
890 
891  if (!err) {
892 
893  for (aNodeList.begin(); aNodeList.end(); aNodeList.next())
894  {
895  // get a node from the selection
896  aNode = TTNodePtr((TTPtr)aNodeList.current()[0]);
897 
898  TTObject anObject = aNode->getObject();
899 
900  if (anObject.valid()) {
901 
902  // return the object
903  outputValue.append(anObject);
904  }
905  }
906 
907  return kTTErrNone;
908  }
909 
910  return err;
911  }
912  }
913 
914  return kTTErrGeneric;
915 }
916 
917 TTErr TTApplication::ObjectSend(const TTValue& inputValue, TTValue& outputValue)
918 {
919  std::cout << "ObjectSend" << std::endl;
920  // get address
921  if (inputValue.size() >= 1) {
922 
923  if (inputValue[0].type() == kTypeSymbol) {
924 
925  TTAddress address = inputValue[0];
926  TTList aNodeList;
927  TTNodePtr aNode;
928 
929  // allow to use wilcards
930  TTErr err = mDirectory->Lookup(address, aNodeList, &aNode);
931 
932  if (!err) {
933 
934  std::cout << "ok" << std::endl;
935 
936  TTValue valueToSend, none;
937 
938  // remove the address part to get the value to send
939  valueToSend.copyFrom(inputValue, 1);
940 
941  for (aNodeList.begin(); aNodeList.end(); aNodeList.next())
942  {
943  // get a node from the selection
944  aNode = TTNodePtr((TTPtr)aNodeList.current()[0]);
945 
946  TTObject anObject = aNode->getObject();
947 
948  if (anObject.valid()) {
949 
950  // TTData case : for value attribute use Command message
951  if (anObject.name() == kTTSym_Data) {
952 
953  if (address.getAttribute() == kTTSym_value)
954  err = anObject.send(kTTSym_Command, valueToSend);
955  else
956  err = anObject.set(address.getAttribute(), valueToSend);
957  }
958  else {
959  // try to set an attribute
960  err = anObject.set(address.getAttribute(), valueToSend);
961 
962  // try to use a message
963  if (err == address)
964  err = anObject.send(address.getAttribute(), valueToSend);
965  }
966  }
967 
968  if (err)
969  break;
970  }
971 
972  return kTTErrNone;
973  }
974  // distant application case : try to send the message even if it is not in the directory
975  else if (this != accessApplicationLocal) {
976 
977  TTSymbol protocolName;
978  TTProtocolPtr aProtocol;
979  TTValue valueToSend, protocolNames;
980 
981  // remove the address part to get the value to send
982  valueToSend.copyFrom(inputValue, 1);
983 
984  // a distant application should have one protocol
985  protocolNames = accessApplicationProtocolNames(mName);
986  protocolName = protocolNames[0];
987 
988  aProtocol = accessProtocol(protocolName);
989  if (aProtocol)
990  return aProtocol->SendSetRequest(mName, address, valueToSend);
991  }
992 
993  return err;
994  }
995  }
996 
997  return kTTErrGeneric;
998 }
999 
1000 TTErr TTApplication::getAllAppNames(TTValue& value)
1001 {
1002  if (mAppToTT.isEmpty())
1003  value = kTTSymEmpty;
1004  else
1005  mAppToTT.getKeys(value);
1006 
1007  return kTTErrNone;
1008 }
1009 
1010 TTErr TTApplication::getAllTTNames(TTValue& value)
1011 {
1012  if (mTTToApp.isEmpty())
1013  value = kTTSymEmpty;
1014  else
1015  mTTToApp.getKeys(value);
1016 
1017  return kTTErrNone;
1018 }
1019 
1020 TTErr TTApplication::ConvertToAppName(const TTValue& inputValue, TTValue& outputValue)
1021 {
1022  TTValue c;
1023  TTSymbol ttName;
1024  TTSymbol appName;
1025 
1026  // if there is only 1 symbol : replace value directly by the found one.
1027  // because it's possible to have conversion containing several appNames for 1 ttname
1028  if (inputValue.size() == 1) {
1029 
1030  if (inputValue[0].type() == kTypeSymbol){
1031 
1032  ttName = inputValue[0];
1033  return this->mTTToApp.lookup(ttName, outputValue);
1034  }
1035  }
1036 
1037  // else convert each symbol of the value.
1038  // !!! in this case 1 to many conversion is not handled
1039  for (TTUInt8 i = 0; i < inputValue.size(); i++)
1040  if (inputValue[i].type() == kTypeSymbol) {
1041  ttName = inputValue[i];
1042  if (!this->mTTToApp.lookup(ttName, c)) {
1043  appName = c[0];
1044  outputValue[i] = appName;
1045  }
1046  }
1047 
1048  return kTTErrNone;
1049 }
1050 
1051 TTErr TTApplication::ConvertToTTName(const TTValue& inputValue, TTValue& outputValue)
1052 {
1053  TTValue c;
1054  TTSymbol appName;
1055  TTSymbol ttName;
1056 
1057  // if there is only 1 symbol : replace value directly by the founded one.
1058  // because it's possible to have conversion containing several ttNames for 1 appName
1059  if (inputValue.size() == 1) {
1060 
1061  if (inputValue[0].type() == kTypeSymbol){
1062 
1063  appName = inputValue[0];
1064  return this->mAppToTT.lookup(appName, outputValue);
1065  }
1066  }
1067 
1068  // else convert each symbol of the value.
1069  // !!! in this case 1 to many conversion is not handled
1070  for (TTUInt8 i = 0; i < inputValue.size(); i++)
1071  if (inputValue[i].type() == kTypeSymbol) {
1072  appName = inputValue[i];
1073  if (!this->mAppToTT.lookup(appName, c)) {
1074  ttName = c[0];
1075  outputValue[i] = ttName;
1076  }
1077  }
1078 
1079  return kTTErrNone;
1080 }
1081 
1082 TTErr TTApplication::WriteAsXml(const TTValue& inputValue, TTValue& outputValue)
1083 {
1084  TTObject o = inputValue[0];
1085  TTXmlHandlerPtr aXmlHandler = (TTXmlHandlerPtr)o.instance();
1086  if (!aXmlHandler)
1087  return kTTErrGeneric;
1088 
1089  // Start "Application" xml node
1090  xmlTextWriterStartElement((xmlTextWriterPtr)aXmlHandler->mWriter, BAD_CAST "application");
1091 
1092  // Write attributes
1093  xmlTextWriterWriteAttribute((xmlTextWriterPtr)aXmlHandler->mWriter, BAD_CAST "name", BAD_CAST mName.c_str());
1094  xmlTextWriterWriteAttribute((xmlTextWriterPtr)aXmlHandler->mWriter, BAD_CAST "author", BAD_CAST mAuthor.c_str());
1095  xmlTextWriterWriteAttribute((xmlTextWriterPtr)aXmlHandler->mWriter, BAD_CAST "version", BAD_CAST mVersion.c_str());
1096  xmlTextWriterWriteAttribute((xmlTextWriterPtr)aXmlHandler->mWriter, BAD_CAST "type", BAD_CAST mType.c_str());
1097 
1098  // write cached attributed for mirror application only
1099  if (mType == kTTSym_mirror) {
1100 
1101  TTValue v;
1102  mCachedAttributes.getKeys(v);
1103  v.toString();
1104  TTString s = TTString(v[0]);
1105  xmlTextWriterWriteAttribute((xmlTextWriterPtr)aXmlHandler->mWriter, BAD_CAST "cachedAttributes", BAD_CAST s.c_str());
1106  }
1107 
1108  // Write all the namespace starting from the root of the directory
1109  if (mDirectory)
1110  writeNodeAsXml(aXmlHandler, mDirectory->getRoot());
1111 
1112  // End xml node
1113  xmlTextWriterEndElement((xmlTextWriterPtr)aXmlHandler->mWriter);
1114 
1115  return kTTErrNone;
1116 }
1117 
1118 void TTApplication::writeNodeAsXml(TTXmlHandlerPtr aXmlHandler, TTNodePtr aNode)
1119 {
1120  TTAddress nameInstance;
1121  TTSymbol objectName, attributeName;
1122  TTObject anObject;
1123  TTValue attributeNameList, v, c, none;
1124  TTList nodeList;
1125  TTNodePtr aChild;
1126  TTString aString;
1127 
1128  // Write node's object attributes
1129 
1130  anObject = aNode->getObject();
1131  if (anObject.valid()) {
1132 
1133  objectName = anObject.name();
1134 
1135  if (objectName == kTTSym_Mirror)
1136  objectName = TTMirrorPtr(anObject.instance())->getName();
1137 
1138  }
1139 
1140  // don't write the application that is registered under the root
1141  if (objectName != kTTSym_Application) {
1142 
1143  // Write description attribute as an xml comment for local or proxy application
1144  if (mType != kTTSym_mirror) {
1145 
1146  if (anObject.valid()) {
1147 
1148  if (!anObject.get(kTTSym_description, v)) {
1149 
1150  v.toString();
1151  aString = TTString(v[0]);
1152  xmlTextWriterWriteFormatComment((xmlTextWriterPtr)aXmlHandler->mWriter, "%s", BAD_CAST aString.data());
1153  }
1154  }
1155  }
1156 
1157  // Start object type xml node
1158  xmlTextWriterStartElement((xmlTextWriterPtr)aXmlHandler->mWriter, BAD_CAST "node");
1159 
1160  // Write address attribute "name.instance"
1161  nameInstance = TTAddress(NO_DIRECTORY, NO_PARENT, aNode->getName(), aNode->getInstance(), NO_ATTRIBUTE);
1162  xmlTextWriterWriteAttribute((xmlTextWriterPtr)aXmlHandler->mWriter, BAD_CAST "address", BAD_CAST nameInstance.c_str());
1163 
1164  // Write object type attribute
1165  if (objectName != kTTSymEmpty)
1166  xmlTextWriterWriteAttribute((xmlTextWriterPtr)aXmlHandler->mWriter, BAD_CAST "object", BAD_CAST objectName.c_str());
1167 
1168  // TODO : allow to choose which kind of object can write its attributes or not
1169  if (objectName != kTTSym_Data &&
1170  objectName != kTTSym_Mirror &&
1171  objectName != kTTSym_Container &&
1172  objectName != kTTSym_Input &&
1173  objectName != kTTSym_InputAudio &&
1174  objectName != kTTSym_Output &&
1175  objectName != kTTSym_OutputAudio)
1176  ; // do nothing
1177 
1178  // Write attributes
1179  else if (anObject.valid()) {
1180 
1181  anObject.attributes(attributeNameList);
1182 
1183  for(TTUInt32 i = 0; i < attributeNameList.size(); i++)
1184  {
1185  attributeName = attributeNameList[i];
1186 
1187  // Filter attribute names
1188  if (attributeName != kTTSym_description &&
1189  attributeName != kTTSym_value &&
1190  attributeName != kTTSym_address &&
1191  attributeName != kTTSym_bypass &&
1192  attributeName != kTTSym_activityIn &&
1193  attributeName != kTTSym_activityOut &&
1194  attributeName != kTTSym_rampStatus &&
1195  attributeName != kTTSym_baton && // because #TTData inherits #TTCallback
1196  attributeName != kTTSym_object && // because #TTData inherits #TTCallback
1197  attributeName != kTTSym_notification && // because #TTData inherits #TTCallback
1198  attributeName != kTTSym_function) // because #TTData inherits #TTCallback
1199  {
1200 
1201  // write only cached attributes
1202  if (mType == kTTSym_mirror)
1203  if (mCachedAttributes.lookup(attributeName, none))
1204  continue;
1205 
1206  anObject.get(attributeName, v);
1207 
1208  if (v.empty())
1209  continue;
1210 
1211  v.toString();
1212  aString = TTString(v[0]);
1213 
1214  if (aString.empty())
1215  continue;
1216 
1217  xmlTextWriterWriteAttribute((xmlTextWriterPtr)aXmlHandler->mWriter, BAD_CAST attributeName.c_str(), BAD_CAST aString.data());
1218  }
1219  }
1220 
1221  // TODO : Write messages ?
1222  }
1223  }
1224 
1225  // Write nodes below
1226  aNode->getChildren(S_WILDCARD, S_WILDCARD, nodeList);
1227 
1228  for (nodeList.begin(); nodeList.end(); nodeList.next())
1229  {
1230  aChild = TTNodePtr((TTPtr)nodeList.current()[0]);
1231  writeNodeAsXml(aXmlHandler, aChild);
1232  }
1233 
1234  // End xml node
1235  // don't write the application that is registered under the root
1236  if (objectName != kTTSym_Application)
1237  xmlTextWriterEndElement((xmlTextWriterPtr)aXmlHandler->mWriter);
1238 }
1239 
1240 TTErr TTApplication::ReadFromXml(const TTValue& inputValue, TTValue& outputValue)
1241 {
1242  TTObject o = inputValue[0];
1243  TTXmlHandlerPtr aXmlHandler = (TTXmlHandlerPtr)o.instance();
1244  if (!aXmlHandler)
1245  return kTTErrGeneric;
1246 
1247  TTString anAppKey, aTTKey;
1248  TTValue appValue, ttValue, v, nameValue, parameterValue;
1249 
1250  // Switch on the name of the XML node
1251 
1252  // Starts reading
1253  if (aXmlHandler->mXmlNodeName == kTTSym_xmlHandlerReadingStarts)
1254  return kTTErrNone;
1255 
1256  // Ends reading
1257  if (aXmlHandler->mXmlNodeName == kTTSym_xmlHandlerReadingEnds)
1258  return kTTErrNone;
1259 
1260  // Comment Node
1261  if (aXmlHandler->mXmlNodeName == kTTSym_xmlHandlerReadingComment)
1262  return kTTErrNone;
1263 
1264  // Conversion Table node
1265  if (aXmlHandler->mXmlNodeName == TTSymbol("conversionTable")) {
1266 
1267  if (aXmlHandler->mXmlNodeStart)
1268  mAppToTT.clear();
1269 
1270  return kTTErrNone;
1271  }
1272 
1273  // Entry node
1274  if (aXmlHandler->mXmlNodeName == TTSymbol("entry")) {
1275 
1276  // get App Symbol
1277  if (xmlTextReaderMoveToAttribute((xmlTextReaderPtr)aXmlHandler->mReader, BAD_CAST "App") == 1) {
1278  aXmlHandler->fromXmlChar(xmlTextReaderValue((xmlTextReaderPtr)aXmlHandler->mReader), appValue);
1279  v = appValue;
1280  v.toString();
1281  anAppKey = TTString(v[0]);
1282  }
1283 
1284  // get TT Value
1285  if (xmlTextReaderMoveToAttribute((xmlTextReaderPtr)aXmlHandler->mReader, BAD_CAST "TT") == 1) {
1286  aXmlHandler->fromXmlChar(xmlTextReaderValue((xmlTextReaderPtr)aXmlHandler->mReader), ttValue);
1287  v = ttValue;
1288  v.toString();
1289  aTTKey = TTString(v[0]);
1290  }
1291 
1292  mAppToTT.append(TTSymbol(anAppKey), ttValue); // here we register the entire value to handle 1 to many conversion
1293  mTTToApp.append(TTSymbol(aTTKey), appValue); // here we register the entire value to handle 1 to many conversion
1294 
1295  return kTTErrNone;
1296  }
1297 
1298  // Application node
1299  if (aXmlHandler->mXmlNodeName == TTSymbol("application")) {
1300 
1301  if (aXmlHandler->mXmlNodeStart) {
1302 
1303  DirectoryClear();
1304  mTempAddress = kTTAdrsRoot;
1305 
1306  // get the type attribute
1307  if (xmlTextReaderMoveToAttribute((xmlTextReaderPtr)aXmlHandler->mReader, (const xmlChar*)("type")) == 1) {
1308 
1309  aXmlHandler->fromXmlChar(xmlTextReaderValue((xmlTextReaderPtr)aXmlHandler->mReader), v);
1310 
1311  if (v.size() == 1) {
1312 
1313  if (v[0].type() == kTypeSymbol) {
1314 
1315  mType = v[0];
1316  }
1317  }
1318  }
1319 
1320  // get the author attribute
1321  if (xmlTextReaderMoveToAttribute((xmlTextReaderPtr)aXmlHandler->mReader, (const xmlChar*)("author")) == 1) {
1322 
1323  aXmlHandler->fromXmlChar(xmlTextReaderValue((xmlTextReaderPtr)aXmlHandler->mReader), v, YES);
1324 
1325  if (v.size() == 1) {
1326 
1327  if (v[0].type() == kTypeSymbol) {
1328 
1329  mAuthor = v[0];
1330  }
1331  }
1332  }
1333 
1334  // get the version attribute
1335  if (xmlTextReaderMoveToAttribute((xmlTextReaderPtr)aXmlHandler->mReader, (const xmlChar*)("version")) == 1) {
1336 
1337  aXmlHandler->fromXmlChar(xmlTextReaderValue((xmlTextReaderPtr)aXmlHandler->mReader), v);
1338 
1339  if (v.size() == 1) {
1340 
1341  if (v[0].type() == kTypeSymbol) {
1342 
1343  mVersion = v[0];
1344  }
1345  }
1346  }
1347 
1348  // get the cached attributes
1349  if (xmlTextReaderMoveToAttribute((xmlTextReaderPtr)aXmlHandler->mReader, (const xmlChar*)("cachedAttributes")) == 1) {
1350 
1351  aXmlHandler->fromXmlChar(xmlTextReaderValue((xmlTextReaderPtr)aXmlHandler->mReader), v);
1352  setCachedAttributes(v);
1353  }
1354  }
1355 
1356  return kTTErrNone;
1357  }
1358 
1359  // Any other node
1360  readNodeFromXml(aXmlHandler);
1361 
1362  return kTTErrNone;
1363 }
1364 
1365 void TTApplication::readNodeFromXml(TTXmlHandlerPtr aXmlHandler)
1366 {
1367  TTSymbol objectName, protocolName, attributeName, attributeToFilterName;
1368  TTAddress address;
1369  TTBoolean useInstanceAsName = NO;
1370  TTInt32 instance;
1371  TTProtocolPtr aProtocol;
1372  TTObject anObject;
1373  TTValue v, protocolNames, none;
1374  TTHash attributesToFilter;
1375 
1376  // when a node starts : append address to the current temp address
1377  if (aXmlHandler->mXmlNodeStart) {
1378 
1379  // the address attribute can store names which are problematic with xml (like number)
1380  if (xmlTextReaderMoveToAttribute((xmlTextReaderPtr)aXmlHandler->mReader, (const xmlChar*)("address")) == 1) {
1381 
1382  aXmlHandler->fromXmlChar(xmlTextReaderValue((xmlTextReaderPtr)aXmlHandler->mReader), v, YES, YES);
1383 
1384  if (v.size() == 1) {
1385 
1386  if (v[0].type() == kTypeSymbol) {
1387 
1388  address = v[0];
1389 
1390  if (address == TTSymbol("instance"))
1391  useInstanceAsName = YES;
1392  else
1393  mTempAddress = mTempAddress.appendAddress(address);
1394  }
1395  }
1396  }
1397 
1398  // optionnal : use the node name to build the address
1399  // NOTE : we keep this option for backward compatibility but now the node name is always stored into address attribute (see in : writeNodeAsXml)
1400  else
1401  mTempAddress = mTempAddress.appendAddress(TTAddress(aXmlHandler->mXmlNodeName));
1402 
1403  // optionnal : the instance attribute allow to easily duplicate a namespace part
1404  instance = 1;
1405  if (xmlTextReaderMoveToAttribute((xmlTextReaderPtr)aXmlHandler->mReader, (const xmlChar*)("instance")) == 1) {
1406 
1407  aXmlHandler->fromXmlChar(xmlTextReaderValue((xmlTextReaderPtr)aXmlHandler->mReader), v);
1408 
1409  if (v.size() == 1) {
1410 
1411  if (v[0].type() == kTypeInt32) {
1412 
1413  instance = v[0];
1414 
1415  // if we don't use the instance as a name
1416  if (!useInstanceAsName)
1417  {
1418  // start instance numbering from 1 (and let the nodelib duplication mechanism do the rest)
1419  mTempAddress = mTempAddress.appendInstance(TTSymbol("1"));
1420 
1421  // if the node is not empty : we have to duplicate its content too !
1422  if (!aXmlHandler->mXmlNodeIsEmpty)
1423  {
1424  mFoldAddress = mTempAddress;
1425  mFolderSize = instance;
1426  TTLogMessage("TTApplication::readNodeFromXml : %s is a fold address to duplicate %d times\n", mFoldAddress.c_str(), mFolderSize);
1427  }
1428  }
1429  }
1430  }
1431  }
1432  // aXmlHandler->mXmlNodeStart : NO
1433  else
1434  {
1435  // end of content duplication
1436  if (mFoldAddress != kTTAdrsEmpty && mTempAddress == mFoldAddress)
1437  {
1438  TTLogMessage("TTApplication::readNodeFromXml : %s fold address ends\n", mTempAddress.c_str());
1439  mFoldAddress = kTTAdrsEmpty;
1440  mFolderSize = 0;
1441  }
1442  }
1443 
1444  // is a parent part of the address is the fold address ?
1445  TTUInt32 duplicate = 1;
1446  TTInt8 duplicateDepth = 0;
1447  if (mFoldAddress != kTTAdrsEmpty && mFoldAddress != mTempAddress)
1448  {
1449  TTAddressComparisonFlag comparison = mTempAddress.compare(mFoldAddress, duplicateDepth);
1450 
1451  if (comparison == kAddressLower)
1452  {
1453  duplicate = mFolderSize;
1454  }
1455  }
1456 
1457  // read the file several times if duplicate > 1
1458  for (TTUInt32 d = 1; d <= duplicate; d++)
1459  {
1460  // in case of content duplication : duplicate fold address part
1461  TTAddress duplicateFoldAddress;
1462  if (mFoldAddress != kTTAdrsEmpty)
1463  {
1464  v = TTInt32(d);
1465  v.toString();
1466  TTString s = TTString(v[0]);
1467  duplicateFoldAddress = mFoldAddress.appendInstance(s);
1468  }
1469 
1470  // read the file several times if instance > 1
1471  for (TTInt32 i = 0; i < instance; i++)
1472  {
1473  if (useInstanceAsName)
1474  {
1475  // start numbering from 1
1476  v = TTInt32(i+1);
1477  v.toString();
1478  TTString s = TTString(v[0]);
1479  address = mTempAddress.appendAddress(TTAddress(s.data()));
1480  }
1481  else
1482  address = mTempAddress;
1483 
1484  // in case of content duplication : merge duplicate fold address part and
1485  if (mFoldAddress != kTTAdrsEmpty && duplicateDepth > 0)
1486  {
1487  TTAddress foldPart;
1488  TTAddress tempPart;
1489  TTUInt8 splitAt = address.countSeparator() - duplicateDepth;
1490  if (useInstanceAsName)
1491  splitAt--;
1492  address.splitAt(splitAt, foldPart, tempPart);
1493  address = duplicateFoldAddress.appendAddress(tempPart);
1494  }
1495 
1496  // get the object name
1497  objectName = kTTSymEmpty;
1498  if (xmlTextReaderMoveToAttribute((xmlTextReaderPtr)aXmlHandler->mReader, (const xmlChar*)("object")) == 1) {
1499 
1500  aXmlHandler->fromXmlChar(xmlTextReaderValue((xmlTextReaderPtr)aXmlHandler->mReader), v);
1501 
1502  if (v.size() == 1) {
1503 
1504  if (v[0].type() == kTypeSymbol)
1505  objectName = v[0];
1506  }
1507  }
1508 
1509  // a distant application should have one protocol
1510  protocolNames = accessApplicationProtocolNames(mName);
1511  protocolName = protocolNames[0];
1512 
1513  aProtocol = accessProtocol(protocolName);
1514  if (aProtocol) {
1515 
1516  // for mirror application
1517  if (mType == kTTSym_mirror) {
1518 
1519  // instantiate a mirror object
1520  anObject = appendMirrorObject(aProtocol, address, objectName, none);
1521 
1522  }
1523  // for proxy appplication
1524  else if (mType == kTTSym_proxy) {
1525 
1526  // instantiate the real object
1527 
1528  // DATA case
1529  if (objectName == kTTSym_Data) {
1530 
1531  // get the data service
1532  if (xmlTextReaderMoveToAttribute((xmlTextReaderPtr)aXmlHandler->mReader, (const xmlChar*)("service")) == 1) {
1533 
1534  aXmlHandler->fromXmlChar(xmlTextReaderValue((xmlTextReaderPtr)aXmlHandler->mReader), v);
1535 
1536  if (v.size() == 1) {
1537 
1538  if (v[0].type() == kTypeSymbol) {
1539 
1540  // instantiate a proxy data
1541  anObject = appendProxyData(aProtocol, address, v[0]);
1542 
1543  // filter service attribute for the parsing of all attributes
1544  attributesToFilter.append(kTTSym_service, none);
1545 
1546  // get the data type
1547  if (xmlTextReaderMoveToAttribute((xmlTextReaderPtr)aXmlHandler->mReader, (const xmlChar*)("type")) == 1) {
1548 
1549  aXmlHandler->fromXmlChar(xmlTextReaderValue((xmlTextReaderPtr)aXmlHandler->mReader), v);
1550 
1551  if (v.size() == 1) {
1552 
1553  if (v[0].type() == kTypeSymbol) {
1554 
1555  // set data type
1556  anObject.set(kTTSym_type, v);
1557 
1558  // filter type attribute for the parsing of all attributes
1559  attributesToFilter.append(kTTSym_type, none);
1560  }
1561  }
1562  }
1563  }
1564  }
1565  }
1566  }
1567  else if (objectName == kTTSym_Container) {
1568 
1569  // instantiate a proxy container
1570  anObject = appendProxyContainer(aProtocol, address);
1571 
1572  }
1573  else if (objectName == kTTSymEmpty ||
1574  objectName == kTTSym_none) // for backward compatibility because we don't write anything when there is no object
1575  {
1576 
1577  // register no object into the directory
1578  TTNodePtr aNode;
1579  TTObject empty;
1580  TTBoolean newInstanceCreated;
1581 
1582  this->mDirectory->TTNodeCreate(address, empty, NULL, &aNode, &newInstanceCreated);
1583  }
1584 
1585  // OTHER case ? Input, Output, Mapper ?
1586 
1587  }
1588 
1589  if (anObject.valid()) {
1590 
1591  // cache attributes (for mirror application only)
1592  if (mType == kTTSym_mirror) {
1593 
1594  TTSymbol cachedAttribute;
1595  TTValue attributesToCache, v, args, none;
1596  TTAttributePtr attribute;
1597 
1598  // cache attributes value
1599  mCachedAttributes.getKeys(attributesToCache);
1600  for (TTUInt32 i = 0; i < attributesToCache.size(); i++) {
1601 
1602  cachedAttribute = attributesToCache[i];
1603 
1604  // if the attribute exist
1605  if (!anObject.instance()->findAttribute(cachedAttribute, &attribute)) {
1606 
1607  // cache the attribute with no value (see after)
1608  args = cachedAttribute;
1609  anObject.send("AttributeCache", args);
1610  }
1611  }
1612  }
1613 
1614  // return to the first attribute
1615  xmlTextReaderMoveToFirstAttribute((xmlTextReaderPtr)aXmlHandler->mReader);
1616 
1617  // get all object attributes and their value
1618  do {
1619  // get attribute name
1620  aXmlHandler->fromXmlChar(xmlTextReaderName((xmlTextReaderPtr)aXmlHandler->mReader), v);
1621 
1622  if (v.size() == 1) {
1623 
1624  if (v[0].type() == kTypeSymbol) {
1625 
1626  attributeName = v[0];
1627 
1628  // filter attributes
1629  if (!attributesToFilter.lookup(attributeName, none))
1630  continue;
1631 
1632  // get attribute value
1633  aXmlHandler->fromXmlChar(xmlTextReaderValue((xmlTextReaderPtr)aXmlHandler->mReader), v);
1634 
1635  // if the attribute is not cached or in proxy application case
1636  anObject.set(attributeName, v);
1637  }
1638  }
1639  } while (xmlTextReaderMoveToNextAttribute((xmlTextReaderPtr)aXmlHandler->mReader) == 1);
1640  }
1641  }
1642  } // for instance
1643  } // for duplication
1644 
1645  // when a node is empty : keep the parent address for next nodes
1646  // but if we use instance as name : don't
1647  if (aXmlHandler->mXmlNodeIsEmpty && !useInstanceAsName)
1648  mTempAddress = mTempAddress.getParent();
1649  }
1650 
1651  // when a node ends : keep the parent address for next nodes
1652  else
1653  mTempAddress = mTempAddress.getParent();
1654 }
1655 
1656 TTErr TTApplication::ProxyDataInstantiate(const TTValue& inputValue, TTValue& outputValue)
1657 {
1658  // for proxy application only
1659  if (mType == kTTSym_proxy) {
1660 
1661  // a distant application should have one protocol
1662  TTValue protocolNames = accessApplicationProtocolNames(mName);
1663  TTSymbol protocolName = protocolNames[0];
1664 
1665  TTProtocolPtr aProtocol = accessProtocol(protocolName);
1666  if (aProtocol) {
1667 
1668  if (inputValue.size() == 2) {
1669 
1670  if (inputValue[0].type() == kTypeSymbol && inputValue[1].type() == kTypeSymbol) {
1671 
1672  TTAddress address = inputValue[0];
1673  TTSymbol service = inputValue[1];
1674 
1675  // instantiate a proxy data object
1676  outputValue = appendProxyData(aProtocol, address.normalize(), service);
1677  return kTTErrNone;
1678  }
1679  }
1680  }
1681  }
1682 
1683  return kTTErrGeneric;
1684 }
1685 
1686 TTObject TTApplication::appendMirrorObject(TTProtocolPtr aProtocol, TTAddress anAddress, TTSymbol objectName, TTValue& attributesName)
1687 {
1688  TTObject aMirror;
1689  TTNodePtr aNode;
1690  TTBoolean newInstanceCreated, allowGetRequest, allowSetRequest, allowListenRequest;
1691  TTObject getAttributeCallback, setAttributeCallback, sendMessageCallback, listenAttributeCallback;
1692  TTObject empty;
1693  TTValue baton;
1694 
1695  if (objectName != kTTSymEmpty && objectName != kTTSym_none) {
1696 
1697  TTValue none, v, args = objectName;
1698 
1699  aProtocol->getAttributeValue(TTSymbol("get"), allowGetRequest);
1700 
1701  if (allowGetRequest) {
1702 
1703  getAttributeCallback = TTObject("callback");
1704  // TODO: How to use TTObject instead of TTObjectBasePtr here ?
1705  baton = TTValue(TTObject(TTObjectBasePtr(aProtocol)), mName, anAddress);
1706  getAttributeCallback.set(kTTSym_baton, baton);
1707  getAttributeCallback.set(kTTSym_function, TTPtr(&TTProtocolGetAttributeCallback));
1708  args.append(getAttributeCallback);
1709  }
1710  else
1711  args.append(empty);
1712 
1713  aProtocol->getAttributeValue(TTSymbol("set"), allowSetRequest);
1714 
1715  if (allowSetRequest) {
1716 
1717  setAttributeCallback = TTObject("callback");
1718  // TODO: How to use TTObject instead of TTObjectBasePtr here ?
1719  baton = TTValue(TTObject(TTObjectBasePtr(aProtocol)), mName, anAddress);
1720  setAttributeCallback.set(kTTSym_baton, baton);
1721  setAttributeCallback.set(kTTSym_function, TTPtr(&TTProtocolSetAttributeCallback));
1722  args.append(setAttributeCallback);
1723 
1724  sendMessageCallback = TTObject("callback");
1725  // TODO: How to use TTObject instead of TTObjectBasePtr here ?
1726  baton = TTValue(TTObject(TTObjectBasePtr(aProtocol)), mName, anAddress);
1727  sendMessageCallback.set(kTTSym_baton, baton);
1728  sendMessageCallback.set(kTTSym_function, TTPtr(&TTProtocolSendMessageCallback));
1729  args.append(sendMessageCallback);
1730  }
1731  else {
1732 
1733  args.append(empty);
1734  args.append(empty);
1735  }
1736 
1737  aProtocol->getAttributeValue(TTSymbol("listen"), allowListenRequest);
1738 
1739  if (allowListenRequest) {
1740 
1741  listenAttributeCallback = TTObject("callback");
1742  // TODO: How to use TTObject instead of TTObjectBasePtr here ?
1743  baton = TTValue(TTObject(TTObjectBasePtr(aProtocol)), mName, anAddress);
1744  listenAttributeCallback.set(kTTSym_baton, baton);
1745  listenAttributeCallback.set(kTTSym_function, TTPtr(&TTProtocolListenAttributeCallback));
1746  args.append(listenAttributeCallback);
1747  }
1748  else
1749  args.append(empty);
1750 
1751  aMirror = TTObject(kTTSym_Mirror, args);
1752 
1753  // if the Mirror cannot instantiate attributes
1754  aMirror.attributes(v);
1755  if (v.size() == 0)
1756  aMirror.send("AttributesInstantiate", attributesName);
1757 
1758  // register object into the directory
1759  this->mDirectory->TTNodeCreate(anAddress, aMirror, NULL, &aNode, &newInstanceCreated);
1760  }
1761 
1762  return aMirror;
1763 }
1764 
1765 TTObject TTApplication::appendProxyData(TTProtocolPtr aProtocol, TTAddress anAddress, TTSymbol service)
1766 {
1767  TTObject aData;
1768  TTValue baton;
1769  TTNodePtr aNode;
1770  TTBoolean newInstanceCreated;
1771 
1772  aData = TTObject(kTTSym_Data, service);
1773 
1774  baton = TTValue(TTObject(TTObjectBasePtr(aProtocol)), mName, anAddress);
1775  aData.set(kTTSym_baton, baton);
1776  aData.set(kTTSym_function, TTPtr(&TTApplicationProxyDataValueCallback));
1777 
1778  // if the node doesn't exist yet
1779  if (this->mDirectory->getTTNode(anAddress, &aNode))
1780 
1781  // register object into the directory
1782  this->mDirectory->TTNodeCreate(anAddress, aData, NULL, &aNode, &newInstanceCreated);
1783 
1784  else
1785  // update the node's object
1786  aNode->setObject(aData);
1787 
1788  return aData;
1789 }
1790 
1791 TTObject TTApplication::appendProxyContainer(TTProtocolPtr aProtocol, TTAddress anAddress)
1792 {
1793  TTObject aContainer;
1794  TTNodePtr aNode;
1795  TTBoolean newInstanceCreated;
1796 
1797  aContainer = TTObject(kTTSym_Container);
1798 
1799  // register object into the directory
1800  this->mDirectory->TTNodeCreate(anAddress, aContainer, aContainer.instance(), &aNode, &newInstanceCreated);
1801 
1802  return aContainer;
1803 }
1804 
1805 #if 0
1806 #pragma mark -
1807 #pragma mark Some Methods
1808 #endif
1809 
1811 {
1812  TTValue v = kTTSym_value;
1813  v.append((TTPtr)&data);
1814 
1815  return TTProtocolSetAttributeCallback(baton, v);
1816 }
TTErr sendMessage(const TTSymbol name)
TODO: Document this function.
TTAddress appendAddress(const TTAddress &toAppend)
Return a new TTAddress with the appended part.
Definition: TTAddress.h:167
TTErr(TTObjectBase::* TTSetterMethod)(const TTAttribute &attribute, const TTValue &value)
A type that can be used to store a pointer to a message for an object.
Definition: TTObjectBase.h:78
bool TTBoolean
Boolean flag, same as Boolean on the Mac.
Definition: TTBase.h:167
TTErr TT_EXTENSION_EXPORT TTProtocolSetAttributeCallback(const TTValue &baton, const TTValue &data)
Definition: TTProtocol.cpp:512
TTErr registerObserverForNotifications(const TTObject &observingObject)
Register an observer.
TTErr send(const TTSymbol aName)
Send a message to this object with no arguments.
Definition: TTObject.cpp:135
TTAddress appendAttribute(TTSymbol anAttribute)
Return a new TTAddress with attribute part.
Definition: TTAddress.h:161
TTErr unregisterObserverForNotifications(const TTObject &observingObject)
Unregister an observer for notifications.
TTSymbol & getName()
Get the name of the node.
Definition: TTNode.cpp:286
TTString toString(TTBoolean quotes=YES) const
Return the content as a single string with spaces between elements.
Definition: TTValue.h:351
virtual TTErr SendGetRequest(TTSymbol to, TTAddress address, TTValue &returnedValue, TTUInt8 tryCount=0)=0
TTErr lookup(const TTSymbol key, TTValue &value)
Find the value for the given key.
Definition: TTHash.cpp:76
TTErr TTNodeCreate(TTAddress &anAddress, TTObject &newObject, void *aContext, TTNodePtr *returnedTTNode, TTBoolean *nodeCreated)
Create a new TTNode, at the given location in the tree.
TTErr fromXmlChar(const void *xCh, TTValue &v, TTBoolean addQuote=NO, TTBoolean numberAsSymbol=NO)
TTXmlReader make a TTValue from an xmlChar* using the fromString method (see in TTValue.h)
#define addAttribute(name, type)
A convenience macro to be used by subclasses for registering attributes with a custom getter...
Definition: TTAttribute.h:29
We build a directory of TTNodes, and you can request a pointer for any TTNode, or add an observer to ...
Definition: TTNode.h:59
void copyFrom(const TTValue &obj, TTUInt16 index)
Copy a value starting from an index until the last element.
Definition: TTValue.h:147
TTErr setObject(TTObject anObject=TTObject())
Set the object of the node.
Definition: TTNode.cpp:271
TTAddress getParent()
Get a pointer to the parent address.
Definition: TTAddress.h:112
TTSymbol getName() const
Return the name of this class.
const char * c_str() const
Return a pointer to the internal C-string.
Definition: TTString.h:83
Object type.
Definition: TTBase.h:283
TTNodePtr getRoot()
Get the root of the TTNodeDirectory.
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
TTProtocol is the base class for all protocol protocol.
Definition: TTProtocol.h:60
TTObject & getObject()
Get the object binded by this node.
Definition: TTNode.cpp:468
size_type size() const noexcept
Return the number of elements.
TTAddress appendInstance(const TTSymbol anInstance)
Return a new TTAddress with a instance part.
Definition: TTAddress.h:173
TTErr sendNotification(const TTSymbol name, const TTValue &arguments)
Send a notification.
TTErr getAttributeValue(const TTSymbol name, TTValue &value)
Get an attribute value for an object.
TTAddress normalize()
Normalize an address for lookup and other directory operations This would return an address without d...
Definition: TTAddress.h:149
this flag means that an address have no leading slash
Definition: TTAddressBase.h:64
TTErr getKeys(TTValue &hashKeys)
Get an array of all of the keys for the hash table.
Definition: TTHash.cpp:126
This class represents a single attribute, as used by the TTObjectBase class.
Definition: TTAttribute.h:79
Handles application namespace using a TTNodeDirectory and two tables to convert any TTName into a spe...
TTBoolean mXmlNodeIsEmpty
true if the Node is empty
Definition: TTXmlHandler.h:66
Base class for all first-class Jamoma objects.
Definition: TTObjectBase.h:109
TTErr TTNodeRemove(TTAddress &anAddress)
Remove a TTNodefrom the directory.
Maintain a collection of TTValue objects indexed by TTSymbol pointers.
Definition: TTHash.h:36
Symbol type.
Definition: TTBase.h:282
TTErr Lookup(TTAddress anAddress, TTList &returnedTTNodes, TTNodePtr *firstReturnedTTNode)
Find TTNodes by address.
This is a special type used by TTAttribute to indicate that a value is a TTValue and is locally maint...
Definition: TTBase.h:286
TTErr setName(TTSymbol aname)
Set the name of the TTNodeDirectory.
void append(const T &anElementValueToAppend)
Insert a single TTElement at the end.
Definition: TTValue.h:243
#define addAttributeWithGetter(name, type)
A convenience macro to be used by subclasses for registering attributes with a custom getter...
Definition: TTAttribute.h:38
void * TTPtr
A generic pointer.
Definition: TTBase.h:248
TTErr get(const TTSymbol aName, T &aReturnedValue) const
Get an attribute value for an object.
TTMODULAR_EXPORT TTApplicationManagerPtr TTModularApplicationManager
Export a pointer to a TTApplicationManager instance.
Definition: TTModular.cpp:34
TTSymbol name() const
Return the name of this class.
Definition: TTObject.cpp:129
TTErr TTApplicationProxyDataValueCallback(const TTValue &baton, const TTValue &data)
A callback used by proxy data (see in appendData method)
TTSymbol & getInstance()
Get the instance of the node.
Definition: TTNode.cpp:291
#define addAttributeProperty(attributeName, propertyName, initialValue)
A convenience macro to be used for registering properties of attributes.
Definition: TTAttribute.h:68
virtual TTErr SendListenRequest(TTSymbol to, TTAddress address, TTBoolean enable, TTUInt8 tryCount=0)=0
TTErr set(const TTSymbol aName, T aValue)
Set an attribute value for an object.
The TTSymbol class is used to represent a string and efficiently pass and compare that string...
Definition: TTSymbol.h:26
TTErr append(const TTSymbol key, const TTValue &value)
Insert an item into the hash table.
Definition: TTHash.cpp:70
TTErr addObserverForNotifications(TTAddress anAddress, TTObject &anObserver, TTInt8 maxDepthDifference=-1)
Add a TTCallback as a life cycle observer of all nodes below this one.
TTBoolean mXmlNodeStart
true if the Reader starts to read a Node
Definition: TTXmlHandler.h:65
#define accessApplicationLocal
Access to local application.
Boolean (1/0) or (true/false) flag.
Definition: TTBase.h:281
#define accessApplicationProtocolNames(applicationName)
Access to all protocol names of an application.
TTBoolean isEmpty()
Return true if the hash has nothing stored in it.
Definition: TTHash.cpp:205
TTErr IsThere(TTListPtr whereToSearch, TTBoolean(*testFunction)(TTNodePtr node, void *args), void *argument, bool *isThere, TTNodePtr *firstTTNode)
Is there is one TTNode or more that respect a test below an address.
TTSymbol & getAttribute()
Get the attribute part.
Definition: TTAddress.h:130
TTSymbol getNameInstance()
Get the name.instance part.
Definition: TTAddress.h:142
#define addMessageWithArguments(name)
A convenience macro to be used by subclasses for registering messages.
Definition: TTMessage.h:27
this flag means that address1 refers to a node at a lower level than address2 in the tree structure ...
Definition: TTAddressBase.h:46
const char * c_str() const
Return a pointer to the internal string as a C-string.
Definition: TTSymbol.h:77
std::int32_t TTInt32
32 bit signed integer
Definition: TTBase.h:177
TTErr clear()
Remove all items from the hash table.
Definition: TTHash.cpp:117
virtual TTErr SendDiscoverRequest(TTSymbol to, TTAddress address, TTSymbol &returnedType, TTValue &returnedChildren, TTValue &returnedAttributes, TTUInt8 tryCount=0)=0
TTErr TT_EXTENSION_EXPORT TTProtocolDirectoryCallback(const TTValue &baton, const TTValue &data)
Called when an application directory send a notification to registered application observers...
Definition: TTProtocol.cpp:433
TTErr TT_EXTENSION_EXPORT TTProtocolListenAttributeCallback(const TTValue &baton, const TTValue &data)
Definition: TTProtocol.cpp:560
TTAddressComparisonFlag
Comparison flags between address returned by address1->compare(address2).
Definition: TTAddressBase.h:45
TTErr getAddress(TTAddress &returnedAddress, TTAddress from=kTTAdrsEmpty)
Get the address of the node.
Definition: TTNode.cpp:478
TTErr TT_EXTENSION_EXPORT TTProtocolAttributeCallback(const TTValue &baton, const TTValue &data)
Called when an application object attribute send a notification to registered application observers...
Definition: TTProtocol.cpp:471
32-bit signed integer, range is -2,147,483,648 through 2,147,483,647.
Definition: TTBase.h:277
void TTFOUNDATION_EXPORT TTLogMessage(TTImmutableCString message,...)
Platform and host independent method for posting log messages.
Definition: TTBase.cpp:534
Something went wrong, but what exactly is not known. Typically used for context-specific problems...
Definition: TTBase.h:344
friend TTErr TTMODULAR_EXPORT TTApplicationProxyDataValueCallback(const TTValue &baton, const TTValue &data)
A callback used by proxy data (see in appendData method)
TTAddressType getType()
Get the type.
Definition: TTAddress.h:136
TTErr remove(const TTSymbol key)
Remove an item from the hash table.
Definition: TTHash.cpp:108
TTErr
Jamoma Error Codes Enumeration of error codes that might be returned by any of the TTBlue functions a...
Definition: TTBase.h:342
signed char TTInt8
8 bit signed integer (char)
Definition: TTBase.h:173
TTErr removeObserverForNotifications(TTAddress anAddress, TTObject &anObserver)
Remove a TTCallback as a life cycle observer of all nodes below this one.
void attributes(TTValue &returnedAttributeNames) const
Return a list of names of the available attributes.
Definition: TTObject.cpp:111
TTErr init()
Initialize the TTNodeDirectory.
TTSymbol mXmlNodeName
the Node name being read by the Reader
Definition: TTXmlHandler.h:67
std::uint32_t TTUInt32
32 bit unsigned integer
Definition: TTBase.h:178
TTErr splitAt(TTUInt32 whereToSplit, TTAddress &returnedPart1, TTAddress &returnedPart2)
A parsing tool : split address in two part from a given '/' position.
Definition: TTAddress.h:192
Pointer type.
Definition: TTBase.h:284
TTErr TT_EXTENSION_EXPORT TTProtocolGetAttributeCallback(const TTValue &baton, const TTValue &data)
Definition: TTProtocol.cpp:488
TTErr sethidden(const TTValue &newHiddenFlag)
Set the hidden flag for the attribute, determining if this attribute is private/invisible to the outs...
#define addAttributeWithSetter(name, type)
A convenience macro to be used by subclasses for registering attributes with a custom setter...
Definition: TTAttribute.h:47
TTErr TT_EXTENSION_EXPORT TTProtocolSendMessageCallback(const TTValue &baton, const TTValue &data)
Definition: TTProtocol.cpp:536
#define addMessage(name)
A convenience macro to be used by subclasses for registering messages.
Definition: TTMessage.h:19
Write / Read mecanism.
Definition: TTXmlHandler.h:48
TODO : how to have TTGetterMethod and TTSetterMethod for Mirror message Property ?
Definition: TTMirror.h:70
TTErr getChildren(TTSymbol &name, TTSymbol &instance, TTList &returnedChildren)
Get a linklist of children of the node : select them by name and instance (use wilcards to select the...
Definition: TTNode.cpp:301
TTObjectBase * instance() const
Return a direct pointer to the internal instance.
Definition: TTObject.cpp:105
No Error.
Definition: TTBase.h:343
TTAddressComparisonFlag compare(const TTAddress &toCompare, TTInt8 &depthDifference)
A comparison tool.
Definition: TTAddress.h:182
The TTString class is used to represent a string.
Definition: TTString.h:34
TTUInt32 countSeparator()
A parsing tool : count how many C_SEPARATOR there is in the address.
Definition: TTAddress.h:206
TTBoolean valid() const
Determine if the object contained by this TTObject is truly ready for use.
Definition: TTObject.cpp:179
TTErr(TTObjectBase::* TTGetterMethod)(const TTAttribute &attribute, TTValue &value)
A type that can be used to store a pointer to a message for an object.
Definition: TTObjectBase.h:73
We build a tree of TTNodes, and you can request a pointer for any TTNode, or add an observer to any T...
#define accessProtocol(protocolName)
Access to a protocol by name.
TTErr setNameInstance(TTAddress &aNameInstance, TTSymbol &newInstance, TTBoolean *newInstanceCreated)
Set the name and the instance of the node.
Definition: TTNode.cpp:101
[doxygenAppendixC_copyExample]
Definition: TTValue.h:34
virtual TTErr SendSetRequest(TTSymbol to, TTAddress address, TTValue &value, TTUInt8 tryCount=0)=0
Bad Attribute specified.
Definition: TTBase.h:348
TTErr getTTNode(const char *anAddress, TTNodePtr *returnedTTNode)
Given an address, return a pointer to a TTNode.
TTErr findAttribute(const TTSymbol name, TTAttribute **attr)
Find an attribute.
unsigned char TTUInt8
8 bit unsigned integer (char)
Definition: TTBase.h:174
#define addMessageProperty(messageName, propertyName, initialValue)
A convenience macro to be used for registering properties of messages.
Definition: TTMessage.h:37