Ok all, at this point we've nailed most of the bugs and feedback so far. The latest PR is https://github.com/pure-data/pure-data/pull/123 https://github.com/pure-data/pure-data/pull/123
As far as I can tell, the only remaining things which could be done/included for the release are:
Small Stuff
* Remove midiin & sysexin Windows warnings in x_midi.c (& update help file)
(Optional) Big Stuff
* Adopt DejaVu Sans Mono a the default font -> this is in the dejavu branch https://github.com/pure-data/pure-data/pull/42 https://github.com/pure-data/pure-data/pull/42 This is mainly for mac & Linux, Windows support will need to be added later as mentioned in the discussion. It also fixes the bad Monaco rendering on retina screens at small font sizes. * Update the icon -> see my pd-icon repo https://github.com/pure-data/pd-icon https://github.com/pure-data/pd-icon & the recent thread on the pd-list
There may be more things, but I think I'm done on my end for now. We could do one final test release after this, but hopefully the feedback bugs will all have been fixed.
-------- Dan Wilcox @danomatika http://twitter.com/danomatika danomatika.com http://danomatika.com/ robotcowboy.com http://robotcowboy.com/
I got some more feedback/code for [list store], apart from the list_store_range bug I've already reported on the list. Is there some time left for you guys to review it? I can send it in a couple of hours. I'm travelling right now.
Christof
Gesendet: Freitag, 21. Juli 2017 um 11:54 Uhr Von: "Dan Wilcox" danomatika@gmail.com An: pd-dev@iem.at Cc: "Miller Puckette" msp@ucsd.edu Betreff: [PD-dev] 0.48.0 release status
Ok all, at this point we've nailed most of the bugs and feedback so far. The latest PR is https://github.com/pure-data/pure-data/pull/123 https://github.com/pure-data/pure-data/pull/123
As far as I can tell, the only remaining things which could be done/included for the release are:
Small Stuff
- Remove midiin & sysexin Windows warnings in x_midi.c (& update help file)
(Optional) Big Stuff
- Adopt DejaVu Sans Mono a the default font -> this is in the dejavu branch https://github.com/pure-data/pure-data/pull/42 https://github.com/pure-data/pure-data/pull/42 This is mainly for mac & Linux, Windows support will need to be added later as mentioned in the discussion. It also fixes the bad Monaco rendering on retina screens at small font sizes.
- Update the icon -> see my pd-icon repo https://github.com/pure-data/pd-icon https://github.com/pure-data/pd-icon & the recent thread on the pd-list
There may be more things, but I think I'm done on my end for now. We could do one final test release after this, but hopefully the feedback bugs will all have been fixed.
Dan Wilcox @danomatika http://twitter.com/danomatika danomatika.com http://danomatika.com/ robotcowboy.com http://robotcowboy.com/
Pd-dev mailing list Pd-dev@lists.iem.at https://lists.puredata.info/listinfo/pd-dev
Always open to bug reports (although swamped right now I'm afraid, will only get to things that are either urgent or easy :)
I've already fixed "list_store_range" following your earlier report, thanks.
Miller
On Fri, Jul 21, 2017 at 01:05:15PM +0200, Christof Ressi wrote:
I got some more feedback/code for [list store], apart from the list_store_range bug I've already reported on the list. Is there some time left for you guys to review it? I can send it in a couple of hours. I'm travelling right now.
Christof
Gesendet: Freitag, 21. Juli 2017 um 11:54 Uhr Von: "Dan Wilcox" danomatika@gmail.com An: pd-dev@iem.at Cc: "Miller Puckette" msp@ucsd.edu Betreff: [PD-dev] 0.48.0 release status
Ok all, at this point we've nailed most of the bugs and feedback so far. The latest PR is https://github.com/pure-data/pure-data/pull/123 https://github.com/pure-data/pure-data/pull/123
As far as I can tell, the only remaining things which could be done/included for the release are:
Small Stuff
- Remove midiin & sysexin Windows warnings in x_midi.c (& update help file)
(Optional) Big Stuff
- Adopt DejaVu Sans Mono a the default font -> this is in the dejavu branch https://github.com/pure-data/pure-data/pull/42 https://github.com/pure-data/pure-data/pull/42 This is mainly for mac & Linux, Windows support will need to be added later as mentioned in the discussion. It also fixes the bad Monaco rendering on retina screens at small font sizes.
- Update the icon -> see my pd-icon repo https://github.com/pure-data/pd-icon https://github.com/pure-data/pd-icon & the recent thread on the pd-list
There may be more things, but I think I'm done on my end for now. We could do one final test release after this, but hopefully the feedback bugs will all have been fixed.
Dan Wilcox @danomatika http://twitter.com/danomatika danomatika.com http://danomatika.com/ robotcowboy.com http://robotcowboy.com/
Pd-dev mailing list Pd-dev@lists.iem.at https://lists.puredata.info/listinfo/pd-dev
Pd-dev mailing list Pd-dev@lists.iem.at https://lists.puredata.info/listinfo/pd-dev
Thanks for your answer! I guess it doesn't have high priority but anyway, the thing is this:
I'm really happy about [list store] but I think it can be way more expressive. My idea was to take the interface of [text] and [array] to add more methods.
First, I renamed [range( to [get( (but kept the old method around as an alias) because it's structurally very similar to [text get] and [array get].
Then I added a method [set <f> ...( which lets you overwrite atoms, just like [text set] and [array set]. the first float is the index, followed by the atoms you want to copy.
Then I added a general [insert <f> ...( method which lets you insert atoms, where the first float is the index, followed by the atoms you want to insert *before* that index. A large index lets you append atoms. I kept [prepend ...( and [append ...( as shortcuts for those two special cases.
Finally I added a [delete <f> <f>( method where the first float is the index to start deleting and the second float is the number of floats to delete.
---
These methods would turn [list store] into a powerful dynamically sized type-agnostic array - which we don't have in Pd yet! [text] comes closest, but it doesn't handle pointers and it bashes everything to binbufs which sometimes leads to unexpected or undesired behaviour.
Please find my version of x_list.c(which also includes the bug fix that you've already applied) and a messy test patch attached. I didn't have much time...
The methods works well with floats and symbols but there are mysterious bugs with pointers. Not only with my new method but also with your [range( method (which I didn't change). For example, sequencing a list of pointers creates 'consistency check failed' errors with [print] and sometimes there are crashes with segmentation faults.
Also, I'm wondering if memmove() and realloc() is really safe with arrays of t_listelem because a gpointer atom l_a inside t_listelem points to l_a. when the array changes location in memory, won't the pointer point to the wrong location?
I know there are more important things to do right now. Just have look when you have time.
Thanks!
Christof
Gesendet: Freitag, 21. Juli 2017 um 17:26 Uhr Von: "Miller Puckette" msp@ucsd.edu An: "Christof Ressi" christof.ressi@gmx.at Cc: "Dan Wilcox" danomatika@gmail.com, pd-dev@iem.at Betreff: Re: [PD-dev] 0.48.0 release status
Always open to bug reports (although swamped right now I'm afraid, will only get to things that are either urgent or easy :)
I've already fixed "list_store_range" following your earlier report, thanks.
Miller
On Fri, Jul 21, 2017 at 01:05:15PM +0200, Christof Ressi wrote:
I got some more feedback/code for [list store], apart from the list_store_range bug I've already reported on the list. Is there some time left for you guys to review it? I can send it in a couple of hours. I'm travelling right now.
Christof
Gesendet: Freitag, 21. Juli 2017 um 11:54 Uhr Von: "Dan Wilcox" danomatika@gmail.com An: pd-dev@iem.at Cc: "Miller Puckette" msp@ucsd.edu Betreff: [PD-dev] 0.48.0 release status
Ok all, at this point we've nailed most of the bugs and feedback so far. The latest PR is https://github.com/pure-data/pure-data/pull/123 https://github.com/pure-data/pure-data/pull/123
As far as I can tell, the only remaining things which could be done/included for the release are:
Small Stuff
- Remove midiin & sysexin Windows warnings in x_midi.c (& update help file)
(Optional) Big Stuff
- Adopt DejaVu Sans Mono a the default font -> this is in the dejavu branch https://github.com/pure-data/pure-data/pull/42 https://github.com/pure-data/pure-data/pull/42 This is mainly for mac & Linux, Windows support will need to be added later as mentioned in the discussion. It also fixes the bad Monaco rendering on retina screens at small font sizes.
- Update the icon -> see my pd-icon repo https://github.com/pure-data/pd-icon https://github.com/pure-data/pd-icon & the recent thread on the pd-list
There may be more things, but I think I'm done on my end for now. We could do one final test release after this, but hopefully the feedback bugs will all have been fixed.
Dan Wilcox @danomatika http://twitter.com/danomatika danomatika.com http://danomatika.com/ robotcowboy.com http://robotcowboy.com/
Pd-dev mailing list Pd-dev@lists.iem.at https://lists.puredata.info/listinfo/pd-dev
Pd-dev mailing list Pd-dev@lists.iem.at https://lists.puredata.info/listinfo/pd-dev
OK... for now, I renamed "range" to "get" (did it right away to avoid the necessity of keeping the other name for compatibility). We can mess with the other stuff later.
Not sure about the pointer issues, will just hope that doesn't bite us before I can look closer at it.
Meanwhile, yeah, I can think of losts of cool things to try (e.g., "sort")
cheers Miller
On Fri, Jul 21, 2017 at 06:20:49PM +0200, Christof Ressi wrote:
Thanks for your answer! I guess it doesn't have high priority but anyway, the thing is this:
I'm really happy about [list store] but I think it can be way more expressive. My idea was to take the interface of [text] and [array] to add more methods.
First, I renamed [range( to [get( (but kept the old method around as an alias) because it's structurally very similar to [text get] and [array get].
Then I added a method [set <f> ...( which lets you overwrite atoms, just like [text set] and [array set]. the first float is the index, followed by the atoms you want to copy.
Then I added a general [insert <f> ...( method which lets you insert atoms, where the first float is the index, followed by the atoms you want to insert *before* that index. A large index lets you append atoms. I kept [prepend ...( and [append ...( as shortcuts for those two special cases.
Finally I added a [delete <f> <f>( method where the first float is the index to start deleting and the second float is the number of floats to delete.
These methods would turn [list store] into a powerful dynamically sized type-agnostic array - which we don't have in Pd yet! [text] comes closest, but it doesn't handle pointers and it bashes everything to binbufs which sometimes leads to unexpected or undesired behaviour.
Please find my version of x_list.c(which also includes the bug fix that you've already applied) and a messy test patch attached. I didn't have much time...
The methods works well with floats and symbols but there are mysterious bugs with pointers. Not only with my new method but also with your [range( method (which I didn't change). For example, sequencing a list of pointers creates 'consistency check failed' errors with [print] and sometimes there are crashes with segmentation faults.
Also, I'm wondering if memmove() and realloc() is really safe with arrays of t_listelem because a gpointer atom l_a inside t_listelem points to l_a. when the array changes location in memory, won't the pointer point to the wrong location?
I know there are more important things to do right now. Just have look when you have time.
Thanks!
Christof
Gesendet: Freitag, 21. Juli 2017 um 17:26 Uhr Von: "Miller Puckette" msp@ucsd.edu An: "Christof Ressi" christof.ressi@gmx.at Cc: "Dan Wilcox" danomatika@gmail.com, pd-dev@iem.at Betreff: Re: [PD-dev] 0.48.0 release status
Always open to bug reports (although swamped right now I'm afraid, will only get to things that are either urgent or easy :)
I've already fixed "list_store_range" following your earlier report, thanks.
Miller
On Fri, Jul 21, 2017 at 01:05:15PM +0200, Christof Ressi wrote:
I got some more feedback/code for [list store], apart from the list_store_range bug I've already reported on the list. Is there some time left for you guys to review it? I can send it in a couple of hours. I'm travelling right now.
Christof
Gesendet: Freitag, 21. Juli 2017 um 11:54 Uhr Von: "Dan Wilcox" danomatika@gmail.com An: pd-dev@iem.at Cc: "Miller Puckette" msp@ucsd.edu Betreff: [PD-dev] 0.48.0 release status
Ok all, at this point we've nailed most of the bugs and feedback so far. The latest PR is https://github.com/pure-data/pure-data/pull/123 https://github.com/pure-data/pure-data/pull/123
As far as I can tell, the only remaining things which could be done/included for the release are:
Small Stuff
- Remove midiin & sysexin Windows warnings in x_midi.c (& update help file)
(Optional) Big Stuff
- Adopt DejaVu Sans Mono a the default font -> this is in the dejavu branch https://github.com/pure-data/pure-data/pull/42 https://github.com/pure-data/pure-data/pull/42 This is mainly for mac & Linux, Windows support will need to be added later as mentioned in the discussion. It also fixes the bad Monaco rendering on retina screens at small font sizes.
- Update the icon -> see my pd-icon repo https://github.com/pure-data/pd-icon https://github.com/pure-data/pd-icon & the recent thread on the pd-list
There may be more things, but I think I'm done on my end for now. We could do one final test release after this, but hopefully the feedback bugs will all have been fixed.
Dan Wilcox @danomatika http://twitter.com/danomatika danomatika.com http://danomatika.com/ robotcowboy.com http://robotcowboy.com/
Pd-dev mailing list Pd-dev@lists.iem.at https://lists.puredata.info/listinfo/pd-dev
Pd-dev mailing list Pd-dev@lists.iem.at https://lists.puredata.info/listinfo/pd-dev
/* Copyright (c) 1997- Miller Puckette and others.
- For information on usage and redistribution, and for a DISCLAIMER OF ALL
- WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
#include "m_pd.h" #include <string.h>
#ifdef _WIN32 # include <malloc.h> /* MSVC or mingw on windows */ #elif defined(__linux__) || defined(__APPLE__) # include <alloca.h> /* linux, mac, mingw, cygwin */ #else # include <stdlib.h> /* BSDs for example */ #endif
#ifndef HAVE_ALLOCA /* can work without alloca() but we never need it */ #define HAVE_ALLOCA 1 #endif
#define LIST_NGETBYTE 100 /* bigger that this we use alloc, not alloca */
/* the "list" object family.
list append - append a list to another list prepend - prepend a list to another list split - first n elements to first outlet, rest to second outlet list trim - trim off "list" selector list length - output number of items in list list fromsymbol - "explode" a symbol into a list of character codes
Need to think more about: list foreach - spit out elements of a list one by one (also in reverse?) list reverse - permute elements of a list back to front list cat - build a list by accumulating elements
Probably don't need: list first - output first n elements. list last - output last n elements list nth - nth item in list, counting from zero list array - get items from a named array as a list list pack - synonym for 'pack' list unpack - synonym for 'unpack' */
/* -------------- utility functions: storage, copying -------------- */ /* List element for storage. Keep an atom and, in case it's a pointer, an associated 'gpointer' to protect against stale pointers. */ typedef struct _listelem { t_atom l_a; t_gpointer l_p; } t_listelem;
typedef struct _alist { t_pd l_pd; /* object to point inlets to */ int l_n; /* number of items */ int l_npointer; /* number of pointers */ t_listelem *l_vec; /* pointer to items */ } t_alist;
#if HAVE_ALLOCA #define ATOMS_ALLOCA(x, n) ((x) = (t_atom *)((n) < LIST_NGETBYTE ? \ alloca((n) * sizeof(t_atom)) : getbytes((n) * sizeof(t_atom)))) #define ATOMS_FREEA(x, n) ( \ ((n) < LIST_NGETBYTE || (freebytes((x), (n) * sizeof(t_atom)), 0))) #else #define ATOMS_ALLOCA(x, n) ((x) = (t_atom *)getbytes((n) * sizeof(t_atom))) #define ATOMS_FREEA(x, n) (freebytes((x), (n) * sizeof(t_atom))) #endif
static void atoms_copy(int argc, t_atom *from, t_atom *to) { int i; for (i = 0; i < argc; i++) to[i] = from[i]; }
/* ------------- fake class to divert inlets to ----------------- */
t_class *alist_class;
static void alist_init(t_alist *x) { x->l_pd = alist_class; x->l_n = x->l_npointer = 0; x->l_vec = 0; }
static void alist_clear(t_alist *x) { int i; for (i = 0; i < x->l_n; i++) { if (x->l_vec[i].l_a.a_type == A_POINTER) gpointer_unset(x->l_vec[i].l_a.a_w.w_gpointer); } if (x->l_vec) freebytes(x->l_vec, x->l_n * sizeof(*x->l_vec)); }
static void alist_copyin(t_alist *x, t_symbol *s, int argc, t_atom *argv, int where) { int i, j; for (i = 0, j = where; i < argc; i++, j++) { x->l_vec[j].l_a = argv[i]; if (x->l_vec[j].l_a.a_type == A_POINTER) { x->l_npointer++; gpointer_copy(x->l_vec[j].l_a.a_w.w_gpointer, &x->l_vec[j].l_p); x->l_vec[j].l_a.a_w.w_gpointer = &x->l_vec[j].l_p; } } }
/* set contents to a list */
static void alist_list(t_alist *x, t_symbol *s, int argc, t_atom *argv) { alist_clear(x); if (!(x->l_vec = (t_listelem *)getbytes(argc * sizeof(*x->l_vec)))) { x->l_n = 0; error("list: out of memory"); return; } x->l_n = argc; x->l_npointer = 0; alist_copyin(x, s, argc, argv, 0); }
/* set contents to an arbitrary non-list message */
static void alist_anything(t_alist *x, t_symbol *s, int argc, t_atom *argv) { int i; alist_clear(x); if (!(x->l_vec = (t_listelem *)getbytes((argc+1) * sizeof(*x->l_vec)))) { x->l_n = 0; error("list_alloc: out of memory"); return; } x->l_n = argc+1; x->l_npointer = 0; SETSYMBOL(&x->l_vec[0].l_a, s); for (i = 0; i < argc; i++) { x->l_vec[i+1].l_a = argv[i]; if (x->l_vec[i+1].l_a.a_type == A_POINTER) { x->l_npointer++; gpointer_copy(x->l_vec[i+1].l_a.a_w.w_gpointer, &x->l_vec[i+1].l_p); x->l_vec[i+1].l_a.a_w.w_gpointer = &x->l_vec[i+1].l_p; } } }
static void alist_toatoms(t_alist *x, t_atom *to, int onset, int count) { int i; for (i = 0; i < count; i++) to[i] = x->l_vec[onset + i].l_a; }
static void alist_clone(t_alist *x, t_alist *y, int onset, int count) { int i; y->l_pd = alist_class; y->l_n = count; y->l_npointer = 0; if (!(y->l_vec = (t_listelem *)getbytes(y->l_n * sizeof(*y->l_vec)))) { y->l_n = 0; error("list_alloc: out of memory"); } else for (i = 0; i < count; i++) { y->l_vec[i].l_a = x->l_vec[onset + i].l_a; if (y->l_vec[i].l_a.a_type == A_POINTER) { gpointer_copy(y->l_vec[i].l_a.a_w.w_gpointer, &y->l_vec[i].l_p); y->l_vec[i].l_a.a_w.w_gpointer = &y->l_vec[i].l_p; y->l_npointer++; } } }
static void alist_setup(void) { alist_class = class_new(gensym("list inlet"), 0, 0, sizeof(t_alist), 0, 0); class_addlist(alist_class, alist_list); class_addanything(alist_class, alist_anything); }
/* ------------- list append --------------------- */
t_class *list_append_class;
typedef struct _list_append { t_object x_obj; t_alist x_alist; } t_list_append;
static void *list_append_new(t_symbol *s, int argc, t_atom *argv) { t_list_append *x = (t_list_append *)pd_new(list_append_class); alist_init(&x->x_alist); alist_list(&x->x_alist, 0, argc, argv); outlet_new(&x->x_obj, &s_list); inlet_new(&x->x_obj, &x->x_alist.l_pd, 0, 0); return (x); }
static void list_append_list(t_list_append *x, t_symbol *s, int argc, t_atom *argv) { t_atom *outv; int n, outc = x->x_alist.l_n + argc; ATOMS_ALLOCA(outv, outc); atoms_copy(argc, argv, outv); if (x->x_alist.l_npointer) { t_alist y; alist_clone(&x->x_alist, &y, 0, x->x_alist.l_n); alist_toatoms(&y, outv+argc, 0, x->x_alist.l_n); outlet_list(x->x_obj.ob_outlet, &s_list, outc, outv); alist_clear(&y); } else { alist_toatoms(&x->x_alist, outv+argc, 0, x->x_alist.l_n); outlet_list(x->x_obj.ob_outlet, &s_list, outc, outv); } ATOMS_FREEA(outv, outc); }
static void list_append_anything(t_list_append *x, t_symbol *s, int argc, t_atom *argv) { t_atom *outv; int n, outc = x->x_alist.l_n + argc + 1; ATOMS_ALLOCA(outv, outc); SETSYMBOL(outv, s); atoms_copy(argc, argv, outv + 1); if (x->x_alist.l_npointer) { t_alist y; alist_clone(&x->x_alist, &y, 0, x->x_alist.l_n); alist_toatoms(&y, outv + 1 + argc, 0, x->x_alist.l_n); outlet_list(x->x_obj.ob_outlet, &s_list, outc, outv); alist_clear(&y); } else { alist_toatoms(&x->x_alist, outv + 1 + argc, 0, x->x_alist.l_n); outlet_list(x->x_obj.ob_outlet, &s_list, outc, outv); } ATOMS_FREEA(outv, outc); }
static void list_append_append(t_list_append *x, t_symbol *s, int argc, t_atom *argv) { if (!(x->x_alist.l_vec = (t_listelem *)resizebytes(x->x_alist.l_vec, (x->x_alist.l_n) * sizeof(*x->x_alist.l_vec), (x->x_alist.l_n + argc) * sizeof(*x->x_alist.l_vec)))) { x->x_alist.l_n = 0; error("list: out of memory"); return; } alist_copyin(&x->x_alist, s, argc, argv, x->x_alist.l_n); x->x_alist.l_n += argc; }
static void list_append_prepend(t_list_append *x, t_symbol *s, int argc, t_atom *argv) { if (!(x->x_alist.l_vec = (t_listelem *)resizebytes(x->x_alist.l_vec, (x->x_alist.l_n) * sizeof(*x->x_alist.l_vec), (x->x_alist.l_n + argc) * sizeof(*x->x_alist.l_vec)))) { x->x_alist.l_n = 0; error("list: out of memory"); return; } memmove(x->x_alist.l_vec + argc, x->x_alist.l_vec, x->x_alist.l_n * sizeof(*x->x_alist.l_vec)); alist_copyin(&x->x_alist, s, argc, argv, 0); x->x_alist.l_n += argc; }
static void list_append_free(t_list_append *x) { alist_clear(&x->x_alist); }
static void list_append_setup(void) { list_append_class = class_new(gensym("list append"), (t_newmethod)list_append_new, (t_method)list_append_free, sizeof(t_list_append), 0, A_GIMME, 0); class_addlist(list_append_class, list_append_list); class_addanything(list_append_class, list_append_anything); class_sethelpsymbol(list_append_class, &s_list); }
/* ------------- list prepend --------------------- */
t_class *list_prepend_class;
typedef t_list_append t_list_prepend;
static void *list_prepend_new(t_symbol *s, int argc, t_atom *argv) { t_list_prepend *x = (t_list_prepend *)pd_new(list_prepend_class); alist_init(&x->x_alist); alist_list(&x->x_alist, 0, argc, argv); outlet_new(&x->x_obj, &s_list); inlet_new(&x->x_obj, &x->x_alist.l_pd, 0, 0); return (x); }
static void list_prepend_list(t_list_prepend *x, t_symbol *s, int argc, t_atom *argv) { t_atom *outv; int n, outc = x->x_alist.l_n + argc; ATOMS_ALLOCA(outv, outc); atoms_copy(argc, argv, outv + x->x_alist.l_n); if (x->x_alist.l_npointer) { t_alist y; alist_clone(&x->x_alist, &y, 0, x->x_alist.l_n); alist_toatoms(&y, outv, 0, x->x_alist.l_n); outlet_list(x->x_obj.ob_outlet, &s_list, outc, outv); alist_clear(&y); } else { alist_toatoms(&x->x_alist, outv, 0, x->x_alist.l_n); outlet_list(x->x_obj.ob_outlet, &s_list, outc, outv); } ATOMS_FREEA(outv, outc); }
static void list_prepend_anything(t_list_prepend *x, t_symbol *s, int argc, t_atom *argv) { t_atom *outv; int n, outc = x->x_alist.l_n + argc + 1; ATOMS_ALLOCA(outv, outc); SETSYMBOL(outv + x->x_alist.l_n, s); atoms_copy(argc, argv, outv + x->x_alist.l_n + 1); if (x->x_alist.l_npointer) { t_alist y; alist_clone(&x->x_alist, &y, 0, x->x_alist.l_n); alist_toatoms(&y, outv, 0, x->x_alist.l_n); outlet_list(x->x_obj.ob_outlet, &s_list, outc, outv); alist_clear(&y); } else { alist_toatoms(&x->x_alist, outv, 0, x->x_alist.l_n); outlet_list(x->x_obj.ob_outlet, &s_list, outc, outv); } ATOMS_FREEA(outv, outc); }
static void list_prepend_free(t_list_prepend *x) { alist_clear(&x->x_alist); }
static void list_prepend_setup(void) { list_prepend_class = class_new(gensym("list prepend"), (t_newmethod)list_prepend_new, (t_method)list_prepend_free, sizeof(t_list_prepend), 0, A_GIMME, 0); class_addlist(list_prepend_class, list_prepend_list); class_addanything(list_prepend_class, list_prepend_anything); class_sethelpsymbol(list_prepend_class, &s_list); }
/* ------------- list store --------------------- */
t_class *list_store_class;
typedef struct _list_store { t_object x_obj; t_alist x_alist; t_outlet *x_out1; t_outlet *x_out2; } t_list_store;
static void *list_store_new(t_symbol *s, int argc, t_atom *argv) { t_list_store *x = (t_list_store *)pd_new(list_store_class); alist_init(&x->x_alist); alist_list(&x->x_alist, 0, argc, argv); x->x_out1 = outlet_new(&x->x_obj, &s_list); x->x_out2 = outlet_new(&x->x_obj, &s_bang); inlet_new(&x->x_obj, &x->x_alist.l_pd, 0, 0); return (x); }
static void list_store_list(t_list_store *x, t_symbol *s, int argc, t_atom *argv) { t_atom *outv; int n, outc = x->x_alist.l_n + argc; ATOMS_ALLOCA(outv, outc); atoms_copy(argc, argv, outv); if (x->x_alist.l_npointer) { t_alist y; alist_clone(&x->x_alist, &y, 0, x->x_alist.l_n); alist_toatoms(&y, outv+argc, 0, x->x_alist.l_n); outlet_list(x->x_out1, &s_list, outc, outv); alist_clear(&y); } else { alist_toatoms(&x->x_alist, outv+argc, 0, x->x_alist.l_n); outlet_list(x->x_out1, &s_list, outc, outv); } ATOMS_FREEA(outv, outc); }
/* insert atoms before a given index */ static void list_store_doinsert(t_list_store *x, int index, t_symbol *s, int argc, t_atom *argv) { if (index < 0) index = 0; /* index = 0 -> prepend */ if (index > x->x_alist.l_n) index = x->x_alist.l_n; /* index >= length -> append */
if (!(x->x_alist.l_vec = (t_listelem *)resizebytes(x->x_alist.l_vec, (x->x_alist.l_n) * sizeof(*x->x_alist.l_vec), (x->x_alist.l_n + argc) * sizeof(*x->x_alist.l_vec)))) { x->x_alist.l_n = 0; error("list: out of memory"); return; } /* we don't need memmove for appending */ if (index < x->x_alist.l_n){ memmove(x->x_alist.l_vec + index + argc, x->x_alist.l_vec + index, (x->x_alist.l_n - index) * sizeof(*x->x_alist.l_vec)); } alist_copyin(&x->x_alist, s, argc, argv, index); x->x_alist.l_n += argc; }
static void list_store_insert(t_list_store *x, t_symbol *s, int argc, t_atom *argv) { if (argc < 2) return;
/* first atom is the index where to start inserting atoms. */ int index = atom_getfloat(argv); argc--; argv++; /* insert remaining atoms */ list_store_doinsert(x, index, s, argc, argv); }
static void list_store_append(t_list_store *x, t_symbol *s, int argc, t_atom *argv) { list_store_doinsert(x, 1e+009, s, argc, argv); }
static void list_store_prepend(t_list_store *x, t_symbol *s, int argc, t_atom *argv) { list_store_doinsert(x, 0, s, argc, argv); }
static void list_store_delete(t_list_store *x, float f1, float f2) { int index = f1; int ndelete = f2;
if (index < 0) index = 0; if (index >= x->x_alist.l_n) return; /* out of range: nothing to delete */
int maxlength = x->x_alist.l_n - index; if (ndelete > maxlength) ndelete = maxlength;
/* first unset pointers */ if (x->x_alist.l_npointer) { t_listelem *vec = x->x_alist.l_vec; for (int i = 0; i < ndelete; i++) { if (vec[index + i].l_a.a_type == A_POINTER) { gpointer_unset(vec[i].l_a.a_w.w_gpointer); x->x_alist.l_npointer--; post("remaining number of pointers: %d", x->x_alist.l_npointer); } } }
/* then move atoms */ memmove(x->x_alist.l_vec + index, x->x_alist.l_vec + index + ndelete, (x->x_alist.l_n - index - ndelete) * sizeof(*x->x_alist.l_vec));
x->x_alist.l_vec = (t_listelem *)resizebytes(x->x_alist.l_vec, (x->x_alist.l_n) * sizeof(*x->x_alist.l_vec), (x->x_alist.l_n - ndelete) * sizeof(*x->x_alist.l_vec));
x->x_alist.l_n -= ndelete;
}
static void list_store_set(t_list_store *x, t_symbol *s, int argc, t_atom *argv) { if (argc < 2) return;
/* first atom is the index where to start copying the atoms */ int index = atom_getfloat(argv); if (index < 0) index = 0; if (index > x->x_alist.l_n - 1) index = x->x_alist.l_n - 1; argc--; argv++;
/* copy remaining atoms */ int maxlength = x->x_alist.l_n - index; /* for now we truncate. we could also append remaining atoms... */ if (argc > maxlength) argc = maxlength;
/* first unset pointers */ if (x->x_alist.l_npointer) { t_listelem *vec = x->x_alist.l_vec; for (int i = 0; i < argc; i++) { if (vec[index + i].l_a.a_type == A_POINTER) { gpointer_unset(vec[i+index].l_a.a_w.w_gpointer); x->x_alist.l_npointer--; } } } /* then copy */ alist_copyin(&x->x_alist, s, argc, argv, index); }
static void list_store_get(t_list_store *x, float f1, float f2) { t_atom *outv; int onset = f1, outc = f2; if (onset < 0 || outc < 0) { pd_error(x, "list_store_range: negative range (%d %d)", onset, outc); return; } if (onset + outc > x->x_alist.l_n) { outlet_bang(x->x_out2); return; } ATOMS_ALLOCA(outv, outc); if (x->x_alist.l_npointer) { t_alist y; alist_clone(&x->x_alist, &y, onset, outc); alist_toatoms(&y, outv, onset, outc); outlet_list(x->x_out1, &s_list, outc, outv); alist_clear(&y); } else { alist_toatoms(&x->x_alist, outv, onset, outc); outlet_list(x->x_out1, &s_list, outc, outv); } ATOMS_FREEA(outv, outc); }
static void list_store_range(t_list_store *x, float f1, float f2) { list_store_get(x, f1, f2); }
static void list_store_free(t_list_store *x) { alist_clear(&x->x_alist); }
static void list_store_setup(void) { list_store_class = class_new(gensym("list store"), (t_newmethod)list_store_new, (t_method)list_store_free, sizeof(t_list_store), 0, A_GIMME, 0); class_addlist(list_store_class, list_store_list); class_addmethod(list_store_class, (t_method)list_store_set, gensym("set"), A_GIMME, 0); class_addmethod(list_store_class, (t_method)list_store_get, gensym("get"), A_FLOAT, A_FLOAT, 0); class_addmethod(list_store_class, (t_method)list_store_range, gensym("range"), A_FLOAT, A_FLOAT, 0); /* alias for "get" */ class_addmethod(list_store_class, (t_method)list_store_insert, gensym("insert"), A_GIMME, 0); class_addmethod(list_store_class, (t_method)list_store_append, gensym("append"), A_GIMME, 0); class_addmethod(list_store_class, (t_method)list_store_prepend, gensym("prepend"), A_GIMME, 0); class_addmethod(list_store_class, (t_method)list_store_delete, gensym("delete"), A_FLOAT, A_FLOAT, 0);
class_sethelpsymbol(list_store_class, &s_list);
}
/* ------------- list split --------------------- */
t_class *list_split_class;
typedef struct _list_split { t_object x_obj; t_float x_f; t_outlet *x_out1; t_outlet *x_out2; t_outlet *x_out3; } t_list_split;
static void *list_split_new(t_floatarg f) { t_list_split *x = (t_list_split *)pd_new(list_split_class); x->x_out1 = outlet_new(&x->x_obj, &s_list); x->x_out2 = outlet_new(&x->x_obj, &s_list); x->x_out3 = outlet_new(&x->x_obj, &s_list); floatinlet_new(&x->x_obj, &x->x_f); x->x_f = f; return (x); }
static void list_split_list(t_list_split *x, t_symbol *s, int argc, t_atom *argv) { int n = x->x_f; if (n < 0) n = 0; if (argc >= n) { outlet_list(x->x_out2, &s_list, argc-n, argv+n); outlet_list(x->x_out1, &s_list, n, argv); } else outlet_list(x->x_out3, &s_list, argc, argv); }
static void list_split_anything(t_list_split *x, t_symbol *s, int argc, t_atom *argv) { t_atom *outv; ATOMS_ALLOCA(outv, argc+1); SETSYMBOL(outv, s); atoms_copy(argc, argv, outv + 1); list_split_list(x, &s_list, argc+1, outv); ATOMS_FREEA(outv, argc+1); }
static void list_split_setup(void) { list_split_class = class_new(gensym("list split"), (t_newmethod)list_split_new, 0, sizeof(t_list_split), 0, A_DEFFLOAT, 0); class_addlist(list_split_class, list_split_list); class_addanything(list_split_class, list_split_anything); class_sethelpsymbol(list_split_class, &s_list); }
/* ------------- list trim --------------------- */
t_class *list_trim_class;
typedef struct _list_trim { t_object x_obj; } t_list_trim;
static void *list_trim_new( void) { t_list_trim *x = (t_list_trim *)pd_new(list_trim_class); outlet_new(&x->x_obj, &s_list); return (x); }
static void list_trim_list(t_list_trim *x, t_symbol *s, int argc, t_atom *argv) { if (argc < 1 || argv[0].a_type != A_SYMBOL) outlet_list(x->x_obj.ob_outlet, &s_list, argc, argv); else outlet_anything(x->x_obj.ob_outlet, argv[0].a_w.w_symbol, argc-1, argv+1); }
static void list_trim_anything(t_list_trim *x, t_symbol *s, int argc, t_atom *argv) { outlet_anything(x->x_obj.ob_outlet, s, argc, argv); }
static void list_trim_setup(void) { list_trim_class = class_new(gensym("list trim"), (t_newmethod)list_trim_new, 0, sizeof(t_list_trim), 0, 0); class_addlist(list_trim_class, list_trim_list); class_addanything(list_trim_class, list_trim_anything); class_sethelpsymbol(list_trim_class, &s_list); }
/* ------------- list length --------------------- */
t_class *list_length_class;
typedef struct _list_length { t_object x_obj; } t_list_length;
static void *list_length_new( void) { t_list_length *x = (t_list_length *)pd_new(list_length_class); outlet_new(&x->x_obj, &s_float); return (x); }
static void list_length_list(t_list_length *x, t_symbol *s, int argc, t_atom *argv) { outlet_float(x->x_obj.ob_outlet, (t_float)argc); }
static void list_length_anything(t_list_length *x, t_symbol *s, int argc, t_atom *argv) { outlet_float(x->x_obj.ob_outlet, (t_float)argc+1); }
static void list_length_setup(void) { list_length_class = class_new(gensym("list length"), (t_newmethod)list_length_new, 0, sizeof(t_list_length), 0, 0); class_addlist(list_length_class, list_length_list); class_addanything(list_length_class, list_length_anything); class_sethelpsymbol(list_length_class, &s_list); }
/* ------------- list fromsymbol --------------------- */
t_class *list_fromsymbol_class;
typedef struct _list_fromsymbol { t_object x_obj; } t_list_fromsymbol;
static void *list_fromsymbol_new( void) { t_list_fromsymbol *x = (t_list_fromsymbol *)pd_new(list_fromsymbol_class); outlet_new(&x->x_obj, &s_list); return (x); }
static void list_fromsymbol_symbol(t_list_fromsymbol *x, t_symbol *s) { t_atom *outv; int n, outc = strlen(s->s_name); ATOMS_ALLOCA(outv, outc); for (n = 0; n < outc; n++) SETFLOAT(outv + n, (unsigned char)s->s_name[n]); outlet_list(x->x_obj.ob_outlet, &s_list, outc, outv); ATOMS_FREEA(outv, outc); }
static void list_fromsymbol_setup(void) { list_fromsymbol_class = class_new(gensym("list fromsymbol"), (t_newmethod)list_fromsymbol_new, 0, sizeof(t_list_fromsymbol), 0, 0); class_addsymbol(list_fromsymbol_class, list_fromsymbol_symbol); class_sethelpsymbol(list_fromsymbol_class, &s_list); }
/* ------------- list tosymbol --------------------- */
t_class *list_tosymbol_class;
typedef struct _list_tosymbol { t_object x_obj; } t_list_tosymbol;
static void *list_tosymbol_new( void) { t_list_tosymbol *x = (t_list_tosymbol *)pd_new(list_tosymbol_class); outlet_new(&x->x_obj, &s_symbol); return (x); }
static void list_tosymbol_list(t_list_tosymbol *x, t_symbol *s, int argc, t_atom *argv) { int i; #if HAVE_ALLOCA char *str = alloca(argc + 1); #else char *str = getbytes(argc + 1); #endif for (i = 0; i < argc; i++) str[i] = (char)atom_getfloatarg(i, argc, argv); str[argc] = 0; outlet_symbol(x->x_obj.ob_outlet, gensym(str)); #if HAVE_ALLOCA #else freebytes(str, argc+1); #endif }
static void list_tosymbol_setup(void) { list_tosymbol_class = class_new(gensym("list tosymbol"), (t_newmethod)list_tosymbol_new, 0, sizeof(t_list_tosymbol), 0, 0); class_addlist(list_tosymbol_class, list_tosymbol_list); class_sethelpsymbol(list_tosymbol_class, &s_list); }
/* ------------- list ------------------- */
static void *list_new(t_pd *dummy, t_symbol *s, int argc, t_atom *argv) { if (!argc || argv[0].a_type != A_SYMBOL) pd_this->pd_newest = list_append_new(s, argc, argv); else { t_symbol *s2 = argv[0].a_w.w_symbol; if (s2 == gensym("append")) pd_this->pd_newest = list_append_new(s, argc-1, argv+1); else if (s2 == gensym("prepend")) pd_this->pd_newest = list_prepend_new(s, argc-1, argv+1); else if (s2 == gensym("split")) pd_this->pd_newest = list_split_new(atom_getfloatarg(1, argc, argv)); else if (s2 == gensym("trim")) pd_this->pd_newest = list_trim_new(); else if (s2 == gensym("length")) pd_this->pd_newest = list_length_new(); else if (s2 == gensym("fromsymbol")) pd_this->pd_newest = list_fromsymbol_new(); else if (s2 == gensym("tosymbol")) pd_this->pd_newest = list_tosymbol_new(); else if (s2 == gensym("store")) pd_this->pd_newest = list_store_new(s, argc-1, argv+1); else { error("list %s: unknown function", s2->s_name); pd_this->pd_newest = 0; } } return (pd_this->pd_newest); }
void x_list_setup(void) { alist_setup(); list_append_setup(); list_prepend_setup(); list_store_setup(); list_split_setup(); list_trim_setup(); list_length_setup(); list_fromsymbol_setup(); list_tosymbol_setup(); class_addcreator((t_newmethod)list_new, &s_list, A_GIMME, 0); }
Pd-dev mailing list Pd-dev@lists.iem.at https://lists.puredata.info/listinfo/pd-dev
Yeah, let's save this for later. In the meantime I'll try to hunt down the pointer bugs...
Gesendet: Freitag, 21. Juli 2017 um 19:58 Uhr Von: "Miller Puckette" msp@ucsd.edu An: "Christof Ressi" christof.ressi@gmx.at Cc: "Dan Wilcox" danomatika@gmail.com, pd-dev@iem.at Betreff: Re: [PD-dev] 0.48.0 release status
OK... for now, I renamed "range" to "get" (did it right away to avoid the necessity of keeping the other name for compatibility). We can mess with the other stuff later.
Not sure about the pointer issues, will just hope that doesn't bite us before I can look closer at it.
Meanwhile, yeah, I can think of losts of cool things to try (e.g., "sort")
cheers Miller
On Fri, Jul 21, 2017 at 06:20:49PM +0200, Christof Ressi wrote:
Thanks for your answer! I guess it doesn't have high priority but anyway, the thing is this:
I'm really happy about [list store] but I think it can be way more expressive. My idea was to take the interface of [text] and [array] to add more methods.
First, I renamed [range( to [get( (but kept the old method around as an alias) because it's structurally very similar to [text get] and [array get].
Then I added a method [set <f> ...( which lets you overwrite atoms, just like [text set] and [array set]. the first float is the index, followed by the atoms you want to copy.
Then I added a general [insert <f> ...( method which lets you insert atoms, where the first float is the index, followed by the atoms you want to insert *before* that index. A large index lets you append atoms. I kept [prepend ...( and [append ...( as shortcuts for those two special cases.
Finally I added a [delete <f> <f>( method where the first float is the index to start deleting and the second float is the number of floats to delete.
These methods would turn [list store] into a powerful dynamically sized type-agnostic array - which we don't have in Pd yet! [text] comes closest, but it doesn't handle pointers and it bashes everything to binbufs which sometimes leads to unexpected or undesired behaviour.
Please find my version of x_list.c(which also includes the bug fix that you've already applied) and a messy test patch attached. I didn't have much time...
The methods works well with floats and symbols but there are mysterious bugs with pointers. Not only with my new method but also with your [range( method (which I didn't change). For example, sequencing a list of pointers creates 'consistency check failed' errors with [print] and sometimes there are crashes with segmentation faults.
Also, I'm wondering if memmove() and realloc() is really safe with arrays of t_listelem because a gpointer atom l_a inside t_listelem points to l_a. when the array changes location in memory, won't the pointer point to the wrong location?
I know there are more important things to do right now. Just have look when you have time.
Thanks!
Christof
Gesendet: Freitag, 21. Juli 2017 um 17:26 Uhr Von: "Miller Puckette" msp@ucsd.edu An: "Christof Ressi" christof.ressi@gmx.at Cc: "Dan Wilcox" danomatika@gmail.com, pd-dev@iem.at Betreff: Re: [PD-dev] 0.48.0 release status
Always open to bug reports (although swamped right now I'm afraid, will only get to things that are either urgent or easy :)
I've already fixed "list_store_range" following your earlier report, thanks.
Miller
On Fri, Jul 21, 2017 at 01:05:15PM +0200, Christof Ressi wrote:
I got some more feedback/code for [list store], apart from the list_store_range bug I've already reported on the list. Is there some time left for you guys to review it? I can send it in a couple of hours. I'm travelling right now.
Christof
Gesendet: Freitag, 21. Juli 2017 um 11:54 Uhr Von: "Dan Wilcox" danomatika@gmail.com An: pd-dev@iem.at Cc: "Miller Puckette" msp@ucsd.edu Betreff: [PD-dev] 0.48.0 release status
Ok all, at this point we've nailed most of the bugs and feedback so far. The latest PR is https://github.com/pure-data/pure-data/pull/123 https://github.com/pure-data/pure-data/pull/123
As far as I can tell, the only remaining things which could be done/included for the release are:
Small Stuff
- Remove midiin & sysexin Windows warnings in x_midi.c (& update help file)
(Optional) Big Stuff
- Adopt DejaVu Sans Mono a the default font -> this is in the dejavu branch https://github.com/pure-data/pure-data/pull/42 https://github.com/pure-data/pure-data/pull/42 This is mainly for mac & Linux, Windows support will need to be added later as mentioned in the discussion. It also fixes the bad Monaco rendering on retina screens at small font sizes.
- Update the icon -> see my pd-icon repo https://github.com/pure-data/pd-icon https://github.com/pure-data/pd-icon & the recent thread on the pd-list
There may be more things, but I think I'm done on my end for now. We could do one final test release after this, but hopefully the feedback bugs will all have been fixed.
Dan Wilcox @danomatika http://twitter.com/danomatika danomatika.com http://danomatika.com/ robotcowboy.com http://robotcowboy.com/
Pd-dev mailing list Pd-dev@lists.iem.at https://lists.puredata.info/listinfo/pd-dev
Pd-dev mailing list Pd-dev@lists.iem.at https://lists.puredata.info/listinfo/pd-dev
/* Copyright (c) 1997- Miller Puckette and others.
- For information on usage and redistribution, and for a DISCLAIMER OF ALL
- WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
#include "m_pd.h" #include <string.h>
#ifdef _WIN32 # include <malloc.h> /* MSVC or mingw on windows */ #elif defined(__linux__) || defined(__APPLE__) # include <alloca.h> /* linux, mac, mingw, cygwin */ #else # include <stdlib.h> /* BSDs for example */ #endif
#ifndef HAVE_ALLOCA /* can work without alloca() but we never need it */ #define HAVE_ALLOCA 1 #endif
#define LIST_NGETBYTE 100 /* bigger that this we use alloc, not alloca */
/* the "list" object family.
list append - append a list to another list prepend - prepend a list to another list split - first n elements to first outlet, rest to second outlet list trim - trim off "list" selector list length - output number of items in list list fromsymbol - "explode" a symbol into a list of character codes
Need to think more about: list foreach - spit out elements of a list one by one (also in reverse?) list reverse - permute elements of a list back to front list cat - build a list by accumulating elements
Probably don't need: list first - output first n elements. list last - output last n elements list nth - nth item in list, counting from zero list array - get items from a named array as a list list pack - synonym for 'pack' list unpack - synonym for 'unpack' */
/* -------------- utility functions: storage, copying -------------- */ /* List element for storage. Keep an atom and, in case it's a pointer, an associated 'gpointer' to protect against stale pointers. */ typedef struct _listelem { t_atom l_a; t_gpointer l_p; } t_listelem;
typedef struct _alist { t_pd l_pd; /* object to point inlets to */ int l_n; /* number of items */ int l_npointer; /* number of pointers */ t_listelem *l_vec; /* pointer to items */ } t_alist;
#if HAVE_ALLOCA #define ATOMS_ALLOCA(x, n) ((x) = (t_atom *)((n) < LIST_NGETBYTE ? \ alloca((n) * sizeof(t_atom)) : getbytes((n) * sizeof(t_atom)))) #define ATOMS_FREEA(x, n) ( \ ((n) < LIST_NGETBYTE || (freebytes((x), (n) * sizeof(t_atom)), 0))) #else #define ATOMS_ALLOCA(x, n) ((x) = (t_atom *)getbytes((n) * sizeof(t_atom))) #define ATOMS_FREEA(x, n) (freebytes((x), (n) * sizeof(t_atom))) #endif
static void atoms_copy(int argc, t_atom *from, t_atom *to) { int i; for (i = 0; i < argc; i++) to[i] = from[i]; }
/* ------------- fake class to divert inlets to ----------------- */
t_class *alist_class;
static void alist_init(t_alist *x) { x->l_pd = alist_class; x->l_n = x->l_npointer = 0; x->l_vec = 0; }
static void alist_clear(t_alist *x) { int i; for (i = 0; i < x->l_n; i++) { if (x->l_vec[i].l_a.a_type == A_POINTER) gpointer_unset(x->l_vec[i].l_a.a_w.w_gpointer); } if (x->l_vec) freebytes(x->l_vec, x->l_n * sizeof(*x->l_vec)); }
static void alist_copyin(t_alist *x, t_symbol *s, int argc, t_atom *argv, int where) { int i, j; for (i = 0, j = where; i < argc; i++, j++) { x->l_vec[j].l_a = argv[i]; if (x->l_vec[j].l_a.a_type == A_POINTER) { x->l_npointer++; gpointer_copy(x->l_vec[j].l_a.a_w.w_gpointer, &x->l_vec[j].l_p); x->l_vec[j].l_a.a_w.w_gpointer = &x->l_vec[j].l_p; } } }
/* set contents to a list */
static void alist_list(t_alist *x, t_symbol *s, int argc, t_atom *argv) { alist_clear(x); if (!(x->l_vec = (t_listelem *)getbytes(argc * sizeof(*x->l_vec)))) { x->l_n = 0; error("list: out of memory"); return; } x->l_n = argc; x->l_npointer = 0; alist_copyin(x, s, argc, argv, 0); }
/* set contents to an arbitrary non-list message */
static void alist_anything(t_alist *x, t_symbol *s, int argc, t_atom *argv) { int i; alist_clear(x); if (!(x->l_vec = (t_listelem *)getbytes((argc+1) * sizeof(*x->l_vec)))) { x->l_n = 0; error("list_alloc: out of memory"); return; } x->l_n = argc+1; x->l_npointer = 0; SETSYMBOL(&x->l_vec[0].l_a, s); for (i = 0; i < argc; i++) { x->l_vec[i+1].l_a = argv[i]; if (x->l_vec[i+1].l_a.a_type == A_POINTER) { x->l_npointer++; gpointer_copy(x->l_vec[i+1].l_a.a_w.w_gpointer, &x->l_vec[i+1].l_p); x->l_vec[i+1].l_a.a_w.w_gpointer = &x->l_vec[i+1].l_p; } } }
static void alist_toatoms(t_alist *x, t_atom *to, int onset, int count) { int i; for (i = 0; i < count; i++) to[i] = x->l_vec[onset + i].l_a; }
static void alist_clone(t_alist *x, t_alist *y, int onset, int count) { int i; y->l_pd = alist_class; y->l_n = count; y->l_npointer = 0; if (!(y->l_vec = (t_listelem *)getbytes(y->l_n * sizeof(*y->l_vec)))) { y->l_n = 0; error("list_alloc: out of memory"); } else for (i = 0; i < count; i++) { y->l_vec[i].l_a = x->l_vec[onset + i].l_a; if (y->l_vec[i].l_a.a_type == A_POINTER) { gpointer_copy(y->l_vec[i].l_a.a_w.w_gpointer, &y->l_vec[i].l_p); y->l_vec[i].l_a.a_w.w_gpointer = &y->l_vec[i].l_p; y->l_npointer++; } } }
static void alist_setup(void) { alist_class = class_new(gensym("list inlet"), 0, 0, sizeof(t_alist), 0, 0); class_addlist(alist_class, alist_list); class_addanything(alist_class, alist_anything); }
/* ------------- list append --------------------- */
t_class *list_append_class;
typedef struct _list_append { t_object x_obj; t_alist x_alist; } t_list_append;
static void *list_append_new(t_symbol *s, int argc, t_atom *argv) { t_list_append *x = (t_list_append *)pd_new(list_append_class); alist_init(&x->x_alist); alist_list(&x->x_alist, 0, argc, argv); outlet_new(&x->x_obj, &s_list); inlet_new(&x->x_obj, &x->x_alist.l_pd, 0, 0); return (x); }
static void list_append_list(t_list_append *x, t_symbol *s, int argc, t_atom *argv) { t_atom *outv; int n, outc = x->x_alist.l_n + argc; ATOMS_ALLOCA(outv, outc); atoms_copy(argc, argv, outv); if (x->x_alist.l_npointer) { t_alist y; alist_clone(&x->x_alist, &y, 0, x->x_alist.l_n); alist_toatoms(&y, outv+argc, 0, x->x_alist.l_n); outlet_list(x->x_obj.ob_outlet, &s_list, outc, outv); alist_clear(&y); } else { alist_toatoms(&x->x_alist, outv+argc, 0, x->x_alist.l_n); outlet_list(x->x_obj.ob_outlet, &s_list, outc, outv); } ATOMS_FREEA(outv, outc); }
static void list_append_anything(t_list_append *x, t_symbol *s, int argc, t_atom *argv) { t_atom *outv; int n, outc = x->x_alist.l_n + argc + 1; ATOMS_ALLOCA(outv, outc); SETSYMBOL(outv, s); atoms_copy(argc, argv, outv + 1); if (x->x_alist.l_npointer) { t_alist y; alist_clone(&x->x_alist, &y, 0, x->x_alist.l_n); alist_toatoms(&y, outv + 1 + argc, 0, x->x_alist.l_n); outlet_list(x->x_obj.ob_outlet, &s_list, outc, outv); alist_clear(&y); } else { alist_toatoms(&x->x_alist, outv + 1 + argc, 0, x->x_alist.l_n); outlet_list(x->x_obj.ob_outlet, &s_list, outc, outv); } ATOMS_FREEA(outv, outc); }
static void list_append_append(t_list_append *x, t_symbol *s, int argc, t_atom *argv) { if (!(x->x_alist.l_vec = (t_listelem *)resizebytes(x->x_alist.l_vec, (x->x_alist.l_n) * sizeof(*x->x_alist.l_vec), (x->x_alist.l_n + argc) * sizeof(*x->x_alist.l_vec)))) { x->x_alist.l_n = 0; error("list: out of memory"); return; } alist_copyin(&x->x_alist, s, argc, argv, x->x_alist.l_n); x->x_alist.l_n += argc; }
static void list_append_prepend(t_list_append *x, t_symbol *s, int argc, t_atom *argv) { if (!(x->x_alist.l_vec = (t_listelem *)resizebytes(x->x_alist.l_vec, (x->x_alist.l_n) * sizeof(*x->x_alist.l_vec), (x->x_alist.l_n + argc) * sizeof(*x->x_alist.l_vec)))) { x->x_alist.l_n = 0; error("list: out of memory"); return; } memmove(x->x_alist.l_vec + argc, x->x_alist.l_vec, x->x_alist.l_n * sizeof(*x->x_alist.l_vec)); alist_copyin(&x->x_alist, s, argc, argv, 0); x->x_alist.l_n += argc; }
static void list_append_free(t_list_append *x) { alist_clear(&x->x_alist); }
static void list_append_setup(void) { list_append_class = class_new(gensym("list append"), (t_newmethod)list_append_new, (t_method)list_append_free, sizeof(t_list_append), 0, A_GIMME, 0); class_addlist(list_append_class, list_append_list); class_addanything(list_append_class, list_append_anything); class_sethelpsymbol(list_append_class, &s_list); }
/* ------------- list prepend --------------------- */
t_class *list_prepend_class;
typedef t_list_append t_list_prepend;
static void *list_prepend_new(t_symbol *s, int argc, t_atom *argv) { t_list_prepend *x = (t_list_prepend *)pd_new(list_prepend_class); alist_init(&x->x_alist); alist_list(&x->x_alist, 0, argc, argv); outlet_new(&x->x_obj, &s_list); inlet_new(&x->x_obj, &x->x_alist.l_pd, 0, 0); return (x); }
static void list_prepend_list(t_list_prepend *x, t_symbol *s, int argc, t_atom *argv) { t_atom *outv; int n, outc = x->x_alist.l_n + argc; ATOMS_ALLOCA(outv, outc); atoms_copy(argc, argv, outv + x->x_alist.l_n); if (x->x_alist.l_npointer) { t_alist y; alist_clone(&x->x_alist, &y, 0, x->x_alist.l_n); alist_toatoms(&y, outv, 0, x->x_alist.l_n); outlet_list(x->x_obj.ob_outlet, &s_list, outc, outv); alist_clear(&y); } else { alist_toatoms(&x->x_alist, outv, 0, x->x_alist.l_n); outlet_list(x->x_obj.ob_outlet, &s_list, outc, outv); } ATOMS_FREEA(outv, outc); }
static void list_prepend_anything(t_list_prepend *x, t_symbol *s, int argc, t_atom *argv) { t_atom *outv; int n, outc = x->x_alist.l_n + argc + 1; ATOMS_ALLOCA(outv, outc); SETSYMBOL(outv + x->x_alist.l_n, s); atoms_copy(argc, argv, outv + x->x_alist.l_n + 1); if (x->x_alist.l_npointer) { t_alist y; alist_clone(&x->x_alist, &y, 0, x->x_alist.l_n); alist_toatoms(&y, outv, 0, x->x_alist.l_n); outlet_list(x->x_obj.ob_outlet, &s_list, outc, outv); alist_clear(&y); } else { alist_toatoms(&x->x_alist, outv, 0, x->x_alist.l_n); outlet_list(x->x_obj.ob_outlet, &s_list, outc, outv); } ATOMS_FREEA(outv, outc); }
static void list_prepend_free(t_list_prepend *x) { alist_clear(&x->x_alist); }
static void list_prepend_setup(void) { list_prepend_class = class_new(gensym("list prepend"), (t_newmethod)list_prepend_new, (t_method)list_prepend_free, sizeof(t_list_prepend), 0, A_GIMME, 0); class_addlist(list_prepend_class, list_prepend_list); class_addanything(list_prepend_class, list_prepend_anything); class_sethelpsymbol(list_prepend_class, &s_list); }
/* ------------- list store --------------------- */
t_class *list_store_class;
typedef struct _list_store { t_object x_obj; t_alist x_alist; t_outlet *x_out1; t_outlet *x_out2; } t_list_store;
static void *list_store_new(t_symbol *s, int argc, t_atom *argv) { t_list_store *x = (t_list_store *)pd_new(list_store_class); alist_init(&x->x_alist); alist_list(&x->x_alist, 0, argc, argv); x->x_out1 = outlet_new(&x->x_obj, &s_list); x->x_out2 = outlet_new(&x->x_obj, &s_bang); inlet_new(&x->x_obj, &x->x_alist.l_pd, 0, 0); return (x); }
static void list_store_list(t_list_store *x, t_symbol *s, int argc, t_atom *argv) { t_atom *outv; int n, outc = x->x_alist.l_n + argc; ATOMS_ALLOCA(outv, outc); atoms_copy(argc, argv, outv); if (x->x_alist.l_npointer) { t_alist y; alist_clone(&x->x_alist, &y, 0, x->x_alist.l_n); alist_toatoms(&y, outv+argc, 0, x->x_alist.l_n); outlet_list(x->x_out1, &s_list, outc, outv); alist_clear(&y); } else { alist_toatoms(&x->x_alist, outv+argc, 0, x->x_alist.l_n); outlet_list(x->x_out1, &s_list, outc, outv); } ATOMS_FREEA(outv, outc); }
/* insert atoms before a given index */ static void list_store_doinsert(t_list_store *x, int index, t_symbol *s, int argc, t_atom *argv) { if (index < 0) index = 0; /* index = 0 -> prepend */ if (index > x->x_alist.l_n) index = x->x_alist.l_n; /* index >= length -> append */
if (!(x->x_alist.l_vec = (t_listelem *)resizebytes(x->x_alist.l_vec, (x->x_alist.l_n) * sizeof(*x->x_alist.l_vec), (x->x_alist.l_n + argc) * sizeof(*x->x_alist.l_vec)))) { x->x_alist.l_n = 0; error("list: out of memory"); return; } /* we don't need memmove for appending */ if (index < x->x_alist.l_n){ memmove(x->x_alist.l_vec + index + argc, x->x_alist.l_vec + index, (x->x_alist.l_n - index) * sizeof(*x->x_alist.l_vec)); } alist_copyin(&x->x_alist, s, argc, argv, index); x->x_alist.l_n += argc; }
static void list_store_insert(t_list_store *x, t_symbol *s, int argc, t_atom *argv) { if (argc < 2) return;
/* first atom is the index where to start inserting atoms. */ int index = atom_getfloat(argv); argc--; argv++; /* insert remaining atoms */ list_store_doinsert(x, index, s, argc, argv); }
static void list_store_append(t_list_store *x, t_symbol *s, int argc, t_atom *argv) { list_store_doinsert(x, 1e+009, s, argc, argv); }
static void list_store_prepend(t_list_store *x, t_symbol *s, int argc, t_atom *argv) { list_store_doinsert(x, 0, s, argc, argv); }
static void list_store_delete(t_list_store *x, float f1, float f2) { int index = f1; int ndelete = f2;
if (index < 0) index = 0; if (index >= x->x_alist.l_n) return; /* out of range: nothing to delete */
int maxlength = x->x_alist.l_n - index; if (ndelete > maxlength) ndelete = maxlength;
/* first unset pointers */ if (x->x_alist.l_npointer) { t_listelem *vec = x->x_alist.l_vec; for (int i = 0; i < ndelete; i++) { if (vec[index + i].l_a.a_type == A_POINTER) { gpointer_unset(vec[i].l_a.a_w.w_gpointer); x->x_alist.l_npointer--; post("remaining number of pointers: %d", x->x_alist.l_npointer); } } }
/* then move atoms */ memmove(x->x_alist.l_vec + index, x->x_alist.l_vec + index + ndelete, (x->x_alist.l_n - index - ndelete) * sizeof(*x->x_alist.l_vec));
x->x_alist.l_vec = (t_listelem *)resizebytes(x->x_alist.l_vec, (x->x_alist.l_n) * sizeof(*x->x_alist.l_vec), (x->x_alist.l_n - ndelete) * sizeof(*x->x_alist.l_vec));
x->x_alist.l_n -= ndelete;
}
static void list_store_set(t_list_store *x, t_symbol *s, int argc, t_atom *argv) { if (argc < 2) return;
/* first atom is the index where to start copying the atoms */ int index = atom_getfloat(argv); if (index < 0) index = 0; if (index > x->x_alist.l_n - 1) index = x->x_alist.l_n - 1; argc--; argv++;
/* copy remaining atoms */ int maxlength = x->x_alist.l_n - index; /* for now we truncate. we could also append remaining atoms... */ if (argc > maxlength) argc = maxlength;
/* first unset pointers */ if (x->x_alist.l_npointer) { t_listelem *vec = x->x_alist.l_vec; for (int i = 0; i < argc; i++) { if (vec[index + i].l_a.a_type == A_POINTER) { gpointer_unset(vec[i+index].l_a.a_w.w_gpointer); x->x_alist.l_npointer--; } } } /* then copy */ alist_copyin(&x->x_alist, s, argc, argv, index); }
static void list_store_get(t_list_store *x, float f1, float f2) { t_atom *outv; int onset = f1, outc = f2; if (onset < 0 || outc < 0) { pd_error(x, "list_store_range: negative range (%d %d)", onset, outc); return; } if (onset + outc > x->x_alist.l_n) { outlet_bang(x->x_out2); return; } ATOMS_ALLOCA(outv, outc); if (x->x_alist.l_npointer) { t_alist y; alist_clone(&x->x_alist, &y, onset, outc); alist_toatoms(&y, outv, onset, outc); outlet_list(x->x_out1, &s_list, outc, outv); alist_clear(&y); } else { alist_toatoms(&x->x_alist, outv, onset, outc); outlet_list(x->x_out1, &s_list, outc, outv); } ATOMS_FREEA(outv, outc); }
static void list_store_range(t_list_store *x, float f1, float f2) { list_store_get(x, f1, f2); }
static void list_store_free(t_list_store *x) { alist_clear(&x->x_alist); }
static void list_store_setup(void) { list_store_class = class_new(gensym("list store"), (t_newmethod)list_store_new, (t_method)list_store_free, sizeof(t_list_store), 0, A_GIMME, 0); class_addlist(list_store_class, list_store_list); class_addmethod(list_store_class, (t_method)list_store_set, gensym("set"), A_GIMME, 0); class_addmethod(list_store_class, (t_method)list_store_get, gensym("get"), A_FLOAT, A_FLOAT, 0); class_addmethod(list_store_class, (t_method)list_store_range, gensym("range"), A_FLOAT, A_FLOAT, 0); /* alias for "get" */ class_addmethod(list_store_class, (t_method)list_store_insert, gensym("insert"), A_GIMME, 0); class_addmethod(list_store_class, (t_method)list_store_append, gensym("append"), A_GIMME, 0); class_addmethod(list_store_class, (t_method)list_store_prepend, gensym("prepend"), A_GIMME, 0); class_addmethod(list_store_class, (t_method)list_store_delete, gensym("delete"), A_FLOAT, A_FLOAT, 0);
class_sethelpsymbol(list_store_class, &s_list);
}
/* ------------- list split --------------------- */
t_class *list_split_class;
typedef struct _list_split { t_object x_obj; t_float x_f; t_outlet *x_out1; t_outlet *x_out2; t_outlet *x_out3; } t_list_split;
static void *list_split_new(t_floatarg f) { t_list_split *x = (t_list_split *)pd_new(list_split_class); x->x_out1 = outlet_new(&x->x_obj, &s_list); x->x_out2 = outlet_new(&x->x_obj, &s_list); x->x_out3 = outlet_new(&x->x_obj, &s_list); floatinlet_new(&x->x_obj, &x->x_f); x->x_f = f; return (x); }
static void list_split_list(t_list_split *x, t_symbol *s, int argc, t_atom *argv) { int n = x->x_f; if (n < 0) n = 0; if (argc >= n) { outlet_list(x->x_out2, &s_list, argc-n, argv+n); outlet_list(x->x_out1, &s_list, n, argv); } else outlet_list(x->x_out3, &s_list, argc, argv); }
static void list_split_anything(t_list_split *x, t_symbol *s, int argc, t_atom *argv) { t_atom *outv; ATOMS_ALLOCA(outv, argc+1); SETSYMBOL(outv, s); atoms_copy(argc, argv, outv + 1); list_split_list(x, &s_list, argc+1, outv); ATOMS_FREEA(outv, argc+1); }
static void list_split_setup(void) { list_split_class = class_new(gensym("list split"), (t_newmethod)list_split_new, 0, sizeof(t_list_split), 0, A_DEFFLOAT, 0); class_addlist(list_split_class, list_split_list); class_addanything(list_split_class, list_split_anything); class_sethelpsymbol(list_split_class, &s_list); }
/* ------------- list trim --------------------- */
t_class *list_trim_class;
typedef struct _list_trim { t_object x_obj; } t_list_trim;
static void *list_trim_new( void) { t_list_trim *x = (t_list_trim *)pd_new(list_trim_class); outlet_new(&x->x_obj, &s_list); return (x); }
static void list_trim_list(t_list_trim *x, t_symbol *s, int argc, t_atom *argv) { if (argc < 1 || argv[0].a_type != A_SYMBOL) outlet_list(x->x_obj.ob_outlet, &s_list, argc, argv); else outlet_anything(x->x_obj.ob_outlet, argv[0].a_w.w_symbol, argc-1, argv+1); }
static void list_trim_anything(t_list_trim *x, t_symbol *s, int argc, t_atom *argv) { outlet_anything(x->x_obj.ob_outlet, s, argc, argv); }
static void list_trim_setup(void) { list_trim_class = class_new(gensym("list trim"), (t_newmethod)list_trim_new, 0, sizeof(t_list_trim), 0, 0); class_addlist(list_trim_class, list_trim_list); class_addanything(list_trim_class, list_trim_anything); class_sethelpsymbol(list_trim_class, &s_list); }
/* ------------- list length --------------------- */
t_class *list_length_class;
typedef struct _list_length { t_object x_obj; } t_list_length;
static void *list_length_new( void) { t_list_length *x = (t_list_length *)pd_new(list_length_class); outlet_new(&x->x_obj, &s_float); return (x); }
static void list_length_list(t_list_length *x, t_symbol *s, int argc, t_atom *argv) { outlet_float(x->x_obj.ob_outlet, (t_float)argc); }
static void list_length_anything(t_list_length *x, t_symbol *s, int argc, t_atom *argv) { outlet_float(x->x_obj.ob_outlet, (t_float)argc+1); }
static void list_length_setup(void) { list_length_class = class_new(gensym("list length"), (t_newmethod)list_length_new, 0, sizeof(t_list_length), 0, 0); class_addlist(list_length_class, list_length_list); class_addanything(list_length_class, list_length_anything); class_sethelpsymbol(list_length_class, &s_list); }
/* ------------- list fromsymbol --------------------- */
t_class *list_fromsymbol_class;
typedef struct _list_fromsymbol { t_object x_obj; } t_list_fromsymbol;
static void *list_fromsymbol_new( void) { t_list_fromsymbol *x = (t_list_fromsymbol *)pd_new(list_fromsymbol_class); outlet_new(&x->x_obj, &s_list); return (x); }
static void list_fromsymbol_symbol(t_list_fromsymbol *x, t_symbol *s) { t_atom *outv; int n, outc = strlen(s->s_name); ATOMS_ALLOCA(outv, outc); for (n = 0; n < outc; n++) SETFLOAT(outv + n, (unsigned char)s->s_name[n]); outlet_list(x->x_obj.ob_outlet, &s_list, outc, outv); ATOMS_FREEA(outv, outc); }
static void list_fromsymbol_setup(void) { list_fromsymbol_class = class_new(gensym("list fromsymbol"), (t_newmethod)list_fromsymbol_new, 0, sizeof(t_list_fromsymbol), 0, 0); class_addsymbol(list_fromsymbol_class, list_fromsymbol_symbol); class_sethelpsymbol(list_fromsymbol_class, &s_list); }
/* ------------- list tosymbol --------------------- */
t_class *list_tosymbol_class;
typedef struct _list_tosymbol { t_object x_obj; } t_list_tosymbol;
static void *list_tosymbol_new( void) { t_list_tosymbol *x = (t_list_tosymbol *)pd_new(list_tosymbol_class); outlet_new(&x->x_obj, &s_symbol); return (x); }
static void list_tosymbol_list(t_list_tosymbol *x, t_symbol *s, int argc, t_atom *argv) { int i; #if HAVE_ALLOCA char *str = alloca(argc + 1); #else char *str = getbytes(argc + 1); #endif for (i = 0; i < argc; i++) str[i] = (char)atom_getfloatarg(i, argc, argv); str[argc] = 0; outlet_symbol(x->x_obj.ob_outlet, gensym(str)); #if HAVE_ALLOCA #else freebytes(str, argc+1); #endif }
static void list_tosymbol_setup(void) { list_tosymbol_class = class_new(gensym("list tosymbol"), (t_newmethod)list_tosymbol_new, 0, sizeof(t_list_tosymbol), 0, 0); class_addlist(list_tosymbol_class, list_tosymbol_list); class_sethelpsymbol(list_tosymbol_class, &s_list); }
/* ------------- list ------------------- */
static void *list_new(t_pd *dummy, t_symbol *s, int argc, t_atom *argv) { if (!argc || argv[0].a_type != A_SYMBOL) pd_this->pd_newest = list_append_new(s, argc, argv); else { t_symbol *s2 = argv[0].a_w.w_symbol; if (s2 == gensym("append")) pd_this->pd_newest = list_append_new(s, argc-1, argv+1); else if (s2 == gensym("prepend")) pd_this->pd_newest = list_prepend_new(s, argc-1, argv+1); else if (s2 == gensym("split")) pd_this->pd_newest = list_split_new(atom_getfloatarg(1, argc, argv)); else if (s2 == gensym("trim")) pd_this->pd_newest = list_trim_new(); else if (s2 == gensym("length")) pd_this->pd_newest = list_length_new(); else if (s2 == gensym("fromsymbol")) pd_this->pd_newest = list_fromsymbol_new(); else if (s2 == gensym("tosymbol")) pd_this->pd_newest = list_tosymbol_new(); else if (s2 == gensym("store")) pd_this->pd_newest = list_store_new(s, argc-1, argv+1); else { error("list %s: unknown function", s2->s_name); pd_this->pd_newest = 0; } } return (pd_this->pd_newest); }
void x_list_setup(void) { alist_setup(); list_append_setup(); list_prepend_setup(); list_store_setup(); list_split_setup(); list_trim_setup(); list_length_setup(); list_fromsymbol_setup(); list_tosymbol_setup(); class_addcreator((t_newmethod)list_new, &s_list, A_GIMME, 0); }
Pd-dev mailing list Pd-dev@lists.iem.at https://lists.puredata.info/listinfo/pd-dev
Hi Miller,
just in case you haven't noticed, here's the promised bugfix for [list store]: https://sourceforge.net/p/pure-data/patches/583/
With this fix I don't get any error messages and crashes anymore.
I've just added a cleaner version.
Christof
Gesendet: Samstag, 22. Juli 2017 um 14:21 Uhr Von: "Christof Ressi" christof.ressi@gmx.at An: "Miller Puckette" msp@ucsd.edu Cc: pd-dev@iem.at Betreff: Re: [PD-dev] 0.48.0 release status
Yeah, let's save this for later. In the meantime I'll try to hunt down the pointer bugs...
Gesendet: Freitag, 21. Juli 2017 um 19:58 Uhr Von: "Miller Puckette" msp@ucsd.edu An: "Christof Ressi" christof.ressi@gmx.at Cc: "Dan Wilcox" danomatika@gmail.com, pd-dev@iem.at Betreff: Re: [PD-dev] 0.48.0 release status
OK... for now, I renamed "range" to "get" (did it right away to avoid the necessity of keeping the other name for compatibility). We can mess with the other stuff later.
Not sure about the pointer issues, will just hope that doesn't bite us before I can look closer at it.
Meanwhile, yeah, I can think of losts of cool things to try (e.g., "sort")
cheers Miller
On Fri, Jul 21, 2017 at 06:20:49PM +0200, Christof Ressi wrote:
Thanks for your answer! I guess it doesn't have high priority but anyway, the thing is this:
I'm really happy about [list store] but I think it can be way more expressive. My idea was to take the interface of [text] and [array] to add more methods.
First, I renamed [range( to [get( (but kept the old method around as an alias) because it's structurally very similar to [text get] and [array get].
Then I added a method [set <f> ...( which lets you overwrite atoms, just like [text set] and [array set]. the first float is the index, followed by the atoms you want to copy.
Then I added a general [insert <f> ...( method which lets you insert atoms, where the first float is the index, followed by the atoms you want to insert *before* that index. A large index lets you append atoms. I kept [prepend ...( and [append ...( as shortcuts for those two special cases.
Finally I added a [delete <f> <f>( method where the first float is the index to start deleting and the second float is the number of floats to delete.
These methods would turn [list store] into a powerful dynamically sized type-agnostic array - which we don't have in Pd yet! [text] comes closest, but it doesn't handle pointers and it bashes everything to binbufs which sometimes leads to unexpected or undesired behaviour.
Please find my version of x_list.c(which also includes the bug fix that you've already applied) and a messy test patch attached. I didn't have much time...
The methods works well with floats and symbols but there are mysterious bugs with pointers. Not only with my new method but also with your [range( method (which I didn't change). For example, sequencing a list of pointers creates 'consistency check failed' errors with [print] and sometimes there are crashes with segmentation faults.
Also, I'm wondering if memmove() and realloc() is really safe with arrays of t_listelem because a gpointer atom l_a inside t_listelem points to l_a. when the array changes location in memory, won't the pointer point to the wrong location?
I know there are more important things to do right now. Just have look when you have time.
Thanks!
Christof
Gesendet: Freitag, 21. Juli 2017 um 17:26 Uhr Von: "Miller Puckette" msp@ucsd.edu An: "Christof Ressi" christof.ressi@gmx.at Cc: "Dan Wilcox" danomatika@gmail.com, pd-dev@iem.at Betreff: Re: [PD-dev] 0.48.0 release status
Always open to bug reports (although swamped right now I'm afraid, will only get to things that are either urgent or easy :)
I've already fixed "list_store_range" following your earlier report, thanks.
Miller
On Fri, Jul 21, 2017 at 01:05:15PM +0200, Christof Ressi wrote:
I got some more feedback/code for [list store], apart from the list_store_range bug I've already reported on the list. Is there some time left for you guys to review it? I can send it in a couple of hours. I'm travelling right now.
Christof
Gesendet: Freitag, 21. Juli 2017 um 11:54 Uhr Von: "Dan Wilcox" danomatika@gmail.com An: pd-dev@iem.at Cc: "Miller Puckette" msp@ucsd.edu Betreff: [PD-dev] 0.48.0 release status
Ok all, at this point we've nailed most of the bugs and feedback so far. The latest PR is https://github.com/pure-data/pure-data/pull/123 https://github.com/pure-data/pure-data/pull/123
As far as I can tell, the only remaining things which could be done/included for the release are:
Small Stuff
- Remove midiin & sysexin Windows warnings in x_midi.c (& update help file)
(Optional) Big Stuff
- Adopt DejaVu Sans Mono a the default font -> this is in the dejavu branch https://github.com/pure-data/pure-data/pull/42 https://github.com/pure-data/pure-data/pull/42 This is mainly for mac & Linux, Windows support will need to be added later as mentioned in the discussion. It also fixes the bad Monaco rendering on retina screens at small font sizes.
- Update the icon -> see my pd-icon repo https://github.com/pure-data/pd-icon https://github.com/pure-data/pd-icon & the recent thread on the pd-list
There may be more things, but I think I'm done on my end for now. We could do one final test release after this, but hopefully the feedback bugs will all have been fixed.
Dan Wilcox @danomatika http://twitter.com/danomatika danomatika.com http://danomatika.com/ robotcowboy.com http://robotcowboy.com/
Pd-dev mailing list Pd-dev@lists.iem.at https://lists.puredata.info/listinfo/pd-dev
Pd-dev mailing list Pd-dev@lists.iem.at https://lists.puredata.info/listinfo/pd-dev
/* Copyright (c) 1997- Miller Puckette and others.
- For information on usage and redistribution, and for a DISCLAIMER OF ALL
- WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
#include "m_pd.h" #include <string.h>
#ifdef _WIN32 # include <malloc.h> /* MSVC or mingw on windows */ #elif defined(__linux__) || defined(__APPLE__) # include <alloca.h> /* linux, mac, mingw, cygwin */ #else # include <stdlib.h> /* BSDs for example */ #endif
#ifndef HAVE_ALLOCA /* can work without alloca() but we never need it */ #define HAVE_ALLOCA 1 #endif
#define LIST_NGETBYTE 100 /* bigger that this we use alloc, not alloca */
/* the "list" object family.
list append - append a list to another list prepend - prepend a list to another list split - first n elements to first outlet, rest to second outlet list trim - trim off "list" selector list length - output number of items in list list fromsymbol - "explode" a symbol into a list of character codes
Need to think more about: list foreach - spit out elements of a list one by one (also in reverse?) list reverse - permute elements of a list back to front list cat - build a list by accumulating elements
Probably don't need: list first - output first n elements. list last - output last n elements list nth - nth item in list, counting from zero list array - get items from a named array as a list list pack - synonym for 'pack' list unpack - synonym for 'unpack' */
/* -------------- utility functions: storage, copying -------------- */ /* List element for storage. Keep an atom and, in case it's a pointer, an associated 'gpointer' to protect against stale pointers. */ typedef struct _listelem { t_atom l_a; t_gpointer l_p; } t_listelem;
typedef struct _alist { t_pd l_pd; /* object to point inlets to */ int l_n; /* number of items */ int l_npointer; /* number of pointers */ t_listelem *l_vec; /* pointer to items */ } t_alist;
#if HAVE_ALLOCA #define ATOMS_ALLOCA(x, n) ((x) = (t_atom *)((n) < LIST_NGETBYTE ? \ alloca((n) * sizeof(t_atom)) : getbytes((n) * sizeof(t_atom)))) #define ATOMS_FREEA(x, n) ( \ ((n) < LIST_NGETBYTE || (freebytes((x), (n) * sizeof(t_atom)), 0))) #else #define ATOMS_ALLOCA(x, n) ((x) = (t_atom *)getbytes((n) * sizeof(t_atom))) #define ATOMS_FREEA(x, n) (freebytes((x), (n) * sizeof(t_atom))) #endif
static void atoms_copy(int argc, t_atom *from, t_atom *to) { int i; for (i = 0; i < argc; i++) to[i] = from[i]; }
/* ------------- fake class to divert inlets to ----------------- */
t_class *alist_class;
static void alist_init(t_alist *x) { x->l_pd = alist_class; x->l_n = x->l_npointer = 0; x->l_vec = 0; }
static void alist_clear(t_alist *x) { int i; for (i = 0; i < x->l_n; i++) { if (x->l_vec[i].l_a.a_type == A_POINTER) gpointer_unset(x->l_vec[i].l_a.a_w.w_gpointer); } if (x->l_vec) freebytes(x->l_vec, x->l_n * sizeof(*x->l_vec)); }
static void alist_copyin(t_alist *x, t_symbol *s, int argc, t_atom *argv, int where) { int i, j; for (i = 0, j = where; i < argc; i++, j++) { x->l_vec[j].l_a = argv[i]; if (x->l_vec[j].l_a.a_type == A_POINTER) { x->l_npointer++; gpointer_copy(x->l_vec[j].l_a.a_w.w_gpointer, &x->l_vec[j].l_p); x->l_vec[j].l_a.a_w.w_gpointer = &x->l_vec[j].l_p; } } }
/* set contents to a list */
static void alist_list(t_alist *x, t_symbol *s, int argc, t_atom *argv) { alist_clear(x); if (!(x->l_vec = (t_listelem *)getbytes(argc * sizeof(*x->l_vec)))) { x->l_n = 0; error("list: out of memory"); return; } x->l_n = argc; x->l_npointer = 0; alist_copyin(x, s, argc, argv, 0); }
/* set contents to an arbitrary non-list message */
static void alist_anything(t_alist *x, t_symbol *s, int argc, t_atom *argv) { int i; alist_clear(x); if (!(x->l_vec = (t_listelem *)getbytes((argc+1) * sizeof(*x->l_vec)))) { x->l_n = 0; error("list_alloc: out of memory"); return; } x->l_n = argc+1; x->l_npointer = 0; SETSYMBOL(&x->l_vec[0].l_a, s); for (i = 0; i < argc; i++) { x->l_vec[i+1].l_a = argv[i]; if (x->l_vec[i+1].l_a.a_type == A_POINTER) { x->l_npointer++; gpointer_copy(x->l_vec[i+1].l_a.a_w.w_gpointer, &x->l_vec[i+1].l_p); x->l_vec[i+1].l_a.a_w.w_gpointer = &x->l_vec[i+1].l_p; } } }
static void alist_toatoms(t_alist *x, t_atom *to, int onset, int count) { int i; for (i = 0; i < count; i++) to[i] = x->l_vec[onset + i].l_a; }
static void alist_clone(t_alist *x, t_alist *y, int onset, int count) { int i; y->l_pd = alist_class; y->l_n = count; y->l_npointer = 0; if (!(y->l_vec = (t_listelem *)getbytes(y->l_n * sizeof(*y->l_vec)))) { y->l_n = 0; error("list_alloc: out of memory"); } else for (i = 0; i < count; i++) { y->l_vec[i].l_a = x->l_vec[onset + i].l_a; if (y->l_vec[i].l_a.a_type == A_POINTER) { gpointer_copy(y->l_vec[i].l_a.a_w.w_gpointer, &y->l_vec[i].l_p); y->l_vec[i].l_a.a_w.w_gpointer = &y->l_vec[i].l_p; y->l_npointer++; } } }
static void alist_setup(void) { alist_class = class_new(gensym("list inlet"), 0, 0, sizeof(t_alist), 0, 0); class_addlist(alist_class, alist_list); class_addanything(alist_class, alist_anything); }
/* ------------- list append --------------------- */
t_class *list_append_class;
typedef struct _list_append { t_object x_obj; t_alist x_alist; } t_list_append;
static void *list_append_new(t_symbol *s, int argc, t_atom *argv) { t_list_append *x = (t_list_append *)pd_new(list_append_class); alist_init(&x->x_alist); alist_list(&x->x_alist, 0, argc, argv); outlet_new(&x->x_obj, &s_list); inlet_new(&x->x_obj, &x->x_alist.l_pd, 0, 0); return (x); }
static void list_append_list(t_list_append *x, t_symbol *s, int argc, t_atom *argv) { t_atom *outv; int n, outc = x->x_alist.l_n + argc; ATOMS_ALLOCA(outv, outc); atoms_copy(argc, argv, outv); if (x->x_alist.l_npointer) { t_alist y; alist_clone(&x->x_alist, &y, 0, x->x_alist.l_n); alist_toatoms(&y, outv+argc, 0, x->x_alist.l_n); outlet_list(x->x_obj.ob_outlet, &s_list, outc, outv); alist_clear(&y); } else { alist_toatoms(&x->x_alist, outv+argc, 0, x->x_alist.l_n); outlet_list(x->x_obj.ob_outlet, &s_list, outc, outv); } ATOMS_FREEA(outv, outc); }
static void list_append_anything(t_list_append *x, t_symbol *s, int argc, t_atom *argv) { t_atom *outv; int n, outc = x->x_alist.l_n + argc + 1; ATOMS_ALLOCA(outv, outc); SETSYMBOL(outv, s); atoms_copy(argc, argv, outv + 1); if (x->x_alist.l_npointer) { t_alist y; alist_clone(&x->x_alist, &y, 0, x->x_alist.l_n); alist_toatoms(&y, outv + 1 + argc, 0, x->x_alist.l_n); outlet_list(x->x_obj.ob_outlet, &s_list, outc, outv); alist_clear(&y); } else { alist_toatoms(&x->x_alist, outv + 1 + argc, 0, x->x_alist.l_n); outlet_list(x->x_obj.ob_outlet, &s_list, outc, outv); } ATOMS_FREEA(outv, outc); }
static void list_append_append(t_list_append *x, t_symbol *s, int argc, t_atom *argv) { if (!(x->x_alist.l_vec = (t_listelem *)resizebytes(x->x_alist.l_vec, (x->x_alist.l_n) * sizeof(*x->x_alist.l_vec), (x->x_alist.l_n + argc) * sizeof(*x->x_alist.l_vec)))) { x->x_alist.l_n = 0; error("list: out of memory"); return; } alist_copyin(&x->x_alist, s, argc, argv, x->x_alist.l_n); x->x_alist.l_n += argc; }
static void list_append_prepend(t_list_append *x, t_symbol *s, int argc, t_atom *argv) { if (!(x->x_alist.l_vec = (t_listelem *)resizebytes(x->x_alist.l_vec, (x->x_alist.l_n) * sizeof(*x->x_alist.l_vec), (x->x_alist.l_n + argc) * sizeof(*x->x_alist.l_vec)))) { x->x_alist.l_n = 0; error("list: out of memory"); return; } memmove(x->x_alist.l_vec + argc, x->x_alist.l_vec, x->x_alist.l_n * sizeof(*x->x_alist.l_vec)); alist_copyin(&x->x_alist, s, argc, argv, 0); x->x_alist.l_n += argc; }
static void list_append_free(t_list_append *x) { alist_clear(&x->x_alist); }
static void list_append_setup(void) { list_append_class = class_new(gensym("list append"), (t_newmethod)list_append_new, (t_method)list_append_free, sizeof(t_list_append), 0, A_GIMME, 0); class_addlist(list_append_class, list_append_list); class_addanything(list_append_class, list_append_anything); class_sethelpsymbol(list_append_class, &s_list); }
/* ------------- list prepend --------------------- */
t_class *list_prepend_class;
typedef t_list_append t_list_prepend;
static void *list_prepend_new(t_symbol *s, int argc, t_atom *argv) { t_list_prepend *x = (t_list_prepend *)pd_new(list_prepend_class); alist_init(&x->x_alist); alist_list(&x->x_alist, 0, argc, argv); outlet_new(&x->x_obj, &s_list); inlet_new(&x->x_obj, &x->x_alist.l_pd, 0, 0); return (x); }
static void list_prepend_list(t_list_prepend *x, t_symbol *s, int argc, t_atom *argv) { t_atom *outv; int n, outc = x->x_alist.l_n + argc; ATOMS_ALLOCA(outv, outc); atoms_copy(argc, argv, outv + x->x_alist.l_n); if (x->x_alist.l_npointer) { t_alist y; alist_clone(&x->x_alist, &y, 0, x->x_alist.l_n); alist_toatoms(&y, outv, 0, x->x_alist.l_n); outlet_list(x->x_obj.ob_outlet, &s_list, outc, outv); alist_clear(&y); } else { alist_toatoms(&x->x_alist, outv, 0, x->x_alist.l_n); outlet_list(x->x_obj.ob_outlet, &s_list, outc, outv); } ATOMS_FREEA(outv, outc); }
static void list_prepend_anything(t_list_prepend *x, t_symbol *s, int argc, t_atom *argv) { t_atom *outv; int n, outc = x->x_alist.l_n + argc + 1; ATOMS_ALLOCA(outv, outc); SETSYMBOL(outv + x->x_alist.l_n, s); atoms_copy(argc, argv, outv + x->x_alist.l_n + 1); if (x->x_alist.l_npointer) { t_alist y; alist_clone(&x->x_alist, &y, 0, x->x_alist.l_n); alist_toatoms(&y, outv, 0, x->x_alist.l_n); outlet_list(x->x_obj.ob_outlet, &s_list, outc, outv); alist_clear(&y); } else { alist_toatoms(&x->x_alist, outv, 0, x->x_alist.l_n); outlet_list(x->x_obj.ob_outlet, &s_list, outc, outv); } ATOMS_FREEA(outv, outc); }
static void list_prepend_free(t_list_prepend *x) { alist_clear(&x->x_alist); }
static void list_prepend_setup(void) { list_prepend_class = class_new(gensym("list prepend"), (t_newmethod)list_prepend_new, (t_method)list_prepend_free, sizeof(t_list_prepend), 0, A_GIMME, 0); class_addlist(list_prepend_class, list_prepend_list); class_addanything(list_prepend_class, list_prepend_anything); class_sethelpsymbol(list_prepend_class, &s_list); }
/* ------------- list store --------------------- */
t_class *list_store_class;
typedef struct _list_store { t_object x_obj; t_alist x_alist; t_outlet *x_out1; t_outlet *x_out2; } t_list_store;
static void *list_store_new(t_symbol *s, int argc, t_atom *argv) { t_list_store *x = (t_list_store *)pd_new(list_store_class); alist_init(&x->x_alist); alist_list(&x->x_alist, 0, argc, argv); x->x_out1 = outlet_new(&x->x_obj, &s_list); x->x_out2 = outlet_new(&x->x_obj, &s_bang); inlet_new(&x->x_obj, &x->x_alist.l_pd, 0, 0); return (x); }
static void list_store_list(t_list_store *x, t_symbol *s, int argc, t_atom *argv) { t_atom *outv; int n, outc = x->x_alist.l_n + argc; ATOMS_ALLOCA(outv, outc); atoms_copy(argc, argv, outv); if (x->x_alist.l_npointer) { t_alist y; alist_clone(&x->x_alist, &y, 0, x->x_alist.l_n); alist_toatoms(&y, outv+argc, 0, x->x_alist.l_n); outlet_list(x->x_out1, &s_list, outc, outv); alist_clear(&y); } else { alist_toatoms(&x->x_alist, outv+argc, 0, x->x_alist.l_n); outlet_list(x->x_out1, &s_list, outc, outv); } ATOMS_FREEA(outv, outc); }
/* insert atoms before a given index */ static void list_store_doinsert(t_list_store *x, int index, t_symbol *s, int argc, t_atom *argv) { if (index < 0) index = 0; /* index = 0 -> prepend */ if (index > x->x_alist.l_n) index = x->x_alist.l_n; /* index >= length -> append */
if (!(x->x_alist.l_vec = (t_listelem *)resizebytes(x->x_alist.l_vec, (x->x_alist.l_n) * sizeof(*x->x_alist.l_vec), (x->x_alist.l_n + argc) * sizeof(*x->x_alist.l_vec)))) { x->x_alist.l_n = 0; error("list: out of memory"); return; } /* we don't need memmove for appending */ if (index < x->x_alist.l_n){ memmove(x->x_alist.l_vec + index + argc, x->x_alist.l_vec + index, (x->x_alist.l_n - index) * sizeof(*x->x_alist.l_vec)); } alist_copyin(&x->x_alist, s, argc, argv, index); x->x_alist.l_n += argc; }
static void list_store_insert(t_list_store *x, t_symbol *s, int argc, t_atom *argv) { if (argc < 2) return;
/* first atom is the index where to start inserting atoms. */ int index = atom_getfloat(argv); argc--; argv++; /* insert remaining atoms */ list_store_doinsert(x, index, s, argc, argv); }
static void list_store_append(t_list_store *x, t_symbol *s, int argc, t_atom *argv) { list_store_doinsert(x, 1e+009, s, argc, argv); }
static void list_store_prepend(t_list_store *x, t_symbol *s, int argc, t_atom *argv) { list_store_doinsert(x, 0, s, argc, argv); }
static void list_store_delete(t_list_store *x, float f1, float f2) { int index = f1; int ndelete = f2;
if (index < 0) index = 0; if (index >= x->x_alist.l_n) return; /* out of range: nothing to delete */
int maxlength = x->x_alist.l_n - index; if (ndelete > maxlength) ndelete = maxlength;
/* first unset pointers */ if (x->x_alist.l_npointer) { t_listelem *vec = x->x_alist.l_vec; for (int i = 0; i < ndelete; i++) { if (vec[index + i].l_a.a_type == A_POINTER) { gpointer_unset(vec[i].l_a.a_w.w_gpointer); x->x_alist.l_npointer--; post("remaining number of pointers: %d", x->x_alist.l_npointer); } } }
/* then move atoms */ memmove(x->x_alist.l_vec + index, x->x_alist.l_vec + index + ndelete, (x->x_alist.l_n - index - ndelete) * sizeof(*x->x_alist.l_vec));
x->x_alist.l_vec = (t_listelem *)resizebytes(x->x_alist.l_vec, (x->x_alist.l_n) * sizeof(*x->x_alist.l_vec), (x->x_alist.l_n - ndelete) * sizeof(*x->x_alist.l_vec));
x->x_alist.l_n -= ndelete;
}
static void list_store_set(t_list_store *x, t_symbol *s, int argc, t_atom *argv) { if (argc < 2) return;
/* first atom is the index where to start copying the atoms */ int index = atom_getfloat(argv); if (index < 0) index = 0; if (index > x->x_alist.l_n - 1) index = x->x_alist.l_n - 1; argc--; argv++;
/* copy remaining atoms */ int maxlength = x->x_alist.l_n - index; /* for now we truncate. we could also append remaining atoms... */ if (argc > maxlength) argc = maxlength;
/* first unset pointers */ if (x->x_alist.l_npointer) { t_listelem *vec = x->x_alist.l_vec; for (int i = 0; i < argc; i++) { if (vec[index + i].l_a.a_type == A_POINTER) { gpointer_unset(vec[i+index].l_a.a_w.w_gpointer); x->x_alist.l_npointer--; } } } /* then copy */ alist_copyin(&x->x_alist, s, argc, argv, index); }
static void list_store_get(t_list_store *x, float f1, float f2) { t_atom *outv; int onset = f1, outc = f2; if (onset < 0 || outc < 0) { pd_error(x, "list_store_range: negative range (%d %d)", onset, outc); return; } if (onset + outc > x->x_alist.l_n) { outlet_bang(x->x_out2); return; } ATOMS_ALLOCA(outv, outc); if (x->x_alist.l_npointer) { t_alist y; alist_clone(&x->x_alist, &y, onset, outc); alist_toatoms(&y, outv, onset, outc); outlet_list(x->x_out1, &s_list, outc, outv); alist_clear(&y); } else { alist_toatoms(&x->x_alist, outv, onset, outc); outlet_list(x->x_out1, &s_list, outc, outv); } ATOMS_FREEA(outv, outc); }
static void list_store_range(t_list_store *x, float f1, float f2) { list_store_get(x, f1, f2); }
static void list_store_free(t_list_store *x) { alist_clear(&x->x_alist); }
static void list_store_setup(void) { list_store_class = class_new(gensym("list store"), (t_newmethod)list_store_new, (t_method)list_store_free, sizeof(t_list_store), 0, A_GIMME, 0); class_addlist(list_store_class, list_store_list); class_addmethod(list_store_class, (t_method)list_store_set, gensym("set"), A_GIMME, 0); class_addmethod(list_store_class, (t_method)list_store_get, gensym("get"), A_FLOAT, A_FLOAT, 0); class_addmethod(list_store_class, (t_method)list_store_range, gensym("range"), A_FLOAT, A_FLOAT, 0); /* alias for "get" */ class_addmethod(list_store_class, (t_method)list_store_insert, gensym("insert"), A_GIMME, 0); class_addmethod(list_store_class, (t_method)list_store_append, gensym("append"), A_GIMME, 0); class_addmethod(list_store_class, (t_method)list_store_prepend, gensym("prepend"), A_GIMME, 0); class_addmethod(list_store_class, (t_method)list_store_delete, gensym("delete"), A_FLOAT, A_FLOAT, 0);
class_sethelpsymbol(list_store_class, &s_list);
}
/* ------------- list split --------------------- */
t_class *list_split_class;
typedef struct _list_split { t_object x_obj; t_float x_f; t_outlet *x_out1; t_outlet *x_out2; t_outlet *x_out3; } t_list_split;
static void *list_split_new(t_floatarg f) { t_list_split *x = (t_list_split *)pd_new(list_split_class); x->x_out1 = outlet_new(&x->x_obj, &s_list); x->x_out2 = outlet_new(&x->x_obj, &s_list); x->x_out3 = outlet_new(&x->x_obj, &s_list); floatinlet_new(&x->x_obj, &x->x_f); x->x_f = f; return (x); }
static void list_split_list(t_list_split *x, t_symbol *s, int argc, t_atom *argv) { int n = x->x_f; if (n < 0) n = 0; if (argc >= n) { outlet_list(x->x_out2, &s_list, argc-n, argv+n); outlet_list(x->x_out1, &s_list, n, argv); } else outlet_list(x->x_out3, &s_list, argc, argv); }
static void list_split_anything(t_list_split *x, t_symbol *s, int argc, t_atom *argv) { t_atom *outv; ATOMS_ALLOCA(outv, argc+1); SETSYMBOL(outv, s); atoms_copy(argc, argv, outv + 1); list_split_list(x, &s_list, argc+1, outv); ATOMS_FREEA(outv, argc+1); }
static void list_split_setup(void) { list_split_class = class_new(gensym("list split"), (t_newmethod)list_split_new, 0, sizeof(t_list_split), 0, A_DEFFLOAT, 0); class_addlist(list_split_class, list_split_list); class_addanything(list_split_class, list_split_anything); class_sethelpsymbol(list_split_class, &s_list); }
/* ------------- list trim --------------------- */
t_class *list_trim_class;
typedef struct _list_trim { t_object x_obj; } t_list_trim;
static void *list_trim_new( void) { t_list_trim *x = (t_list_trim *)pd_new(list_trim_class); outlet_new(&x->x_obj, &s_list); return (x); }
static void list_trim_list(t_list_trim *x, t_symbol *s, int argc, t_atom *argv) { if (argc < 1 || argv[0].a_type != A_SYMBOL) outlet_list(x->x_obj.ob_outlet, &s_list, argc, argv); else outlet_anything(x->x_obj.ob_outlet, argv[0].a_w.w_symbol, argc-1, argv+1); }
static void list_trim_anything(t_list_trim *x, t_symbol *s, int argc, t_atom *argv) { outlet_anything(x->x_obj.ob_outlet, s, argc, argv); }
static void list_trim_setup(void) { list_trim_class = class_new(gensym("list trim"), (t_newmethod)list_trim_new, 0, sizeof(t_list_trim), 0, 0); class_addlist(list_trim_class, list_trim_list); class_addanything(list_trim_class, list_trim_anything); class_sethelpsymbol(list_trim_class, &s_list); }
/* ------------- list length --------------------- */
t_class *list_length_class;
typedef struct _list_length { t_object x_obj; } t_list_length;
static void *list_length_new( void) { t_list_length *x = (t_list_length *)pd_new(list_length_class); outlet_new(&x->x_obj, &s_float); return (x); }
static void list_length_list(t_list_length *x, t_symbol *s, int argc, t_atom *argv) { outlet_float(x->x_obj.ob_outlet, (t_float)argc); }
static void list_length_anything(t_list_length *x, t_symbol *s, int argc, t_atom *argv) { outlet_float(x->x_obj.ob_outlet, (t_float)argc+1); }
static void list_length_setup(void) { list_length_class = class_new(gensym("list length"), (t_newmethod)list_length_new, 0, sizeof(t_list_length), 0, 0); class_addlist(list_length_class, list_length_list); class_addanything(list_length_class, list_length_anything); class_sethelpsymbol(list_length_class, &s_list); }
/* ------------- list fromsymbol --------------------- */
t_class *list_fromsymbol_class;
typedef struct _list_fromsymbol { t_object x_obj; } t_list_fromsymbol;
static void *list_fromsymbol_new( void) { t_list_fromsymbol *x = (t_list_fromsymbol *)pd_new(list_fromsymbol_class); outlet_new(&x->x_obj, &s_list); return (x); }
static void list_fromsymbol_symbol(t_list_fromsymbol *x, t_symbol *s) { t_atom *outv; int n, outc = strlen(s->s_name); ATOMS_ALLOCA(outv, outc); for (n = 0; n < outc; n++) SETFLOAT(outv + n, (unsigned char)s->s_name[n]); outlet_list(x->x_obj.ob_outlet, &s_list, outc, outv); ATOMS_FREEA(outv, outc); }
static void list_fromsymbol_setup(void) { list_fromsymbol_class = class_new(gensym("list fromsymbol"), (t_newmethod)list_fromsymbol_new, 0, sizeof(t_list_fromsymbol), 0, 0); class_addsymbol(list_fromsymbol_class, list_fromsymbol_symbol); class_sethelpsymbol(list_fromsymbol_class, &s_list); }
/* ------------- list tosymbol --------------------- */
t_class *list_tosymbol_class;
typedef struct _list_tosymbol { t_object x_obj; } t_list_tosymbol;
static void *list_tosymbol_new( void) { t_list_tosymbol *x = (t_list_tosymbol *)pd_new(list_tosymbol_class); outlet_new(&x->x_obj, &s_symbol); return (x); }
static void list_tosymbol_list(t_list_tosymbol *x, t_symbol *s, int argc, t_atom *argv) { int i; #if HAVE_ALLOCA char *str = alloca(argc + 1); #else char *str = getbytes(argc + 1); #endif for (i = 0; i < argc; i++) str[i] = (char)atom_getfloatarg(i, argc, argv); str[argc] = 0; outlet_symbol(x->x_obj.ob_outlet, gensym(str)); #if HAVE_ALLOCA #else freebytes(str, argc+1); #endif }
static void list_tosymbol_setup(void) { list_tosymbol_class = class_new(gensym("list tosymbol"), (t_newmethod)list_tosymbol_new, 0, sizeof(t_list_tosymbol), 0, 0); class_addlist(list_tosymbol_class, list_tosymbol_list); class_sethelpsymbol(list_tosymbol_class, &s_list); }
/* ------------- list ------------------- */
static void *list_new(t_pd *dummy, t_symbol *s, int argc, t_atom *argv) { if (!argc || argv[0].a_type != A_SYMBOL) pd_this->pd_newest = list_append_new(s, argc, argv); else { t_symbol *s2 = argv[0].a_w.w_symbol; if (s2 == gensym("append")) pd_this->pd_newest = list_append_new(s, argc-1, argv+1); else if (s2 == gensym("prepend")) pd_this->pd_newest = list_prepend_new(s, argc-1, argv+1); else if (s2 == gensym("split")) pd_this->pd_newest = list_split_new(atom_getfloatarg(1, argc, argv)); else if (s2 == gensym("trim")) pd_this->pd_newest = list_trim_new(); else if (s2 == gensym("length")) pd_this->pd_newest = list_length_new(); else if (s2 == gensym("fromsymbol")) pd_this->pd_newest = list_fromsymbol_new(); else if (s2 == gensym("tosymbol")) pd_this->pd_newest = list_tosymbol_new(); else if (s2 == gensym("store")) pd_this->pd_newest = list_store_new(s, argc-1, argv+1); else { error("list %s: unknown function", s2->s_name); pd_this->pd_newest = 0; } } return (pd_this->pd_newest); }
void x_list_setup(void) { alist_setup(); list_append_setup(); list_prepend_setup(); list_store_setup(); list_split_setup(); list_trim_setup(); list_length_setup(); list_fromsymbol_setup(); list_tosymbol_setup(); class_addcreator((t_newmethod)list_new, &s_list, A_GIMME, 0); }
Pd-dev mailing list Pd-dev@lists.iem.at https://lists.puredata.info/listinfo/pd-dev
Pd-dev mailing list Pd-dev@lists.iem.at https://lists.puredata.info/listinfo/pd-dev
2017-07-21 6:54 GMT-03:00 Dan Wilcox danomatika@gmail.com:
Ok all, at this point we've nailed most of the bugs and feedback so far. The latest PR is https://github.com/pure-data/pure-data/pull/123
As far as I can tell, the only remaining things which could be done/included for the release are:
Small Stuff
- Remove midiin & sysexin Windows warnings in x_midi.c (& update help file)
You mean this, right? https://github.com/pure-data/pure-data/pull/79
But there are no "Windows warnings" here, so I don't know, maybe it's also something else.
Anyway, just made another "simple stuff" request, so I suppose, which is an update to the documentation of expr, that includes information on the latest additions and fixes. https://github.com/pure-data/pure-data/pull/132
But I'd like to bring attention to a bug for expr that I hope we could fix before the final release, which is the fact that in windows, the expr object cannot be instantiated when calling atanh(), asinh() and acosh(), such as in [expr atanh($f1)]. I reported that in https://sourceforge.net/p/pure-data/bugs/1293/ - I understood from Shahrokh that Miller had this on his list, if I'm not mistaken.
cheers
I think we figured out that those functions aren't in teh Windows math API and so can't be supported by expr there. Anyweay, I had to take them out in order to compile expr for windows. I think for now let's let that one slide.
Will check out the new doc when I have a moment :)
M
On Fri, Jul 21, 2017 at 04:14:44PM -0300, Alexandre Torres Porres wrote:
2017-07-21 6:54 GMT-03:00 Dan Wilcox danomatika@gmail.com:
Ok all, at this point we've nailed most of the bugs and feedback so far. The latest PR is https://github.com/pure-data/pure-data/pull/123
As far as I can tell, the only remaining things which could be done/included for the release are:
Small Stuff
- Remove midiin & sysexin Windows warnings in x_midi.c (& update help file)
You mean this, right? https://github.com/pure-data/pure-data/pull/79
But there are no "Windows warnings" here, so I don't know, maybe it's also something else.
Anyway, just made another "simple stuff" request, so I suppose, which is an update to the documentation of expr, that includes information on the latest additions and fixes. https://github.com/pure-data/pure-data/pull/132
But I'd like to bring attention to a bug for expr that I hope we could fix before the final release, which is the fact that in windows, the expr object cannot be instantiated when calling atanh(), asinh() and acosh(), such as in [expr atanh($f1)]. I reported that in https://sourceforge.net/p/pure-data/bugs/1293/ - I understood from Shahrokh that Miller had this on his list, if I'm not mistaken.
cheers
Pd-dev mailing list Pd-dev@lists.iem.at https://lists.puredata.info/listinfo/pd-dev
ok, but as I understand it, they will still be kept for linux/mac, right?
I'm making a remark about that in the documentation, then I'll update the pull request
2017-07-21 16:30 GMT-03:00 Miller Puckette msp@ucsd.edu:
I think we figured out that those functions aren't in teh Windows math API and so can't be supported by expr there. Anyweay, I had to take them out in order to compile expr for windows. I think for now let's let that one slide.
Will check out the new doc when I have a moment :)
M
On Fri, Jul 21, 2017 at 04:14:44PM -0300, Alexandre Torres Porres wrote:
2017-07-21 6:54 GMT-03:00 Dan Wilcox danomatika@gmail.com:
Ok all, at this point we've nailed most of the bugs and feedback so
far.
The latest PR is https://github.com/pure-data/pure-data/pull/123
As far as I can tell, the only remaining things which could be done/included for the release are:
Small Stuff
- Remove midiin & sysexin Windows warnings in x_midi.c (& update help
file)
You mean this, right? https://github.com/pure-data/pure-data/pull/79
But there are no "Windows warnings" here, so I don't know, maybe it's
also
something else.
Anyway, just made another "simple stuff" request, so I suppose, which is
an
update to the documentation of expr, that includes information on the latest additions and fixes. https://github.com/pure-data/
pure-data/pull/132
But I'd like to bring attention to a bug for expr that I hope we could
fix
before the final release, which is the fact that in windows, the expr object cannot be instantiated when calling atanh(), asinh() and acosh(),
such
as in [expr atanh($f1)]. I reported that in https://sourceforge.net/p/pure-data/bugs/1293/ - I understood from
Shahrokh
that Miller had this on his list, if I'm not mistaken.
cheers
Pd-dev mailing list Pd-dev@lists.iem.at https://lists.puredata.info/listinfo/pd-dev
Those functions are in the windows math.h if you're using Visual Studio 2012 or greater. I think it would be relatively easy to check the MSVC version in the preprocessor and disable those functions if it's too old.
https://stackoverflow.com/questions/15539116/atanh-arc-hyperbolic-tangent-fu...
enohp ym morf tnes ----------- Dan Wilcox danomatika.com robotcowboy.com
On Jul 21, 2017, at 9:38 PM, Alexandre Torres Porres porres@gmail.com wrote:
ok, but as I understand it, they will still be kept for linux/mac, right?
I'm making a remark about that in the documentation, then I'll update the pull request
2017-07-21 16:30 GMT-03:00 Miller Puckette msp@ucsd.edu:
I think we figured out that those functions aren't in teh Windows math API and so can't be supported by expr there. Anyweay, I had to take them out in order to compile expr for windows. I think for now let's let that one slide.
Will check out the new doc when I have a moment :)
M
On Fri, Jul 21, 2017 at 04:14:44PM -0300, Alexandre Torres Porres wrote:
2017-07-21 6:54 GMT-03:00 Dan Wilcox danomatika@gmail.com:
Ok all, at this point we've nailed most of the bugs and feedback so far. The latest PR is https://github.com/pure-data/pure-data/pull/123
As far as I can tell, the only remaining things which could be done/included for the release are:
Small Stuff
- Remove midiin & sysexin Windows warnings in x_midi.c (& update help file)
You mean this, right? https://github.com/pure-data/pure-data/pull/79
But there are no "Windows warnings" here, so I don't know, maybe it's also something else.
Anyway, just made another "simple stuff" request, so I suppose, which is an update to the documentation of expr, that includes information on the latest additions and fixes. https://github.com/pure-data/pure-data/pull/132
But I'd like to bring attention to a bug for expr that I hope we could fix before the final release, which is the fact that in windows, the expr object cannot be instantiated when calling atanh(), asinh() and acosh(), such as in [expr atanh($f1)]. I reported that in https://sourceforge.net/p/pure-data/bugs/1293/ - I understood from Shahrokh that Miller had this on his list, if I'm not mistaken.
cheers
Pd-dev mailing list Pd-dev@lists.iem.at https://lists.puredata.info/listinfo/pd-dev
2017-07-21 16:44 GMT-03:00 Dan Wilcox danomatika@gmail.com:
Those functions are in the windows math.h if you're using Visual Studio 2012 or greater.
Hey, I just realized we have an [atanh] object for cyclone, I actually did that one myself, and I just tested, it's working on windows!
here's the source https://github.com/porres/pd-cyclone/blob/master/cyclone_src/binaries/contro...
so, definitely, those functions may exist for windows, not sure what building system you're using, but it may need an update
On 07/21/2017 09:55 PM, Alexandre Torres Porres wrote:
2017-07-21 16:44 GMT-03:00 Dan Wilcox danomatika@gmail.com:
Those functions are in the windows math.h if you're using Visual Studio 2012 or greater.
Hey, I just realized we have an [atanh] object for cyclone, I actually did that one myself, and I just tested, it's working on windows!
here's the source https://github.com/porres/pd-cyclone/blob/master/cyclone_src/binaries/contro...
so, definitely, those functions may exist for windows, not sure what building system you're using, but it may need an update
Pd's windows binaries rely on both VisualStudio and gcc, and the former lacks atanhf() on older versions (as Dan has put it). hence it's missing. cyclone doesn't use VisualStudio for building, so it can use atanhf() without further thought.
the situation of Pd's build system on w32 is complicated at best, and so far we haven't found a proper solution (that would allow us to complitely ditch VisualStudio).
gmasdr IOhannes
2017-07-21 17:20 GMT-03:00 IOhannes m zmölnig zmoelnig@iem.at:
the situation of Pd's build system on w32 is complicated at best, and so far we haven't found a proper solution (that would allow us to complitely ditch VisualStudio).
And what would be the issue of upgrading VisualStudio?
On 07/21/2017 10:27 PM, Alexandre Torres Porres wrote:
2017-07-21 17:20 GMT-03:00 IOhannes m zmölnig zmoelnig@iem.at:
the situation of Pd's build system on w32 is complicated at best, and so far we haven't found a proper solution (that would allow us to complitely ditch VisualStudio).
And what would be the issue of upgrading VisualStudio?
like: that it completely borks my¹ w32 dev machine which is a running albeit fragile equilibristic system.
gfmadsr IOhannes
¹ sidenote: no, it's not *my* w32 dev machine, as i don't personally do any Pd builds on VisualStudio these days; however, "been there, done that", so I know that this can be a PITA. it's not like "apt-get install gcc-7".
It's most probably working because you are compiling on a newer system with a newer Visual Studio which has the newer math.h which has the function.
Older versions pre-2012 do not, hence the current non-usage.
On Jul 21, 2017, at 9:55 PM, Alexandre Torres Porres porres@gmail.com wrote:
2017-07-21 16:44 GMT-03:00 Dan Wilcox <danomatika@gmail.com mailto:danomatika@gmail.com>: Those functions are in the windows math.h if you're using Visual Studio 2012 or greater.
Hey, I just realized we have an [atanh] object for cyclone, I actually did that one myself, and I just tested, it's working on windows!
here's the source https://github.com/porres/pd-cyclone/blob/master/cyclone_src/binaries/contro... https://github.com/porres/pd-cyclone/blob/master/cyclone_src/binaries/control/atanh.c
so, definitely, those functions may exist for windows, not sure what building system you're using, but it may need an update
-------- Dan Wilcox @danomatika http://twitter.com/danomatika danomatika.com http://danomatika.com/ robotcowboy.com http://robotcowboy.com/
Looks like the preprocessor define is _MSC_VER: https://stackoverflow.com/questions/70013/how-to-detect-if-im-compiling-code... https://stackoverflow.com/questions/70013/how-to-detect-if-im-compiling-code-with-visual-studio-2008
So something like the following could probably work:
#ifdef _WIN32 #if (_MSC_VER < 17000) #define ATANH_NOT_AVAILABLE #endif #endif #include <math.h>
On Jul 21, 2017, at 10:21 PM, Dan Wilcox danomatika@gmail.com wrote:
It's most probably working because you are compiling on a newer system with a newer Visual Studio which has the newer math.h which has the function.
Older versions pre-2012 do not, hence the current non-usage.
On Jul 21, 2017, at 9:55 PM, Alexandre Torres Porres <porres@gmail.com mailto:porres@gmail.com> wrote:
2017-07-21 16:44 GMT-03:00 Dan Wilcox <danomatika@gmail.com mailto:danomatika@gmail.com>: Those functions are in the windows math.h if you're using Visual Studio 2012 or greater.
Hey, I just realized we have an [atanh] object for cyclone, I actually did that one myself, and I just tested, it's working on windows!
here's the source https://github.com/porres/pd-cyclone/blob/master/cyclone_src/binaries/contro... https://github.com/porres/pd-cyclone/blob/master/cyclone_src/binaries/control/atanh.c
so, definitely, those functions may exist for windows, not sure what building system you're using, but it may need an update
Dan Wilcox @danomatika http://twitter.com/danomatika danomatika.com http://danomatika.com/ robotcowboy.com http://robotcowboy.com/
-------- Dan Wilcox @danomatika http://twitter.com/danomatika danomatika.com http://danomatika.com/ robotcowboy.com http://robotcowboy.com/
OK, will try that for next release :)
Anyhow, I have to profile MSVC against mingw and (hopefully) move the whole compile chain over. But certainly not now.
Miller
On Fri, Jul 21, 2017 at 10:30:26PM +0200, Dan Wilcox wrote:
Looks like the preprocessor define is _MSC_VER: https://stackoverflow.com/questions/70013/how-to-detect-if-im-compiling-code... https://stackoverflow.com/questions/70013/how-to-detect-if-im-compiling-code-with-visual-studio-2008
So something like the following could probably work:
#ifdef _WIN32 #if (_MSC_VER < 17000) #define ATANH_NOT_AVAILABLE #endif #endif #include <math.h>
On Jul 21, 2017, at 10:21 PM, Dan Wilcox danomatika@gmail.com wrote:
It's most probably working because you are compiling on a newer system with a newer Visual Studio which has the newer math.h which has the function.
Older versions pre-2012 do not, hence the current non-usage.
On Jul 21, 2017, at 9:55 PM, Alexandre Torres Porres <porres@gmail.com mailto:porres@gmail.com> wrote:
2017-07-21 16:44 GMT-03:00 Dan Wilcox <danomatika@gmail.com mailto:danomatika@gmail.com>: Those functions are in the windows math.h if you're using Visual Studio 2012 or greater.
Hey, I just realized we have an [atanh] object for cyclone, I actually did that one myself, and I just tested, it's working on windows!
here's the source https://github.com/porres/pd-cyclone/blob/master/cyclone_src/binaries/contro... https://github.com/porres/pd-cyclone/blob/master/cyclone_src/binaries/control/atanh.c
so, definitely, those functions may exist for windows, not sure what building system you're using, but it may need an update
Dan Wilcox @danomatika http://twitter.com/danomatika danomatika.com http://danomatika.com/ robotcowboy.com http://robotcowboy.com/
Dan Wilcox @danomatika http://twitter.com/danomatika danomatika.com http://danomatika.com/ robotcowboy.com http://robotcowboy.com/
This is also the kind of thing the configure script can check for :)
On Jul 21, 2017, at 10:39 PM, Miller Puckette msp@ucsd.edu wrote:
OK, will try that for next release :)
Anyhow, I have to profile MSVC against mingw and (hopefully) move the whole compile chain over. But certainly not now.
Miller
On Fri, Jul 21, 2017 at 10:30:26PM +0200, Dan Wilcox wrote:
Looks like the preprocessor define is _MSC_VER: https://stackoverflow.com/questions/70013/how-to-detect-if-im-compiling-code... https://stackoverflow.com/questions/70013/how-to-detect-if-im-compiling-code-with-visual-studio-2008
So something like the following could probably work:
#ifdef _WIN32 #if (_MSC_VER < 17000) #define ATANH_NOT_AVAILABLE #endif #endif #include <math.h>
On Jul 21, 2017, at 10:21 PM, Dan Wilcox danomatika@gmail.com wrote:
It's most probably working because you are compiling on a newer system with a newer Visual Studio which has the newer math.h which has the function.
Older versions pre-2012 do not, hence the current non-usage.
On Jul 21, 2017, at 9:55 PM, Alexandre Torres Porres <porres@gmail.com mailto:porres@gmail.com> wrote:
2017-07-21 16:44 GMT-03:00 Dan Wilcox <danomatika@gmail.com mailto:danomatika@gmail.com>: Those functions are in the windows math.h if you're using Visual Studio 2012 or greater.
Hey, I just realized we have an [atanh] object for cyclone, I actually did that one myself, and I just tested, it's working on windows!
here's the source https://github.com/porres/pd-cyclone/blob/master/cyclone_src/binaries/contro... https://github.com/porres/pd-cyclone/blob/master/cyclone_src/binaries/control/atanh.c
so, definitely, those functions may exist for windows, not sure what building system you're using, but it may need an update
Dan Wilcox @danomatika http://twitter.com/danomatika danomatika.com http://danomatika.com/ robotcowboy.com http://robotcowboy.com/
Dan Wilcox @danomatika http://twitter.com/danomatika danomatika.com http://danomatika.com/ robotcowboy.com http://robotcowboy.com/
-------- Dan Wilcox @danomatika http://twitter.com/danomatika danomatika.com http://danomatika.com/ robotcowboy.com http://robotcowboy.com/
ok, since we can't have that for now, I'm updating the help file of [expr] again, cause I was using [expr acosh(0)] to generate 'nan', as an example to the [expr isnan($f1)] function.
now I'm using [expr log(-1)]
all seems good now.
2017-07-21 17:40 GMT-03:00 Dan Wilcox danomatika@gmail.com:
This is also the kind of thing the configure script can check for :)
On Jul 21, 2017, at 10:39 PM, Miller Puckette msp@ucsd.edu wrote:
OK, will try that for next release :)
Anyhow, I have to profile MSVC against mingw and (hopefully) move the whole compile chain over. But certainly not now.
Miller
On Fri, Jul 21, 2017 at 10:30:26PM +0200, Dan Wilcox wrote:
Looks like the preprocessor define is _MSC_VER: https://stackoverflow.com/ questions/70013/how-to-detect-if-im-compiling-code-with-visual-studio-2008 https://stackoverflow.com/questions/70013/how-to-detect- if-im-compiling-code-with-visual-studio-2008
So something like the following could probably work:
#ifdef _WIN32 #if (_MSC_VER < 17000) #define ATANH_NOT_AVAILABLE #endif #endif #include <math.h>
On Jul 21, 2017, at 10:21 PM, Dan Wilcox danomatika@gmail.com wrote:
It's most probably working because you are compiling on a newer system with a newer Visual Studio which has the newer math.h which has the function.
Older versions pre-2012 do not, hence the current non-usage.
On Jul 21, 2017, at 9:55 PM, Alexandre Torres Porres <porres@gmail.com < mailto:porres@gmail.com porres@gmail.com>> wrote:
2017-07-21 16:44 GMT-03:00 Dan Wilcox <danomatika@gmail.com < mailto:danomatika@gmail.com danomatika@gmail.com>>: Those functions are in the windows math.h if you're using Visual Studio 2012 or greater.
Hey, I just realized we have an [atanh] object for cyclone, I actually did that one myself, and I just tested, it's working on windows!
here's the source https://github.com/porres/pd- cyclone/blob/master/cyclone_src/binaries/control/atanh.c < https://github.com/porres/pd-cyclone/blob/master/cyclone_ src/binaries/control/atanh.c>
so, definitely, those functions may exist for windows, not sure what building system you're using, but it may need an update
Dan Wilcox @danomatika http://twitter.com/danomatika danomatika.com http://danomatika.com/ robotcowboy.com http://robotcowboy.com/
Dan Wilcox @danomatika http://twitter.com/danomatika danomatika.com http://danomatika.com/ robotcowboy.com http://robotcowboy.com/
Dan Wilcox @danomatika http://twitter.com/danomatika danomatika.com robotcowboy.com
Simplest fix is to replace the
#ifndef _WIN32
with
#if !defined(_WIN32) || (defined(_MSC_VER) && (_MSC_VER >= 17000))
I think that is pretty safe and can be added now without any real issues. If Pd is compiled with a newer MSVC than 2008, boom those are available.
Another, longer & probably more difficult option, is to provide implementations for MSVC < 2012 such as:
// versions of MSVC prior to 2012 do not have these #if defined(_WIN32) && defined(_MSC_VER) && (_MSC_VER < 17000) #define asinh(x) log(x + sqrt(x2 + 1)) #define acosh(x) log(x + sqrt(x2 - 1)) #define atanh(x) (log(1+x) - log(1-x))/2 #define isnan(x) _isnan(x) #define isinf(x) (!_finite(x)) ... #endif
I have no idea exactly how express calls the root C functions, so this approach may not work anyway.
On Jul 21, 2017, at 10:39 PM, Miller Puckette msp@ucsd.edu wrote:
OK, will try that for next release :)
Anyhow, I have to profile MSVC against mingw and (hopefully) move the whole compile chain over. But certainly not now.
Miller
On Fri, Jul 21, 2017 at 10:30:26PM +0200, Dan Wilcox wrote:
Looks like the preprocessor define is _MSC_VER: https://stackoverflow.com/questions/70013/how-to-detect-if-im-compiling-code... https://stackoverflow.com/questions/70013/how-to-detect-if-im-compiling-code-with-visual-studio-2008
So something like the following could probably work:
#ifdef _WIN32 #if (_MSC_VER < 17000) #define ATANH_NOT_AVAILABLE #endif #endif #include <math.h>
On Jul 21, 2017, at 10:21 PM, Dan Wilcox danomatika@gmail.com wrote:
It's most probably working because you are compiling on a newer system with a newer Visual Studio which has the newer math.h which has the function.
Older versions pre-2012 do not, hence the current non-usage.
On Jul 21, 2017, at 9:55 PM, Alexandre Torres Porres <porres@gmail.com mailto:porres@gmail.com> wrote:
2017-07-21 16:44 GMT-03:00 Dan Wilcox <danomatika@gmail.com mailto:danomatika@gmail.com>: Those functions are in the windows math.h if you're using Visual Studio 2012 or greater.
Hey, I just realized we have an [atanh] object for cyclone, I actually did that one myself, and I just tested, it's working on windows!
here's the source https://github.com/porres/pd-cyclone/blob/master/cyclone_src/binaries/contro... https://github.com/porres/pd-cyclone/blob/master/cyclone_src/binaries/control/atanh.c
so, definitely, those functions may exist for windows, not sure what building system you're using, but it may need an update
Dan Wilcox @danomatika http://twitter.com/danomatika danomatika.com http://danomatika.com/ robotcowboy.com http://robotcowboy.com/
Dan Wilcox @danomatika http://twitter.com/danomatika danomatika.com http://danomatika.com/ robotcowboy.com http://robotcowboy.com/
-------- Dan Wilcox @danomatika http://twitter.com/danomatika danomatika.com http://danomatika.com/ robotcowboy.com http://robotcowboy.com/
Wouldn't it be...
#if !defined(_MSC_VER) || (_MSC_VER >= 17000))
i.e., always true unlese we're MSVC and < 17000 ?
(I think the line below would stop it from being compiled in with mingw).
cheers Miller
On Sat, Jul 22, 2017 at 12:35:23AM +0200, Dan Wilcox wrote:
Simplest fix is to replace the
#ifndef _WIN32
with
#if !defined(_WIN32) || (defined(_MSC_VER) && (_MSC_VER >= 17000))
I think that is pretty safe and can be added now without any real issues. If Pd is compiled with a newer MSVC than 2008, boom those are available.
Another, longer & probably more difficult option, is to provide implementations for MSVC < 2012 such as:
// versions of MSVC prior to 2012 do not have these #if defined(_WIN32) && defined(_MSC_VER) && (_MSC_VER < 17000) #define asinh(x) log(x + sqrt(x2 + 1)) #define acosh(x) log(x + sqrt(x2 - 1)) #define atanh(x) (log(1+x) - log(1-x))/2 #define isnan(x) _isnan(x) #define isinf(x) (!_finite(x)) ... #endif
I have no idea exactly how express calls the root C functions, so this approach may not work anyway.
On Jul 21, 2017, at 10:39 PM, Miller Puckette msp@ucsd.edu wrote:
OK, will try that for next release :)
Anyhow, I have to profile MSVC against mingw and (hopefully) move the whole compile chain over. But certainly not now.
Miller
On Fri, Jul 21, 2017 at 10:30:26PM +0200, Dan Wilcox wrote:
Looks like the preprocessor define is _MSC_VER: https://stackoverflow.com/questions/70013/how-to-detect-if-im-compiling-code... https://stackoverflow.com/questions/70013/how-to-detect-if-im-compiling-code-with-visual-studio-2008
So something like the following could probably work:
#ifdef _WIN32 #if (_MSC_VER < 17000) #define ATANH_NOT_AVAILABLE #endif #endif #include <math.h>
On Jul 21, 2017, at 10:21 PM, Dan Wilcox danomatika@gmail.com wrote:
It's most probably working because you are compiling on a newer system with a newer Visual Studio which has the newer math.h which has the function.
Older versions pre-2012 do not, hence the current non-usage.
On Jul 21, 2017, at 9:55 PM, Alexandre Torres Porres <porres@gmail.com mailto:porres@gmail.com> wrote:
2017-07-21 16:44 GMT-03:00 Dan Wilcox <danomatika@gmail.com mailto:danomatika@gmail.com>: Those functions are in the windows math.h if you're using Visual Studio 2012 or greater.
Hey, I just realized we have an [atanh] object for cyclone, I actually did that one myself, and I just tested, it's working on windows!
here's the source https://github.com/porres/pd-cyclone/blob/master/cyclone_src/binaries/contro... https://github.com/porres/pd-cyclone/blob/master/cyclone_src/binaries/control/atanh.c
so, definitely, those functions may exist for windows, not sure what building system you're using, but it may need an update
Dan Wilcox @danomatika http://twitter.com/danomatika danomatika.com http://danomatika.com/ robotcowboy.com http://robotcowboy.com/
Dan Wilcox @danomatika http://twitter.com/danomatika danomatika.com http://danomatika.com/ robotcowboy.com http://robotcowboy.com/
Dan Wilcox @danomatika http://twitter.com/danomatika danomatika.com http://danomatika.com/ robotcowboy.com http://robotcowboy.com/
Right, don't need the _WIN32 for MINGW which has GNU libc.
On Jul 22, 2017, at 1:26 AM, Miller Puckette msp@ucsd.edu wrote:
Wouldn't it be...
#if !defined(_MSC_VER) || (_MSC_VER >= 17000))
i.e., always true unlese we're MSVC and < 17000 ?
(I think the line below would stop it from being compiled in with mingw).
cheers Miller
On Sat, Jul 22, 2017 at 12:35:23AM +0200, Dan Wilcox wrote:
Simplest fix is to replace the
#ifndef _WIN32
with
#if !defined(_WIN32) || (defined(_MSC_VER) && (_MSC_VER >= 17000))
I think that is pretty safe and can be added now without any real issues. If Pd is compiled with a newer MSVC than 2008, boom those are available.
Another, longer & probably more difficult option, is to provide implementations for MSVC < 2012 such as:
// versions of MSVC prior to 2012 do not have these #if defined(_WIN32) && defined(_MSC_VER) && (_MSC_VER < 17000) #define asinh(x) log(x + sqrt(x2 + 1)) #define acosh(x) log(x + sqrt(x2 - 1)) #define atanh(x) (log(1+x) - log(1-x))/2 #define isnan(x) _isnan(x) #define isinf(x) (!_finite(x)) ... #endif
I have no idea exactly how express calls the root C functions, so this approach may not work anyway.
On Jul 21, 2017, at 10:39 PM, Miller Puckette msp@ucsd.edu wrote:
OK, will try that for next release :)
Anyhow, I have to profile MSVC against mingw and (hopefully) move the whole compile chain over. But certainly not now.
Miller
On Fri, Jul 21, 2017 at 10:30:26PM +0200, Dan Wilcox wrote:
Looks like the preprocessor define is _MSC_VER: https://stackoverflow.com/questions/70013/how-to-detect-if-im-compiling-code... https://stackoverflow.com/questions/70013/how-to-detect-if-im-compiling-code-with-visual-studio-2008
So something like the following could probably work:
#ifdef _WIN32 #if (_MSC_VER < 17000) #define ATANH_NOT_AVAILABLE #endif #endif #include <math.h>
On Jul 21, 2017, at 10:21 PM, Dan Wilcox danomatika@gmail.com wrote:
It's most probably working because you are compiling on a newer system with a newer Visual Studio which has the newer math.h which has the function.
Older versions pre-2012 do not, hence the current non-usage.
On Jul 21, 2017, at 9:55 PM, Alexandre Torres Porres <porres@gmail.com mailto:porres@gmail.com> wrote:
2017-07-21 16:44 GMT-03:00 Dan Wilcox <danomatika@gmail.com mailto:danomatika@gmail.com>: Those functions are in the windows math.h if you're using Visual Studio 2012 or greater.
Hey, I just realized we have an [atanh] object for cyclone, I actually did that one myself, and I just tested, it's working on windows!
here's the source https://github.com/porres/pd-cyclone/blob/master/cyclone_src/binaries/contro... https://github.com/porres/pd-cyclone/blob/master/cyclone_src/binaries/control/atanh.c
so, definitely, those functions may exist for windows, not sure what building system you're using, but it may need an update
Dan Wilcox @danomatika http://twitter.com/danomatika danomatika.com http://danomatika.com/ robotcowboy.com http://robotcowboy.com/
Dan Wilcox @danomatika http://twitter.com/danomatika danomatika.com http://danomatika.com/ robotcowboy.com http://robotcowboy.com/
Dan Wilcox @danomatika http://twitter.com/danomatika danomatika.com http://danomatika.com/ robotcowboy.com http://robotcowboy.com/
-------- Dan Wilcox @danomatika http://twitter.com/danomatika danomatika.com http://danomatika.com/ robotcowboy.com http://robotcowboy.com/
hey, I thought atanh() wouldn't make into expr right now, but it did with test 5 ;) - great. I have to update the expr patch, cause I said there it wouldn't load for windows yet. I'll do another Pull Request soon.
cheers
2017-07-21 17:39 GMT-03:00 Miller Puckette msp@ucsd.edu:
OK, will try that for next release :)
Anyhow, I have to profile MSVC against mingw and (hopefully) move the whole compile chain over. But certainly not now.
Miller
On Fri, Jul 21, 2017 at 10:30:26PM +0200, Dan Wilcox wrote:
Looks like the preprocessor define is _MSC_VER:
https://stackoverflow.com/questions/70013/how-to-detect- if-im-compiling-code-with-visual-studio-2008 <https://stackoverflow.com/ questions/70013/how-to-detect-if-im-compiling-code-with-visual-studio-2008
So something like the following could probably work:
#ifdef _WIN32 #if (_MSC_VER < 17000) #define ATANH_NOT_AVAILABLE #endif #endif #include <math.h>
On Jul 21, 2017, at 10:21 PM, Dan Wilcox danomatika@gmail.com wrote:
It's most probably working because you are compiling on a newer system
with a newer Visual Studio which has the newer math.h which has the function.
Older versions pre-2012 do not, hence the current non-usage.
On Jul 21, 2017, at 9:55 PM, Alexandre Torres Porres <
porres@gmail.com mailto:porres@gmail.com> wrote:
2017-07-21 16:44 GMT-03:00 Dan Wilcox <danomatika@gmail.com <mailto:
danomatika@gmail.com>>:
Those functions are in the windows math.h if you're using Visual
Studio 2012 or greater.
Hey, I just realized we have an [atanh] object for cyclone, I
actually did that one myself, and I just tested, it's working on windows!
here's the source https://github.com/porres/pd-
cyclone/blob/master/cyclone_src/binaries/control/atanh.c < https://github.com/porres/pd-cyclone/blob/master/cyclone_ src/binaries/control/atanh.c>
so, definitely, those functions may exist for windows, not sure what
building system you're using, but it may need an update
Dan Wilcox @danomatika http://twitter.com/danomatika danomatika.com http://danomatika.com/ robotcowboy.com http://robotcowboy.com/
Dan Wilcox @danomatika http://twitter.com/danomatika danomatika.com http://danomatika.com/ robotcowboy.com http://robotcowboy.com/
2017-07-21 6:54 GMT-03:00 Dan Wilcox danomatika@gmail.com:
(Optional) Big Stuff
- Adopt DejaVu Sans Mono a the default font -> this is in the dejavu
branch https://github.com/pure-data/pure-data/pull/42 This is mainly for mac & Linux, Windows support will need to be added later as mentioned in the discussion. It also fixes the bad Monaco rendering on retina screens at small font sizes.
Hi, I'm testing this and I see it still doesn't result in the same metrics as Pd-Extended, making everything compatible between cross platforms, but also compatible to extended (and purr data by extent).
I've inquired before if that was the goal, and @danomatika 's answer was "yes", and that it simply didn't have that change applied yet. So it seems it still hasn't been applied, right?
So, do we still need further discussion before applying this change?
Cause the way things are right now, there's a metrics change that compromise backwards compatibility and it would change and compromise many of cyclone's documentation, for instance. So I'm not that happy if it would be included as is.
cheers
Look, I know you guys go on and on about this but it's really up to Miller.
I think the object boxes are sometimes too small with those metrics and I'm not willing to put forward what might be a major change for people without some actual talk.
The font is one thing, object sizing another. Also, there are multiple places where the metrics are placed and calculated so I'm not sure if changing the numbers in one place but not in the source code is the right idea either. I just don't know, hence need input for those that do.
Devils Advocate: Also, as IOhannes mentioned at one point, *exact* pixel sizing between platforms is always going to be close but probably not perfect and what happens when people use a different font or different sizing via startup flags? Maybe simply having some space around things and using sub patches is the easiest solution?
enohp ym morf tnes ----------- Dan Wilcox danomatika.com robotcowboy.com
On Jul 22, 2017, at 7:40 AM, Alexandre Torres Porres porres@gmail.com wrote:
2017-07-21 6:54 GMT-03:00 Dan Wilcox danomatika@gmail.com:
(Optional) Big Stuff
- Adopt DejaVu Sans Mono a the default font -> this is in the dejavu branch https://github.com/pure-data/pure-data/pull/42 This is mainly for mac & Linux, Windows support will need to be added later as mentioned in the discussion. It also fixes the bad Monaco rendering on retina screens at small font sizes.
Hi, I'm testing this and I see it still doesn't result in the same metrics as Pd-Extended, making everything compatible between cross platforms, but also compatible to extended (and purr data by extent).
I've inquired before if that was the goal, and @danomatika 's answer was "yes", and that it simply didn't have that change applied yet. So it seems it still hasn't been applied, right?
So, do we still need further discussion before applying this change?
Cause the way things are right now, there's a metrics change that compromise backwards compatibility and it would change and compromise many of cyclone's documentation, for instance. So I'm not that happy if it would be included as is.
cheers
2017-07-22 4:40 GMT-03:00 Dan Wilcox danomatika@gmail.com:
Look, I know you guys go on and on about this but it's really up to Miller.
I think the object boxes are sometimes too small with those metrics and I'm not willing to put forward what might be a major change for people without some actual talk.
The font is one thing, object sizing another. Also, there are multiple places where the metrics are placed and calculated so I'm not sure if changing the numbers in one place but not in the source code is the right idea either. I just don't know, hence need input for those that do.
ok, agreed, let's actually talk, and be sure what needed change and all - but maybe this won't be a priority right now, huh?
Devils Advocate: Also, as IOhannes mentioned at one point, *exact* pixel
sizing between platforms is always going to be close but probably not perfect and what happens when people use a different font or different sizing via startup flags? Maybe simply having some space around things and using sub patches is the easiest solution?
I can live with that, not being perfect and all, but as it is, it's just really hard to manage. I also, I don't see much point in not wanting to make things look exactly the same in all Operating Systems, so we could agree that is a desirable goal for everyone, at least, right?
cheers
On Jul 22, 2017, at 5:23 PM, Alexandre Torres Porres porres@gmail.com wrote:
2017-07-22 4:40 GMT-03:00 Dan Wilcox <danomatika@gmail.com mailto:danomatika@gmail.com>: Look, I know you guys go on and on about this but it's really up to Miller.
I think the object boxes are sometimes too small with those metrics and I'm not willing to put forward what might be a major change for people without some actual talk.
The font is one thing, object sizing another. Also, there are multiple places where the metrics are placed and calculated so I'm not sure if changing the numbers in one place but not in the source code is the right idea either. I just don't know, hence need input for those that do.
ok, agreed, let's actually talk, and be sure what needed change and all - but maybe this won't be a priority right now, huh?
Maybe not. I do want to make a branch for really testing this. We can get to that 90% (as I mention below).
Some assumptions from extended may not hold true now, also considering the addition of the zoom feature in the meantime.
Devils Advocate: Also, as IOhannes mentioned at one point, *exact* pixel sizing between platforms is always going to be close but probably not perfect and what happens when people use a different font or different sizing via startup flags? Maybe simply having some space around things and using sub patches is the easiest solution?
I can live with that, not being perfect and all, but as it is, it's just really hard to manage. I also, I don't see much point in not wanting to make things look exactly the same in all Operating Systems, so we could agree that is a desirable goal for everyone, at least, right?
With cross platform software, you sometimes give up making things look & work*exactly* the same for the ability to run the software on different systems. There are always idiosyncrasies you have to deal with and, since we're relying on Tk to do the canvas drawing which in turns relies on the underlying platform APIs, we don't have total control of all aspects of this. If we were rendering the GUI with something like openGL then maybe, but even that has differences to work around between systems. But working with something like openGL negates the development savings of using Tk to being with. It's a balance between "doing everything yourself" and "doing things with others."
Basically, I think we can get pretty *close* to things looking the same and, arguably, we can definitely be close with using the same font on all systems. We're pretty close now. But we don't have total control in how the fonts are rendered. Windows and macOS deal with sub pixel rendering and antialiasing in different ways, for example. What I'm saying is that spending 100% more time on that last 10% to make things "pixel perfect between all platforms" is perhaps not worth the effort and may not be completely possible without tons of fragile hacks. We can get to that 90% relatively easily but is the 10% more worth it? Especially for an open source project relying on volunteers?
This is where my devil's advocate argument comes in: perhaps fixing the 10% by padding out your help patches is an easier solution?
-------- Dan Wilcox @danomatika http://twitter.com/danomatika danomatika.com http://danomatika.com/ robotcowboy.com http://robotcowboy.com/
Sure, I get and I agree it can be about 90% (I said I didn't care getting to 100%). The question is wether we'd change the metrics as well so things would look the same and consistent with Pd Extended and Purr Data too. But I get that this needs further discussion and more people giving feedback.
cheers
2017-07-22 13:30 GMT-03:00 Dan Wilcox danomatika@gmail.com:
On Jul 22, 2017, at 5:23 PM, Alexandre Torres Porres porres@gmail.com wrote:
2017-07-22 4:40 GMT-03:00 Dan Wilcox danomatika@gmail.com:
Look, I know you guys go on and on about this but it's really up to Miller.
I think the object boxes are sometimes too small with those metrics and I'm not willing to put forward what might be a major change for people without some actual talk.
The font is one thing, object sizing another. Also, there are multiple places where the metrics are placed and calculated so I'm not sure if changing the numbers in one place but not in the source code is the right idea either. I just don't know, hence need input for those that do.
ok, agreed, let's actually talk, and be sure what needed change and all - but maybe this won't be a priority right now, huh?
Maybe not. I do want to make a branch for really testing this. We can get to that 90% (as I mention below).
Some assumptions from extended may not hold true now, also considering the addition of the zoom feature in the meantime.
Devils Advocate: Also, as IOhannes mentioned at one point, *exact* pixel
sizing between platforms is always going to be close but probably not perfect and what happens when people use a different font or different sizing via startup flags? Maybe simply having some space around things and using sub patches is the easiest solution?
I can live with that, not being perfect and all, but as it is, it's just really hard to manage. I also, I don't see much point in not wanting to make things look exactly the same in all Operating Systems, so we could agree that is a desirable goal for everyone, at least, right?
With cross platform software, you sometimes give up making things look & work*exactly* the same for the ability to run the software on different systems. There are always idiosyncrasies you have to deal with and, since we're relying on Tk to do the canvas drawing which in turns relies on the underlying platform APIs, we don't have total control of all aspects of this. If we were rendering the GUI with something like openGL then maybe, but even that has differences to work around between systems. But working with something like openGL negates the development savings of using Tk to being with. It's a balance between "doing everything yourself" and "doing things with others."
Basically, I think we can get pretty *close* to things looking the same and, arguably, we can definitely be close with using the same font on all systems. We're pretty close now. But we don't have total control in how the fonts are rendered. Windows and macOS deal with sub pixel rendering and antialiasing in different ways, for example. What I'm saying is that spending 100% more time on that last 10% to make things "pixel perfect between all platforms" is perhaps not worth the effort and may not be completely possible without tons of fragile hacks. We can get to that 90% relatively easily but is the 10% more worth it? Especially for an open source project relying on volunteers?
This is where my devil's advocate argument comes in: perhaps fixing the 10% by padding out your help patches is an easier solution?
Dan Wilcox @danomatika http://twitter.com/danomatika danomatika.com robotcowboy.com
2017-07-21 6:54 GMT-03:00 Dan Wilcox danomatika@gmail.com:
Ok all, at this point we've nailed most of the bugs and feedback so far. The latest PR is https://github.com/pure-data/pure-data/pull/123
As far as I can tell, the only remaining things which could be done/included for the release are:
Small Stuff
- Remove midiin & sysexin Windows warnings in x_midi.c (& update help file)
Hi, did you mean My Pull Request for removing [midiclkin]? => https://github.com/pure-data/pure-data/pull/79
That seems like a small stuff indeed, and it's been sitting there for a while. I wonder if it's being forgotten or if there's something to check/debate on.
cheers
On Jul 31, 2017, at 9:51 PM, Alexandre Torres Porres porres@gmail.com wrote:
2017-07-21 6:54 GMT-03:00 Dan Wilcox <danomatika@gmail.com mailto:danomatika@gmail.com>: Ok all, at this point we've nailed most of the bugs and feedback so far. The latest PR is https://github.com/pure-data/pure-data/pull/123 https://github.com/pure-data/pure-data/pull/123
As far as I can tell, the only remaining things which could be done/included for the release are:
Small Stuff
- Remove midiin & sysexin Windows warnings in x_midi.c (& update help file)
Hi, did you mean My Pull Request for removing [midiclkin]? => https://github.com/pure-data/pure-data/pull/79 https://github.com/pure-data/pure-data/pull/79
No. https://github.com/pure-data/pure-data/commit/cad03cde700dc3b756c1c77150a746... https://github.com/pure-data/pure-data/commit/cad03cde700dc3b756c1c77150a746950791a83f
That seems like a small stuff indeed, and it's been sitting there for a while. I wonder if it's being forgotten or if there's something to check/debate on.
I have the feeling [midiclkin] will not be removed and, s IOhannes suggests, it's better to put the help file updates in a different PR.
-------- Dan Wilcox @danomatika http://twitter.com/danomatika danomatika.com http://danomatika.com/ robotcowboy.com http://robotcowboy.com/
2017-07-31 16:56 GMT-03:00 Dan Wilcox danomatika@gmail.com:
I have the feeling [midiclkin] will not be removed and, s IOhannes suggests, it's better to put the help file updates in a different PR.
Ok, I'll do that! But I was also acting on Miller's request to remove it, and it also involves messing with help documentation. I'll just break them into two other requests.
cheers
well, I closed it and created a new PR just for the help updates. If [midiclkin] is probably staying after all and the PR has a chance to not be merged, maybe I won't bother ;)
But if Miller decides it should go away, indeed, just say the word and I can go ahead and do the job.
cheers
2017-07-31 17:02 GMT-03:00 Alexandre Torres Porres porres@gmail.com:
2017-07-31 16:56 GMT-03:00 Dan Wilcox danomatika@gmail.com:
I have the feeling [midiclkin] will not be removed and, s IOhannes suggests, it's better to put the help file updates in a different PR.
Ok, I'll do that! But I was also acting on Miller's request to remove it, and it also involves messing with help documentation. I'll just break them into two other requests.
cheers
I thought it was gone already... looks like I fumbled it somehow. But I think let's leave it for teh next release - too much stuff is going on for me to track it competently :)
M
On Mon, Jul 31, 2017 at 05:40:55PM -0300, Alexandre Torres Porres wrote:
well, I closed it and created a new PR just for the help updates. If [midiclkin] is probably staying after all and the PR has a chance to not be merged, maybe I won't bother ;)
But if Miller decides it should go away, indeed, just say the word and I can go ahead and do the job.
cheers
2017-07-31 17:02 GMT-03:00 Alexandre Torres Porres porres@gmail.com:
2017-07-31 16:56 GMT-03:00 Dan Wilcox danomatika@gmail.com:
I have the feeling [midiclkin] will not be removed and, s IOhannes suggests, it's better to put the help file updates in a different PR.
Ok, I'll do that! But I was also acting on Miller's request to remove it, and it also involves messing with help documentation. I'll just break them into two other requests.
cheers
On Jul 31, 2017, at 10:58 PM, Miller Puckette msp@ucsd.edu wrote:
- too much stuff is going on for
me to track it competently :)
You can blame me for that. I'm trying to handle the bug reports for what we have now.
-------- Dan Wilcox @danomatika http://twitter.com/danomatika danomatika.com http://danomatika.com/ robotcowboy.com http://robotcowboy.com/
Haha!
Ok! Once this is out, I'll pinch it again
2017-07-31 17:58 GMT-03:00 Miller Puckette msp@ucsd.edu:
I thought it was gone already... looks like I fumbled it somehow. But I think let's leave it for teh next release - too much stuff is going on for me to track it competently :)
M
On Mon, Jul 31, 2017 at 05:40:55PM -0300, Alexandre Torres Porres wrote:
well, I closed it and created a new PR just for the help updates. If [midiclkin] is probably staying after all and the PR has a chance to not
be
merged, maybe I won't bother ;)
But if Miller decides it should go away, indeed, just say the word and I can go ahead and do the job.
cheers
2017-07-31 17:02 GMT-03:00 Alexandre Torres Porres porres@gmail.com:
2017-07-31 16:56 GMT-03:00 Dan Wilcox danomatika@gmail.com:
I have the feeling [midiclkin] will not be removed and, s IOhannes suggests, it's better to put the help file updates in a different PR.
Ok, I'll do that! But I was also acting on Miller's request to remove
it,
and it also involves messing with help documentation. I'll just break
them
into two other requests.
cheers
oops,
I'll "pitch" it again (so much for the brazilian trying to sound american)
2017-07-31 18:06 GMT-03:00 Alexandre Torres Porres porres@gmail.com:
Haha!
Ok! Once this is out, I'll pinch it again
2017-07-31 17:58 GMT-03:00 Miller Puckette msp@ucsd.edu:
I thought it was gone already... looks like I fumbled it somehow. But I think let's leave it for teh next release - too much stuff is going on for me to track it competently :)
M
On Mon, Jul 31, 2017 at 05:40:55PM -0300, Alexandre Torres Porres wrote:
well, I closed it and created a new PR just for the help updates. If [midiclkin] is probably staying after all and the PR has a chance to
not be
merged, maybe I won't bother ;)
But if Miller decides it should go away, indeed, just say the word and I can go ahead and do the job.
cheers
2017-07-31 17:02 GMT-03:00 Alexandre Torres Porres porres@gmail.com:
2017-07-31 16:56 GMT-03:00 Dan Wilcox danomatika@gmail.com:
I have the feeling [midiclkin] will not be removed and, s IOhannes suggests, it's better to put the help file updates in a different PR.
Ok, I'll do that! But I was also acting on Miller's request to remove
it,
and it also involves messing with help documentation. I'll just break
them
into two other requests.
cheers