Skip to main content
Inspiring
November 18, 2009
Answered

StatusChangeEvent.INLINE_GRAPHIC_STATUS_CHANGE unexpectedly fired within composeToPosition()

  • November 18, 2009
  • 1 reply
  • 1135 views

Hello,

I have a text flow in which I have an image. I listen to the corresponding StatusChangeEvent.INLINE_GRAPHIC_STATUS_CHANGE to find out when the image gets loaded and as recommended by the TLF documentation I try to compose the text again so the image gets visible.

The problem is that I get the event (StatusChangeEvent.INLINE_GRAPHIC_STATUS_CHANGE) in the middle of a call to composeToPosition(). In my scenario I listen to UPDATE_COMPLETE for my wrapping container and then I do some size adjustments to the Sprites that contain the text flow and within this piece of code I invoke composeToPosition() so I have the whole text composed. Within this call my StatusChangeEvent.INLINE_GRAPHIC_STATUS_CHANGE event handler gets invoked and this is a surprise for me. I thought that my StatusChangeEvent.INLINE_GRAPHIC_STATUS_CHANGE handler would be invoked when the image gets loaded but somehow the event is fired when I call composeToPosition(). This led to problems because I try to get the dimensions of some of the text lines and since the composer is still composing the results are wrong. I easily protected myself from entering this state by examining flowComposer.composing flag and this solved this particular problem however this made me think how to protected all event handlers where similar situations could occur i.e. being invoked while the composer is composing so I have two questions in order to be able to desing my code:

1. Why StatusChangeEvent.INLINE_GRAPHIC_STATUS_CHANGE could get fired while executing composeToPosition()?

The image loading should be asynchronous to the composition but in my case it always gets fired within composeToPosition().

2. What would be recommended approach to prevent all my event handlers getting in the same state i.e. invoked while composition is running?

In fact in which situations a client event handler might get called while composing?

I have a lot of event handlers which listen for mouse/keyboard/resize/etc. effects and so far I have never experienced similar problems. My probably naive interpretation is that whenever a developer writes code which uses TLF they should not need flowComposer.composing flag at all. The composer is composing whenever you call any of the TLF methods that lead to composition and after it is over the composition is over. There are also scenarios in which composition is triggered indirectly let's say by resizing a component but hopefully any events could be fired before or after the actual composition.

So before going to implement a way to protect my handlers from being in such state I would like to get more info when this could happen.

Thanks!

This topic has been closed for replies.
Correct answer rdermer

Hi Richard,

Thank you for the time spent on discussing this topic!

Re:

"TLF dispatches many events that can be called recursively from a script - all of the TextFlow events in fact."

Can I safely assume that the only handlers in my code which could be called while the composer is composing are handlers for TLF events?

I have a lot of mouse/keyboard/resize handlers and if the above assumption is correct then I don't need to worry being called there while TLF is composing. This would really simplify the way I deal with such cases.

Re:

"TLF does not load graphics from URLs until they are composed - its during composition that TLF decides a particular graphic will be displayed and then loads it - that way arbitrary ILG elements that are sitting in a TextScrap or otherwise aren't displayed don't hold onto image content.  That's when the event is being sent."

This is still a bit confusing to me. In case you start the image loading only at the first compose call (provided the image will be displayed) then TLF should receive asynchronously results related to the image loading which in turn means TLF would receive any image loading results only after composeToPosition() is done therefore my StatusChangeEvent.INLINE_GRAPHIC_STATUS_CHANGE event handler will not be called in the middle of composeToPosition() execution. But in fact it is called exactly there.

The only way I could explain such a behavior is that there was an initial composition which triggered the image loading however the image was not displayed (could be because the wrapping sprite was small enough) therefore my INLINE_GRAPHIC_STATUS_CHANGE event handler was not called at the point when TLF received the original image loading event and only when I called composeToPosition() and my wrapping sprite was big enough to visualize the image then my handler got called.

I am still digging into this because I search for logical explanation otherwise I might be leaving timebombs in my code and have surprises in the future.

Thank you!


1) Yes - composition isn't interrupted by player events such as keyboard and mouse events.

2) The LOADING event is a TLF event saying that the load of the image is being initiated - its generated synchronously.  Please examine the InlineGraphicElementStatus class and use these values in your event handler.

1 reply

Adobe Employee
November 18, 2009

It gets fired whenever the status is changed.  The composeToPosition call changes the status to "loading".  Your handler needs to check the status in the event and compose conditionally.

Get the examples as described here:  http://forums.adobe.com/message/2402084#2402084

Hope that helps,

Richard

Inspiring
November 19, 2009

Hi Richard,

I realize that my event handler will be called when the status is changed but I don't expect that this will happen while composeToPosition is running.

For example if you have an ordinary "Image" element like this one:

<mx:Image id="imageID" source="some url" complete="completeHandler()" /> then you will never have any of your scripts interrupted in the middle and get your completeHandler() called. The way it works is that any currently executing script will finish its work and only then the next handler in this case completeHandler() will be called. Similarly I don't expect that in the middle of composeToPosition the event came so my handler was called.

My guess is that the TLF framework didn't propagate the event (that the image is loaded) at the point in time it was received but it delayed its dispatching and later when I called composeToPosition the framework decided that now is the time to fire it.


This is the first time I ever experience one of my handlers being called while the composer is composing. I easily fixed this particular case by examining composer.composing flag but before implementing a generic solution for the rest (or some) of my handlers I would like to collect more information in which scenarios this could happen. I would like to know what kind of client code could be called (I guess these are only handlers) while TLF is composing. I am also curious to know why at all there are cases in which client code could be invoked during composition. Ideally designed TLF probably will never call client code during composition thus simplify the job of the developers who depend on TLF.

Probably some of the people involved in the TLF development could give more information.

Thanks!

Adobe Employee
November 19, 2009

TLF does not load graphics from URLs until they are composed - its during composition that TLF decides a particular graphic will be displayed and then loads it - that way arbitrary ILG elements that are sitting in a TextScrap or otherwise aren't displayed don't hold onto image content.  That's when the event is being sent.

The "loading" event can be useful - feel free to ignore it. You don't need to look at the composing flag - just look at the event.  Consider this thread which is a nice use case of the loading event. http://forums.adobe.com/message/2404466

TLF dispatches many events that can be called recursively from a script - all of the TextFlow events in fact.

Thanks,

Richard