• Login
sketchucation logo sketchucation
  • Login
⚠️ Libfredo 15.4b | Minor release with bugfixes and improvements Update

EntitiesObserver and Attributes - work around

Scheduled Pinned Locked Moved Developers' Forum
21 Posts 3 Posters 2.5k Views 3 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.
  • R Offline
    rvs1977
    last edited by 31 Jul 2012, 12:07

    Hi!
    Im trying to figure out how to use the add_observer method on the entities in a group, and saw TTs list (url below)
    http://www.thomthom.net/software/sketchup/observers/#ViewObserver

    Here my worst nightmare came through... The Sketchup::EntitiesObserver - onElementModified(entities, entity) dont work. Just as I had experienced myself.

    What I try to accomplish (see the code below), is to keep track of the area of a specific face, named yv_face_area (green color). Initially I have set an attribute to the rsgroup (which contains the yv_face_area) set_attribute("rsdict, "area", area). It seems to work fine.

    But, as mentioned, the onElementModified method dont seems to work.

    Anyone haves an idea how to work around this problem?

    snippet:

    
    mod = Sketchup.active_model # Open model
    ent = mod.entities # All entities in model
    sel = mod.selection # Current selection
    
    class MyEntityObserver < Sketchup;;EntityObserver        
        def onEraseEntity(entity) #this work        
            UI.messagebox("onEraseEntity; " + entity.to_s)        
        end  
    end #class
    
    class MyEntitiesObserver < Sketchup;;EntitiesObserver        
        def onElementModified(entities, entity) #dont seems to work    
            UI.messagebox("onElementModified; " + entity.to_s)  
        end
        def onEraseEntities(entities) #this seems to work    
             UI.messagebox("onEraseEntities; " + entities.to_s)  
        end
        def onElementRemoved(entities, entity_id) #dont seems to work    
            UI.messagebox("onElementRemoved; " + entity_id)  
        end
        def onElementAdded(entities, entity) #this seems to work   
            UI.messagebox("onElementAdded; " + entity.to_s)  
        end
    end #class
    
    pts = []
    
    pts[0] = [ 0, 0, 0]
    pts[1] = [ 1000.mm, 0, 0]
    pts[2] = [ 1000.mm, 1000.mm, 0]
    pts[3] = [ 0, 1000.mm, 0]
    
    pts[4] = [ 0, 0, 1000.mm]
    pts[5] = [ 1000.mm, 0, 1000.mm]
    pts[6] = [ 1000.mm, 1000.mm, 1000.mm]
    pts[7] = [ 0, 1000.mm, 1000.mm]
    
    5.times do |i|
        rsgroup = ent.add_group
        
        rsgroup.entities.add_face pts[0..3]
        yv_face_height = rsgroup.entities.add_face pts[4..7]
        rsgroup.entities.add_face pts[0], pts[3], pts[7], pts[4]
        rsgroup.entities.add_face pts[3], pts[2], pts[6], pts[7]
        rsgroup.entities.add_face pts[1], pts[2], pts[6], pts[5]
        yv_face_area = rsgroup.entities.add_face pts[0], pts[1], pts[5], pts[4]
        
        yv_face_height.pushpull rand(1000.mm)
        yv_area = yv_face_area.area.to_m.to_m
        yv_face_area.material = (0xAADEAA)    
        rsgroup.set_attribute "rsdict","area", yv_area
        yv_face_area.set_attribute "rsdict", "area2", yv_area
            
        point = Geom;;Point3d.new (1100.mm * i, 0, 0)
        t = Geom;;Transformation.new point
        rsgroup.transform! t
        
        rsgroup.add_observer(MyEntityObserver.new)
        rsgroup.entities.add_observer(MyEntitiesObserver.new)
        
        
    end #times_do
    
    ent.each do |o|
        point = Geom;;Point3d.new (0, 1100.mm, 0)
        t = Geom;;Transformation.new point
        o.transform! t
    end #each_do 
    
    i = 0
    ent.each do |o|
        attr = o.get_attribute "rsdict","area" 
    
        if attr        
            UI.messagebox "Attr - Area; " + attr.to_s + " m² - n; " + i.to_s       
            i = i + 1
        end
    end
    
    

    Get a Ruby

    1 Reply Last reply Reply Quote 0
    • T Offline
      thomthom
      last edited by 31 Jul 2012, 12:39

      http://www.thomthom.net/software/sketchup/observers/#EntitiesObserver
      Here I noted that EntitiesObserver.onElementModified is working in SU8...

      btw - what are you planning to do on the event? Make model changes? I found that can often mess up other scripts or even crash SketchUp.

      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
        thomthom
        last edited by 31 Jul 2012, 12:40

        Also, when testing observer I don't use messageboxes as the silly manual does. If the observer trigger many events you'll be stuck with clicking messageboxes. I prefer to use puts - or even win Win32API to output to DebugView.

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

        1 Reply Last reply Reply Quote 0
        • R Offline
          rvs1977
          last edited by 31 Jul 2012, 17:49

          When a wall is resized I want the walls area-attribute to update. Thats basically what Im trying to do.

          Great to know that SU8 might work.

          About using put, I dont know how to use it? Is it possible to use it with Alex Screyers Ruby Editor? I have tried without any output. Im interested to know more about Win32Api. Is it something I need to download?


          Get a Ruby

          1 Reply Last reply Reply Quote 0
          • Dan RathbunD Offline
            Dan Rathbun
            last edited by 31 Jul 2012, 19:27

            It is is puts, not "put". (It is short for "put string".)

            puts() outputs to STDOUT so you must have some console open before you call it. You can use the built-in Ruby Console that comes with SketchUp, from the Window menu. (Or you can use also Alex's WebConsole. It is your choice.)

            You do not need to worry about the Win32API, or win32-api libraries, at this time. (Using them is at the advanced level.)

            If you are developing plugins, you should be using the latest version of SU 8, not 7. (You can still have 7 installed if you need to import/export DWG files. But that is really all you should be using 7 for.)

            I'm not here much anymore.

            1 Reply Last reply Reply Quote 0
            • R Offline
              rvs1977
              last edited by 31 Jul 2012, 20:28

              Next problem:

              When deleting a group, and undoing - it looses all the observers. 👎
              Well, have to look at that tomorrow.

              Luckily it keeps the attributes as far as I can see...

              Dan, ok I stay away from win32api for a while 😄


              Get a Ruby

              1 Reply Last reply Reply Quote 0
              • R Offline
                rvs1977
                last edited by 1 Aug 2012, 16:38

                Think I found a usable solution to this problem:
                (It only works in SU8+)

                1. Add EntitiesObserver to each Entity with the attributes("rsdict","area")
                2. Keep the EntitiesObservers when undoing a deleted group
                3. Keep the EntitiesObservers when copying a group.
                4. Add EntitiesOberservers to each group with the attributes ("rsdict", "area")

                The solution seems to be simple: - Every time something happens (like undo or change, etc.) the executed observer iterates through each entity and, in my case, when it finds an entity with the attributes ("rsdict", "area") it simply add_observer(MyEntitiesObserver.new).

                It can be testet with the two pieces of codes below.
                In this example it messures the area of the green face, when you pushpull the red face at the top.

                In the first codepiece it draws some boxes and adds some attributes, but dont add any observers. Try to run the code a few times so it will produce a number of boxes.

                
                mod = Sketchup.active_model # Open model
                ent = mod.entities # All entities in model
                sel = mod.selection # Current selection
                
                pts = []
                
                pts[0] = [ 0, 0, 0]
                pts[1] = [ 1000.mm, 0, 0]
                pts[2] = [ 1000.mm, 1000.mm, 0]
                pts[3] = [ 0, 1000.mm, 0]
                
                pts[4] = [ 0, 0, 1000.mm]
                pts[5] = [ 1000.mm, 0, 1000.mm]
                pts[6] = [ 1000.mm, 1000.mm, 1000.mm]
                pts[7] = [ 0, 1000.mm, 1000.mm]
                
                10.times do |i|
                    rsgroup = ent.add_group
                    
                    rsgroup.entities.add_face pts[0..3]
                    yv_face_height = rsgroup.entities.add_face pts[4..7]
                    rsgroup.entities.add_face pts[0], pts[3], pts[7], pts[4]
                    rsgroup.entities.add_face pts[3], pts[2], pts[6], pts[7]
                    yv_face_length = rsgroup.entities.add_face pts[1], pts[2], pts[6], pts[5]
                    yv_face_area = rsgroup.entities.add_face pts[0], pts[1], pts[5], pts[4]
                    
                    yv_face_height.pushpull rand(1000.mm)
                    yv_area = yv_face_area.area.to_m.to_m
                    yv_face_area.material = (0xAADEAA) #green
                    yv_face_height.material =(0x8811FF) #red
                    rsgroup.set_attribute "rsdict","area", yv_area
                    yv_face_area.set_attribute "rsdict", "yv_face_area", yv_area
                    yv_face_length.set_attribute "rsdict", "yv_face_length" , 0
                    yv_face_height.set_attribute "rsdict", "yv_face_height", 0
                        
                    point = Geom;;Point3d.new (1100.mm * i, 0, 0)
                    t = Geom;;Transformation.new point
                    rsgroup.transform! t
                       
                    
                end #times_do
                
                ent.each do |o|
                    point = Geom;;Point3d.new (0, 1100.mm, 0)
                    t = Geom;;Transformation.new point
                    o.transform! t
                end #each_do 
                
                

                Second piece of code: - Here it add the observers. Every time the code is executed it will asign the observers. And it seems like it doesnt matter how many times you do it.There will only be one observer for each entity.

                
                mod = Sketchup.active_model # Open model
                ent = mod.entities # All entities in model
                sel = mod.selection # Current selection
                
                class MyModelObserver < Sketchup;;ModelObserver
                    def onTransactionUndo(model)    
                        #UI.messagebox("onTransactionUndo; " + model.to_s)
                        Sketchup.active_model.entities.each do |o|
                            attr = o.get_attribute "rsdict","area"
                    
                            if attr  
                                o.add_observer(MyEntityObserver.new)    
                                o.entities.add_observer(MyEntitiesObserver.new)                
                            end
                        end        
                    end    
                end #MyModelObserver
                #Adding ModelObserver - Undo
                Sketchup.active_model.add_observer(MyModelObserver.new)
                
                class MyEntityObserver < Sketchup;;EntityObserver        
                    #def onEraseEntity(entity) #this work        
                        #UI.messagebox("onEraseEntity; " + entity.to_s)        
                    #end
                    
                    #def onChangeEntity(entity)    
                        #UI.messagebox("onChangeEntity; " + entity.to_s)
                    #end
                end #class
                
                class MyEntitiesObserver < Sketchup;;EntitiesObserver        
                    def onElementModified(entities, entity)    
                        attr_length = entity.get_attribute "rsdict", "yv_face_length"
                        attr_height = entity.get_attribute "rsdict", "yv_face_height"       
                		
                		if attr_length           
                            entities.each do |i|
                                attr_area = i.get_attribute "rsdict", "yv_face_area"
                                
                                if attr_area
                                    yv_area_new = i.area.to_m.to_m
                                    #UI.messagebox "Length changed - area before; " + attr_area.to_s + " m² - area after; " + yv_area_new.to_s + " m²"                    
                                    i.set_attribute "rsdict", "yv_face_area", yv_area_new
                                end #attr_area
                            end #each do
                        end #if attr_length
                        
                		
                        if attr_height            
                            entities.each do |i|
                                attr_area = i.get_attribute "rsdict", "yv_face_area"
                                
                                if attr_area
                                    yv_area_new = i.area.to_m.to_m
                                    UI.messagebox "Height changed - green face - area before; " + attr_area.to_s + " m² - area after; " + yv_area_new.to_s + " m²"                    
                                    i.set_attribute "rsdict", "yv_face_area", yv_area_new
                                end #attr_area
                            end #each do
                        end #if attr_height
                        
                    end #onElementModified_end   
                end #class
                
                i = 0
                ent.each do |o|
                    attr = o.get_attribute "rsdict","area"
                    
                    if attr  
                        o.add_observer(MyEntityObserver.new)    
                        o.entities.add_observer(MyEntitiesObserver.new)
                        i += 1
                    end
                end
                
                UI.messagebox "number of boxes; " + i.to_s
                
                
                

                Get a Ruby

                1 Reply Last reply Reply Quote 0
                • T Offline
                  thomthom
                  last edited by 1 Aug 2012, 17:06

                  There is still the problem that you modify the model on observer events. When you do that you interfer with any operation that is going on - which might be in the middle of a start/commit operation of another plugin or native tool. You'll be adding to the Undo stack - causing unexpected behaviour when the user expects to undo their last operation but instead the undo is your injected attribute change.
                  Model change at observer events may cause bug splats.

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

                  1 Reply Last reply Reply Quote 0
                  • R Offline
                    rvs1977
                    last edited by 1 Aug 2012, 18:54

                    @thomthom said:

                    There is still the problem that you modify the model on observer events. When you do that you interfer with any operation that is going on - which might be in the middle of a start/commit operation of another plugin or native tool. You'll be adding to the Undo stack - causing unexpected behaviour when the user expects to undo their last operation but instead the undo is your injected attribute change.
                    Model change at observer events may cause bug splats.

                    Im not sure how to do it yet, but I think a solution could be to remove the observers, when editing the group, and adding the observer again when finished.

                    It seems to be very quick to add observers to ALL the entities in the model, and its not possible to add more than one observer to each entity, so you dont have to take care if the entity allready has got one.


                    Get a Ruby

                    1 Reply Last reply Reply Quote 0
                    • T Offline
                      thomthom
                      last edited by 2 Aug 2012, 07:31

                      @rvs1977 said:

                      It seems to be very quick to add observers to ALL the entities in the model

                      Strongly recommend you use observers sparsely. Also what you do within the events. Some events trigger many times a second - and that mean you can easily bog down SketchUp.

                      @rvs1977 said:

                      and its not possible to add more than one observer to each entity, so you dont have to take care if the entity allready has got one.

                      Yes you can add more than one observer.

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

                      1 Reply Last reply Reply Quote 0
                      • R Offline
                        rvs1977
                        last edited by 2 Aug 2012, 09:09

                        @rvs1977 said:

                        and its not possible to add more than one observer to each entity, so you dont have to take care if the entity allready has got one.

                        @thomthom said:

                        Yes you can add more than one observer.

                        What I meant was, if you do like this:
                        (adding 3 identical observers to one entity)
                        Code:
                        [....]
                        mygroup.entities.add_observer(myEntitiesObserver.new)
                        mygroup.entities.add_observer(myEntitiesObserver.new)
                        mygroup.entities.add_observer(myEntitiesObserver.new)
                        [....]

                        it will only have one myEntitesObserver attached to mygroup. - not three. That means its easier to handle... You dont need to check if its allready added, its faster just to add new one to every entities.

                        Yes you can add more observers to one entity eg. MyEntitiesObserverWatchFaces and MyEntitiesObserverWatchEdges


                        Get a Ruby

                        1 Reply Last reply Reply Quote 0
                        • T Offline
                          thomthom
                          last edited by 2 Aug 2012, 09:22

                          Not correct. For each new instance of your observer class you attach you add an observer:
                          ObserverInstances.png
                          Here I first drew one line. Then added another observer. When I draw a second line I get two observer triggering - and they are both of the same class.

                          However, if you attach the same instance of your observer to the same element, then it's no extra observers added:
                          ObserverSameInstance.png
                          Here I only ever get one observer triggering - because I'd only ever attached a single instance.

                          I store the reference to the observers I use. Then I remove it - just to be sure.

                          ` @entities_observer = myEntitiesObserver.new

                          def self.observers
                          mygroup.entities.remove_observer( @entities_observer )
                          mygroup.entities.add_observer( @entities_observer )
                          end`

                          Just to be sure

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

                          1 Reply Last reply Reply Quote 0
                          • R Offline
                            rvs1977
                            last edited by 2 Aug 2012, 09:53

                            @thomthom said:

                            Not correct. For each new instance of your observer class you attach you add an observer

                            Ok, maybe you are right, but to me it seems like it only triggers once, even though I have attached it many times in a row.

                            Could it be that it is overwritten each time its attached?! As far as I can see its not possible to see which observers is added in the model.

                            If you try the code I have attached above you can what I mean...
                            (Run the first code a couple of times to get some boxes without observers, then run the second code as many times you want, and the observers only triggers once)


                            Get a Ruby

                            1 Reply Last reply Reply Quote 0
                            • T Offline
                              thomthom
                              last edited by 2 Aug 2012, 10:48

                              @rvs1977 said:

                              Could it be that it is overwritten each time its attached?!

                              If you attach the same instance. But if you do like in my second example, you keep a reference to an instance and use that reference when you attach observers it won't create duplicates.

                              @rvs1977 said:

                              As far as I can see its not possible to see which observers is added in the model.

                              Correct, there isn't.

                              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
                                thomthom
                                last edited by 2 Aug 2012, 10:57

                                @rvs1977 said:

                                If you try the code I have attached above you can what I mean...
                                (Run the first code a couple of times to get some boxes without observers, then run the second code as many times you want, and the observers only triggers once)

                                Got a sample model with "Boxes"?
                                What do you do to trigger the events?

                                Btw - you know that model.entities isn't all the entities in the model? It's just the root context. The rest of the entities is inside Groups, Components and Image entities.
                                http://www.thomthom.net/thoughts/2012/02/definitions-and-instances-in-sketchup/

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

                                1 Reply Last reply Reply Quote 0
                                • R Offline
                                  rvs1977
                                  last edited by 2 Aug 2012, 11:18

                                  @thomthom said:

                                  Got a sample model with "Boxes"?
                                  What do you do to trigger the events?

                                  In post number 7 in this thread there are two pieces of codes attached...
                                  The 1. piece of code draw boxes without observers, the 2. piece of code add observers to the boxes.
                                  When you have deleted a box, try to undo, and it attaches new observers in a way that it solves the problem with lost observers.

                                  It triggers when the red face is modified (push/pulled) using the def onElementModified(entities, entity) in the "MyEntitesObserver", and it messure the area of the green face.


                                  Get a Ruby

                                  1 Reply Last reply Reply Quote 0
                                  • T Offline
                                    thomthom
                                    last edited by 2 Aug 2012, 11:40

                                    Ok - seeing it now. Still trying to work out the code flow.

                                    But you still have the issue with setting observers adds to the Undo stack.
                                    So when you push pull - the observer triggers and add an event to the Undo stack. So when the user press undo after push/pull he first undo the attribute change - then he has to undo again to undo the push pull.
                                    If the user undo just one - he will have undone the attribute change, but not the push-pull - making your data invalid. Also, the user is likely to become frustrated that Undo is working unpredictably.

                                    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
                                      thomthom
                                      last edited by 2 Aug 2012, 11:46

                                      Worked out why your observer triggered only once:
                                      The set_attribute call short-circuited the other events. When I commented out set_attribute and also changed the UI::Messagebox to this:
                                      puts "#{self} - Height changed - green face - area before: " + attr_area.to_s + " m² - area after: " + yv_area_new.to_s + " m²"
                                      You will then see that all the MyEntitiesObserver.new adds new observers - and doesn't remove the old ones. You'll see it output events for each instance you created. It was just your model change that prevented the events to propagate.

                                      <span class="syntaxdefault"><br />&nbsp;&nbsp;&nbsp;&nbsp;mod&nbsp;</span><span class="syntaxkeyword">=&nbsp;</span><span class="syntaxdefault">Sketchup</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">active_model&nbsp;</span><span class="syntaxcomment">#&nbsp;Open&nbsp;model<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="syntaxdefault">ent&nbsp;</span><span class="syntaxkeyword">=&nbsp;</span><span class="syntaxdefault">mod</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">entities&nbsp;</span><span class="syntaxcomment">#&nbsp;All&nbsp;entities&nbsp;in&nbsp;model<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="syntaxdefault">sel&nbsp;</span><span class="syntaxkeyword">=&nbsp;</span><span class="syntaxdefault">mod</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">selection&nbsp;</span><span class="syntaxcomment">#&nbsp;Current&nbsp;selection<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="syntaxkeyword">class&nbsp;</span><span class="syntaxdefault">MyModelObserver&nbsp;</span><span class="syntaxkeyword"><&nbsp;</span><span class="syntaxdefault">Sketchup</span><span class="syntaxkeyword">;;</span><span class="syntaxdefault">ModelObserver<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;def&nbsp;onTransactionUndo</span><span class="syntaxkeyword">(</span><span class="syntaxdefault">model</span><span class="syntaxkeyword">)&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="syntaxcomment">#UI.messagebox("onTransactionUndo;&nbsp;"&nbsp;+&nbsp;model.to_s)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="syntaxdefault">Sketchup</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">active_model</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">entities</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">each&nbsp;</span><span class="syntaxkeyword">do&nbsp;|</span><span class="syntaxdefault">o</span><span class="syntaxkeyword">|<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="syntaxdefault">attr&nbsp;</span><span class="syntaxkeyword">=&nbsp;</span><span class="syntaxdefault">o</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">get_attribute&nbsp;</span><span class="syntaxstring">"rsdict"</span><span class="syntaxkeyword">,</span><span class="syntaxstring">"area"<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="syntaxkeyword">if&nbsp;</span><span class="syntaxdefault">attr&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;o</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">add_observer</span><span class="syntaxkeyword">(</span><span class="syntaxdefault">MyEntityObserver</span><span class="syntaxkeyword">.new)&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="syntaxdefault">o</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">entities</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">add_observer</span><span class="syntaxkeyword">(</span><span class="syntaxdefault">MyEntitiesObserver</span><span class="syntaxkeyword">.new)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="syntaxdefault">end<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;end&nbsp;</span><span class="syntaxcomment">#MyModelObserver<br />&nbsp;&nbsp;&nbsp;&nbsp;#Adding&nbsp;ModelObserver&nbsp;-&nbsp;Undo<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="syntaxdefault">Sketchup</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">active_model</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">add_observer</span><span class="syntaxkeyword">(</span><span class="syntaxdefault">MyModelObserver</span><span class="syntaxkeyword">.new)<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;class&nbsp;</span><span class="syntaxdefault">MyEntityObserver&nbsp;</span><span class="syntaxkeyword"><&nbsp;</span><span class="syntaxdefault">Sketchup</span><span class="syntaxkeyword">;;</span><span class="syntaxdefault">EntityObserver&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="syntaxcomment">#def&nbsp;onEraseEntity(entity)&nbsp;#this&nbsp;work&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#UI.messagebox("onEraseEntity;&nbsp;"&nbsp;+&nbsp;entity.to_s)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#end<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#def&nbsp;onChangeEntity(entity)&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#UI.messagebox("onChangeEntity;&nbsp;"&nbsp;+&nbsp;entity.to_s)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#end<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="syntaxdefault">end&nbsp;</span><span class="syntaxcomment">#class<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="syntaxkeyword">class&nbsp;</span><span class="syntaxdefault">MyEntitiesObserver&nbsp;</span><span class="syntaxkeyword"><&nbsp;</span><span class="syntaxdefault">Sketchup</span><span class="syntaxkeyword">;;</span><span class="syntaxdefault">EntitiesObserver&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;def&nbsp;onElementModified</span><span class="syntaxkeyword">(</span><span class="syntaxdefault">entities</span><span class="syntaxkeyword">,&nbsp;</span><span class="syntaxdefault">entity</span><span class="syntaxkeyword">)&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="syntaxdefault">attr_length&nbsp;</span><span class="syntaxkeyword">=&nbsp;</span><span class="syntaxdefault">entity</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">get_attribute&nbsp;</span><span class="syntaxstring">"rsdict"</span><span class="syntaxkeyword">,&nbsp;</span><span class="syntaxstring">"yv_face_length"<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="syntaxdefault">attr_height&nbsp;</span><span class="syntaxkeyword">=&nbsp;</span><span class="syntaxdefault">entity</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">get_attribute&nbsp;</span><span class="syntaxstring">"rsdict"</span><span class="syntaxkeyword">,&nbsp;</span><span class="syntaxstring">"yv_face_height"&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="syntaxkeyword">if&nbsp;</span><span class="syntaxdefault">attr_length&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;entities</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">each&nbsp;</span><span class="syntaxkeyword">do&nbsp;|</span><span class="syntaxdefault">i</span><span class="syntaxkeyword">|<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="syntaxdefault">attr_area&nbsp;</span><span class="syntaxkeyword">=&nbsp;</span><span class="syntaxdefault">i</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">get_attribute&nbsp;</span><span class="syntaxstring">"rsdict"</span><span class="syntaxkeyword">,&nbsp;</span><span class="syntaxstring">"yv_face_area"<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="syntaxkeyword">if&nbsp;</span><span class="syntaxdefault">attr_area<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;yv_area_new&nbsp;</span><span class="syntaxkeyword">=&nbsp;</span><span class="syntaxdefault">i</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">area</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">to_m</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">to_m<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="syntaxcomment">#UI.messagebox&nbsp;"Length&nbsp;changed&nbsp;-&nbsp;area&nbsp;before;&nbsp;"&nbsp;+&nbsp;attr_area.to_s&nbsp;+&nbsp;"&nbsp;m²&nbsp;-&nbsp;area&nbsp;after;&nbsp;"&nbsp;+&nbsp;yv_area_new.to_s&nbsp;+&nbsp;"&nbsp;m²"&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#i.set_attribute&nbsp;"rsdict",&nbsp;"yv_face_area",&nbsp;yv_area_new<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="syntaxdefault">end&nbsp;</span><span class="syntaxcomment">#attr_area<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="syntaxdefault">end&nbsp;</span><span class="syntaxcomment">#each&nbsp;do<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="syntaxdefault">end&nbsp;</span><span class="syntaxcomment">#if&nbsp;attr_length<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="syntaxkeyword">if&nbsp;</span><span class="syntaxdefault">attr_height&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;entities</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">each&nbsp;</span><span class="syntaxkeyword">do&nbsp;|</span><span class="syntaxdefault">i</span><span class="syntaxkeyword">|<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="syntaxdefault">attr_area&nbsp;</span><span class="syntaxkeyword">=&nbsp;</span><span class="syntaxdefault">i</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">get_attribute&nbsp;</span><span class="syntaxstring">"rsdict"</span><span class="syntaxkeyword">,&nbsp;</span><span class="syntaxstring">"yv_face_area"<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="syntaxkeyword">if&nbsp;</span><span class="syntaxdefault">attr_area<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;yv_area_new&nbsp;</span><span class="syntaxkeyword">=&nbsp;</span><span class="syntaxdefault">i</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">area</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">to_m</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">to_m<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;puts&nbsp;</span><span class="syntaxstring">"#{self}&nbsp;-&nbsp;Height&nbsp;changed&nbsp;-&nbsp;green&nbsp;face&nbsp;-&nbsp;area&nbsp;before;&nbsp;"&nbsp;</span><span class="syntaxkeyword">+&nbsp;</span><span class="syntaxdefault">attr_area</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">to_s&nbsp;</span><span class="syntaxkeyword">+&nbsp;</span><span class="syntaxstring">"&nbsp;m²&nbsp;-&nbsp;area&nbsp;after;&nbsp;"&nbsp;</span><span class="syntaxkeyword">+&nbsp;</span><span class="syntaxdefault">yv_area_new</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">to_s&nbsp;</span><span class="syntaxkeyword">+&nbsp;</span><span class="syntaxstring">"&nbsp;m²"&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="syntaxcomment">#i.set_attribute&nbsp;"rsdict",&nbsp;"yv_face_area",&nbsp;yv_area_new<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="syntaxdefault">end&nbsp;</span><span class="syntaxcomment">#attr_area<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="syntaxdefault">end&nbsp;</span><span class="syntaxcomment">#each&nbsp;do<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="syntaxdefault">end&nbsp;</span><span class="syntaxcomment">#if&nbsp;attr_height<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="syntaxdefault">end&nbsp;</span><span class="syntaxcomment">#onElementModified_end&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="syntaxdefault">end&nbsp;</span><span class="syntaxcomment">#class<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="syntaxdefault">i&nbsp;</span><span class="syntaxkeyword">=&nbsp;</span><span class="syntaxdefault">0<br />&nbsp;&nbsp;&nbsp;&nbsp;ent</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">each&nbsp;</span><span class="syntaxkeyword">do&nbsp;|</span><span class="syntaxdefault">o</span><span class="syntaxkeyword">|<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="syntaxdefault">attr&nbsp;</span><span class="syntaxkeyword">=&nbsp;</span><span class="syntaxdefault">o</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">get_attribute&nbsp;</span><span class="syntaxstring">"rsdict"</span><span class="syntaxkeyword">,</span><span class="syntaxstring">"area"<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="syntaxkeyword">if&nbsp;</span><span class="syntaxdefault">attr&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;o</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">add_observer</span><span class="syntaxkeyword">(</span><span class="syntaxdefault">MyEntityObserver</span><span class="syntaxkeyword">.new)&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="syntaxdefault">o</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">entities</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">add_observer</span><span class="syntaxkeyword">(</span><span class="syntaxdefault">MyEntitiesObserver</span><span class="syntaxkeyword">.new)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="syntaxdefault">i&nbsp;</span><span class="syntaxkeyword">+=&nbsp;</span><span class="syntaxdefault">1<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end<br />&nbsp;&nbsp;&nbsp;&nbsp;end<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;UI</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">messagebox&nbsp;</span><span class="syntaxstring">"number&nbsp;of&nbsp;boxes;&nbsp;"&nbsp;</span><span class="syntaxkeyword">+&nbsp;</span><span class="syntaxdefault">i</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">to_s<br /></span>
                                      

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

                                      1 Reply Last reply Reply Quote 0
                                      • R Offline
                                        rvs1977
                                        last edited by 2 Aug 2012, 12:28

                                        I'm not sure how to do these tests.

                                        Are you saying if I pushpull one red face, it triggers events for every instance?? (If there is 200 boxes it triggers 200 times?) (box=instance)

                                        Or will it trigger the number of times, you have runned the script which adds observers? (instance = observer added)
                                        (Because in my case it only shows the UI.messagebox once)


                                        Get a Ruby

                                        1 Reply Last reply Reply Quote 0
                                        • T Offline
                                          thomthom
                                          last edited by 2 Aug 2012, 12:44

                                          @rvs1977 said:

                                          Or will it trigger the number of times, you have runned the script which adds observers? (instance = observer added)
                                          (Because in my case it only shows the UI.messagebox once)

                                          As describe above - in your case it triggers only once because when you modify the model with set_attribute it blocks all the other observers attached. Comment out the set_attribute code and you'll see all the observers you added will trigger.
                                          And then it's the issue with the Undo stack which I also mentioned.

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

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

                                          Advertisement