5 Replies Latest reply on Jun 8, 2010 10:22 AM by Bob Stucky

    Adding and removing application event listeners

    Harbs. Level 6

      I'm not 100% clear on how/when application event listeners are added and removed.

       

      If I add an event handler on creationComplete of a panel, what's the recommended way to make sure that the event handler is removed when the panel is closed?

       

      Is there a better way than creating the event handler on creationComplete?

       

      Is the event handler removed automatically?

       

      here's one example of what I'm talking about (I definitely don't want this event firing more than once!):

       

      IDScriptingEventAdapter.getInstance().addEventListenerToObject(com.adobe.indesign.Event.AFTER_SELECTION_CHANGED, updateMe, app);
      
      

       

      Harbs

        • 1. Re: Adding and removing application event listeners
          david_a_clark Adobe Employee

          I guess you're aware of this already, but the IDScriptingEventAdapter class simply provides an ActionScript wrapper over the ExtendScript functions for adding/removing event listeners.

          If I add an event handler on creationComplete of a panel, what's the recommended way to make sure that the event handler is removed when the panel is closed?

           

          ...

           

          Is the event handler removed automatically?

           

          Correct me if I'm misunderstanding, but I take this question to mean "If my extension adds a listener for event X through ID Host Adapter, then the extension window is closed, is the listener removed?"

           

          This isn't something I've tested. My guess would be yes - but I'd suggest you try it out yourself. For the avoidance of doubt, you could listen for the panel's "close" event. From the handler for that event, remove the ID event listener using IDScriptingEventAdapter.removeEventListenerFromObject(..).

           

          Is there a better way than creating the event handler on creationComplete?

          If you're aiming simply to register an ID event listener on extension startup, doing it in response to creationComplete is ideal.

           

          Thanks

          David.

          • 2. Re: Adding and removing application event listeners
            Harbs. Level 6

            david_clark_111 wrote:

             

            I guess you're aware of this already, but the IDScriptingEventAdapter class simply provides an ActionScript wrapper over the ExtendScript functions for adding/removing event listeners.

             

            Yup! It's Bob's work, right? Very nicely done!

             

            Actually, the fact that they are InDesign event handlers and not Flash ones is why I have the question whether they live through a panel close-open cycle. There's no Flash garbage collection involved here...

             

            Correct me if I'm misunderstanding, but I take this question to mean "If my extension adds a listener for event X through ID Host Adapter, then the extension window is closed, is the listener removed?"

             

            This isn't something I've tested. My guess would be yes - but I'd suggest you try it out yourself. For the avoidance of doubt, you could listen for the panel's "close" event. From the handler for that event, remove the ID event listener using IDScriptingEventAdapter.removeEventListenerFromObject(..).

             

            Yes. This is what I was asking. I know I could test myself, but I'm lazy, and I was hoping someone had a quick answer.

             

            What would remove the event handler? garbage collection? It couldn't be ActionScript garbage collection, because it's an InDesign event. Does InDesign garbage collection remove event handler pointing to actionscript functions?

             

            Part of my question is: if the evet handlers are not removed automatically, while they fire events against the panel when it's recreated? (It should still have the same id when it's re-created.) If yes, we'll wind up with multiple events firing in the same panel. That's no good...

             

            If you're aiming simply to register an ID event listener on extension  startup, doing it in response to creationComplete is ideal.

             

            Yes. But that assumes we will not get mutiple event handlers.If the event handlers survive the panel being reopening, it might be better to not remove the event handler, but instead add it only once.

             

             

            I guess I'd better do some testing...

             

             

            Harbs

            • 3. Re: Adding and removing application event listeners
              Bob Stucky Adobe Employee

              Harbs,

               

              I have not seen a problem with dangling event listeners causing multiple event handler firings.

               

              When the IDScriptingEventAdapter registers for an ID event, it creates an anonymous ES function as an event handler. Remember that the root host adapter allows you to pass objects both directions (AS->ES and ES->AS). The anonymous function (which is an ExtendScript function) contains references to the (ActionScript) IDScriptingEventAdapter - AND - the ActionScript handler method you passed. When the event fires, the AS handler method is passed back to the IDScriptingEventAdapter's "call" method. The call method simply invokes your AS handler.

               

              Here's what I *think* is happening:

               

              When your panel is destroyed, the AS side objects are destroyed. The event listener's anonymous function is very likely still called, it just doesn't point to anything (the anonymous function wraps everything in a try/catch and ignores any errors). When the panel is re-opened, the "old" event listeners are not pointing to the new instances of the objects in the re-opened panel.

               

              If the listeners are not removed between re-creations, assuming that I am correct, performance would be affected as the number of event listeners increase. I can run some tests on this to be absolutely certain. I would set my confidence level with the above synopsis at 95%.

               

              As for how to remove an event listener in ID -

               

              The IDScriptingEventAdapter add listener functions return an ActionScript-wrapped EventListener from ID's scripting DOM. That listener has a remove method.

               

              var listener: com.adobe.indesign.EventListener = IDScriptingEventAdapter.getInstance().addEventListenerToObject(...);

               

              To remove that listener:

               

              listener.remove();

               

              That will remove the ES side's event listener, the AS side is destroyed with the panel.

               

              Regards

               

              Bob

              • 4. Re: Adding and removing application event listeners
                Harbs. Level 6

                Hi Bob,

                 

                Your explanation is how I would think it would be working as well (although I didn't examine well enough what the ExtendScript handler function points to). Maybe there's a way to construct the ES function that if the AS object is not there, it removes the listener which called it?

                 

                Thanks

                Harbs

                • 5. Re: Adding and removing application event listeners
                  Bob Stucky Adobe Employee

                  Excellent thought. Have to figure a really slick way to do it as the anonymous function is created before the ID event listener. We'll have a look at it, and I'll log it as a bug/feature request.

                   

                  Thanks

                   

                  Bob