27.PureMVC的更新通知和升级Command

27.PureMVC框架-更新通知和升级命令


27.1 知识点

在启动命令脚本中判断代理数据有没有注册,没有就注册。方便等一下更新命令使用。

public class StartUpCommand : SimpleCommand
{
    //继承Command相关的脚本
    //重写里面的执行函数
    public override void Execute(INotification notification)
    {
        base.Execute(notification);
        //当命令被执行时 就会调用该方法
        //启动命令中 往往是做一些初始化操作
        
        //没有这个数据代理 才注册 有了就别注册
        if (!Facade.HasProxy(PlayerProxy.NAME))
        {
            Facade.RegisterProxy(new PlayerProxy());
        }
    }
}

在显示命令的执行命令方法中,在两个界面显示了过后,使用SendNotification函数发送更新信息通知,并通过游戏外观类得到玩家数据代理再得到玩家数据作为参数传进去。

public class ShowPanelCommand : SimpleCommand
{
    public override void Execute(INotification notification)
    {
        base.Execute(notification);
        //写面板创建的逻辑 
        string panelName = notification.Body.ToString();
        
        switch (panelName)
        {
            case "MainPanel":
                //显示面板相关内容
                
                //如果要使用Mediator 一定也要在Facade中去注册
                //command、proxy都是一样的 要用 就要注册
                //可以在命令 中 直接使用Facade代表的就是唯一的 Facade
                
                //判断如果没有mediator就去new一个 
                if (!Facade.HasMediator(NewMainViewMediator.NAME))
                {
                    Facade.RegisterMediator(new NewMainViewMediator());
                }
                //有mediator了 下一步 就是去创建界面 创建预设体 
                
                //Facade 得到Mediator的方法
                NewMainViewMediator mm = Facade.RetrieveMediator(NewMainViewMediator.NAME) as NewMainViewMediator;
                //实例化面板对象
                if (mm.ViewComponent == null)
                {
                    GameObject res = Resources.Load<GameObject>("UI/MainPanel");
                    GameObject obj = GameObject.Instantiate(res);
                    //设置它的父对象 为Canvas
                    obj.transform.SetParent(GameObject.Find("Canvas").transform, false);
                    //得到预设体上的 view脚本 关联到 mediator上
                    mm.SetView(obj.GetComponent<NewMainView>());
                }
                //往往现实了面板后 需要在这里进行第一次更新
                //需要把 数据一起通过参数 传出去
                SendNotification(PureNotification.UPDATE_PLAYER_INFO, Facade.RetrieveProxy(PlayerProxy.NAME).Data);
                
                break;
            case "RolePanel":
                //判断如果没有mediator就去new一个 
                if (!Facade.HasMediator(NewRoleViewMediator.NAME))
                {
                    Facade.RegisterMediator(new NewRoleViewMediator());
                }
                //有mediator了 下一步 就是去创建界面 创建预设体 
                
                //Facade 得到Mediator的方法
                NewRoleViewMediator rm = Facade.RetrieveMediator(NewRoleViewMediator.NAME) as NewRoleViewMediator;
                //实例化面板对象
                if (rm.ViewComponent == null)
                {
                    GameObject res = Resources.Load<GameObject>("UI/RolePanel");
                    GameObject obj = GameObject.Instantiate(res);
                    //设置它的父对象 为Canvas
                    obj.transform.SetParent(GameObject.Find("Canvas").transform, false);
                    //得到预设体上的 view脚本 关联到 mediator上
                    rm.SetView(obj.GetComponent<NewRoleView>());
                }
                SendNotification(PureNotification.UPDATE_PLAYER_INFO, Facade.RetrieveProxy(PlayerProxy.NAME).Data);
                break;
        }
    }
}

为什么发送更新通知会生效了?因为我们在界面中介者脚本中重写监听通知的方法监听了更新通知,并重写处理通知的方法处理通知。同时要注意处理通知时对面板对象的判空处理,否则可能导致空指针报错。

//重写监听通知的方法
public override string[] ListNotificationInterests()
{
    //这是一个PureMVC的规则
    //就是你需要监听哪些通知 那就在这里把通知们通过字符串数组的形式返回出去
    //PureMVC就会帮助我们监听这些通知 
    // 类似于 通过事件名 注册事件监听
    return new string[]{
        PureNotification.UPDATE_PLAYER_INFO,
    };
}

//重写处理通知的方法
public override void HandleNotification(INotification notification)
{
    //INotification 对象 里面包含两个队我们来说 重要的参数
    //1.通知名 notification.Name 我们根据这个名字 来做对应的处理
    //2.通知包含的信息 notification.Body 可以理解为通知参数 可以进行as转换
    
    //ViewComponent代表着实际面板对象
    switch (notification.Name)
    {
        case PureNotification.UPDATE_PLAYER_INFO:
            //收到 更新通知的时候 做处理 
            if (ViewComponent != null)
            {
                (ViewComponent as NewMainView).UpdateInfo(notification.Body as PlayerDataObj);
            }
            break;
    }
}

创建升级命令脚本。执行是得到游戏外观的玩家数据代理,只要得到的玩家数据不为空就升级并保存数据,并且通知更新。

public class LevUpCommand : SimpleCommand
{
    public override void Execute(INotification notification)
    {
        base.Execute(notification);
        
        //得到数据代理 调用升级 升级完成后通知别人 更新数据
        PlayerProxy playerProxy = Facade.RetrieveProxy(PlayerProxy.NAME) as PlayerProxy;
        
        if (playerProxy != null)
        {
            //升级
            playerProxy.LevUp();
            playerProxy.SaveData();
            //通知更新
            SendNotification(PureNotification.UPDATE_PLAYER_INFO, playerProxy.Data);
        }
    }
}

在游戏外观中注册升级命令绑定通知。

protected override void InitializeController()
{
    base.InitializeController();
    //这里面要写一些 关于 命令和通知 绑定的逻辑
    RegisterCommand(PureNotification.START_UP,() =>
    {
        return new StartUpCommand();
    });
    
    RegisterCommand(PureNotification.SHOW_PANEL, () =>
    {
        return new ShowPanelCommand();
    });
    
    RegisterCommand(PureNotification.HIDE_PANEL, () =>
    {
        return new HidePanelCommand();
    });
    
    RegisterCommand(PureNotification.LEV_UP, () =>
    {
        return new LevUpCommand();
    });
}

27.2 知识点代码

StartUpCommand

using PureMVC.Interfaces;
using PureMVC.Patterns.Command;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class StartUpCommand : SimpleCommand
{
    //1.继承Command相关的脚本
    //2.重写里面的执行函数
    public override void Execute(INotification notification)
    {
        base.Execute(notification);
        //当命令被执行时 就会调用该方法
        //启动命令中 往往是做一些初始化操作

        //没有这个数据代理 才注册 有了就别注册
        if( !Facade.HasProxy(PlayerProxy.NAME) )
        {
            Facade.RegisterProxy(new PlayerProxy());
        }
    }

}

ShowPanelCommand

using PureMVC.Interfaces;
using PureMVC.Patterns.Command;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ShowPanelCommand : SimpleCommand
{
    public override void Execute(INotification notification)
    {
        base.Execute(notification);
        //写面板创建的逻辑 
        string panelName = notification.Body.ToString();

        switch(panelName)
        {
            case "MainPanel":
                //显示面板相关内容

                //如果要使用Mediator 一定也要在Facade中去注册
                //command、proxy都是一样的 要用 就要注册
                //可以在命令 中 直接使用Facade代表的就是唯一的 Facade

                //判断如果没有mediator就去new一个 
                if( !Facade.HasMediator(NewMainViewMediator.NAME) )
                {
                    Facade.RegisterMediator(new NewMainViewMediator());
                }
                //有mediator了 下一步 就是去创建界面 创建预设体 

                //Facade 得到Mediator的方法
                NewMainViewMediator mm = Facade.RetrieveMediator(NewMainViewMediator.NAME) as NewMainViewMediator;
                //实例化面板对象
                if (mm.ViewComponent == null)
                {
                    GameObject res = Resources.Load<GameObject>("BaseFramework/UI/UGUI/PureMVC/MainPanel");
                    GameObject obj = GameObject.Instantiate(res);
                    //设置它的父对象 为Canvas
                    obj.transform.SetParent(GameObject.Find("UGUICanvas").transform, false);
                    //得到预设体上的 view脚本 关联到 mediator上
                    mm.SetView(obj.GetComponent<NewMainView>());
                }
                //往往现实了面板后 需要在这里进行第一次更新
                //需要把 数据一起通过参数 传出去
                SendNotification(PureNotification.UPDATE_PLAYER_INFO, Facade.RetrieveProxy(PlayerProxy.NAME).Data);

                break;
            case "RolePanel":
                //判断如果没有mediator就去new一个 
                if (!Facade.HasMediator(NewRoleViewMediator.NAME))
                {
                    Facade.RegisterMediator(new NewRoleViewMediator());
                }
                //有mediator了 下一步 就是去创建界面 创建预设体 

                //Facade 得到Mediator的方法
                NewRoleViewMediator rm = Facade.RetrieveMediator(NewRoleViewMediator.NAME) as NewRoleViewMediator;
                //实例化面板对象
                if (rm.ViewComponent == null)
                {
                    GameObject res = Resources.Load<GameObject>("BaseFramework/UI/UGUI/PureMVC/RolePanel");
                    GameObject obj = GameObject.Instantiate(res);
                    //设置它的父对象 为Canvas
                    obj.transform.SetParent(GameObject.Find("UGUICanvas").transform, false);
                    //得到预设体上的 view脚本 关联到 mediator上
                    rm.SetView(obj.GetComponent<NewRoleView>());
                }
                SendNotification(PureNotification.UPDATE_PLAYER_INFO, Facade.RetrieveProxy(PlayerProxy.NAME).Data);
                break;
        }
    }
}

LevUpCommand

using PureMVC.Interfaces;
using PureMVC.Patterns.Command;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class LevUpCommand : SimpleCommand
{
    public override void Execute(INotification notification)
    {
        base.Execute(notification);

        //得到数据代理 调用升级 升级完成后通知别人 更新数据
        PlayerProxy playerProxy = Facade.RetrieveProxy(PlayerProxy.NAME) as PlayerProxy;

        if( playerProxy != null )
        {
            //升级
            playerProxy.LevUp();
            playerProxy.SaveData();
            //通知更新
            SendNotification(PureNotification.UPDATE_PLAYER_INFO, playerProxy.Data);
        }


    }
}

GameFacade

using PureMVC.Interfaces;
using PureMVC.Patterns.Facade;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

//1.继承PureMVC中Facade脚本
public class GameFacade : Facade
{
    //2.为了方便我们使用Facade 需要自己写一个单例模式的属性
    public static GameFacade Instance
    {
        get
        {
            if (instance == null)
            {
                instance = new GameFacade();
            }
            return instance as GameFacade;
        }
    }

    /// <summary>
    /// 3.初始化 控制层相关的内容
    /// </summary>
    protected override void InitializeController()
    {
        base.InitializeController();
        //这里面要写一些 关于 命令和通知 绑定的逻辑
        RegisterCommand(PureNotification.START_UP, () =>
        {
            return new StartUpCommand();
        });

        RegisterCommand(PureNotification.SHOW_PANEL, () =>
        {
            return new ShowPanelCommand();
        });

        RegisterCommand(PureNotification.HIDE_PANEL, () =>
        {
            return new HidePanelCommand();
        });

        RegisterCommand(PureNotification.LEV_UP, () =>
        {
            return new LevUpCommand();
        });
    }

    //4.一定是有一个启动函数的
    public void StartUp()
    {
        //发送通知
        SendNotification(PureNotification.START_UP);

        //SendNotification(PureNotification.SHOW_PANEL, "MainPanel");
    }
}


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com

×

喜欢就点赞,疼爱就打赏