2 Replies Latest reply on Oct 11, 2017 11:03 PM by HughM

    "per-thread" variable scope question

    HughM Level 1

      I am writing a plugin where I want to apply develop settings on multiple photos.  I would like to do something like the following:

       

           local selectedPhotos = catalog:getTargetPhotos()

           for photo in selectedPhotos do

                catalog:withWriteAccessDo("My Apply Params", AutoCropApplyParams, {timeout = 10})

           end

       

      Then in the child function AutoCropApplyParams() I would like to refer to "photo" or other thread-specific variables.  The issue here is that withWriteAccessDo() and startAsyncTask() call the child function without any obvious way to pass parameters into the called function.  One option would be use global variables, but then it seems there would be a collision risk if two copies of a long-running plugin are invoked in parallel.  Is there a best practice to pass parameters that keeps any parallel calls to the plugin separated?

       

      In this specific case I guess I can call catalog:setSelectedPhotos() to select each photo 1-by-1.  But I'd prefer to understand the recommended practice here?  Unless I am misunderstanding how Lightroom handles multiple parallel calls to the same plugin and this is already covered somehow?

       

      This seems like a case where a language like C would use thread-local storage, but it's not clear what LUA recommends.

        • 1. Re: "per-thread" variable scope question
          johnrellis Most Valuable Participant

          The issue here is that withWriteAccessDo() ... call[s] the child function without any obvious way to pass parameters into the called function. 

          Use a closure:

           

          local selectedPhotos = catalog:getTargetPhotos ()
          for photo in selectedPhotos do
              catalog:withWriteAccessDo ("My Apply Params",
                  function () AutoCropApplyParams (photo) end,
                  {timeout = 10})
              end
          

           

          I recommend that you spend a couple of hours reading Programming in Lua, 2nd edition, especially if you haven't worked with languages like Lua and Scheme before. Our tendency is to dive right in and start hacking, learning along the way, which is often an effective tactic. But with Lua, I think most people who do this end up wasting many hours chasing bugs caused by an imperfect understanding of the language and its idioms.

          • 2. Re: "per-thread" variable scope question
            HughM Level 1

            Thanks.  For the record I did read the 1st edition of the Lua book at Programming in Lua (first edition) but I'd not seen the 2nd edition, or unfortunately the chapter on closures that is also in the 1st edition.

             

            Also for the record the for loop I posed in my example is incorrect; the correct working code needs ipairs (or another iterator):

             

            for key,photo in ipairs(selectedPhotos) do

                  -- catalog:setSelectedPhotos(photo, selectedPhotos)

                  catalog:withWriteAccessDo("Auto crop/rotate",

                      function() AutoCropApplyCropParams(photo) end,

                  {timeout = 10})

              end