This allows to require files without specifying the path.
I was wondering whether this is actually a good idea. If two authors create a file with the same name, then only the first file would be loaded from require and this is not necessarily the right one. Am I understanding it correctly?
I was thinking to a way to make the plugin independent from the main plugin file in the Plugin folder and I thought that the following approach should work. I first define three constants:
I would then replace all the requires in my code with
require File.join(PLUGIN_PATH, 'file_required')
In this way, if I want to change the plugin name (and I need to do that in the future) I can simply change the main rb file and the corresponding folder name
Is this the recommended approach?
Corollary question about require: would it make sense to put all the requires in the loader file within the respective plugin folder?
IMHO, too many plugins overload Ruby with occasional use methodsā¦
To ensure none get loaded before the user actually wants to use them,
I tend to use the menu file to load the āloadersā needed for my pluginsā¦
it will add the menu items, toolbars and occasionally relevant observers, then only when called, they load the required logicā¦
command1 = UI::Command.new("Add This Now"){
load( File.join(File.dirname(__FILE__), "Add_This_Now_logic.rb"))}
Yes, this is how most of us do it. Also some of this path creation has been built into the SketchupExtension class (in later versions.)
Read āTools/extensions.rbā
I am trying to use this technique with my plugin but the problem is that after the menu item runs once it will not fire again.
Here is a snippet of the Medeek_Load.rb file :
module Medeek_Engineering_Inc_Extensions
module MedeekTrussPluginModuleLoader
# Show the Ruby Console at startup so we can
# see any programming errors we may make.
# SKETCHUP_CONSOLE.show
# First we pull in the standard API hooks.
this_dir=File.dirname(__FILE__)
# Fix for ruby 2.0
if this_dir.respond_to?(:force_encoding)
this_dir=this_dir.dup.force_encoding("UTF-8")
end
PATH=this_dir
entries=Dir.entries(this_dir)
ext=".rbs"
# Add a toolbar item to launch our plugin.
toolbar = UI::Toolbar.new "Medeek Truss"
cmd = UI::Command.new("Draw Roof Truss") {
Sketchup.load(File.join(this_dir,"MEDEEK_ROOF_TRUSS.rbs"))
}
cmd.small_icon = "images/mdkplg_tool_icon16_2.png"
cmd.large_icon = "images/mdkplg_tool_icon24_2.png"
cmd.tooltip = "Medeek Truss"
cmd.status_bar_text = "Draw Roof Truss"
cmd.menu_text = "Roof Truss"
toolbar = toolbar.add_item cmd
# toolbar.show
cmd2 = UI::Command.new("Draw Floor Truss") {
Sketchup.load(File.join(this_dir,"MEDEEK_FLOOR_TRUSS.rbs"))
}
cmd2.small_icon = "images/mdkplg_tool_icon16_3.png"
cmd2.large_icon = "images/mdkplg_tool_icon24_3.png"
cmd2.tooltip = "Medeek Truss"
cmd2.status_bar_text = "Draw Floor Truss"
cmd2.menu_text = "Floor Truss"
toolbar = toolbar.add_item cmd2
# toolbar.show
cmd3 = UI::Command.new("Draw Truss Set") {
Sketchup.load(File.join(this_dir,"MEDEEK_TRUSS_SET.rbs"))
}
cmd3.small_icon = "images/mdkplg_tool_icon16_4.png"
cmd3.large_icon = "images/mdkplg_tool_icon24_4.png"
cmd3.tooltip = "Medeek Truss"
cmd3.status_bar_text = "Draw Truss Set"
cmd3.menu_text = "Truss Set"
toolbar = toolbar.add_item cmd3
toolbar.show
cmd4 = UI::Command.new("Draw Roof Rafters") {
Sketchup.load(File.join(this_dir,"MEDEEK_ROOF_RAFTERS.rbs"))
}
cmd4.small_icon = "images/mdkplg_tool_icon16_5.png"
cmd4.large_icon = "images/mdkplg_tool_icon24_5.png"
cmd4.tooltip = "Medeek Truss"
cmd4.status_bar_text = "Draw Roof Rafters"
cmd4.menu_text = "Roof Rafters"
toolbar = toolbar.add_item cmd4
toolbar.show
# Add a menu item to launch our plugin.
submenu = UI.menu("Plugins").add_submenu("Medeek Truss")
submenu.add_item("Roof Truss") { Sketchup.load(File.join(this_dir,"MEDEEK_ROOF_TRUSS.rbs")) }
submenu.add_item("Floor Truss") { Sketchup.load(File.join(this_dir,"MEDEEK_FLOOR_TRUSS.rbs")) }
submenu.add_item("Truss Set") { Sketchup.load(File.join(this_dir,"MEDEEK_TRUSS_SET.rbs")) }
submenu.add_item("Roof Rafters") { Sketchup.load(File.join(this_dir,"MEDEEK_ROOF_RAFTERS.rbs")) }
end
end
It depends if you have a call as the last line in the file, or as part of the commandā¦
in this example I call JcB::TransL8.get_text from the command2ā¦
if @dev_mode
transL8_menu = UI.menu('Help',(TRANSL8["Add Translation to Plugin"]))
command2 = UI::Command.new((TRANSL8["Add Translation to Plugin"])){
load( File.join(File.dirname(__FILE__), 'transL8_process.rb'))
JcB::TransL8.get_text
}
transL8_menu.add_item(command2)
end
once you have a command you can reuse it for both menu and toolbarā¦
for a .rbs you may need to use Sketchup.requireā¦
for your toolbar it is better to use restore for people who want it āoffāā¦
For the first item I call up the file āMEDEEK_ROOF_TRUSS.rbsā, the code in this file in very condensed form looks like:
require 'sketchup.rb'
require 'extensions.rb'
require 'langhandler.rb'
module Medeek_Engineering_Inc_Extensions
module MedeekTrussPlugin
##############################
#
# Class Methods of Plugin
#
##############################
class MedeekMethods
class << self
include Math
def some method name
{
ā¦
}
def another method name
{
ā¦
}
end # << self
end # MedeekMethods Class
###########################
#
# Main Entry into Program
#
###########################
MedeekMethods.roof_truss_family_menu
end # MedeekTrussPlugin
I guess Iām not fully understanding how to make this work. I will study your example above and see if I can implement it.
My original code was all contained within one file and now it has become rather lengthy and unmanageable. The idea is to break it into four separate files and only that portion of the code that pertains is loaded when a user clicks on a menu item or toolbar icon.
I am very new to Ruby programming so I apologize for my ignorance.
I guess I had not paid much attention to this topic at the time, but Iāll weigh in (7.5 years later.)
(1) Avoid the use of Sketchup::load as there is an open issue to alter it to make it work like Kernel#load.
Currently it is just alias for Sketchup::require which should be used explicitly.
Also the file extensions should not be used with these methods calls.
(2) The best way to conditionally load files that define objects, is to test whether those objects (modules or classes) have been defined yet.