Extension Warehouse - set limit for number of startup files

There seems to be many extensions/plugins that load all their files when SU starts up.

This is crazy. I’m sure there are many extensions (including native SU extensions) that users aren’t running every time they use SU.

Many extensions could load most of their files on an ‘as needed’ basis, as they aren’t needed until the user interacts with a menu, toolbar, or context menu.

Thoughts? Obviously there is a trade-off, as ‘loading on demand’ will slow up the session ‘first use’ of a plugin, but SU boot time may improve and it will lower the resources Ruby consumes.

Note that require statements can be guarded with defined? or const_defined?, which saves a search of $LOADED_FEATURES

Right … Lazy loading. We’ve discussed this here in the past.

Currently this is the responsibility of each extension developer.

(1) Are you perhaps brainstorming some automated way that newbs could easily understand ?

(2) I thought there was a way in Ruby to load modules “on access” … is there still and can it be used within an embedded environment like SketchUp ?

Yes, because sketchup.rb loads langhadler.rb, I’ve often suggested …

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

… for all the extension registrar files in the “Plugins” folder.
This should cut way down on searches through the $LOADED_FEATURES array during the startup cycle.

EDIT: These require statements are actually not needed at runtime as SketchUp has alreeady loaded them before it even begins loading any extensions. They might be needed in an IDE if API stubs must be loaded.

I guess that I am referring to Kernel#autoload().

The drawback is that it uses Kernel#require which would not work for .rbe encrypted files.

So, either the API would need to implement a Sketchup::autoload() equivalent that can use Sketchup::require or override the global Kernel#autoload() to redirect .rbe files to load with Sketchup::require.

If the Extension Warehouse enforced a maximum limit, there wouldn’t be an issue.

Right … Lazy loading. We’ve discussed this here in the past.

Yes, I know I’ve brought it up. A common concept in coding is “Don’t waste resources”, and if people have several extensions installed, they could be loading hundreds of files on startup.

As to autoload, it would be very nice if it worked, and it might, but I’ve never tried.

Also, I’ve asked for a Sketchup.require_relative, which would also help. One can pass a full path to Sketchup.require, but that just clutters the code. require_relative is used in a lot of Ruby code, as it bypasses the RubyGems code.

It’s crazy to boot SU and find hundreds of files in $LOADED_FEATURES.

JFYI, when using code involving threads, loading files in any way can get messy. It may be fixed in recent Ruby versions, not sure.

The following pattern seems to work:

Lazy Load a Command
# File: "main.rb"
# The main file loaded for an extension.
module SomeAuthor
  module SomeNiftyExtension

    extend self

    # Lazy loader.
    def lazy_load(files)
      files.each do |file|
        Sketchup.require( File.join(__dir__, file) )
      end
    end

    # Initially a method that only loads the files that support it.
    def nifty_command
      # One of these files will redefine THIS method:
      lazy_load(['nifty_support', 'nifty_command'])
      # Call the newly redefined edition of this method:
      nifty_command()
    end
    
    if !defined?(@gui_loaded)
      cmd = UI::Command.new('Nifty Command') { nifty_command() }
      cmd.tooltip= cmd.status_bar_text= cmd.menu_text
      menu = UI.menu('Plugins').add_item(cmd)
      @gui_loaded = true
    end

  end
end
# File: "nifty_command.rb"
# Redefines method nifty_command().
module SomeAuthor
  module SomeNiftyExtension

    def nifty_command
      # Actual command code:
      nifty_message()
    end

  end
end
# File: "nifty_support.rb"
# Supports method nifty_command().
module SomeAuthor
  module SomeNiftyExtension

    def nifty_message
      UI.messagebox("Nifty Command has been loaded.")
    end

  end
end

Here is a test extension archive:

ADD: Well lazy loading is likely to increase the number of entries in $", but after the startup cycle.

I have one extension that’s been in ‘public’ use for at least a dozen years. I don’t remember much of the code in it, and much of it is still rather odd Ruby code, as I was mostly coding with C# and JS when I wrote it. I’ve updated it two or three times, one was a change from WebDialog to HtmlDialog.

Anyway, using const_missing and a hash of object names/file names, I implemented an autoload equivalent for the main classes in the extension.

So, it’s possible to centralize file loading and also ‘lazy loading’.

1 Like

Not sure what you mean. If lazy loading was used, the upper limit of $LOADED_FEATURES’s length would equal what we’re seeing now without lazy loading.

For many users, it might be considerably less, since they probably don’t use all the functionality of every extension they have loaded in every SU session.