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

    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.
    • onidarbeO Offline
      onidarbe
      last edited by

      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
      • Dan RathbunD Offline
        Dan Rathbun
        last edited by

        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
        • Dan RathbunD Offline
          Dan Rathbun
          last edited by

          @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
          • onidarbeO Offline
            onidarbe
            last edited by

            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
            • Dan RathbunD Offline
              Dan Rathbun
              last edited by

              @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
              • onidarbeO Offline
                onidarbe
                last edited by

                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
                • Dan RathbunD Offline
                  Dan Rathbun
                  last edited by

                  @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
                  • Dan RathbunD Offline
                    Dan Rathbun
                    last edited by

                    @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
                    • Dan RathbunD Offline
                      Dan Rathbun
                      last edited by

                      @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
                      • onidarbeO Offline
                        onidarbe
                        last edited by

                        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
                        • Dan RathbunD Offline
                          Dan Rathbun
                          last edited by

                          @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
                          • onidarbeO Offline
                            onidarbe
                            last edited by

                            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
                            • Dan RathbunD Offline
                              Dan Rathbun
                              last edited by

                              @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
                              • onidarbeO Offline
                                onidarbe
                                last edited by

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

                                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