[Qt-creator] Couple of questions about the design of Qt Creator

Elvis Stansvik elvstone at gmail.com
Sun Sep 10 13:09:58 CEST 2017


2017-09-10 12:06 GMT+02:00 Christian Gagneraud <chgans at gmail.com>:
> On 10 September 2017 at 21:31, Elvis Stansvik <elvstone at gmail.com> wrote:
>> 2017-09-10 11:03 GMT+02:00 Elvis Stansvik <elvstone at gmail.com>:
>>> Hi all,
>>>
>>> In a quest to find inspiration for good Qt application architectures,
>>> I've been looking at the plugin based one you're using in Qt Creator.
>>> It strikes me as a really nice design.
>>>
>>> I've been reading the available docs on it, and dug into the code a
>>> bit. This may be a bit much to ask, but I was wondering if any of you
>>> devs could answer a few questions that popped up? It would be much
>>> appreciated!
>>>
>>> It's really just two questions, about two different topics:
>>>
>>> 1. The Invoker / invoke<...> Thingie:
>>>
>>> You have ExtensionSystem::Invoker and the associated invoke<..>
>>> helper, which are syntactic sugar for achieving "soft" extension
>>> points. It seems it's not used that much (?). I grepped for
>>> "Invoker|invoke<" in the code and could only find a few uses of it. I
>>> also grepped for "invokeMethod" to see if the approach was being used
>>> "manually" so to speak (without the sugar), and found a few more hits.
>>>
>>> What was the motivation for adding this? I assume it's for cases where
>>> you want a looser coupling between plugins (no linking, no shared
>>> header), but can you give an example of when you really wanted that
>>> looser coupling and why?
>>>
>>> 2. The Plugin System in General:
>>>
>>> Is there anything about the plugin system in its current form, or how
>>> it is used, that you would do fundamentally different if you could do
>>> it all over again? Any areas that you find messy/awkward, that need a
>>> re-think/makeover? In short: What are the biggest warts in the code in
>>> your opinion?
>>
>> As soon as I hit send, I realized I have a third question:
>>
>> 3. Communication Between Plugins:
>>
>> There seems to be two main mechanisms through which plugins
>> communicate: Either objects that implement shared interfaces are added
>> to the plugin manager object pool and picked up by downstream or
>> upstream plugins (in the top-down or bottom-up phase of plugin
>> initialization, respectively), or a singleton instance is acquired and
>> calls made on it.
>>
>> Is the former approach used when dependants provide functionality to
>> their dependees (which are unknown), and the latter approach used when
>> dependees use their dependants (which are known)? Is that the deciding
>> factor?
>
> I'm not a Qtc dev, but like you i spent some time studying some of the
> QtC internals, and especially the extension system and the
> document/editor system.
>
> I think the way QtC load and initialise plugins allows for a 2-way
> communication without any ambiguity.
>
> The plugin's initialise() is call in the bottom-to-top order, so when
> your initialise() is called, you know that the plugins you depend upon
> are initialised.
>
> Then comes the extensionsInitialized() call, when this one is called,
> you know for sure that all the plugins that depends on you have had
> their initialise() called.
> So it is a good place, for example, to query the object pool for all
> objects that implements one of your interface and that have been
> registered by your dependees.

Right, the two-phase plugin initialization and object pool is quite
well described in the docs:

    https://doc-snapshots.qt.io/qtcreator-extending/plugin-lifecycle.html

I think my question was a little vague, sorry about that.

Consider an example: Some functionality "foo" is to be added to the
core plugin, and a plugin Bar written to implement that functionality.

Approach 1:

- Add an interface IFoo to the core plugin.
- Bar implements IFoo and add an instance of its implementation to the
pool in its initialize().
- The core plugin get the object from the pool (in its
extensionsInitialized()), and make use of it.

Approach 2:

- Add a singleton Foo to the core plugin.
- Bar carries out its work using direct calls on Foo::instance().

I was just wondering if the second approach is ever used, or if the
mechanism set up by the object pool + two-phase initialization is
always used. If approach 2 is used, I was interested in what the
deciding factor is between the two approaches.

Elvis

>
> My 2 cents.
> Chris
>
>
>>
>> Elvis
>>
>>>
>>> Many thanks in advance,
>>> Elvis
>> _______________________________________________
>> Qt-creator mailing list
>> Qt-creator at qt-project.org
>> http://lists.qt-project.org/mailman/listinfo/qt-creator



More information about the Qt-creator mailing list