sketchucation logo sketchucation
    • Login
    πŸ€‘ SketchPlus 1.3 | 44 Tools for $15 until June 20th Buy Now

    Weirdest loading bug ever?

    Scheduled Pinned Locked Moved Developers' Forum
    16 Posts 2 Posters 680 Views 2 Watching
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • L Offline
      lothcat
      last edited by

      This is such a strange issue, I don't even know how to describe it properly.

      I am developing a plugin for distribution, and therefore I am using scrambled files. I do most of my coding/debugging with the unscrambled files and only load the scrambled files to make sure they work before I send them to my boss. We're just now entering the testing phase.

      I only noticed I had an issue when I realized one of my messageboxes was wrong while I was using the scrambled files. It was a silly bug - it had a blank where it needed a dropdown. I fixed it, scrambled it, restarted sketchup - and the blank was still there. So I reworked that messagebox and reordered the inputs, scrambled, reloaded - and it was still the same (wrong) messagebox from before. When I loaded the unscrambled version, the messagebox was fixed, but as soon as I tried to load a scrambled version it was wrong again.

      I thought it might be the scrambler, that maybe it was just outputting the wrong file, but when I added or removed comments the scrambled file changed size. I thought it might be a caching issue, so I shut down my computer - but it was still there the next day.

      So then, on a whim, I renamed the folder I was loading the plugin from. The images were gone, but my plugin still popped up and worked! The wrong messagebox version, of course.

      I was able to load my plugin on a borrowed laptop just to make sure the scrambled files are actually correct, but now I'm worried that I'll be giving out new versions to my testers and this weird glitch is going to keep the older version there, especially since this glitch has appeared on my boss's computer as well.

      I am completely flabbergasted, I have no idea how this is even possible. I am using Sketchup.load(extension_name) and Sketchup version 7 running on Windows 7, and my boss has Sketchup 7 running on Windows XP.

      Has anybody else had this issue? Is there some sort of unload or reload command that I need to include to make sure Sketchup is using the correct files? Is this a known bug they fixed with Sketchup 8? Or am I the only one with this problem?

      1 Reply Last reply Reply Quote 0
      • L Offline
        lothcat
        last edited by

        Thanks for all your help! But I'm not sure I understand - is it better to have the loading script inside the widget folder instead of the plugin folder?

        My current loading script is inside the plugin folder, and goes something like this:

        Sketchup.load('LothCatWidget/widget')
        
        WIDGET_tool = WIDGETmaker.new
        
                plugins = "LothCatWidget/" 
                imgdir = plugins
        
        
                # create toolbar
                tb = UI;;Toolbar.new("LothCatWidget Toolbar")
        
                # Button 1
                cmd = UI;;Command.new("Widget") { Sketchup.active_model.select_tool WIDGET_tool }
                cmd.large_icon = cmd.small_icon = File.join(imgdir, "WIDGET.png")
                cmd.status_bar_text = cmd.tooltip = "Widget"
                tb.add_item cmd
        
        

        Would it be better to have this script inside the folder? Do I need to separate out the 'load' command from the toolbar script? And are you saying that it's the fact that I'm using Sketchup.load instead of Sketchup.require that's causing my weird bug?

        1 Reply Last reply Reply Quote 0
        • Dan RathbunD Offline
          Dan Rathbun
          last edited by

          @dan rathbun said:

          Also.. the image paths for toolbar cmds, in rbs may give you problems...

          I went for a swim, and thot about this some more.

          I remembered finding images could be a problem, so I looked at several Google supplied examples.

          The UI::Command instance methods large_icon() and small_icon() can (in unscrambled rb files,) take either an absolute path, or a relative path (that is relative to the dir that the ruby script is in, NOT relative to the Plugins folder.)

          A scrambled rbs file CAN take an absolute path. But I don't know if it can take a relative path.

          I'm not here much anymore.

          1 Reply Last reply Reply Quote 0
          • Dan RathbunD Offline
            Dan Rathbun
            last edited by

            @lothcat said:

            Thanks for all your help! But I'm not sure I understand - is it better to have the loading script inside the widget folder instead of the plugin folder?

            YES.

            • The only file in the Plugins folder is as I showed above, the file that registers the plugin with Sketchup, so it can be enabled / disabled with the Window (menu) > Preferences (dialog) > Extensions (panel)

            @lothcat said:

            My current loading script is inside the plugin folder, and goes something like this:
            Sketchup.load('LothCatWidget/widget')
            Remove this first line.. and create the "lothcat/widget/widget_loader.rb" file as above.

            • You should have an "author" subdir for all YOUR plugins, beneath the Plugins dir.* For example.. we call it "lothcat" (but it could be a company name, if you release plugins thru a company. As long as it's unique. Don't use some other entity's trademarked name, like Coca-Cola!)* Then, EACH separate plugin of your's, goes in a separate subdir of your "author" subdir.* A specific plugin subdir, can have it's own subdirs, if you wish, such as "images"* It's all about organizing, your OWN "filespace"...* ... but more importantly, not mixing up YOUR files with everyone else's, ...* ... and keeping the files for each of YOUR separate plugins from getting mixed up together.

            @lothcat said:

            Do I need to separate out the 'load' command from the toolbar script?
            It becomes a one-line script, named widget_loader.rb (as shown above,) saved into the widget dir, of YOUR "author/company" dir (which we call "lothcat" here for example.)
            @lothcat said:

            And are you saying that it's the fact that I'm using Sketchup.load instead of Sketchup.require that's causing my weird bug?
            Well.. you mentioned strange things happening if files get loaded twice. Use the require method to be sure the "package" is loaded only once.

            Did you use __FILE__ anywhere to build paths to datafiles or image files ??

            Also.. the image paths for toolbar cmds, in rbs may give you problems... see below:

            @lothcat said:

            WIDGET_tool = WIDGETmaker.new
            > 
            >         plugins = "LothCatWidget/" 
            >         imgdir = plugins
            > 
            > 
            >         # create toolbar
            >         tb = UI;;Toolbar.new("LothCatWidget Toolbar")
            > 
            >         # Button 1
            >         cmd = UI;;Command.new("Widget") { Sketchup.active_model.select_tool WIDGET_tool }
            >         cmd.large_icon = cmd.small_icon = File.join(imgdir, "WIDGET.png")
            >         cmd.status_bar_text = cmd.tooltip = "Widget"
            >         tb.add_item cmd
            > 
            

            Would it be better to have this script inside the folder?

            YES... the script snippet above, along with your Tool class definition, needs to be wrapped in your plugin namespace. (Your defining it at the TOPLEVEL which is within Object.)
            It would be scrambled as "widget.rbs", and saved into the "widget" dir, beneath your "author/company" dir ("lothcat" or whatever name you use.)

            I'd also suggest (since you are within your namespace Lothcat::Widget, that you use either a constant, or a module @@var to hold your toolbar reference.

            Like so:

            # widget.rbs
            require('sketchup.rb')
            
            module Lothcat;;Widget
            
              # The constants PATH, ABSDIR, RELDIR, RBSFILE, etc., can be
              # accessed here because they are local to this namespace.
              # The same is true for the module var @@plugin, which is the
              # reference to your SketchupExtension plugin instance.
            
              def self.plugin()
                @@plugin
              end
            
              class WIDGETmaker
                # your Tool class definition
              end #class
            
              WIDGET_tool = WIDGETmaker.new
            
              def self.tool()
                WIDGET_tool
              end
            
              # plugins = "LothCatWidget/" # dont need, use local constant
              #   RELDIR defined in "plugins/lothcat_widget_ext.rb"
            
              #  
              # imgdir = plugins # this may have problems in rbs
              # try an absolute path, use ABSDIR;
              imgdir = ABSDIR # or ABSDIR + "/images" if in a subdir
            
            
              # do only once block
              #
              unless file_loaded?( RBSFILE )
            
                # create toolbar
                @@toolbar = UI;;Toolbar.new("LothCatWidget Toolbar")
            
                def self.toolbar()
                  @@toolbar
                end
            
                # Button 1
                cmd = UI;;Command.new("Widget") { Sketchup.active_model.select_tool WIDGET_tool }
                cmd.large_icon = cmd.small_icon = File.join(imgdir, "WIDGET.png")
                cmd.status_bar_text = cmd.tooltip = "Widget"
                @@toolbar.add_item cmd
            
                file_loaded( RBSFILE )
            
              end # unless
            
              # The rest of your scrambled code goes here.
              # Can have nested submodules and class definitions, etc.
            
            end #mod Lothcat;;Widget
            

            I'm not here much anymore.

            1 Reply Last reply Reply Quote 0
            • Dan RathbunD Offline
              Dan Rathbun
              last edited by

              Fixed code examples above (added a RBSFILE constant.)

              Also created a generic [ Code ] example thread (per request.)

              I'm not here much anymore.

              1 Reply Last reply Reply Quote 0
              • Dan RathbunD Offline
                Dan Rathbun
                last edited by

                There are a few quirks you need to be aware of with scrambled rubies.

                1) If your using the SketchupExtension class (see file Tools/extensions.rb,) the file refered to in the path attribute must be an unscrambled script. Convention is that it is named with a "_loader.rb" suffix. So if the name of your plugin is "widget" then the registration script in the plugins folder would be "lothcat_widget_ext.rb", which sets the path to "lothcat/widget/widget_loader.rb" (in your plugin subfolder, of your author subfolder, which you should be using, by the way.)
                The script for "lothcat/widget/widget_loader.rb" would be a one-liner, that simply says:
                Sketchup.require("lothcat/widget/widget")
                which will (if it isn't loaded,) will call Sketchup.load("lothcat/widget/widget.rbs")

                2) **Special Ruby vars**The special Ruby keywords (actually built-in functions,) __FILE__ and __LINE__ do NOT work inside scrambled rbs scripts (as of v8.0M1.) This is because scrambled scripts are loaded into the system as an encrypted String, decrypted by Sketchup.load() internally into a plain text String, and that String is then passed as the argument to the Object.eval() method. Google neglected to search and replace those two constants, before passing the code String to eval. I've reported it in the last beta round, and we've complained about it all thru the ver 7 lifecycle as well.
                Hoping it will be fixed in the next release.

                Workaround:

                Keep a reference to your SketchupExtension instance object, by doing this for your extension registration script (this file goes in the main Plugins folder.)
                lothcat_widget_ext.rb

                require('extensions.rb')
                
                module Lothcat  # Proprietary TopLevel Namespace; No Tresspassing!
                
                  module Widget  # Namespace for THIS plugin
                
                    # Create an entry in the Extension list that loads
                    #  a script called; "lothcat/widget/widget_loader.rb"
                  
                
                    @@plugin = SketchupExtension.new( "Lothcat's Widget", "lothcat/widget/widget_loader.rb" )
                    
                    @@plugin.creator   = 'Lothcat'
                    @@plugin.copyright = "(c)2011 by Lothcat"
                    
                    @@plugin.version   = '1.0.0'
                
                    @@plugin.description = "A Widget that does fancy things."
                    
                    Sketchup.register_extension( @@plugin, true )
                    
                    unless @@plugin.class.method_defined?(;path)
                      #
                      # define a singleton method for @@plugin to access the path attribute
                      # (because Google did not do it in extensions.rb !!)
                      #
                      def @@plugin.path()
                        @path
                      end
                    end # unless
                    
                    # Create local path and filename constants;
                    #
                    PATH = @@plugin.path()
                    LOADER_SUFFIX = '_loader'
                    LOADER = File.basename(PATH)
                    RBSFILE = LOADER.split("_")[0] << '.rbs'
                
                    # RELDIR is relative to Plugins dir, OR the dir from
                    # the $LOAD_PATH array that require used to find it.
                    RELDIR = File.dirname(PATH)
                    ABSDIR = File.expand_path(RELDIR) # absolute path
                
                  end # module Lothcat;;Widget
                  
                end # module Lothcat
                

                "lothcat/widget/widget_loader.rb"

                Sketchup.require("lothcat/widget/widget")
                

                Now all of the code in the "lothcat/widget/widget.rbs" file should also be namespace wrapped within module Lothcat::Widget like so:

                require('sketchup.rb')
                module Lothcat;;Widget
                
                  # The constants PATH, ABSDIR, RELDIR, RBSFILE, etc., can be
                  # accessed here because they are local to this namespace.
                  # The same is true for the module var @@plugin, which is the
                  # reference to your SketchupExtension plugin instance.
                
                  # The rest of your scrambled code goes here.
                  # Can have nested submodules and class definitions, etc.
                
                  ### Do only once block
                  #
                  unless file_loaded?( RBSFILE )
                
                    # define menu items and toolbars
                
                    file_loaded( RBSFILE )
                
                  end # once block
                
                end #mod Lothcat;;Widget
                

                I'm not here much anymore.

                1 Reply Last reply Reply Quote 0
                • L Offline
                  lothcat
                  last edited by

                  I'm trying to use this loader, but I keep getting errors. Specifically:

                  Error Loading File F:/Program Files (x86)/Google/Google SketchUp 7/Plugins/lothcat/widget/widget.rb
                  uninitialized constant Lothcat::Widget::RBSFILEError Loading File F:/Program Files (x86)/Google/Google SketchUp 7/Plugins/lothcat/widget/widget_loader.rb
                  uninitialized constant Lothcat::Widget::RBSFILEError Loading File lothcat_widget_ext.rb
                  uninitialized constant Lothcat::Widget::RBSFILE

                  When I changed the names, I still get an uninitialized constant error.

                  1 Reply Last reply Reply Quote 0
                  • Dan RathbunD Offline
                    Dan Rathbun
                    last edited by

                    Are you loading the "lothcat/widget/widget.rb" directly using the load() command at the console?
                    If so you need to first load "lothcat_widget_ext.rb" where the RBSFILE constant gets defined.

                    You need to learn how to debug !! I cannot always do it for you.
                    I inserted debugging puts() statements into the "lothcat_wigdet_ext.rb" file, like so:

                        # Create local path and filename constants;
                        #
                        PATH = @@plugin.path()
                        puts "Lothcat;;Widget;;PATH = '#{PATH}'"
                        LOADER_SUFFIX = '_loader'
                        LOADER = File.basename(PATH)
                        puts "Lothcat;;Widget;;LOADER = '#{LOADER}'"
                        RBSFILE = LOADER.split("_")[0] << '.rbs'
                        puts "Lothcat;;Widget;;RBSFILE = '#{RBSFILE}'"
                        
                     
                        # RELDIR is relative to Plugins dir, OR the dir from
                        # the $LOAD_PATH array that require used to find it.
                        RELDIR = File.dirname(PATH)
                        puts "Lothcat;;Widget;;RELDIR = '#{RELDIR}'"
                        ABSDIR = File.expand_path(RELDIR) # absolute path
                        puts "Lothcat;;Widget;;ABSDIR = '#{ABSDIR}'"
                    
                    

                    I then loaded the file, and the console output was:
                    Lothcat::Widget::PATH = 'lothcat/widget/widget_loader.rb' Lothcat::Widget::LOADER = 'widget_loader.rb' Lothcat::Widget::RBSFILE = 'widget.rbs' Lothcat::Widget::RELDIR = 'lothcat/widget' Lothcat::Widget::ABSDIR = 'F:/Program Files (x86)/Google/Google SketchUp 7/Plugins/lothcat/widget'

                    Looks to me like you are not loading loading the extension registration script, before the plugin script.

                    I'm not here much anymore.

                    1 Reply Last reply Reply Quote 0
                    • Dan RathbunD Offline
                      Dan Rathbun
                      last edited by

                      Also... the "lothcat/widget/widget_loader.rb" can be changed so it autoloads either an rb or an rbs file.
                      This can make it easier during development.

                      "lothcat/widget/widget_loader.rb"

                      #
                      #  "widget_loader.rb"
                      #
                      
                      require('sketchup.rb')
                       
                      module Lothcat;;Widget  # Namespace for THIS plugin
                       
                          # Conditionally loads a script&#058;
                          #  1) trys; "lothcat/widget/widget.rb"
                          #  2) trys; "lothcat/widget/widget.rbs"
                         
                          begin
                      
                            require(File.join(RELDIR,"widget.rb"))
                      
                          rescue LoadError ==> e
                      
                            if e.message.include?("no such file to load -- #{RELDIR}/widget.rb")
                            
                              begin
                                Sketchup.require(File.join(RELDIR,"widget.rbs"))
                              rescue
                                raise
                              else
                                unless file_loaded?(File.join(RELDIR,File.basename(__FILE__)))
                                  file_loaded(File.join(RELDIR,File.basename(__FILE__)))
                                end # if not loaded
                              end
                            
                            else
                              raise  # just reraise the error
                            end
                      
                          else
                      
                            unless file_loaded?(File.join(RELDIR,File.basename(__FILE__)))
                              file_loaded(File.join(RELDIR,File.basename(__FILE__)))
                            end # if not loaded
                      
                          end
                       
                      end # module Lothcat;;Widget
                      
                      

                      I'm not here much anymore.

                      1 Reply Last reply Reply Quote 0
                      • L Offline
                        lothcat
                        last edited by

                        You're right, I'm leaning on you a lot - it's because you're introducing a ton of stuff here that I've never used, and I wasn't even sure where to begin debugging. I'm still new to this.

                        I tried modifying your code to my module, but when it didn't work, I tried making the snippets exactly how you wrote them.

                        I'm putting the ext file in the plugin folder, and the others under lothcat/widget, then starting up sketchup rather than using load. The error is what appears on startup. I thought maybe it was loading the files in the @@plugin statement, so I moved that further down... and that didn't work either.

                        I can fiddle with it on my own for a while to try to find the problem.

                        Thank you so much for your help!

                        1 Reply Last reply Reply Quote 0
                        • Dan RathbunD Offline
                          Dan Rathbun
                          last edited by

                          Why are you still using Sketchup 7 ??

                          Version 8 fixes all manner of bugs, and runs Ruby v1.8.6-p287
                          SU 7, "out-of-the-box" still has Ruby v1.8.0 (initial rel.)

                          If you don't want to move up to ver 8, at the very least, update the Ruby DLL in the "Sketchup 7" dir, to v1.8.6-p287.

                          Get it here: Ruby Interpreter DLLs (Win32)

                          I'm not here much anymore.

                          1 Reply Last reply Reply Quote 0
                          • L Offline
                            lothcat
                            last edited by

                            I'm still using seven because I want to make sure that everyone in the company can use it, but if I have to force people to upgrade, so be it.

                            Turning off the RELDIR/ABSDIR calls seems to fix it for now.

                            1 Reply Last reply Reply Quote 0
                            • Dan RathbunD Offline
                              Dan Rathbun
                              last edited by

                              @lothcat said:

                              I'm still using seven because I want to make sure that everyone in the company can use it, but if I have to force people to upgrade, so be it.

                              Well OK.. but update the DLL to v1.8.6-p287, at least. Then retry the code.

                              @lothcat said:

                              Turning off the RELDIR/ABSDIR calls seems to fix it for now.

                              That does not make sense.. and is not a real solution.

                              When you get an error during Sketchup startup.. the display of the error messages are hard to read in that little box. Press the OK button, and let Sketchup finish loading.

                              Immediately open the Ruby Console.
                              and type $!
                              (The last error message will be redisplayed.)
                              ... then immediately, type puts $@
                              (The backtrace for that last error will be displayed.)

                              Don't make any typo errors in the console, or those two variables will lose the info from the LoadError, and take on new typo booboo error!

                              The backtrace will list the error and the filename where the error occured, followed by a colon, and the line number from the code.
                              Then the same for the file and line that called the previous line, and so on, all the way back to the original require() call, that tried to load "lothcat_widget_ext.rb"

                              So it's the first line of the backtrace where the actual error occurs. The backtrace you sent earlier shows that some of those constants may not be getting set.

                              I will bet that it's because your running Ruby v1.8.0, update that DLL.

                              Debugging tip. Always verify that the first file to load, is correct. So debug the extension registration script, and all those constant will be available in the plugin file.

                              I'm not here much anymore.

                              1 Reply Last reply Reply Quote 0
                              • Dan RathbunD Offline
                                Dan Rathbun
                                last edited by

                                Ok found it!!!

                                Duh (slap me.) File.expand_path assumes the relative path is from the current working directory.
                                Which you can get:
                                Dir.getwd

                                So in the example above:
                                (line 42) ABSDIR = File.expand_path(RELDIR) # absolute path
                                will be wrong.

                                I'm doing this in my files now:

                                    ROOT = $LOAD_PATH.find(false) do |abspath|
                                      Kernel.test(?d, File.join(abspath,RELDIR) )
                                    end
                                    if ROOT
                                      ABSDIR = File.join( ROOT, RELDIR )
                                    else
                                      # assume the target dir is directly below, the dir that THIS file is in.
                                      ABSDIR = File.join( File.dirname(__FILE__), RELDIR )
                                    end
                                
                                

                                I'm not here much anymore.

                                1 Reply Last reply Reply Quote 0
                                • L Offline
                                  lothcat
                                  last edited by

                                  Thank you so much! It's working now and I'm not having that weird loading bug!

                                  Also, thank you for being patient with me. This was a real learning experience.

                                  1 Reply Last reply Reply Quote 0
                                  • Dan RathbunD Offline
                                    Dan Rathbun
                                    last edited by

                                    @lothcat said:

                                    Thank you so much! It's working now and I'm not having that weird loading bug!

                                    Excellent!

                                    @lothcat said:

                                    Also, thank you for being patient with me. This was a real learning experience.

                                    I would be very worried if you had not learned anything, here .... πŸ˜†

                                    I'm not here much anymore.

                                    1 Reply Last reply Reply Quote 0
                                    • 1 / 1
                                    • First post
                                      Last post
                                    Buy SketchPlus
                                    Buy SUbD
                                    Buy WrapR
                                    Buy eBook
                                    Buy Modelur
                                    Buy Vertex Tools
                                    Buy SketchCuisine
                                    Buy FormFonts

                                    Advertisement