There has been some discussion about what to name the things that add functionality to Inkscape, but are not part of the core. I've always called these modules, while there was discussion on this before - it seems that it is time to change the name. I don't really care what we call stuff, I just want everyone to use the same terms. Here's what I'm proposing:
extension --- a chunk of functionality that extends the functionality of Inkscape, but is not part of the core code.
script --- an extension that is built using STDIO to pass SVG data and change it in some way.
extension system --- The code that deals with all of the glue between extensions and the core.
Complaints? Comments? Additions? Ideas?
--Ted
On 3 Jan 2004, Ted Gould wrote:
There has been some discussion about what to name the things that add functionality to Inkscape, but are not part of the core. I've always called these modules, while there was discussion on this before - it seems that it is time to change the name. I don't really care what we call stuff, I just want everyone to use the same terms. Here's what I'm proposing:
extension --- a chunk of functionality that extends the functionality of Inkscape, but is not part of the core code.
script --- an extension that is built using STDIO to pass SVG data and change it in some way.
extension system --- The code that deals with all of the glue between extensions and the core.
Complaints? Comments? Additions? Ideas?
This sounds good to me. Mental and I had discussed this when I wrote the namespaces proposal, and also chose 'extension'. We also considered 'plugin'. (See SubsystemRearchitecture)
We had briefly toyed with the idea of dividing out the Inkscape::Extension namespace according to different types of extensions, but decided to leave that 'til later since it was beyond the scope of what we were doing. We were also uncertain if sub-namespaces were even necessary. You might want to give some thought to it, though. We identified a few things that could be covered by this namespace: import/export mechanisms, GUI plugins, stdin/stdout programs, language bindings, etc.
Bryce
On Sat, 2004-01-03 at 16:19, Bryce Harrington wrote:
We had briefly toyed with the idea of dividing out the Inkscape::Extension namespace according to different types of extensions, but decided to leave that 'til later since it was beyond the scope of what we were doing. We were also uncertain if sub-namespaces were even necessary. You might want to give some thought to it, though. We identified a few things that could be covered by this namespace: import/export mechanisms, GUI plugins, stdin/stdout programs, language bindings, etc.
Here's what I'm working on converting to:
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)
Inkscape::Extension::Implementation::implementation Inkscape::Extension::Implementation::script (inherit from implementation)
Then, internal modules just need to create a class inheriting from implementation for what they want to do, and then all the other functions will work happily. So then the SVG stuff will create the class
Inkscape::Extension::Implementation::svg (inherit from implementation)
And the gnome-print stuff will create
Inkscape::Extension::Implementation::gnomeprint (inherit from implementation)
And each of these will implement the functions that they are interested in for their functionality. Those will get overloaded, and the others will work as stubs. I thought about breaking out the implementation stuff into input/output/filter/print also, but I thought the the overloading worked as well, and was less work to code. Plus it makes it easier to add additional types of modules (like file selector).
--Ted
On Sun, 2004-01-04 at 11:42, Ted Gould wrote:
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)
Inkscape::Extension::Implementation::implementation Inkscape::Extension::Implementation::script (inherit from implementation)
Looks good... only, the C++ coding standards we're converging on dictate capitalizing class names...
-mental
On 3 Jan 2004, Ted Gould wrote:
There has been some discussion about what to name the things that add functionality to Inkscape, but are not part of the core. I've always called these modules, while there was discussion on this before - it seems that it is time to change the name. I don't really care what we call stuff, I just want everyone to use the same terms. Here's what I'm proposing:
extension --- a chunk of functionality that extends the functionality of Inkscape, but is not part of the core code.
script --- an extension that is built using STDIO to pass SVG data and change it in some way.
Added note - we've been calling these 'filters' since that's what they are, but unfortunately we can't use that term because 'filter' has a specific and completely unrelated meaning in SVG. 'script' is better, although note that these kind of tools could also be written in compiled languages, so maybe there's a better term?
extension system --- The code that deals with all of the glue between extensions and the core.
Complaints? Comments? Additions? Ideas?
--Ted
On Sat, 2004-01-03 at 16:24, Bryce Harrington wrote:
Added note - we've been calling these 'filters' since that's what they are, but unfortunately we can't use that term because 'filter' has a specific and completely unrelated meaning in SVG. 'script' is better, although note that these kind of tools could also be written in compiled languages, so maybe there's a better term?
I was thinking that script would refer to the implementation and filter would be refering to what role it plays in the application. So a filter would be like drop shadow, but something that uses the ill2svg.pl file would be a script also.
I agree that we need to change the term filter, atleast in the menu if nothing else. How about "Effect"?
--Ted
On 4 Jan 2004, Ted Gould wrote:
On Sat, 2004-01-03 at 16:24, Bryce Harrington wrote:
Added note - we've been calling these 'filters' since that's what they are, but unfortunately we can't use that term because 'filter' has a specific and completely unrelated meaning in SVG. 'script' is better, although note that these kind of tools could also be written in compiled languages, so maybe there's a better term?
I was thinking that script would refer to the implementation and filter would be refering to what role it plays in the application. So a filter would be like drop shadow, but something that uses the ill2svg.pl file would be a script also.
Can you explain about distinguishing between implementation and role? Is this like a class/instance type relationship or something else? I'm wondering if it would be conceptually simpler if this dualism could be handled in a different fashion than at the namespace level.
I agree that we need to change the term filter, atleast in the menu if nothing else. How about "Effect"?
That'd probably be better. 'Transformation' also comes to mind, although 'Effect' may be more user-friendly (and shorter.)
Bryce
On Sun, 2004-01-04 at 12:50, Bryce Harrington wrote:
Can you explain about distinguishing between implementation and role? Is this like a class/instance type relationship or something else? I'm wondering if it would be conceptually simpler if this dualism could be handled in a different fashion than at the namespace level.
It's mostly to make things simpler in my mind (and hopefully others using the code). I'm looking at that there will be several types of implementations (scripts, internal, other languages (python, perl...)) and all of those will require some code and configuration to get them to work. I wanted to put those two things into their own little block and that desire is what implemenations came out of.
What it does for the user (user of code, not end user) is that they get a clear choice of what to look at for what they want to do. If they want to use extensions within the program, they only need to look at the extensions interface. If they want to build their own extension, all they need to look at is the implemenations interface.
So, in a nutshell, yes, it isn't a required seperation to make things work - but I think it does make things simpler for the users of the code (which hopefully there will be alot of) and it makes the object definitions a little bit cleaner for everything.
I'm open to other ideas though... this is just the one I thought of.
--Ted
On 5 Jan 2004, Ted Gould wrote:
On Sun, 2004-01-04 at 12:50, Bryce Harrington wrote:
Can you explain about distinguishing between implementation and role? Is this like a class/instance type relationship or something else? I'm wondering if it would be conceptually simpler if this dualism could be handled in a different fashion than at the namespace level.
It's mostly to make things simpler in my mind (and hopefully others using the code). I'm looking at that there will be several types of implementations (scripts, internal, other languages (python, perl...)) and all of those will require some code and configuration to get them to work. I wanted to put those two things into their own little block and that desire is what implemenations came out of.
What it does for the user (user of code, not end user) is that they get a clear choice of what to look at for what they want to do. If they want to use extensions within the program, they only need to look at the extensions interface. If they want to build their own extension, all they need to look at is the implemenations interface.
So, in a nutshell, yes, it isn't a required seperation to make things work - but I think it does make things simpler for the users of the code (which hopefully there will be alot of) and it makes the object definitions a little bit cleaner for everything.
I'm open to other ideas though... this is just the one I thought of.
Ah... I think I think I sort of understand now. Feels like the seed of a good idea.
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.
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.
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.
Next, we run a registration routine, which lets the extension "publish" its API to Inkscape core. It does this by returning the metadata for each function, identifying its identification/name, calling parameters, return type, and a pointer to the function itself. Probably this will need to be done as an array of structs rather than a hashmap of objects, since we'll be limited by the dynamic linker.
Inkscape core takes this data structure and loads it into its internal extension registry, which would be implemented as a hashmap of id's to the routine itself.
So then in memory you'd end up with a data structure containing all of registered extensions; the loaded ones would have Extension objects attached, while the non-loaded ones would be NULL and loaded on demand. Each Extension object would have both the generic Extension API, plus (if converted into its correct subclass) its unique API if any. The Extension object would also hold another data structure of its "self-published" API, as id->routine mappings, that can be used by other extensions to communicate between themselves. We will need a way to provide arbitrary parameters and type checking for the routines, so that'll require some thought (perhaps via printf-like varargs, or else just pass all the params in as an void* array of (name,type,value) triplets).
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.
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.
Bryce
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
participants (3)
-
Bryce Harrington
-
MenTaLguY
-
Ted Gould