• Login
sketchucation logo sketchucation
  • Login
πŸ”Œ Quick Selection | Try Didier Bur's reworked classic extension that supercharges selections in SketchUp Download

Class installs twice when reloaded!

Scheduled Pinned Locked Moved Developers' Forum
14 Posts 2 Posters 477 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.
  • O Offline
    onidarbe
    last edited by 1 Jan 2014, 22:54

    When I start SU, it will output 1 "x" releasing the middle-mouse-button, but when I reload the plugin, it will output 2 times "x"? Though a second reload doesn't produce 3 times "x"!

    [ruby]class MyToolsObserver < Sketchup;;ToolsObserver
        def onActiveToolChanged(tools, tool_name, tool_id)
          if @prevOrbit
            puts "x"
            @prevOrbit=false
          else
            @prevOrbit = true if tool_name == "CameraOrbitTool"
          end
        end
    end
    unless file_loaded?(__FILE__)
      Sketchup.active_model.tools.add_observer(MyToolsObserver.new)
    	file_loaded(__FILE__)
    end[/ruby]
    

    Is there even a way to unload any class, module of method? Maybe there is a total reset, removing all plugins, before reloading them all again, without the need to restart SU and reloading the model...

    thanks

    1 Reply Last reply Reply Quote 0
    • D Offline
      Dan Rathbun
      last edited by 2 Jan 2014, 10:20

      I tested and the only way I could get double puts was if an observer instance was attached twice to the active_model.

      I'm not here much anymore.

      1 Reply Last reply Reply Quote 0
      • D Offline
        Dan Rathbun
        last edited by 2 Jan 2014, 10:28

        @onidarbe said:

        Is there even a way to unload any class, module of method?

        Observers need to be unattached before destroying their class.
        This means you need to keep track of what you attach to what objects., so you can dettach them.

        MyViewObserver = nil
        or WITHIN your module (because it is a private method):
        remove_const(:MyViewObserver)

        @onidarbe said:

        Maybe there is a total reset, removing all plugins, before reloading them all again, without the need to restart SU and reloading the model...

        NO there is no total reset.

        I'm not here much anymore.

        1 Reply Last reply Reply Quote 0
        • O Offline
          onidarbe
          last edited by 2 Jan 2014, 11:29

          Thanks again, your always answering! β˜€

          It seems file_loaded(__FILE__) and unless file_loaded?(__FILE__) just doesn't work! It lets it reload a second time. And they are all using this techniek?!

          Isn't there any way to find which modules, classes, methods and observers have been added by all plugins?! Maybe I just need to search through the code of every *.rb file in the plugins-maps! But then I still need to know if I can undo everything. I already now that I can't remove any menu added items, although I could gray them out... But can I remove everything: methods, modules, classes, observers and variables. And I probably forget a lot of other things, considering I'm just starting to learn Ruby.

          1 Reply Last reply Reply Quote 0
          • D Offline
            Dan Rathbun
            last edited by 2 Jan 2014, 16:55

            @onidarbe said:

            It seems file_loaded(__FILE__) and unless file_loaded?(__FILE__) just doesn't work!

            The method just caompares string elements of an array ( $loaded_files).
            It does not absolutely need to be the full pathname of the script.
            I often only write the plugin module names, a colon and then the basename of the script, ie:
            this_file = "#{Module.nesting[0].name}:#{File.basename(__FILE__)}" file_loaded(this_file)

            If you do not like the way the file_loaded() from "sketchup.rb" works, you can write your OWN in a library module and mix in into each of your modules.

            Or you can use the built-in Ruby function defined?( *object* )

            @onidarbe said:

            But can I remove everything: methods, modules, classes, observers and variables.

            NO do not mess with other people's Ruby objects. Turn plugin's off via the Preferences > Extensions dialog. Then restart SketchUp.

            @onidarbe said:

            And I probably forget a lot of other things, considering I'm just starting to learn Ruby.

            Then start with easier coding projects.

            I'm not here much anymore.

            1 Reply Last reply Reply Quote 0
            • O Offline
              onidarbe
              last edited by 3 Jan 2014, 13:21

              Thanks Dan,

              With your help I found the problem with reloading plugins:

              When my Sketchup starts, file_loaded(__FILE__) adds "c:/progra~2/sketchup/sketch~1/plugins/any_script.rb" to $loaded_files, but when reloading the plugin it adds "c:/program files (x86)/sketchup/sketchup 2013/plugins/any_script.rb". So when SU starts it's using the shorter DOS-path though the filename isn't truncated to 8 characters, at least in my Windows 7 x64.
              That's why if !file_loaded?(__FILE__) doesn't work!

              So I only need to find a way to put in the full path length on startup. Any idea?
              Using only the filename or module:basename doesn't seem right to me, because shouldn't we all add the same to $loaded_files? Buy the way Module.nesting[0].name gives "undefined method"! Probably because of an older Ruby version.

              I was playing with the as_pluginloader.rb from Alexander Schreyer. I wanted to add a "reload all plugins". That's when I figured out that many plugins don't even use file_loaded. So that's a bummer 😞

              1 Reply Last reply Reply Quote 0
              • D Offline
                Dan Rathbun
                last edited by 3 Jan 2014, 23:19

                @onidarbe said:

                So I only need to find a way to put in the full path length on startup. Any idea?

                thisfile = File.expand_path(__FILE__)
                
                unless file_loaded?( thisfile )
                
                  # RUN ONCE CODE
                
                  file_loaded( thisfile )
                
                end
                

                I'm not here much anymore.

                1 Reply Last reply Reply Quote 0
                • D Offline
                  Dan Rathbun
                  last edited by 3 Jan 2014, 23:40

                  @onidarbe said:

                  BY (not Buy,) the way Module.nesting[0].name gives "undefined method"! Probably because of an older Ruby version.

                  Wrong, you cannot call it from the console. From within "main" instance of Object it will just return nil. And NilClass does not have a name() instance method.

                  Module.nesting[0].name
                  %(#008000)[Error: #<NoMethodError: undefined methodname' for nil:NilClass>]`

                  It must be called from within a class or module.

                  I'm not here much anymore.

                  1 Reply Last reply Reply Quote 0
                  • D Offline
                    Dan Rathbun
                    last edited by 3 Jan 2014, 23:54

                    @onidarbe said:

                    Using only the filename or module:basename doesn't seem right to me, because shouldn't we all add the same to $loaded_files?

                    You miss the point.

                    The arg requires a String (of any kind,) .. a does NOT require a real pathname, even though the API show this in the example.

                    Only YOU will be testing the $loaded_files array for YOUR strings, so they can be whatever YOU need.

                    The ACTUAL loaded file's path is stored in the Ruby global array $LOADED_FEATURES (aliased as $".)

                    Since ALL of YOUR plugin's should be within a sub-module or YOUR OWN toplevel module (whatever you choose to name it,) ... you can instead use your OWN custom loaded files array.

                    See my example (from the Snippet's Index):
                    [Code] custom file_loaded() and file_loaded?() v2.0.0

                    πŸ’­

                    I'm not here much anymore.

                    1 Reply Last reply Reply Quote 0
                    • O Offline
                      onidarbe
                      last edited by 4 Jan 2014, 00:43

                      ooh OK, that explains a lot. Thanks Dan!

                      Maybe you could also edit that post of you and add that they should never use the full path, because in windows it could be truncated! πŸ˜‰

                      1 Reply Last reply Reply Quote 0
                      • D Offline
                        Dan Rathbun
                        last edited by 4 Jan 2014, 01:41

                        @dan rathbun said:

                        @onidarbe said:

                        So I only need to find a way to put in the full path length on startup. Any idea?

                        thisfile = File.expand_path(__FILE__)
                        > 
                        > unless file_loaded?( thisfile )
                        > 
                        >   # RUN ONCE CODE
                        > 
                        >   file_loaded( thisfile )
                        > 
                        > end
                        

                        Just tested this File.expand_path does not really expand those Window pathnames.

                        I'm not here much anymore.

                        1 Reply Last reply Reply Quote 0
                        • O Offline
                          onidarbe
                          last edited by 4 Jan 2014, 01:54

                          yheah I know, tried that one already.
                          Need to use win32API, but I can't seem to figure out how to use that!
                          require "Win32API" gives me: "parenthesize argument(s) for future version" and "no such file to load"

                          1 Reply Last reply Reply Quote 0
                          • D Offline
                            Dan Rathbun
                            last edited by 4 Jan 2014, 02:50

                            @onidarbe said:

                            Need to use win32API, but I can't seem to figure out how to use that!

                            I posted the so files in the "Plugins" forum:
                            [Plugin Library] Win32API and Win32OLE so files

                            @onidarbe said:

                            require "Win32API" gives me: "parenthesize argument(s) for future version" and "no such file to load"

                            Get in the habit of putting parenthesis around argument lists, like:
                            require("Win32API")
                            Do NOT put a space between method names and the opening **(**

                            I'm not here much anymore.

                            1 Reply Last reply Reply Quote 0
                            • O Offline
                              onidarbe
                              last edited by 5 Jan 2014, 01:04

                              aoh, I need to have that file Win32API.so in the plugin map!
                              thanks

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

                              Advertisement