Jamoma API  0.6.0.a19
TTPresetManager.cpp
Go to the documentation of this file.
1 /** @file
2  *
3  * @ingroup modularLibrary
4  *
5  * @brief A PresetManager 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 "TTPresetManager.h"
18 #include <libxml/encoding.h>
19 #include <libxml/xmlwriter.h>
20 #include <libxml/xmlreader.h>
21 
22 #define thisTTClass TTPresetManager
23 #define thisTTClassName "PresetManager"
24 #define thisTTClassTags "preset, manager"
25 
26 TT_MODULAR_CONSTRUCTOR,
27 mAddress(kTTAdrsEmpty),
28 mCurrent(kTTSymEmpty),
29 mCurrentPosition(0)
30 {
31  if (arguments.size() == 1)
32  mReturnLineCallback = arguments[0];
33 
34  registerAttribute(TTSymbol("value"), kTypeLocalValue, NULL, (TTGetterMethod)&TTPresetManager::getValue, (TTSetterMethod)&TTPresetManager::setValue);
35 
37 
39  addAttributeProperty(Names, readOnly, YES);
40 
41  addAttribute(Current, kTypeSymbol);
42  addAttributeProperty(Current, readOnly, YES);
43 
44  addAttribute(CurrentPosition, kTypeUInt32);
45  addAttributeProperty(CurrentPosition, readOnly, YES);
46 
48  addAttributeProperty(Presets, readOnly, YES);
49  addAttributeProperty(Presets, hidden, YES);
50 
51  addMessage(Clear);
52 
57  addMessageWithArguments(Interpolate);
64 
65  // needed to be handled by a TTXmlHandler
66  addMessageWithArguments(WriteAsXml);
67  addMessageProperty(WriteAsXml, hidden, YES);
68  addMessageWithArguments(ReadFromXml);
69  addMessageProperty(ReadFromXml, hidden, YES);
70 
71  // needed to be handled by a TTTextHandler
72  addMessageWithArguments(WriteAsText);
73  addMessageProperty(WriteAsText, hidden, YES);
74  addMessageWithArguments(ReadFromText);
75  addMessageProperty(ReadFromText, hidden, YES);
76 }
77 
78 TTPresetManager::~TTPresetManager()
79 {
80  ;
81 }
82 
83 TTErr TTPresetManager::getPresets(TTValue& value)
84 {
85  value = TTPtr(&mPresets);
86  return kTTErrNone;
87 }
88 
89 TTErr TTPresetManager::setAddress(const TTValue& value)
90 {
91  Clear();
92 
93  mAddress = value[0];
94 
95  return kTTErrNone;
96 }
97 
98 TTErr TTPresetManager::getValue(TTValue& value)
99 {
100  value = mCurrentPosition+1;
101  value.append(mCurrent);
102 
103  return kTTErrNone;
104 }
105 
106 TTErr TTPresetManager::setValue(const TTValue& value)
107 {
108  TTValue outputValue;
109 
110  return Recall(value, outputValue);
111 }
112 
113 TTErr TTPresetManager::Clear()
114 {
115  mPresets.clear();
116  mCurrentPreset = TTObject();
117  mCurrent = kTTSymEmpty;
118  mCurrentPosition = 0;
119  mNames.clear();
120 
121  notifyNamesObservers();
122  notifyValueObservers();
123 
124  return kTTErrNone;
125 }
126 
127 TTErr TTPresetManager::New(const TTValue& inputValue, TTValue& outputValue)
128 {
129  TTValue v, out;
130  TTErr err;
131 
132  // get preset name
133  if (inputValue.size() == 1)
134  if (inputValue[0].type() == kTypeSymbol)
135  mCurrent = inputValue[0];
136 
137  // get preset position and name
138  if (inputValue.size() == 2)
139  if (inputValue[1].type() == kTypeSymbol)
140  mCurrent = inputValue[1];
141 
142  if (mCurrent == kTTSymEmpty)
143  return kTTErrGeneric;
144 
145  // don't create two presets with the same name
146  if (mPresets.lookup(mCurrent, v)) {
147 
148  // Create a new preset
149  mCurrentPreset = TTObject(kTTSym_Preset, mReturnLineCallback);
150 
151  mCurrentPreset.set(kTTSym_address, mAddress);
152  mCurrentPreset.set(kTTSym_name, mCurrent);
153 
154  // Append the new preset
155  mPresets.append(mCurrent, mCurrentPreset);
156  mNames.append(mCurrent);
157  mCurrentPosition = mNames.size();
158 
159  notifyNamesObservers();
160  notifyValueObservers();
161  }
162  else {
163  mCurrentPreset = v[0];
164  mCurrentPreset.send("Clear");
165  }
166 
167  err = mCurrentPreset.send("Store");
168 
169  // Move the preset at position
170  if (inputValue.size() == 2) {
171 
172  v = mCurrent;
173  v.append(inputValue[0]);
174 
175  err = Move(v, out);
176  }
177 
178  return err;
179 }
180 
181 TTErr TTPresetManager::Update(const TTValue& inputValue, TTValue& outputValue)
182 {
183  TTValue v, none;
184 
185  if (inputValue.size() >= 1) {
186 
187  // get cue name
188  if (inputValue[0].type() == kTypeSymbol) {
189  mCurrent = inputValue[0];
190 
191  TTSymbol name;
192  // TODO refactor this code : it is everywhere in this file.
193  for (TTUInt32 i = 0; i < mNames.size(); i++) {
194  name = mNames[i];
195  if (name == mCurrent) {
196  mCurrentPosition = i+1;
197  break;
198  }
199  }
200  }
201 
202  // get cue at position
203  if (inputValue[0].type() == kTypeInt32) {
204 
205  mCurrentPosition = inputValue[0];
206 
207  if (mCurrentPosition > 0 && mCurrentPosition <= mNames.size())
208  mCurrent = mNames[mCurrentPosition-1];
209  else
210  return kTTErrGeneric;
211  }
212  }
213 
214  // if preset exists
215  if (!mPresets.lookup(mCurrent, v)) {
216 
217  mCurrentPreset = v[0];
218 
219  if (mCurrentPreset.valid())
220  return mCurrentPreset.send(kTTSym_Update);
221  }
222 
223  return kTTErrGeneric;
224 }
225 
226 TTErr TTPresetManager::Recall(const TTValue& inputValue, TTValue& outputValue)
227 {
228  TTValue v, none;
229  TTAddress anAddress = kTTAdrsRoot;
230  TTErr err;
231 
232  if (inputValue.size() == 1) {
233 
234  // get preset name
235  if (inputValue[0].type() == kTypeSymbol) {
236  mCurrent = inputValue[0];
237 
238  TTSymbol name;
239  for (TTUInt32 i = 0; i < mNames.size(); i++) {
240  name = mNames[i];
241  if (name == mCurrent) {
242  mCurrentPosition = i+1;
243  break;
244  }
245  }
246  }
247 
248  // get preset at position
249  if (inputValue[0].type() == kTypeInt32) {
250 
251  mCurrentPosition = inputValue[0];
252 
253  if (mCurrentPosition > 0 && mCurrentPosition <= mNames.size())
254  mCurrent = mNames[mCurrentPosition-1];
255  else
256  return kTTErrGeneric;
257  }
258  }
259 
260  // get address from where recall starts (default : kAdrsRoot)
261  if (inputValue.size() == 2)
262  if (inputValue[1].type() == kTypeSymbol)
263  anAddress = inputValue[1];
264 
265  // if preset exists
266  if (!mPresets.lookup(mCurrent, v)) {
267 
268  mCurrentPreset = v[0];
269 
270  err = mCurrentPreset.send(kTTSym_Recall, mAddress.appendAddress(anAddress));
271 
272  notifyValueObservers();
273 
274  return err;
275  }
276 
277  return kTTErrGeneric;
278 }
279 
280 TTErr TTPresetManager::Output(const TTValue& inputValue, TTValue& outputValue)
281 {
282  TTValue v, none;
283  TTAddress anAddress = kTTAdrsRoot;
284  TTErr err;
285 
286  if (inputValue.size() >= 1) {
287 
288  // get preset name
289  if (inputValue[0].type() == kTypeSymbol) {
290  mCurrent = inputValue[0];
291 
292  TTSymbol name;
293  for (TTUInt32 i = 0; i < mNames.size(); i++) {
294  name = mNames[i];
295  if (name == mCurrent) {
296  mCurrentPosition = i+1;
297  break;
298  }
299  }
300  }
301 
302  // get preset at position
303  if (inputValue[0].type() == kTypeInt32) {
304 
305  mCurrentPosition = inputValue[0];
306 
307  if (mCurrentPosition > 0 && mCurrentPosition <= mNames.size())
308  mCurrent = mNames[mCurrentPosition-1];
309  else
310  return kTTErrGeneric;
311  }
312  }
313 
314  // get address from where recall starts
315  if (inputValue.size() == 2)
316  if (inputValue[1].type() == kTypeSymbol)
317  anAddress = inputValue[1];
318 
319  // if preset exists
320  if (!mPresets.lookup(mCurrent, v)) {
321 
322  mCurrentPreset = v[0];
323 
324  err = mCurrentPreset.send("Output", mAddress.appendAddress(anAddress));
325 
326  notifyValueObservers();
327 
328  return err;
329  }
330 
331  return kTTErrGeneric;
332 }
333 
334 TTErr TTPresetManager::Interpolate(const TTValue& inputValue, TTValue& outputValue)
335 {
336  TTValue v1, v2;
337  TTInt32 i1, i2;
338  TTSymbol name1, name2;
339  TTObject preset1, preset2;
340  TTFloat32 position;
341 
342  if (inputValue.size() == 3) {
343 
344  // get presets by name
345  if (inputValue[0].type() == kTypeSymbol && inputValue[1].type() == kTypeSymbol && inputValue[2].type() == kTypeFloat64) {
346 
347  name1 = inputValue[0];
348  name2 = inputValue[1];
349  position = inputValue[2];
350  }
351 
352  // get presets by position
353  else if (inputValue[0].type() == kTypeInt32 && inputValue[1].type() == kTypeInt32 && inputValue[2].type() == kTypeFloat64) {
354 
355  i1 = inputValue[0] ;
356  if (i1 > 0 && i1 <= (TTInt32) mNames.size())
357  name1 = mNames[i1-1];
358  else
359  return kTTErrGeneric;
360 
361  i2 = inputValue[1];
362  if (i2 > 0 && i2 <= (TTInt32) mNames.size())
363  name2 = mNames[i2-1];
364  else
365  return kTTErrGeneric;
366 
367  position = inputValue[2];
368  }
369 
370  // if presets exist
371  if (!mPresets.lookup(name1, v1) && !mPresets.lookup(name2, v2)) {
372 
373  preset1 = v1[0];
374  preset2 = v2[0];
375 
376  return TTPresetInterpolate(preset1, preset2, position);
377  }
378  }
379 
380  return kTTErrGeneric;
381 }
382 
383 TTErr TTPresetManager::Mix(const TTValue& inputValue, TTValue& outputValue)
384 {
385  TTInt32 i, id, mixSize;
386  TTSymbol name;
387  TTObject preset;
388  TTValue v, presets, factors;
389 
390  mixSize = inputValue.size() / 2;
391  if (inputValue.size() != mixSize * 2)
392  return kTTErrGeneric;
393 
394  for (i = 0; i < mixSize * 2; i = i+2) {
395 
396  if (inputValue[i].type() == kTypeSymbol && inputValue[i+1].type() == kTypeFloat64) {
397 
398  name = inputValue[i] ;
399  }
400  else if (inputValue[i].type() == kTypeInt32 && inputValue[i+1].type() == kTypeFloat64) {
401 
402  id = inputValue[i];
403  if (id > 0 && id <= (TTInt32) mNames.size())
404  name = mNames[id-1];
405  else
406  return kTTErrGeneric;
407  }
408 
409  // if preset exist
410  if (!mPresets.lookup(name, v)) {
411 
412  preset = v[0];
413 
414  presets.append(preset);
415  factors.append(TTFloat64(inputValue[i+1]));
416  }
417  }
418 
419  return TTPresetMix(presets, factors);
420 }
421 
422 TTErr TTPresetManager::Move(const TTValue& inputValue, TTValue& outputValue)
423 {
424  TTList temp;
425  TTSymbol name;
426  TTUInt32 i, newPosition = 0;
427  TTValue v;
428 
429  if (inputValue.size() >= 1) {
430 
431  // get preset name
432  if (inputValue[0].type() == kTypeSymbol)
433  mCurrent = inputValue[0];
434 
435  // get preset at position
436  if (inputValue[0].type() == kTypeInt32) {
437 
438  mCurrentPosition = inputValue[0];
439 
440  if (mCurrentPosition > 0 && mCurrentPosition <= mNames.size())
441  mCurrent = mNames[mCurrentPosition-1];
442  else
443  return kTTErrGeneric;
444  }
445  }
446 
447  // get new position
448  if (inputValue.size() == 2)
449  if (inputValue[1].type() == kTypeInt32)
450  newPosition = inputValue[1] ;
451 
452  if (newPosition < 1 || newPosition > mNames.size())
453  return kTTErrGeneric;
454 
455  // if preset exists
456  if (!mPresets.lookup(mCurrent, v)) {
457 
458  mCurrentPreset = v[0];
459 
460  // copy all the mNames names into a TTList
461  // except the mCurrent
462  for (i = 0; i < mNames.size(); i++) {
463  name = mNames[i];
464 
465  if (name == mCurrent)
466  continue;
467 
468  v = TTValue(name);
469  temp.append(v);
470  }
471 
472  // insert the mCurrent
473  v = TTValue(mCurrent);
474  temp.insert(newPosition-1, v);
475  mNames.clear();
476 
477  // copy the TTList names into a newNames
478  for (temp.begin(); temp.end(); temp.next()) {
479  name = temp.current()[0];
480  mNames.append(name);
481  }
482 
483  mCurrentPosition = newPosition;
484 
485  notifyNamesObservers();
486  notifyValueObservers();
487 
488  return kTTErrNone;
489  }
490 
491  return kTTErrGeneric;
492 }
493 
494 TTErr TTPresetManager::Delete(const TTValue& inputValue, TTValue& outputValue)
495 {
496  TTSymbol name;
497  TTValue v, newNames;
498 
499  if (inputValue.size() == 1) {
500 
501  // get preset name
502  if (inputValue[0].type() == kTypeSymbol)
503  mCurrent = inputValue[0];
504 
505  // get preset at position
506  if (inputValue[0].type() == kTypeInt32) {
507 
508  mCurrentPosition = inputValue[0];
509 
510  if (mCurrentPosition > 0 && mCurrentPosition <= mNames.size())
511  mCurrent = mNames[mCurrentPosition-1];
512  else
513  return kTTErrGeneric;
514  }
515  }
516 
517  // if preset exists
518  if (!mPresets.lookup(mCurrent, v)) {
519 
520  mPresets.remove(mCurrent);
521 
522  // remove the name without changing the order
523  for (TTUInt32 i = 0; i < mNames.size(); i++) {
524 
525  name = mNames[i];
526 
527  if (name != mCurrent)
528  newNames.append(name);
529  }
530 
531  mCurrentPreset = TTObject();
532  mCurrent = kTTSymEmpty;
533  mCurrentPosition = 0;
534  mNames = newNames;
535 
536  notifyNamesObservers();
537  notifyValueObservers();
538 
539  return kTTErrNone;
540  }
541 
542  return kTTErrGeneric;
543 }
544 
545 
546 TTErr TTPresetManager::Order(const TTValue& inputValue, TTValue& outputValue)
547 {
548  TTSymbol name;
549  TTValue v, newNames;
550 
551  // check if each name is part of the list
552  for (TTUInt32 i = 0; i < inputValue.size(); i++) {
553 
554  name = inputValue[i];
555 
556  if (!mPresets.lookup(name, v))
557  newNames.append(name);
558 
559  // update current position
560  if (name == mCurrent)
561  mCurrentPosition = i;
562  }
563 
564  // if the newNames size is not equal to the current name list
565  if (newNames.size() != mNames.size())
566  return kTTErrGeneric;
567 
568  mNames = newNames;
569 
570  notifyNamesObservers();
571 
572  return kTTErrNone;
573 }
574 
575 TTErr TTPresetManager::Rename(const TTValue& inputValue, TTValue& outputValue)
576 {
577  TTSymbol name, newName;
578  TTUInt32 i;
579  TTValue v;
580 
581  if (inputValue.size() >= 1) {
582 
583  // get preset name
584  if (inputValue[0].type() == kTypeSymbol)
585  mCurrent = inputValue[0];
586 
587  // get preset at position
588  if (inputValue[0].type() == kTypeInt32) {
589 
590  mCurrentPosition = inputValue[0];
591 
592  if (mCurrentPosition > 0 && mCurrentPosition <= mNames.size())
593  mCurrent = mNames[mCurrentPosition-1];
594  else
595  return kTTErrGeneric;
596  }
597  }
598 
599  // get new name
600  if (inputValue.size() == 2)
601  if (inputValue[1].type() == kTypeSymbol)
602  newName = inputValue[1] ;
603 
604  if (newName == kTTSymEmpty)
605  return kTTErrGeneric;
606 
607  // if preset exists
608  if (!mPresets.lookup(mCurrent, v)) {
609 
610  mCurrentPreset = v[0];
611 
612  // replace the name in the hash table
613  mPresets.remove(mCurrent);
614  mPresets.append(newName, v);
615 
616  mCurrentPreset.set(kTTSym_name, newName);
617 
618  // replace the name in the order
619  for (i = 0; i < mNames.size(); i++) {
620 
621  name = mNames[i];
622 
623  if (name == mCurrent) {
624  mNames[i] = newName;
625  break;
626  }
627  }
628 
629  mCurrent = newName;
630  mCurrentPosition = i+1;
631 
632  notifyNamesObservers();
633  notifyValueObservers();
634 
635  return kTTErrNone;
636  }
637 
638  return kTTErrGeneric;
639 }
640 
641 TTErr TTPresetManager::Copy(const TTValue& inputValue, TTValue& outputValue)
642 {
643  TTObject aPresetCopy;
644  TTSymbol nameCopy;
645  TTString s;
646  TTInt32 positionCopy;
647  TTValue v, args, none;
648 
649  if (inputValue.size() >= 1) {
650 
651  // get preset name
652  if (inputValue[0].type() == kTypeSymbol)
653  mCurrent = inputValue[0];
654 
655  // get preset at position
656  if (inputValue[0].type() == kTypeInt32) {
657 
658  mCurrentPosition = inputValue[0];
659 
660  if (mCurrentPosition > 0 && mCurrentPosition <= mNames.size())
661  mCurrent = mNames[mCurrentPosition-1];
662  else
663  return kTTErrGeneric;
664  }
665  }
666 
667  // if preset exists
668  if (!mPresets.lookup(mCurrent, v)) {
669 
670  mCurrentPreset = v[0];
671 
672  // create a new preset
673  aPresetCopy = TTObject(kTTSym_Preset, mReturnLineCallback);
674 
675  // copy the current preset into
676  TTPresetCopy(mCurrentPreset, aPresetCopy);
677 
678  // maybe there is a name for the copy
679  if (inputValue.size() >= 2) {
680 
681  if (inputValue[1].type() == kTypeSymbol)
682  nameCopy = inputValue[1] ;
683 
684  }
685  else {
686  // edit a name copy : current cue name - copy
687  s = mCurrent.c_str();
688  s += " - copy";
689  nameCopy = TTSymbol(s.data());
690  }
691 
692  // rename the copy
693  aPresetCopy.set(kTTSym_name, nameCopy);
694 
695  // append the copy
696  v = TTValue(aPresetCopy);
697  mPresets.append(nameCopy, v);
698  mNames.append(nameCopy);
699  mCurrent = nameCopy;
700  mCurrentPosition = mNames.size();
701 
702  // maybe there is a position for the copy
703  if (inputValue.size() == 3) {
704 
705  if (inputValue[2].type() == kTypeInt32) {
706  TTValue dummy;
707  positionCopy = inputValue[2] ;
708 
709 #ifdef __TT_ELEMENT_H__
710  v = (int)mCurrentPosition;
711 #else
712  v = mCurrentPosition;
713 #endif
714  v.append((int)positionCopy);
715  return Move(v, dummy);
716  }
717  }
718  else {
719 
720  notifyNamesObservers();
721  notifyValueObservers();
722 
723  return kTTErrNone;
724  }
725  }
726 
727  return kTTErrGeneric;
728 }
729 
730 TTErr TTPresetManager::WriteAsXml(const TTValue& inputValue, TTValue& outputValue)
731 {
732  TTObject o = inputValue[0];
733  TTXmlHandlerPtr aXmlHandler = (TTXmlHandlerPtr)o.instance();
734  if (!aXmlHandler)
735  return kTTErrGeneric;
736 
737  TTSymbol presetName;
738  TTValue v;
739  TTUInt32 i;
740 
741  for (i = 0; i < mNames.size(); i++) {
742 
743  presetName = mNames[i];
744  if (!mPresets.lookup(presetName, v)) {
745 
746  TTValue name = presetName;
747  name.toString(NO); //no quotes
748  TTString s = TTString(name[0]);
749 
750  // start to write a preset
751  xmlTextWriterStartElement((xmlTextWriterPtr)aXmlHandler->mWriter, BAD_CAST "preset");
752  xmlTextWriterWriteAttribute((xmlTextWriterPtr)aXmlHandler->mWriter, BAD_CAST "name", BAD_CAST s.c_str());
753 
754  aXmlHandler->setAttributeValue(kTTSym_object, v);
755  aXmlHandler->sendMessage(TTSymbol("Write"));
756 
757  // end to write a preset
758  xmlTextWriterEndElement((xmlTextWriterPtr)aXmlHandler->mWriter);
759  }
760  }
761 
762  return kTTErrNone;
763 }
764 
765 TTErr TTPresetManager::ReadFromXml(const TTValue& inputValue, TTValue& outputValue)
766 {
767  TTObject o = inputValue[0];
768  TTXmlHandlerPtr aXmlHandler = (TTXmlHandlerPtr)o.instance();
769  if (!aXmlHandler)
770  return kTTErrGeneric;
771 
772  TTValue v;
773 
774  // Switch on the name of the XML node
775 
776  // Starts file reading : clear the preset list
777  if (aXmlHandler->mXmlNodeName == kTTSym_xmlHandlerReadingStarts) {
778  Clear();
779  return kTTErrNone;
780  }
781 
782  // Ends file reading : bind on first preset
783  if (aXmlHandler->mXmlNodeName == kTTSym_xmlHandlerReadingEnds) {
784 
785  if (mNames.size()) {
786 
787  mCurrent = mNames[0];
788  if (!mPresets.lookup(mCurrent, v))
789  mCurrentPreset = v[0];
790  }
791 
792  notifyNamesObservers();
793  notifyValueObservers();
794 
795  return kTTErrNone;
796 
797  }
798 
799  // Preset node :
800  if (aXmlHandler->mXmlNodeName == TTSymbol("preset")) {
801 
802  if (!aXmlHandler->mXmlNodeStart)
803  return kTTErrNone;
804 
805  // Get preset name
806  if (!aXmlHandler->getXmlAttribute(kTTSym_name, v, YES)) {
807 
808  if (v.size() == 1) {
809 
810  if (v[0].type() == kTypeSymbol) {
811 
812  mCurrent = v[0];
813 
814  // Create a new preset
815  mCurrentPreset = TTObject(kTTSym_Preset, mReturnLineCallback);
816 
817  mCurrentPreset.set(kTTSym_address, mAddress);
818  mCurrentPreset.set(kTTSym_name, mCurrent);
819 
820  mPresets.append(mCurrent, mCurrentPreset);
821  mNames.append(mCurrent);
822  }
823  }
824 
825  // go back to the element to allow the preset to parse it
826  xmlTextReaderMoveToElement((xmlTextReaderPtr)aXmlHandler->mReader);
827  }
828  }
829 
830  // edit the current preset from the xml file using the XmlHandler
831  if (mCurrentPreset.valid()) {
832 
833  aXmlHandler->setAttributeValue(kTTSym_object, mCurrentPreset);
834  return aXmlHandler->sendMessage(TTSymbol("Read"));
835  }
836  else
837  return kTTErrGeneric;
838 }
839 
840 TTErr TTPresetManager::WriteAsText(const TTValue& inputValue, TTValue& outputValue)
841 {
842  TTObject o = inputValue[0];
843  TTTextHandlerPtr aTextHandler = (TTTextHandlerPtr)o.instance();
844  if (!aTextHandler)
845  return kTTErrGeneric;
846 
847  TTString *buffer;
848  TTSymbol presetName;
849  TTValue v;
850 
851  buffer = aTextHandler->mWriter;
852 
853  for (TTUInt32 i = 0; i < mNames.size(); i++) {
854 
855  presetName = mNames[i];
856  if (!mPresets.lookup(presetName, v)) {
857 
858  aTextHandler->setAttributeValue(kTTSym_object, v);
859  aTextHandler->sendMessage(TTSymbol("Write"));
860  }
861  }
862 
863  return kTTErrNone;
864 }
865 
866 TTErr TTPresetManager::ReadFromText(const TTValue& inputValue, TTValue& outputValue)
867 {
868  TTObject o = inputValue[0];
869  TTTextHandlerPtr aTextHandler = (TTTextHandlerPtr)o.instance();
870  if (!aTextHandler)
871  return kTTErrGeneric;
872 
873  TTDictionaryBasePtr line;
874  TTSymbol flagName;
875  TTValue v, args;
876 
877  // if it is the first line :
878  if (aTextHandler->mFirstLine)
879  Clear();
880 
881  // parse the buffer line into TTDictionary
882  line = TTScriptParseLine(*(aTextHandler->mLine));
883 
884  if (line) {
885 
886  // replace the buffer line value by the parsed line dictionary
887  aTextHandler->mLine = new TTValue((TTPtr)line);
888 
889  // match preset flag line : - preset name
890  if (line->getSchema() == kTTSym_flag) {
891 
892  line->lookup(kTTSym_name, v);
893  flagName = v[0];
894 
895  if (flagName == TTSymbol("preset")) {
896 
897  // get preset name
898  if (!line->getValue(v)) {
899 
900  mCurrent = v[0];
901 
902  // Create a new preset
903  mCurrentPreset = TTObject(kTTSym_Preset, mReturnLineCallback);
904 
905  mCurrentPreset.set(kTTSym_address, mAddress);
906  mCurrentPreset.set(kTTSym_name, mCurrent);
907 
908  mPresets.append(mCurrent, mCurrentPreset);
909  mNames.append(mCurrent);
910  }
911  }
912  }
913 
914  // edit the current preset with the line
915  if (mCurrentPreset.valid()) {
916 
917  aTextHandler->setAttributeValue(kTTSym_object, mCurrentPreset);
918  return aTextHandler->sendMessage(TTSymbol("Read"));
919  }
920  }
921 
922  // if it is the last line : bind on the first preset
923  if (aTextHandler->mLastLine) {
924 
925  if (mNames.size()) {
926 
927  mCurrent = mNames[0];
928  if (!mPresets.lookup(mCurrent, v))
929  mCurrentPreset = v[0];
930  }
931 
932  notifyNamesObservers();
933  notifyValueObservers();
934 
935  return kTTErrNone;
936  }
937 
938  return kTTErrGeneric;
939 }
940 
941 TTErr TTPresetManager::notifyValueObservers()
942 {
943  TTAttributePtr anAttribute = NULL;
944  TTValue v;
945  TTErr err;
946 
947  err = this->findAttribute(kTTSym_value, &anAttribute);
948 
949  if (!err) {
950  getValue(v);
951  anAttribute->sendNotification(kTTSym_notify, v); // we use kTTSym_notify because we know that observers are TTCallback
952  }
953 
954  return kTTErrNone;
955 }
956 
957 TTErr TTPresetManager::notifyNamesObservers()
958 {
959  TTAttributePtr anAttribute = NULL;
960  TTErr err;
961 
962  err = this->findAttribute(kTTSym_names, &anAttribute);
963 
964  if (!err)
965  anAttribute->sendNotification(kTTSym_notify, mNames); // we use kTTSym_notify because we know that observers are TTCallback
966 
967  return kTTErrNone;
968 }
TTErr sendMessage(const TTSymbol name)
TODO: Document this function.
TTErr(TTObjectBase::* TTSetterMethod)(const TTAttribute &attribute, const TTValue &value)
A type that can be used to store a pointer to a message for an object.
Definition: TTObjectBase.h:78
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
A type that contains a key and a value.
const char * c_str() const
Return a pointer to the internal C-string.
Definition: TTString.h:83
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.
size_type size() const noexcept
Return the number of elements.
TTErr sendNotification(const TTSymbol name, const TTValue &arguments)
Send a notification.
This class represents a single attribute, as used by the TTObjectBase class.
Definition: TTAttribute.h:79
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
This is a special type used by TTAttribute to indicate that a value is a TTValue and is locally maint...
Definition: TTBase.h:286
void append(const T &anElementValueToAppend)
Insert a single TTElement at the end.
Definition: TTValue.h:243
#define addAttributeWithGetter(name, type)
A convenience macro to be used by subclasses for registering attributes with a custom getter...
Definition: TTAttribute.h:38
void * TTPtr
A generic pointer.
Definition: TTBase.h:248
64-bit floating point
Definition: TTBase.h:272
#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.
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
float TTFloat32
32 bit floating point number
Definition: TTBase.h:187
#define addMessageWithArguments(name)
A convenience macro to be used by subclasses for registering messages.
Definition: TTMessage.h:27
A PresetManager Object.
TTErr lookup(const TTSymbol key, TTValue &value) const
Find the value for the given key.
std::int32_t TTInt32
32 bit signed integer
Definition: TTBase.h:177
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
TTErr
Jamoma Error Codes Enumeration of error codes that might be returned by any of the TTBlue functions a...
Definition: TTBase.h:342
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
#define addAttributeWithSetter(name, type)
A convenience macro to be used by subclasses for registering attributes with a custom setter...
Definition: TTAttribute.h:47
#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
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
TTErr(TTObjectBase::* TTGetterMethod)(const TTAttribute &attribute, TTValue &value)
A type that can be used to store a pointer to a message for an object.
Definition: TTObjectBase.h:73
[doxygenAppendixC_copyExample]
Definition: TTValue.h:34
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