Jamoma API  0.6.0.a19
TTScript.cpp
Go to the documentation of this file.
1 /** @file
2  *
3  * @ingroup modularLibrary
4  *
5  * @brief A Script 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 "TTScript.h"
18 #include <libxml/encoding.h>
19 #include <libxml/xmlwriter.h>
20 #include <libxml/xmlreader.h>
21 
22 #define thisTTClass TTScript
23 #define thisTTClassName "Script"
24 #define thisTTClassTags "script"
25 
26 TT_MODULAR_CONSTRUCTOR,
27 mFlattened(NO)
28 {
29  if (arguments.size() == 1)
30  mReturnLineCallback = arguments[0];
31 
32  addAttribute(Flattened, kTypeBoolean);
33  addAttributeProperty(Flattened, readOnly, YES);
34 
35  addAttribute(Lines, kTypePointer);
36  addAttributeProperty(Lines, readOnly, YES);
37 
38  addAttribute(FlattenedLines, kTypePointer);
39  addAttributeProperty(FlattenedLines, readOnly, YES);
40 
41  addAttribute(SubScript, kTypeObject);
42  addAttributeProperty(SubScript, hidden, YES);
43 
44  addAttribute(ParentScript, kTypeObject);
45  addAttributeProperty(ParentScript, hidden, YES);
46 
47  addMessage(Clear);
49  addMessageWithArguments(RunCommand);
50  addMessageWithArguments(RemoveCommand);
51 
53  addMessageWithArguments(DumpLine);
54 
55  addMessageWithArguments(Flatten);
56  addMessageProperty(Flatten, hidden, YES);
57 
58  addMessageWithArguments(Unflatten);
59  addMessageProperty(Unflatten, hidden, YES);
60 
62  addMessageWithArguments(AppendCommand);
63  addMessageWithArguments(AppendComment);
64  addMessageWithArguments(AppendFlag);
65  addMessageWithArguments(AppendScript);
66 
67  // needed to be handled by a TTXmlHandler
68  addMessageWithArguments(WriteAsXml);
69  addMessageProperty(WriteAsXml, hidden, YES);
70  addMessageWithArguments(ReadFromXml);
71  addMessageProperty(ReadFromXml, hidden, YES);
72 
73  // needed to be handled by a TTTextHandler
74  addMessageWithArguments(WriteAsText);
75  addMessageProperty(WriteAsText, hidden, YES);
76  addMessageWithArguments(ReadFromText);
77  addMessageProperty(ReadFromText, hidden, YES);
78 
79  mLines = new TTList();
80  mFlattenedLines = new TTList();
81 }
82 
83 TTScript::~TTScript()
84 {
85  TTDictionaryBasePtr aLine = NULL;
86  TTValue v;
87 
88  for (mLines->begin(); mLines->end(); mLines->next()) {
89 
90  aLine = TTDictionaryBasePtr((TTPtr)mLines->current()[0]);
91 
92  if (aLine) {
93 
94  delete aLine;
95  aLine = NULL;
96  }
97  }
98 
99  // don't delete the lines into the mFlattenedLines because
100  // it stores only pointers to the lines stored into the mLines
101  delete mLines;
102  delete mFlattenedLines;
103 }
104 
105 TTErr TTScript::Clear()
106 {
107  TTDictionaryBasePtr aLine = NULL;
108  TTValue v;
109 
110  for (mLines->begin(); mLines->end(); mLines->next()) {
111 
112  aLine = TTDictionaryBasePtr((TTPtr)mLines->current()[0]);
113 
114  if (aLine) {
115 
116  delete aLine;
117  aLine = NULL;
118  }
119  }
120 
121  // don't delete the lines into the mFlattenedLines because
122  // it stores only pointers to the lines stored into the mLines
123 
124  mLines->clear();
125  mFlattenedLines->clear();
126 
127  mFlattened = NO;
128 
129  return kTTErrNone;
130 }
131 
132 TTErr TTScript::Flatten(const TTValue& inputValue, TTValue& outputValue)
133 {
134  TTObject aScriptToFlatten;
135  TTDictionaryBasePtr aLine;
136  TTSymbol schema;
137  TTAddress address, parentAddress = kTTAdrsRoot;
138  TTValue v, none;
139 
140  // It is possible to flatten the script from a parent address
141  if (inputValue.size() >= 1)
142  if (inputValue[0].type() == kTypeSymbol)
143  parentAddress = inputValue[0];
144 
145  // It is possible to flatten another script and store into the mFlattenedLines of this script
146  if (inputValue.size() == 2) {
147 
148  if (inputValue[1].type() == kTypeObject) {
149  aScriptToFlatten = inputValue[1];
150  }
151  }
152 
153  // else start to flatten this script
154  if (!aScriptToFlatten.valid()) {
155  Unflatten();
156  aScriptToFlatten = TTObject(this);
157  mFlattened = YES;
158  }
159 
160  // flatten each command line of the script
161  for (TTScriptPtr(aScriptToFlatten.instance())->mLines->begin(); TTScriptPtr(aScriptToFlatten.instance())->mLines->end(); TTScriptPtr(aScriptToFlatten.instance())->mLines->next()) {
162 
163  aLine = TTDictionaryBasePtr((TTPtr)TTScriptPtr(aScriptToFlatten.instance())->mLines->current()[0]);
164 
165  schema = aLine->getSchema();
166  if (schema == kTTSym_command) {
167 
168  // clear target field
169  aLine->remove(kTTSym_target);
170 
171  // edit the absolute address and bind to the node
172  aLine->lookup(kTTSym_address, v);
173  address = v[0];
174 
175  // use parentAddress for relative address
176  if (address.getType() == kAddressRelative)
177  address = parentAddress.appendAddress(address);
178 
179  // keep the absolute address in mind under a target field
180  aLine->append(kTTSym_target, address);
181 
182  // append the command line to the Flattened lines list
183  this->mFlattenedLines->append((TTPtr)aLine);
184 
185  }
186  else if (schema == kTTSym_script) {
187 
188  // get the script
189  aLine->getValue(v);
190  mSubScript = v[0];
191 
192  // get the address
193  aLine->lookup(kTTSym_address, v);
194  address = v[0];
195 
196  // use parentAddress for relative address
197  if (address.getType() == kAddressRelative)
198  address = parentAddress.appendAddress(address);
199 
200  v = TTValue(address);
201  v.append(mSubScript);
202 
203  // flatten the sub script into this script
204  this->sendMessage(kTTSym_Flatten, v, none);
205  }
206  // any other case : copy the line
207  else
208  this->mFlattenedLines->append((TTPtr)aLine);
209  }
210 
211  return kTTErrNone;
212 }
213 
214 TTErr TTScript::Unflatten()
215 {
216  // don't delete the lines into the mFlattenedLines because
217  // it stores only pointers to the lines stored into the mLines
218 
219  mFlattenedLines->clear();
220 
221  mFlattened = NO;
222 
223  return kTTErrNone;
224 }
225 
226 TTErr TTScript::Run(const TTValue& inputValue, TTValue& outputValue)
227 {
228  // use the Flattened lines if they are ready
229  if (mFlattened)
230  return RunFlattened();
231 
232  // else use the none Flattened lines
233  TTNodeDirectoryPtr aDirectory;
234  TTDictionaryBasePtr aLine;
235  TTSymbol schema, name, attribute;
236  TTNodePtr aNode;
237  TTAddress address, parentAddress = kTTAdrsRoot;
238  TTObject anObject, aContainer, aParentContainer;
239  TTValue v, c, none;
240  TTErr err;
241 
242  // get the parent address
243  if (inputValue.size() >= 1)
244  if (inputValue[0].type() == kTypeSymbol)
245  parentAddress = inputValue[0];
246 
247  // eventually get a container to go faster
248  if (inputValue.size() == 2)
249  if (inputValue[1].type() == kTypeObject)
250  aParentContainer = inputValue[1];
251 
252  // run each line of the script
253  for (mLines->begin(); mLines->end(); mLines->next()) {
254 
255  aLine = TTDictionaryBasePtr((TTPtr)mLines->current()[0]);
256 
257  // run script line depending on his schema
258  schema = aLine->getSchema();
259  if (schema == kTTSym_flag) {
260 
261  // get flag name
262  aLine->lookup(kTTSym_name, v);
263  name = v[0];
264 
265  // TODO : output current flag to display it
266  }
267  else if (schema == kTTSym_comment) {
268 
269  // TODO : output current comment to display it
270  continue;
271  }
272  else if (schema == kTTSym_command) {
273 
274  // get the address
275  aLine->lookup(kTTSym_address, v);
276  address = v[0];
277 
278  // if there is a parent container
279  if (aParentContainer.valid()) {
280 
281  // use container to send relative address command
282  if (aLine->getSchema() == kTTSym_command && address.getType() == kAddressRelative) {
283 
284  v = TTValue(address);
285  c = TTValue((TTPtr)aLine);
286  v.append((TTPtr)&c);
287 
288  aParentContainer.send(kTTSym_Send, v);
289  }
290  }
291  // or retreive the node
292  else {
293 
294  // bind to the node
295  // (each time ! this is why using flattened list could be usefull but dangerous)
296  aDirectory = accessApplicationDirectoryFrom(address);
297  if (aDirectory == NULL)
298  return kTTErrGeneric;
299 
300  if (address.getType() == kAddressRelative)
301  err = aDirectory->getTTNode(parentAddress.appendAddress(address), &aNode);
302  else
303  err = aDirectory->getTTNode(address, &aNode);
304 
305  // if there is a node
306  if (!err) {
307 
308  anObject = aNode->getObject();
309 
310  // check object type
311  if (anObject.valid()) {
312 
313  // default attribute is value attribute
314  if (address.getAttribute() == kTTSymEmpty)
315  attribute = kTTSym_value;
316  else
317  attribute = address.getAttribute();
318 
319  // for data object
320  if (anObject.name() == kTTSym_Data) {
321 
322  // send the line using the command message
323  if (attribute == kTTSym_value) {
324 
325  anObject.send(kTTSym_Command, (TTPtr)aLine);
326  continue;
327  }
328  }
329 
330  // any other case : set attribute
331  aLine->getValue(v);
332  anObject.set(attribute, v);
333  }
334  }
335  }
336  }
337  else if (schema == kTTSym_script) {
338 
339  // get the script
340  aLine->getValue(v);
341  mSubScript = TTScriptPtr((TTPtr)v[0]);
342 
343  // get the address
344  aLine->lookup(kTTSym_address, v);
345  address = v[0];
346 
347  // bind to the node
348  // (each time ! this why using flattened list could be usefull but dangerous)
349  aDirectory = accessApplicationDirectoryFrom(address);
350  if (aDirectory == NULL)
351  return kTTErrGeneric;
352 
353  if (address.getType() == kAddressRelative)
354  err = aDirectory->getTTNode(parentAddress.appendAddress(address), &aNode);
355  else
356  err = aDirectory->getTTNode(address, &aNode);
357 
358  // if there is a node
359  aContainer = NULL;
360  if (!err) {
361 
362  anObject = aNode->getObject();
363 
364  // check object type
365  if (anObject.valid()) {
366 
367  // for container object
368  if (anObject.name() == kTTSym_Container) {
369 
370  // get the container
371  aContainer = anObject;
372  }
373  }
374  }
375 
376  // prepare argument to run the sub script
377  if (address.getType() == kAddressRelative)
378  v = parentAddress.appendAddress(address);
379  else
380  v = address;
381 
382  // use container to go faster
383  if (aContainer.valid())
384  v.append(aContainer);
385 
386  mSubScript.send(kTTSym_Run, v);
387  }
388  }
389 
390  return kTTErrNone;
391 }
392 
393 TTErr TTScript::RunFlattened()
394 {
395  TTNodeDirectoryPtr aDirectory;
396  TTDictionaryBasePtr aLine;
397  TTNodePtr aNode;
398  TTAddress address;
399  TTSymbol attribute, schema;
400  TTObject anObject;
401  TTValue v, none;
402  TTErr err;
403 
404  // run each line of the script
405  for (mFlattenedLines->begin(); mFlattenedLines->end(); mFlattenedLines->next()) {
406 
407  aLine = TTDictionaryBasePtr((TTPtr)mFlattenedLines->current()[0]);
408 
409  // in flatten mode there is no subscript so only run command and wait lines
410  schema = aLine->getSchema();
411  if (schema == kTTSym_command)
412  {
413  // get the target address
414  aLine->lookup(kTTSym_target, v);
415  address = v[0];
416 
417  aDirectory = accessApplicationDirectoryFrom(address);
418  if (aDirectory == NULL)
419  return kTTErrGeneric;
420 
421  err = aDirectory->getTTNode(address, &aNode);
422 
423  if (!err) {
424 
425  anObject = aNode->getObject();
426 
427  // check object type
428  if (anObject.valid()) {
429 
430  // default attribute is value attribute
431  if (address.getAttribute() == kTTSymEmpty)
432  attribute = kTTSym_value;
433  else
434  attribute = address.getAttribute();
435 
436  // for data object
437  if (anObject.name() == kTTSym_Data) {
438 
439  // send the line using the command message
440  if (attribute == kTTSym_value) {
441 
442  anObject.send(kTTSym_Command, (TTPtr)aLine);
443  continue;
444  }
445  }
446 
447  // any other case : set attribute
448  aLine->getValue(v);
449  anObject.set(attribute, v);
450  }
451  }
452  }
453  else if (schema == kTTSym_WAIT)
454  {
455  ; // do nothing to not block the thread
456  }
457  }
458 
459  return kTTErrNone;
460 }
461 
462 TTErr TTScript::RunCommand(const TTValue& inputValue, TTValue& outputValue)
463 {
464  TTNodeDirectoryPtr aDirectory;
465  TTDictionaryBasePtr aLine;
466  TTNodePtr aNode;
467  TTAddress address, addressToRun;
468  TTSymbol attribute, schema;
469  TTObject anObject;
470  TTValue v, none;
471  TTErr err;
472  TTInt8 depthDifference;
474 
475  if (inputValue.size() == 1) {
476 
477  addressToRun = inputValue[0];
478 
479  // compare each line of the script
480  for (mFlattenedLines->begin(); mFlattenedLines->end(); mFlattenedLines->next()) {
481 
482  aLine = TTDictionaryBasePtr((TTPtr)mFlattenedLines->current()[0]);
483 
484  // in flatten mode there is no subscript so only run command line
485  schema = aLine->getSchema();
486  if (schema != kTTSym_command)
487  continue;
488 
489  // get the target address
490  aLine->lookup(kTTSym_target, v);
491  address = v[0];
492 
493  // compare the address
494  comp = addressToRun.compare(address, depthDifference);
495  if (comp == kAddressEqual || comp == kAddressUpper) {
496 
497  aDirectory = accessApplicationDirectoryFrom(address);
498  if (aDirectory == NULL)
499  return kTTErrGeneric;
500 
501  err = aDirectory->getTTNode(address, &aNode);
502 
503  if (!err) {
504 
505  anObject = aNode->getObject();
506 
507  // check object type
508  if (anObject.valid()) {
509 
510  // default attribute is value attribute
511  if (address.getAttribute() == kTTSymEmpty)
512  attribute = kTTSym_value;
513  else
514  attribute = address.getAttribute();
515 
516  // for data object
517  if (anObject.name() == kTTSym_Data) {
518 
519  // send the line using the command message
520  if (attribute == kTTSym_value) {
521 
522  anObject.send(kTTSym_Command, (TTPtr)aLine);
523  continue;
524  }
525  }
526 
527  // any other case : set attribute
528  aLine->getValue(v);
529  anObject.set(attribute, v);
530  }
531  }
532  }
533  }
534 
535  return kTTErrNone;
536  }
537 
538  return kTTErrGeneric;
539 }
540 
541 TTErr TTScript::RemoveCommand(const TTValue& inputValue, TTValue& outputValue)
542 {
543  TTDictionaryBasePtr aLine;
544  TTAddress address, addressToRemove;
545  TTValue v;
546  TTInt8 depthDifference;
547  TTList linesToRemove;
548  TTSymbol schema;
550 
551  if (inputValue.size() == 1) {
552 
553  addressToRemove = inputValue[0];
554 
555  // compare each line of the script
556  for (mFlattenedLines->begin(); mFlattenedLines->end(); mFlattenedLines->next()) {
557 
558  aLine = TTDictionaryBasePtr((TTPtr)mFlattenedLines->current()[0]);
559 
560  // in flatten mode there is no subscript so only run command line
561  schema = aLine->getSchema();
562  if (schema != kTTSym_command)
563  continue;
564 
565  // get the target address
566  aLine->lookup(kTTSym_target, v);
567  address = v[0];
568 
569  // compare the address
570  comp = addressToRemove.compare(address, depthDifference);
571  if (comp == kAddressEqual || comp == kAddressUpper)
572 
573  // append to the list of lines to remove
574  linesToRemove.append(mFlattenedLines->current());
575  }
576 
577  // remove each lines from the the line list and flattened line list and delete it
578  for (linesToRemove.begin(); linesToRemove.end(); linesToRemove.next()) {
579 
580  mLines->remove(linesToRemove.current());
581  mFlattenedLines->remove(linesToRemove.current());
582 
583  aLine = TTDictionaryBasePtr((TTPtr)linesToRemove.current()[0]);
584  delete aLine;
585  }
586 
587  return kTTErrNone;
588  }
589 
590  return kTTErrGeneric;
591 }
592 
593 TTErr TTScript::Dump(const TTValue& inputValue, TTValue& outputValue)
594 {
595  // use the Flattened lines if they are ready
596  if (mFlattened)
597  return DumpFlattened();
598 
599  TTDictionaryBasePtr aLine;
600  TTSymbol schema, name, unit;
601  TTAddress address, parentAddress = kTTAdrsRoot;
602  TTValue v, valueToDump, none;
603  TTUInt32 ramp;
604 
605  if (!mReturnLineCallback.valid())
606  return kTTErrGeneric;
607 
608  // It is possible to output the command address relatively to a container address
609  if (inputValue.size() == 1)
610  if (inputValue[0].type() == kTypeSymbol)
611  parentAddress = inputValue[0];
612 
613  // output each line of the script
614  for (mLines->begin(); mLines->end(); mLines->next()) {
615 
616  valueToDump.clear();
617  aLine = TTDictionaryBasePtr((TTPtr)mLines->current()[0]);
618 
619  // output script line depending on his schema
620  schema = aLine->getSchema();
621  if (schema == kTTSym_flag) {
622 
623  // get flag value
624  aLine->getValue(valueToDump);
625 
626  // prepend flag name
627  aLine->lookup(kTTSym_name, v);
628  name = v[0];
629  valueToDump.prepend(name);
630 
631  // prepend dash
632  valueToDump.prepend(kTTSym_dash);
633 
634  // output line value
635  mReturnLineCallback.send("notify", valueToDump);
636  }
637  else if (schema == kTTSym_comment) {
638 
639  // get comment value
640  aLine->getValue(valueToDump);
641 
642  // prepend sharp
643  valueToDump.prepend(kTTSym_sharp);
644 
645  // output line value
646  mReturnLineCallback.send("notify", valueToDump);
647  }
648  else if (schema == kTTSym_command) {
649 
650  // get command value
651  aLine->getValue(valueToDump);
652 
653  // get the unit
654  if (!aLine->lookup(kTTSym_unit, v)) {
655  unit = v[0];
656  valueToDump.append(unit);
657  }
658 
659  // get the ramp
660  if (!aLine->lookup(kTTSym_ramp, v)) {
661  ramp = v[0];
662  valueToDump.append(kTTSym_ramp);
663  valueToDump.append(ramp);
664  }
665 
666  // get the address
667  aLine->lookup(kTTSym_address, v);
668  address = v[0];
669 
670  // if relative, append to container address
671  if (address.getType() == kAddressRelative)
672  address = parentAddress.appendAddress(address);
673 
674  // append the address
675  valueToDump.prepend(address);
676 
677  // output line value
678  mReturnLineCallback.send("notify", valueToDump);
679  }
680  else if (schema == kTTSym_script) {
681 
682  // get the script
683  aLine->getValue(v);
684  mSubScript = v[0];
685 
686  TTScriptPtr(mSubScript.instance())->mReturnLineCallback = mReturnLineCallback;
687 
688  // get address
689  aLine->lookup(kTTSym_address, v);
690  address = v[0];
691 
692  // if relative, append to container address
693  if (address.getType() == kAddressRelative)
694  address = parentAddress.appendAddress(address);
695 
696  // dump the subscript
697  mSubScript.send(kTTSym_Dump, address);
698  }
699  }
700 
701  return kTTErrNone;
702 }
703 
704 TTErr TTScript::DumpFlattened()
705 {
706  TTDictionaryBasePtr aLine;
707  TTAddress address;
708  TTSymbol unit, schema;
709  TTValue v, valueToDump, none;
710  TTUInt32 ramp;
711 
712  // run each line of the script
713  for (mFlattenedLines->begin(); mFlattenedLines->end(); mFlattenedLines->next()) {
714 
715  aLine = TTDictionaryBasePtr((TTPtr)mFlattenedLines->current()[0]);
716 
717  // in flatten mode there is no subscript so only run command line
718  schema = aLine->getSchema();
719  if (schema == kTTSym_command)
720  {
721 
722  // get command value
723  aLine->getValue(valueToDump);
724 
725  // get the unit
726  if (!aLine->lookup(kTTSym_unit, v)) {
727  unit = v[0];
728  valueToDump.append(unit);
729  }
730 
731  // get the ramp
732  if (!aLine->lookup(kTTSym_ramp, v)) {
733  ramp = v[0];
734  valueToDump.append(kTTSym_ramp);
735  valueToDump.append(ramp);
736  }
737 
738  // get the target address
739  aLine->lookup(kTTSym_target, v);
740  address = v[0];
741 
742  // append the address
743  valueToDump.prepend(address);
744 
745  // output line value
746  mReturnLineCallback.send("notify", valueToDump);
747  }
748  else if (schema == kTTSym_WAIT)
749  {
750  aLine->getValue(valueToDump);
751 
752  valueToDump.prepend(kTTSym_WAIT);
753 
754  // output WAIT time
755  mReturnLineCallback.send("notify", valueToDump);
756  }
757  }
758 
759  return kTTErrNone;
760 }
761 
762 TTErr TTScript::DumpLine(const TTValue& inputValue, TTValue& outputValue)
763 {
764  TTDictionaryBasePtr aLine;
765  TTAddress address, addressToDump;;
766  TTSymbol unit, schema;
767  TTValue v, valueToDump, none;
768  TTUInt32 ramp;
769  TTInt8 depthDifference;
771 
772  if (inputValue.size() == 1) {
773 
774  addressToDump = inputValue[0];
775 
776  // run each line of the script
777  for (mFlattenedLines->begin(); mFlattenedLines->end(); mFlattenedLines->next()) {
778 
779  aLine = TTDictionaryBasePtr((TTPtr)mFlattenedLines->current()[0]);
780 
781  // in flatten mode there is no subscript so only run command line
782  schema = aLine->getSchema();
783  if (schema != kTTSym_command)
784  continue;
785 
786  // get the target address
787  aLine->lookup(kTTSym_target, v);
788  address = v[0];
789 
790  // compare the address
791  comp = addressToDump.compare(address, depthDifference);
792  if (comp == kAddressEqual || comp == kAddressUpper) {
793 
794  // get command value
795  aLine->getValue(valueToDump);
796 
797  // get the unit
798  if (!aLine->lookup(kTTSym_unit, v)) {
799  unit = v[0];
800  valueToDump.append(unit);
801  }
802 
803  // get the ramp
804  if (!aLine->lookup(kTTSym_ramp, v)) {
805  ramp = v[0];
806  valueToDump.append(kTTSym_ramp);
807  valueToDump.append(ramp);
808  }
809 
810  // append the address
811  valueToDump.prepend(address);
812 
813  // output line value
814  mReturnLineCallback.send("notify", valueToDump);
815  }
816  }
817 
818  return kTTErrNone;
819  }
820 
821  return kTTErrGeneric;
822 }
823 
824 TTErr TTScript::Append(const TTValue& newLine, TTValue& outputValue)
825 {
826  TTDictionaryBasePtr line = NULL;
827  TTAddress address;
828  TTValue v;
829 
830  // if the line is already parsed into a TTDictionnary
831  // append it directly (this allows script owners to parse a line before to append it)
832  if (newLine.size() == 1) {
833 
834  if (newLine[0].type() == kTypePointer) {
835 
836  mLines->append(newLine);
837  outputValue = newLine;
838  return kTTErrNone;
839  }
840  }
841 
842  line = TTScriptParseLine(newLine);
843 
844  if (line) {
845 
846  // append the line
847  v = TTValue((TTPtr)line);
848  mLines->append(v);
849 
850  // append the line to the flatenned line if possible
851  if (mFlattened && (line->getSchema() == kTTSym_command || line->getSchema() == kTTSym_script)) {
852 
853  line->lookup(kTTSym_address, v);
854  address = v[0];
855 
856  if (address.getType() == kAddressAbsolute) {
857  line->append(kTTSym_target, address);
858 
859  v = TTValue((TTPtr)line);
860  mFlattenedLines->append(v);
861  }
862  }
863 
864  outputValue = v;
865  return kTTErrNone;
866  }
867 
868  return kTTErrGeneric;
869 }
870 
871 TTErr TTScript::AppendCommand(const TTValue& newCommand, TTValue& outputValue)
872 {
873  TTDictionaryBasePtr line = NULL;
874  TTAddress address;
875  TTValue v;
876 
877  line = TTScriptParseCommand(newCommand);
878 
879  if (line) {
880 
881  // append the line
882  v = TTValue((TTPtr)line);
883  mLines->append(v);
884 
885  // append the line to the flatenned line if possible
886  if (mFlattened) {
887 
888  line->lookup(kTTSym_address, v);
889  address = v[0];
890 
891  if (address.getType() == kAddressAbsolute) {
892  line->append(kTTSym_target, address);
893 
894  v = TTValue((TTPtr)line);
895  mFlattenedLines->append(v);
896  }
897  }
898 
899  outputValue = v;
900 
901  return kTTErrNone;
902  }
903 
904  return kTTErrGeneric;
905 }
906 
907 TTErr TTScript::AppendComment(const TTValue& newComment, TTValue& outputValue)
908 {
909  TTDictionaryBasePtr line = NULL;
910  TTValue v;
911 
912  line = TTScriptParseComment(newComment);
913 
914  if (line) {
915 
916  // append the line
917  v = TTValue((TTPtr)line);
918  mLines->append(v);
919 
920  outputValue = v;
921  return kTTErrNone;
922  }
923 
924  return kTTErrGeneric;
925 }
926 
927 TTErr TTScript::AppendScript(const TTValue& newScript, TTValue& outputValue)
928 {
930  TTAddress address;
931  TTValue v;
932 
933  line = TTScriptParseScript(newScript);
934 
935  if (line) {
936 
937  // get the sub script
938  line->getValue(v);
939  mSubScript = v[0];
940 
941  // append the line
942  v = TTValue((TTPtr)line);
943  mLines->append(v);
944  mFlattenedLines->append(v);
945  outputValue = v;
946 
947  return kTTErrNone;
948  }
949 
950  return kTTErrGeneric;
951 }
952 
953 TTErr TTScript::AppendFlag(const TTValue& newflagAndArguments, TTValue& outputValue)
954 {
955  TTDictionaryBasePtr line = NULL;
956  TTValue v;
957 
958  line = TTScriptParseFlag(newflagAndArguments);
959 
960  if (line) {
961 
962  // append the line
963  v = TTValue((TTPtr)line);
964  mLines->append(v);
965 
966  outputValue = v;
967  return kTTErrNone;
968  }
969 
970  return kTTErrGeneric;
971 }
972 
973 TTErr TTScript::WriteAsXml(const TTValue& inputValue, TTValue& outputValue)
974 {
975  TTObject o = inputValue[0];
976  TTXmlHandlerPtr aXmlHandler = (TTXmlHandlerPtr)o.instance();
977  if (!aXmlHandler)
978  return kTTErrGeneric;
979 
980  TTDictionaryBasePtr aLine = NULL;
981  TTSymbol name, unit;
982  TTAddress address;
983  TTValue v;
984  TTString aString;
985 
986  // Write all lines
987  for (mLines->begin(); mLines->end(); mLines->next()) {
988 
989  aLine = TTDictionaryBasePtr((TTPtr)mLines->current()[0]);
990 
991  // Write script line depending on his schema
992  if (aLine->getSchema() == kTTSym_flag) {
993 
994  // get flag name
995  aLine->lookup(kTTSym_name, v);
996  name = v[0];
997 
998  // dont't write preset or cue flags
999  // TODO : we need to filter those flag line before (in TTPreset or TTCue)
1000  if (name == TTSymbol("preset") || name == TTSymbol("cue"))
1001  continue;
1002 
1003  // else get flag arguments value
1004  aLine->getValue(v);
1005  v.toString(NO); // no quotes
1006  aString = TTString(v[0]);
1007 
1008  // write flag name and arguments as an Element
1009  xmlTextWriterStartElement((xmlTextWriterPtr)aXmlHandler->mWriter, BAD_CAST "flag");
1010  xmlTextWriterWriteAttribute((xmlTextWriterPtr)aXmlHandler->mWriter, BAD_CAST "name", BAD_CAST name.c_str());
1011  xmlTextWriterWriteRaw((xmlTextWriterPtr)aXmlHandler->mWriter, BAD_CAST aString.data());
1012  xmlTextWriterEndElement((xmlTextWriterPtr)aXmlHandler->mWriter);
1013  }
1014  if (aLine->getSchema() == kTTSym_comment) {
1015 
1016  // get comment value
1017  aLine->getValue(v);
1018  v.toString();
1019  aString = TTString(v[0]);
1020 
1021  // write comment attribute
1022  xmlTextWriterWriteFormatComment((xmlTextWriterPtr)aXmlHandler->mWriter, "%s", BAD_CAST aString.data());
1023  }
1024  else if (aLine->getSchema() == kTTSym_command) {
1025 
1026  // get address
1027  aLine->lookup(kTTSym_address, v);
1028  address = v[0];
1029 
1030  // start command Element
1031  xmlTextWriterStartElement((xmlTextWriterPtr)aXmlHandler->mWriter, BAD_CAST kTTSym_command.c_str());
1032 
1033  // write name attribute
1034  xmlTextWriterWriteAttribute((xmlTextWriterPtr)aXmlHandler->mWriter, BAD_CAST "address", BAD_CAST address.c_str());
1035 
1036  // write unit attribute
1037  if (!aLine->lookup(kTTSym_unit, v)) {
1038  unit = v[0];
1039 
1040  xmlTextWriterWriteAttribute((xmlTextWriterPtr)aXmlHandler->mWriter, BAD_CAST "unit", BAD_CAST unit.c_str());
1041  }
1042 
1043  // write ramp attribute
1044  if (!aLine->lookup(kTTSym_ramp, v)) {
1045  v.toString();
1046  aString = TTString(v[0]);
1047 
1048  xmlTextWriterWriteAttribute((xmlTextWriterPtr)aXmlHandler->mWriter, BAD_CAST "ramp", BAD_CAST aString.data());
1049  }
1050 
1051  // write value
1052  if (!aLine->getValue(v)) {
1053  v.toString();
1054  aString = TTString(v[0]);
1055 
1056  xmlTextWriterWriteString((xmlTextWriterPtr)aXmlHandler->mWriter, BAD_CAST aString.data());
1057  }
1058 
1059  // close command Element
1060  xmlTextWriterEndElement((xmlTextWriterPtr)aXmlHandler->mWriter);
1061  }
1062  else if (aLine->getSchema() == kTTSym_script) {
1063 
1064  // get address
1065  aLine->lookup(kTTSym_address, v);
1066  address = v[0];
1067 
1068  // start script Element
1069  xmlTextWriterStartElement((xmlTextWriterPtr)aXmlHandler->mWriter, BAD_CAST kTTSym_script.c_str());
1070 
1071  // write address attribute
1072  xmlTextWriterWriteAttribute((xmlTextWriterPtr)aXmlHandler->mWriter, BAD_CAST "address", BAD_CAST address.c_str());
1073 
1074  // get the script
1075  aLine->getValue(v);
1076  mSubScript = v[0];
1077 
1078  // use WriteAsXml of the script
1079  aXmlHandler->setAttributeValue(kTTSym_object, mSubScript);
1080  aXmlHandler->sendMessage(TTSymbol("Write"));
1081 
1082  // close script Element
1083  xmlTextWriterEndElement((xmlTextWriterPtr)aXmlHandler->mWriter);
1084  }
1085  }
1086 
1087  return kTTErrNone;
1088 }
1089 
1090 TTErr TTScript::ReadFromXml(const TTValue& inputValue, TTValue& outputValue)
1091 {
1092  TTObject o = inputValue[0];
1093  TTXmlHandlerPtr aXmlHandler = (TTXmlHandlerPtr)o.instance();
1094  if (!aXmlHandler)
1095  return kTTErrGeneric;
1096 
1097  TTDictionaryBasePtr aLine;
1098  TTSymbol name, attributeName;
1099  TTAddress address;
1100  TTValue v, parsedLine;
1101 
1102  // if there is a current sub script : pass it the XML content
1103  if (mSubScript.valid()) {
1104 
1105  // use ReadFromXml of the sub script
1106  return mSubScript.send("ReadFromXml", inputValue, outputValue);
1107  }
1108 
1109  // Switch on the name of the XML node
1110 
1111  // Starts file reading
1112  if (aXmlHandler->mXmlNodeName == kTTSym_xmlHandlerReadingStarts) {
1113  Clear();
1114  return kTTErrNone;
1115  }
1116 
1117  // Ends file reading
1118  if (aXmlHandler->mXmlNodeName == kTTSym_xmlHandlerReadingEnds)
1119  return kTTErrNone;
1120 
1121  // Comment node : edit comment line
1122  if (aXmlHandler->mXmlNodeName == kTTSym_xmlHandlerReadingComment) {
1123 
1124  // edit comment line
1125  aLine = new TTDictionaryBase();
1126  aLine->setSchema(kTTSym_comment);
1127  aLine->setValue(aXmlHandler->mXmlNodeValue);
1128 
1129  // append the line
1130  mLines->append((TTPtr)aLine);
1131 
1132  return kTTErrNone;
1133  }
1134 
1135  // Flag node : edit flag line
1136  if (aXmlHandler->mXmlNodeName == kTTSym_flag) {
1137 
1138  if (!aXmlHandler->mXmlNodeStart)
1139  return kTTErrNone;
1140 
1141  // Get flag name
1142  if (!aXmlHandler->getXmlAttribute(kTTSym_name, v)) {
1143 
1144  if (v.size() == 1) {
1145 
1146  if (v[0].type() == kTypeSymbol) {
1147 
1148  name = v[0];
1149 
1150  // edit flag line
1151  aLine = new TTDictionaryBase();
1152  aLine->setSchema(kTTSym_flag);
1153  aLine->append(kTTSym_name, name);
1154  aLine->setValue(aXmlHandler->mXmlNodeValue);
1155 
1156  // append the line
1157  mLines->append((TTPtr)aLine);
1158  }
1159  }
1160  }
1161 
1162  return kTTErrNone;
1163  }
1164 
1165  // Command node : edit command line
1166  if (aXmlHandler->mXmlNodeName == kTTSym_command) {
1167 
1168  if (!aXmlHandler->mXmlNodeStart)
1169  return kTTErrNone;
1170 
1171  // get address attribute
1172  if (!aXmlHandler->getXmlAttribute(kTTSym_address, v)) {
1173 
1174  if (v.size() == 1) {
1175 
1176  if (v[0].type() == kTypeSymbol) {
1177 
1178  address = v[0];
1179  }
1180  else {
1181 
1182  v.toString();
1183  address = TTAddress(TTString(v[0]));
1184  }
1185 
1186  // edit command line
1187  aLine = new TTDictionaryBase();
1188  aLine->setSchema(kTTSym_command);
1189  aLine->append(kTTSym_address, address);
1190  aLine->setValue(aXmlHandler->mXmlNodeValue);
1191 
1192  // get all other command line attribute (unit, ramp, ...)
1193  while (!aXmlHandler->getXmlNextAttribute(attributeName, v)) {
1194 
1195  // append attribute to the command line
1196  aLine->append(attributeName, v);
1197  }
1198 
1199  // append the line
1200  mLines->append((TTPtr)aLine);
1201 
1202  return kTTErrNone;
1203  }
1204  }
1205  }
1206 
1207  // Script node : edit script line
1208  if (aXmlHandler->mXmlNodeName == kTTSym_script) {
1209 
1210  // end of the script node
1211  if (!aXmlHandler->mXmlNodeStart) {
1212 
1213  if (mParentScript.valid()) {
1214 
1215  // set no sub script for the parent script
1216  v = TTObject();
1217  mParentScript.set("subScript", v);
1218  }
1219  }
1220 
1221  // get address attribute of the node
1222  else if (!aXmlHandler->getXmlAttribute(kTTSym_address, v)) {
1223 
1224  if (v.size() == 1) {
1225 
1226  // edit sub script line
1227  this->AppendScript(v, parsedLine);
1228 
1229  // set this as parent script of the subscript
1230  mSubScript.set("parentScript", TTObject(this));
1231  }
1232  }
1233 
1234  return kTTErrNone;
1235  }
1236 
1237  return kTTErrGeneric;
1238 }
1239 
1240 TTErr TTScript::WriteAsText(const TTValue& inputValue, TTValue& outputValue)
1241 {
1242  TTObject o = inputValue[0];
1243  TTTextHandlerPtr aTextHandler = (TTTextHandlerPtr)o.instance();
1244  if (!aTextHandler)
1245  return kTTErrGeneric;
1246 
1247  TTString *buffer;
1248  TTDictionaryBasePtr aLine;
1249  TTAddress address;
1250  TTSymbol name;
1251  TTString aString;
1252  TTUInt8 i;
1253  TTValue v;
1254 
1255  buffer = aTextHandler->mWriter;
1256 
1257  if (mFlattened) {
1258 
1259  // Write all flattened lines
1260  for (mFlattenedLines->begin(); mFlattenedLines->end(); mFlattenedLines->next()) {
1261 
1262  aLine = TTDictionaryBasePtr((TTPtr)mFlattenedLines->current()[0]);
1263 
1264  // Write script line depending on his schema
1265  if (aLine->getSchema() == kTTSym_flag) {
1266 
1267  TTBoolean oneSymbol = NO;
1268 
1269  // get flag name
1270  aLine->lookup(kTTSym_name, v);
1271  name = v[0];
1272 
1273  // get flag arguments value if exists
1274  if (!aLine->getValue(v)) {
1275 
1276  if (v.size() == 1)
1277  if (v[0].type() == kTypeSymbol)
1278  oneSymbol = YES;
1279 
1280  v.toString(NO); // no quotes
1281  aString = TTString(v[0]);
1282  }
1283  else aString = "";
1284 
1285  // write flag name and arguments
1286  *buffer += "- ";
1287  *buffer += name.c_str();
1288  *buffer += " ";
1289 
1290  // if the value is an unique symbol : add quotes
1291  if (oneSymbol) *buffer += "\"";
1292  *buffer += aString.data();
1293  if (oneSymbol) *buffer += "\"";
1294 
1295  *buffer += "\n";
1296  }
1297  if (aLine->getSchema() == kTTSym_comment) {
1298 
1299  // get comment value
1300  if (!aLine->getValue(v)) {
1301  v.toString();
1302  aString = TTString(v[0]);
1303  }
1304  else aString = "";
1305 
1306  // write comment
1307  *buffer += "# ";
1308  *buffer += aString.data();
1309  *buffer += "\n";
1310  }
1311  if (aLine->getSchema() == kTTSym_WAIT) {
1312 
1313  // get comment value
1314  if (!aLine->getValue(v)) {
1315  v.toString();
1316  aString = TTString(v[0]);
1317  }
1318  else aString = "";
1319 
1320  // write comment
1321  *buffer += "WAIT ";
1322  *buffer += aString.data();
1323  *buffer += "\n";
1324  }
1325  else if (aLine->getSchema() == kTTSym_command) {
1326 
1327  // get target address
1328  if (!aLine->lookup(kTTSym_target, v)) {
1329  address = v[0];
1330 
1331  // write address
1332  *buffer += address.c_str();
1333 
1334  // get and write value
1335  if (!aLine->getValue(v)) {
1336  v.toString();
1337  aString = TTString(v[0]);
1338 
1339  *buffer += " ";
1340  *buffer += aString.data();
1341 
1342  // get and write unit
1343  if (!aLine->lookup(kTTSym_unit, v)) {
1344  v.toString();
1345  aString = TTString(v[0]);
1346 
1347  *buffer += " ";
1348  *buffer += aString.data();
1349  }
1350 
1351  // get and write ramp
1352  if (!aLine->lookup(kTTSym_ramp, v)) {
1353  v.toString();
1354  aString = TTString(v[0]);
1355 
1356  *buffer += " ramp ";
1357  *buffer += aString.data();
1358  }
1359  }
1360 
1361  *buffer += "\n";
1362  }
1363  }
1364  // no sub script in flatten mode
1365  }
1366 
1367  return kTTErrNone;
1368  }
1369 
1370  // write a new line for level 0
1371  if (!aTextHandler->mTabCount)
1372  *buffer += "\n";
1373 
1374  // Write all lines
1375  for (mLines->begin(); mLines->end(); mLines->next()) {
1376 
1377  aLine = TTDictionaryBasePtr((TTPtr)mLines->current()[0]);
1378 
1379  // write tabulation
1380  for (i = 0; i < aTextHandler->mTabCount; i++)
1381  *buffer += "\t";
1382 
1383  // Write script line depending on his schema
1384  if (aLine->getSchema() == kTTSym_flag) {
1385 
1386  TTBoolean oneSymbol = NO;
1387 
1388  // get flag name
1389  aLine->lookup(kTTSym_name, v);
1390  name = v[0];
1391 
1392  // get flag arguments value if exists
1393  if (!aLine->getValue(v)) {
1394 
1395  if (v.size() == 1)
1396  if (v[0].type() == kTypeSymbol)
1397  oneSymbol = YES;
1398 
1399  v.toString(NO); // no quotes
1400  aString = TTString(v[0]);
1401  }
1402  else aString = "";
1403 
1404  // write flag name and arguments
1405  *buffer += "- ";
1406  *buffer += name.c_str();
1407  *buffer += " ";
1408 
1409  // if the value is an unique symbol : add quotes
1410  if (oneSymbol) *buffer += "\"";
1411  *buffer += aString.data();
1412  if (oneSymbol) *buffer += "\"";
1413 
1414  *buffer += "\n";
1415  }
1416  if (aLine->getSchema() == kTTSym_comment) {
1417 
1418  // get comment value
1419  if (!aLine->getValue(v)) {
1420  v.toString();
1421  aString = TTString(v[0]);
1422  }
1423  else aString = "";
1424 
1425  // write comment
1426  *buffer += "# ";
1427  *buffer += aString.data();
1428  *buffer += "\n";
1429  }
1430  else if (aLine->getSchema() == kTTSym_WAIT) {
1431 
1432  // get duration value
1433  if (!aLine->getValue(v)) {
1434  v.toString();
1435  aString = TTString(v[0]);
1436  }
1437  else aString = "";
1438 
1439  // write WAIT
1440  *buffer += "WAIT ";
1441  *buffer += aString.data();
1442  *buffer += "\n";
1443  }
1444  else if (aLine->getSchema() == kTTSym_command) {
1445 
1446  // get name
1447  if (!aLine->lookup(kTTSym_address, v)) {
1448  address = v[0];
1449 
1450  // write address
1451  *buffer += address.c_str();
1452 
1453  // get and write value
1454  if (!aLine->getValue(v)) {
1455  v.toString();
1456  aString = TTString(v[0]);
1457 
1458  *buffer += " ";
1459  *buffer += aString.data();
1460 
1461  // get and write unit
1462  if (!aLine->lookup(kTTSym_unit, v)) {
1463  v.toString();
1464  aString = TTString(v[0]);
1465 
1466  *buffer += " ";
1467  *buffer += aString.data();
1468  }
1469 
1470  // get and write ramp
1471  if (!aLine->lookup(kTTSym_ramp, v)) {
1472  v.toString();
1473  aString = TTString(v[0]);
1474 
1475  *buffer += " ramp ";
1476  *buffer += aString.data();
1477  }
1478  }
1479 
1480  *buffer += "\n";
1481  }
1482  }
1483  else if (aLine->getSchema() == kTTSym_script) {
1484 
1485  // get address
1486  aLine->lookup(kTTSym_address, v);
1487  address = v[0];
1488 
1489  // write address
1490  *buffer += address.c_str();
1491  *buffer += "\n";
1492 
1493  // get the script
1494  aLine->getValue(v);
1495  mSubScript = v[0];
1496 
1497  // set this as parent script of the subscript
1498  mSubScript.set("parentScript", TTObject(this));
1499 
1500  // increment the tab count to indent lines
1501  aTextHandler->mTabCount++;
1502 
1503  // use WriteAsText of the sub script
1504  mSubScript.send("WriteAsText", inputValue, outputValue);
1505 
1506  // decrement the tab count
1507  aTextHandler->mTabCount--;
1508  }
1509  }
1510 
1511  if (mParentScript.valid()) {
1512 
1513  // set no sub script for the parent script
1514  v = TTObject();
1515  mParentScript.set("subScript", v);
1516  }
1517 
1518  return kTTErrNone;
1519 }
1520 
1521 TTErr TTScript::ReadFromText(const TTValue& inputValue, TTValue& outputValue)
1522 {
1523  TTObject o = inputValue[0];
1524  TTTextHandlerPtr aTextHandler = (TTTextHandlerPtr)o.instance();
1525  if (!aTextHandler)
1526  return kTTErrGeneric;
1527 
1528  TTDictionaryBasePtr aLine;
1529  TTValue v, parsedLine;
1530 
1531  // this line is for this script
1532  if (aTextHandler->mTabCount == 0) {
1533 
1534  this->Append(*(aTextHandler->mLine), parsedLine);
1535 
1536  // check for script line to set it as current mSubScript
1537  aLine = TTDictionaryBasePtr((TTPtr)parsedLine[0]);
1538 
1539  if (aLine) {
1540 
1541  if (aLine->getSchema() == kTTSym_script) {
1542 
1543  // get script
1544  aLine->getValue(v);
1545  mSubScript = v[0];
1546  }
1547  }
1548  }
1549 
1550  // else it is for a sub script
1551  else {
1552 
1553  // if no sub script something goes wrong
1554  if (!mSubScript.valid())
1555  return kTTErrGeneric;
1556 
1557  aTextHandler->mTabCount--;
1558 
1559  // set this as parent script of the subscript
1560  mSubScript.set("parentScript", TTObject(this));
1561 
1562  // use ReadFromText of the sub script
1563  aTextHandler->setAttributeValue(kTTSym_object, mSubScript);
1564  aTextHandler->sendMessage(TTSymbol("Read"));
1565  }
1566 
1567  return kTTErrNone;
1568 }
1569 
1570 #if 0
1571 #pragma mark -
1572 #pragma mark Some Methods
1573 #endif
1574 
1575 TTDictionaryBasePtr TTScriptParseLine(const TTValue& newLine)
1576 {
1577  TTSymbol firstSymbol;
1578  TTValue v, rest, none;
1579  TTUInt32 size = newLine.size();
1580 
1581  if (size >= 1) {
1582 
1583  // get the first symbol
1584  if (newLine[0].type() == kTypeSymbol) {
1585 
1586  firstSymbol = newLine[0];
1587  }
1588  // if the first element is not a symbol
1589  else {
1590 
1591  v = newLine[0];
1592  v.toString();
1593  firstSymbol = TTString(v[0]);
1594  }
1595 
1596  // if starts by a "-" : flag line
1597  if (firstSymbol == kTTSym_dash) {
1598 
1599  if (size >= 2) {
1600  if (newLine[1].type() == kTypeSymbol) {
1601 
1602  rest.copyFrom(newLine, 1);
1603  return TTScriptParseFlag(rest);
1604  }
1605  }
1606  }
1607  // if starts by a "#" : comment line
1608  else if (firstSymbol == kTTSym_sharp) {
1609 
1610  if (size >= 2) {
1611  if (newLine[1].type() == kTypeSymbol) {
1612 
1613  rest.copyFrom(newLine, 1);
1614  return TTScriptParseComment(rest);
1615  }
1616  }
1617  else
1618  return TTScriptParseComment(none);
1619  }
1620  // if starts by a "WAIT" : wait line
1621  else if (firstSymbol == kTTSym_WAIT)
1622  {
1623  if (size == 2)
1624  {
1625  if (newLine[1].type() == kTypeInt32)
1626  {
1627  rest.copyFrom(newLine, 1);
1628  return TTScriptParseWait(rest);
1629  }
1630  }
1631  }
1632  }
1633 
1634  // else if more than one symbol : append a command
1635  if (size > 1)
1636  return TTScriptParseCommand(newLine);
1637 
1638  // else : append a sub script
1639  else
1640  return TTScriptParseScript(newLine);
1641 }
1642 
1643 TTDictionaryBasePtr TTScriptParseComment(const TTValue& newComment)
1644 {
1646 
1647  line->setSchema(kTTSym_comment);
1648  line->setValue(newComment);
1649 
1650  return line;
1651 }
1652 
1653 TTDictionaryBasePtr TTScriptParseWait(const TTValue& duration)
1654 {
1656 
1657  line->setSchema(kTTSym_WAIT);
1658  line->setValue(duration);
1659 
1660  return line;
1661 }
1662 
1663 TTDictionaryBasePtr TTScriptParseFlag(const TTValue& newflagAndArguments)
1664 {
1665  TTDictionaryBasePtr line = NULL;
1666  TTSymbol flagName;
1667  TTValue v, arguments;
1668 
1669  if (newflagAndArguments.size() >= 1) {
1670 
1671  // get the first symbol
1672  if (newflagAndArguments[0].type() == kTypeSymbol) {
1673 
1674  flagName = newflagAndArguments[0];
1675  }
1676  // if the first element is not a symbol
1677  else {
1678 
1679  v = newflagAndArguments[0];
1680  v.toString();
1681  flagName = TTString(v[0]);
1682  }
1683 
1684  arguments.copyFrom(newflagAndArguments, 1);
1685 
1686  line = new TTDictionaryBase();
1687  line->setSchema(kTTSym_flag);
1688  line->append(kTTSym_name, flagName);
1689  line->setValue(arguments);
1690  }
1691 
1692  return line;
1693 }
1694 
1695 TTDictionaryBasePtr TTScriptParseCommand(const TTValue& newCommand)
1696 {
1697  TTDictionaryBasePtr line = NULL;
1698  TTSymbol firstSymbol;
1699  TTValue v, commandValue;
1700 
1701  // parse name + command
1702  if (newCommand.size() >= 1 ) {
1703 
1704  if (newCommand[0].type() == kTypeSymbol) {
1705 
1706  firstSymbol = newCommand[0];
1707  }
1708  else {
1709 
1710  v = newCommand[0];
1711  v.toString();
1712  firstSymbol = TTString(v[0]);
1713  }
1714 
1715  commandValue.copyFrom(newCommand, 1);
1716 
1717  line = TTDataParseCommand(commandValue);
1718 
1719  if (line)
1720  line->append(kTTSym_address, firstSymbol);
1721  }
1722 
1723  return line;
1724 }
1725 
1726 TTDictionaryBasePtr TTScriptParseScript(const TTValue& newScript)
1727 {
1728  TTDictionaryBasePtr line = NULL;
1729  TTSymbol firstSymbol;
1730  TTObject script;
1731  TTValue v, none;
1732 
1733  // parse script address
1734  if (newScript.size() >= 1 ) {
1735 
1736  if (newScript[0].type() == kTypeSymbol) {
1737 
1738  firstSymbol = newScript[0];
1739  }
1740  else {
1741 
1742  v = newScript[0];
1743  v.toString();
1744  firstSymbol = TTString(v[0]);
1745  }
1746 
1747  line = new TTDictionaryBase();
1748 
1749  if (line) {
1750 
1751  line->setSchema(kTTSym_script);
1752  line->append(kTTSym_address, firstSymbol);
1753 
1754  script = TTObject(kTTSym_Script);
1755 
1756  line->setValue(script);
1757  }
1758 
1759  }
1760 
1761  return line;
1762 }
1763 
1764 TTErr TTScriptInterpolate(TTObject script1, TTObject script2, TTFloat64 position)
1765 {
1766  TTDictionaryBasePtr line1, line2;
1767  TTAddress adrs1, adrs2;
1768  TTValue v1, v2, v, newValue;
1769  TTSymbol schema1, schema2, attribute, type, function;
1770  TTNodePtr aNode;
1771  TTObject aData;
1772  TTValue found, none;
1773  TTUInt32 i, s;
1774 
1775  for (TTScriptPtr(script1.instance())->mFlattenedLines->begin(), TTScriptPtr(script2.instance())->mFlattenedLines->begin();
1776  TTScriptPtr(script1.instance())->mFlattenedLines->end() && TTScriptPtr(script2.instance())->mFlattenedLines->end();
1777  TTScriptPtr(script1.instance())->mFlattenedLines->next(), TTScriptPtr(script2.instance())->mFlattenedLines->next()) {
1778 
1779  line1 = TTDictionaryBasePtr((TTPtr)TTScriptPtr(script1.instance())->mFlattenedLines->current()[0]);
1780  line2 = TTDictionaryBasePtr((TTPtr)TTScriptPtr(script2.instance())->mFlattenedLines->current()[0]);
1781 
1782  // get the line schema
1783  line1->lookup(kTTSym_schema, v);
1784  schema1 = v[0];
1785 
1786  line2->lookup(kTTSym_schema, v);
1787  schema2 = v[0];
1788 
1789  if (schema1 != kTTSym_command && schema2 != kTTSym_command)
1790  continue;
1791 
1792  // get the target address
1793  line1->lookup(kTTSym_target, v);
1794  adrs1 = v[0];
1795 
1796  line2->lookup(kTTSym_target, v);
1797  adrs2 = v[0];
1798 
1799  // adrs1 and adrs2 have to be the same
1800  if (adrs1 != adrs2) {
1801 
1802  TTScriptPtr(script2.instance())->mFlattenedLines->find(&TTScriptFindTarget, (TTPtr)&adrs1, found);
1803 
1804  // couldn't find the same address in script2 : skip the command
1805  if (found.empty()) {
1806  TTScriptPtr(script2.instance())->mFlattenedLines->begin();
1807  continue;
1808  }
1809  else
1810  line2 = TTDictionaryBasePtr((TTPtr)found[0]);
1811  }
1812 
1813  // bind to the node
1814  if (!accessApplicationDirectoryFrom(adrs1)->getTTNode(adrs1, &aNode)) {
1815 
1816  aData = aNode->getObject();
1817  if (aData.valid()) {
1818 
1819  // check type
1820  if (!aData.get(kTTSym_type, v)) {
1821 
1822  type = v[0];
1823 
1824  // get line values
1825  line1->getValue(v1);
1826  line2->getValue(v2);
1827 
1828  // don't interpolate attribute
1829  attribute = adrs1.getAttribute();
1830  if (attribute != kTTSymEmpty && attribute != kTTSym_value)
1831  continue;
1832 
1833  // check function
1834  if (!aData.get(kTTSym_rampFunction, v)) {
1835 
1836  function = v[0];
1837 
1838  if (function != kTTSym_none) {
1839 
1840  // set the starting value
1841  aData.send(kTTSym_RampSet, v1);
1842 
1843  // set the target value
1844  aData.send(kTTSym_RampTarget, v2);
1845 
1846  // set interpolate using the ramp function
1847  aData.send(kTTSym_RampSlide, position);
1848  }
1849 
1850  // process the interpolation our self
1851  else {
1852 
1853  if (type == kTTSym_integer) {
1854  newValue = TTValue(TTInt32(v1[0]) * (1. - position) + TTInt32(v2[0]) * position);
1855 
1856  } else if (type == kTTSym_decimal) {
1857  newValue = TTValue(TTFloat64(v1[0]) * (1. - position) + TTFloat64(v2[0]) * position);
1858 
1859  } else if (type == kTTSym_array) {
1860  s = v1.size();
1861  if (s == v2.size()) {
1862 
1863  newValue.resize(s);
1864  for (i = 0; i < s; i++)
1865  newValue[i] = TTFloat64(v1[i]) * (1. - position) + TTFloat64(v2[i]) * position;
1866  }
1867 
1868  } else
1869  newValue = position == 0. ? v1 : v2;
1870 
1871  // set the interpolated value
1872  aData.set(kTTSym_value, newValue);
1873  }
1874  }
1875  }
1876  }
1877  }
1878  }
1879 
1880  return kTTErrNone;
1881 }
1882 
1883 TTErr TTScriptMix(const TTValue& scripts, const TTValue& factors)
1884 {
1885  TTObject firstScript, aScript;
1886  TTDictionaryBasePtr firstScriptLine, aLine;
1887  TTAddress firstAdrs, adrs;
1888  TTValue v, valueToMix, mixedValue, found;
1889  TTSymbol schema, type;
1890  TTNodePtr aNode;
1891  TTObject anObject;
1892  TTFloat64 sumFactors;
1893  TTUInt32 i, mixSize;
1894 
1895  if (scripts.empty())
1896  return kTTErrGeneric;
1897 
1898  mixSize = scripts.size();
1899 
1900  // initialized lines list iterator
1901  firstScript = scripts[0];
1902  TTScriptPtr(firstScript.instance())->mFlattenedLines->begin();
1903 
1904  for (i = 1; i < mixSize; i++) {
1905 
1906  aScript = scripts[i];
1907  TTScriptPtr(aScript.instance())->mFlattenedLines->begin();
1908  }
1909 
1910  // iterate over all flattened lines of first given script
1911  for (; TTScriptPtr(firstScript.instance())->mFlattenedLines->end(); TTScriptPtr(firstScript.instance())->mFlattenedLines->next()) {
1912 
1913  firstScriptLine = TTDictionaryBasePtr((TTPtr)TTScriptPtr(firstScript.instance())->mFlattenedLines->current()[0]);
1914 
1915  // get the line schema
1916  firstScriptLine->lookup(kTTSym_schema, v);
1917  schema = v[0];
1918 
1919  if (schema != kTTSym_command)
1920  continue;
1921 
1922  // get the target address
1923  firstScriptLine->lookup(kTTSym_target, v);
1924  firstAdrs = v[0];
1925 
1926  // bind to the node
1927  if (!accessApplicationDirectoryFrom(firstAdrs)->getTTNode(firstAdrs, &aNode)) {
1928 
1929  anObject = aNode->getObject();
1930 
1931  if (anObject.valid()) {
1932 
1933  if (!anObject.get(kTTSym_type, v)) {
1934 
1935  type = v[0];
1936 
1937  // initialize the mix with the command of the first script
1938  sumFactors = TTScriptMixLine(firstScriptLine, type, mixSize, TTFloat64(factors[0]), mixedValue, YES);
1939 
1940  // then look for same line into the other script
1941  for (i = 1; i < mixSize; i++) {
1942 
1943  aScript = scripts[i];
1944 
1945  aLine = NULL;
1946  if (!TTScriptPtr(aScript.instance())->mFlattenedLines->end()) {
1947 
1948  // go to the next line
1949  TTScriptPtr(aScript.instance())->mFlattenedLines->next();
1950  aLine = TTDictionaryBasePtr((TTPtr)TTScriptPtr(aScript.instance())->mFlattenedLines->current()[0]);
1951 
1952  // get the target address
1953  aLine->lookup(kTTSym_target, v);
1954  adrs = v[0];
1955 
1956  // is the address equal ?
1957  if (adrs != firstAdrs)
1958  aLine = NULL;
1959  }
1960 
1961  // if the next line is not the good line
1962  if (!aLine) {
1963 
1964  // try to find the same line
1965  TTScriptPtr(aScript.instance())->mFlattenedLines->find(&TTScriptFindTarget, (TTPtr)&firstAdrs, found);
1966 
1967  // couldn't find the same node in the script :
1968  // look into to next script for this command
1969  if (found.empty()) {
1970  TTScriptPtr(aScript.instance())->mFlattenedLines->begin();
1971  continue;
1972  }
1973  else
1974  aLine = TTDictionaryBasePtr((TTPtr)found[0]);
1975  }
1976 
1977  // if a line have been found
1978  if (aLine) {
1979 
1980  // mix the command of this script
1981  // TODO : introduce a mixWeight information into command lines
1982  sumFactors += TTScriptMixLine(aLine, type, mixSize, TTFloat64(factors[i]), mixedValue, NO);
1983 
1984  TTScriptPtr(aScript.instance())->mFlattenedLines->next();
1985  }
1986  }
1987 
1988  // prepare and send the mixed value
1989  if (sumFactors > 0) {
1990 
1991  // if numeric : normalise by sum of mixWeight
1992  if (type == kTTSym_integer)
1993  mixedValue[0] = TTInt32(mixedValue[0]) / sumFactors + 1; // +1 because the value is truncate in TTData::setValue
1994 
1995  else if (type == kTTSym_decimal)
1996  mixedValue[0] = TTFloat64(mixedValue[0]) / sumFactors;
1997 
1998  else if (type == kTTSym_array)
1999  for (TTUInt32 i = 0; i < mixedValue.size(); i++)
2000  mixedValue[i] = TTFloat64(mixedValue[i]) / sumFactors;
2001  // for any other type : remove the coef at the end of the value
2002  else
2003  mixedValue.resize(mixedValue.size()-1);
2004 
2005  // set the mixed value
2006  anObject.set(kTTSym_value, mixedValue);
2007  }
2008  }
2009  }
2010  }
2011  }
2012 
2013  return kTTErrNone;
2014 }
2015 
2016 TTFloat64 TTScriptMixLine(TTDictionaryBasePtr lineToMix, TTSymbol dataType, TTUInt32 mixSize, TTFloat64 factor, TTValue& mixedValue, TTBoolean init)
2017 {
2018  TTUInt32 i, s;
2019  TTFloat64 mixWeight = 1.; // TODO : introduce a mixWeight information into command lines
2020  TTValue valueToMix;
2021 
2022  lineToMix->getValue(valueToMix);
2023 
2024  if (init) {
2025  mixedValue.clear();
2026  for (i = 0; i < valueToMix.size(); i++)
2027  mixedValue.append(0);
2028  }
2029 
2030  if (dataType == kTTSym_integer)
2031  mixedValue[0] = TTInt32(mixedValue[0]) + (TTInt32(valueToMix[0]) * factor * mixWeight);
2032 
2033  else if (dataType == kTTSym_decimal)
2034  mixedValue[0] = TTFloat64(mixedValue[0]) + (TTFloat64(valueToMix[0]) * factor * mixWeight);
2035 
2036  else if (dataType == kTTSym_array) {
2037 
2038  s = valueToMix.size();
2039  if (s == mixedValue.size()) {
2040 
2041  for (i = 0; i < s; i++)
2042  mixedValue[i] = TTFloat64(mixedValue[i]) + (TTFloat64(valueToMix[i]) * factor * mixWeight);
2043  }
2044  }
2045  // for any other type : store the coef at the end of the value to keep only the max coef
2046  else {
2047 
2048  if (init) mixedValue.append((TTFloat64)0.);
2049 
2050  if (factor * mixWeight >= TTFloat64(mixedValue[mixedValue.size()-1])) {
2051 
2052  mixedValue = valueToMix;
2053  mixedValue.append((TTFloat64) factor * mixWeight);
2054  }
2055  }
2056 
2057  return factor * mixWeight;
2058 }
2059 
2060 TTErr TTScriptMerge(TTObject scriptToMerge, TTObject mergedScript)
2061 {
2062  TTDictionaryBasePtr lineToMerge, mergedLine;
2063  TTObject subScriptToMerge, mergedSubScript;
2064  TTAddress addressToMerged, mergedAddress;
2065  TTValue v, valueToMerged, mergedValue, found, parsedLine;
2066  TTBoolean merged = NO; // to know if a line have already been merged
2067  TTErr err;
2068 
2069  if (TTScriptPtr(scriptToMerge.instance())->mLines->isEmpty())
2070  return kTTErrGeneric;
2071 
2072  for (TTScriptPtr(scriptToMerge.instance())->mLines->begin(); TTScriptPtr(scriptToMerge.instance())->mLines->end(); TTScriptPtr(scriptToMerge.instance())->mLines->next()) {
2073 
2074  lineToMerge = TTDictionaryBasePtr((TTPtr)TTScriptPtr(scriptToMerge.instance())->mLines->current()[0]);
2075 
2076  // get address
2077  addressToMerged = kTTAdrsEmpty;
2078  if (!lineToMerge->lookup(kTTSym_address, v))
2079  addressToMerged = v[0];
2080 
2081  if (addressToMerged != kTTAdrsEmpty) {
2082 
2083  // try to find a line for this address into the merged script
2084  merged = NO;
2085  if (!TTScriptPtr(mergedScript.instance())->mLines->isEmpty()) {
2086 
2087  TTScriptPtr(mergedScript.instance())->mLines->find(&TTScriptFindAddress, (TTPtr)&addressToMerged, found);
2088 
2089  if (!(found.empty())) {
2090  mergedLine = TTDictionaryBasePtr((TTPtr)found[0]);
2091  merged = YES;
2092  }
2093  }
2094 
2095  // merge a line depending on his schema
2096  if (lineToMerge->getSchema() == kTTSym_command) {
2097 
2098  // if this script line haven't been merged yet
2099  if (!merged) {
2100  // copy the command line and append it to the merged script
2101  v = TTValue((TTPtr)TTScriptCopyLine(lineToMerge));
2102  TTScriptPtr(mergedScript.instance())->Append(v, parsedLine);
2103  }
2104  else {
2105  // get lines value
2106  lineToMerge->getValue(valueToMerged);
2107  mergedLine->getValue(mergedValue);
2108 
2109  // don't merge a command if it already exists
2110  if (valueToMerged == mergedValue)
2111  continue;
2112 
2113  // otherwise replace by the value to merge
2114  mergedLine->setValue(valueToMerged);
2115  }
2116  }
2117  else if (lineToMerge->getSchema() == kTTSym_script) {
2118 
2119  // get the sub scripts
2120  if (!lineToMerge->getValue(v))
2121  subScriptToMerge = v[0];
2122 
2123  // if this script line haven't been merged yet
2124  if (!merged)
2125  // create a line for the merged sub script
2126  mergedLine = TTScriptParseScript(addressToMerged);
2127 
2128  // get the new sub script
2129  if (!mergedLine->getValue(v))
2130  mergedSubScript = v[0];
2131 
2132  // merge the sub scripts if they exist
2133  if (subScriptToMerge.valid() && mergedSubScript.valid()) {
2134 
2135  err = TTScriptMerge(subScriptToMerge, mergedSubScript);
2136 
2137  // if this script line haven't been merged yet
2138  if (!merged) {
2139 
2140  // append the line to the merged script
2141  TTScriptPtr(mergedScript.instance())->Append((TTPtr)mergedLine, parsedLine);
2142  }
2143  }
2144  }
2145  }
2146  // else copy the line and append it to the merged script
2147  else {
2148  TTScriptPtr(mergedScript.instance())->Append((TTPtr)TTScriptCopyLine(lineToMerge), parsedLine);
2149  }
2150  }
2151 
2152  return kTTErrNone;
2153 }
2154 
2155 TTErr TTScriptOptimize(TTObject aScriptToOptimize, TTObject aScript, TTObject optimizedScript)
2156 {
2157  TTDictionaryBasePtr lineToOptimize, aLine, optimizedLine;
2158  TTObject subScriptToOptimize, aSubScript, optimizedSubScript;
2159  TTAddress addressToOptimize, address;
2160  TTValue v, valueToOptimize, value, found, parsedLine;
2161  TTBoolean empty = YES; // to know if the optimized script contains at least one command
2162  TTErr err;
2163 
2164  if (TTScriptPtr(aScriptToOptimize.instance())->mLines->isEmpty() || TTScriptPtr(aScript.instance())->mLines->isEmpty())
2165  return kTTErrGeneric;
2166 
2167  for (TTScriptPtr(aScriptToOptimize.instance())->mLines->begin(), TTScriptPtr(aScript.instance())->mLines->begin();
2168  TTScriptPtr(aScriptToOptimize.instance())->mLines->end();
2169  TTScriptPtr(aScriptToOptimize.instance())->mLines->next(), TTScriptPtr(aScript.instance())->mLines->next())
2170  {
2171  addressToOptimize = kTTAdrsEmpty;
2172  lineToOptimize = TTDictionaryBasePtr((TTPtr)TTScriptPtr(aScriptToOptimize.instance())->mLines->current()[0]);
2173 
2174  if (!lineToOptimize->lookup(kTTSym_address, v))
2175  addressToOptimize = v[0];
2176 
2177  address = kTTAdrsEmpty;
2178  if (TTScriptPtr(aScript.instance())->mLines->end())
2179  {
2180  aLine = TTDictionaryBasePtr((TTPtr)TTScriptPtr(aScript.instance())->mLines->current()[0]);
2181  if (!aLine->lookup(kTTSym_address, v))
2182  address = v[0];
2183  }
2184 
2185  if (addressToOptimize != kTTAdrsEmpty)
2186  {
2187  // the both addresses have to be the same
2188  if (addressToOptimize != address)
2189  {
2190  TTScriptPtr(aScript.instance())->mLines->find(&TTScriptFindAddress, (TTPtr)&addressToOptimize, found);
2191 
2192  // couldn't find the same address in the script : copy the line and append it to the optimized script
2193  if (found.empty())
2194  {
2195  TTScriptPtr(optimizedScript.instance())->Append((TTPtr)TTScriptCopyLine(lineToOptimize), parsedLine);
2196  continue;
2197  }
2198  else
2199  aLine = TTDictionaryBasePtr((TTPtr)found[0]);
2200  }
2201 
2202  // optimize the line depending on the schema
2203  if (lineToOptimize->getSchema() == kTTSym_command && aLine->getSchema() == kTTSym_command)
2204  {
2205  // get line values
2206  lineToOptimize->getValue(valueToOptimize);
2207  aLine->getValue(value);
2208 
2209  // don't copy a command if it already exists
2210  if (valueToOptimize == value)
2211  continue;
2212 
2213  // copy the command line and append it to the optimized script
2214  TTScriptPtr(optimizedScript.instance())->Append((TTPtr)TTScriptCopyLine(lineToOptimize), parsedLine);
2215 
2216  // the optimized script contains at least one command line now
2217  empty = NO;
2218  }
2219  else if (lineToOptimize->getSchema() == kTTSym_script && aLine->getSchema() == kTTSym_script)
2220  {
2221  // get the sub scripts
2222  if (!lineToOptimize->getValue(v))
2223  subScriptToOptimize = v[0];
2224 
2225  if (!aLine->getValue(v))
2226  aSubScript = v[0];
2227 
2228  // optimize the sub scripts if they exist
2229  if (subScriptToOptimize.valid() && aSubScript.valid())
2230  {
2231  // create a line for the optimized sub script
2232  optimizedLine = TTScriptParseScript(addressToOptimize);
2233 
2234  // get the new sub script
2235  optimizedLine->getValue(v);
2236  optimizedSubScript = v[0];
2237 
2238  err = TTScriptOptimize(subScriptToOptimize, aSubScript, optimizedSubScript);
2239 
2240  // if no error occurs during th optimization of the sub script
2241  if (!err)
2242  {
2243  // copy the script line and append it to the optimized script
2244  TTScriptPtr(optimizedScript.instance())->Append((TTPtr)optimizedLine, parsedLine);
2245 
2246  // the optimized script contains at least one command line now
2247  empty = NO;
2248  }
2249  else
2250  {
2251  // delete the line
2252  delete optimizedLine;
2253  }
2254  }
2255  }
2256  }
2257  // else copy the line and append it to the optimized script
2258  else
2259  TTScriptPtr(optimizedScript.instance())->Append((TTPtr)TTScriptCopyLine(lineToOptimize), parsedLine);
2260 
2261  }
2262 
2263  if (empty)
2264  return kTTErrGeneric;
2265 
2266  return kTTErrNone;
2267 }
2268 
2269 TTErr TTScriptCopy(TTObject scriptTocopy, TTObject aScriptCopy)
2270 {
2271  TTObject aSubScriptToCopy, aSubScriptCopy;
2272  TTDictionaryBasePtr aLine, aLineCopy;
2273  TTValue v, args;
2274 
2275  // copy each line of the script
2276  for (TTScriptPtr(scriptTocopy.instance())->mLines->begin(); TTScriptPtr(scriptTocopy.instance())->mLines->end(); TTScriptPtr(scriptTocopy.instance())->mLines->next()) {
2277 
2278  aLine = TTDictionaryBasePtr((TTPtr)TTScriptPtr(scriptTocopy.instance())->mLines->current()[0]);
2279 
2280  aLineCopy = TTScriptCopyLine(aLine);
2281 
2282  if (aLineCopy->getSchema() == kTTSym_script) {
2283 
2284  // get the subscript
2285  aLineCopy->getValue(v);
2286  aSubScriptToCopy = v[0];
2287 
2288  // create a subscript copy
2289  aSubScriptCopy = TTObject(kTTSym_Script, TTScriptPtr(scriptTocopy.instance())->mReturnLineCallback);
2290 
2291  // copy the subscript into
2292  TTScriptCopy(aSubScriptToCopy, aSubScriptCopy);
2293 
2294  aLineCopy->setValue(aSubScriptCopy);
2295  }
2296 
2297  TTScriptPtr(aScriptCopy.instance())->mLines->append(aLineCopy);
2298  }
2299 
2300  return kTTErrNone;
2301 }
2302 
2303 void TTScriptFindAddress(const TTValue& lineValue, TTPtr addressPtrToMatch, TTBoolean& found)
2304 {
2305  TTDictionaryBasePtr aLine;
2306  TTAddress address;
2307  TTValue v;
2308 
2309  aLine = TTDictionaryBasePtr((TTPtr)lineValue[0]);
2310 
2311  if (!aLine->lookup(kTTSym_address, v))
2312  address = v[0];
2313 
2314  found = address == *((TTAddress*)addressPtrToMatch);
2315 }
2316 
2317 void TTScriptFindTarget(const TTValue& lineValue, TTPtr addressPtrToMatch, TTBoolean& found)
2318 {
2319  TTDictionaryBasePtr aLine;
2320  TTAddress address;
2321  TTValue v;
2322 
2323  aLine = TTDictionaryBasePtr((TTPtr)lineValue[0]);
2324 
2325  if (!aLine->lookup(kTTSym_target, v))
2326  address = v[0];
2327 
2328  found = address == *((TTAddress*)addressPtrToMatch);
2329 }
2330 
2331 TTDictionaryBasePtr TTScriptCopyLine(TTDictionaryBasePtr lineTocopy)
2332 {
2333  TTValue v;
2334  //TTValue keys, v;
2335  //TTSymbol key;
2336  //TTUInt32 i;
2337 
2338  TTDictionaryBasePtr newLine = new TTDictionaryBase();
2339 
2340  /* TTDictionary::getKeys is broken
2341  lineTocopy->getKeys(keys);
2342  for (i = 0; i < keys.size(); i++) {
2343  key = keys[i];
2344  lineTocopy->lookup(key, v);
2345  newLine->append(key, v);
2346  }
2347  */
2348 
2349  if (!lineTocopy->lookup(kTTSym_schema, v))
2350  newLine->append(kTTSym_schema, v);
2351 
2352  if (!lineTocopy->lookup(kTTSym_value, v))
2353  newLine->append(kTTSym_value, v);
2354 
2355  if (!lineTocopy->lookup(kTTSym_name, v))
2356  newLine->append(kTTSym_name, v);
2357 
2358  if (!lineTocopy->lookup(kTTSym_address, v))
2359  newLine->append(kTTSym_address, v);
2360 
2361  if (!lineTocopy->lookup(kTTSym_unit, v))
2362  newLine->append(kTTSym_unit, v);
2363 
2364  if (!lineTocopy->lookup(kTTSym_ramp, v))
2365  newLine->append(kTTSym_address, v);
2366 
2367  return newLine;
2368 }
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 setSchema(const TTSymbol schemaName)
TODO: Add documentation schemaName TODO: Add documentation.
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.
TTValue mXmlNodeValue
the Node value being read by the Reader
Definition: TTXmlHandler.h:68
TTErr send(const TTSymbol aName)
Send a message to this object with no arguments.
Definition: TTObject.cpp:135
TTString toString(TTBoolean quotes=YES) const
Return the content as a single string with spaces between elements.
Definition: TTValue.h:351
#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.
void copyFrom(const TTValue &obj, TTUInt16 index)
Copy a value starting from an index until the last element.
Definition: TTValue.h:147
Object type.
Definition: TTBase.h:283
TTErr setValue(const TTValue &newValue)
TODO: Add documentation.
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
TTErr getXmlAttribute(TTSymbol attributeName, TTValue &returnedValue, TTBoolean addQuote=NO, TTBoolean numberAsSymbol=NO)
Get the value of an xml element attribute.
TTObject & getObject()
Get the object binded by this node.
Definition: TTNode.cpp:468
size_type size() const noexcept
Return the number of elements.
this flag means that an address have no leading slash
Definition: TTAddressBase.h:64
About line schemas :
Definition: TTScript.h:40
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.
TTSymbol name() const
Return the name of this class.
Definition: TTObject.cpp:129
this flag means that address1 an address2 refer to the same node in the tree structure ...
Definition: TTAddressBase.h:48
#define addAttributeProperty(attributeName, propertyName, initialValue)
A convenience macro to be used for registering properties of attributes.
Definition: TTAttribute.h:68
TTErr set(const TTSymbol aName, T aValue)
Set an attribute value for an object.
TTErr getXmlNextAttribute(TTSymbol &returnedAttributeName, TTValue &returnedValue, TTBoolean addQuote=NO, TTBoolean numberAsSymbol=NO)
Get the value of the next xml element attribute.
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
Boolean (1/0) or (true/false) flag.
Definition: TTBase.h:281
TTDictionaryBasePtr TTMODULAR_EXPORT TTDataParseCommand(const TTValue &commandValue, TTBoolean parseUnitAndRamp=YES)
Format the command to update the value of TTData as a TTDictionary.
Definition: TTData.cpp:703
TTSymbol & getAttribute()
Get the attribute part.
Definition: TTAddress.h:130
this flag means that an address have a leading slash
Definition: TTAddressBase.h:65
#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
std::int32_t TTInt32
32 bit signed integer
Definition: TTBase.h:177
void clear()
Clear all values from the vector, leaving with size of 0.
Definition: TTValue.h:131
TTAddressComparisonFlag
Comparison flags between address returned by address1->compare(address2).
Definition: TTAddressBase.h:45
this flag means that address1 refers to a node at a upper level than address2 in the tree structure ...
Definition: TTAddressBase.h:49
32-bit signed integer, range is -2,147,483,648 through 2,147,483,647.
Definition: TTBase.h:277
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.
signed char TTInt8
8 bit signed integer (char)
Definition: TTBase.h:173
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
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
Write / Read mecanism.
Definition: TTXmlHandler.h:48
TTObjectBase * instance() const
Return a direct pointer to the internal instance.
Definition: TTObject.cpp:105
A Script Object.
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
TTBoolean valid() const
Determine if the object contained by this TTObject is truly ready for use.
Definition: TTObject.cpp:179
void resize(size_type n)
Change the number of elements.
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 getTTNode(const char *anAddress, TTNodePtr *returnedTTNode)
Given an address, return a pointer to a TTNode.
unsigned char TTUInt8
8 bit unsigned integer (char)
Definition: TTBase.h:174
TTErr getValue(TTValue &returnedValue) const
TODO: Add documentation.
#define addMessageProperty(messageName, propertyName, initialValue)
A convenience macro to be used for registering properties of messages.
Definition: TTMessage.h:37