How does the IDE work with plugins?

| | Comments (3)

One may wonder: how does the IDE get all the plugin information out of a compiled plugin? When I install a plugin into my Plugins directory, how does that translate into something the IDE can understand?

Well, the answer isn't magic, but it is complex. ;-) Generally speaking, when you write a plugin, you have to register all the classes, modules, etc within the PluginEntry method. The way that registration works is that it makes a call to REALRegisterClass (or one of the other registration methods). This is what gets the ball rolling. One in the plugin bridge, we can query for all of the plugin information and use it to build things into data structures the IDE can handle. From there, the IDE can treat it like anything else (such as your user code).

The first step of the detailed process is to find all of the plugins the user has installed. So the IDE loops over all the files in the plugins directory and looks for ones which match the plugin format (such as an rbx file). Upon finding something that it thinks might be a plugin, the IDE asks the plugin bridge to try to load it. The plugin bridge attempts to find an exported function called REALPluginMain. This function is exported by the plugin SDK itself, and calls thru to your PluginEntry method. If the bridge can find this export, it then executes it.

Then control jumps to the plugin's PluginEntry function, which starts to register objects. You'll notice that this is a place where bad things can happen. If the plugin author has a bug in their PluginEntry method which causes a crash to happen, then it can take down the entire IDE. Authors should use extreme caution with their PluginEntry method to ensure that it doesn't cause crashes (and the majority won't crash, since they simply call registration functions).

When the plugin goes to register an object (let's say it's registering a class), then that call winds up back in the plugin bridge (by way of the call resolver). So the plugin bridge is handed a REALclassDefinition which describes the class. The plugin bridge then takes this information and parses it into a set of classes that the IDE can grok. So, the REALclassDefinition winds up as something called a PluginClass, which is simply a user-friendly wrapper around the data within the definition. So the PluginClass would have a PropertyCount method, and a GetProperty function, etc.

The bridge will make all of the various wrapper objects for an entire plugin, and it stores them internally on something called a PluginDefinition object. This definition object stores all of the various classes, modules, etc in RB-readable classes so that the IDE can retrieve the information.

After the bridge has finished parsing the entire plugin, control returns back to the IDE (remember, it originally asked the bridge to start this process). So the IDE is given back a PluginDefinition object. It then iterates over all of the data within the definition (which are classes, modules, global methods, etc) and uses it to build up internal data structures which represent REALbasic objects. The ultimate resolution of this is that the data within the plugin ends up in the exact same format as the data in your projects. When you go to make a new class, an RBClass structure is made internally which houses all of your class information. Likewise, when a plugin exposes a class, it ultimately ends up as an RBClass. By processing plugins this way, they gain full access to everything else which already knows how to grok the internal structures (such as autocomplete, and the compiler).

The internal structures contain all of the code items (properties, methods, etc) that the class exposes. The body of these items contain declares which can call back into the individual plugins. So the way the compiler sees a plugin is exactly the same as the way the compiler sees your user code. It's just another RB class (that happens to have been automatically generated for you).

You may be wondering where all of these plugin classes live. For instance, if you install a plugin which exposes the Foobar class, and you search for Foobar, the plugin code isn't displayed in the search results. This is because a project is comprised of multiple documents of data. A Document describes a logical set of project items. So each plugin is its own Document internally, just like how your project is its own Document. So searching functionality goes on a document-by-document basis. When you search your project, it only can see the project items within its Document. But at compile time, multiple documents are sent to the compiler to be used. For instance, the RB framework is a document as well.

How does this affect you as a plugin author?

Keep in mind that at some point(s), your plugin is executing its code while the IDE is running, from within the IDE's memory space. This means that if your plugin has a bug in it, it will bring down the entire IDE. Obviously, any bugs are considered bad, but ones which bring down the IDE are the worst kind. So pay extra special attention to IDE-driven code such as the PluginEntry method.

How does this affect you as a REALbasic user?

If you notice that your IDE crashes on launch, try removing plugins and see if the crash goes away. But aside from that, it really doesn't affect you -- this is just information to take the mystery out of something which would otherwise seem like black magic.

3 Comments

Aaron wrote: "...take the mystery out of something which would otherwise seem like black magic." Or white magic, this depends on the exact plugin.

Seriously, thank you, very interesting.

Russ

Gald you found it interesting!

"and parses it into a set of classes that the IDE can *grok*"

You young'ns and yer fancy smancy compooter jergin'. Good thing I have Dictionary Search installed on Firefox, otherwise the whole article would have been lost on me. Guess I'm just too old.

Now on-topic...thank you Aaron! I've always wondered how plug-ins work in RB. Now I have just enough knowledge to be dangerous... ;)

Leave a comment

Disclaimer

I'm currently an employee of REAL Software. My blog is mine. The opinions represented in this blog are mine as well and may not represent my employer's opinions. All original material is copyrighted and property of the author.

REALbasic® is a registered trademark of REAL Software, Inc. REAL SQL Server™ and Lingua™ are pending trademarks of REAL Software, Inc. All rights reserved.