| 514 | } |
| 515 | |
| 516 | void SendInParts(NetworkPeer* peer, NetworkChannelType channel, const byte* data, const uint16 dataSize, NetworkMessage& msg, const NetworkRpcName& name, bool toServer, const Guid& objectId, uint32 ownerFrame, NetworkMessageIDs partId) |
| 517 | { |
| 518 | NetworkMessageObjectPartPayload msgDataPayload; |
| 519 | msgDataPayload.DataSize = dataSize; |
| 520 | const uint32 networkKeyIdWorstCaseSize = sizeof(uint32) + sizeof(Guid); |
| 521 | const uint32 msgMaxData = peer->Config.MessageSize - msg.Position - sizeof(NetworkMessageObjectPartPayload); |
| 522 | const uint32 partMaxData = peer->Config.MessageSize - sizeof(NetworkMessageObjectPart) - networkKeyIdWorstCaseSize; |
| 523 | uint32 partsCount = 1; |
| 524 | uint32 dataStart = 0; |
| 525 | uint32 msgDataSize = dataSize; |
| 526 | if (dataSize > msgMaxData) |
| 527 | { |
| 528 | // Send msgMaxData within first message |
| 529 | msgDataSize = msgMaxData; |
| 530 | dataStart += msgMaxData; |
| 531 | |
| 532 | // Send rest of the data in separate parts |
| 533 | partsCount += Math::DivideAndRoundUp(dataSize - dataStart, partMaxData); |
| 534 | |
| 535 | // TODO: promote channel to Ordered when using parts? |
| 536 | } |
| 537 | else |
| 538 | dataStart += dataSize; |
| 539 | ASSERT(partsCount <= MAX_uint8); |
| 540 | msgDataPayload.PartsCount = partsCount; |
| 541 | msgDataPayload.PartSize = msgDataSize; |
| 542 | msg.WriteStructure(msgDataPayload); |
| 543 | msg.WriteBytes(data, msgDataSize); |
| 544 | uint32 messageSize = msg.Length; |
| 545 | if (toServer) |
| 546 | peer->EndSendMessage(channel, msg); |
| 547 | else |
| 548 | peer->EndSendMessage(channel, msg, CachedTargets); |
| 549 | |
| 550 | // Send all other parts |
| 551 | for (uint32 partIndex = 1; partIndex < partsCount; partIndex++) |
| 552 | { |
| 553 | NetworkMessageObjectPart msgDataPart; |
| 554 | msgDataPart.ID = partId; |
| 555 | msgDataPart.OwnerFrame = ownerFrame; |
| 556 | msgDataPart.DataSize = msgDataPayload.DataSize; |
| 557 | msgDataPart.PartsCount = msgDataPayload.PartsCount; |
| 558 | msgDataPart.PartStart = dataStart; |
| 559 | msgDataPart.PartSize = Math::Min(dataSize - dataStart, partMaxData); |
| 560 | msg = peer->BeginSendMessage(); |
| 561 | msg.WriteStructure(msgDataPart); |
| 562 | msg.WriteNetworkId(objectId); |
| 563 | msg.WriteBytes(data + msgDataPart.PartStart, msgDataPart.PartSize); |
| 564 | messageSize += msg.Length; |
| 565 | dataStart += msgDataPart.PartSize; |
| 566 | if (toServer) |
| 567 | peer->EndSendMessage(channel, msg); |
| 568 | else |
| 569 | peer->EndSendMessage(channel, msg, CachedTargets); |
| 570 | } |
| 571 | ASSERT_LOW_LAYER(dataStart == dataSize); |
| 572 | |
| 573 | #if COMPILE_WITH_PROFILER |
no test coverage detected