erget源碼分析(3):生命週期

概述

下面咱們來分析一下erget中的生命週期。ide

src/egret/player/SystemTicker.ts:函數

export namespace lifecycle {

        export type LifecyclePlugin = (context: LifecycleContext) => void;

        /**
         * @private
         */
        export let stage: egret.Stage;

        /**
         * @private
         */
        export let contexts: LifecycleContext[] = [];
        let isActivate = true;

        export class LifecycleContext {

            pause() {
                if (isActivate) {
                    isActivate = false;
                    stage.dispatchEvent(new Event(Event.DEACTIVATE));
                    if (onPause) {
                        onPause();
                    }
                }
            }

            resume() {
                if (!isActivate) {
                    isActivate = true;
                    stage.dispatchEvent(new Event(Event.ACTIVATE));
                    if (onResume) {
                        onResume();
                    }
                }
            }

            onUpdate?: () => void;
        }

        export let onResume: () => void;

        export let onPause: () => void;

        export function addLifecycleListener(plugin: LifecyclePlugin) {
            let context = new LifecycleContext();
            contexts.push(context);
            plugin(context);
        }
    }

LifecycleContext定義了監聽生命週期的類,pause(),resume(),update()這個三個成員方法分別執行暫停、繼續和刷新。LifecyclePlugin定義了一個監聽應用程序狀態變化的函數類型,它有一個類型爲LifecycleContext的context參數。addLifecycleListener()方法建立了LifecycleContext的一個實例,把這個實例做爲參數調用了傳入的plugin()方法。
這樣看好像有點亂,咱們梳理一下。spa

分析

type LifecyclePlugin

export type LifecyclePlugin = (context: LifecycleContext) => void;

由於不一樣平臺監聽應用程序狀態變化的實現不一樣(Native平臺要應用到原生接口,Web使用一些Javascript的API),它們的共同點是要用到LifecycleContext的一個實例,在對應的監聽實現代碼裏去調動這個實例的pause(),resume(),update()這三個方法去暫停、繼續和刷新應用程序,因此定義了LifecyclePlugin這個函數類型。code

function addLifecycleListener

export function addLifecycleListener(plugin: LifecyclePlugin) {
            let context = new LifecycleContext();
            contexts.push(context);
            plugin(context);
        }

addLifecycleListener()方法做爲橋樑,接收到具體的LifecyclePlugin類型的函數,建立LifecycleContext的一個實例做爲參數調用它。接口

class LifecycleContext

let isActivate = true;

        export class LifecycleContext {

            pause() {
                if (isActivate) {
                    isActivate = false;
                    stage.dispatchEvent(new Event(Event.DEACTIVATE));
                    if (onPause) {
                        onPause();
                    }
                }
            }

            resume() {
                if (!isActivate) {
                    isActivate = true;
                    stage.dispatchEvent(new Event(Event.ACTIVATE));
                    if (onResume) {
                        onResume();
                    }
                }
            }

            onUpdate?: () => void;
        }

        export let onResume: () => void;

        export let onPause: () => void;

isActivate做爲一個布爾值類型的成員屬性用來標記當前是否暫停,這個if語言的做用是防止重複觸發暫停事件,若是觸發,主要作了兩件事情,一個是向全局事件系統觸發了一個Event.DEACTIVATE類型的事件(關於全局事件系統在後面的章節中具體分析)。一個是調用了onPause()方法。咱們在egret-core/tools/templates/game/src/Main.ts中找到這幾行生命週期

private onAddToStage(event: egret.Event) {

        egret.lifecycle.addLifecycleListener((context) => {
            // custom lifecycle plugin

            context.onUpdate = () => {
                console.log('hello,world')
            }
        })

        egret.lifecycle.onPause = () => {
            egret.ticker.pause();
        }

        egret.lifecycle.onResume = () => {
            egret.ticker.resume();
        }


        //設置加載進度界面
        //......

        //初始化Resource資源加載庫
        //......
    }

    /**
     * 心跳計時器單例
     */
    export let ticker: sys.SystemTicker = new sys.SystemTicker();

這裏延遲定義了onPause()方法,這個方法只有一行,執行了egret.ticker.pause()方法。resume()方法相似pause()方法。事件

使用例子

Web平臺

Native平臺

egret-core/src/egret/native/NativeHideHandler.ts:ip

namespace egret.native {
    /**
     * @private
     */
    export let NativeLifeCycleHandler: egret.lifecycle.LifecyclePlugin = (context) => {
        egret_native.pauseApp = () => {
            context.pause();
            egret_native.Audio.pauseBackgroundMusic();
            egret_native.Audio.pauseAllEffects();
        };

        egret_native.resumeApp = () => {
            context.resume();
            egret_native.Audio.resumeBackgroundMusic();
            egret_native.Audio.resumeAllEffects();
        };
    }
}

這個Native平臺監聽函數定義了原平生臺的兩個方法egret_native.pauseApp()和egret_native.resumeApp()。pauseApp()函數作了兩件事情:暫停應用程序,暫停背景音樂和音效的播放。resumeApp()相似。資源

egret-core/src/egret/native/NativePlayer.ts:get

namespace egret.native {
    /**
     * @private
     */
    export class NativePlayer extends egret.HashObject implements egret.sys.Screen {
        //...

        private init(option: PlayerOption): void {
            //...
            lifecycle.addLifecycleListener(NativeLifeCycleHandler);
            //...
        }
        //...
    }
}

這裏利用addLifecycleListener()方法綁定了NativeLifeCycleHandler()這個函數。

相關文章
相關標籤/搜索