Weaver Rpc code doesn't manually construct the message anymore. The NetworkWriter is now passed to NetworkBehaviour.SendRPCInternal, where the message is properly constructed. Reduces dependencies on NetworkConnection.SendBytes and avoids expensive GetComponent calls that the Weaver previously generated.

This commit is contained in:
vis2k 2018-07-26 19:15:42 +02:00
parent 75351927c1
commit 1097d000ff
4 changed files with 50 additions and 35 deletions

View File

@ -612,22 +612,21 @@ static void OnUpdateVarsMessage(NetworkMessage netMsg)
static void OnRPCMessage(NetworkMessage netMsg)
{
var cmdHash = (int)netMsg.reader.ReadPackedUInt32();
var netId = netMsg.reader.ReadNetworkId();
RpcMessage message = netMsg.ReadMessage<RpcMessage>();
if (LogFilter.logDebug) { Debug.Log("ClientScene::OnRPCMessage hash:" + cmdHash + " netId:" + netId); }
if (LogFilter.logDebug) { Debug.Log("ClientScene::OnRPCMessage hash:" + message.rpcHash + " netId:" + message.netId); }
NetworkIdentity uv;
if (s_NetworkScene.GetNetworkIdentity(netId, out uv))
if (s_NetworkScene.GetNetworkIdentity(message.netId, out uv))
{
uv.HandleRPC(cmdHash, netMsg.reader);
uv.HandleRPC(message.rpcHash, new NetworkReader(message.payload));
}
else
{
if (LogFilter.logWarn)
{
string errorCmdName = NetworkBehaviour.GetCmdHashHandlerName(cmdHash);
Debug.LogWarningFormat("Could not find target object with netId:{0} for RPC call {1}", netId, errorCmdName);
string errorRpcName = NetworkBehaviour.GetCmdHashHandlerName(message.rpcHash);
Debug.LogWarningFormat("Could not find target object with netId:{0} for RPC call {1}", message.netId, errorRpcName);
}
}
}

View File

@ -161,13 +161,28 @@ public override void Serialize(NetworkWriter writer)
}
}
/* These are not used directly but manually serialized, these are here for reference.
public struct RPCMessage
class RpcMessage : MessageBase
{
public NetworkId netId;
public int cmdHash;
public byte[] payload;
public NetworkInstanceId netId;
public int rpcHash;
public byte[] payload; // the parameters for the Rpc function
public override void Deserialize(NetworkReader reader)
{
netId = reader.ReadNetworkId();
rpcHash = reader.ReadInt32(); // hash is always 4 full bytes, WritePackedInt would send 1 extra byte here
payload = reader.ReadBytesAndSize();
}
public override void Serialize(NetworkWriter writer)
{
writer.Write(netId);
writer.Write(rpcHash);
writer.WriteBytesAndSize(payload);
}
}
/* These are not used directly but manually serialized, these are here for reference.
public struct SyncEventMessage
{
public NetworkId netId;

View File

@ -92,7 +92,7 @@ public virtual bool InvokeCommand(int cmdHash, NetworkReader reader)
// ----------------------------- Client RPCs --------------------------------
[EditorBrowsable(EditorBrowsableState.Never)]
protected void SendRPCInternal(NetworkWriter writer, int channelId, string rpcName)
protected void SendRPCInternal(int rpcHash, NetworkWriter writer, int channelId, string rpcName)
{
// This cannot use NetworkServer.active, as that is not specific to this object.
if (!isServer)
@ -101,8 +101,13 @@ protected void SendRPCInternal(NetworkWriter writer, int channelId, string rpcNa
return;
}
writer.FinishMessage();
NetworkServer.SendBytesToReady(gameObject, writer.ToArray(), channelId);
// construct the message
RpcMessage message = new RpcMessage();
message.netId = netId;
message.rpcHash = rpcHash;
message.payload = writer.ToArray();
NetworkServer.SendByChannelToReady(gameObject, (short)MsgType.Rpc, message, channelId);
#if UNITY_EDITOR
UnityEditor.NetworkDetailStats.IncrementStat(

View File

@ -1368,6 +1368,18 @@ MethodDefinition ProcessTargetRpcCall(MethodDefinition md, CustomAttribute ca)
return rpc;
}
/* generates code like:
public void CallRpcTest (int param)
{
if (!NetworkServer.get_active ()) {
Debug.LogError ((object)"RPC Function RpcTest called on client.");
} else {
NetworkWriter writer = new NetworkWriter ();
writer.WritePackedUInt32((uint)param);
base.SendRPCInternal(Player.kRpcRpcTest, writer, 0, "RpcTest");
}
}
*/
MethodDefinition ProcessRpcCall(MethodDefinition md, CustomAttribute ca)
{
MethodDefinition rpc = new MethodDefinition("Call" + md.Name, MethodAttributes.Public |
@ -1389,34 +1401,17 @@ MethodDefinition ProcessRpcCall(MethodDefinition md, CustomAttribute ca)
WriteCreateWriter(rpcWorker);
WriteMessageSize(rpcWorker);
WriteMessageId(rpcWorker, 2); // UNetwork.SYSTEM_RPC
// create the command id constant
// create the rpc id constant
FieldDefinition rpcConstant = new FieldDefinition("kRpc" + md.Name,
FieldAttributes.Static | FieldAttributes.Private,
Weaver.int32Type);
m_td.Fields.Add(rpcConstant);
// write command constant
rpcWorker.Append(rpcWorker.Create(OpCodes.Ldloc_0));
rpcWorker.Append(rpcWorker.Create(OpCodes.Ldsfld, rpcConstant));
rpcWorker.Append(rpcWorker.Create(OpCodes.Callvirt, Weaver.NetworkWriterWritePacked32));
// write this.unetView.netId
rpcWorker.Append(rpcWorker.Create(OpCodes.Ldloc_0));
rpcWorker.Append(rpcWorker.Create(OpCodes.Ldarg_0));
// load unetviewfield
rpcWorker.Append(rpcWorker.Create(OpCodes.Call, Weaver.getComponentReference));
// load and write netId field
rpcWorker.Append(rpcWorker.Create(OpCodes.Callvirt, Weaver.getUNetIdReference));
rpcWorker.Append(rpcWorker.Create(OpCodes.Callvirt, Weaver.NetworkWriterWriteNetworkInstanceId));
// write all the arguments that the user passed to the Rpc call
if (!WriteArguments(rpcWorker, md, "RPC", false))
return null;
// find channel for SyncEvent
// find channel for Rpc
int channel = 0;
foreach (var field in ca.Fields)
{
@ -1435,6 +1430,7 @@ MethodDefinition ProcessRpcCall(MethodDefinition md, CustomAttribute ca)
// invoke SendInternal and return
rpcWorker.Append(rpcWorker.Create(OpCodes.Ldarg_0)); // this
rpcWorker.Append(rpcWorker.Create(OpCodes.Ldsfld, rpcConstant)); // rpcHash
rpcWorker.Append(rpcWorker.Create(OpCodes.Ldloc_0)); // writer
rpcWorker.Append(rpcWorker.Create(OpCodes.Ldc_I4, channel)); // QoS transport channel (reliable/unreliable)
rpcWorker.Append(rpcWorker.Create(OpCodes.Ldstr, rpcName));