/** * セットされているレシーバーへと、byte[]を送付する * 受け取った側ではデシリアライズが行われ、以降デシリアライズされた状態でデータが伝搬する */ public void SendTo(byte[] data, params Type[] targetReceiverTypes) { // メッセージ型の特定 var messageType = TypeIdentificationResolver.DetermineMessageType(data); foreach (var targetReceiverType in targetReceiverTypes) { if (receiverType_messageType_deserializeActionDict.ContainsKey(targetReceiverType)) { var actionList = receiverType_messageType_deserializeActionDict[targetReceiverType]; if (actionList != null) { foreach (var action in actionList) { // このアクションのターゲットがこのデータの形式にマッチしなければ無視 if (messageType != action.Key) { continue; } // 実行 action.Value(data); } } } } }
/** * 特定の型に対して、特定のデータ型が来た時に、そのデータ型をインスタンスで受け取るメソッドを登録 */ public void SetReceiver <T_CurrentMessage> (Action <T_CurrentMessage> action) where T_CurrentMessage : T, new() { if (action.Target != null) { // do nothing. } else { throw new Exception("action should be defined as function. not lambda."); } var actionOwnerType = action.Target.GetType(); // determine data type. var messageTypeKey = TypeIdentificationResolver.DetermineMessageType <T_CurrentMessage>(); { if (!receiverType_messageType_actionDict.ContainsKey(actionOwnerType)) { receiverType_messageType_actionDict[actionOwnerType] = new Dictionary <MessageType, Action <T> >(); } /* * non deserialized data transfer. * deserialized data -> execute action. */ Action <T> executeAct = deserializedData => { // execute act. action((T_CurrentMessage)deserializedData); }; receiverType_messageType_actionDict[actionOwnerType][messageTypeKey] = executeAct; } { if (!receiverType_messageType_deserializeActionDict.ContainsKey(actionOwnerType)) { receiverType_messageType_deserializeActionDict[actionOwnerType] = new Dictionary <MessageType, Action <byte[]> >(); } /* * deserialize and transfer action. * byte -> data type -> execute action. */ Action <byte[]> deserializeAndExecuteAct = baseDataBytes => { var receivedData = TypeIdentificationResolver.Deserialize <T_CurrentMessage>(baseDataBytes); // execute act. action((T_CurrentMessage)receivedData); }; receiverType_messageType_deserializeActionDict[actionOwnerType][messageTypeKey] = deserializeAndExecuteAct; } }
public void RemoveReceiver <T_MessageType, T_TypeOfReceiver> () where T_MessageType : T, new() { var messageType = TypeIdentificationResolver.DetermineMessageType <T_MessageType>(); if (receiverType_messageType_actionDict.ContainsKey(typeof(T_TypeOfReceiver))) { receiverType_messageType_actionDict[typeof(T_TypeOfReceiver)].Remove(messageType); } if (receiverType_messageType_deserializeActionDict.ContainsKey(typeof(T_TypeOfReceiver))) { receiverType_messageType_deserializeActionDict[typeof(T_TypeOfReceiver)].Remove(messageType); } }
public void Input(byte[] data) { switch (state) { case BattleState.None: { // do nothing. break; } case BattleState.Running: { // この時にイベントを受け取らせたいクラスを指定し、受け取り用に登録されているメソッドを着火する。 // 該当するデータ型のレシーバが登録されていなければ無視される。 // パターンその1、データの型を完全に無視してbyte[]のまま特定の下流型に流す。 // 下流では指定した型のデータのみを受け取ることができる。 { Dispatchers <MessageBase> .DispatchRoute <SourceEmitter>().SendTo(data, typeof(WantToReceiveMessage1)); } // パターンその2、ここでデシリアライズして、デシリアライズしたデータを特定の下流型に流す。 // この書き方だと、ここで全てのデータのデシリアライズを記述しなければいけなくてダルい(避けたくて上のパターンがある)。 { // determine type here. var deserializeType = TypeIdentificationResolver.DetermineMessageType(data); switch (deserializeType) { case MessageType._1: { var deserializedData1 = TypeIdentificationResolver.Deserialize <Message1>(data); Dispatchers <MessageBase> .DispatchRoute <SourceEmitter>().Relay(deserializedData1, typeof(WantToReceiveMessage1)); break; } case MessageType._2: { var deserializedData2 = TypeIdentificationResolver.Deserialize <Message2>(data); Dispatchers <MessageBase> .DispatchRoute <SourceEmitter>().Relay(deserializedData2, typeof(WantToReceiveMessage1)); break; } } } break; } } }
/** * デシリアライズが済んでいるデータをそのまま次のディスパッチャへと伝える */ public void Relay(T dataSource, params Type[] targetReceiverTypes) { // メッセージ型の特定 var messageType = TypeIdentificationResolver.DetermineMessageType(dataSource); foreach (var targetReceiverType in targetReceiverTypes) { if (receiverType_messageType_actionDict.ContainsKey(targetReceiverType)) { var actionList = receiverType_messageType_actionDict[targetReceiverType]; foreach (var action in actionList) { // このアクションのターゲットがこのkindでなければ無視 if (messageType != action.Key) { continue; } // 実行 action.Value(dataSource); } } } }