On Sun, Aug 28, 2011 at 1:26 PM, Mathieu Bouchard matju@artengine.cawrote:
On Sun, 28 Aug 2011, Peter Brinkmann wrote:
Can you bypass many of the functions in libpd and use m_pd.h directly?
Sure, but then again maybe m_pd.h is pointless because you can just hack your binaries with a hex editor. That doesn't mean that that's a good level of abstraction to work at. libpd aims to provide a high-level API at a consistent level of abstraction, and I believe that that's the correct level of abstraction for the kind of work that libpd is intended for.
Well, for the libpd message-passing, I felt like it added an API at the same level of abstraction as <m_pd.h>, except a tiny bit slower than SETFLOAT and SETSYMBOL macros, and which needed a bit more thread-safety than <m_pd.h>, as even the construction of the message has to be protected. Those are really small details, and to me, the biggie is that this API is not any easier than <m_pd.h>'s message passing to a C programmer.
Matter of taste, I suppose. When working with libpd, I want to think in terms of calls to libpd. Reaching into m_pd.h is a context switch that I'd rather avoid, and with the latest revision of libpd I can avoid it altogether. And I do think that saying "libpd_get_symbol(a)" is simpler than saying "a.a_w.w_symbol->s_name" (although the former is just a macro that maps to the latter).
Then again, my instincts run libertarian. I have no desire to tell you how to do your work. When you include z_libpd.h, you get m_pd.h with it. If you want to work too hard, I won't stand in your way;)
The immediate motivation was to create an API that would be easy to wrap
for languages like Java and Python, but I also have deeper reasons for wanting to work at this level of abstraction.
I don't see any practical difference in easiness of wrapping for other languages. I don't know how you see that.
One major simplification is the use of built-in data types vs custom structs and unions. Many of the functions that you find pointless basically do two things; they convert const char* to t_symbol and then delegate to functions in m_pd.h. With this transition to built-in data types, you can simply run SWIG on the header file and automatically create bindings for a significant part of libpd for lots of target languages; only the callbacks will require some additional work. Without this conversion, you would have to descend into the netherworld of custom typemaps and such.
I'm hoping that we'll see a major redesign of Pd in the not too distant
future. One goal we talked about at PdCon is to allow multiple instances of Pd.
I don't see any planning about this in the way that the libpd api works, and
I don't see how the libpd api currently helps for that.
It doesn't. The point is that it would be easy to extend because you'd just need to add an instance pointer to the parameter list of a smallish collection of functions.
Incidentally, I've also gotten flak for not baking any multi-instance support into the initial version of libpd (I did consider it, but it seemed pointless because with the current version of Pd it would still have just one single instance). I figure that as long as I'm drawing fire from both low-level C hackers and high-level OOP types, I must be doing something right;)
Another change I'm hoping to see is a rewrite that takes advantage of
multiple cores on current machines.
What's a «rewrite», and how much actual change do you wish for ? Do you have a plan for actual changes to the API ?
It's more of a general consideration, and I don't have any road map in mind. Right now I'm just hoping to have a conversation about this.
I also believe that such changes will be necessary to remain competitive.
If anyone really needs a big speed hike, then how about integrating SSE support in vanilla and/or libpd ? The prototype was made in 2005 or so, and then abandoned. That's a lot easier to do than to support double/triple/quad CPUs.
I'd be more than happy to see that, ideally in vanilla because I want libpd to remain nothing more than a thin wrapper on top of Pd.
The libpd API is meant to be (mostly) above such implementation details,
while the low-level API will almost certainly change when Pd is updated. Pd itself will be much more nimble and maintainable if developers think about it at a higher level of abstraction.
What constitutes a higher level of abstraction ?
In this case, I mostly mean hiding implementation details. For example, as an application programmer I don't want to know what exactly is going on inside an instance of t_atom, I just want to get string or float values in and out. Cheers, Peter