When I’m debugging my plugins I typically encounter an error, fix it, move the updated .rb or .rbz file into the current plugin folder and then restart SketchUp and try to duplicate the error again.
Sometimes it will take a few iterations before I get it right. However I’m finding that I spend a lot of time just restarting SketchUp so that it loads the updated plugin files.
Is there a way to reload a plugin without having to keep restarting SketchUp?
I’ve set up SketchUp to load extensions directly from my development folder so i don’t need to create any intermediate RBZ. The script I have in my plugins folder look like this:
pattern = "D:/Sketchup Plugins/Working Dir/*/src/"
Dir.glob(pattern).each do |dir|
$LOAD_PATH << dir
Dir.glob("#{dir}/*.rb").each { |p| require p }
end
This allows each project to have its own folder, corresponding to a Git repo. Each such folder has a src folder corresponding to what will become the RBZ, but also allows additional folders, e.g. for unit tests, 3D models icons are based on etc. I know ThomThom does something similarly, but explicitly lists projects to load rather than iterating all possible projects.
In my main extension file I have this method for simply reloading the extension.
# Reload extension.
#
# @param clear_console [Boolean] Whether console should be cleared.
# @param undo [Boolean] Whether last oration should be undone.
#
# @return [void]
def self.reload(clear_console = true, undo = false)
# Hide warnings for already defined constants.
verbose = $VERBOSE
$VERBOSE = nil
Dir.glob(File.join(PLUGIN_ROOT, "**/*.{rb,rbe}")).each { |f| load(f) }
$VERBOSE = verbose
# Use a timer to make call to method itself register to console.
# Otherwise the user cannot use up arrow to repeat command.
UI.start_timer(0) { SKETCHUP_CONSOLE.clear } if clear_console
Sketchup.undo if undo
nil
end
After having called this once I just press Arrow Up and Enter in the console a bunch of times while testing.
Keep your plugins folder as empty as possible on your development machine so that there is no interference from other plugins
There is a startup argument for SketchUp that lets you launch sketchup auto-loading a .rb file. You can use that to auto load your extension even if it isn’t located in the plugins folder. In my development folder I have a .bat to launch SketchUp with the following content:
This .bat tries to launch SketchUp with a .rb file named launch.rb located in the same folder as the .bat file. The contents of launch.rb is:
require "sketchup"
timer_id = UI.start_timer(0, false) {
# always show the console
SKETCHUP_CONSOLE.show
# stop the timer
UI.stop_timer(timer_id)
src_folder = "#{File.dirname(__FILE__)}/src_extension/"
extension_files = Dir[src_folder + "*.rb"]
extension_files.each do |f|
extension_name = File.basename( f, ".*" )
extension_folder = "#{src_folder}#{extension_name}"
$LOAD_PATH << extension_folder
require f
end #do
}
You will notice that I do the real loading of the extension in a timer and that the real extension is located in ./src_extension/ which in return contains the extension as you would place it in the plugins folder.
I use a timer because I believe that errors that occur during the initial loading of Sketchup are not outputted to the console.
Why?
As mentioned, only the extension I am working on is loaded so there is no interference or time lost loading unneeded extensions.
you can also specify a .skp that has to be loaded, so you do not lose time specifying and searching for your test file over and over again.
I do not launch the .bat myself, but launch it from my IDE (visual studio code) in a task. Have a look at my task.json file:
{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "2.0.0",
"tasks": [
{
"label": "launch_SU19",
"type": "shell",
"command": "open -a SketchUp --args -RubyStartup \"$PWD/launch.rb\"",
"windows": {
"command": "./launch_SU19.bat"
},
"problemMatcher": []
}
]
}
as you see, I also have a MAC to develop and test on osx. The .bat will not work on osx, therefore this command on osx: open -a SketchUp --args -RubyStartup \"$PWD/launch.rb\"
Yup, same as mentioned above: use a loader script in your Plugins directory to set up additional directories to load extensions directly from your source.
The Examples/Tutorials repo have a brief example of this: