Is there a predictable order in which plugins are loaded?

I am preparing to submit a few plugins to SU for review. Together the plugins are part of one ecosystem, but each one will have specific functionality. There is one base level plugin on which the others rely on that (ideally) should be loaded to Sketchup first.

Is there a predictable order in which the plugins that are installed by a user are loaded to Sketchup?

Thanks!

Hi Karen.

:woman_superhero:

Generally, they load in alphabetical order of the name of the registrar files in the "Plugins" folder.

But there are some Mac releases in which the load order was random. I’m not sure if this has been fixed or in what version. (Check API release notes.)

Well, then I would suggest placing a require call for this “library’s” extension registrar file at the top of each of the dependent registrar files, using a conditional modifier.

For example I often use something like:

require 'sketchup' unless defined?(LanguageHandler)
require 'extensions' unless defined?(SketchupExtension)

The "sketchup.rb" file loads "langhandler.rb" which defines the LanguageHandler class, so it can be used as the conditional test. Simialr thing for the "extensions.rb" file as it defines the SketchupExtension class.

The conditional tests in modifier position prevent the unnecessary repeated large string matching iterations through the $LOADED_FEATURES (aka $") array.

So since you know what the common resource’s module identifier will be, you can require it before the dependent extension loads …

# At the top of the registrar file for SuperGirl's NiftyTool

require 'SuperGirl_CoreLib' unless defined?(SuperGirl::CoreLib)

But take care that each dependent extensions checks to be sure that users have not switched off the core library.
Otherwise, there will be NameError exceptions raised whenever the non-loaded Ruby objects are referenced.

Thanks Dan. With your solution, would you need to have copies of the library files included with each tool, or is there a way to determine the directory of the library so that there is only one copy of the library? This would be easy if all plugins are installed in the same directory, but my understanding is that it’s not a requirement.

One other idea I had is to have the parent tool load all files only when the user clicks a “load plugin” button from within Sketchup. The way this is accomplished is that when Sketchup starts, each tool registers itself with the parent tool and provides the path to the directory where it’s files are located. Any thoughts on this approach? I tested it - and it works well, but I’m not sure if the SU team will have security concerns about this approach.

Thank you!

Karen

You can if you choose, but then each time you update or fix the library you will need to republish each extension.

The choice is yours.

You do not need to determine the directory if it is packaged as an extension with it’s subdirectory in the "Plugins" directory. SketchUp pushes the path to it’s "Plugins" directories into the %LOAD_PATH (aka $:) array, which is used by the require() and Sketchup::require methods.

ThomThom’s TT_Lib is like this.

You will need to make it plain to consumers that they also need to install the library.
Despite your best efforts there will always be those users who do not read stuff and will try to use the extension without installing the library. There will then be some overhead here in responding to bogus bug reports and complaints that the extension will not work.

This already exists in the Extension Manager.

But what I think you refer to is called lazy loading. This is done usually by checking a state variable the first time one of the extensions commands is accessed. If the supporting code is not loaded, then it is loaded at the time of first use.

It’s not a “load plugin” button. Each one of the extension UI::Command objects would call a load check method before doing it’s task.

Sketchup.extensions.each { |ext| puts "#{ext.name.ljust 30} #{ext.extension_path}" }

If one is following standard conventions, the folder with each extension’s files should be the same as the extension_path, less the file extension…

require can take a full file path. Using $LOAD_PATH will also work, but isn’t needed if you know the file’s location.