Recently in learning a blogger wrote about message decoupling code operations, here are my Learning notes about that blog-- message decoupling
Rewrite the code for the messaging mechanism, which establishes the main message queue, callback queue, deferred Message Queuing, and establishes a subscription mechanism between messages, as follows:
namespace Slqj {///<summary>///message distribution, decoupling///</summary> public class Notificationmanager {public static Notificationmanager Instance {get {return singletonprovider<notificationmanager>. Instance;
} public delegate void Msgcallback (Messageobject eb); <summary>///callback Queue///</summary> private dictionary<string, List<msgcallbac
k>> registedcallbacks = new dictionary<string, list<msgcallback>> (); <summary>///Delay Message Queuing///</summary> private readonly list<messageobject> del
Ayednotifymsgs = new list<messageobject> (); <summary>///main message queue///</summary> private readonly list<messageobject> Real
Callbacks = new list<messageobject> ();
private static bool isincalling = FALSE; public void Init () {} public VoID Update () {lock (this) {if (Realcallbacks.count = 0)
{///main message team, add deferred message to main message list foreach (Messageobject eb in Delayednotifymsgs)
{Realcallbacks.add (EB);
} delayednotifymsgs.clear ();
Return
//Adjust the main message to the team column isincalling = true; foreach (Messageobject eb in realcallbacks) {if Registedcallbacks.containskey (EB. Msgname)) {for (int i = 0; i < Registedcallbacks[eb. Msgname]. Count; i++) {Msgcallback ECB = Registedcallbacks[eb.
Msgname][i];
if (ECB = = null) {continue;
} #if Unity_editor ECB (EB);
#else try {ECB (EB);
catch (Exception e) { Debug.logerror ("Callbackerror:" + EB.
Msgname + ":" + e.tostring ());
#endif}} else {Debug.Log ("msg_already_deleted:" + EB.)
Msgname);
} realcallbacks.clear ();
} isincalling = false; public void Reset () {dictionary<string, list<msgcallback>> systemmsg = new Dic
Tionary<string, list<msgcallback>> (); foreach (KeyvaluepaiR<string, list<msgcallback>> item in this.registedcallbacks) {if (item. Key.startswith ("_")) {Systemmsg.add (item). Key, item.
Value);
} this.registedcallbacks = systemmsg;
public void Destroy () {Reset (); ///<summary>///Subscription message///</summary>///<param name= "Msgname" ></ param>///<param name= "msgcallback" ></param> public void Subscribe (string msgname, Msgcall Back Msgcallback} {Lock (this) {if (!registedcallbacks.containskey) (Msgna
Me)) {Registedcallbacks.add (Msgname, New list<msgcallback> ()); {//Prevent duplicate subscription message callback list<msgcallback> List = Registedcallbacks
[Msgname]; for (int i = 0; i < list. Count; i++) {if (List[i].
Equals (Msgcallback)) {return; } list.
ADD (Msgcallback); ///<summary>///unsubscribe///</summary>///<param Name= "Msgname" ></param>///<param name= "msgcallback" ></param> public void Unsubscri Be (string msgname, Msgcallback msgcallback) {lock (this) {if (!registedc Allbacks.
ContainsKey (Msgname)) {return; }//debug.log (Msgname + ":-s-" + registedcallbacks[msgname).
Count); Registedcallbacks[msgname].
Remove (Msgcallback); Debug.Log (Msgname + ":-e-" + registedcallbacks[msgname).
Count);
} public void Printmsg () {String content = "";
foreach (keyvaluepair<string, list<msgcallback>> registedcallback in registedcallbacks) {
int total = RegistedCallback.Value.Count;
if (Total > 0) {content + = Registedcallback.key + ":" + total + "\ n"; for (int i = 0; i < total; i++) {content = "\ t" + Registedcallba Ck. Value[i]. Method.name + "--" + registedcallback.value[i].
Target + "\ n";
///<summary>///to distribute messages///</summary> <param name= "Msgname" ></param>///<param name= "Msgparam" ></param> public
void Notify (String msgname, params object[] msgparam) {object msgvalueparam = null; if (Msgparam!=NULL) {if (Msgparam.length = 1) {Msgvalueparam = Msgpar
AM[0];
else {msgvalueparam = Msgparam;
} lock (This) {if (!registedcallbacks.containskey (msgname))
{return; } if (isincalling) {Delayednotifymsgs.add (new Messageobject (Msgname),
Msgvalueparam));
else {realcallbacks.add (new Messageobject (Msgname, Msgvalueparam));
"}}} public class Messageobject {public Object msgvalue;
public string Msgname; Public Messageobject () {msgname = this. GetType ().
FullName; Public Messageobject (String msgname, OBject ev) {msgvalue = EV;
Msgname = Msgname; }
}
}
In unity, to start this message sending mechanism, you need to start with the following code:
public class Main:monobehaviour {
//initialization
void Awake ()
{
notificationmanager.in Stance. Init ();
}
Update is called once per frame
void Update ()
{
NotificationManager.Instance.Update ()
}
}
Note: You need to call once in each frame application of trigger in handle button event
In fact, is in the code to add a message subscription mechanism, when received a message, notify the whole method of the Message object, and received the message to match, find a qualified message, and then execute its method, the other methods do not have to respond.
<summary>///can add events, and then realize the transfer of the message. </summary>//Reality handle case Event function public class Viveevent:monobehaviour {void Start () {var trackedcon
Troller = getcomponent<steamvr_trackedcontroller> (); if (Trackedcontroller = = null) {Trackedcontroller = Gameobject.addcomponent<steamvr_trackedcontrol
Ler> ();
} trackedcontroller.triggerclicked + = new Clickedeventhandler (ontriggerclicked);
Trackedcontroller.triggerpressdown + = new Clickedeventhandler (ONTRIGGERPRESSDN);
trackedcontroller.triggerunclicked + = new Clickedeventhandler (ontriggerunclicked);
trackedcontroller.padclicked + = new Clickedeventhandler (onpadclicked);
trackedcontroller.padunclicked + = new Clickedeventhandler (onpadunclicked); } void Ontriggerclicked (object sender, Clickedeventargs e) {Debug.Log (E.controllerindex + "trigger click
Ed "); Fire NotificationManager.Instance.Notify (NoTificationType.Gun_Fire.ToString ()); } void Ontriggerpressdn (object sender, Clickedeventargs e) {Debug.Log (E.controllerindex + "trigger Press
Down ");
NotificationManager.Instance.Notify (NotificationType.Gathering_Stength.ToString ()); } void Ontriggerunclicked (object sender, Clickedeventargs e) {Debug.Log (e.controllerindex + "trigger UN
Clicked ");
NotificationManager.Instance.Notify (NotificationType.Gun_KeyUp.ToString ()); } void Onpadclicked (object sender, Clickedeventargs e) {//throwing Thunder NotificationManager.Instance.Notif
Y (NotificationType.Throw_Bomb.ToString ());
Debug.Log (E.controllerindex + "pad clicked"); } void Onpadunclicked (object sender, Clickedeventargs e) {Debug.Log (e.controllerindex + "Padd un Clicke
D ");
}
}
Mainly wrote the Key Trigger press, hold and bounce and pad of press and bounce events.
Then there is the acceptance of the triggering event, which shows the benefits of understanding the decoupling event. Here is really more than just using the VIVE key to handle this here.
public class Controlbuttonans:monobehaviour {//initialization void Start () {notific
AtionManager.Instance.Subscribe (NotificationType.Gun_Fire.ToString (), gunfire);
NotificationManager.Instance.Subscribe (NotificationType.Gathering_Stength.ToString (), gatheringstength);
NotificationManager.Instance.Subscribe (NotificationType.Throw_Bomb.ToString (), Throwbomb);
NotificationManager.Instance.Subscribe (NotificationType.Gun_KeyUp.ToString (), gunkeyup);
} void Gunfire (Messageobject obj) {Debug.Log ("Response gun fire, trigger button click"); } void Gatheringstength (Messageobject obj) {Debug.Log ("Response gathering stength, trigger button hold")
;
} void Gunkeyup (Messageobject obj) {Debug.Log ("Response key up, trigger button unclicked");
} void Throwbomb (Messageobject obj) {Debug.Log ("response throw Bomb, Pad button click");
}
}
After the code is written, add it on the component, as shown in the figure
That would be a success.
The results are as follows--