private void DoCall(Node Target) { switch (Type) { case TypeOfCall.RPC: MethodInfo methodInfo = MDStatics.GetMethodInfo(Target, Convert.ToInt32(Name)); if (methodInfo == null) { MDLog.Fatal(LOG_CAT, $"Could not find method {Target.GetType().ToString()}#{Name}"); return; } object[] convertedParams = MDStatics.ConvertParametersBackToObject(methodInfo, Parameters); MDStatics.GetReplicator().RpcSenderId = SenderPeerId; methodInfo.Invoke(Target, convertedParams); MDStatics.GetReplicator().RpcSenderId = -1; break; case TypeOfCall.RSET: MemberInfo memberInfo = MDStatics.GetMemberInfo(Target, Name); IMDDataConverter Converter = MDStatics.GetConverterForType(memberInfo.GetUnderlyingType()); object value = Converter.ConvertBackToObject(memberInfo.GetValue(Target), Parameters); MDLog.Trace(LOG_CAT, $"Setting {Name} on {Target.Name} to value {value}"); memberInfo.SetValue(Target, value); break; } }
/// /// <summary> /// Invoke the method with the given number on the node /// </summary> /// <param name="MethodNumber">The method number to invoke</param> /// <param name="Parameters">Parameters</param> /// <returns>True if invoked, false if not found</returns> public static bool Invoke(this Node Instance, int MethodNumber, params object[] Parameters) { MethodInfo Info = MDStatics.GetMethodInfo(Instance, MethodNumber); if (Info != null) { MDLog.Trace(LOG_CAT, $"Invoking {Info.Name} with parameters {MDStatics.GetParametersAsString(Parameters)}"); Info.Invoke(Instance, Parameters); return(true); } MDLog.Trace(LOG_CAT, $"Failed to invoke method number {MethodNumber} with parameters {MDStatics.GetParametersAsString(Parameters)}"); return(false); }
/// <summary> /// Sends a clocked RPC call to another client /// </summary> /// <param name="PeerId">The peer to send to</param> /// <param name="Reliability">Reliability to send at</param> /// <param name="Target">The node that is the target of our rpc call</param> /// <param name="Method">The method we want to invoke on the node</param> /// <param name="Parameters">Parameters for the call</param> public void SendClockedRpc(int PeerId, MDReliability Reliability, Node Target, string Method, params object[] Parameters) { if (PeerId == MDStatics.GetPeerId()) { // This is to ourselves so just invoke RpcSenderId = PeerId; Target.Invoke(Method, Parameters); RpcSenderId = -1; return; } MDRemoteMode Mode = MDStatics.GetMethodRpcType(Target, Method, Parameters); int MethodNumber = MDStatics.GetMethodNumber(Target, Method, Parameters); if (MethodNumber == -1) { // Abort MDLog.Fatal(LOG_CAT, $"Could not find method number for {Target.GetType().ToString()}#{Method}({MDStatics.GetParametersAsString(Parameters)})"); return; } MethodInfo MethodInfo = MDStatics.GetMethodInfo(Target, MethodNumber); object[] SendingParams = MDStatics.ConvertParametersForSending(MethodInfo, Parameters); switch (Mode) { case MDRemoteMode.Master: if (!Target.IsNetworkMaster()) { // Remote invoke master only SendClockedCall(PeerId, ClockedRemoteCall.TypeOfCall.RPC, Reliability, Target.GetPath(), MethodNumber.ToString(), Mode, SendingParams); } break; case MDRemoteMode.MasterSync: if (!Target.IsNetworkMaster()) { // Remote invoke master only SendClockedCall(PeerId, ClockedRemoteCall.TypeOfCall.RPC, Reliability, Target.GetPath(), MethodNumber.ToString(), Mode, SendingParams); } Target.Invoke(Method, Parameters); break; case MDRemoteMode.Puppet: case MDRemoteMode.Remote: // Remote invoke SendClockedCall(PeerId, ClockedRemoteCall.TypeOfCall.RPC, Reliability, Target.GetPath(), MethodNumber.ToString(), Mode, SendingParams); break; case MDRemoteMode.PuppetSync: case MDRemoteMode.RemoteSync: // Remote invoke and local invoke SendClockedCall(PeerId, ClockedRemoteCall.TypeOfCall.RPC, Reliability, Target.GetPath(), MethodNumber.ToString(), Mode, SendingParams); Target.Invoke(Method, Parameters); break; } }