7 Replies Latest reply on Jul 29, 2011 1:06 PM by FM_Flame

    Is there any way to delay flex from drawing anything until everything is ready to be rendered?

    FM_Flame Level 1

      I have this CustomVideoPlayer which uses a skinned VideoPlayer and a button for closing. The problem I see is that when going out of fullscreen mode I can litterally see how the subcomponents of the videoPlayer - background frame etc shrinks and repositions in the middle of the screen cause I have vertical and horizontalCenter and etc. So whiching between both states is not fluent. I don't want to animate it, I just want not to see the glitching resizing and repostioning.

       

      So how can I "wait" till all elements are resized and repositioned in the normal state and then show the new state all at once with no glitching? Is it possible ?

       

      And one more extra question:

      I've taken a look inside the VideoPlayer class and I've noticed that when adding skin part for example PlayButton, they add a listener for Click, when they remove the part they remove it. That's ok but as component is removed from it's parent partRemoved is not called so the listener is never removed and would this make the component stuck in memory cause of that listener?

       

      Oh and one more small extra question:

      If a skin part is required does this also mean that it must exist in all states?

      (cause if it does that would mean I could add it's event listeners in the creation complete or partAdded, but not partRemoved function, since it would never be removed...)

        • 1. Re: Is there any way to delay flex from drawing anything until everything is ready to be rendered?
          drkstr_1 Level 4
          So how can I "wait" till all elements are resized and repositioned in the normal state and then show the new state all at once with no glitching? Is it possible ?

           

          You should be able to create a custom skin, and listen for a stateChanging event. Make things invisible until you recieve the stateChange event (checking for the appropriate states of course). You may need to wait for an updateComplete event if the stateChange happens earlier in the chain (I'm not sure off the top of my head). There are many other methods for doing this as well.

           

          And one more extra question:

          I've taken a look inside the VideoPlayer class and I've noticed that when adding skin part for example PlayButton, they add a listener for Click, when they remove the part they remove it. That's ok but as component is removed from it's parent partRemoved is not called so the listener is never removed and would this make the component stuck in memory cause of that listener?

           

          Nope. The partRemoved is for dynamic skin parts, when you wish to remove a skin part while keeping the parent component in the display list. All children (including the skin parts) of a parent component will be Garbage Collected once there are no more references to it.

           

           

          Oh and one more small extra question:

          If a skin part is required does this also mean that it must exist in all states?

          (cause if it does that would mean I could add it's event listeners in the creation complete or partAdded, but not partRemoved function, since it would never be removed...)

           

          Nope. It only requires that the skin have some instance for that part. I think technically it doesn't even need to be on the display list, but I could be wrong about that.

          1 person found this helpful
          • 2. Re: Is there any way to delay flex from drawing anything until everything is ready to be rendered?
            FM_Flame Level 1
            You should be able to create a custom skin, and listen for a stateChanging event. Make things invisible until you recieve the stateChange event (checking for the appropriate states of course). You may need to wait for an updateComplete event if the stateChange happens earlier in the chain (I'm not sure off the top of my head). There are many other methods for doing this as well.

             

            If I do this then I will have my video player in fullscreen disappear for a moment and then reappear out of fullscreen, and I want it not to disappear, but to just jump to the other state fully resized and repositioned with no glitching in between states.

             

            Nope. The partRemoved is for dynamic skin parts, when you wish to remove a skin part while keeping the parent component in the display list. All children (including the skin parts) of a parent component will be Garbage Collected once there are no more references to it.

            As far as I know dynimic skin parts have another meaning - creating more than one instance at runtime. Also I've read just now (again) partAdded and partRemoved are called on component initialization and skin change. So basicly if I change the skin, it makes sense to remove the eventListeners from the old skin parts. But still, I've read on many places that if an object has event listeners attached to it it will Not be GC unless they are weak, so it will be stuck in memory forever.

            So looking at the VideoPlayer and it's skin parts, I'm not seeing any event listener being removed when I remove the instance I have of the VideoPlayer. Why is that? Why the component does not remove it's skin parts event listeners?

             

            Nope. It only requires that the skin have some instance for that part. I think technically it doesn't even need to be on the display list, but I could be wrong about that.

             

            I'm interested in the skin parts and states relation. With includeIn and excludeFrom you define in which states the component is added to or removed from as a child (element). So If I have a skin part which is required=true and I have 2 states from one of which it is excluded... whouldn't that result in a runtime error since the part is not there but it is required?

            • 3. Re: Is there any way to delay flex from drawing anything until everything is ready to be rendered?
              drkstr_1 Level 4
              If I do this then I will have my video player in fullscreen disappear for a moment and then reappear out of fullscreen, and I want it not to disappear, but to just jump to the other state fully resized and repositioned with no glitching in between states.

               

              Than you will need to implement your own solution which meets your specific design goals. That's the nature of the beast my friend.

               

               

              As far as I know dynimic skin parts have another meaning - creating more than one instance at runtime. Also I've read just now (again) partAdded and partRemoved are called on component initialization and skin change. So basicly if I change the skin, it makes sense to remove the eventListeners from the old skin parts. But still, I've read on many places that if an object has event listeners attached to it it will Not be GC unless they are weak, so it will be stuck in memory forever.

              So looking at the VideoPlayer and it's skin parts, I'm not seeing any event listener being removed when I remove the instance I have of the VideoPlayer. Why is that? Why the component does not remove it's skin parts event listeners?

               

               

              Are you changing skins? If so, I bet the parts would be removed as expected. The partRemoved method is not being called because it's not needed. If you remove the parent component, than any reference encapuslated within that component are removed as well.Fire up the profiler if you don't believe me.

               

               

              I'm interested in the skin parts and states relation. With includeIn and excludeFrom you define in which states the component is added to or removed from as a child (element). So If I have a skin part which is required=true and I have 2 states from one of which it is excluded... whouldn't that result in a runtime error since the part is not there but it is required?

               

              I'm pretty sure that it only checks if the instance exists, and does not care if it has been created and added to the display list. I do not really know for certain though. This could easily be answered with a simple test.

              1 person found this helpful
              • 4. Re: Is there any way to delay flex from drawing anything until everything is ready to be rendered?
                FM_Flame Level 1
                Than you will need to implement your own solution which meets your specific design goals. That's the nature of the beast my friend.

                 

                About this, I think I am not doing the repositioning the best way here. As I said before I have this VideoPlayer CloseButton and VideoTitle, all put in a VideoHolderGroup. Since verticalCenter and horizontalCenter will center all of this on screen and I what I want is to center the VideoPlayer on screen. I need to use some math to substract the VideoTitle space and the CloseButton space.

                 

                So I am doing this repositioning in the skin in it's updateCompleteHandler, which seems not to be the best way since after the screen is drawn once it calls it and then updates it again, that's why I guess I see this glitching more than I want to.

                 

                I just tried this:

                 

                override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
                            {
                                super.updateDisplayList(unscaledWidth, unscaledHeight);
                               
                                themeVideoPlayerHolder.x = Math.round(this.width/2 - videoPlayer.width/2);
                                themeVideoPlayerHolder.y = Math.round(this.height/2 - videoPlayer.height/2 - (themeVideoPlayerHolder.height - videoPlayer.height));
                            }

                 

                And looks like the glitching is a lot less. Is this the right place to put the code in ? On the other hand I do not call invalidateDisplayList() (but it works anyway), since I see the glitching only when going out of fullscreen which is applied by the VideoPlayer which is subcomponent of my CustomVideoPlayer. So maybe when the fullscreen changes the first thing it does is invalidating the skin state of the VideoPlayer and then invalidating the displayList of my CustomVideoPlayer? Maybe it will be even better if I put this code in the stateChange(ing)Handler of the VideoPlayer subcomponent?

                 

                Not sure if my thinking is right so enlighten me

                • 5. Re: Is there any way to delay flex from drawing anything until everything is ready to be rendered?
                  drkstr_1 Level 4

                  If I'm not mistaken, the "glitching" happens because of how the VideoPlayer switches between full screen and normal modes, in that it actually detaches the video from the VideoPlayer and attaches it the stage (or something like that, I dont have the code in front of me at the moment). If it were me, I would probably go about it by overriding the VideoPlayer (or creating my own) so that it would use some kind of smoothing effect to resize and position the video back into it's original position. I don't know if this can be achieved simply by updating the skin. I think you will need to actually change the behaviour in the host component for this to work. If I have time later I can pop open the VideoPlayer code and see if I have any better ideas.

                  • 6. Re: Is there any way to delay flex from drawing anything until everything is ready to be rendered?
                    FM_Flame Level 1

                    Here to ease your testing is my very simple example, you can download the source (flex 4.1)

                     

                    http://filip.nedyalkov.net/flex_test_examples/validation_test/

                     

                    As you can see there is a very fast glitching right after you click to go away from fullscreen. The player is located under where it's supposed to be and then it fast repositions to where it should be. It happens very fast but it happens (it's more obvious when there's more complicated architecture). I've commented out the overriding of the updateDisplayList, uncomment it and comment the updateCompleteHandler to see that the glitching is pretty much gone.

                     

                    But it still bothers me since I do not understand if I'm doing this right, cause I've read that when overriding the updateDisplayList you should use move() method to position the subcomponents, but when I tried that I found out that the updateDisplayList gets the fullscreen dimensions (width,height) of the VideoPlayer istead of the normal ones and positions it wrong... So I am not really sure how setting the position using X and Y properties works fine...

                     

                    Basicly I need to undestand this:

                     

                    When you have a skinnableComponent (CustomComponent) which has a skinnableComponent as a subcomponent (SubComponent) - how does the Validation work ?

                     

                    As with this example: the SubComponent changes his skin state from fullscreen to normal, it's parts resize and reposition as defined in the state. When in this chain exactly the CustomComponent gets notified that one of it's subcomponents has changed size and at that point I have the actual new size of that subcomponent so I can properly reposition it and all of this to happen before it is rendered?

                    • 7. Re: Is there any way to delay flex from drawing anything until everything is ready to be rendered?
                      FM_Flame Level 1

                      I've dig up in the UIComponent class and I found that when component's size changes (due to change in width, height, transforms, rotations etc) this method is called: invalidateParentSizeAndDisplayList(). So I guess I am correct to overriding the updateDisplayList of the parent component to reposition it's skin parts.

                       

                      This is the final code I ended up with for now that I can say I don't notice any glitching... seems like it works perfect:

                       

                      override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
                                  {
                                      super.updateDisplayList(unscaledWidth, unscaledHeight);
                                      if(videoPlayer.parent.parent == themeVideoPlayerHolder){
                                          themeVideoPlayerHolder.validateNow();
                                         
                                          var x:Number = Math.round(this.width/2 - videoPlayer.width/2);
                                          var y:Number = Math.round(this.height/2 - videoPlayer.height/2 - (themeVideoPlayerHolder.height - videoPlayer.height));
                                          themeVideoPlayerHolder.move(x,y);
                                      }
                                  }

                       

                      I called themeVideoPlayerHolder.validateNow(); so I get the actual width and height after changing the VideoPlayer state to normal from fullscreen for the calculations, and then positioned the themeVideoPlayerHolder as advised using the move() method. In the docs it's also adviced to use this.getExplicitOrMeasuredWidth() or height when overriding the updateDisplayList, but I wasn't sure where I am supposed to use it... should I use it everywhere like:

                      1) this.width -> this.getExplicitOrMeasuredWidth();

                      2) videoPlayer.width -> videoPlayer.getExplicitOrMeasuredWidth();

                      3) themeVideoPlayerHolder.width -> themeVideoPlayerHolder.getExplicitOrMeasuredWidth();

                       

                      ?

                       

                      I still need some guidance If I am thinking or doing this right... thoughts ?