• Login
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 27 Jul 2011, 18:50

    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 28 Jul 2011, 18:35

      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
      • D Offline
        Dan Rathbun
        last edited by 28 Jul 2011, 23:23

        @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
        • D Offline
          Dan Rathbun
          last edited by 31 Jul 2011, 16:35

          @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
          • D Offline
            Dan Rathbun
            last edited by 31 Jul 2011, 16:46

            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
            • D Offline
              Dan Rathbun
              last edited by 2 Aug 2011, 20:41

              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 18 Aug 2011, 19:50

                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
                • D Offline
                  Dan Rathbun
                  last edited by 18 Aug 2011, 21:36

                  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
                  • D Offline
                    Dan Rathbun
                    last edited by 18 Aug 2011, 21:54

                    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 18 Aug 2011, 22:03

                      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
                      • D Offline
                        Dan Rathbun
                        last edited by 19 Aug 2011, 01:01

                        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 19 Aug 2011, 01:25

                          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
                          • D Offline
                            Dan Rathbun
                            last edited by 19 Aug 2011, 01:55

                            @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
                            • D Offline
                              Dan Rathbun
                              last edited by 19 Aug 2011, 02:20

                              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 19 Aug 2011, 15:39

                                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
                                • D Offline
                                  Dan Rathbun
                                  last edited by 19 Aug 2011, 17:17

                                  @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