Jamoma API  0.6.0.a19
TTCue.cpp
Go to the documentation of this file.
1 /** @file
2  *
3  * @ingroup modularLibrary
4  *
5  * @brief A Cue Object
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 "TTCue.h"
18 
19 #define thisTTClass TTCue
20 #define thisTTClassName "Cue"
21 #define thisTTClassTags "cue"
22 
23 TT_MODULAR_CONSTRUCTOR,
24 mName(kTTSymEmpty),
25 mDescription("something about this cue"),
26 mRamp(0),
27 mAddress(kTTAdrsRoot)
28 {
32  addAttribute(Address, kTypeSymbol);
33 
34  addMessage(Clear);
41 
42  // needed to be handled by a TTXmlHandler
43  addMessageWithArguments(WriteAsXml);
44  addMessageProperty(WriteAsXml, hidden, YES);
45  addMessageWithArguments(ReadFromXml);
46  addMessageProperty(ReadFromXml, hidden, YES);
47 
48  // needed to be handled by a TTTextHandler
49  addMessageWithArguments(WriteAsText);
50  addMessageProperty(WriteAsText, hidden, YES);
51  addMessageWithArguments(ReadFromText);
52  addMessageProperty(ReadFromText, hidden, YES);
53 
54  mScript = TTObject(kTTSym_Script, arguments);
55 }
56 
57 TTCue::~TTCue()
58 {}
59 
60 
62 {
63  TTListPtr lines;
64  TTDictionaryBasePtr aLine;
65  TTSymbol name;
66  TTValue v;
67 
68  mScript.get(kTTSym_lines, v);
69  lines = TTListPtr((TTPtr)v[0]);
70 
71  // lookat each line of the script
72  for (lines->begin(); lines->end(); lines->next()) {
73 
74  aLine = TTDictionaryBasePtr((TTPtr)lines->current()[0]);
75 
76  if (aLine->getSchema() == kTTSym_flag) {
77 
78  aLine->lookup(kTTSym_name, v);
79  name = v[0];
80 
81  if (name == TTSymbol("cue")) {
82  aLine->getValue(value);
83  break;
84  }
85  }
86  }
87 
88  mName = value; // remind the name in case the cue is cleared
89 
90  return kTTErrNone;
91 }
92 
93 TTErr TTCue::setName(const TTValue& value)
94 {
95  TTListPtr lines;
96  TTDictionaryBasePtr aLine;
97  TTSymbol name;
98  TTValue v;
99 
100  mScript.get(kTTSym_lines, v);
101  lines = TTListPtr((TTPtr)v[0]);
102 
103  // lookat each line of the script
104  for (lines->begin(); lines->end(); lines->next()) {
105 
106  aLine = TTDictionaryBasePtr((TTPtr)lines->current()[0]);
107 
108  if (aLine->getSchema() == kTTSym_flag) {
109 
110  aLine->lookup(kTTSym_name, v);
111  name = v[0];
112 
113  if (name == TTSymbol("cue")) {
114  aLine->setValue(value);
115  break;
116  }
117  }
118  }
119 
120  mName = value; // remind the name in case the cue is cleared
121 
122  return kTTErrNone;
123 }
124 
125 TTErr TTCue::getDescription(TTValue& value)
126 {
127  TTListPtr lines;
128  TTDictionaryBasePtr aLine;
129  TTSymbol name;
130  TTValue v;
131 
132  mScript.get(kTTSym_lines, v);
133  lines = TTListPtr((TTPtr)v[0]);
134 
135  // lookat each line of the script
136  for (lines->begin(); lines->end(); lines->next()) {
137 
138  aLine = TTDictionaryBasePtr((TTPtr)lines->current()[0]);
139 
140  if (aLine->getSchema() == kTTSym_flag) {
141 
142  aLine->lookup(kTTSym_name, v);
143  name = v[0];
144 
145  if (name == kTTSym_description) {
146  aLine->getValue(value);
147  break;
148  }
149  }
150  }
151 
152  if (value.size())
153  mDescription = value[0]; // remind the description in case the cue is cleared
154 
155  return kTTErrNone;
156 }
157 
158 TTErr TTCue::setDescription(const TTValue& value)
159 {
160  TTListPtr lines;
161  TTDictionaryBasePtr aLine;
162  TTSymbol name;
163  TTValue v;
164 
165  mScript.get(kTTSym_lines, v);
166  lines = TTListPtr((TTPtr)v[0]);
167 
168  // lookat each line of the script
169  for (lines->begin(); lines->end(); lines->next()) {
170 
171  aLine = TTDictionaryBasePtr((TTPtr)lines->current()[0]);
172 
173  if (aLine->getSchema() == kTTSym_flag) {
174 
175  aLine->lookup(kTTSym_name, v);
176  name = v[0];
177 
178  if (name == kTTSym_description) {
179  aLine->setValue(value);
180  mDescription = value; // remind the description in case the cue is cleared
181  break;
182  }
183  }
184  }
185 
186  return kTTErrNone;
187 }
188 
189 TTErr TTCue::getRamp(TTValue& value)
190 {
191  searchRamp(mScript, mRamp);
192 
193  value = mRamp;
194 
195  return kTTErrNone;
196 }
197 
198 TTErr TTCue::searchRamp(TTObject aScript, TTUInt32& ramp)
199 {
200  TTListPtr lines;
201  TTObject aSubScript;
202  TTDictionaryBasePtr aLine;
203  TTValue v, r;
204 
205  aScript.get(kTTSym_lines, v);
206  lines = TTListPtr((TTPtr)v[0]);
207 
208  // lookat each line of the script
209  for (lines->begin(); lines->end(); lines->next()) {
210 
211  aLine = TTDictionaryBasePtr((TTPtr)lines->current()[0]);
212 
213  if (aLine->getSchema() == kTTSym_command) {
214 
215  // if there is a ramp
216  if (!aLine->lookup(kTTSym_ramp, v)) {
217 
218  ramp = v[0];
219  break;
220  }
221  }
222  else if (aLine->getSchema() == kTTSym_script) {
223 
224  // get the script
225  aLine->getValue(v);
226  aSubScript = v[0];
227 
228  if (aSubScript.valid())
229  searchRamp(aSubScript, ramp);
230  }
231  }
232 
233  return kTTErrNone;
234 }
235 
236 TTErr TTCue::setRamp(const TTValue& value)
237 {
238  TTValue v, none;
239  TTBoolean flattened;
240 
241  mRamp = value;
242 
243  // is the cue already flattened ?
244  mScript.get(kTTSym_flattened, v);
245  flattened = v[0];
246 
247  if (!flattened)
248  mScript.send(kTTSym_Flatten, kTTAdrsRoot);
249 
250  // TODO : don't change line with a ramp value different from the mRamp
251  return processRamp(mScript, mRamp);
252 }
253 
254 TTErr TTCue::processRamp(TTObject aScript, TTUInt32 ramp)
255 {
256  TTListPtr lines;
257  TTDictionaryBasePtr aLine;
258  TTAddress anAddress;
259  TTNodePtr aNode;
260  TTObject anObject;
261  TTSymbol rampDrive;
262  TTValue v, r;
263  TTErr err;
264 
265  r = TTValue((int)ramp);
266 
267  aScript.get("flattenedLines", v);
268  lines = TTListPtr((TTPtr)v[0]);
269 
270  // lookat each line of the script
271  for (lines->begin(); lines->end(); lines->next()) {
272 
273  aLine = TTDictionaryBasePtr((TTPtr)lines->current()[0]);
274 
275  // if it is a Data object with a ramp drive
276  if (!aLine->lookup(kTTSym_target, v)) {
277 
278  anAddress = v[0];
279  err = accessApplicationDirectoryFrom(anAddress)->getTTNode(anAddress, &aNode);
280 
281  if (!err) {
282 
283  anObject = aNode->getObject();
284 
285  if (anObject.valid()) {
286 
287  if (anObject.name() == kTTSym_Data) {
288 
289  anObject.get(kTTSym_rampDrive, v);
290  rampDrive = v[0];
291 
292  if (rampDrive != kTTSym_none) {
293 
294  // set the ramp
295  if (ramp)
296  aLine->append(kTTSym_ramp, r);
297  else
298  aLine->remove(kTTSym_ramp);
299  }
300  }
301  }
302  }
303  }
304  }
305 
306  return kTTErrNone;
307 }
308 
309 TTErr TTCue::Store(const TTValue& inputValue, TTValue& outputValue)
310 {
311  TTAddressItemPtr aSelection = NULL;
312  TTNodePtr aNode;
313  TTSymbol name;
314  TTValue v, parsedLine;
315 
316  if (inputValue.size() == 1) {
317 
318  if (inputValue[0].type() == kTypePointer)
319  aSelection = TTAddressItemPtr((TTPtr)inputValue[0]);
320 
321  else if (inputValue[0].type() == kTypeSymbol) {
322  name = inputValue[0];
323  aSelection = TTModularSelectionLookup(name);
324  }
325  }
326 
327  if (aSelection) {
328 
329  Clear();
330 
331  // 1. Append a cue flag with the name
332  v = TTValue(TTSymbol("cue"));
333  v.append(mName);
334  mScript.send("AppendFlag", v, parsedLine);
335 
336  // 2. Append a description flag
337  v = TTValue(TTSymbol("description"));
338  v.append(mDescription);
339  mScript.send("AppendFlag", v, parsedLine);
340 
341  // 3. Append a comment line
342  v = TTValue(TTSymbol("###########################################"));
343  mScript.send("AppendComment", v, parsedLine);
344 
345  // 4. Process namespace storage from the mAddress
346  // (but others directories are handled too. see in processStore)
347  if (mAddress != kTTAdrsRoot)
348  if (aSelection->find(mAddress, & aSelection))
349  return kTTErrGeneric;
350 
351  accessApplicationDirectoryFrom(mAddress)->getTTNode(mAddress, &aNode);
352 
353  processStore(mScript, aSelection, aNode);
354 
355  // 5. Append an empty comment line
356  v.clear();
357  mScript.send("AppendComment", v, parsedLine);
358 
359  // 6. Append a comment line at the end
360  v = TTValue(TTSymbol("###########################################"));
361  mScript.send("AppendComment", v, parsedLine);
362 
363  // 7. Process ramp
364  if (mRamp) setRamp(mRamp);
365 
366  // théo - since the workshop in june 2014 in Albi we decide to force the script to be flattened
367  // but we should review all the #TTCue and #TTScript architecture to improve this
368  mScript.send("Flatten");
369 
370  return kTTErrNone;
371  }
372 
373  return kTTErrGeneric;
374 }
375 
376 TTErr TTCue::processStore(TTObject aScript, const TTAddressItemPtr aSelection, TTNodePtr nodeToProcess)
377 {
378  // stop recursion if the selection is empty
379  if (aSelection->isEmpty())
380  return kTTErrNone;
381 
382  TTAddressItemPtr nameItem, instanceItem;
383  TTString nameInstance;
384  TTNodePtr scriptNode, aNode;
385  TTDictionaryBasePtr aLine;
386  TTObject anObject, aSubScript;
387  TTList aNodeList, childrenNodes;
388  TTListPtr instanceOptions;
389  TTAddress scriptAddress, childAddress, address;
390  TTSymbol service, option;
391  TTValue v, parsedLine, none;
392  TTBoolean empty = YES;
393  TTErr err;
394 
395  scriptNode = nodeToProcess;
396 
397  // get the scriptNode address
398  scriptNode->getAddress(scriptAddress);
399 
400  // each script line is a name.instance (which means 2 levels of the namespace)
401  // but the first level name can be directory:/name sometimes to include other directory
402 
403  // for all names
404  for (aSelection->begin(); aSelection->end(); aSelection->next()) {
405 
406  nameItem = aSelection->current();
407 
408  // at root : check if the item is an application name
409  if (scriptAddress == kTTAdrsRoot) {
410 
411  // TODO : find a solution for case where applications are named with an instance part (like myApp.1)
412  // in this case we will need to test if each name.instance is an application name ...
413  // for the moment the nameItem should be with 1 "" item
414  if (nameItem->getSize() == 1) {
415 
416  // TODO : do not test only with the nameItem
417  TTNodeDirectoryPtr aDirectory = accessApplicationDirectory(nameItem->getSymbol());
418 
419  if (aDirectory) {
420 
421  scriptNode = aDirectory->getRoot();
422 
423  // TODO : do not take only the first instanceItem
424  nameItem->begin();
425  instanceItem = nameItem->current();
426 
427  // TODO : do not use only the nameItem
428  nameInstance = nameItem->getSymbol().c_str();
429  nameInstance += ":"; //S_DIRECTORY.string();
430 
431  // edit a sub script line
432  v = TTValue(TTSymbol(nameInstance));
433  aLine = TTScriptParseScript(v);
434 
435  // get the sub script
436  aLine->getValue(v);
437  aSubScript = v[0];
438 
439  // process namespace item on sub script
440  err = processStore(aSubScript, instanceItem, scriptNode);
441 
442  // if the sub script is not empty
443  if (!err) {
444 
445  // append 2 comment lines to the script before the sub script line
446  aScript.send("AppendComment", none, parsedLine);
447  aScript.send("AppendComment", none, parsedLine);
448 
449  // append the sub script line
450  v = TTValue((TTPtr)aLine);
451  aScript.send("Append", v, parsedLine);
452 
453  // the script is not empty
454  empty = NO;
455  }
456 
457  // go to the next application
458  continue;
459  }
460  }
461  }
462 
463  // for all instances of a name
464  for (nameItem->begin(); nameItem->end(); nameItem->next()) {
465 
466  instanceItem = nameItem->current();
467 
468  if (!instanceItem->getSelection())
469  continue;
470 
471  // get children
472  scriptNode->getChildren(nameItem->getSymbol(), instanceItem->getSymbol(), childrenNodes);
473 
474  for (childrenNodes.begin(); childrenNodes.end(); childrenNodes.next()) {
475 
476  aNode = TTNodePtr((TTPtr)childrenNodes.current()[0]);
477 
478  // edit name.instance using effective node's name and instance
479  nameInstance = aNode->getName().c_str();
480 
481  if (aNode->getInstance() != kTTSymEmpty) {
482  nameInstance += C_INSTANCE;
483  nameInstance += aNode->getInstance().c_str();
484  }
485 
486  // get object
487  anObject = aNode->getObject();
488 
489  // edit the script depending on the object type
490  if (anObject.valid()) {
491 
492  // DATA case : get value attribute
493  if (anObject.name() == kTTSym_Data)
494  {
495  v.clear();
496  anObject.get(kTTSym_service, v);
497  service = v[0];
498 
499  if (service == kTTSym_parameter)
500  {
501  // create a line for each option of the item
502  instanceOptions = instanceItem->getOptions();
503 
504  for (instanceOptions->begin(); instanceOptions->end(); instanceOptions->next())
505  {
506  option = instanceOptions->current()[0];
507 
508  if (option == kTTSymEmpty)
509  option = kTTSym_value;
510 
511  v.clear();
512  anObject.get(option, v);
513 
514  if (v.empty())
515  continue;
516 
517  if (option == kTTSym_value)
518  address = TTAddress(nameInstance);
519  else
520  address = TTAddress(nameInstance).appendAttribute(option);
521 
522  // append a command line
523  v.prepend(address);
524  aScript.send("AppendCommand", v, parsedLine);
525 
526  // the script is not empty
527  empty = NO;
528  }
529  }
530  }
531  }
532 
533  // Any other case : create a sub script
534 
535  // edit a sub script line
536  v = TTValue(TTSymbol(nameInstance));
537  aLine = TTScriptParseScript(v);
538 
539  // get the sub script
540  aLine->getValue(v);
541  aSubScript = v[0];
542 
543  // process namespace item on sub script
544  err = processStore(aSubScript, instanceItem, aNode);
545 
546  // if the sub script is not empty
547  if (!err)
548  {
549  if (anObject.valid())
550  {
551  // CONTAINER case : append a comment line to the script before the sub script line
552  if (anObject.name() == kTTSym_Container)
553  aScript.send("AppendComment", none, parsedLine);
554  }
555 
556  // append the sub script line
557  v = TTValue((TTPtr)aLine);
558  aScript.send("Append", v, parsedLine);
559 
560  // the script is not empty
561  empty = NO;
562  }
563  else
564  {
565  // unselect this item from the namespace
566  instanceItem->setSelection(NO);
567  }
568  }
569  }
570  }
571 
572  if (empty)
573  return kTTErrGeneric;
574  else
575  return kTTErrNone;
576 }
577 
578 TTErr TTCue::Update(const TTValue& inputValue, TTValue& outputValue)
579 {
580  TTValue v, none;
581  TTBoolean flattened;
582 
583  // TODO : update from an address
584 
585  // is the cue already flattened ?
586  mScript.get(kTTSym_flattened, v);
587  flattened = v[0];
588 
589  if (!flattened)
590  mScript.send(kTTSym_Flatten, kTTAdrsRoot);
591 
592  return processUpdate(mScript);
593 }
594 
595 TTErr TTCue::processUpdate(TTObject aScript)
596 {
597  TTListPtr lines;
598  TTDictionaryBasePtr aLine;
599  TTAddress anAddress;
600  TTNodePtr aNode;
601  TTObject anObject;
602  TTSymbol service;
603  TTValue v;
604  TTErr err;
605 
606  aScript.get("flattenedLines", v);
607  lines = TTListPtr((TTPtr)v[0]);
608 
609  // lookat each line of the script
610  for (lines->begin(); lines->end(); lines->next()) {
611 
612  aLine = TTDictionaryBasePtr((TTPtr)lines->current()[0]);
613 
614  // if it is a Data object
615  if (!aLine->lookup(kTTSym_target, v)) {
616 
617  anAddress = v[0];
618  err = accessApplicationDirectoryFrom(anAddress)->getTTNode(anAddress, &aNode);
619 
620  if (!err) {
621 
622  anObject = aNode->getObject();
623 
624  if (anObject.valid()) {
625 
626  if (anObject.name() == kTTSym_Data) {
627 
628  // get his service attribute value
629  anObject.get(kTTSym_service, v);
630  service = v[0];
631 
632  // update only parameters
633  if (service == kTTSym_parameter) {
634 
635  // get his current value
636  err = anObject.get(kTTSym_value, v);
637 
638  if (!err) {
639 
640  // replace the former value
641  aLine->remove(kTTSym_value);
642  aLine->append(kTTSym_value, v);
643  }
644  }
645  }
646  }
647  }
648  }
649  }
650 
651  return kTTErrNone;
652 }
653 
654 TTErr TTCue::Append(const TTValue& inputValue, TTValue& outputValue)
655 {
656  return mScript.send("Append", inputValue, outputValue);
657 }
658 
659 TTErr TTCue::Clear()
660 {
661  return mScript.send("Clear");
662 }
663 
664 TTErr TTCue::Recall(const TTValue& inputValue, TTValue& outputValue)
665 {
666  TTAddress anAddress = kTTAdrsRoot;
667  TTBoolean flattened;
668  TTValue v, none;
669 
670  if (inputValue.size() == 1)
671  if (inputValue[0].type() == kTypeSymbol) {
672 
673  anAddress = inputValue[0];
674 
675  if (anAddress.getType() == kAddressRelative)
676  anAddress = mAddress.appendAddress(anAddress);
677  }
678 
679  // is the cue already flattened ?
680  mScript.get(kTTSym_flattened, v);
681  flattened = v[0];
682 
683  if (!flattened)
684  mScript.send(kTTSym_Flatten, mAddress);
685 
686  // if an address is passed, run the line at address
687  if (anAddress != kTTAdrsRoot)
688  return mScript.send("RunCommand", anAddress);
689 
690  // else run all the script
691  else
692  return mScript.send(kTTSym_Run, inputValue);
693 }
694 
695 TTErr TTCue::Output(const TTValue& inputValue, TTValue& outputValue)
696 {
697  TTAddress anAddress = kTTAdrsRoot;
698  TTBoolean flattened;
699  TTValue v, none;
700 
701  if (inputValue.size() == 1)
702  if (inputValue[0].type() == kTypeSymbol) {
703 
704  anAddress = inputValue[0];
705 
706  if (anAddress.getType() == kAddressRelative)
707  anAddress = mAddress.appendAddress(anAddress);
708  }
709 
710  // is the cue already flattened ?
711  mScript.get(kTTSym_flattened, v);
712  flattened = v[0];
713 
714  if (!flattened)
715  mScript.send(kTTSym_Flatten, mAddress);
716 
717  // if an address is passed, dump the line at address
718  if (anAddress != kTTAdrsRoot)
719  return mScript.send("DumpLine", anAddress);
720 
721  // else dump all the script
722  else
723  return mScript.send(kTTSym_Dump, inputValue);
724 }
725 
726 TTErr TTCue::Select(const TTValue& inputValue, TTValue& outputValue)
727 {
728  TTAddressItemPtr aSelection = NULL;
729  TTSymbol name;
730 
731  if (inputValue.size() == 1) {
732 
733  if (inputValue[0].type() == kTypePointer)
734  aSelection = TTAddressItemPtr((TTPtr)inputValue[0]);
735 
736  else if (inputValue[0].type() == kTypeSymbol) {
737  name = inputValue[0];
738  aSelection = TTModularSelectionLookup(name);
739  }
740  }
741 
742  if (aSelection) {
743 
744  // unselect all the namespace
745  aSelection->setSelection(NO, YES);
746 
747  // edit selection
748  return processSelect(mScript, aSelection);
749  }
750 
751  return kTTErrNone;
752 }
753 
754 TTErr TTCue::processSelect(TTObject aScript, TTAddressItemPtr aSelection)
755 {
756  TTListPtr lines;
757  TTAddressItemPtr anItem;
758  TTObject aSubScript;
759  TTDictionaryBasePtr aLine;
760  TTAddress address;
761  TTValue v;
762  TTErr err;
763 
764  aScript.get(kTTSym_lines, v);
765  lines = TTListPtr((TTPtr)v[0]);
766 
767  // select all items which are in the script
768  for (lines->begin(); lines->end(); lines->next()) {
769 
770  aLine = TTDictionaryBasePtr((TTPtr)lines->current()[0]);
771 
772  if (aLine->getSchema() == kTTSym_command || aLine->getSchema() == kTTSym_script) {
773 
774  // get the address
775  aLine->lookup(kTTSym_address, v);
776  address = v[0];
777 
778  // find item into the namespace
779  err = aSelection->find(address, &anItem);
780 
781  if (!err) {
782 
783  // select it
784  anItem->setSelection(YES);
785 
786  // process select on the subscript
787  if (aLine->getSchema() == kTTSym_script) {
788 
789  // get the script
790  aLine->getValue(v);
791  aSubScript = v[0];
792 
793  if (aSubScript.valid())
794  processSelect(aSubScript, anItem);
795  }
796  }
797  }
798  }
799 
800  return kTTErrNone;
801 }
802 
803 TTErr TTCue::WriteAsXml(const TTValue& inputValue, TTValue& outputValue)
804 {
805  TTObject o = inputValue[0];
806  TTXmlHandlerPtr aXmlHandler = (TTXmlHandlerPtr)o.instance();
807  if (!aXmlHandler)
808  return kTTErrGeneric;
809 
810  TTValue v;
811 
812  // use WriteAsXml of the script
813  v = TTValue(mScript);
814  aXmlHandler->setAttributeValue(kTTSym_object, v);
815  aXmlHandler->sendMessage(TTSymbol("Write"));
816 
817  return kTTErrNone;
818 }
819 
820 TTErr TTCue::ReadFromXml(const TTValue& inputValue, TTValue& outputValue)
821 {
822  TTObject o = inputValue[0];
823  TTXmlHandlerPtr aXmlHandler = (TTXmlHandlerPtr)o.instance();
824  if (!aXmlHandler)
825  return kTTErrGeneric;
826 
827  TTValue v, parsedLine;
828 
829  // Cue node : append a cue flag with the name
830  if (aXmlHandler->mXmlNodeName == TTSymbol("cue")) {
831 
832  if (!aXmlHandler->mXmlNodeStart)
833  return kTTErrNone;
834 
835  v = TTValue(TTSymbol("cue"));
836  v.append(mName);
837  mScript.send("AppendFlag", v, parsedLine);
838 
839  return kTTErrNone;
840  }
841 
842  // use ReadFromXml of the script
843  v = TTValue(mScript);
844  aXmlHandler->setAttributeValue(kTTSym_object, v);
845  aXmlHandler->sendMessage(TTSymbol("Read"));
846 
847  return kTTErrNone;
848 }
849 
850 TTErr TTCue::WriteAsText(const TTValue& inputValue, TTValue& outputValue)
851 {
852  TTObject o = inputValue[0];
853  TTTextHandlerPtr aTextHandler = (TTTextHandlerPtr)o.instance();
854  if (!aTextHandler)
855  return kTTErrGeneric;
856 
857  TTValue v;
858 
859  /* get the address of the script
860  mScript.get(kTTSym_address, v);
861  address = v[0];
862 
863  // write address of the script
864  *buffer += "\t";
865  *buffer += mAddress->getCString();
866  *buffer += "\n";
867  */
868 
869  // théo - since the workshop in june 2014 in Albi we decide to force the script to be flattened
870  // but we should review all the #TTCue and #TTScript architecture to improve this
871  mScript.send("Flatten");
872 
873  // use WriteAsText of the script
874  v = TTValue(mScript);
875  aTextHandler->setAttributeValue(kTTSym_object, v);
876  aTextHandler->sendMessage(TTSymbol("Write"));
877 
878  return kTTErrNone;
879 }
880 
881 TTErr TTCue::ReadFromText(const TTValue& inputValue, TTValue& outputValue)
882 {
883  TTObject o = inputValue[0];
884  TTTextHandlerPtr aTextHandler = (TTTextHandlerPtr)o.instance();
885  if (!aTextHandler)
886  return kTTErrGeneric;
887 
888  TTDictionaryBasePtr line;
889  TTValue v;
890 
891  // if it is the first line :
892  if (aTextHandler->mFirstLine)
893  Clear();
894 
895  if (aTextHandler->mLine->size() == 0)
896  return kTTErrGeneric;
897 
898  // if needed : parse the buffer line into TTDictionary
899  if ((*(aTextHandler->mLine))[0].type() != kTypePointer) {
900 
901  line = TTScriptParseLine(*(aTextHandler->mLine));
902 
903  if (line)
904 
905  // replace the buffer line value by the parsed line dictionary
906  aTextHandler->mLine = new TTValue((TTPtr)line);
907  }
908  else
909  line = TTDictionaryBasePtr((TTPtr)aTextHandler->mLine[0]);
910 
911  // match description or tag flag lines :
912  if (line->getSchema() == kTTSym_flag) {
913 
914  line->lookup(kTTSym_name, v);
915  TTSymbol flagName = v[0];
916 
917  if (flagName == TTSymbol("description")) {
918 
919  // get description
920  if (!line->getValue(v)) {
921 
922  mDescription = v[0];
923  }
924  }
925  }
926 
927  // use ReadFromText of the script
928  v = TTValue(mScript);
929  aTextHandler->setAttributeValue(kTTSym_object, v);
930  aTextHandler->sendMessage(TTSymbol("Read"));
931 
932  // théo - since the workshop in june 2014 in Albi we decide to force the script to be flattened
933  // but we should review all the #TTCue and #TTScript architecture to improve this
934  if (aTextHandler->mLastLine)
935  mScript.send("Flatten");
936 
937  return kTTErrNone;
938 }
939 
940 #if 0
941 #pragma mark -
942 #pragma mark Some Methods
943 #endif
944 
945 TTErr TTCueInterpolate(TTObject cue1, TTObject cue2, TTFloat64 position)
946 {
947  TTBoolean flattened1, flattened2;
948  TTValue v, none;
949 
950  // is the cue1 already flattened ?
951  TTCuePtr(cue1.instance())->mScript.get(kTTSym_flattened, v);
952  flattened1 = v[0];
953 
954  if (!flattened1)
955  TTCuePtr(cue1.instance())->mScript.send(kTTSym_Flatten, kTTAdrsRoot);
956 
957  // is the cue2 already flattened ?
958  TTCuePtr(cue2.instance())->mScript.get(kTTSym_flattened, v);
959  flattened2 = v[0];
960 
961  if (!flattened2)
962  TTCuePtr(cue2.instance())->mScript.send(kTTSym_Flatten, kTTAdrsRoot);
963 
964  return TTScriptInterpolate(TTCuePtr(cue1.instance())->mScript, TTCuePtr(cue2.instance())->mScript, position);
965 }
966 
967 TTErr TTCueMix(const TTValue& cues, const TTValue& factors)
968 {
969  TTObject aCue;
970  TTValue scripts;
971  TTBoolean flattened;
972  TTValue v, none;
973  TTUInt32 i;
974 
975  for (i = 0; i < cues.size(); i++) {
976 
977  aCue = cues[i];
978 
979  // is the cue already flattened ?
980  TTCuePtr(aCue.instance())->mScript.get(kTTSym_flattened, v);
981  flattened = v[0];
982 
983  if (!flattened)
984  TTCuePtr(aCue.instance())->mScript.send(kTTSym_Flatten, kTTAdrsRoot);
985 
986  scripts.append(TTCuePtr(aCue.instance())->mScript);
987  }
988 
989  return TTScriptMix(scripts, factors);
990 }
991 
992 TTErr TTCueMerge(TTObject aCueToMerge, TTObject mergedCue)
993 {
994  return TTScriptMerge(TTCuePtr(aCueToMerge.instance())->mScript, TTCuePtr(mergedCue.instance())->mScript);
995 }
996 
997 TTErr TTCueOptimize(TTObject aCueToOptimize, TTObject aCue, TTObject optimizedCue)
998 {
999  return TTScriptOptimize(TTCuePtr(aCueToOptimize.instance())->mScript, TTCuePtr(aCue.instance())->mScript, TTCuePtr(optimizedCue.instance())->mScript);
1000 }
1001 
1002 TTErr TTCueCopy(TTObject aCueToCopy, TTObject aCueCopy)
1003 {
1004  TTValue v, args;
1005 
1006  TTCuePtr(aCueCopy.instance())->mName = TTCuePtr(aCueToCopy.instance())->mName;
1007  TTCuePtr(aCueCopy.instance())->mDescription = TTCuePtr(aCueToCopy.instance())->mDescription;
1008  TTCuePtr(aCueCopy.instance())->mRamp = TTCuePtr(aCueToCopy.instance())->mRamp;
1009  TTCuePtr(aCueCopy.instance())->mAddress = TTCuePtr(aCueToCopy.instance())->mAddress;
1010  return TTScriptCopy(TTCuePtr(aCueToCopy.instance())->mScript, TTCuePtr(aCueCopy.instance())->mScript);
1011 }
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
bool TTBoolean
Boolean flag, same as Boolean on the Mac.
Definition: TTBase.h:167
#define accessApplicationDirectoryFrom(anAddress)
Access to an application directory using an address.
TTDictionaryBase * TTDictionaryBasePtr
Pointer to a TTDictionary.
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
TTSymbol & getName()
Get the name of the node.
Definition: TTNode.cpp:286
#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
A type that contains a key and a value.
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
TTErr setValue(const TTValue &newValue)
TODO: Add documentation.
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
TTObject & getObject()
Get the object binded by this node.
Definition: TTNode.cpp:468
size_type size() const noexcept
Return the number of elements.
TTAddressItemPtr TTMODULAR_EXPORT TTModularSelectionLookup(const TTSymbol selectionName)
Get a selection or create one if it doesn't exist yet.
Definition: TTModular.cpp:110
this flag means that an address have no leading slash
Definition: TTAddressBase.h:64
const TTSymbol getSchema() const
TODO: Add documentation.
TTErr setAttributeValue(const TTSymbol name, TTValue &value)
Set an attribute value for an object.
Symbol type.
Definition: TTBase.h:282
double TTFloat64
64 bit floating point number
Definition: TTBase.h:188
void prepend(const TTValue &aValueToPrepend)
Insert another TTValue before the first element.
Definition: TTValue.h:162
void append(const T &anElementValueToAppend)
Insert a single TTElement at the end.
Definition: TTValue.h:243
void * TTPtr
A generic pointer.
Definition: TTBase.h:248
TTErr get(const TTSymbol aName, T &aReturnedValue) const
Get an attribute value for an object.
A Cue Object.
TTSymbol name() const
Return the name of this class.
Definition: TTObject.cpp:129
TTSymbol & getInstance()
Get the instance of the node.
Definition: TTNode.cpp:291
The TTSymbol class is used to represent a string and efficiently pass and compare that string...
Definition: TTSymbol.h:26
TTBoolean mXmlNodeStart
true if the Reader starts to read a Node
Definition: TTXmlHandler.h:65
#define accessApplicationDirectory(applicationName)
Access to an application directory by name.
#define addMessageWithArguments(name)
A convenience macro to be used by subclasses for registering messages.
Definition: TTMessage.h:27
TTErr lookup(const TTSymbol key, TTValue &value) const
Find the value for the given key.
const char * c_str() const
Return a pointer to the internal string as a C-string.
Definition: TTSymbol.h:77
void clear()
Clear all values from the vector, leaving with size of 0.
Definition: TTValue.h:131
TTErr getAddress(TTAddress &returnedAddress, TTAddress from=kTTAdrsEmpty)
Get the address of the node.
Definition: TTNode.cpp:478
Something went wrong, but what exactly is not known. Typically used for context-specific problems...
Definition: TTBase.h:344
TTAddressType getType()
Get the type.
Definition: TTAddress.h:136
TTErr
Jamoma Error Codes Enumeration of error codes that might be returned by any of the TTBlue functions a...
Definition: TTBase.h:342
TTErr append(const TTSymbol key, const TTValue &value)
Insert an item into the hash table.
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 get(const TTSymbol aName, T &aReturnedValue)
Get an attribute value for an object This is the same as calling getAttributeValue().
Definition: TTObjectBase.h:280
Pointer type.
Definition: TTBase.h:284
TTErr remove(const TTSymbol key)
Remove an item from the hash table.
#define addMessage(name)
A convenience macro to be used by subclasses for registering messages.
Definition: TTMessage.h:19
TTCue ...
Definition: TTCue.h:30
Write / Read mecanism.
Definition: TTXmlHandler.h:48
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
32-bit unsigned integer, range is 0 through 4,294,967,295.
Definition: TTBase.h:278
TTObjectBase * instance() const
Return a direct pointer to the internal instance.
Definition: TTObject.cpp:105
No Error.
Definition: TTBase.h:343
The TTString class is used to represent a string.
Definition: TTString.h:34
TTBoolean valid() const
Determine if the object contained by this TTObject is truly ready for use.
Definition: TTObject.cpp:179
We build a tree of TTNodes, and you can request a pointer for any TTNode, or add an observer to any T...
[doxygenAppendixC_copyExample]
Definition: TTValue.h:34
TTErr getValue(TTValue &returnedValue) const
TODO: Add documentation.
#define addAttributeWithGetterAndSetter(name, type)
A convenience macro to be used by subclasses for registering attributes with a custom getter and sett...
Definition: TTAttribute.h:57
#define addMessageProperty(messageName, propertyName, initialValue)
A convenience macro to be used for registering properties of messages.
Definition: TTMessage.h:37