As Tim and I discussed, this is the new design for LockScreen state machine: 1. Panel -> sub-components are all state machine, and they would manage only the transferring for their level. For example, panel switching shouldn't care about keypad rising/hiding, which should be managed by the sub-component of keypad only. 2. Invert the design from busy looping for transferring to transfer only when the transferring event comes. 3. Instantiate and start the new state every time the transferring start, after the current state get stopped. Details would be summarized after the design get early evaluated.
Created attachment 8525203 [details] [review] Demo Tim: I want to discuss the concept with you as early as possible, to make sure what we concluded get fully implemented in this patch. This demo patch now shows two things: 1. The possible implementation of panel, and the common component across panels, the widget. They're all state machine and can be instantiated and started (transferred to), as we discussed. 2. The panel only care the things related to how to transfer to the next panel (state). While the sub-component (widget) would be instantiated to manage the sub-states. 3. To prevent the risk of racing code, the properties must be fetched from mozSettings now would be fetched inside a promised step, and only when these properties get fetched, the initialization continues. Thus, other steps like register event handlers must be in the promise chain, too. 4. I now adopt the 'stop - stopped - start' model to transfer to the new state. That is, the new state only get started after the previous one really stopped. This is to prevent two states races to control the same resource (like DOM elements or even events). I summarize it here, but if it's possible we should have an offline discussion, so that we can discover some more details we may not notice before.
Attachment #8525203 - Flags: feedback?(timdream)
Comment on attachment 8525203 [details] [review] Demo Discussed offline. We would need implement a promise queue for many operations.
Attachment #8525203 - Flags: feedback?(timdream) → feedback+
Tim: I've updated the patch according what we discussed: 1. Every steps in the panel would need to concat themselves to a Process instance, which is a wrapped Promises that can be aborted and switch to one of these phases: started, stopped or destroyed. Component should only handle event at the 'started' phase, and if it get stopped it receives no more inputs and do nothing but preparing to end itself. The destroyed phase require the panel to finish it's ending work at the time the next state has been transferred to (started). 2. Every event handler would be queued inside a Stream instance, which only handles event when the process is started but *not* stopped. This prevents the potential errors you mentioned that handling events before the asynchronous preparations getting done. 3. Although Stream queues events, some special events have higher property should not be queued, since they may end the Stream and Process. These events ('interrupts') would be directly handled by the handler. For example, if user press power-off/on button 50 times and thus we queue so many the event handling, while the component handles the queued events the user suddenly slide to unlock, then the sliding event should be an interrupt and not be queued, or we can't immediately response to user's behavior. I left something we discussed unfinished (the settings cache) because I want to discuss this part with you first, so that I can fix anything I missing before we go further.
Tim: In my another experience I've found modulejs can be a lightweight AMD module loader and dependencies resolver. The loader would do actually no loading thing but to provide a global namespace to define modules and solve the dependencies, so we can keep the same way to load scripts by script tags. The library looks small enough and the function it provide is so simple that maybe we can modularize our code without too much efforts. Of course this needs more test especially for the performance, but if it's possible I wish to have such tool to wrap these new modules under our new architecture of state machine. I wonder what's your concern about this despite the potential performance impact, thanks.  http://larsjung.de/modulejs/  https://github.com/lrsjng/modulejs/blob/master/src/modulejs.js
Discussed offline. Let's not introduce a dependency resolver in the System app scope at this time. As of the code we are making great progress -- I think this can work in a few more rounds.
You need to log in before you can comment on or make changes to this bug.