On Wed, 2004-01-07 at 17:21, Bryce Harrington wrote:
I'm tempted to think, though, that we don't need to have this idea show up at the namespace layer. It sort of sounds like you're going to want to have a root class with subclasses for each type of implementational interface, and that is probably best done in a uniform namespace.
So I think for the purposes of namespaces and the extension architecture perhaps we should just have everything live in Inkscape::Extension. The idea could be that you'd create a root class within this namespace named Extension, for instance, that establishes the common API that all of the different kinds of extensions would need to implement. Then you'd create a subclass of Extension for each different specialized kind of extension, with added interfaces unique to them, and then developers of plugins would subclass from there, as appropriate.
Yeah, that's what I was thinking - but only for the interface into the Inkscape core. So something like this (capitalized this time ;)
Inkscape::Extension::Extension (virtual class) Inkscape::Extension::Input (inherit from Extension) Inkscape::Extension::Output (inherit from Extension) Inkscape::Extension::Filter (inherit from Extension) Inkscape::Extension::Print (inherit from Extension)
So these would be functionality based in this name space.
Then in the other namespace we'd have the implementations - which could very well be in the Extension namespace, but I'm just worried about them getting crowded.
One thing we may need to consider is whether we need a way for the extension to publish its own API, versus if we can enforce all extensions of a given type to have exactly the same API. If we need an API publishing mechanism, I doubt we'd need anything as elaborate as CORBA or COM; it could simply expose a vtable as a hashmap of function pointers for its internal routines. Where this might turn up handy is if we want to allow extensions to be accessed from other extensions or scripts, to perform specialized activity. For example, I could imagine once a MathML extension exists, someone might put together a "solver" extension that manipulates the MathML extension to solve for particular variables.
I'd love to have extensions that publish their own functional interfaces, but I think we're a ways off of that. I think that we're also going to have issues of how to inform other people of that interface without reimplementing a runtime linker. I think this becomes even more difficult when it starts going cross-language (which makes alot of sense as you'd want the solver is something low level while the MathML could be in something higher level).
Here's a rough idea for doing this. On Inkscape startup, the extension.xml file is loaded, to identify (potentially) registered extensions. When an extension first gains a reference we attempt to load it, erroring if it doesn't exist. The load process works as follows. First, the .so or .dll is loaded into memory. We run an identification routine to learn the plugin's information such as its name, version number, and type. This lets us update extension.xml and cast the Extension into the appropriate subclass. Now we know that we can use the routines in that subclasses' API.
A couple of things, I'd really like to avoid loading the libraries or running the scripts before they are used. I think this will keep us with a siginificantly lower foot print and a much faster startup time. I like the idea of having descriptive XML files for the extensions that could also describe their API. When someone links to it, or uses it, then the library gets loaded.
I don't believe that C++ allows us to do runtime definition of subclasses, which is what this would require to use the C++ compiler to help us. So then, I think we're stuck with giving each function a name, and have a handler for that string and some parameters. Seems like kinda a hack, and as complex as CORBA is, I'm ready to choose that over string handling for function calls.
Now, of course, if we wish to put off inter-extension invokations, then we can leave out this publishing mechanism, but I suspect we'll find this to be a major limitation quickly. An advantage of providing this publishing mechanism is that we won't need to rev the general extension API's very often, which will save major maintenance hassle.
I think that we should support loading of API's and other modules using them - but it is a thorny subject.
Anyway, that's my off the cuff thinking. Should be useful as food for thought if nothing else. Might be useful to research how other drawing apps do this, to see if we can just borrow a design.
http://sourceforge.net/mailarchive/message.php?msg_id=2057634
Here's some research on other programs that I did, well over a year ago now. But I think it's an interesting start.
--Ted