hi all,
is it possible -in the context of writing a pd external class- to invisibly patch some other object and attach to it/bind it?
I'll try to explain better with an example: if I were writing an external that is somewhat an interface to arrays (read/write), I have some design choices:
1) copy/paste the code of array (g_array.c) (or eventually only copy [tabread]/[tabwrite]) pros: resulting external is tight & tidy cons: code duplication, possible breakage in future releases
2) provide appropriate inlets and outlets, and require the user to patch the external among [tabread]/[tabwrite] objects pros: modular. is independent from the array implementation. cons: tricky to use, the user can patch it incorrectly and won't work.
3) is possible to patch the required objects without phisically put them in the canvas [?] pros: all pros mentioned in 1) and 2) cons: [?]
obviously, 1) and 2) are ugly under some point of view; what I am interested in is 3), hence asking here if possible, and directions on how to proceed.
thanks
On Sun, Sep 13, 2009 at 9:01 PM, mescalinum@gmail.com mescalinum@gmail.comwrote:
if I were writing an external that is somewhat an interface to arrays (read/write), I have some design choices:
- copy/paste the code of array (g_array.c) (or eventually only copy
[tabread]/[tabwrite]) pros: resulting external is tight & tidy cons: code duplication, possible breakage in future releases
- provide appropriate inlets and outlets, and require the user to patch
the external among [tabread]/[tabwrite] objects pros: modular. is independent from the array implementation. cons: tricky to use, the user can patch it incorrectly and won't work.
- is possible to patch the required objects without phisically put them
in the canvas [?] pros: all pros mentioned in 1) and 2) cons: [?]
obviously, 1) and 2) are ugly under some point of view; what I am interested in is 3), hence asking here if possible, and directions on how to proceed.
I would suggest the following two options. Everything used in the examples is declared in the "m_pd.h" header that you have to include in your external anyway. Basically, I will explain the techniques used by the pd objects that operate on arrays and the delay objects, so this is stuff that will most probably not be broken for numerous future releases, or a very large part of pd should drastically change.
1. You can get a direct pointer to data stored in a g_array with the following code:
t_symbol *array_name = gensym( "array-named-foo"); t_pd *the_array = *pd_findbyclass*( array_name, garray_class ); int size; t_float *data; *garray_getfloatarray*( (t_garray) the_array, &size, &data );
You have to pass the name of the array as it was set in the pd patch as the "s" argument of pd_findbyclass function. Therefore you can easily let the user choose the array you will operate on via an argument to your external.
2. You can associate your pd external with a symbol using the function
void *pd_bind*(t_pd *x, t_symbol *s)
...where you pass the struct of your external as the "x" argument (you can easily cast it to t_pd). What this means in effect is that you can get a pointer to that structure from another external with the already introduced *pd_findbyclass* function, by passing it as arguments the registered symbol and the *t_class* of the registered external. Again, it is a good idea to let the user choose the registered symbol via an argument of the external.
This effectively means that you can separate the functionality you want to achieve into many externals, so that one allocates memory for some data in its struct and the others will be able to operate on that memory by accesing the struct of the registered external, while the "invisible connections" are made via the symbols that the user gives as arguments to the externals (we can say, by the names that the user assigns to the instances of the externals).
If you have further questions, please ask!
Best regards, Jakob Leben
Jakob Leben wrote:
On Sun, Sep 13, 2009 at 9:01 PM, mescalinum@gmail.com mailto:mescalinum@gmail.com <mescalinum@gmail.com mailto:mescalinum@gmail.com> wrote:
if I were writing an external that is somewhat an interface to arrays (read/write), I have some design choices: 1) copy/paste the code of array (g_array.c) (or eventually only copy [tabread]/[tabwrite]) pros: resulting external is tight & tidy cons: code duplication, possible breakage in future releases 2) provide appropriate inlets and outlets, and require the user to patch the external among [tabread]/[tabwrite] objects pros: modular. is independent from the array implementation. cons: tricky to use, the user can patch it incorrectly and won't work. 3) is possible to patch the required objects without phisically put them in the canvas [?] pros: all pros mentioned in 1) and 2) cons: [?] obviously, 1) and 2) are ugly under some point of view; what I am interested in is 3), hence asking here if possible, and directions on how to proceed.
I would suggest the following two options. Everything used in the examples is declared in the "m_pd.h" header that you have to include in your external anyway. Basically, I will explain the techniques used by the pd objects that operate on arrays and the delay objects, so this is stuff that will most probably not be broken for numerous future releases, or a very large part of pd should drastically change.
You can get a direct pointer to data stored in a g_array with the following code:
t_symbol *array_name = gensym( "array-named-foo"); t_pd *the_array = *pd_findbyclass*( array_name, garray_class ); int size; t_float *data; *garray_getfloatarray*( (t_garray) the_array, &size, &data );
You have to pass the name of the array as it was set in the pd patch as the "s" argument of pd_findbyclass function. Therefore you can easily let the user choose the array you will operate on via an argument to your external.
You can associate your pd external with a symbol using the function
void *pd_bind*(t_pd *x, t_symbol *s)
...where you pass the struct of your external as the "x" argument (you can easily cast it to t_pd). What this means in effect is that you can get a pointer to that structure from another external with the already introduced *pd_findbyclass* function, by passing it as arguments the registered symbol and the *t_class* of the registered external. Again, it is a good idea to let the user choose the registered symbol via an argument of the external.
This effectively means that you can separate the functionality you want to achieve into many externals, so that one allocates memory for some data in its struct and the others will be able to operate on that memory by accesing the struct of the registered external, while the "invisible connections" are made via the symbols that the user gives as arguments to the externals (we can say, by the names that the user assigns to the instances of the externals).
If you have further questions, please ask!
hi Jakob, I appreciate your contribution, but what I'm looking for is a general purpose, so probably I want to do exactly what I ask.
for sure, if I'll need to interface with arrays I'll use your proposed solution number 2, but here I'm developing a meta-external (tclpd, a toolkit for writing externals in Tcl language) so it has to be general purpose.
On Sep 21, 2009, at 5:10 PM, mescalinum@gmail.com wrote:
Jakob Leben wrote:
On Sun, Sep 13, 2009 at 9:01 PM, mescalinum@gmail.com mailto:mescalinum@gmail.com <mescalinum@gmail.com mailto:mescalinum@gmail.com> wrote:
if I were writing an external that is somewhat an interface to arrays (read/write), I have some design choices:
- copy/paste the code of array (g_array.c) (or eventually only
copy [tabread]/[tabwrite]) pros: resulting external is tight & tidy cons: code duplication, possible breakage in future releases
- provide appropriate inlets and outlets, and require the user to
patch the external among [tabread]/[tabwrite] objects pros: modular. is independent from the array implementation. cons: tricky to use, the user can patch it incorrectly and won't work.
- is possible to patch the required objects without phisically
put them in the canvas [?] pros: all pros mentioned in 1) and 2) cons: [?]
obviously, 1) and 2) are ugly under some point of view; what I am interested in is 3), hence asking here if possible, and directions on how to proceed.
I would suggest the following two options. Everything used in the examples is declared in the "m_pd.h" header that you have to include in your external anyway. Basically, I will explain the techniques used by the pd objects that operate on arrays and the delay objects, so this is stuff that will most probably not be broken for numerous future releases, or a very large part of pd should drastically change.
You can get a direct pointer to data stored in a g_array with the following code:
t_symbol *array_name = gensym( "array-named-foo"); t_pd *the_array = *pd_findbyclass*( array_name, garray_class ); int size; t_float *data; *garray_getfloatarray*( (t_garray) the_array, &size, &data );
You have to pass the name of the array as it was set in the pd patch as the "s" argument of pd_findbyclass function. Therefore you can easily let the user choose the array you will operate on via an argument to your external.
You can associate your pd external with a symbol using the function
void *pd_bind*(t_pd *x, t_symbol *s)
...where you pass the struct of your external as the "x" argument (you can easily cast it to t_pd). What this means in effect is that you can get a pointer to that structure from another external with the already introduced *pd_findbyclass* function, by passing it as arguments the registered symbol and the *t_class* of the registered external. Again, it is a good idea to let the user choose the registered symbol via an argument of the external.
This effectively means that you can separate the functionality you want to achieve into many externals, so that one allocates memory for some data in its struct and the others will be able to operate on that memory by accesing the struct of the registered external, while the "invisible connections" are made via the symbols that the user gives as arguments to the externals (we can say, by the names that the user assigns to the instances of the externals).
If you have further questions, please ask!
hi Jakob, I appreciate your contribution, but what I'm looking for is a general purpose, so probably I want to do exactly what I ask.
for sure, if I'll need to interface with arrays I'll use your proposed solution number 2, but here I'm developing a meta-external (tclpd, a toolkit for writing externals in Tcl language) so it has to be general purpose.
What Jakob outlines are the two methods of getting array data when writing an external in C. If you are talking about creating a Tcl API to Pd arrays, I think there should be a Tcl equivalent of those two options. If that's not what you mean, then perhaps you could illustrate the idea more?
.hc
----------------------------------------------------------------------------
There is no way to peace, peace is the way. -A.J. Muste
Hans-Christoph Steiner wrote:
On Sep 21, 2009, at 5:10 PM, mescalinum@gmail.com wrote:
Jakob Leben wrote:
On Sun, Sep 13, 2009 at 9:01 PM, mescalinum@gmail.com mailto:mescalinum@gmail.com <mescalinum@gmail.com mailto:mescalinum@gmail.com> wrote:
if I were writing an external that is somewhat an interface to arrays (read/write), I have some design choices:
- copy/paste the code of array (g_array.c) (or eventually only copy
[tabread]/[tabwrite]) pros: resulting external is tight & tidy cons: code duplication, possible breakage in future releases
- provide appropriate inlets and outlets, and require the user to
patch the external among [tabread]/[tabwrite] objects pros: modular. is independent from the array implementation. cons: tricky to use, the user can patch it incorrectly and won't work.
- is possible to patch the required objects without phisically
put them in the canvas [?] pros: all pros mentioned in 1) and 2) cons: [?]
obviously, 1) and 2) are ugly under some point of view; what I am interested in is 3), hence asking here if possible, and directions on how to proceed.
I would suggest the following two options. Everything used in the examples is declared in the "m_pd.h" header that you have to include in your external anyway. Basically, I will explain the techniques used by the pd objects that operate on arrays and the delay objects, so this is stuff that will most probably not be broken for numerous future releases, or a very large part of pd should drastically change.
You can get a direct pointer to data stored in a g_array with the following code:
t_symbol *array_name = gensym( "array-named-foo"); t_pd *the_array = *pd_findbyclass*( array_name, garray_class ); int size; t_float *data; *garray_getfloatarray*( (t_garray) the_array, &size, &data );
You have to pass the name of the array as it was set in the pd patch as the "s" argument of pd_findbyclass function. Therefore you can easily let the user choose the array you will operate on via an argument to your external.
You can associate your pd external with a symbol using the function
void *pd_bind*(t_pd *x, t_symbol *s)
...where you pass the struct of your external as the "x" argument (you can easily cast it to t_pd). What this means in effect is that you can get a pointer to that structure from another external with the already introduced *pd_findbyclass* function, by passing it as arguments the registered symbol and the *t_class* of the registered external. Again, it is a good idea to let the user choose the registered symbol via an argument of the external.
This effectively means that you can separate the functionality you want to achieve into many externals, so that one allocates memory for some data in its struct and the others will be able to operate on that memory by accesing the struct of the registered external, while the "invisible connections" are made via the symbols that the user gives as arguments to the externals (we can say, by the names that the user assigns to the instances of the externals).
If you have further questions, please ask!
hi Jakob, I appreciate your contribution, but what I'm looking for is a general purpose, so probably I want to do exactly what I ask.
for sure, if I'll need to interface with arrays I'll use your proposed solution number 2, but here I'm developing a meta-external (tclpd, a toolkit for writing externals in Tcl language) so it has to be general purpose.
What Jakob outlines are the two methods of getting array data when writing an external in C. If you are talking about creating a Tcl API to Pd arrays, I think there should be a Tcl equivalent of those two options. If that's not what you mean, then perhaps you could illustrate the idea more?
I don't need specifically to access arrays (tclpd already support what Jakob proposed, using pd_bind).
question was: "is it possible -in the context of writing a pd external class- to invisibly patch some other object and attach to it/bind it?"
and that's what I want to support in tclpd, to avoid code duplication or tricky patching of objects or using abstractions with their reduced functionality (in respect to externals).
if it's not possible, I already have fallback solutions.
On Tue, Sep 22, 2009 at 8:06 PM, mescalinum@gmail.com mescalinum@gmail.comwrote:
question was: "is it possible -in the context of writing a pd external class- to invisibly patch some other object and attach to it/bind it?"
Frankly speaking, I have trouble understanding what the question was. Could you clarify, please? What do you mean by "attach to it/bind it" ?
Is your final goal to offer to a user who wants to write pd externals in tcl the option to create other pd objects and connect them from the tcl code of the external? Or was that only a part of a solution to another problem that could be solved differently?
On Sun, 2009-09-13 at 21:01 +0200, mescalinum@gmail.com wrote:
hi all,
is it possible -in the context of writing a pd external class- to invisibly patch some other object and attach to it/bind it?
I'll try to explain better with an example: if I were writing an external that is somewhat an interface to arrays (read/write), I have some design choices:
- copy/paste the code of array (g_array.c) (or eventually only copy
[tabread]/[tabwrite]) pros: resulting external is tight & tidy cons: code duplication, possible breakage in future releases
- provide appropriate inlets and outlets, and require the user to patch
the external among [tabread]/[tabwrite] objects pros: modular. is independent from the array implementation. cons: tricky to use, the user can patch it incorrectly and won't work.
- is possible to patch the required objects without phisically put them
in the canvas [?] pros: all pros mentioned in 1) and 2) cons: [?]
obviously, 1) and 2) are ugly under some point of view; what I am interested in is 3), hence asking here if possible, and directions on how to proceed.
i cannot give any technical help, but from a strict pd _user_ point of view, i like the 2) approach the most, simply because it is so easy to turn what you want into an abstraction. would there be a reason not to do so?
roman
___________________________________________________________ Der frühe Vogel fängt den Wurm. Hier gelangen Sie zum neuen Yahoo! Mail: http://mail.yahoo.de
Roman Haefeli wrote:
On Sun, 2009-09-13 at 21:01 +0200, mescalinum@gmail.com wrote:
hi all,
is it possible -in the context of writing a pd external class- to invisibly patch some other object and attach to it/bind it?
I'll try to explain better with an example: if I were writing an external that is somewhat an interface to arrays (read/write), I have some design choices:
- copy/paste the code of array (g_array.c) (or eventually only copy
[tabread]/[tabwrite]) pros: resulting external is tight & tidy cons: code duplication, possible breakage in future releases
- provide appropriate inlets and outlets, and require the user to patch
the external among [tabread]/[tabwrite] objects pros: modular. is independent from the array implementation. cons: tricky to use, the user can patch it incorrectly and won't work.
- is possible to patch the required objects without phisically put them
in the canvas [?] pros: all pros mentioned in 1) and 2) cons: [?]
obviously, 1) and 2) are ugly under some point of view; what I am interested in is 3), hence asking here if possible, and directions on how to proceed.
i cannot give any technical help, but from a strict pd _user_ point of view, i like the 2) approach the most, simply because it is so easy to turn what you want into an abstraction. would there be a reason not to do so?
there are things you can't do with abstractions (have variable number of iolets, accepting variable-type arguments, just to name some)
On Sun, Sep 13, 2009 at 9:01 PM, mescalinum@gmail.com mescalinum@gmail.comwrote:
hi all,
is it possible -in the context of writing a pd external class- to invisibly patch some other object and attach to it/bind it?
I guess everybody has missed the point of the second option I gave. Indeed it is an extension to the first, but it doesn't have to do anything with pd's arrays. The point of it is in binding your own externals to pd symbols, thus allowing "yourself" (or themselves) to pass data between them (yes, using the same technique as for accessing g_array data, but that doesn't matter here). So considering that you want to "invisibly patch" something, and that you thought of copying the g_array code - I thought this could be a solution. Instead of doing insivible patch connections between some objects, you access data from one into the other within their own code.
Now, if passing data between *your own* externals is not what you want, but you really truly want to programmatically control patching to other objects, then my proposal is not the solution.
Jakob Leben wrote:
I guess everybody has missed the point of the second option I gave. Indeed it is an extension to the first, but it doesn't have to do anything with pd's arrays. The point of it is in binding your own externals to pd symbols, thus allowing "yourself" (or themselves) to pass data between them (yes, using the same technique as for accessing g_array data, but that doesn't matter here). So considering that you want to "invisibly patch" something, and that you thought of copying the g_array code - I thought this could be a solution. Instead of doing insivible patch connections between some objects, you access data from one into the other within their own code.
yep works well for externals you are writing, or externals that already support this mechanism
Now, if passing data between *your own* externals is not what you want, but you really truly want to programmatically control patching to other objects, then my proposal is not the solution.
you got it
Is your final goal to offer to a user who wants to write pd externals in tcl the option to create other pd objects and connect them from the tcl code of the external?
YES! :)
Or was that only a part of a solution to another problem that could be solved differently?
perhaps. since it's an externals toolkit, that would be just giving the developer one more option (hopefully that would not be the main option, but still an option, to be used when other solutions suck more)