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

This commit is contained in:
vis2k 2018-07-26 14:19:29 +02:00
parent d7539fcef3
commit 75351927c1
4 changed files with 42 additions and 44 deletions

View File

@ -139,14 +139,29 @@ public override void Serialize(NetworkWriter writer)
}
// ---------- System Messages requried for code gen path -------------------
/* These are not used directly but manually serialized, these are here for reference.
public struct CommandMessage
class CommandMessage : MessageBase
{
public NetworkInstanceId netId;
public int cmdHash;
public string cmdName;
public byte[] payload;
public byte[] payload; // the parameters for the Cmd function
public override void Deserialize(NetworkReader reader)
{
netId = reader.ReadNetworkId();
cmdHash = 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(cmdHash);
writer.WriteBytesAndSize(payload);
}
}
/* These are not used directly but manually serialized, these are here for reference.
public struct RPCMessage
{
public NetworkId netId;
@ -168,8 +183,7 @@ internal class SyncListMessage<T> where T: struct
public int itemIndex;
public T item;
}
*/
*/
// ---------- Internal System Messages -------------------

View File

@ -2,6 +2,7 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using UnityEngine.Networking.NetworkSystem;
namespace UnityEngine.Networking
{
@ -52,7 +53,7 @@ NetworkIdentity myView
// ----------------------------- Commands --------------------------------
[EditorBrowsable(EditorBrowsableState.Never)]
protected void SendCommandInternal(NetworkWriter writer, int channelId, string cmdName)
protected void SendCommandInternal(int cmdHash, NetworkWriter writer, int channelId, string cmdName)
{
// local players can always send commands, regardless of authority, other objects must have authority.
if (!(isLocalPlayer || hasAuthority))
@ -67,8 +68,13 @@ protected void SendCommandInternal(NetworkWriter writer, int channelId, string c
return;
}
writer.FinishMessage();
ClientScene.readyConnection.SendBytes(writer.ToArray(), channelId);
// construct the message
CommandMessage message = new CommandMessage();
message.netId = netId;
message.cmdHash = cmdHash;
message.payload = writer.ToArray();
ClientScene.readyConnection.SendByChannel((short)MsgType.Command, message, channelId);
#if UNITY_EDITOR
UnityEditor.NetworkDetailStats.IncrementStat(

View File

@ -1083,20 +1083,19 @@ static void OnRemovePlayerMessage(NetworkMessage netMsg)
// Handle command from specific player, this could be one of multiple players on a single client
static void OnCommandMessage(NetworkMessage netMsg)
{
int cmdHash = (int)netMsg.reader.ReadPackedUInt32();
var netId = netMsg.reader.ReadNetworkId();
CommandMessage message = netMsg.ReadMessage<CommandMessage>();
var cmdObject = FindLocalObject(netId);
var cmdObject = FindLocalObject(message.netId);
if (cmdObject == null)
{
if (LogFilter.logWarn) { Debug.LogWarning("Instance not found when handling Command message [netId=" + netId + "]"); }
if (LogFilter.logWarn) { Debug.LogWarning("Instance not found when handling Command message [netId=" + message.netId + "]"); }
return;
}
var uv = cmdObject.GetComponent<NetworkIdentity>();
if (uv == null)
{
if (LogFilter.logWarn) { Debug.LogWarning("NetworkIdentity deleted when handling Command message [netId=" + netId + "]"); }
if (LogFilter.logWarn) { Debug.LogWarning("NetworkIdentity deleted when handling Command message [netId=" + message.netId + "]"); }
return;
}
@ -1108,13 +1107,13 @@ static void OnCommandMessage(NetworkMessage netMsg)
{
if (uv.clientAuthorityOwner != netMsg.conn)
{
if (LogFilter.logWarn) { Debug.LogWarning("Command for object without authority [netId=" + netId + "]"); }
if (LogFilter.logWarn) { Debug.LogWarning("Command for object without authority [netId=" + message.netId + "]"); }
return;
}
}
if (LogFilter.logDev) { Debug.Log("OnCommandMessage for netId=" + netId + " conn=" + netMsg.conn); }
uv.HandleCommand(cmdHash, netMsg.reader);
if (LogFilter.logDev) { Debug.Log("OnCommandMessage for netId=" + message.netId + " conn=" + netMsg.conn); }
uv.HandleCommand(message.cmdHash, new NetworkReader(message.payload));
}
static internal void SpawnObject(GameObject obj)

View File

@ -1129,13 +1129,9 @@ public void CallCmdThrust(float thrusting, int spin)
}
NetworkWriter networkWriter = new NetworkWriter();
networkWriter.Write(0);
networkWriter.Write((ushort)MsgType.SYSTEM_COMMAND);
networkWriter.WritePackedUInt32((uint)ShipControl.kCmdCmdThrust);
networkWriter.WritePackedUInt32((uint)playerId);
networkWriter.Write(thrusting);
networkWriter.WritePackedUInt32((uint)spin);
base.SendCommandInternal(networkWriter);
base.SendCommandInternal(ShipControl.kCmdCmdThrust, networkWriter, channelId, cmdName);
}
*/
MethodDefinition ProcessCommandCall(MethodDefinition md, CustomAttribute ca)
@ -1180,34 +1176,16 @@ MethodDefinition ProcessCommandCall(MethodDefinition md, CustomAttribute ca)
cmdWorker.Append(cmdWorker.Create(OpCodes.Ret));
cmdWorker.Append(localClientLabel);
// NetworkWriter writer = new NetworkWriter();
WriteCreateWriter(cmdWorker);
WriteMessageSize(cmdWorker);
WriteMessageId(cmdWorker, 5); //UNetwork.SYSTEM_COMMAND
// create the command id constant
FieldDefinition cmdConstant = new FieldDefinition("kCmd" + md.Name,
FieldAttributes.Static | FieldAttributes.Private,
Weaver.int32Type);
m_td.Fields.Add(cmdConstant);
// write command constant
cmdWorker.Append(cmdWorker.Create(OpCodes.Ldloc_0));
cmdWorker.Append(cmdWorker.Create(OpCodes.Ldsfld, cmdConstant));
cmdWorker.Append(cmdWorker.Create(OpCodes.Callvirt, Weaver.NetworkWriterWritePacked32));
// write playerId from this NetworkBehaviour
cmdWorker.Append(cmdWorker.Create(OpCodes.Ldloc_0));
cmdWorker.Append(cmdWorker.Create(OpCodes.Ldarg_0));
// load unetviewfield
cmdWorker.Append(cmdWorker.Create(OpCodes.Call, Weaver.getComponentReference));
// load and write netId field
cmdWorker.Append(cmdWorker.Create(OpCodes.Callvirt, Weaver.getUNetIdReference));
var writeFunc = Weaver.GetWriteFunc(Weaver.NetworkInstanceIdType);
cmdWorker.Append(cmdWorker.Create(OpCodes.Callvirt, writeFunc));
// write all the arguments that the user passed to the Cmd call
if (!WriteArguments(cmdWorker, md, "Command", false))
return null;
@ -1229,8 +1207,9 @@ MethodDefinition ProcessCommandCall(MethodDefinition md, CustomAttribute ca)
}
// invoke interal send and return
cmdWorker.Append(cmdWorker.Create(OpCodes.Ldarg_0));
cmdWorker.Append(cmdWorker.Create(OpCodes.Ldloc_0));
cmdWorker.Append(cmdWorker.Create(OpCodes.Ldarg_0)); // load 'base.' to call the SendCommand function with
cmdWorker.Append(cmdWorker.Create(OpCodes.Ldsfld, cmdConstant)); // cmdHash
cmdWorker.Append(cmdWorker.Create(OpCodes.Ldloc_0)); // writer
cmdWorker.Append(cmdWorker.Create(OpCodes.Ldc_I4, channel)); // QoS transport channel (reliable/unreliable)
cmdWorker.Append(cmdWorker.Create(OpCodes.Ldstr, cmdName));
cmdWorker.Append(cmdWorker.Create(OpCodes.Call, Weaver.sendCommandInternal));