• Login
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 5 Dec 2012, 14:26

    @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
    • T Offline
      thomthom
      last edited by 5 Dec 2012, 14:34

      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
      • T Offline
        thomthom
        last edited by 5 Dec 2012, 14:43

        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
        • T Offline
          thomthom
          last edited by 5 Dec 2012, 14:56

          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
          • T Offline
            thomthom
            last edited by 5 Dec 2012, 15:20

            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
            • T Offline
              thomthom
              last edited by 5 Dec 2012, 15:23

              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 5 Dec 2012, 16:19

                @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
                • T Offline
                  thomthom
                  last edited by 5 Dec 2012, 16:27

                  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
                  1 / 1
                  • First post
                    1/8
                    Last post
                  Buy SketchPlus
                  Buy SUbD
                  Buy WrapR
                  Buy eBook
                  Buy Modelur
                  Buy Vertex Tools
                  Buy SketchCuisine
                  Buy FormFonts

                  Advertisement