sketchucation logo sketchucation
    • Login
    ℹ️ Licensed Extensions | FredoBatch, ElevationProfile, FredoSketch, LayOps, MatSim and Pic2Shape will require license from Sept 1st More Info

    Tool <> WebDialog <> Observers relationship

    Scheduled Pinned Locked Moved Developers' Forum
    23 Posts 4 Posters 1.1k Views 4 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.
    • T Offline
      tomasz
      last edited by

      @dan rathbun said:

      Tools are meant to be re-used.

      I have downloaded Google's 'rectangle.rb' tool example and I find following on the start-up:

      if( not $rectangle_menu_loaded )
          add_separator_to_menu("Draw")
          UI.menu("Draw").add_item("Rotated Rectangle") {
              Sketchup.active_model.select_tool RectangleTool.new }
          $rectangle_menu_loaded = true
      end
      

      The tool is created each time the plugin is started.
      Maybe if I have a Tool as a global variable inside a MyWebDialog class it multiplies now tools, every-time I open the dialog..

      What you propose has definitely a lot of merit. I will check if it improves my tool stability.

      Author of [Thea Render for SketchUp](http://www.thearender.com/sketchup)

      1 Reply Last reply Reply Quote 0
      • thomthomT Offline
        thomthom
        last edited by

        Yea - I used to create tools every time it was activated as well - due to the examples in the manual always do so. Can't remember if it was Fredo or Whaat that mentioned it was not necessary.

        Thomas Thomassen — SketchUp Monkey & Coding addict
        List of my plugins and link to the CookieWare fund

        1 Reply Last reply Reply Quote 0
        • AdamBA Offline
          AdamB
          last edited by

          @thomthom said:

          Yea - I used to create tools every time it was activated as well - due to the examples in the manual always do so. Can't remember if it was Fredo or Whaat that mentioned it was not necessary.

          Well Dan is sensible guy who says smart stuff. But I'm not quite sure why you want to keep a reference to the Tool around rather than release it back to the system. The specific reason I generally keep dialogs as class variables is to avoid the weird GC behaviour I wrote about earlier. But the rule of thumb in OO systems, is you create stuff, use it and explicit/implicit release stuff.

          The exception is sometimes performance when you pre-create Pools of objects to use/share. But this isn't one of those cases.

          Adam

          Developer of LightUp Click for website

          1 Reply Last reply Reply Quote 0
          • thomthomT Offline
            thomthom
            last edited by

            @adamb said:

            The exception is sometimes performance when you pre-create Pools of objects to use/share. But this isn't one of those cases.

            That is what I am doing. I was going a bit OT. I wasn't referring to a tool that created webdialogs.

            Thomas Thomassen — SketchUp Monkey & Coding addict
            List of my plugins and link to the CookieWare fund

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

              @unknownuser said:

              @dan rathbun said:

              Tools are meant to be re-used.

              I have downloaded Google's 'rectangle.rb' tool example ...
              Warning! Most of the Google Ruby examples, have very poor Ruby programming practices. (One of the things on my to-do list is to edit these examples, so newbies see the proper Ruby way of scripting. Just need to find the time is all.)

              @unknownuser said:

              The tool is created each time the plugin is started.
              And that makes my point. The example is a poor example.

              @unknownuser said:

              Maybe if I have a Tool as a global variable inside a MyWebDialog class it multiplies now tools, every-time I open the dialog..
              Globals are not kept inside a class, even if they are defined inside a class.

              I'm not here much anymore.

              1 Reply Last reply Reply Quote 0
              • thomthomT Offline
                thomthom
                last edited by

                @dan rathbun said:

                Warning! Most of the Google Ruby examples, have very poor Ruby programming practices. (One of the things on my to-do list is to edit these examples, so newbies see the proper Ruby way of scripting. Just need to find the time is all.)

                Yes - I have some to realise this. Bit of a shame as one easily use the documentation as guideline when learning a language.

                Thomas Thomassen — SketchUp Monkey & Coding addict
                List of my plugins and link to the CookieWare fund

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

                  @adamb said:

                  Well Dan is sensible guy who says smart stuff. But I'm not quite sure why you want to keep a reference to the Tool around rather than release it back to the system.
                  Depends... if it's a base drawing or editing tool, that will be used often.. keep it around. If it's say a import, export or report tool, that will be used only on occasion, then yes create it when it's used, and release the reference to it when it's no longer needed. (Hoping GC will dispose on it.)

                  @adamb said:

                  The specific reason I generally keep dialogs as class variables is to avoid the weird GC behaviour I wrote about earlier.
                  So is there a difference when the WebDialog instance, is created inside Object (at the console,) as opposed to within a custom namespace (Class or Module.) ?? It's always dangerous to create objects in the ObjectSpace, because all other objects may inherit them in some way (especially true of methods.) Local variables, Class variables and Instance variables defined in Object (at the console,) act strangly like Global variables when they're inherited by all the other objects.

                  @adamb said:

                  The exception is sometimes performance when you pre-create Pools of objects to use/share. But this isn't one of those cases.
                  Well I have no idea what kind of tool he's talking about. If it's an occasional tool, then you are correct AB. If it will be used often, he will want to, keep the instance alive.

                  I'm not here much anymore.

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

                    @adamb said:

                    But the rule of thumb in OO systems, is you create stuff, use it and explicit/implicit release stuff.

                    Agreed.. however, it would nice to have direct control over "my" objects. When I want to get rid of an object, I'd like to call a dispose method. Perhaps also a release method that would release ALL references (vars) to the object. And finally, I'd like the undef function/keyword to act upon references (of all kinds,) so when I'm done with a reference, it can be removed from the module/class reference hash-table. (There is cheat to this. Use vars that begin with a capital letter so Ruby sees them as Constants, then you can use the remove_const to remove the definition.)

                    Anyhow... these wishes need to be voiced over at
                    http://redmine.ruby-lang.org/projects/ruby/issues

                    I'm not here much anymore.

                    1 Reply Last reply Reply Quote 0
                    • T Offline
                      tomasz
                      last edited by

                      @dan rathbun said:

                      The next time the user clicks a toolbar button (or menu item,) for your tool, Sketchup will call the Tool's activate method. This means that the Tool class object is still defined and should remain defined.

                      I have noticed that 'activate' method of my tool is never called. I create a object=MyTool.new, it launches initialize().

                      @dan rathbun said:

                      Warning! Most of the Google Ruby examples, have very poor Ruby programming practices. (One of the things on my to-do list is to edit these examples, so newbies see the proper Ruby way of scripting. Just need to find the time is all.)

                      Could we create a simple structure of a properly programmed tool?
                      I have written something for a start. I think it is bugged because set_on_close is fired up twice.

                      
                      require "sketchup.rb"
                      
                      module ProperTool
                      
                      	#Observer
                      	class ProperTool;;ViewObserver < Sketchup;;ViewObserver
                      		def onViewChanged(view)
                      			puts "View changed; #{view}"
                      		end
                      	end
                      
                      	#Create observer
                      	version="ProperTool_001"
                      	unless file_loaded?(version)
                      		ProperTool;;VERSION=version
                      		@@view_observer=ProperTool;;ViewObserver.new
                      	end
                      
                      	#Define reader method for the observer
                      	def ProperTool;;get_view_observer
                      		return @@view_observer
                      	end
                      
                      	#Tool
                      	class ProperTool;;TestTool
                      		def initialize(web_dialog)
                      			@ip = Sketchup;;InputPoint.new
                      			@web_dialog=web_dialog
                      		end
                      
                      		def onCancel(reason,view)
                      			@web_dialog.close
                      		end
                      
                      		def deactivate(view)
                      			@web_dialog.close
                      		end
                      	end
                      
                      	#Web Dialog controls the rest
                      	class ProperTool;;MainDialog
                      
                      		def initialize
                      
                      			@dlg=UI;;WebDialog.new("ProperTool")
                      
                      			@dlg.set_html("<html><body>
                      				<form>
                      				<input type=\"button\" value=\"Close Me\" onclick=\"window.location.href='skp;close_me'\" />
                      				</form></body><html>"
                      			)
                      
                      			@dlg.set_on_close {
                      				puts "Set on close fired."
                      				Sketchup.active_model.active_view.remove_observer ProperTool;;get_view_observer
                      				Sketchup.active_model.select_tool(nil)
                      			}
                      
                      			@dlg.add_action_callback('close_me'){ |dialog, params| self.close() }
                      
                      			@tool = Sketchup.active_model.select_tool ProperTool;;TestTool.new(@dlg)
                      			Sketchup.active_model.active_view.add_observer ProperTool;;get_view_observer
                      			@dlg.show
                      
                      		end
                      
                      		def close
                      			@dlg.close
                      		end
                      
                      	end
                      
                      end # Module
                      
                      unless file_loaded?(ProperTool;;VERSION)
                      		main_menu = UI.menu("Plugins")
                      		main_menu.add_item("ProperTool") {ProperTool;;MainDialog.new}
                      end
                      
                      file_loaded(ProperTool;;VERSION)
                      

                      Version 001

                      Author of [Thea Render for SketchUp](http://www.thearender.com/sketchup)

                      1 Reply Last reply Reply Quote 0
                      • thomthomT Offline
                        thomthom
                        last edited by

                        @unknownuser said:

                        I have noticed that 'activate' method of my tool is never called. I create a object=MyTool.new, it launches initialize()

                        activate and initialize both works - for completely different purposes.

                        initialize triggers when you create an instance of your Tools class - as any other class. activate triggers when the tool is being activated - either by Sketchup.active_model.select_tool or Sketchup.active_model.tools.push_tools.

                        Are you not seeing that behaviour?

                        Thomas Thomassen — SketchUp Monkey & Coding addict
                        List of my plugins and link to the CookieWare fund

                        1 Reply Last reply Reply Quote 0
                        • T Offline
                          tomasz
                          last edited by

                          @thomthom said:

                          Are you not seeing that behaviour?

                          When I have added the activate method to the posted sample, it does trigger, but the initialize() doesn't.
                          For some odd reason activate doesn't fire up in my own tool. I start both tools exactly in the same way:
                          @tool = Sketchup.active_model.select_tool ToolName.new


                          Version 002 - activate tool method added

                          Author of [Thea Render for SketchUp](http://www.thearender.com/sketchup)

                          1 Reply Last reply Reply Quote 0
                          • thomthomT Offline
                            thomthom
                            last edited by

                            ` > class MyTool; def initialize; puts 'init'; end; def activate; puts 'activate'; end; end;
                            nil

                            t = MyTool.new
                            init
                            #MyTool:0x11752260
                            Sketchup.active_model.select_tool(t)
                            activate
                            #Sketchup::Model:0x11269cf8
                            Sketchup.active_model.select_tool( MyTool.new )
                            init
                            activate
                            #Sketchup::Model:0x11269cf8`

                            Thomas Thomassen — SketchUp Monkey & Coding addict
                            List of my plugins and link to the CookieWare fund

                            1 Reply Last reply Reply Quote 0
                            • thomthomT Offline
                              thomthom
                              last edited by

                              @unknownuser said:

                              @thomthom said:

                              Are you not seeing that behaviour?

                              When I have added the activate method to the posted sample, it does trigger, but the initialize() doesn't.
                              For some odd reason activate doesn't fire up in my own tool. I start both tools exactly in the same way:
                              @tool = Sketchup.active_model.select_tool ToolName.new

                              In your code:

                              
                              def initialize(web_dialog)
                                "Tool created."
                                @web_dialog=web_dialog
                              end
                              
                              

                              You're missing a puts.

                              Thomas Thomassen — SketchUp Monkey & Coding addict
                              List of my plugins and link to the CookieWare fund

                              1 Reply Last reply Reply Quote 0
                              • thomthomT Offline
                                thomthom
                                last edited by

                                
                                def onCancel(reason,view)
                                  @web_dialog.close
                                end
                                
                                

                                Do you need to close the webdialog here? It does not stop the Tool.

                                If the tool is a line tool for instance, and the user starts to draw a line:
                                Clicks once to set start point - then the tool enters a state where it expects the user to pick another. but if the user hit Escape this event is triggered with reason == 0 - and the tool should then reset itself. But the tool itself is not killed.

                                Thomas Thomassen — SketchUp Monkey & Coding addict
                                List of my plugins and link to the CookieWare fund

                                1 Reply Last reply Reply Quote 0
                                • thomthomT Offline
                                  thomthom
                                  last edited by

                                  @dlg.set_on_close { puts "Set on close fired." Sketchup.active_model.active_view.remove_observer ProperTool::get_view_observer Sketchup.active_model.select_tool(nil) }

                                  Regarding Sketchup.active_model.select_tool(nil) - that will activate SU's Select tool. I'd recommend that you instead use Sketchup.active_model.tools's push_tool and pop_tool so that when you deactivate your own tool it return to the previously selected tool (which might very likely not be the Select tool)

                                  Thomas Thomassen — SketchUp Monkey & Coding addict
                                  List of my plugins and link to the CookieWare fund

                                  1 Reply Last reply Reply Quote 0
                                  • T Offline
                                    tomasz
                                    last edited by

                                    @thomthom said:

                                    You're missing a puts.

                                    👊

                                    @thomthom said:

                                    
                                    > def onCancel(reason,view)
                                    >   @web_dialog.close
                                    > end
                                    > 
                                    

                                    Do you need to close the webdialog here? It does not stop the Tool.

                                    It is just a single stage tool. If an user presses escape I want to close the webdialog and deactivate.the_tool. Invoking @dlg.set_on_close {Sketchup.active_model.active_view.remove_observer ProperTool::get_view_observer; **Sketchup.active_model.select_tool(nil)**} will close the tool... and will trigger @web_dialog.close again. That is why it fires up twice.

                                    Author of [Thea Render for SketchUp](http://www.thearender.com/sketchup)

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

                                    Advertisement