I'm working on an external that loads analysis data into tables for use in re-synthesis and I want to make sure I'm not going to be leaking memory with this approach.
I'd like to be able to load several sets of tables with a single object, and then access that data with an arbitrary number of resynthizers.
So my question is: if I allocate an array/table in an external, do I have to manage its de-allocation or is there some sort of reference counter?
How about with canvases? If I create a canvas per analysis data set, do I have to manage the canvas de-allocation? If I de-allocate an array (inside a canvas I create in code or not) and some other object is using that array, what happens?
Thanks, Ale
Hi,
So my question is: if I allocate an array/table in an external, do I have to manage its de-allocation or is there some sort of reference counter?
A graphical array always belongs to a canvas and it will be automatically be destroyed when the canvas is freed. Destroying a single graphical array in code is a bit tricky and you need stuff from private headers like g_canvas.h.
How about with canvases? If I create a canvas per analysis data set, do I have to manage the canvas de-allocation?
This is how you create a private canvas in the object constructor:
pd_vmess(&pd_canvasmaker,gensym("canvas"),"iiiii",0,0,100,100,10); x_canvas =(t_canvas*)s__X.s_thing;
pd_vmess((t_pd *)x_canvas, gensym("pop"),"i",0);
Such a canvas will have an owner, but it doesn't actually belong to a glist, so you have to free it yourself in the destructor:
pd_free((t_pd *)x_canvas);
Note that if you want to create a table outside the object constructor, you should cache the current canvas with canvas_getcurrent() in the constructor. Before creating a new canvas you have to push the cached canvas with pd_push() or canvas_setcurrent() and in the end pop it with pd_pop() or canvas_unsetcurrent(). This makes sure that the canvas gets an owner and doesn't go to the root canvas list.
If I de-allocate an array (inside a canvas I create in code or not) and some other object is using that array, what happens?
A crash :-) Unless the object uses a gpointer, so it can check whether the glist is still alive.
I just want to stress that managing canvasses/garrays programmatically is not officially supported by the Pd API. It's possible with the workarounds shown above, but I wouldn't recommend it unless it's 100% necessary.
---
I'd like to be able to load several sets of tables with a single object, and then access that data with an arbitrary number of resynthizers.
You might reconsider whether you really need actual Pd tables to do this. I think you only need them if the data should be accessible as tables outside your own externals. Otherwise I would strongly recommend to use your own private data structure and share it among your externals.
Just create a faux-class like this:
static t_class *data_class;
typedef struct _data { t_pd d_pd; // your data.. } t_data;
// in the setup routine: data_class=class_new(gensym("data private"), 0,0,sizeof(t_data),CLASS_PD,0);
There's no need to (de)allocate instances with pd_new()/pd_free(), you can just do getbytes()/freebytes(), but you have to make sure to set d_pd to data_class. See the "alist" class in x_list.c.
Because t_data is a Pd class, you can now safely bind instances to symbols with pd_bind() and retrieve instances with pd_findbyclass().
As you can see, this allows you to easily share custom data structures across externals. This is also safe as long as you always access the data through the symbol with pd_findbyclass(). It will return NULL if the data has been unbound (and deleted).
This means you can have an object similar to [array define] which creates a t_data instance and binds it to a symbol. In your patch you can pass this symbol to your other externals which can retrieve the data and do something with it.
Christof
On 27.01.2020 19:54, x nor wrote:
I'm working on an external that loads analysis data into tables for use in re-synthesis and I want to make sure I'm not going to be leaking memory with this approach.
I'd like to be able to load several sets of tables with a single object, and then access that data with an arbitrary number of resynthizers.
So my question is: if I allocate an array/table in an external, do I have to manage its de-allocation or is there some sort of reference counter?
How about with canvases? If I create a canvas per analysis data set, do I have to manage the canvas de-allocation? If I de-allocate an array (inside a canvas I create in code or not) and some other object is using that array, what happens?
Thanks, Ale
Pd-dev mailing list Pd-dev@lists.iem.at https://lists.puredata.info/listinfo/pd-dev
Thanks for your insights Christof!
I would like to be able to access the data outside my external, specifically with tabread4~. I'm thinking I will create a canvas per data set, managed by my object, that has all the tables I need, via the approach you gave me some weeks ago (binbuf). The private data structure approach is interesting but part of the point is being able to utilize this data outside of the externals I write, but either way it is good to know about that appraoch.
-Alex
On Tue, Jan 28, 2020 at 6:41 AM Christof Ressi info@christofressi.com wrote:
Hi,
So my question is: if I allocate an array/table in an external, do I have to manage its de-allocation or is there some sort of reference counter?
A graphical array always belongs to a canvas and it will be automatically be destroyed when the canvas is freed. Destroying a single graphical array in code is a bit tricky and you need stuff from private headers like g_canvas.h.
How about with canvases? If I create a canvas per analysis data set, do I have to manage the canvas de-allocation?
This is how you create a private canvas in the object constructor:
pd_vmess(&pd_canvasmaker, gensym("canvas"), "iiiii", 0, 0, 100, 100, 10);x_canvas = (t_canvas *)s__X.s_thing;
pd_vmess((t_pd *)x_canvas, gensym("pop"), "i", 0);
Such a canvas will have an owner, but it doesn't actually belong to a glist, so you have to free it yourself in the destructor:
pd_free((t_pd *)x_canvas);
Note that if you want to create a table outside the object constructor, you should cache the current canvas with canvas_getcurrent() in the constructor. Before creating a new canvas you have to push the cached canvas with pd_push() or canvas_setcurrent() and in the end pop it with pd_pop() or canvas_unsetcurrent(). This makes sure that the canvas gets an owner and doesn't go to the root canvas list.
If I de-allocate an array (inside a canvas I create in code or not) and some other object is using that array, what happens?
A crash :-) Unless the object uses a gpointer, so it can check whether the glist is still alive.
I just want to stress that managing canvasses/garrays programmatically is not officially supported by the Pd API. It's possible with the workarounds shown above, but I wouldn't recommend it unless it's 100% necessary.
I'd like to be able to load several sets of tables with a single object, and then access that data with an arbitrary number of resynthizers.
You might reconsider whether you really need actual Pd tables to do this. I think you only need them if the data should be accessible as tables outside your own externals. Otherwise I would strongly recommend to use your own private data structure and share it among your externals.
Just create a faux-class like this:
static t_class *data_class;
typedef struct _data { t_pd d_pd; // your data.. } t_data;
// in the setup routine: data_class = class_new(gensym("data private"), 0, 0, sizeof(t_data), CLASS_PD, 0);
There's no need to (de)allocate instances with pd_new()/pd_free(), you can just do getbytes()/freebytes(), but you have to make sure to set d_pd to data_class. See the "alist" class in x_list.c.
Because t_data is a Pd class, you can now safely bind instances to symbols with pd_bind() and retrieve instances with pd_findbyclass().
As you can see, this allows you to easily share custom data structures across externals. This is also safe as long as you always access the data through the symbol with pd_findbyclass(). It will return NULL if the data has been unbound (and deleted).
This means you can have an object similar to [array define] which creates a t_data instance and binds it to a symbol. In your patch you can pass this symbol to your other externals which can retrieve the data and do something with it.
Christof On 27.01.2020 19:54, x nor wrote:
I'm working on an external that loads analysis data into tables for use in re-synthesis and I want to make sure I'm not going to be leaking memory with this approach.
I'd like to be able to load several sets of tables with a single object, and then access that data with an arbitrary number of resynthizers.
So my question is: if I allocate an array/table in an external, do I have to manage its de-allocation or is there some sort of reference counter?
How about with canvases? If I create a canvas per analysis data set, do I have to manage the canvas de-allocation? If I de-allocate an array (inside a canvas I create in code or not) and some other object is using that array, what happens?
Thanks, Ale
Pd-dev mailing listPd-dev@lists.iem.athttps://lists.puredata.info/listinfo/pd-dev
Pd-dev mailing list Pd-dev@lists.iem.at https://lists.puredata.info/listinfo/pd-dev
Since the only problem is managing (de)allocation of arrays, another option would be to ask the user to provide the arrays and pass the symbol to the external. The external can then resize it with garray_resize_long() to the required size. Might save you some headache :-)
via the approach you gave me some weeks ago (binbuf).
Binbufs are useful for dynamically creating patch files, but adding a single garray to a canvas is much easier:
pd_vmess((t_pd *)mycanvas, gensym("obj"), "iisss", 0, 0, gensym("array"), gensym("define"), arraysymbol);
This basically sends the message "obj 0 0 array define arraysymbol" to the canvas like in dynamic patching.
Christof
On 30.01.2020 19:14, x nor wrote:
Thanks for your insights Christof!
I would like to be able to access the data outside my external, specifically with tabread4~. I'm thinking I will create a canvas per data set, managed by my object, that has all the tables I need, via the approach you gave me some weeks ago (binbuf). The private data structure approach is interesting but part of the point is being able to utilize this data outside of the externals I write, but either way it is good to know about that appraoch.
-Alex
On Tue, Jan 28, 2020 at 6:41 AM Christof Ressi <info@christofressi.com mailto:info@christofressi.com> wrote:
Hi,
So my question is: if I allocate an array/table in an external, do I have to manage its de-allocation or is there some sort of reference counter?
A graphical array always belongs to a canvas and it will be automatically be destroyed when the canvas is freed. Destroying a single graphical array in code is a bit tricky and you need stuff from private headers like g_canvas.h.
How about with canvases? If I create a canvas per analysis data set, do I have to manage the canvas de-allocation?
This is how you create a private canvas in the object constructor: pd_vmess(&pd_canvasmaker,gensym("canvas"),"iiiii",0,0,100,100,10); x_canvas =(t_canvas*)s__X.s_thing; pd_vmess((t_pd *)x_canvas, gensym("pop"),"i",0); Such a canvas will have an owner, but it doesn't actually belong to a glist, so you have to free it yourself in the destructor: pd_free((t_pd *)x_canvas); Note that if you want to create a table outside the object constructor, you should cache the current canvas with canvas_getcurrent() in the constructor. Before creating a new canvas you have to push the cached canvas with pd_push() or canvas_setcurrent() and in the end pop it with pd_pop() or canvas_unsetcurrent(). This makes sure that the canvas gets an owner and doesn't go to the root canvas list.
If I de-allocate an array (inside a canvas I create in code or not) and some other object is using that array, what happens?
A crash :-) Unless the object uses a gpointer, so it can check whether the glist is still alive. I just want to stress that managing canvasses/garrays programmatically is not officially supported by the Pd API. It's possible with the workarounds shown above, but I wouldn't recommend it unless it's 100% necessary. ---
I'd like to be able to load several sets of tables with a single object, and then access that data with an arbitrary number of resynthizers.
You might reconsider whether you really need actual Pd tables to do this. I think you only need them if the data should be accessible as tables outside your own externals. Otherwise I would strongly recommend to use your own private data structure and share it among your externals. Just create a faux-class like this: static t_class *data_class; typedef struct _data { t_pd d_pd; // your data.. } t_data; // in the setup routine: data_class=class_new(gensym("data private"), 0,0,sizeof(t_data),CLASS_PD,0); There's no need to (de)allocate instances with pd_new()/pd_free(), you can just do getbytes()/freebytes(), but you have to make sure to set d_pd to data_class. See the "alist" class in x_list.c. Because t_data is a Pd class, you can now safely bind instances to symbols with pd_bind() and retrieve instances with pd_findbyclass(). As you can see, this allows you to easily share custom data structures across externals. This is also safe as long as you always access the data through the symbol with pd_findbyclass(). It will return NULL if the data has been unbound (and deleted). This means you can have an object similar to [array define] which creates a t_data instance and binds it to a symbol. In your patch you can pass this symbol to your other externals which can retrieve the data and do something with it. Christof On 27.01.2020 19:54, x nor wrote:
I'm working on an external that loads analysis data into tables for use in re-synthesis and I want to make sure I'm not going to be leaking memory with this approach. I'd like to be able to load several sets of tables with a single object, and then access that data with an arbitrary number of resynthizers. So my question is: if I allocate an array/table in an external, do I have to manage its de-allocation or is there some sort of reference counter? How about with canvases? If I create a canvas per analysis data set, do I have to manage the canvas de-allocation? If I de-allocate an array (inside a canvas I create in code or not) and some other object is using that array, what happens? Thanks, Ale _______________________________________________ Pd-dev mailing list Pd-dev@lists.iem.at <mailto:Pd-dev@lists.iem.at> https://lists.puredata.info/listinfo/pd-dev
_______________________________________________ Pd-dev mailing list Pd-dev@lists.iem.at <mailto:Pd-dev@lists.iem.at> https://lists.puredata.info/listinfo/pd-dev
The analysis data sets will have a variable number of tables depending on the analysis parameters and the audio that was analyzed so unless I want to do mega long table with offsets or have the user overshoot the count of tables, that would be rather cumbersome. As an example, one data set has 3x42 tables of data... Would be cool if PD had multi dimensional tables readable by the standard table objects..
-Alex
On Thu, Jan 30, 2020 at 10:46 AM Christof Ressi info@christofressi.com wrote:
Since the only problem is managing (de)allocation of arrays, another option would be to ask the user to provide the arrays and pass the symbol to the external. The external can then resize it with garray_resize_long() to the required size. Might save you some headache :-)
via the approach you gave me some weeks ago (binbuf).
Binbufs are useful for dynamically creating patch files, but adding a single garray to a canvas is much easier:
pd_vmess((t_pd *)mycanvas, gensym("obj"), "iisss", 0, 0, gensym("array"), gensym("define"), arraysymbol);
This basically sends the message "obj 0 0 array define arraysymbol" to the canvas like in dynamic patching.
Christof On 30.01.2020 19:14, x nor wrote:
Thanks for your insights Christof!
I would like to be able to access the data outside my external, specifically with tabread4~. I'm thinking I will create a canvas per data set, managed by my object, that has all the tables I need, via the approach you gave me some weeks ago (binbuf). The private data structure approach is interesting but part of the point is being able to utilize this data outside of the externals I write, but either way it is good to know about that appraoch.
-Alex
On Tue, Jan 28, 2020 at 6:41 AM Christof Ressi info@christofressi.com wrote:
Hi,
So my question is: if I allocate an array/table in an external, do I have to manage its de-allocation or is there some sort of reference counter?
A graphical array always belongs to a canvas and it will be automatically be destroyed when the canvas is freed. Destroying a single graphical array in code is a bit tricky and you need stuff from private headers like g_canvas.h.
How about with canvases? If I create a canvas per analysis data set, do I have to manage the canvas de-allocation?
This is how you create a private canvas in the object constructor:
pd_vmess(&pd_canvasmaker, gensym("canvas"), "iiiii", 0, 0, 100, 100, 10);x_canvas = (t_canvas *)s__X.s_thing;
pd_vmess((t_pd *)x_canvas, gensym("pop"), "i", 0);
Such a canvas will have an owner, but it doesn't actually belong to a glist, so you have to free it yourself in the destructor:
pd_free((t_pd *)x_canvas);
Note that if you want to create a table outside the object constructor, you should cache the current canvas with canvas_getcurrent() in the constructor. Before creating a new canvas you have to push the cached canvas with pd_push() or canvas_setcurrent() and in the end pop it with pd_pop() or canvas_unsetcurrent(). This makes sure that the canvas gets an owner and doesn't go to the root canvas list.
If I de-allocate an array (inside a canvas I create in code or not) and some other object is using that array, what happens?
A crash :-) Unless the object uses a gpointer, so it can check whether the glist is still alive.
I just want to stress that managing canvasses/garrays programmatically is not officially supported by the Pd API. It's possible with the workarounds shown above, but I wouldn't recommend it unless it's 100% necessary.
I'd like to be able to load several sets of tables with a single object, and then access that data with an arbitrary number of resynthizers.
You might reconsider whether you really need actual Pd tables to do this. I think you only need them if the data should be accessible as tables outside your own externals. Otherwise I would strongly recommend to use your own private data structure and share it among your externals.
Just create a faux-class like this:
static t_class *data_class;
typedef struct _data { t_pd d_pd; // your data.. } t_data;
// in the setup routine: data_class = class_new(gensym("data private"), 0, 0, sizeof(t_data), CLASS_PD, 0);
There's no need to (de)allocate instances with pd_new()/pd_free(), you can just do getbytes()/freebytes(), but you have to make sure to set d_pd to data_class. See the "alist" class in x_list.c.
Because t_data is a Pd class, you can now safely bind instances to symbols with pd_bind() and retrieve instances with pd_findbyclass().
As you can see, this allows you to easily share custom data structures across externals. This is also safe as long as you always access the data through the symbol with pd_findbyclass(). It will return NULL if the data has been unbound (and deleted).
This means you can have an object similar to [array define] which creates a t_data instance and binds it to a symbol. In your patch you can pass this symbol to your other externals which can retrieve the data and do something with it.
Christof On 27.01.2020 19:54, x nor wrote:
I'm working on an external that loads analysis data into tables for use in re-synthesis and I want to make sure I'm not going to be leaking memory with this approach.
I'd like to be able to load several sets of tables with a single object, and then access that data with an arbitrary number of resynthizers.
So my question is: if I allocate an array/table in an external, do I have to manage its de-allocation or is there some sort of reference counter?
How about with canvases? If I create a canvas per analysis data set, do I have to manage the canvas de-allocation? If I de-allocate an array (inside a canvas I create in code or not) and some other object is using that array, what happens?
Thanks, Ale
Pd-dev mailing listPd-dev@lists.iem.athttps://lists.puredata.info/listinfo/pd-dev
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
[clone] allows to easily create multiple tables encapsulated into abstractions. This way you can kinda emulate multi-dimensional tables...
Le jeu. 30 janv. 2020 à 20:43, x nor x37v.alex@gmail.com a écrit :
The analysis data sets will have a variable number of tables depending on the analysis parameters and the audio that was analyzed so unless I want to do mega long table with offsets or have the user overshoot the count of tables, that would be rather cumbersome. As an example, one data set has 3x42 tables of data... Would be cool if PD had multi dimensional tables readable by the standard table objects..
-Alex
On Thu, Jan 30, 2020 at 10:46 AM Christof Ressi info@christofressi.com wrote:
Since the only problem is managing (de)allocation of arrays, another option would be to ask the user to provide the arrays and pass the symbol to the external. The external can then resize it with garray_resize_long() to the required size. Might save you some headache :-)
via the approach you gave me some weeks ago (binbuf).
Binbufs are useful for dynamically creating patch files, but adding a single garray to a canvas is much easier:
pd_vmess((t_pd *)mycanvas, gensym("obj"), "iisss", 0, 0, gensym("array"), gensym("define"), arraysymbol);
This basically sends the message "obj 0 0 array define arraysymbol" to the canvas like in dynamic patching.
Christof On 30.01.2020 19:14, x nor wrote:
Thanks for your insights Christof!
I would like to be able to access the data outside my external, specifically with tabread4~. I'm thinking I will create a canvas per data set, managed by my object, that has all the tables I need, via the approach you gave me some weeks ago (binbuf). The private data structure approach is interesting but part of the point is being able to utilize this data outside of the externals I write, but either way it is good to know about that appraoch.
-Alex
On Tue, Jan 28, 2020 at 6:41 AM Christof Ressi info@christofressi.com wrote:
Hi,
So my question is: if I allocate an array/table in an external, do I have to manage its de-allocation or is there some sort of reference counter?
A graphical array always belongs to a canvas and it will be automatically be destroyed when the canvas is freed. Destroying a single graphical array in code is a bit tricky and you need stuff from private headers like g_canvas.h.
How about with canvases? If I create a canvas per analysis data set, do I have to manage the canvas de-allocation?
This is how you create a private canvas in the object constructor:
pd_vmess(&pd_canvasmaker, gensym("canvas"), "iiiii", 0, 0, 100, 100, 10);x_canvas = (t_canvas *)s__X.s_thing;
pd_vmess((t_pd *)x_canvas, gensym("pop"), "i", 0);
Such a canvas will have an owner, but it doesn't actually belong to a glist, so you have to free it yourself in the destructor:
pd_free((t_pd *)x_canvas);
Note that if you want to create a table outside the object constructor, you should cache the current canvas with canvas_getcurrent() in the constructor. Before creating a new canvas you have to push the cached canvas with pd_push() or canvas_setcurrent() and in the end pop it with pd_pop() or canvas_unsetcurrent(). This makes sure that the canvas gets an owner and doesn't go to the root canvas list.
If I de-allocate an array (inside a canvas I create in code or not) and some other object is using that array, what happens?
A crash :-) Unless the object uses a gpointer, so it can check whether the glist is still alive.
I just want to stress that managing canvasses/garrays programmatically is not officially supported by the Pd API. It's possible with the workarounds shown above, but I wouldn't recommend it unless it's 100% necessary.
I'd like to be able to load several sets of tables with a single object, and then access that data with an arbitrary number of resynthizers.
You might reconsider whether you really need actual Pd tables to do this. I think you only need them if the data should be accessible as tables outside your own externals. Otherwise I would strongly recommend to use your own private data structure and share it among your externals.
Just create a faux-class like this:
static t_class *data_class;
typedef struct _data { t_pd d_pd; // your data.. } t_data;
// in the setup routine: data_class = class_new(gensym("data private"), 0, 0, sizeof(t_data), CLASS_PD, 0);
There's no need to (de)allocate instances with pd_new()/pd_free(), you can just do getbytes()/freebytes(), but you have to make sure to set d_pd to data_class. See the "alist" class in x_list.c.
Because t_data is a Pd class, you can now safely bind instances to symbols with pd_bind() and retrieve instances with pd_findbyclass().
As you can see, this allows you to easily share custom data structures across externals. This is also safe as long as you always access the data through the symbol with pd_findbyclass(). It will return NULL if the data has been unbound (and deleted).
This means you can have an object similar to [array define] which creates a t_data instance and binds it to a symbol. In your patch you can pass this symbol to your other externals which can retrieve the data and do something with it.
Christof On 27.01.2020 19:54, x nor wrote:
I'm working on an external that loads analysis data into tables for use in re-synthesis and I want to make sure I'm not going to be leaking memory with this approach.
I'd like to be able to load several sets of tables with a single object, and then access that data with an arbitrary number of resynthizers.
So my question is: if I allocate an array/table in an external, do I have to manage its de-allocation or is there some sort of reference counter?
How about with canvases? If I create a canvas per analysis data set, do I have to manage the canvas de-allocation? If I de-allocate an array (inside a canvas I create in code or not) and some other object is using that array, what happens?
Thanks, Ale
Pd-dev mailing listPd-dev@lists.iem.athttps://lists.puredata.info/listinfo/pd-dev
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
Pd-dev mailing list Pd-dev@lists.iem.at https://lists.puredata.info/listinfo/pd-dev