On Fri, Dec 02, 2005 at 02:43:54PM -0800, thockin@xxxxxxxxxx wrote: > Anyone have opinions? This is one of those fundamental design choices > that can set precedent for other aspects of the API... How about soemthing like this? (pseudo-code) (discussion below) /* * A plugin is essentially a tree of elements. You can inspect the tree, * one group at a time. */ enum GMPI_ElementType { GMPI_ELEM_AUDIO, GMPI_ELEM_CONTROL, GMPI_ELEM_GROUP } /* an element is a single piece of a plugin */ GMPI_Element { GMPI_ElementType type; uint32_t key; char* name; } GMPI_Plugin { ... Inspect(uint32_t group, int index, GMPI_Element* element); GetAudioIO(uint32_t key, GMPI_Unknown* unknown); GetControlIO(uint32_t key, GMPI_Unknown* unknown); ... } GMPI_AudioIO { ... GetDirection(void); GetChannels(void); GetEncoding(void); ... } GMPI_ControlIO { ... GetType(void); GetDirection(void); ... } GMPI_FloatControl { ... GetType(void); GetDirection(void); GetMin(void); GetMax(void); GetDefault(void); ... } GMPI_IntControl { ... GetType(void); GetDirection(void); GetMin(void); GetMax(void); GetDefault(void); ... } host internals: -------- main loop { ... Find and load a plugin InspectGroup(plugin, GMPI_GROUP_ROOT); ... } InspectGroup(GMPI_Plugin* plugin, uint32_t group) { GMPI_Element element; int index = 0; while (plugin->Inspect(group, index, &element) == GMPI_SUCCESS) { if (element.type == GMPI_ELEM_GROUP) { /* recurse into a sub-group */ InspectGroup(plugin, element.key); } /* * we found an element - save it's object */ if (element.type == GMPI_ELEM_AUDIO) { /* * An audio IO */ GMPI_Unknown* unknown; GMPI_AudioIO* audio; plugin->GetAudioIO(key, &unknown); unknown->QueryInterface(IID_AUDIO_IO, &audio); SaveAudio(plugin, audio, element); } else if (element.type == GMPI_ELEM_CONTROL) { /* * Some sort of control - but what kind? */ GMPI_Unknown* unknown; GMPI_Control* control; plugin->GetControlIO(key, &unknown); unknown->QueryInterface(IID_CONTROL_IO, &control); switch (control->Type()) { case GMPI_CONTROL_FLOAT: { /* * a float control */ GMPI_FloatControl* floatControl; control->QueryInterface(IID_FLOAT_CONTROL, &floatControl); SaveControl(plugin, floatControl, element); break; } case GMPI_CONTROL_INT: { /* * an int control */ GMPI_IntControl* intControl; control->QueryInterface(IID_INT_CONTROL, &intControl); SaveControl(plugin, intControl, element); break; } } } index++; } } Essentially, the host walks the plugin's tree of elements, figuring out what they are along the way, and getting handles to them. For controls, it can specialize down to a type-specific interface. This results in a unique interface class for each type of control. Each interface has a number of small data-query methods. Because we agreed that *all* methods return GMPI_Result and take pointers to out parameters, these are not quite as simple as I have illustrated. I'd like to argue that sometimes it is ok to just return a value. For example, if QueryInterface returned a void*, then catcher could implicitly convert types instead of needing reinterpret_cast<>. This is just one model. It makes sense to me, but it is pretty highly normalized. I'm open to ideas. > On Tue, Nov 29, 2005 at 04:28:34PM -0800, thockin@xxxxxxxxxx wrote: > > We've got very basic plugins that can be found and loaded. > > > > Now how do we find out what they do? The host has to figure out all the > > control inputs, control outputs, audio inputs, audio outputs, etc. There > > are a lot of potential models, I'd like to hear some reasons to go with > > one or the other or something totally different. > > > > Remember that we need to be able to extract a lot of data: > > * control ports > > - name > > - data type > > - range > > - flags > > * audio ports > > - name > > - format > > - channels > > * nested sub-groups of the above > > * channels > > * ..and more > > > > Some ideas I've already heard: > > > > 1) Host loops from 0 to n, asking the plugin for metadata about "thing x". > > The metadata explains what each thing is. > > > > 2) Host asks for structure and gets back an XML blob that represents > > everything. > > > > What else? What makes the most sense? What will be easy to program and > > easy to expand? > > > > Tim > > > > ---------------------------------------------------------------------- > > Generalized Music Plugin Interface (GMPI) public discussion list > > Participation in this list is contingent upon your abiding by the > > following rules: Please stay on topic. You are responsible for your own > > words. Please respect your fellow subscribers. Please do not > > redistribute anyone else's words without their permission. > > > > Archive: //www.freelists.org/archives/gmpi > > Email gmpi-request@xxxxxxxxxxxxx w/ subject "unsubscribe" to unsubscribe > > > > -- > Tim Hockin > thockin@xxxxxxxxxx > Soon anyone who's not on the World Wide Web will qualify for a government > subsidy for the home-pageless. > > ---------------------------------------------------------------------- > Generalized Music Plugin Interface (GMPI) public discussion list > Participation in this list is contingent upon your abiding by the > following rules: Please stay on topic. You are responsible for your own > words. Please respect your fellow subscribers. Please do not > redistribute anyone else's words without their permission. > > Archive: //www.freelists.org/archives/gmpi > Email gmpi-request@xxxxxxxxxxxxx w/ subject "unsubscribe" to unsubscribe > -- Tim Hockin thockin@xxxxxxxxxx Soon anyone who's not on the World Wide Web will qualify for a government subsidy for the home-pageless. ---------------------------------------------------------------------- Generalized Music Plugin Interface (GMPI) public discussion list Participation in this list is contingent upon your abiding by the following rules: Please stay on topic. You are responsible for your own words. Please respect your fellow subscribers. Please do not redistribute anyone else's words without their permission. Archive: //www.freelists.org/archives/gmpi Email gmpi-request@xxxxxxxxxxxxx w/ subject "unsubscribe" to unsubscribe