Unity-GUI设计模式-基于观察者模式的设计
在最近的项目工程中。用到了观察者模式。记录一下。
首先,展示一下观察者与被观察者的接口
被观察者IObviewer接口,定义了三个函数。
1.添加观察者 addViewer()
2.删除观察者 deleteViewer()
3.广播 broadCast()
观察者IViewer接口,定义了三个函数。
1.观察者接收广播后的操作 updae()
====然后,给出一个实例:
当我在场景Baseboard中定义好新的底板模型,并且存入xml中后,
1:需要返回到主场景MainScene中
2:需要在主场景的下拉框中,显示:我之前定义好的底板模型。
由于两个场景不互通。只有static静态的数据才可以被获取。
【1】首先要设置状态onRebackFromInsBaseBoard,从InsBaseBoard场景跳转回来之后设定非空。
public class DataCatche : MonoBehaviour {
/// <summary>
/// 我从InsBaseBoard回来之后,只有从那个场景跳转会MainScene时才会设定非空
/// </summary>
public static int onRebackFromInsBaseBoard = -1;
}
【2】在按下保存底板类型button后,改变onRebackFromInsBaseBoard,返回主界面
//按下button的函数中写:
DataCatche.onRebackFromInsBaseBoard = int.Parse(baseboard_type);
SceneManager.LoadScene("MainScene");
============ 【被观察者】MainInitManager================
在localManger下创建delayInit,挂上MainInitManager的脚本,
【3】MainInitManager实现了,在第三帧中加载数据
(1)加载观察者列表 addViewer(CustomController.Instance);
(2)第三帧 StartCoroutine(delayInit());
(3)获取两个参数:要显示的底板的id 以及 下拉框的value。
(4)向观察者们广播
ViewInfo info = new ViewInfo();
info.arg1 = value+"";
info.arg3 = reData;
broadCast(info);
(2) 重新加载loadxml:ConfigFile.Instance.LoadXml();
因为在跳转之后,更新xml是只更新【ROM】的数据,但是动态加载的【RAM】数据(static)没有被更新。所以需要重新加载loadXML
public class MainInitManager : MonoBehaviour, IObviewer
{
public Dropdown Baseboard_Type;
/// <summary>
/// 存储观察者
/// </summary>
List<IViewer> viewList = new List<IViewer>();
// Use this for initialization
void Start () {
addViewer(CustomController.Instance);//加载观察者
StartCoroutine(delayInit()); //第三帧
}
IEnumerator delayInit(){
yield return new WaitForSeconds(Time.deltaTime);
ConfigFile.Instance.LoadXml();//重新加载loadxml
List<string> Baseboard_tempList = new List<string>();
if (DataCatche.onRebackFromInsBaseBoard != null && DataCatche.onRebackFromInsBaseBoard!=-1 )
{
Debug.Log(DataCatche.onRebackFromInsBaseBoard);
//从存有baseboard的字典里面获取id对应属性
foreach (BaseboardData element in BaseboardData.Baseboard_dic.Values)
{
Baseboard_tempList.Add(element.id);
}
BaseboardData reData ;
int value = getDdValue(DataCatche.onRebackFromInsBaseBoard + "", Baseboard_tempList, out reData);
//value 是返回的option的value“0,1,2,3”
//reData是字典中baseBoard_id对应的BaseboardData
ViewInfo info = new ViewInfo();
info.arg1 = value+"";
info.arg3 = reData;
broadCast(info);
}
}
void Update () {
}
//调用接口的函数
public void addViewer(IViewer view)
{
viewList.Add(view);
}
public void deleteViewer(IViewer view)
{
viewList.Remove(view);
}
public void broadCast(ViewInfo info)
{
foreach (IViewer view in viewList)
{
view.update(info);
}
}
}
getDdValue函数:获取value 以及BaseboardData
//获取value 以及BaseboardData
public static int getDdValue(string baseBoard_id, List<string> opTions, out BaseboardData data)
{
data = BaseboardData.Baseboard_dic[baseBoard_id];
for(int i =0;i<opTions.Count;i++)
{
if (opTions[i] == baseBoard_id)
{
return i;
}
}
return 0;
}
onRebackOption函数:更新下拉框的value
public void onRebackOption(BaseboardData _reData, int _value)
{
MainSceneCustomPage page = (MainSceneCustomPage)MainScenePage.stackDic["MainSceneCustomPage"];
//找到下拉框资源
Baseboard_Type = page.baseboard_Dropdown;
//在存列表的字典中,找到在config文件中的“下拉框”子节点对应列表;
List<string> Baseboard_tempList = new List<string>();
Baseboard_Type.value = _value;
}
============ 【观察者】CustomController================ ```
加载onClickCustom()
接收广播的参数
更新下拉框的value
public void update(ViewInfo info)
{
MainFuncPage.Instance.onClickCustom();
int value = int.Parse(info.arg1);
BaseboardData data = (BaseboardData)info.arg3;
Debug.Log("接受的参数:" + value);
//
setDropDownView(page.baseboard_Dropdown, value+1);
}
public void setDropDownView(Dropdown dn,int value)
{
dn.value = value;
}