コード例 #1
0
        /// <summary>
        /// Helper function to write a packet to a stream with an optional <see cref="T:CollatedPacketEncoder"/>.
        /// </summary>
        /// <param name="stream">Stream to write <paramref name="packet"/> to.</param>
        /// <param name="encoder">Optional collated packet encoder. May be null for no collation.</param>
        /// <param name="packet">The packet data to write.</param>
        /// <remarks>
        /// The <paramref name="encoder"/> is flushed if required.
        /// </remarks>
        static void WritePacket(Stream stream, CollatedPacketEncoder encoder, PacketBuffer packet)
        {
            if (packet.Status != PacketBufferStatus.Complete)
            {
                if (!packet.FinalisePacket())
                {
                    throw new IOException("Packet finalisation failed.");
                }
            }

            if (encoder == null)
            {
                stream.Write(packet.Data, 0, packet.Count);
            }
            else
            {
                if (encoder.Add(packet) == -1)
                {
                    // Failed to add. Try flushing the packet first.
                    Flush(stream, encoder);
                    if (encoder.Add(packet) == -1)
                    {
                        // Failed after flush. Raise exception.
                        throw new IOException("Failed to collate data packet after flush.");
                    }
                }
            }
        }
コード例 #2
0
 /// <summary>
 /// Instantiates a <code>TcpClient</code> using the given socket and flags.
 /// </summary>
 /// <param name="socket">Socket.</param>
 /// <param name="serverFlags">Server flags.</param>
 public TcpConnection(TcpClient socket, ServerFlag serverFlags)
 {
     _client     = socket;
     EndPoint    = _client.Client.RemoteEndPoint as IPEndPoint;
     ServerFlags = serverFlags;
     _collator   = new CollatedPacketEncoder((serverFlags & ServerFlag.Compress) == ServerFlag.Compress);
     //_collator.Reset();
     _currentResourceProgress.Reset();
 }
コード例 #3
0
        /// <summary>
        /// A helper function for flushing <paramref name="encoder"/> into <paramref name="stream"/>.
        /// </summary>
        /// <param name="stream">The stream to flush into.</param>
        /// <param name="encoder">The collated packet encoder to flush and reset. May be null (noop).</param>
        static void Flush(Stream stream, CollatedPacketEncoder encoder)
        {
            if (encoder != null)
            {
                // Ensure we have some data to flush.
                if (encoder.CollatedBytes > 0)
                {
                    if (!encoder.FinaliseEncoding())
                    {
                        throw new IOException("Collated encoding finalisation failed.");
                    }

                    stream.Write(encoder.Buffer, 0, encoder.Count);
                    encoder.Reset();
                }
            }
        }
コード例 #4
0
        /// <summary>
        /// Populates <paramref name="stream"/> with a series of data packets describing a simple, multi-frame scene.
        /// </summary>
        /// <param name="stream">The stream to write the scene packets to.</param>
        public static void PopulateScene(Stream stream, bool collate, bool compress)
        {
            CollatedPacketEncoder collator = (collate) ? new CollatedPacketEncoder(compress) : null;
            List <Shape>          shapes   = new List <Shape>();
            PacketBuffer          packet   = new PacketBuffer(16 * 1024);
            uint           objId           = 1;
            Vector3        pos             = new Vector3(0, 0, 0);
            Vector3        posDelta        = new Vector3(0.5f, 0.5f, 0.5f);
            ControlMessage endFrameMsg     = new ControlMessage();

            endFrameMsg.Value32 = 1000000 / 30; // ~30Hz

            // Initialise scene objects.
            shapes.Add(new Arrow(objId++, pos, pos + new Vector3(0.2f, 0, 1), 0.05f));
            pos += posDelta;

            shapes.Add(new Box(objId++, pos, new Vector3(0.2f, 0.3f, 0.5f)));
            pos += posDelta;

            shapes.Add(new Capsule(objId++, pos, pos + new Vector3(0, 0, 2.0f), 0.2f));
            pos += posDelta;

            shapes.Add(new Cone(objId++, pos, pos + new Vector3(0, 0, 1.0f), 0.2f));
            pos += posDelta;

            shapes.Add(new Cylinder(objId++, pos, pos + new Vector3(0, 0, 2.0f), 0.2f));
            pos += posDelta;

            shapes.Add(new Sphere(objId++, pos));
            pos += posDelta;

            shapes.Add(new Plane(objId++, pos, new Vector3(1, 0.5f, 0.3f).Normalised));
            pos += posDelta;

            shapes.Add(new Star(objId++, pos));
            pos += posDelta;

            // Serialise creation packets.
            uint progress = 0;
            int  res      = 0;

            foreach (Shape shape in shapes)
            {
                shape.WriteCreate(packet);
                WritePacket(stream, collator, packet);

                if (shape.IsComplex)
                {
                    while ((res = shape.WriteData(packet, ref progress)) >= 0)
                    {
                        WritePacket(stream, collator, packet);
                    }
                }
            }

            // Write a frame flush.
            packet.Reset((ushort)RoutingID.Control, (ushort)ControlMessageID.EndFrame);
            endFrameMsg.Write(packet);
            WritePacket(stream, collator, packet);
            Flush(stream, collator);

            // Move things around.
            for (int i = 0; i < 100; ++i)
            {
                posDelta = new Vector3(3.0f * (float)Math.Sin(i * (5.0 / Math.PI * 180)), 0, 0);
                foreach (Shape s in shapes)
                {
                    s.Position = s.Position + posDelta;
                    s.WriteUpdate(packet);
                    WritePacket(stream, collator, packet);
                }

                // Write a frame flush.
                packet.Reset((ushort)RoutingID.Control, (ushort)ControlMessageID.EndFrame);
                endFrameMsg.Write(packet);
                WritePacket(stream, collator, packet);
                Flush(stream, collator);
            }

            Flush(stream, collator);
            stream.Flush();
        }
コード例 #5
0
        public void CollationTest(bool compress)
        {
            // Allocate encoder.
            CollatedPacketEncoder encoder = new CollatedPacketEncoder(compress);

            // Create a mesh object to generate some messages.
            List <Vector3> vertices = new List <Vector3>();
            List <Vector3> normals  = new List <Vector3>();
            List <int>     indices  = new List <int>();

            Common.MakeLowResSphere(vertices, indices, normals);

            MeshShape mesh = new MeshShape(Net.MeshDrawType.Triangles, vertices.ToArray(), indices.ToArray());

            mesh.ID      = 42;
            mesh.Normals = normals.ToArray();

            // Use the encoder as a connection.
            // The Create() call will pack the mesh create message and multiple data messages.
            int wroteBytes = encoder.Create(mesh);

            Assert.True(wroteBytes > 0);
            Assert.True(encoder.FinaliseEncoding());

            // Allocate a reader. Contains a CollatedPacketDecoder.
            System.IO.MemoryStream memoryStream = new System.IO.MemoryStream(encoder.Buffer, 0, encoder.Count);
            PacketStreamReader     decoder      = new PacketStreamReader(memoryStream);

            PacketBuffer packet;
            MeshShape    readMesh       = new MeshShape();
            int          packetCount    = 0;
            long         processedBytes = 0;

            while ((packet = decoder.NextPacket(ref processedBytes)) != null)
            {
                NetworkReader reader = new NetworkReader(packet.CreateReadStream(true));
                ++packetCount;
                Assert.True(packet.ValidHeader);
                Assert.Equal(packet.Header.Marker, PacketHeader.PacketMarker);
                Assert.Equal(packet.Header.VersionMajor, PacketHeader.PacketVersionMajor);
                Assert.Equal(packet.Header.VersionMinor, PacketHeader.PacketVersionMinor);

                Assert.Equal(packet.Header.RoutingID, mesh.RoutingID);

                // Peek the shape ID.
                uint shapeId = packet.PeekUInt32(PacketHeader.Size);
                Assert.Equal(shapeId, mesh.ID);

                switch ((ObjectMessageID)packet.Header.MessageID)
                {
                case ObjectMessageID.Create:
                    Assert.True(readMesh.ReadCreate(packet, reader));
                    break;

                case ObjectMessageID.Update:
                    Assert.True(readMesh.ReadUpdate(packet, reader));
                    break;

                case ObjectMessageID.Data:
                    Assert.True(readMesh.ReadData(packet, reader));
                    break;
                }
            }

            Assert.True(packetCount > 0);
            // FIXME: Does not match, but results are fine. processedBytes is 10 greater than wroteBytes.
            //Assert.Equal(processedBytes, wroteBytes);

            // Validate what we've read back.
            ShapeTestFramework.ValidateShape(readMesh, mesh, new Dictionary <ulong, Resource>());
        }