基底部の宣言
- メッセージの送受信者とメッセージ自体のインターフェース及び、メッセージリスナーとメッセージのハブのクラスを宣言する
- メッセージの送信者と受信者は任意のクラスでインターフェースを実装して用意する
- メッセージは処理の目的単位でインターフェースを実装したクラスを作成する想定
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
namespace MyObserver {
public class ObserverManager {
private static ObserverManager mInstance;
public static void Init () { mInstance = new ObserverManager(); }
public static ObserverManager Instance { get { return mInstance; } }
List<Listener> listeners = new List<Listener> ();
public void RegisterListener (Listener l) {
listeners.Add (l);
}
public void SendToListners (IMessage m) {
foreach (var f in listeners.FindAll(l => l.eventName == m.eventName)) {
f.observer.GetType().GetMethod(f.methodName).Invoke(f.observer, new object[]{ m });
}
}
}
public class Listener {
public string eventName;
public IObserver observer;
public string methodName;
public Listener (string e, IObserver o, string m) {
eventName = e;
observer = o;
methodName = m;
}
}
public interface IObserver {
}
public interface ISubject {
}
public interface IMessage {
ISubject subject { get; set; }
string eventName { get; set; }
}
}
個別実装部とテスト
- メッセージ送信者と受信者、メッセージをそれぞれ実装
- Unity Test Tools を使って動作確認をしたいので、"Unity Test Tools" を Asset Store からインポートする
- スクリプトを Unity Test Tools の対象にするため "Editor" というフォルダを作成し、その下に配置する
- テストの実行は [Unity Test Tools] > [Unit Test Runner] でテスト用のビューを開いて、実行ボタンの押下する
using UnityEngine;
using System.Collections;
using NUnit.Framework;
using MyObserver;
namespace MyObserver.Test {
public class ObserverA : IObserver {
private int count;
public int Count { get { return count; } }
public ObserverA () {
count = 0;
ObserverManager.Instance.RegisterListener (new Listener ("ObserverA", this, "IncrCount"));
}
public void IncrCount (MessageA m) {
count++;
Debug.Log ("message value is " + m.eventValue);
}
}
public class SubjectA : ISubject {
public void SendMessage () {
ObserverManager.Instance.SendToListners (new MessageA (this, "ObserverA", "send message from SubjectA"));
}
}
public class MessageA : IMessage {
public ISubject subject { get; set; }
public string eventName { get; set; }
public string eventValue { get; set; }
public MessageA (ISubject s, string n, string v) {
subject = s;
eventName = n;
eventValue = v;
}
}
[TestFixture]
[Category("MyObserver")]
internal class ObserverTest {
[Test]
public void MyObserverTest () {
ObserverManager.Init ();
ObserverA o = new ObserverA ();
SubjectA s = new SubjectA ();
s.SendMessage ();
Assert.That (o.Count == 1);
s.SendMessage ();
s.SendMessage ();
Assert.That (o.Count == 3);
}
}
}