Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>I decided a better solution to this issue was a small tweak to LayoutManager. It should be smart enough to know when validating an object if any of the previous phases are invalid. </p> <p>This problem can manifest itself in several ways. Essentially invalidating objects from within the measure() or the updateDisplayList() methods can cause this. For instance, if an event is dispatched from within the measure() function, and the handler for the event happens to invalidate an objects size and properties, the measure() function may get ran before commitProperties() potentially breaking the component. </p> <p>The show event is dispatched from within UIComponent's updateDisplayList() which is why it is subject to this failure.</p> <p>I ended up modifying validateSize() and validateDisplayList() slightly. Added a bit of code to check for the invalid flags of previous phases and to re-invalidate the object if necessary. Also added a flag to force LayoutManager to run another cycle immediately if an object is re-invalidated due to the above condition.</p> <p>Just as an FYI, its usually not a good idea to modify the SDK but it can be done on a per-project basis by copying the SDK file into a matching folder structure in your project and doing a clean on the project. The file in your project will be used rather than the one in the SDK. </p> <pre><code>private function validateSize():void { // trace("--- LayoutManager: validateSize ---&gt;"); //SDK Mod - Storage for items to be re-invalidated. var reInvalidate:Array = []; var obj:ILayoutManagerClient = ILayoutManagerClient(invalidateSizeQueue.removeLargest()); while (obj) { // trace("LayoutManager calling validateSize() on " + Object(obj)); //SDK Mod - Check if we need to record this item due to invalid dependencies. if (obj is UIComponent) { if (UIComponent(obj).mx_internal::invalidatePropertiesFlag == true) { //Record the invalid item. reInvalidate.push(obj); //Set flag so LayoutManager immediately runs another cycle recycleImmediately = true; } } obj.validateSize(); if (!obj.updateCompletePendingFlag) { updateCompleteQueue.addObject(obj, obj.nestLevel); obj.updateCompletePendingFlag = true; } // trace("LayoutManager validateSize: " + Object(obj) + " " + IFlexDisplayObject(obj).measuredWidth + " " + IFlexDisplayObject(obj).measuredHeight); obj = ILayoutManagerClient(invalidateSizeQueue.removeLargest()); } //Re-invalidate any items with invalid dependencies. while (reInvalidate.length &gt; 0) invalidateSize(ILayoutManagerClient(reInvalidate.shift())); if (invalidateSizeQueue.isEmpty()) { // trace("Measurement Queue is empty"); invalidateSizeFlag = false; } // trace("&lt;--- LayoutManager: validateSize ---"); } private function validateDisplayList():void { // trace("--- LayoutManager: validateDisplayList ---&gt;"); //SDK Mod - Storage for items to be re-invalidated. var reInvalidate:Array = []; var obj:ILayoutManagerClient = ILayoutManagerClient(invalidateDisplayListQueue.removeSmallest()); while (obj) { // trace("LayoutManager calling validateDisplayList on " + Object(obj) + " " + DisplayObject(obj).width + " " + DisplayObject(obj).height); //SDK Mod - Check if we need to record this item due to invalid dependencies. if (obj is UIComponent) { if (UIComponent(obj).mx_internal::invalidatePropertiesFlag == true || UIComponent(obj).mx_internal::invalidateSizeFlag == true) { //Record the invalid item. reInvalidate.push(obj); //Set flag so LayoutManager immediately runs another cycle recycleImmediately = true; } } obj.validateDisplayList(); if (!obj.updateCompletePendingFlag) { updateCompleteQueue.addObject(obj, obj.nestLevel); obj.updateCompletePendingFlag = true; } // trace("LayoutManager return from validateDisplayList on " + Object(obj) + " " + DisplayObject(obj).width + " " + DisplayObject(obj).height); // Once we start, don't stop. obj = ILayoutManagerClient(invalidateDisplayListQueue.removeSmallest()); } //Re-invalidate any items with invalid dependencies. while (reInvalidate.length &gt; 0) invalidateDisplayList(ILayoutManagerClient(reInvalidate.shift())); if (invalidateDisplayListQueue.isEmpty()) { // trace("Layout Queue is empty"); invalidateDisplayListFlag = false; } // trace("&lt;--- LayoutManager: validateDisplayList ---"); } </code></pre> <p>Then inside doPhasedInstantiation() . . .</p> <pre><code>if (invalidatePropertiesFlag || invalidateSizeFlag || invalidateDisplayListFlag) { //SDK Mod - Check if we re-invalidated any items durring the cycle. if (recycleImmediately == false) { //No items were re-invalidated, default behavior. callLaterObject.callLater(doPhasedInstantiation); } else { //We re-invalidated items durring the current cycle, run another cycle immediately and bail out. recycleImmediately = false; doPhasedInstantiation(); return; } } </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload