8 Replies Latest reply on Jun 24, 2009 1:06 PM by CoreyRLucier

    Gumbo StateChangeEvent Contract

    tcorbet

      Since I don't see this problem posted as a bug either open or closed, the odds are pretty good that this is not a bug, just a long latent defect in my code being exposed by the attempt to migrate my AIR application to the latest SDK from the Gumbo folks.

       

      Here is what always worked fine:

       

          A.  A simple two-state User Interface, State A and State B.

          B.  I never believed in, so never accepted the idea that the 'Initial State' was the one with no name!

          C.  So, the initialization code of my application -- invoked on WindowedApplication's CreationComplete event -- always set  currentState = "A" after establishing an EventListener for StateChangeEvent.CURRENT_STATE_CHANGE.

          D.  I always received a StateChangeEvent, and performed the remaining application-defined initializations step in a switch block testing the value of that event's newState for "A".  It just seemed like the right way to code, and it just seemed to work wonderfully -- until Gumbo.

       

      Since the beta documentation makes it pretty difficult to know whether we are supposed to change our MXML from <mx.states> to <s.states> and our <mx.State> to<s.State>, when it failed with the new build, I tried all possible combinations, and pretty much concluded that, at the moment, State and states are reserved symbols defined in both the old Halo stuff and the new Sparc stuff, and no matter which form of declaration you make, the result is the same.  And that is, that you will not get the firing of a StateChangeEvent on start up.  I had to first assign currentState to 'B', then immediately reassign it to 'A' in order to get through my start-up code.

       

      Since I would guess that anyone testing his existing application making the fewest possible changes to run in a Gumbo-ed world, would see this behavior, either this is somehow related to an AIR top level application start-up as behaving differently from a Flex top level application start-up OR, I've been doing it the wrong way for 18 months and have just been dumb lucky up 'til now.  I hope I wasn't supposed to be looking for CURRENT_STATE_CHANGING instead of CURRENT_STATE_CHANGED, just in case someone responsible for the implementation 'inside the black box' changed his mind about whether or not the setting of an initial state means that the state has changed, or just been 'established'!

        • 1. Re: Gumbo StateChangeEvent Contract
          Flex harUI Adobe Employee

          I could be wrong since I don't work with States that much, but before Gumbo, the initial state was null and so you changed state to "A" and got an event.  In Gumbo there is no null initial state so the app starts up in the first state you defined which is "A" and there probably is no StateChangeEvent since it didn't "change" it was "initialized".  Similar to how there is no "show" event when a component is first created since it started with visible=true.

           

          So, I'd finish your init on creationComplete or applicationComplete

           

          Alex Harui

          Flex SDK Developer

          Adobe Systems Inc.

          Blog: http://blogs.adobe.com/aharui

          • 2. Re: Gumbo StateChangeEvent Contract
            tcorbet Level 1

            You are, no doubt, correct.  I think a change to Joan's "Differences" document might do the trick.

             

            Here, just concentrating on state changes, not all the syntax changes that you make to express your state model in the new manner as compared to the old, is what caught me, and might catch others:

             

            Old states simplified declaration:

             

               <mx:states>

                   <mx:State name="A" />

                   <mx:State name="B" />

               </mx:states>

             

            Old behavior:  At start up all components declared as a part of the "A" State are on the stage.  In your initialization  code if you set currentState = "A"  you WILL GET a StateChangeEvent saying that you have just 'entered the A State', so you can do what is appropriate.

             

            [When I say "all components are on the stage", I am just ignoring as not important to this discussion, the question of whether the engineer chose a 'deferred-until-needed' strategy.  That strategy/implementation is unchanged as between the older and the newer SDKs.]

             

            New states simplified declaration:

             

               <mx:states>

                   <mx:State name="A" />

                   <mx:State name="B" />

               </mx:states>

             

            New behavior:  At start up all components declared as a part of the "A" State are on the stage.  In your initialization code if you set currentState = "A" you WILL NOT GET a StateChangeEvent saying that you have just 'entered the A State' in order to do what is appropriate.

             

            This fix, allowed the rest of my application to behave properly with Gumbo:

             

               <mx:states>

                   <mx:State name = "A TIme Before Time" />

                   <mx:State name="A" />

                   <mx:State name="B" />

               </mx:states>

             

            So, actually, re-reading the current migration guide, it almost says this, but because "A Time before Time" is referred to as 'default' as a way of sort of saying "because we have done away with an internal State that used to be an empty string", it was not clear to me that, unlike the old behavior, the new beharior depends upon there being a 'place marker' at the head of the list of chidren for <mx:states>.

            • 3. Re: Gumbo StateChangeEvent Contract
              tinylion_uk Level 2

              I also work in the same way as you, almost. The one difference being that I always left the "" state in there

               

              ie

               

                 <mx:states>

                     <mx:State name="" (or sometimes i used "blank" i now tend to have a "blank" in sdk4 states />

                     <mx:State name="A" />

                     <mx:State name="B" />

                 </mx:states>

               

              I also shuddered (don’t know why lol) at the thought of having an empty string as a state name, so I always had absolutely nothing in the "" state, and in the same way you did then set state="A" at start-up, thus getting the event fired. Seeing as i always left "" in there (again, i'm not sure why i did this really) at least it meant that when i first went over to 4 that the states continued to work in the same way.

               

              I think there was a part of my that sort of like State="" just being an empty state.

               

              Now I look back at this though, I think it was just an arbitrary decision on my part early in my flex dev and just kind of followed along with me.

               

              Cheers

               

              Glenn

              tinylion

               

              ps - by the way, that was a really well thought out and laid out question

              1 person found this helpful
              • 4. Re: Gumbo StateChangeEvent Contract
                CoreyRLucier Adobe Employee

                So in Flex 4 as you stated, there is no explicit base state or 'null' state...  A stateful document or component must exist in one of the states that are defined in the set of states.  Upon component creation and initialization the component is automatically placed in the 'first' of these states (first in the array of states) unless an alternative is specified on the root tag (w/currentState attribute).

                 

                That said, the legacy state change events still fire, the following works (e.g. StateChangeEvent.CURRENT_STATE_CHANGE fires initially:

                 

                <?xml version="1.0" encoding="utf-8"?>
                <s:Application
                            xmlns:fx="http://ns.adobe.com/mxml/2009"
                            xmlns:s="library://ns.adobe.com/flex/spark"
                            xmlns:mx="library://ns.adobe.com/flex/halo"
                            currentStateChange="onStateChange()" >
                   
                    <s:states>
                        <s:State name="A" />
                        <s:State name="B" />
                    </s:states>
                   
                    <fx:Script>
                        <![CDATA[
                        import com.corey.CoreyClass;
                        import flash.utils.describeType;
                       
                        private function onStateChange():void
                        {
                           trace("stateChangeOccured");
                        }
                        ]]>
                    </fx:Script>

                </s:Application>

                 

                Are you finding that this is contrary to your understand or that this should work in a different manner than I defined?

                 

                -Corey

                1 person found this helpful
                • 5. Re: Gumbo StateChangeEvent Contract
                  tcorbet Level 1

                  I guess another thing I have to 'fess up to' is that all of my applications -- whether developed for the desktop

                  with a topLevelApplication Windowed, or just the Flex variety of Application -- are built using only the SDK with

                  as much separation between 'presentation' and 'logic' as possible.  In that mode [of thinking], both the establishment

                  of the StateChangeEvent listener, and the consumption of events is always done in a separate ActionScript class.

                  Actually, in the application I was trying to migrate, the event that was never being received was in the main

                  ActionScript class which backs an Application running as a sub-application to an AIR WindowedApplication.

                   

                  So, as I said in my second  posting, and as Glen indicated in his reply, the correct solution seems to be to

                  add an explicit 'dummy first entry' in the <states> list.  The difference is that he had always used the explicit

                  'dummy first entry' in his pre-Gumbo work, so his migration path automatically yielded a valid construct for Gumbo.

                   

                  Therefore, I cannot answer your question about what would happen if the Application component had its

                  StateChangeEvent listener established via the Application declaration -- that changes too much about the

                  separation of 'presentation' and 'logic' for my old bones to be comfortable with.  I thank you for the suggestion.

                  It increases my level of understanding, and I am absolutely certain that if I ran your nice test case example,

                  the event would be 'seen'.

                   

                  So, "while we've got you on the line" could you provide some guidance concerning the secondary question that

                  I raised in the original posting.  Suppose that I wanted to 'wallk before I flew' to Gumbo land?  What should I

                  expect the behavior of state change processsing to be if, in your example, each tag prefixed by 's' were left

                  prefixed by 'mx'?  I realize that this is just interim, but we have to maintain production code while getting ready

                  for the next generation, so we would probably go through a stage in which we introduced as little change as

                  possible -- for our engineers and for our end-users.  Will <mx.states> and <mx.State> perform just the same

                  in your example?

                   

                  Thank you.

                  • 6. Re: Gumbo StateChangeEvent Contract
                    CoreyRLucier Adobe Employee

                    The new states semantics only applies when the Flex 4 language namespace is declared for a given document.

                     

                    e.g.

                     

                    xmlns:fx="http://ns.adobe.com/mxml/2009"

                     

                    A document can have only one language namespace, but for example if the legacy 2006 (Flex 3) namespace was declared, e.g. xmlns:mx=”http://www.adobe.com/2006/mxml”, then the older states semantics would be in place.

                     

                    That is really the only granularity we've provided.

                     

                    -Corey

                    • 7. Re: Gumbo StateChangeEvent Contract
                      tcorbet Level 1

                      Well, I'm glad I asked, because I am obviously confused. [If it's only me, I will drop off this thread pretty soon, but I think there may be others.]

                       

                      This is what I am using that seems to give me just the minimal Gumbo-ness, while letting me incrementally test compilation with the new compiler in the new SDK.  I found that <Script> and <Style> demanded to be changed from mx to their fx brethren, but that -- as you see in the contrived test case -- I could mix and match mx and sp for the <states> and <States> tags.  Not that that is what I think I really want to do, but what I did to test my understanding of what goes on 'under the covers' when I make the namespace changes requried of the new compiler.  [Yes, I also did some testing of setting the compiler compatibility version back to "3.0.0", but that would really not move the ball very far down the Gumbo playing field.]

                       

                      <mx:Application
                          xmlns:fx="http://ns.adobe.com/mxml/2009"
                          xmlns:mx="library://ns.adobe.com/flex/halo"
                          xmlns:sp="library://ns.adobe.com/flex/spark"
                          creationComplete="appInit (event)"
                          frameRate="12"
                          height="100%"
                          layout="vertical"
                          styleName="sssApplication"
                          width="100%"
                          >

                       

                          <fx:Script>
                          <![CDATA[
                              import mx.events.FlexEvent;
                              import com.sss.extrusion.GlyphExtractor;

                       

                              public var $LAM_Controller:GlyphExtractor;

                       

                              internal function
                              appInit (event:FlexEvent)
                              :void
                              {
                                  $LAM_Controller = new GlyphExtractor (this);
                              } // End of appInit().
                          ]]>
                          </fx:Script>

                       

                          <fx:Style source="../../../../resources/appStyle.css" />

                       

                          <mx:states>
                              <sp:State name="NEVER_LAND" />
                              <sp:State name="SELECT_MODE" />
                              <sp:State name="GLYPH_MODE" />
                          </mx:states>

                       

                      [The $LAM notation is for LoadedApplicationModule, has nothing to do with this topic, and still works correctly as between 3.3.1 and 4.0.0]

                      • 8. Re: Gumbo StateChangeEvent Contract
                        CoreyRLucier Adobe Employee

                        Well... states is still a UIComponent property (of type Array), so it's a property of Application.

                         

                        As with any MXML documents, when you set a property using a tag (e.g. states in this case you must match the namespace of the owning component.  So since you are using the Halo Application (mx), states must also be scoped to mx.

                         

                        Now 'State' is itself just a component, which in the beta build I believe can be resolved in either the halo or spark namepace, as such s: or mx: is fine, they both resolve to the same class under the hood. e.g. the manifest file for both Halo and Spark namespaces include mx.states.State.

                         

                        With the sample above, you are going to get the new Flex 4 states semantics due to presence of the 2009 "language* namespace.

                         

                        -C