Jamoma API  0.6.0.a19
PureData/source/j.model/j.model_preset.cpp
Go to the documentation of this file.
1 /** @file
2  *
3  * @ingroup implementationPdExternals
4  *
5  * @brief j.model / j.view - - preset features
6  *
7  * @details
8  *
9  * @authors Théo de la Hogue, Trond Lossius, Antoine Villeret
10  *
11  * @copyright Copyright © 2010 Théo de la Hogue @n
12  * Copyright © 2015, Antoine Villeret@n
13  * This code is licensed under the terms of the "New BSD License" @n
14  * http://creativecommons.org/licenses/BSD/
15  */
16 
17 
18 #include "j.model.h"
19 
21 {
23  TTAddress modelAdrs;
24  TTValue v, a, args, none;
25  TTAddress presetAddress;
26 
27  // get model:address
28  EXTRA->modelInfo->get(kTTSym_address, v);
29  modelAdrs = v[0];
30 
31  // create the preset manager
32  jamoma_presetManager_create((t_object*)x, *EXTRA->presetManager);
33 
34  // suscribe it under a preset node
35  presetAddress = modelAdrs.appendAddress(TTAddress("preset"));
36 
37  args = TTValue(presetAddress, *EXTRA->presetManager, x->patcherPtr);
38 
39  if (!JamomaApplication.send("ObjectRegister", args, none)) {
40 
41  EXTRA->presetManager->set(kTTSym_address, modelAdrs);
42 
43 // defer_low(x, (method)model_preset_default, 0, 0, 0L);
45  }
46 }
47 
48 /*
49 void model_preset_return_value(TTPtr self, t_symbol *msg, long argc, t_atom *argv)
50 {
51  WrappedModularInstancePtr x = (WrappedModularInstancePtr)self;
52 
53  // avoid blank before line
54  if (msg == _sym_nothing)
55  outlet_atoms(x->outlets[line_out], argc, argv);
56  else
57  outlet_anything(x->outlets[line_out], msg, argc, argv);
58 }
59 */
60 
61 void model_preset_return_names(TTPtr self, t_symbol *msg, long argc, t_atom *argv)
62 {
64  outlet_anything((t_outlet*)x->outlets[dump_out], gensym("names"), argc, argv);
65 }
66 
67 void model_preset_read(TTPtr self, t_symbol *msg, long argc, t_atom *argv)
68 {
69 // defer(self, (method)model_preset_doread, msg, argc, argv);
70  model_preset_doread(self,msg,argc,argv);
71 }
72 
73 void model_preset_doread(TTPtr self, t_symbol *msg, long argc, t_atom *argv)
74 {
76  TTValue o, v, none;
77  TTSymbol fullpath;
78  TTObject aTextHandler;
79  TTErr tterr;
80 
81  if (EXTRA->presetManager->valid()) {
82 
83  fullpath = jamoma_file_read((t_object*)x, argc, argv, 'TEXT');
84  v.append(fullpath);
85 
86  tterr = x->internals->lookup(kTTSym_TextHandler, o);
87 
88  if (!tterr) {
89 
90  aTextHandler = o[0];
91 
92  aTextHandler.set(kTTSym_object, *EXTRA->presetManager);
93 
94 // critical_enter(0);
95  tterr = aTextHandler.send(kTTSym_Read, v, none);
96 // critical_exit(0);
97 
98  if (!tterr)
99  {
100 // object_obex_dumpout(self, _sym_read, argc, argv);
101  outlet_anything(x->dumpOut,gensym("read"), argc, argv);
102  } else {
103 // object_obex_dumpout(self, _sym_error, 0, NULL);
104  outlet_anything(x->dumpOut, gensym("error"), 0 , NULL);
105  }
106  }
107  }
108 }
109 
111 {
112 // defer(self, (method)model_preset_doread_again, NULL, 0, NULL);
114 }
115 
117 {
119  TTObject aTextHandler;
120  TTValue o;
121  TTErr tterr;
122 
123  tterr = x->internals->lookup(kTTSym_TextHandler, o);
124 
125  if (!tterr) {
126 
127  aTextHandler = o[0];
128 
129  aTextHandler.set(kTTSym_object, *EXTRA->presetManager);
130 
131 // critical_enter(0);
132  tterr = aTextHandler.send(kTTSym_ReadAgain);
133 // critical_exit(0);
134 
135  if (!tterr)
136  {
137 // object_obex_dumpout(self, _sym_read, 0, NULL);
138  outlet_anything(x->dumpOut,gensym("read"),0,NULL);
139  } else {
140 // object_obex_dumpout(self, _sym_error, 0, NULL);
141  outlet_anything(x->dumpOut,gensym("error"),0,NULL);
142  }
143  }
144 }
145 
146 void model_preset_write(TTPtr self, t_symbol *msg, long argc, t_atom *argv)
147 {
148 // defer(self, (method)model_preset_dowrite, msg, argc, argv);
149  model_preset_dowrite(self,msg,argc,argv);
150 }
151 
152 void model_preset_dowrite(TTPtr self, t_symbol *msg, long argc, t_atom *argv)
153 {
155  char filename[MAX_FILENAME_CHARS];
156  TTSymbol fullpath;
157  TTValue o, v, none;
158  TTObject aTextHandler;
159  TTErr tterr;
160 
161  // stop filewatcher
162  /* TODO write a filewatcher for PD
163  if (EXTRA->filewatcher)
164  filewatcher_stop(EXTRA->filewatcher);
165  */
166 
167  if (EXTRA->presetManager->valid()) {
168 
169  // Default TEXT File Name
170  snprintf(filename, MAX_FILENAME_CHARS, "%s.%s.presets.txt", x->patcherClass.c_str(), x->patcherContext.c_str());
171  fullpath = jamoma_file_write((t_object*)x, argc, argv, filename);
172  v.append(fullpath);
173 
174  tterr = x->internals->lookup(kTTSym_TextHandler, o);
175 
176  if (!tterr) {
177  aTextHandler = o[0];
178 
179  aTextHandler.set(kTTSym_object, *EXTRA->presetManager);
180 
181 // critical_enter(0);
182  tterr = aTextHandler.send(kTTSym_Write, v, none);
183 // critical_exit(0);
184 
185  if (!tterr) {
186 // object_obex_dumpout(self, _sym_write, argc, argv);
187  outlet_anything(x->dumpOut, gensym("write"),0,NULL);
188  } else {
189 // object_obex_dumpout(self, _sym_error, 0, NULL);
190  outlet_anything(x->dumpOut, gensym("error"),0,NULL);
191  }
192  }
193  }
194 
195  // start filewatcher
196  /* TODO rewrite a filewatcher for PD
197  if (EXTRA->filewatcher)
198  filewatcher_start(EXTRA->filewatcher);
199  */
200 }
201 
203 {
204 // defer(self, (method)model_preset_dowrite_again, NULL, 0, NULL);
206 }
207 
209 {
211  TTObject aTextHandler;
212  TTValue o;
213  TTErr tterr;
214 
215  // stop filewatcher
216  /* TODO rewrite a filewatcher for PD
217  if (EXTRA->filewatcher)
218  filewatcher_stop(EXTRA->filewatcher);
219  */
220 
221  tterr = x->internals->lookup(kTTSym_TextHandler, o);
222 
223  if (!tterr) {
224 
225  aTextHandler = o[0];
226 
227  aTextHandler.set(kTTSym_object, *EXTRA->presetManager);
228 
229 // critical_enter(0);
230  tterr = aTextHandler.send(kTTSym_WriteAgain);
231 // critical_exit(0);
232 
233  if (!tterr) {
234 // object_obex_dumpout(self, _sym_write, 0, NULL);
235  outlet_anything(x->dumpOut, gensym("write"),0,NULL);
236  } else {
237 // object_obex_dumpout(self, _sym_error, 0, NULL);
238  outlet_anything(x->dumpOut, gensym("error"),0,NULL);
239  }
240  }
241 
242  // start filewatcher
243  /* TODO rewrite a filewatcher for PD
244  if (EXTRA->filewatcher)
245  filewatcher_start(EXTRA->filewatcher);
246  */
247 }
248 
250 {
252  short outvol;
253  t_fourcc outtype, filetype = 'TEXT';
254  char fullpath[MAX_PATH_CHARS]; // path and name passed on to the xml parser
255  char posixpath[MAX_PATH_CHARS];
256  t_atom a;
257  t_symbol* textfile;
258 
259  if (x->patcherClass != kTTSymEmpty) {
260 
261  if (EXTRA->attr_presets != kTTSym_none) {
262 
263  textfile = gensym(EXTRA->attr_presets.c_str());
264  }
265  else if (x->patcherContext == kTTSym_model)
266  jamoma_edit_filename(*ModelPresetFormat, x->patcherClass, &textfile);
267 
268  else if (x->patcherContext == kTTSym_view)
269  jamoma_edit_filename(*ViewPresetFormat, x->patcherClass, &textfile);
270  else
271  return pd_error((t_object*)x, "preset_default : can't get the context of the patcher");
272 
273  if (locatefile_extended((char*)textfile->s_name, &outvol, &outtype, &filetype, 1)) {
274  //object_warn((t_object*)x, "preset_default : can't find %s file in the Max search path", textfile.data());
275  return;
276  }
277 
278  path_topathname(outvol, (char*)textfile->s_name, fullpath);
279  //path_nameconform(fullpath, posixpath, PATH_STYLE_NATIVE, PATH_TYPE_BOOT);
280 
281  atom_setsym(&a, gensym(posixpath));
282 // defer_low(self, (method)model_preset_doread, gensym("read"), 1, &a);
283  model_preset_doread(self, gensym("read"),1,&a);
284 
285  // recall the default preset if exists
286  atom_setsym(&a, gensym("default"));
287 // defer_low((t_object*)x, (method)model_preset_dorecall, NULL, 1, &a);
288  model_preset_dorecall((t_object*)x,NULL,1,&a);
289  // replace filewatcher
290  /* TODO rewrite a filewatcher for PD
291  if (EXTRA->filewatcher) {
292  filewatcher_stop(EXTRA->filewatcher);
293  object_free(EXTRA->filewatcher);
294  }
295 
296  EXTRA->filewatcher = filewatcher_new((t_object*)x, outvol, (char*)textfile->s_name);
297  filewatcher_start(EXTRA->filewatcher);
298  */
299  }
300  else
301  pd_error((t_object*)x, "preset_default : can't get the class of the patcher");
302 }
303 
304 void model_preset_filechanged(TTPtr self, char *filename, short path)
305 {
307  char fullpath[MAX_PATH_CHARS]; // path and name passed on to the xml parser
308  char posixpath[MAX_PATH_CHARS];
309  TTValue v;
310  TTSymbol current;
311  t_atom a;
312 
313  // get current preset
314  EXTRA->presetManager->get("current", v);
315 
316  path_topathname(path, filename, fullpath);
317  // path_nameconform(fullpath, posixpath, PATH_STYLE_NATIVE, PATH_TYPE_BOOT);
318 
319  atom_setsym(&a, gensym(posixpath));
320 // defer_low(self, (method)model_preset_doread, gensym("read"), 1, &a);
321  model_preset_doread(self,gensym("read"),1,&a);
322 
323  /* since JamomaMax#711 : we decide to mute the triggering of the current preset
324 
325  // try to recall last current preset
326  current = v[0];
327  atom_setsym(&a, gensym((char*)current.c_str()));
328  defer_low((t_object*)x, (method)model_preset_dorecall, NULL, 1, &a);
329 
330  */
331 }
332 
333 void model_preset_dorecall(TTPtr self, t_symbol *msg, long argc, t_atom *argv)
334 {
336  TTValue v, none;
337 
338  if (argc && argv)
339  if (atom_gettype(argv) == A_SYM)
340  v = TTValue(TTSymbol(atom_getsym(argv)->s_name));
341 
342  // recall the preset
343  EXTRA->presetManager->send(kTTSym_Recall, v, none);
344 }
345 
346 void model_preset_edit(TTPtr self, t_symbol *msg, long argc, t_atom *argv)
347 {
349  TTString *buffer;
350  char title[MAX_FILENAME_CHARS];
351  TTObject aTextHandler;
352  TTHashPtr allPresets;
353  TTValue v, o, args, none;
354  TTSymbol name;
355  t_atom a;
356  TTErr tterr;
357 
358  // choose object to edit : default the cuelist
359  *EXTRA->toEdit = *EXTRA->presetManager;
360  EXTRA->presetName = kTTSymEmpty;
361 
362  if (argc && argv) {
363 
364  if (atom_gettype(argv) == A_LONG) {
365 
366  // get presets names
367  EXTRA->presetManager->get("names", v);
368 
369  if (atom_getlong(argv) <= (TTInt32) v.size())
370  name = v[atom_getlong(argv)-1];
371 
372  else {
373  pd_error((t_object*)x, "%ld doesn't exist", atom_getlong(argv));
374  return;
375  }
376  }
377  else if (atom_gettype(argv) == A_SYM)
378  name = TTSymbol(atom_getsym(argv)->s_name);
379 
380  if (name != kTTSymEmpty) {
381 
382  // get preset object table
383  EXTRA->presetManager->get("presets", v);
384  allPresets = TTHashPtr((TTPtr)v[0]);
385 
386  if (allPresets) {
387 
388  // get cue to edit
389  if (!allPresets->lookup(name, v)) {
390 
391  // edit a preset
392  *EXTRA->toEdit = v[0];
393  EXTRA->presetName = name;
394  }
395  else {
396  pd_error((t_object*)x, "%s doesn't exist", atom_getsym(argv)->s_name);
397  return;
398  }
399  }
400  }
401  }
402 
403  // only one editor can be open in the same time
404  /* TODO rewrtite textEditor for Pd
405  if (!EXTRA->textEditor) {
406 
407  EXTRA->textEditor = (t_object*)object_new(_sym_nobox, _sym_jed, x, 0);
408 
409  buffer = new TTString();
410 
411  // get the buffer handler
412  tterr = x->internals->lookup(kTTSym_TextHandler, o);
413 
414  if (!tterr) {
415 
416  aTextHandler = o[0];
417 
418  critical_enter(0);
419  aTextHandler.set(kTTSym_object, *EXTRA->toEdit);
420  tterr = aTextHandler.send(kTTSym_Write, (TTPtr)buffer, none);
421  critical_exit(0);
422  }
423 
424  // pass the buffer to the editor
425  object_method(EXTRA->textEditor, _sym_settext, buffer->c_str(), _sym_utf_8);
426  object_attr_setchar(EXTRA->textEditor, gensym("scratch"), 1);
427 
428  snprintf(title, MAX_FILENAME_CHARS, "%s preset editor", x->patcherClass.c_str());
429  object_attr_setsym(EXTRA->textEditor, _sym_title, gensym(title));
430 
431  // output a flag
432  atom_setsym(&a, gensym("opened"));
433  object_obex_dumpout(self, gensym("editor"), 1, &a);
434 
435  buffer->clear();
436  delete buffer;
437  buffer = NULL;
438  }
439  */
440 }
441 
442 void model_preset_edclose(TTPtr self, char **text, long size)
443 {
445 
446  EXTRA->text = new TTString(*text);
447  EXTRA->textEditor = NULL;
449 // defer_low((t_object*)x, (method)model_preset_doedit, NULL, 0, NULL);
450 }
451 
453 {
455  TTObject aTextHandler;
456  TTValue o, none;
457  t_atom a;
458  TTErr tterr;
459 
460  // get the buffer handler
461  tterr = x->internals->lookup(kTTSym_TextHandler, o);
462 
463  if (!tterr) {
464 
465  aTextHandler = o[0];
466 
467 // critical_enter(0);
468  tterr = aTextHandler.send(kTTSym_Read, (TTPtr)EXTRA->text, none);
469 // critical_exit(0);
470 
471  // output a flag
472  atom_setsym(&a, gensym("closed"));
473  outlet_anything(x->dumpOut, gensym("editor"),1,&a);
474 // object_obex_dumpout(self, gensym("editor"), 1, &a);
475 
476  if (!tterr) {
477  outlet_anything(x->dumpOut,gensym("read"),0,NULL);
478 // object_obex_dumpout(self, _sym_read, 0, NULL);
479  } else {
480  outlet_anything(x->dumpOut,gensym("error"),0,NULL);
481 // object_obex_dumpout(self, _sym_error, 0, NULL);
482  }
483  }
484 
485  delete EXTRA->text;
486  EXTRA->text = NULL;
487  EXTRA->textEditor = NULL;
488  *EXTRA->toEdit = *EXTRA->presetManager;
489  EXTRA->presetName = kTTSymEmpty;
490 }
491 
492 t_max_err model_preset_set_presets(TTPtr self, TTPtr attr, long ac, t_atom *av)
493 {
495 
496  if (ac&&av) {
497  EXTRA->attr_presets = TTSymbol(atom_getsym(av)->s_name);
498  }
499  else
500  EXTRA->attr_presets = kTTSym_none; // default true
501 
502  return 0; // MAX_ERR_NONE;
503 }
504 
505 t_max_err model_preset_get_presets(TTPtr self, TTPtr attr, long *ac, t_atom **av)
506 {
508 
509  if ((*ac)&&(*av)) {
510  //memory passed in, use it
511  } else {
512  //otherwise allocate memory
513  *ac = 1;
514  if (!(*av = (t_atom*)getbytes(sizeof(t_atom)*(*ac)))) {
515  *ac = 0;
516  return -4; // MAX_ERR_OUT_OF_MEM;
517  }
518  }
519 
520  atom_setsym(*av, gensym(EXTRA->attr_presets.c_str()));
521 
522  return 0; // MAX_ERR_NONE;
523 }
TTAddress appendAddress(const TTAddress &toAppend)
Return a new TTAddress with the appended part.
Definition: TTAddress.h:167
void model_preset_read(TTPtr self, t_symbol *msg, long argc, t_atom *argv)
void JAMOMA_EXPORT jamoma_edit_filename(TTString format, TTSymbol className, t_symbol **returnedFileName)
Edit a file name from a given file format and a class name.
void model_preset_doread_again(TTPtr self)
TTErr send(const TTSymbol aName)
Send a message to this object with no arguments.
Definition: TTObject.cpp:135
j.model / j.view - The main control center of Jamoma model and view patcher
void model_preset_filechanged(TTPtr self, char *filename, short path)
TTHandle outlets
an array of outlet
void model_preset_write_again(TTPtr self)
TTErr lookup(const TTSymbol key, TTValue &value)
Find the value for the given key.
Definition: TTHash.cpp:76
TTSymbol patcherClass
the patcher class in which the external is
void model_preset_dorecall(TTPtr self, t_symbol *msg, long argc, t_atom *argv)
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
size_type size() const noexcept
Return the number of elements.
t_object * patcherPtr
the patcher in which the external is (ignoring subpatcher)
TTSymbol JAMOMA_EXPORT jamoma_file_read(t_object *x, long argc, const t_atom *argv, t_fourcc filetype)
Get BOOT style filepath from args or, if no args open a dialog to read a file.
TTHashPtr internals
An hash table to store any internal TTObjectBases (like TTData, TTViewer, ...)
Maintain a collection of TTValue objects indexed by TTSymbol pointers.
Definition: TTHash.h:36
void append(const T &anElementValueToAppend)
Insert a single TTElement at the end.
Definition: TTValue.h:243
void model_preset_amenities(TTPtr self)
void * TTPtr
A generic pointer.
Definition: TTBase.h:248
void model_preset_read_again(TTPtr self)
void model_preset_edclose(TTPtr self, char **text, long size)
void model_preset_doedit(TTPtr self)
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
TTSymbol JAMOMA_EXPORT jamoma_file_write(t_object *x, long argc, const t_atom *argv, char *default_filename)
Get BOOT style filepath from args or, if no args open a dialog to write a file.
void model_preset_edit(TTPtr self, t_symbol *msg, long argc, t_atom *argv)
void model_preset_doread(TTPtr self, t_symbol *msg, long argc, t_atom *argv)
void model_preset_default(TTPtr self)
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 model_preset_dowrite(TTPtr self, t_symbol *msg, long argc, t_atom *argv)
TTErr JAMOMA_EXPORT jamoma_presetManager_create(t_object *x, TTObject &returnedPresetManager)
Create a #TTPresetManager object.
void model_preset_write(TTPtr self, t_symbol *msg, long argc, t_atom *argv)
Data Structure for this object.
t_max_err model_preset_set_presets(TTPtr self, TTPtr attr, long ac, t_atom *av)
TTErr
Jamoma Error Codes Enumeration of error codes that might be returned by any of the TTBlue functions a...
Definition: TTBase.h:342
void model_preset_dowrite_again(TTPtr self)
void model_preset_return_names(TTPtr self, t_symbol *msg, long argc, t_atom *argv)
TTSymbol patcherContext
the patcher context in which the external is (model, view)
The TTString class is used to represent a string.
Definition: TTString.h:34
WrappedModularInstance * WrappedModularInstancePtr
Pointer to a wrapped instance of our object.
[doxygenAppendixC_copyExample]
Definition: TTValue.h:34
t_max_err model_preset_get_presets(TTPtr self, TTPtr attr, long *ac, t_atom **av)