[PD-dev] array/table and canvas memory management

Antoine Rousseau antoine at metalu.net
Thu Jan 30 23:35:00 CET 2020


[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 at 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 at 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 at 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 at lists.iem.athttps://lists.puredata.info/listinfo/pd-dev
>>>
>>> _______________________________________________
>>> Pd-dev mailing list
>>> Pd-dev at lists.iem.at
>>> https://lists.puredata.info/listinfo/pd-dev
>>>
>> _______________________________________________
>> Pd-dev mailing list
>> Pd-dev at lists.iem.at
>> https://lists.puredata.info/listinfo/pd-dev
>>
> _______________________________________________
> Pd-dev mailing list
> Pd-dev at lists.iem.at
> https://lists.puredata.info/listinfo/pd-dev
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.puredata.info/pipermail/pd-dev/attachments/20200130/176ffd14/attachment-0001.html>


More information about the Pd-dev mailing list