Esempio n. 1
0
        private static void Initialize(out DataStreamWriter self, NativeArray <byte> data)
        {
            self.m_SendHandleData = IntPtr.Zero;

            self.m_Data.capacity     = data.Length;
            self.m_Data.length       = 0;
            self.m_Data.buffer       = (byte *)data.GetUnsafePtr();
            self.m_Data.bitBuffer    = 0;
            self.m_Data.bitIndex     = 0;
            self.m_Data.failedWrites = 0;

#if ENABLE_UNITY_COLLECTIONS_CHECKS
            self.m_Safety = NativeArrayUnsafeUtility.GetAtomicSafetyHandle(data);
#endif
            uint test = 1;
            unsafe
            {
                byte *test_b = (byte *)&test;
                self.m_IsLittleEndian = test_b[0] == 1 ? 1 : 0;
            }
        }
Esempio n. 2
0
        public DataStreamReader(DataStreamWriter writer, int offset, int length)
        {
#if ENABLE_UNITY_COLLECTIONS_CHECKS
            if (offset + length > writer.Length)
            {
                throw new System.ArgumentOutOfRangeException();
            }
            m_Safety = writer.m_Safety;
            AtomicSafetyHandle.UseSecondaryVersion(ref m_Safety);
            AtomicSafetyHandle.SetAllowSecondaryVersionWriting(m_Safety, false);
#endif
            m_bufferPtr = writer.GetUnsafeReadOnlyPtr() + offset;
            m_Length    = length;

            uint test = 1;
            unsafe
            {
                byte *test_b = (byte *)&test;
                IsLittleEndian = test_b[0] == 1;
            }
        }
Esempio n. 3
0
            internal unsafe void ProcessPipelineSend <T>(T driver, int startStage, NetworkPipeline pipeline, NetworkConnection connection,
                                                         NativeSlice <byte> payloadBuffer, NativeList <UpdatePipeline> currentUpdates) where T : struct, INetworkPipelineSender
            {
                NetworkPipelineContext ctx = default(NetworkPipelineContext);

                ctx.timestamp = m_timestamp[0];
                var p            = m_Pipelines[pipeline.Id - 1];
                var connectionId = connection.m_NetworkId;

                var resumeQ      = new NativeList <int>(16, Allocator.Temp);
                int resumeQStart = 0;

                ctx.header = new DataStreamWriter(p.headerCapacity, Allocator.Temp);

                var inboundBuffer = default(InboundBufferVec);

                inboundBuffer.buffer1 = payloadBuffer;

                var prevHeader = new DataStreamWriter(p.headerCapacity, Allocator.Temp);

                while (true)
                {
                    int internalBufferOffset       = p.sendBufferOffset + sizePerConnection[SendSizeOffset] * connectionId;
                    int internalSharedBufferOffset = p.sharedBufferOffset + sizePerConnection[SharedSizeOffset] * connectionId;

                    bool needsUpdate = false;
                    // If this is not the first stage we need to fast forward the buffer offset to the correct place
                    if (startStage > 0)
                    {
                        for (int i = 0; i < startStage; ++i)
                        {
                            internalBufferOffset       += m_StageCollection.GetSendCapacity(m_StageList[p.FirstStageIndex + i]);
                            internalSharedBufferOffset += m_StageCollection.GetSharedStateCapacity(m_StageList[p.FirstStageIndex + i]);
                        }
                    }

                    for (int i = startStage; i < p.NumStages; ++i)
                    {
                        var prevInbound = inboundBuffer;
                        ProcessSendStage(i, internalBufferOffset, internalSharedBufferOffset, p, ref resumeQ, ref ctx, ref inboundBuffer, ref needsUpdate);
                        if (inboundBuffer.buffer1 == prevInbound.buffer1 &&
                            inboundBuffer.buffer2 == prevInbound.buffer2)
                        {
                            if (ctx.header.Length > 0)
                            {
                                if (prevHeader.Length > 0)
                                {
                                    ctx.header.WriteBytes(prevHeader.GetUnsafeReadOnlyPtr(), prevHeader.Length);
                                }
                                prevHeader.Clear();
                                var tempHeader = ctx.header;
                                ctx.header = prevHeader;
                                prevHeader = tempHeader;
                                if (inboundBuffer.buffer2.Length == 0)
                                {
                                    inboundBuffer.buffer2 = inboundBuffer.buffer1;
                                }
                                inboundBuffer.buffer1 = prevHeader.GetNativeSlice(0, prevHeader.Length);
                            }
                        }
                        else
                        {
#if ENABLE_UNITY_COLLECTIONS_CHECKS
                            if (inboundBuffer.buffer2.Length > 0)
                            {
                                throw new InvalidOperationException("Pipeline send stages must return either the unmodified inbound buffers or a consolidated version with a single buffer");
                            }
#endif
                            // Prev header is now part of payload
                            prevHeader.Clear();
                            if (ctx.header.Length > 0)
                            {
                                var tempHeader = ctx.header;
                                ctx.header            = prevHeader;
                                prevHeader            = tempHeader;
                                inboundBuffer.buffer2 = inboundBuffer.buffer1;
                                inboundBuffer.buffer1 = prevHeader.GetNativeSlice(0, prevHeader.Length);
                            }
                        }
                        if (needsUpdate)
                        {
                            AddSendUpdate(connection, i, pipeline, currentUpdates);
                        }
                        if (inboundBuffer.buffer1.Length == 0)
                        {
                            break;
                        }

                        needsUpdate = false;

                        internalBufferOffset       += ctx.internalProcessBuffer.Length;
                        internalSharedBufferOffset += ctx.internalSharedProcessBuffer.Length;
                    }

                    if (inboundBuffer.buffer1.Length != 0)
                    {
                        var iov        = stackalloc network_iovec[4];
                        var pipelineId = pipeline.Id;
                        iov[0].buf = &pipelineId;
                        iov[0].len = 1;
                        iov[1].buf = ctx.header.GetUnsafePtr();
                        iov[1].len = ctx.header.Length;
                        iov[2].buf = inboundBuffer.buffer1.GetUnsafeReadOnlyPtr();
                        iov[2].len = inboundBuffer.buffer1.Length;
                        if (inboundBuffer.buffer2.Length > 0)
                        {
                            iov[3].buf = inboundBuffer.buffer2.GetUnsafeReadOnlyPtr();
                            iov[3].len = inboundBuffer.buffer2.Length;
                            // FIXME: handle send errors
                            driver.Send(connection, iov, 4);
                        }
                        else
                        {
                            driver.Send(connection, iov, 3);
                        }
                    }

                    if (resumeQStart >= resumeQ.Length)
                    {
                        break;
                    }

                    startStage = resumeQ[resumeQStart++];

                    prevHeader.Clear();
                    inboundBuffer = default(InboundBufferVec);
                }
            }
Esempio n. 4
0
 public int Send(NetworkPipeline pipe, NetworkConnection id, DataStreamWriter strm)
 {
     return(m_genericConcurrent.Send(pipe, id, strm));
 }
Esempio n. 5
0
 public int Send(NetworkPipeline pipe, NetworkConnection con, DataStreamWriter strm)
 {
     return(m_genericDriver.Send(pipe, con, strm));
 }
 public int Send <T>(T driver, DataStreamWriter bs) where T : struct, INetworkDriver
 {
     return(driver.Send(this, bs));
 }
        /// <summary>
        /// Constructor for BasicNetworkDriver.
        /// </summary>
        /// <param name="param">
        /// An array of INetworkParameter. There are currently only two <see cref="INetworkParameter"/>,
        /// the <see cref="NetworkDataStreamParameter"/> and the <see cref="NetworkConfigParameter"/>.
        /// </param>
        public BasicNetworkDriver(params INetworkParameter[] param)
        {
            m_timer         = new Timer();
            m_updateTime    = m_timer.ElapsedMilliseconds;
            m_NetworkParams = default(Parameters);
            object boxedParams = m_NetworkParams;

            foreach (var field in typeof(Parameters).GetFields(
                         BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public))
            {
                for (int i = 0; i < param.Length; ++i)
                {
                    if (field.FieldType.IsAssignableFrom(param[i].GetType()))
                    {
                        field.SetValue(boxedParams, param[i]);
                    }
                }
            }

            m_NetworkParams = (Parameters)boxedParams;

            if (m_NetworkParams.config.maxConnectAttempts == 0)
            {
                m_NetworkParams.config.maxConnectAttempts = NetworkParameterConstants.MaxConnectAttempts;
            }

            if (m_NetworkParams.config.connectTimeoutMS == 0)
            {
                m_NetworkParams.config.connectTimeoutMS = NetworkParameterConstants.ConnectTimeoutMS;
            }

            if (m_NetworkParams.config.disconnectTimeoutMS == 0)
            {
                m_NetworkParams.config.disconnectTimeoutMS = NetworkParameterConstants.DisconnectTimeoutMS;
            }

            int initialStreamSize = m_NetworkParams.dataStream.size;

            if (initialStreamSize == 0)
            {
                initialStreamSize = NetworkParameterConstants.DriverDataStreamSize;
            }
            m_DataStream = new DataStreamWriter(initialStreamSize, Allocator.Persistent);

            m_NetworkInterface = new T();
            m_NetworkInterface.Initialize();

            m_NetworkAcceptQueue = new NativeQueue <int>(Allocator.Persistent);

            m_ConnectionList = new NativeList <Connection>(1, Allocator.Persistent);

            m_FreeList   = new NativeQueue <int>(Allocator.Persistent);
            m_EventQueue = new NetworkEventQueue(NetworkParameterConstants.InitialEventQueueSize);

            m_InternalState = new NativeArray <int>(2, Allocator.Persistent);
            m_PendingFree   = new NativeQueue <int>(Allocator.Persistent);

            m_ReceiveCount        = new NativeArray <int>(1, Allocator.Persistent);
            m_SessionIdCounter    = new NativeArray <ushort>(1, Allocator.Persistent);
            m_SessionIdCounter[0] = (ushort)(new Random().Next() & 0xFFFF);
            ReceiveCount          = 0;
            Listening             = false;
        }
Esempio n. 8
0
 public static void WritePackedVector3(this DataStreamWriter writer, Vector3 b,
                                       NetworkCompressionModel compressionModel) => writer.WritePackedFloat3(b, compressionModel);