<div dir="ltr"><div>Thanks for your insights Christof!</div><div><br></div><div>I would like to be able to access the data outside my external, specifically with tabread4~.</div><div>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).<br></div><div>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.<br></div><div><br></div><div>-Alex<br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Tue, Jan 28, 2020 at 6:41 AM Christof Ressi <<a href="mailto:info@christofressi.com">info@christofressi.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
  
    
  
  <div>
    <p>Hi,</p>
    <p>
      </p><blockquote type="cite">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?</blockquote>
    <p></p>
    <p>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.</p>
    <p>
      </p><blockquote type="cite">
        <div>How about with canvases?</div>
        <div>If I create a canvas per analysis data set, do I have to
          manage the canvas de-allocation? <br>
        </div>
      </blockquote>
    <p></p>
    <p>This is how you create a private canvas in the object
      constructor:<span style="color:rgb(0,0,0)"></span><br>
      <span style="color:rgb(0,0,0)"></span></p>
    <pre style="margin:0px;text-indent:0px"><span style="color:rgb(0,0,0)">pd_vmess</span><span style="color:rgb(0,0,0)">(&</span>pd_canvasmaker<span style="color:rgb(0,0,0)">,</span><span style="color:rgb(192,192,192)"> </span><span style="color:rgb(0,0,0)">gensym</span><span style="color:rgb(0,0,0)">(</span><span style="color:rgb(0,128,0)">"canvas"</span><span style="color:rgb(0,0,0)">),</span><span style="color:rgb(192,192,192)"> </span><span style="color:rgb(0,0,0)"></span><span style="color:rgb(128,128,0)"></span><span style="color:rgb(192,192,192)"></span><span style="color:rgb(0,0,0)"></span><span style="color:rgb(0,128,0)">"iiiii"</span><span style="color:rgb(0,0,0)">,</span><span style="color:rgb(192,192,192)"> </span><span style="color:rgb(0,0,128)">0</span><span style="color:rgb(0,0,0)">,</span><span style="color:rgb(192,192,192)"> </span><span style="color:rgb(0,0,128)">0</span><span style="color:rgb(0,0,0)">,</span><span style="color:rgb(192,192,192)"> </span><span style="color:rgb(0,0,128)">100</span><span style="color:rgb(0,0,0)">,</span><span style="color:rgb(192,192,192)"> </span><span style="color:rgb(0,0,128)">100</span><span style="color:rgb(0,0,0)">,</span><span style="color:rgb(192,192,192)"> </span><span style="color:rgb(0,0,128)">10</span><span style="color:rgb(0,0,0)">);</span>
<span style="color:rgb(128,0,0)">x_canvas </span><span style="color:rgb(0,0,0)">=</span><span style="color:rgb(192,192,192)"> </span><span style="color:rgb(0,0,0)">(</span><span style="color:rgb(0,0,128)">t_canvas</span><span style="color:rgb(192,192,192)"> </span><span style="color:rgb(0,0,0)">*)</span>s__X<span style="color:rgb(0,0,0)">.</span><span style="color:rgb(128,0,0)">s_thing</span><span style="color:rgb(0,0,0)">;</span></pre>
    <pre style="margin:0px;text-indent:0px">pd_vmess<span style="color:rgb(0,0,0)">((t_pd *)x_canvas, </span><span style="color:rgb(0,0,0)">gensym</span><span style="color:rgb(0,0,0)">(</span><span style="color:rgb(0,128,0)">"pop"</span><span style="color:rgb(0,0,0)">),</span><span style="color:rgb(192,192,192)"> </span><span style="color:rgb(0,128,0)">"i"</span><span style="color:rgb(0,0,0)">,</span><span style="color:rgb(192,192,192)"> </span><span style="color:rgb(0,0,128)">0</span><span style="color:rgb(0,0,0)">);</span></pre>
    <p>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:</p>
    <pre>pd_free((t_pd *)x_canvas);</pre>
    <p>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.<br>
    </p>
    <p>
      </p><blockquote type="cite">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?</blockquote>
    <p></p>
    <p>A crash :-) Unless the object uses a gpointer, so it can check
      whether the glist is still alive.</p>
    <p>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.</p>
    <p>---<br>
    </p>
    <p>
      </p><blockquote type="cite">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.</blockquote>
    <p></p>
    <p>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.</p>
    <p>Just create a faux-class like this:<br>
    </p>
    <pre>static t_class *data_class;

typedef struct _data {
    t_pd d_pd;
    // your data..
} t_data;

// in the setup routine:
data_class <span style="color:rgb(0,0,0)">=</span><span style="color:rgb(192,192,192)"> </span><span style="color:rgb(0,0,0)">class_new</span><span style="color:rgb(0,0,0)">(</span><span style="color:rgb(0,0,0)">gensym</span><span style="color:rgb(0,0,0)">(</span><span style="color:rgb(0,128,0)">"data private</span><span style="color:rgb(0,128,0)">"</span><span style="color:rgb(0,0,0)">),</span>
<span style="color:rgb(192,192,192)">        </span><span style="color:rgb(0,0,128)">0</span><span style="color:rgb(0,0,0)">,</span><span style="color:rgb(192,192,192)"> </span><span style="color:rgb(0,0,128)">0</span><span style="color:rgb(0,0,0)">,</span><span style="color:rgb(192,192,192)"> </span><span style="color:rgb(128,128,0)">sizeof</span><span style="color:rgb(0,0,0)">(t_data</span><span style="color:rgb(0,0,0)">),</span><span style="color:rgb(192,192,192)"> </span><span style="color:rgb(0,0,128)">CLASS_PD</span><span style="color:rgb(0,0,0)">,</span><span style="color:rgb(192,192,192)"> </span><span style="color:rgb(0,0,128)">0</span><span style="color:rgb(0,0,0)">);</span>

</pre>
    <p>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.<br>
    </p>
    <p>Because t_data is a Pd class, you can now safely bind instances
      to symbols with pd_bind() and retrieve instances with <span style="color:rgb(0,0,0)">pd_findbyclass().</span></p>
    <p><span style="color:rgb(0,0,0)">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).<br>
      </span></p>
    <p><span style="color:rgb(0,0,0)">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.<br>
      </span></p>
    <p><span style="color:rgb(0,0,0)">Christof<br>
      </span></p>
    <div>On 27.01.2020 19:54, x nor wrote:<br>
    </div>
    <blockquote type="cite">
      
      <div dir="ltr">
        <div>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.</div>
        <div><br>
        </div>
        <div>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.</div>
        <div><br>
        </div>
        <div>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?</div>
        <div><br>
        </div>
        <div>How about with canvases?</div>
        <div>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?</div>
        <div><br>
        </div>
        <div>Thanks,</div>
        <div>Ale</div>
      </div>
      <br>
      <fieldset></fieldset>
      <pre>_______________________________________________
Pd-dev mailing list
<a href="mailto:Pd-dev@lists.iem.at" target="_blank">Pd-dev@lists.iem.at</a>
<a href="https://lists.puredata.info/listinfo/pd-dev" target="_blank">https://lists.puredata.info/listinfo/pd-dev</a>
</pre>
    </blockquote>
  </div>

_______________________________________________<br>
Pd-dev mailing list<br>
<a href="mailto:Pd-dev@lists.iem.at" target="_blank">Pd-dev@lists.iem.at</a><br>
<a href="https://lists.puredata.info/listinfo/pd-dev" rel="noreferrer" target="_blank">https://lists.puredata.info/listinfo/pd-dev</a><br>
</blockquote></div>