资讯专栏INFORMATION COLUMN

erget源码分析(3):生命周期

Hydrogen / 937人阅读

摘要:概述下面我们来分析一下中的生命周期。定义了监听生命周期的类,这个三个成员方法分别执行暂停继续和刷新。方法作为桥梁,接收到具体的类型的函数,创建的一个实例作为参数调用它。函数做了两件事情暂停应用程序,暂停背景音乐和音效的播放。

概述

下面我们来分析一下erget中的生命周期。

src/egret/player/SystemTicker.ts:

</>复制代码

  1. export namespace lifecycle {
  2. export type LifecyclePlugin = (context: LifecycleContext) => void;
  3. /**
  4. * @private
  5. */
  6. export let stage: egret.Stage;
  7. /**
  8. * @private
  9. */
  10. export let contexts: LifecycleContext[] = [];
  11. let isActivate = true;
  12. export class LifecycleContext {
  13. pause() {
  14. if (isActivate) {
  15. isActivate = false;
  16. stage.dispatchEvent(new Event(Event.DEACTIVATE));
  17. if (onPause) {
  18. onPause();
  19. }
  20. }
  21. }
  22. resume() {
  23. if (!isActivate) {
  24. isActivate = true;
  25. stage.dispatchEvent(new Event(Event.ACTIVATE));
  26. if (onResume) {
  27. onResume();
  28. }
  29. }
  30. }
  31. onUpdate?: () => void;
  32. }
  33. export let onResume: () => void;
  34. export let onPause: () => void;
  35. export function addLifecycleListener(plugin: LifecyclePlugin) {
  36. let context = new LifecycleContext();
  37. contexts.push(context);
  38. plugin(context);
  39. }
  40. }

LifecycleContext定义了监听生命周期的类,pause(),resume(),update()这个三个成员方法分别执行暂停、继续和刷新。LifecyclePlugin定义了一个监听应用程序状态变化的函数类型,它有一个类型为LifecycleContext的context参数。addLifecycleListener()方法创建了LifecycleContext的一个实例,把这个实例作为参数调用了传入的plugin()方法。
这样看好像有点乱,我们梳理一下。

分析 type LifecyclePlugin

</>复制代码

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

因为不同平台监听应用程序状态变化的实现不同(Native平台要应用到原生接口,Web使用一些Javascript的API),它们的共同点是要用到LifecycleContext的一个实例,在对应的监听实现代码里去调动这个实例的pause(),resume(),update()这三个方法去暂停、继续和刷新应用程序,所以定义了LifecyclePlugin这个函数类型。

function addLifecycleListener

</>复制代码

  1. export function addLifecycleListener(plugin: LifecyclePlugin) {
  2. let context = new LifecycleContext();
  3. contexts.push(context);
  4. plugin(context);
  5. }

addLifecycleListener()方法作为桥梁,接收到具体的LifecyclePlugin类型的函数,创建LifecycleContext的一个实例作为参数调用它。

class LifecycleContext

</>复制代码

  1. let isActivate = true;
  2. export class LifecycleContext {
  3. pause() {
  4. if (isActivate) {
  5. isActivate = false;
  6. stage.dispatchEvent(new Event(Event.DEACTIVATE));
  7. if (onPause) {
  8. onPause();
  9. }
  10. }
  11. }
  12. resume() {
  13. if (!isActivate) {
  14. isActivate = true;
  15. stage.dispatchEvent(new Event(Event.ACTIVATE));
  16. if (onResume) {
  17. onResume();
  18. }
  19. }
  20. }
  21. onUpdate?: () => void;
  22. }
  23. export let onResume: () => void;
  24. export let onPause: () => void;

isActivate作为一个布尔值类型的成员属性用来标记当前是否暂停,这个if语言的作用是防止重复触发暂停事件,如果触发,主要做了两件事情,一个是向全局事件系统触发了一个Event.DEACTIVATE类型的事件(关于全局事件系统在后面的章节中具体分析)。一个是调用了onPause()方法。我们在egret-core/tools/templates/game/src/Main.ts中找到这几行

</>复制代码

  1. private onAddToStage(event: egret.Event) {
  2. egret.lifecycle.addLifecycleListener((context) => {
  3. // custom lifecycle plugin
  4. context.onUpdate = () => {
  5. console.log("hello,world")
  6. }
  7. })
  8. egret.lifecycle.onPause = () => {
  9. egret.ticker.pause();
  10. }
  11. egret.lifecycle.onResume = () => {
  12. egret.ticker.resume();
  13. }
  14. //设置加载进度界面
  15. //......
  16. //初始化Resource资源加载库
  17. //......
  18. }
  19. /**
  20. * 心跳计时器单例
  21. */
  22. export let ticker: sys.SystemTicker = new sys.SystemTicker();

这里延迟定义了onPause()方法,这个方法只有一行,执行了egret.ticker.pause()方法。resume()方法类似pause()方法。

使用例子 Web平台 Native平台

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

</>复制代码

  1. namespace egret.native {
  2. /**
  3. * @private
  4. */
  5. export let NativeLifeCycleHandler: egret.lifecycle.LifecyclePlugin = (context) => {
  6. egret_native.pauseApp = () => {
  7. context.pause();
  8. egret_native.Audio.pauseBackgroundMusic();
  9. egret_native.Audio.pauseAllEffects();
  10. };
  11. egret_native.resumeApp = () => {
  12. context.resume();
  13. egret_native.Audio.resumeBackgroundMusic();
  14. egret_native.Audio.resumeAllEffects();
  15. };
  16. }
  17. }

这个Native平台监听函数定义了原生平台的两个方法egret_native.pauseApp()和egret_native.resumeApp()。pauseApp()函数做了两件事情:暂停应用程序,暂停背景音乐和音效的播放。resumeApp()类似。

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

</>复制代码

  1. namespace egret.native {
  2. /**
  3. * @private
  4. */
  5. export class NativePlayer extends egret.HashObject implements egret.sys.Screen {
  6. //...
  7. private init(option: PlayerOption): void {
  8. //...
  9. lifecycle.addLifecycleListener(NativeLifeCycleHandler);
  10. //...
  11. }
  12. //...
  13. }
  14. }

这里利用addLifecycleListener()方法绑定了NativeLifeCycleHandler()这个函数。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/92847.html

相关文章

  • erget源码分析(2):全局哈希基类和全局异步函数对象接口

    摘要:异步函数对象接口,包含和两个成员方法。哈希计数在整个的源码中都没有找到和方法的调用,这两个方法的具体作用是在原生中实现类式继承和私有属性一类的功能。 文件结构 utils/HashObject.ts文件:showImg(https://segmentfault.com/img/bVZpuq?w=642&h=472); 首先解释一下文件结构图 __extends方法 通过原型对象模拟类...

    godlong_X 评论0 收藏0
  • erget源码分析(1):入口文件分析

    摘要:是一个静态类,调用方法来初始化各项支持信息。小结通过和这两个静态类初始化了项目运行的环境参数,然后创建了屏幕适配器根据不同的适配策略调整。下一篇源码分析全局哈希基类和全局异步函数对象接口 egret的github地址是https://github.com/egret-labs...,大家自己git clone到本地。 一.路口html文件 用ergetWing新建一个工程,打开根目录下...

    Rainie 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<