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

    Using object ids to restore object instance references?

    Scheduled Pinned Locked Moved Developers' Forum
    8 Posts 2 Posters 1.8k 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.
    • M Offline
      Myhand
      last edited by Myhand

      @myhand said:

      Is there a reason I not just use the the material's object_id.to_s() as key and also as thumbnail file name etc. It seems unnecessary to concatenate with display_name and then hash, when object_id should be unique within one session...?

      I seem to have found the answer to this question the hard way... The object_id seem to expire after a while and I am getting "The object has been garbage collected" errors on a very large model when listing component definitions. It is all still in the same Sketchup session and all the component definitions are still in Sketchup, but somehow the id's you get from ComponentDefinition.object_id can no longer be used to lookup those objects with ObjectSpace._id2ref.

      Does anyone know of a good key to use to uniquely reference Materials and ComponentDefinitions which can later (in the same Sketchup session) be used to reference them again. I could use Entity.entityID but then would have to iterate over all materials or component definitions to find the instance again.

      http://www.keepingmyhandin.com/

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

        That's an interesting question I'd also like to know. Wasn't aware of ObjectSpace._id2ref .
        Too bad that didn't work. Strange though, that it's garbage collected even when the entity exist. That would somewhat indicate that the Ruby object isn't permanently linked to the entity. I guess the Ruby object exist only for as long as there is a reference to it.

        (Might this be worthy of a separate topic for general discussion?)

        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

          hmm...

          I tried to create a simple test case:

          Get selected face: face=sel[0]
          Get its id: id = face.object_id
          Dereference: face = nil
          Trigger GC: GC.start

          I'd then thought that I'd get the same error you got. But alas.

          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

            Here we go:

            Sample model: A Face and four edges

            <span class="syntaxdefault"><br />GC</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">start<br />nil<br /><br />ObjectSpace</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">each_object</span><span class="syntaxkeyword">(</span><span class="syntaxdefault">Sketchup</span><span class="syntaxkeyword">;;</span><span class="syntaxdefault">Edge</span><span class="syntaxkeyword">)&nbsp;{&nbsp;|</span><span class="syntaxdefault">e</span><span class="syntaxkeyword">|&nbsp;</span><span class="syntaxdefault">p&nbsp;e&nbsp;</span><span class="syntaxkeyword">}<br /></span><span class="syntaxdefault">0<br /></span>
            

            Lets fetch the ID of each edge:

            <span class="syntaxdefault"><br />ids&nbsp;</span><span class="syntaxkeyword">=&nbsp;</span><span class="syntaxdefault">model</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">entities</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">grep</span><span class="syntaxkeyword">(</span><span class="syntaxdefault">Sketchup</span><span class="syntaxkeyword">;;</span><span class="syntaxdefault">Edge</span><span class="syntaxkeyword">)&nbsp;{&nbsp;|</span><span class="syntaxdefault">e</span><span class="syntaxkeyword">|&nbsp;</span><span class="syntaxdefault">e</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">object_id&nbsp;</span><span class="syntaxkeyword">}<br />[</span><span class="syntaxdefault">141734820</span><span class="syntaxkeyword">,&nbsp;</span><span class="syntaxdefault">141734790</span><span class="syntaxkeyword">,&nbsp;</span><span class="syntaxdefault">141404510</span><span class="syntaxkeyword">,&nbsp;</span><span class="syntaxdefault">141734760</span><span class="syntaxkeyword">]<br />&nbsp;</span><span class="syntaxdefault"></span>
            

            When we then inspect ObjectSpace:

            <span class="syntaxdefault"><br />ids&nbsp;</span><span class="syntaxkeyword">=&nbsp;</span><span class="syntaxdefault">model</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">entities</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">grep</span><span class="syntaxkeyword">(</span><span class="syntaxdefault">Sketchup</span><span class="syntaxkeyword">;;</span><span class="syntaxdefault">Edge</span><span class="syntaxkeyword">)&nbsp;{&nbsp;|</span><span class="syntaxdefault">e</span><span class="syntaxkeyword">|&nbsp;</span><span class="syntaxdefault">e</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">object_id&nbsp;</span><span class="syntaxkeyword">}<br /></span><span class="syntaxdefault">ObjectSpace</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">each_object</span><span class="syntaxkeyword">(</span><span class="syntaxdefault">Sketchup</span><span class="syntaxkeyword">;;</span><span class="syntaxdefault">Edge</span><span class="syntaxkeyword">)&nbsp;{&nbsp;|</span><span class="syntaxdefault">e</span><span class="syntaxkeyword">|&nbsp;</span><span class="syntaxdefault">p&nbsp;e&nbsp;</span><span class="syntaxkeyword">}<br /></span><span class="syntaxcomment">#<Sketchup;;Edge;0x10db52bc><br />#<Sketchup;;Edge;0x10e566d0><br />#<Sketchup;;Edge;0x10e5670c><br />#<Sketchup;;Edge;0x10e56748><br /></span><span class="syntaxdefault">4<br /></span>
            

            If we then trigger the GC:

            <span class="syntaxdefault"><br />GC</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">start<br />nil<br /><br />edges&nbsp;</span><span class="syntaxkeyword">=&nbsp;</span><span class="syntaxdefault">ids</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">map&nbsp;</span><span class="syntaxkeyword">{&nbsp;|</span><span class="syntaxdefault">id</span><span class="syntaxkeyword">|&nbsp;</span><span class="syntaxdefault">ObjectSpace</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">_id2ref</span><span class="syntaxkeyword">(</span><span class="syntaxdefault">id</span><span class="syntaxkeyword">)&nbsp;}<br /></span><span class="syntaxdefault">Error</span><span class="syntaxkeyword">;&nbsp;</span><span class="syntaxcomment">#<RangeError;&nbsp;(eval);48;in&nbsp;`_id2ref';&nbsp;0x872b3a4&nbsp;is&nbsp;recycled&nbsp;object><br /></span><span class="syntaxkeyword">(eval);</span><span class="syntaxdefault">48<br /></span><span class="syntaxkeyword">(eval);</span><span class="syntaxdefault">48<br /></span><span class="syntaxkeyword">(eval);</span><span class="syntaxdefault">48</span><span class="syntaxkeyword">;</span><span class="syntaxdefault">in&nbsp;</span><span class="syntaxkeyword">`</span><span class="syntaxstring">map'<br />(eval);48<br /></span>
            

            Confirming my suspicion in my previous post.

            Let then try to keep the references to each edge in an array:

            <span class="syntaxdefault"><br />ids&nbsp;</span><span class="syntaxkeyword">=&nbsp;</span><span class="syntaxdefault">model</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">entities</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">grep</span><span class="syntaxkeyword">(</span><span class="syntaxdefault">Sketchup</span><span class="syntaxkeyword">;;</span><span class="syntaxdefault">Edge</span><span class="syntaxkeyword">)&nbsp;{&nbsp;|</span><span class="syntaxdefault">e</span><span class="syntaxkeyword">|&nbsp;</span><span class="syntaxdefault">e</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">object_id&nbsp;</span><span class="syntaxkeyword">}<br />[</span><span class="syntaxdefault">141626980</span><span class="syntaxkeyword">,&nbsp;</span><span class="syntaxdefault">141626950</span><span class="syntaxkeyword">,&nbsp;</span><span class="syntaxdefault">141404510</span><span class="syntaxkeyword">,&nbsp;</span><span class="syntaxdefault">141626920</span><span class="syntaxkeyword">]<br /><br /></span><span class="syntaxdefault">edges&nbsp;</span><span class="syntaxkeyword">=&nbsp;</span><span class="syntaxdefault">ids</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">map&nbsp;</span><span class="syntaxkeyword">{&nbsp;|</span><span class="syntaxdefault">id</span><span class="syntaxkeyword">|&nbsp;</span><span class="syntaxdefault">ObjectSpace</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">_id2ref</span><span class="syntaxkeyword">(</span><span class="syntaxdefault">id</span><span class="syntaxkeyword">)&nbsp;}<br />[</span><span class="syntaxcomment">#<Sketchup;;Edge;0x10e21cc8>,&nbsp;#<Sketchup;;Edge;0x10e21c8c>,&nbsp;#<Sketchup;;Edge;0x10db52bc>,&nbsp;#<Sketchup;;Edge;0x10e21c50>]<br /><br /></span><span class="syntaxdefault">GC</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">start<br />nil<br /><br />edges&nbsp;</span><span class="syntaxkeyword">=&nbsp;</span><span class="syntaxdefault">ids</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">map&nbsp;</span><span class="syntaxkeyword">{&nbsp;|</span><span class="syntaxdefault">id</span><span class="syntaxkeyword">|&nbsp;</span><span class="syntaxdefault">ObjectSpace</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">_id2ref</span><span class="syntaxkeyword">(</span><span class="syntaxdefault">id</span><span class="syntaxkeyword">)&nbsp;}<br />[</span><span class="syntaxcomment">#<Sketchup;;Edge;0x10e21cc8>,&nbsp;#<Sketchup;;Edge;0x10e21c8c>,&nbsp;#<Sketchup;;Edge;0x10db52bc>,&nbsp;#<Sketchup;;Edge;0x10e21c50>]<br />&nbsp;</span><span class="syntaxdefault"></span>
            

            Now the code worked - it survived the GC because we kept references to the Ruby objects pointing to the SketchUp entities.

            Now sure how viable or even safe it would be to keep a cache of all the entities you keep an object ID of. If you did try so, you could even keep your own hash with object_id's as keys. But you'd have to ensure to check the entities if they are erased. Then further more there's the challenge that an entity is erased, but then restored after and undo/redo.
            I see danger written all over this with memory leaks and stale references.

            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

              Another observation:

              <span class="syntaxdefault"><br />ids&nbsp;</span><span class="syntaxkeyword">=&nbsp;</span><span class="syntaxdefault">model</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">entities</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">grep</span><span class="syntaxkeyword">(</span><span class="syntaxdefault">Sketchup</span><span class="syntaxkeyword">;;</span><span class="syntaxdefault">Edge</span><span class="syntaxkeyword">)&nbsp;{&nbsp;|</span><span class="syntaxdefault">e</span><span class="syntaxkeyword">|&nbsp;</span><span class="syntaxdefault">e</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">object_id&nbsp;</span><span class="syntaxkeyword">}<br />[</span><span class="syntaxdefault">139751680</span><span class="syntaxkeyword">,&nbsp;</span><span class="syntaxdefault">139751650</span><span class="syntaxkeyword">,&nbsp;</span><span class="syntaxdefault">139751630</span><span class="syntaxkeyword">,&nbsp;</span><span class="syntaxdefault">139751610</span><span class="syntaxkeyword">]<br /><br /></span><span class="syntaxdefault">ObjectSpace</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">each_object</span><span class="syntaxkeyword">(</span><span class="syntaxdefault">Sketchup</span><span class="syntaxkeyword">;;</span><span class="syntaxdefault">Edge</span><span class="syntaxkeyword">)&nbsp;{&nbsp;|</span><span class="syntaxdefault">e</span><span class="syntaxkeyword">|&nbsp;</span><span class="syntaxdefault">p&nbsp;e&nbsp;</span><span class="syntaxkeyword">}<br /></span><span class="syntaxcomment">#<Sketchup;;Edge;0x10a8e174><br />#<Sketchup;;Edge;0x10a8e19c><br />#<Sketchup;;Edge;0x10a8e1c4><br />#<Sketchup;;Edge;0x10a8e200><br /></span><span class="syntaxdefault">4<br /><br />GC</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">start<br /><br />new_ids&nbsp;</span><span class="syntaxkeyword">=&nbsp;</span><span class="syntaxdefault">model</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">entities</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">grep</span><span class="syntaxkeyword">(</span><span class="syntaxdefault">Sketchup</span><span class="syntaxkeyword">;;</span><span class="syntaxdefault">Edge</span><span class="syntaxkeyword">)&nbsp;{&nbsp;|</span><span class="syntaxdefault">e</span><span class="syntaxkeyword">|&nbsp;</span><span class="syntaxdefault">e</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">object_id&nbsp;</span><span class="syntaxkeyword">}<br />[</span><span class="syntaxdefault">141455560</span><span class="syntaxkeyword">,&nbsp;</span><span class="syntaxdefault">141455530</span><span class="syntaxkeyword">,&nbsp;</span><span class="syntaxdefault">141455510</span><span class="syntaxkeyword">,&nbsp;</span><span class="syntaxdefault">141455490</span><span class="syntaxkeyword">]<br /><br /></span><span class="syntaxdefault">edges&nbsp;</span><span class="syntaxkeyword">=&nbsp;</span><span class="syntaxdefault">new_ids</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">map&nbsp;</span><span class="syntaxkeyword">{&nbsp;|</span><span class="syntaxdefault">id</span><span class="syntaxkeyword">|&nbsp;</span><span class="syntaxdefault">ObjectSpace</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">_id2ref</span><span class="syntaxkeyword">(</span><span class="syntaxdefault">id</span><span class="syntaxkeyword">)&nbsp;}<br />[</span><span class="syntaxcomment">#<Sketchup;;Edge;0x10dce190>,&nbsp;#<Sketchup;;Edge;0x10dce154>,&nbsp;#<Sketchup;;Edge;0x10dce12c>,&nbsp;#<Sketchup;;Edge;0x10dce104>]<br />&nbsp;</span><span class="syntaxdefault"></span>
              

              Notice that after the Ruby object has been GC's and you then again request new references it's all new object instances.

              It does seem like that SketchUp will ensure there is only ever one Ruby object per entity - so as long as anything is holding on to the reference to an entity SketchUp will reuse this. But once garbage collected it'll generate a new one when needed.

              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

                There are times when I wished I could extend just an instance reference to an entity, but I found that if I made changes to that instance, by adding a method or whatnot - it would also come over into any other plugin that referenced that entity.

                Now I see that it's because SketchUp recycles the Ruby objects. Wish there was a way to decouple this - so I could get a unique ruby reference which I could mess with as much as I'd like.

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

                1 Reply Last reply Reply Quote 0
                • M Offline
                  Myhand
                  last edited by

                  @thomthom said:

                  Notice that after the Ruby object has been GC's and you then again request new references it's all new object instances.

                  It does seem like that SketchUp will ensure there is only ever one Ruby object per entity - so as long as anything is holding on to the reference to an entity SketchUp will reuse this. But once garbage collected it'll generate a new one when needed.

                  Very good detective work! 👍 Come to think of it I have seen similar behavior in JNI (Java Native Interface) where Java will garbage collect references to "proxy objects" when there are no longer java side references. This is because the C++ objects are not managed code running in a VM, and therefore Java does not have access the C++ object lifecycle (without custom hooks added on the C++ side).

                  http://www.keepingmyhandin.com/

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

                    Yea. Remember that the Ruby API was added in version 4 - it's on top of the C++ core 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
                    • 1 / 1
                    • First post
                      Last post
                    Buy SketchPlus
                    Buy SUbD
                    Buy WrapR
                    Buy eBook
                    Buy Modelur
                    Buy Vertex Tools
                    Buy SketchCuisine
                    Buy FormFonts

                    Advertisement