Esempio n. 1
0
 public static unsafe JobHandle ScheduleUnsafeIndex0 <T>(this T jobData, NativeArray <int> forEachCount, int innerloopBatchCount, JobHandle dependsOn = new JobHandle())
     where T : struct, IJobParallelForDefer
 {
     return(jobData.Schedule((int *)NativeArrayUnsafeUtility.GetUnsafeBufferPointerWithoutChecks(forEachCount), innerloopBatchCount, dependsOn));
 }
Esempio n. 2
0
    private void InitializeEntities(EntityManager manager)
    {
        if (count == 0)
        {
            return;
        }
        var entities = new NativeArray <Entity>((int)count, Allocator.TempJob, NativeArrayOptions.UninitializedMemory);

        try
        {
            entities[0] = manager.CreateEntity(ComponentType.Create <Position>(), ComponentType.Create <MeshInstanceRenderer>(), ComponentType.Create <StartTime>(), ComponentType.Create <Velocity>(), ComponentType.Create <DanceMove>(), ComponentType.Create <DanceSystem.Tag>());
            manager.SetSharedComponentData(entities[0], meshInstanceRenderer);
            manager.SetComponentData(entities[0], new StartTime {
                Value = Time.timeSinceLevelLoad
            });
            unsafe
            {
                var rest = NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray <Entity>(((Entity * )NativeArrayUnsafeUtility.GetUnsafePtr(entities)) + 1, entities.Length - 1, Allocator.Temp);
#if ENABLE_UNITY_COLLECTIONS_CHECKS
                NativeArrayUnsafeUtility.SetAtomicSafetyHandle(ref rest, NativeArrayUnsafeUtility.GetAtomicSafetyHandle(entities));
#endif
                manager.Instantiate(entities[0], rest);
            }
            var rand = new Unity.Mathematics.Random((uint)DateTime.Now.Ticks);
            for (int i = 0; i < entities.Length; i++)
            {
                InitializeEntity(ref rand, manager, entities[i]);
            }
        }
        finally
        {
            entities.Dispose();
        }
    }
 public NativeArray <T> GetMipData <T>() where T : struct
 {
     unsafe { return(NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray <T>(mipData, mipDataSize, Allocator.None)); }
 }
        public unsafe ComponentChanges GatherComponentChangesAsync(EntityQuery query, Allocator allocator, out JobHandle jobHandle)
        {
            var chunks = query.CreateArchetypeChunkArrayAsync(Allocator.TempJob, out var chunksJobHandle);
            var allocatedShadowChunksForTheFrame = new NativeArray <ShadowChunk>(chunks.Length, Allocator.TempJob, NativeArrayOptions.UninitializedMemory);
            var gatheredChanges      = new NativeArray <ChangesCollector>(chunks.Length, Allocator.TempJob);
            var removedChunkBuffer   = new NativeList <byte>(Allocator.TempJob);
            var removedChunkEntities = new NativeList <Entity>(Allocator.TempJob);

            var buffer            = new NativeList <byte>(allocator);
            var addedComponents   = new NativeList <Entity>(allocator);
            var removedComponents = new NativeList <Entity>(allocator);

            var changesJobHandle = new GatherComponentChangesJob
            {
                TypeIndex     = m_TypeIndex,
                ComponentSize = m_ComponentSize,
                Chunks        = chunks,
                ShadowChunksBySequenceNumber = m_PreviousChunksBySequenceNumber,
                GatheredChanges = (ChangesCollector *)NativeArrayUnsafeUtility.GetUnsafeBufferPointerWithoutChecks(gatheredChanges)
            }.Schedule(chunks.Length, 1, chunksJobHandle);

            var allocateNewShadowChunksJobHandle = new AllocateNewShadowChunksJob
            {
                TypeIndex     = m_TypeIndex,
                ComponentSize = m_ComponentSize,
                Chunks        = chunks,
                ShadowChunksBySequenceNumber = m_PreviousChunksBySequenceNumber,
                AllocatedShadowChunks        = (ShadowChunk *)NativeArrayUnsafeUtility.GetUnsafeBufferPointerWithoutChecks(allocatedShadowChunksForTheFrame)
            }.Schedule(chunks.Length, 1, chunksJobHandle);

            var copyJobHandle = new CopyComponentDataJob
            {
                TypeIndex     = m_TypeIndex,
                ComponentSize = m_ComponentSize,
                Chunks        = chunks,
                ShadowChunksBySequenceNumber    = m_PreviousChunksBySequenceNumber,
                AllocatedShadowChunks           = (ShadowChunk *)NativeArrayUnsafeUtility.GetUnsafeBufferPointerWithoutChecks(allocatedShadowChunksForTheFrame),
                RemovedChunkComponentDataBuffer = removedChunkBuffer,
                RemovedChunkEntities            = removedChunkEntities
            }.Schedule(JobHandle.CombineDependencies(changesJobHandle, allocateNewShadowChunksJobHandle));

            var concatResultJobHandle = new ConcatResultJob
            {
                ComponentSize   = m_ComponentSize,
                GatheredChanges = gatheredChanges,
                RemovedChunkComponentDataBuffer = removedChunkBuffer.AsDeferredJobArray(),
                RemovedChunkEntities            = removedChunkEntities.AsDeferredJobArray(),

                ComponentDataBuffer = buffer,
                AddedComponents     = addedComponents,
                RemovedComponents   = removedComponents
            }.Schedule(copyJobHandle);

            var handles = new NativeArray <JobHandle>(5, Allocator.Temp)
            {
                [0] = chunks.Dispose(copyJobHandle),
                [1] = gatheredChanges.Dispose(concatResultJobHandle),
                [2] = removedChunkBuffer.Dispose(concatResultJobHandle),
                [3] = removedChunkEntities.Dispose(concatResultJobHandle),
                [4] = allocatedShadowChunksForTheFrame.Dispose(copyJobHandle)
            };

            jobHandle = JobHandle.CombineDependencies(handles);
            handles.Dispose();

            return(new ComponentChanges(m_TypeIndex, buffer, addedComponents, removedComponents));
        }
Esempio n. 5
0
        public unsafe void Update(InputUpdateType type)
        {
            if (!onShouldRunUpdate.Invoke(type))
            {
                return;
            }

            lock (m_Lock)
            {
                if (type == InputUpdateType.Dynamic && !dontAdvanceUnscaledGameTimeNextDynamicUpdate)
                {
                    unscaledGameTime += 1 / 30f;
                    dontAdvanceUnscaledGameTimeNextDynamicUpdate = false;
                }

                if (m_NewDeviceDiscoveries != null && m_NewDeviceDiscoveries.Count > 0)
                {
                    if (onDeviceDiscovered != null)
                    {
                        foreach (var entry in m_NewDeviceDiscoveries)
                        {
                            onDeviceDiscovered(entry.Key, entry.Value);
                        }
                    }
                    m_NewDeviceDiscoveries.Clear();
                }

                onBeforeUpdate?.Invoke(type);

                // Advance time *after* onBeforeUpdate so that events generated from onBeforeUpdate
                // don't get bumped into the following update.
                if (type == InputUpdateType.Dynamic && !dontAdvanceTimeNextDynamicUpdate)
                {
                    currentTime += advanceTimeEachDynamicUpdate;
                    dontAdvanceTimeNextDynamicUpdate = false;
                }

                if (onUpdate != null)
                {
                    var buffer = new InputEventBuffer(
                        (InputEvent *)NativeArrayUnsafeUtility.GetUnsafeBufferPointerWithoutChecks(m_EventBuffer),
                        m_EventCount, m_EventWritePosition, m_EventBuffer.Length);

                    try
                    {
                        onUpdate(type, ref buffer);
                    }
                    catch (Exception e)
                    {
                        // Same order as in NativeInputRuntime
                        Debug.LogException(e);
                        Debug.LogError($"{e.GetType().Name} during event processing of {type} update; resetting event buffer");

                        // Rethrow exception for test runtime to enable us to assert against it in tests.
                        m_EventCount         = 0;
                        m_EventWritePosition = 0;
                        throw;
                    }

                    m_EventCount         = buffer.eventCount;
                    m_EventWritePosition = (int)buffer.sizeInBytes;

                    if (NativeArrayUnsafeUtility.GetUnsafeBufferPointerWithoutChecks(buffer.data) !=
                        NativeArrayUnsafeUtility.GetUnsafeBufferPointerWithoutChecks(m_EventBuffer))
                    {
                        m_EventBuffer = buffer.data;
                    }
                }
                else
                {
                    m_EventCount         = 0;
                    m_EventWritePosition = 0;
                }
            }
        }
Esempio n. 6
0
 public unsafe static int BinarySearch <T, U>(this NativeArray <T> container, T value, U comp)
     where T : unmanaged
     where U : IComparer <T>
 {
     return(BinarySearch((T *)NativeArrayUnsafeUtility.GetUnsafeBufferPointerWithoutChecks(container), container.Length, value, comp));
 }
Esempio n. 7
0
            internal unsafe int ProcessPipelineSend(NetworkDriver.Concurrent driver, int startStage, NetworkPipeline pipeline, NetworkConnection connection,
                                                    NetworkInterfaceSendHandle sendHandle, int headerSize, NativeList <UpdatePipeline> currentUpdates)
            {
                int retval = sendHandle.size;
                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;

#if ENABLE_UNITY_COLLECTIONS_CHECKS
                if (headerSize != p.headerCapacity + UnsafeUtility.SizeOf <UdpCHeader>() + 1 && sendHandle.data != IntPtr.Zero)
                {
                    throw new InvalidOperationException("Invalid header size.");
                }
#endif
                var inboundBuffer = default(InboundSendBuffer);
                if (sendHandle.data != IntPtr.Zero)
                {
                    inboundBuffer.bufferWithHeaders       = (byte *)sendHandle.data + UnsafeUtility.SizeOf <UdpCHeader>() + 1;
                    inboundBuffer.bufferWithHeadersLength = sendHandle.size - UnsafeUtility.SizeOf <UdpCHeader>() - 1;
                    inboundBuffer.buffer       = inboundBuffer.bufferWithHeaders + p.headerCapacity;
                    inboundBuffer.bufferLength = inboundBuffer.bufferWithHeadersLength - p.headerCapacity;
                }

                while (true)
                {
                    headerSize = p.headerCapacity;

                    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)
                    {
#if ENABLE_UNITY_COLLECTIONS_CHECKS
                        if (inboundBuffer.bufferWithHeadersLength > 0)
                        {
                            throw new InvalidOperationException("Can't start from a stage with a buffer");
                        }
#endif
                        for (int i = 0; i < startStage; ++i)
                        {
                            internalBufferOffset       += (m_StageCollection[m_StageList[p.FirstStageIndex + i]].SendCapacity + AlignmentMinusOne) & (~AlignmentMinusOne);
                            internalSharedBufferOffset += (m_StageCollection[m_StageList[p.FirstStageIndex + i]].SharedStateCapacity + AlignmentMinusOne) & (~AlignmentMinusOne);
                            headerSize -= m_StageCollection[m_StageList[p.FirstStageIndex + i]].HeaderCapacity;
                        }
                    }

                    for (int i = startStage; i < p.NumStages; ++i)
                    {
                        int stageHeaderCapacity = m_StageCollection[m_StageList[p.FirstStageIndex + i]].HeaderCapacity;
#if ENABLE_UNITY_COLLECTIONS_CHECKS
                        if (stageHeaderCapacity > headerSize)
                        {
                            throw new InvalidOperationException("Not enough header space");
                        }
#endif
                        inboundBuffer.headerPadding = headerSize;
                        headerSize -= stageHeaderCapacity;
                        if (stageHeaderCapacity > 0 && inboundBuffer.bufferWithHeadersLength > 0)
                        {
                            var headerArray = NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray <byte>(inboundBuffer.bufferWithHeaders + headerSize, stageHeaderCapacity, Allocator.Invalid);
#if ENABLE_UNITY_COLLECTIONS_CHECKS
                            NativeArrayUnsafeUtility.SetAtomicSafetyHandle(ref headerArray, AtomicSafetyHandle.GetTempMemoryHandle());
#endif
                            ctx.header = new DataStreamWriter(headerArray);
                        }
                        else
                        {
                            ctx.header = new DataStreamWriter(stageHeaderCapacity, Allocator.Temp);
                        }
                        var prevInbound = inboundBuffer;
                        ProcessSendStage(i, internalBufferOffset, internalSharedBufferOffset, p, ref resumeQ, ref ctx, ref inboundBuffer, ref needsUpdate);

                        if (needsUpdate)
                        {
                            AddSendUpdate(connection, i, pipeline, currentUpdates);
                        }
                        if (inboundBuffer.bufferWithHeadersLength == 0)
                        {
                            break;
                        }

#if ENABLE_UNITY_COLLECTIONS_CHECKS
                        if (inboundBuffer.headerPadding != prevInbound.headerPadding)
                        {
                            throw new InvalidOperationException("Changing the header padding in a pipeline is not supported");
                        }
#endif
                        if (inboundBuffer.buffer != prevInbound.buffer)
                        {
#if ENABLE_UNITY_COLLECTIONS_CHECKS
                            if (inboundBuffer.buffer != inboundBuffer.bufferWithHeaders + inboundBuffer.headerPadding ||
                                inboundBuffer.bufferLength + inboundBuffer.headerPadding > inboundBuffer.bufferWithHeadersLength)
                            {
                                throw new InvalidOperationException("When creating an internal buffer in piplines the buffer must be a subset of the buffer width headers");
                            }
#endif

                            // Copy header to new buffer so it is part of the payload
                            UnsafeUtility.MemCpy(inboundBuffer.bufferWithHeaders + headerSize, ctx.header.AsNativeArray().GetUnsafeReadOnlyPtr(), ctx.header.Length);
                        }
#if ENABLE_UNITY_COLLECTIONS_CHECKS
                        else
                        {
                            if (inboundBuffer.bufferWithHeaders != prevInbound.bufferWithHeaders)
                            {
                                throw new InvalidOperationException("Changing the send buffer with headers without changing the buffer is not supported");
                            }
                        }
#endif
                        if (ctx.header.Length < stageHeaderCapacity)
                        {
                            int wastedSpace = stageHeaderCapacity - ctx.header.Length;
                            // Remove wasted space in the header
                            UnsafeUtility.MemMove(inboundBuffer.buffer - wastedSpace, inboundBuffer.buffer, inboundBuffer.bufferLength);
                        }

                        // Update the inbound buffer for next iteration
                        inboundBuffer.buffer       = inboundBuffer.bufferWithHeaders + headerSize;
                        inboundBuffer.bufferLength = ctx.header.Length + inboundBuffer.bufferLength;


                        needsUpdate = false;

                        internalBufferOffset       += (ctx.internalProcessBufferLength + AlignmentMinusOne) & (~AlignmentMinusOne);
                        internalSharedBufferOffset += (ctx.internalSharedProcessBufferLength + AlignmentMinusOne) & (~AlignmentMinusOne);
                    }

                    if (inboundBuffer.bufferLength != 0)
                    {
                        if (sendHandle.data != IntPtr.Zero && inboundBuffer.bufferWithHeaders == (byte *)sendHandle.data + UnsafeUtility.SizeOf <UdpCHeader>() + 1)
                        {
                            // Actually send the data - after collapsing it again
                            if (inboundBuffer.buffer != inboundBuffer.bufferWithHeaders)
                            {
                                UnsafeUtility.MemMove(inboundBuffer.bufferWithHeaders, inboundBuffer.buffer, inboundBuffer.bufferLength);
                                inboundBuffer.buffer = inboundBuffer.bufferWithHeaders;
                            }
                            ((byte *)sendHandle.data)[UnsafeUtility.SizeOf <UdpCHeader>()] = (byte)pipeline.Id;
                            int sendSize = UnsafeUtility.SizeOf <UdpCHeader>() + 1 + inboundBuffer.bufferLength;
#if ENABLE_UNITY_COLLECTIONS_CHECKS
                            if (sendSize > sendHandle.size)
                            {
                                throw new InvalidOperationException("Pipeline increased the data in the buffer, this is not allowed");
                            }
#endif
                            sendHandle.size = sendSize;
                            retval          = driver.CompleteSend(connection, sendHandle);
                            sendHandle      = default;
                        }
                        else
                        {
                            // Sending without pipeline, the correct pipeline will be added by the default flags when this is called
                            var writer = driver.BeginSend(connection);
                            writer.WriteByte((byte)pipeline.Id);
                            writer.WriteBytes(inboundBuffer.buffer, inboundBuffer.bufferLength);
                            if (writer.HasFailedWrites)
                            {
                                driver.AbortSend(writer);
                            }
                            else
                            {
                                driver.EndSend(writer);
                            }
                        }
                    }

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

                    startStage = resumeQ[resumeQStart++];

                    inboundBuffer = default(InboundSendBuffer);
                }
                if (sendHandle.data != IntPtr.Zero)
                {
                    driver.AbortSend(sendHandle);
                }
                return(retval);
            }
Esempio n. 8
0
        unsafe JobHandle?GetColors32Job(
            void *input,
            GLTFComponentType inputType,
            GLTFAccessorAttributeType attributeType,
            int inputByteStride,
            NativeArray <Color> output
            )
        {
            Profiler.BeginSample("PrepareColors32");
            JobHandle?jobHandle = null;

            if (attributeType == GLTFAccessorAttributeType.VEC3)
            {
                switch (inputType)
                {
                case GLTFComponentType.UnsignedByte:
                {
                    var job = new Jobs.GetColorsVec3UInt8Job {
                        input           = (byte *)input,
                        inputByteStride = inputByteStride > 0 ? inputByteStride : 3,
                        result          = output
                    };
                    jobHandle = job.Schedule(output.Length, GLTFast.DefaultBatchCount);
                }
                break;

                case GLTFComponentType.Float:
                {
                    var job = new Jobs.GetColorsVec3FloatJob {
                        input           = (float *)input,
                        inputByteStride = inputByteStride > 0 ? inputByteStride : 12,
                        result          = output
                    };
                    jobHandle = job.Schedule(output.Length, GLTFast.DefaultBatchCount);
                }
                break;

                case GLTFComponentType.UnsignedShort:
                {
                    var job = new Jobs.GetColorsVec3UInt16Job {
                        input           = (System.UInt16 *)input,
                        inputByteStride = inputByteStride > 0 ? inputByteStride : 6,
                        result          = output
                    };
                    jobHandle = job.Schedule(output.Length, GLTFast.DefaultBatchCount);
                }
                break;

                default:
                    Debug.LogErrorFormat(GLTFast.ErrorUnsupportedColorFormat, attributeType);
                    break;
                }
            }
            else if (attributeType == GLTFAccessorAttributeType.VEC4)
            {
                switch (inputType)
                {
                case GLTFComponentType.UnsignedByte:
                {
                    var job = new Jobs.GetColorsVec4UInt8Job {
                        input           = (byte *)input,
                        inputByteStride = inputByteStride > 0 ? inputByteStride : 4,
                        result          = output
                    };
                    jobHandle = job.Schedule(output.Length, GLTFast.DefaultBatchCount);
                }
                break;

                case GLTFComponentType.Float:
                {
                    var job = new Jobs.MemCopyJob();
                    job.bufferSize = output.Length * 16;
                    job.input      = input;
                    job.result     = NativeArrayUnsafeUtility.GetUnsafeReadOnlyPtr(output);
                    jobHandle      = job.Schedule();
                }
                break;

                case GLTFComponentType.UnsignedShort:
                {
                    var job = new Jobs.GetColorsVec4UInt16Job {
                        input           = (System.UInt16 *)input,
                        inputByteStride = inputByteStride > 0 ? inputByteStride : 8,
                        result          = output
                    };
                    jobHandle = job.Schedule(output.Length, GLTFast.DefaultBatchCount);
                }
                break;

                default:
                    Debug.LogErrorFormat(GLTFast.ErrorUnsupportedColorFormat, attributeType);
                    break;
                }
            }
            else
            {
                Debug.LogErrorFormat(GLTFast.ErrorUnsupportedType, "color accessor", inputType);
            }
            Profiler.EndSample();
            return(jobHandle);
        }
Esempio n. 9
0
        void PrepareDelaunay(NativeArray <int2> edges, int edgeCount)
        {
            m_StarCount = m_CellCount * 3;
            m_Stars     = new NativeArray <UStar>(m_StarCount, m_Allocator);
            m_SPArray   = new NativeArray <int>(m_StarCount * m_StarCount, m_Allocator);

            var UEdgeCount = 0;
            var UEdges     = new NativeArray <int2>(m_StarCount, m_Allocator);

            // Input Edges.
            for (int i = 0; i < edgeCount; ++i)
            {
                int2 e = edges[i];
                e.x      = (edges[i].x < edges[i].y) ? edges[i].x : edges[i].y;
                e.y      = (edges[i].x > edges[i].y) ? edges[i].x : edges[i].y;
                edges[i] = e;
                InsertUniqueEdge(UEdges, e, ref UEdgeCount);
            }

            m_Edges = new NativeArray <int2>(UEdgeCount, m_Allocator);
            for (int i = 0; i < UEdgeCount; ++i)
            {
                m_Edges[i] = UEdges[i];
            }
            UEdges.Dispose();

            unsafe
            {
                ModuleHandle.InsertionSort <int2, TessEdgeCompare>(
                    NativeArrayUnsafeUtility.GetUnsafeBufferPointerWithoutChecks(m_Edges), 0, m_Edges.Length - 1,
                    new TessEdgeCompare());
            }

            // Init Stars.
            for (int i = 0; i < m_StarCount; ++i)
            {
                UStar s = m_Stars[i];
                s.points     = new ArraySlice <int>(m_SPArray, i * m_StarCount, m_StarCount);
                s.pointCount = 0;
                m_Stars[i]   = s;
            }

            // Fill stars.
            for (int i = 0; i < m_CellCount; ++i)
            {
                int   a  = m_Cells[i].x;
                int   b  = m_Cells[i].y;
                int   c  = m_Cells[i].z;
                UStar sa = m_Stars[a];
                UStar sb = m_Stars[b];
                UStar sc = m_Stars[c];
                sa.points[sa.pointCount++] = b;
                sa.points[sa.pointCount++] = c;
                sb.points[sb.pointCount++] = c;
                sb.points[sb.pointCount++] = a;
                sc.points[sc.pointCount++] = a;
                sc.points[sc.pointCount++] = b;
                m_Stars[a] = sa;
                m_Stars[b] = sb;
                m_Stars[c] = sc;
            }
        }
Esempio n. 10
0
        public unsafe static JobHandle ScheduleBatch(NativeArray <SpherecastCommand> commands, NativeArray <RaycastHit> results, int minCommandsPerJob, JobHandle dependsOn = new JobHandle())
        {
            var jobData        = new BatchQueryJob <SpherecastCommand, RaycastHit>(commands, results);
            var scheduleParams = new JobsUtility.JobScheduleParameters(UnsafeUtility.AddressOf(ref jobData), BatchQueryJobStruct <BatchQueryJob <SpherecastCommand, RaycastHit> > .Initialize(), dependsOn, ScheduleMode.Batched);

            return(ScheduleSpherecastBatch(ref scheduleParams, NativeArrayUnsafeUtility.GetUnsafeBufferPointerWithoutChecks(commands), commands.Length, NativeArrayUnsafeUtility.GetUnsafeBufferPointerWithoutChecks(results), results.Length, minCommandsPerJob));
        }
Esempio n. 11
0
        public static unsafe HIDDeviceDescriptor ReadHIDDeviceDescriptor(int deviceId, ref InputDeviceDescription deviceDescription, IInputRuntime runtime)
        {
            if (deviceDescription.interfaceName != kHIDInterface)
            {
                throw new ArgumentException(
                          string.Format("Device '{0}' is not a HID", deviceDescription));
            }

            // See if we have to request a HID descriptor from the device.
            // We support having the descriptor directly as a JSON string in the `capabilities`
            // field of the device description.
            var needToRequestDescriptor = true;
            var hidDeviceDescriptor     = new HIDDeviceDescriptor();

            if (!string.IsNullOrEmpty(deviceDescription.capabilities))
            {
                try
                {
                    hidDeviceDescriptor = HIDDeviceDescriptor.FromJson(deviceDescription.capabilities);

                    // If there's elements in the descriptor, we're good with the descriptor. If there aren't,
                    // we go and ask the device for a full descriptor.
                    if (hidDeviceDescriptor.elements != null && hidDeviceDescriptor.elements.Length > 0)
                    {
                        needToRequestDescriptor = false;
                    }
                }
                catch (Exception exception)
                {
                    Debug.LogError(string.Format("Could not parse HID descriptor of device '{0}'", deviceDescription));
                    Debug.LogException(exception);
                }
            }

            ////REVIEW: we *could* switch to a single path here that supports *only* parsed descriptors but it'd
            ////        mean having to switch *every* platform supporting HID to the hack we currently have to do
            ////        on Windows

            // Request descriptor, if necessary.
            if (needToRequestDescriptor)
            {
                // If the device has no assigned ID yet, we can't perform IOCTLs on the
                // device so no way to get a report descriptor.
                if (deviceId == kInvalidDeviceId)
                {
                    return(new HIDDeviceDescriptor());
                }

                // Try to get the size of the HID descriptor from the device.
                var sizeOfDescriptorCommand = new InputDeviceCommand(QueryHIDReportDescriptorSizeDeviceCommandType);
                var sizeOfDescriptorInBytes = runtime.DeviceCommand(deviceId, ref sizeOfDescriptorCommand);
                if (sizeOfDescriptorInBytes > 0)
                {
                    // Now try to fetch the HID descriptor.
                    using (var buffer =
                               InputDeviceCommand.AllocateNative(QueryHIDReportDescriptorDeviceCommandType, (int)sizeOfDescriptorInBytes))
                    {
                        var commandPtr = (InputDeviceCommand *)NativeArrayUnsafeUtility.GetUnsafePtr(buffer);
                        if (runtime.DeviceCommand(deviceId, ref *commandPtr) != sizeOfDescriptorInBytes)
                        {
                            return(new HIDDeviceDescriptor());
                        }

                        // Try to parse the HID report descriptor.
                        if (!HIDParser.ParseReportDescriptor((byte *)commandPtr->payloadPtr, (int)sizeOfDescriptorInBytes, ref hidDeviceDescriptor))
                        {
                            return(new HIDDeviceDescriptor());
                        }
                    }

                    // Update the descriptor on the device with the information we got.
                    deviceDescription.capabilities = hidDeviceDescriptor.ToJson();
                }
                else
                {
                    // The device may not support binary descriptors but may support parsed descriptors so
                    // try the IOCTL for parsed descriptors next.
                    //
                    // This path exists pretty much only for the sake of Windows where it is not possible to get
                    // unparsed/binary descriptors from the device (and where getting element offsets is only possible
                    // with some dirty hacks we're performing in the native runtime).

                    const int kMaxDescriptorBufferSize = 2 * 1024 * 1024; ////TODO: switch to larger buffer based on return code if request fails
                    using (var buffer =
                               InputDeviceCommand.AllocateNative(QueryHIDParsedReportDescriptorDeviceCommandType, kMaxDescriptorBufferSize))
                    {
                        var commandPtr = (InputDeviceCommand *)NativeArrayUnsafeUtility.GetUnsafePtr(buffer);
                        var utf8Length = runtime.DeviceCommand(deviceId, ref *commandPtr);
                        if (utf8Length < 0)
                        {
                            return(new HIDDeviceDescriptor());
                        }

                        // Turn UTF-8 buffer into string.
                        ////TODO: is there a way to not have to copy here?
                        var utf8 = new byte[utf8Length];
                        fixed(byte *utf8Ptr = utf8)
                        {
                            UnsafeUtility.MemCpy(utf8Ptr, commandPtr->payloadPtr, utf8Length);
                        }

                        var descriptorJson = Encoding.UTF8.GetString(utf8, 0, (int)utf8Length);

                        // Try to parse the HID report descriptor.
                        try
                        {
                            hidDeviceDescriptor = HIDDeviceDescriptor.FromJson(descriptorJson);
                        }
                        catch (Exception exception)
                        {
                            Debug.LogError(string.Format("Could not parse HID descriptor of device '{0}'", deviceDescription));
                            Debug.LogException(exception);
                            return(new HIDDeviceDescriptor());
                        }

                        // Update the descriptor on the device with the information we got.
                        deviceDescription.capabilities = descriptorJson;
                    }
                }
            }

            return(hidDeviceDescriptor);
        }
 public ConwayGOLSystem(NativeArray <MaterialData> writeMaterialData, Resolution resolution)
 {
     this._writeDataPrt = NativeArrayUnsafeUtility.GetUnsafePtr(writeMaterialData);
     this._resolution   = resolution;
 }
Esempio n. 13
0
        private static void Receive(ref NetworkPipelineContext ctx, ref InboundRecvBuffer inboundBuffer, ref NetworkPipelineStage.Requests requests)
        {
            var fragContext = (FragContext *)ctx.internalProcessBuffer;
            var dataBuffer  = ctx.internalProcessBuffer + sizeof(FragContext);
            var param       = (FragmentationUtility.Parameters *)ctx.staticInstanceBuffer;

            var inboundArray = NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray <byte>(inboundBuffer.buffer, inboundBuffer.bufferLength, Allocator.Invalid);

#if ENABLE_UNITY_COLLECTIONS_CHECKS
            var safetyHandle = AtomicSafetyHandle.GetTempMemoryHandle();
            NativeArrayUnsafeUtility.SetAtomicSafetyHandle(ref inboundArray, safetyHandle);
#endif
            var reader = new DataStreamReader(inboundArray);

            var combined      = reader.ReadShort();
            var foundSequence = combined & (int)FragFlags.SeqMask;
            var flags         = (FragFlags)combined & ~FragFlags.SeqMask;
            inboundBuffer = inboundBuffer.Slice(FragHeaderCapacity);

            var expectedSequence = fragContext->sequence;
            var isFirst          = 0 != (flags & FragFlags.First);
            var isLast           = 0 != (flags & FragFlags.Last);

            if (isFirst)
            {
                expectedSequence         = foundSequence;
                fragContext->packetError = false;
                fragContext->endIndex    = 0;
            }

            if (foundSequence != expectedSequence)
            {
                // We've missed a packet.
                fragContext->packetError = true;
                fragContext->endIndex    = 0;     // Discard data we have already collected
            }

            if (!fragContext->packetError)
            {
                if (!isLast || fragContext->endIndex > 0)
                {
                    if (fragContext->endIndex + inboundBuffer.bufferLength > param->PayloadCapacity)
                    {
                        throw new InvalidOperationException($"Fragmentation capacity exceeded");
                    }
                    // Append the data to the end
                    UnsafeUtility.MemCpy(dataBuffer + fragContext->endIndex, inboundBuffer.buffer, inboundBuffer.bufferLength);
                    fragContext->endIndex += inboundBuffer.bufferLength;
                }

                if (isLast && fragContext->endIndex > 0)
                {
                    // Data is complete
                    inboundBuffer = new InboundRecvBuffer
                    {
                        buffer       = dataBuffer,
                        bufferLength = fragContext->endIndex
                    };
                }
            }

            if (!isLast || fragContext->packetError)
            {
                // No output if we expect more data, or if data is incomplete due to packet loss
                inboundBuffer = default;
            }

            fragContext->sequence = (foundSequence + 1) & (int)FragFlags.SeqMask;
        }
Esempio n. 14
0
        private static void Receive(ref NetworkPipelineContext ctx, ref InboundRecvBuffer inboundBuffer, ref NetworkPipelineStage.Requests requests)
        {
            // Request a send update to see if a queued packet needs to be resent later or if an ack packet should be sent
            requests = NetworkPipelineStage.Requests.SendUpdate;
            bool needsResume = false;

            var header = default(ReliableUtility.PacketHeader);
            var slice  = default(InboundRecvBuffer);

            ReliableUtility.Context *      reliable = (ReliableUtility.Context *)ctx.internalProcessBuffer;
            ReliableUtility.SharedContext *shared   = (ReliableUtility.SharedContext *)ctx.internalSharedProcessBuffer;
            shared->errorCode = 0;
            if (reliable->Resume == ReliableUtility.NullEntry)
            {
                if (inboundBuffer.bufferLength <= 0)
                {
                    inboundBuffer = slice;
                    return;
                }
                var inboundArray = NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray <byte>(inboundBuffer.buffer, inboundBuffer.bufferLength, Allocator.Invalid);
#if ENABLE_UNITY_COLLECTIONS_CHECKS
                var safetyHandle = AtomicSafetyHandle.GetTempMemoryHandle();
                NativeArrayUnsafeUtility.SetAtomicSafetyHandle(ref inboundArray, safetyHandle);
#endif
                var reader = new DataStreamReader(inboundArray);
                reader.ReadBytes((byte *)&header, UnsafeUtility.SizeOf <ReliableUtility.PacketHeader>());

                if (header.Type == (ushort)ReliableUtility.PacketType.Ack)
                {
                    ReliableUtility.ReadAckPacket(ctx, header);
                    inboundBuffer = default;
                    return;
                }

                var result = ReliableUtility.Read(ctx, header);

                if (result >= 0)
                {
                    var nextExpectedSequenceId = (ushort)(reliable->Delivered + 1);
                    if (result == nextExpectedSequenceId)
                    {
                        reliable->Delivered = result;
                        slice = inboundBuffer.Slice(UnsafeUtility.SizeOf <ReliableUtility.PacketHeader>());

                        if (needsResume = SequenceHelpers.GreaterThan16((ushort)shared->ReceivedPackets.Sequence,
                                                                        (ushort)result))
                        {
                            reliable->Resume = (ushort)(result + 1);
                        }
                    }
                    else
                    {
                        ReliableUtility.SetPacket(ctx.internalProcessBuffer, result, inboundBuffer.Slice(UnsafeUtility.SizeOf <ReliableUtility.PacketHeader>()));
                        slice = ReliableUtility.ResumeReceive(ctx, reliable->Delivered + 1, ref needsResume);
                    }
                }
            }
            else
            {
                slice = ReliableUtility.ResumeReceive(ctx, reliable->Resume, ref needsResume);
            }
            if (needsResume)
            {
                requests |= NetworkPipelineStage.Requests.Resume;
            }
            inboundBuffer = slice;
        }
Esempio n. 15
0
 public unsafe static JobHandle Sort <T>(this NativeArray <T> array, JobHandle inputDeps)
     where T : unmanaged, IComparable <T>
 {
     return(Sort((T *)NativeArrayUnsafeUtility.GetUnsafeBufferPointerWithoutChecks(array), array.Length, new DefaultComparer <T>(), inputDeps));
 }
Esempio n. 16
0
        internal bool Triangulate(NativeArray <float2> points, int pointCount, NativeArray <int2> edges, int edgeCount)
        {
            m_NumEdges  = edgeCount;
            m_NumHulls  = edgeCount * 2;
            m_NumPoints = pointCount;
            m_CellCount = 0;
            m_Cells     = new NativeArray <int3>(ModuleHandle.kMaxTriangleCount, m_Allocator);
            m_ILArray   = new NativeArray <int>(m_NumHulls * (m_NumHulls + 1), m_Allocator); // Make room for -1 node.
            m_IUArray   = new NativeArray <int>(m_NumHulls * (m_NumHulls + 1), m_Allocator); // Make room for -1 node.

            NativeArray <UHull> hulls = new NativeArray <UHull>(m_NumPoints * 8, m_Allocator);
            int hullCount             = 0;

            NativeArray <UEvent> events = new NativeArray <UEvent>(m_NumPoints + (m_NumEdges * 2), m_Allocator);
            int eventCount = 0;

            for (int i = 0; i < m_NumPoints; ++i)
            {
                UEvent evt = new UEvent();
                evt.a                = points[i];
                evt.b                = new float2();
                evt.idx              = i;
                evt.type             = (int)UEventType.EVENT_POINT;
                events[eventCount++] = evt;
            }

            for (int i = 0; i < m_NumEdges; ++i)
            {
                int2   e = edges[i];
                float2 a = points[e.x];
                float2 b = points[e.y];
                if (a.x < b.x)
                {
                    UEvent _s = new UEvent();
                    _s.a    = a;
                    _s.b    = b;
                    _s.idx  = i;
                    _s.type = (int)UEventType.EVENT_START;

                    UEvent _e = new UEvent();
                    _e.a    = b;
                    _e.b    = a;
                    _e.idx  = i;
                    _e.type = (int)UEventType.EVENT_END;

                    events[eventCount++] = _s;
                    events[eventCount++] = _e;
                }
                else if (a.x > b.x)
                {
                    UEvent _s = new UEvent();
                    _s.a    = b;
                    _s.b    = a;
                    _s.idx  = i;
                    _s.type = (int)UEventType.EVENT_START;

                    UEvent _e = new UEvent();
                    _e.a    = a;
                    _e.b    = b;
                    _e.idx  = i;
                    _e.type = (int)UEventType.EVENT_END;

                    events[eventCount++] = _s;
                    events[eventCount++] = _e;
                }
            }

            unsafe
            {
                ModuleHandle.InsertionSort <UEvent, TessEventCompare>(
                    NativeArrayUnsafeUtility.GetUnsafeBufferPointerWithoutChecks(events), 0, eventCount - 1,
                    new TessEventCompare());
                ;
            }

            var   hullOp = true;
            float minX   = events[0].a.x - (1 + math.abs(events[0].a.x)) * math.pow(2.0f, -16.0f);
            UHull hull;

            hull.a.x           = minX;
            hull.a.y           = 1;
            hull.b.x           = minX;
            hull.b.y           = 0;
            hull.idx           = -1;
            hull.ilarray       = new ArraySlice <int>(m_ILArray, m_NumHulls * m_NumHulls, m_NumHulls); // Last element
            hull.iuarray       = new ArraySlice <int>(m_IUArray, m_NumHulls * m_NumHulls, m_NumHulls);
            hull.ilcount       = 0;
            hull.iucount       = 0;
            hulls[hullCount++] = hull;


            for (int i = 0, numEvents = eventCount; i < numEvents; ++i)
            {
                switch (events[i].type)
                {
                case (int)UEventType.EVENT_POINT:
                {
                    hullOp = AddPoint(hulls, hullCount, points, events[i].a, events[i].idx);
                }
                break;

                case (int)UEventType.EVENT_START:
                {
                    hullOp = SplitHulls(hulls, ref hullCount, points, events[i]);
                }
                break;

                default:
                {
                    hullOp = MergeHulls(hulls, ref hullCount, points, events[i]);
                }
                break;
                }

                if (!hullOp)
                {
                    break;
                }
            }

            events.Dispose();
            hulls.Dispose();
            return(hullOp);
        }
Esempio n. 17
0
 public unsafe static JobHandle Sort <T, U>(this NativeArray <T> array, U comp, JobHandle inputDeps)
     where T : unmanaged
     where U : IComparer <T>
 {
     return(Sort((T *)NativeArrayUnsafeUtility.GetUnsafeBufferPointerWithoutChecks(array), array.Length, comp, inputDeps));
 }
Esempio n. 18
0
        // This is the workhorse for figuring out fallback options for HIDs attached to the system.
        // If the system cannot find a more specific layout for a given HID, this method will try
        // to produce a layout builder on the fly based on the HID descriptor received from
        // the device.
        internal static unsafe string OnFindControlLayoutForDevice(int deviceId, ref InputDeviceDescription description, string matchedLayout, IInputRuntime runtime)
        {
            // If the system found a matching layout, there's nothing for us to do.
            if (!string.IsNullOrEmpty(matchedLayout))
            {
                return(null);
            }

            // If the device isn't a HID, we're not interested.
            if (description.interfaceName != kHIDInterface)
            {
                return(null);
            }

            // See if we have to request a HID descriptor from the device.
            // We support having the descriptor directly as a JSON string in the `capabilities`
            // field of the device description.
            var needToRequestDescriptor = true;
            var hidDeviceDescriptor     = new HIDDeviceDescriptor();

            if (!string.IsNullOrEmpty(description.capabilities))
            {
                try
                {
                    hidDeviceDescriptor = HIDDeviceDescriptor.FromJson(description.capabilities);

                    // If there's elements in the descriptor, we're good with the descriptor. If there aren't,
                    // we go and ask the device for a full descriptor.
                    if (hidDeviceDescriptor.elements != null && hidDeviceDescriptor.elements.Length > 0)
                    {
                        needToRequestDescriptor = false;
                    }
                }
                catch (Exception exception)
                {
                    Debug.Log(string.Format("Could not parse HID descriptor (exception: {0})", exception));
                }
            }

            ////REVIEW: we *could* switch to a single path here that supports *only* parsed descriptors but it'd
            ////        mean having to switch *every* platform supporting HID to the hack we currently have to do
            ////        on Windows

            // Request descriptor, if necessary.
            if (needToRequestDescriptor)
            {
                // If the device has no assigned ID yet, we can't perform IOCTLs on the
                // device so no way to get a report descriptor.
                if (deviceId == kInvalidDeviceId)
                {
                    return(null);
                }

                // Try to get the size of the HID descriptor from the device.
                var sizeOfDescriptorCommand = new InputDeviceCommand(QueryHIDReportDescriptorSizeDeviceCommandType);
                var sizeOfDescriptorInBytes = runtime.DeviceCommand(deviceId, ref sizeOfDescriptorCommand);
                if (sizeOfDescriptorInBytes > 0)
                {
                    // Now try to fetch the HID descriptor.
                    using (var buffer =
                               InputDeviceCommand.AllocateNative(QueryHIDReportDescriptorDeviceCommandType, (int)sizeOfDescriptorInBytes))
                    {
                        var commandPtr = (InputDeviceCommand *)NativeArrayUnsafeUtility.GetUnsafePtr(buffer);
                        if (runtime.DeviceCommand(deviceId, ref *commandPtr) != sizeOfDescriptorInBytes)
                        {
                            return(null);
                        }

                        // Try to parse the HID report descriptor.
                        if (!HIDParser.ParseReportDescriptor((byte *)commandPtr->payloadPtr, (int)sizeOfDescriptorInBytes, ref hidDeviceDescriptor))
                        {
                            return(null);
                        }
                    }

                    // Update the descriptor on the device with the information we got.
                    description.capabilities = hidDeviceDescriptor.ToJson();
                }
                else
                {
                    // The device may not support binary descriptors but may support parsed descriptors so
                    // try the IOCTL for parsed descriptors next.
                    //
                    // This path exists pretty much only for the sake of Windows where it is not possible to get
                    // unparsed/binary descriptors from the device (and where getting element offsets is only possible
                    // with some dirty hacks we're performing in the native runtime).

                    const int kMaxDescriptorBufferSize = 2 * 1024 * 1024; ////TODO: switch to larger buffer based on return code if request fails
                    using (var buffer =
                               InputDeviceCommand.AllocateNative(QueryHIDParsedReportDescriptorDeviceCommandType, kMaxDescriptorBufferSize))
                    {
                        var commandPtr = (InputDeviceCommand *)NativeArrayUnsafeUtility.GetUnsafePtr(buffer);
                        var utf8Length = runtime.DeviceCommand(deviceId, ref *commandPtr);
                        if (utf8Length < 0)
                        {
                            return(null);
                        }

                        // Turn UTF-8 buffer into string.
                        ////TODO: is there a way to not have to copy here?
                        var utf8 = new byte[utf8Length];
                        fixed(byte *utf8Ptr = utf8)
                        {
                            UnsafeUtility.MemCpy(utf8Ptr, commandPtr->payloadPtr, utf8Length);
                        }

                        var descriptorJson = Encoding.UTF8.GetString(utf8, 0, (int)utf8Length);

                        // Try to parse the HID report descriptor.
                        try
                        {
                            hidDeviceDescriptor = HIDDeviceDescriptor.FromJson(descriptorJson);
                        }
                        catch (Exception exception)
                        {
                            Debug.Log(string.Format("Could not parse HID descriptor JSON returned from runtime (exception: {0})", exception));
                            return(null);
                        }

                        // Update the descriptor on the device with the information we got.
                        description.capabilities = descriptorJson;
                    }
                }
            }

            // Determine if there's any usable elements on the device.
            var hasUsableElements = false;

            if (hidDeviceDescriptor.elements != null)
            {
                foreach (var element in hidDeviceDescriptor.elements)
                {
                    if (element.DetermineLayout() != null)
                    {
                        hasUsableElements = true;
                        break;
                    }
                }
            }

            // If not, there's nothing we can do with the device.
            if (!hasUsableElements)
            {
                return(null);
            }

            // Determine base layout.
            var baseLayout = "HID";

            if (hidDeviceDescriptor.usagePage == UsagePage.GenericDesktop)
            {
                /*
                 * ////TODO: there's some work to be done to make the HID *actually* compatible with these devices
                 * if (hidDeviceDescriptor.usage == (int)GenericDesktop.Joystick)
                 *  baseLayout = "Joystick";
                 * else if (hidDeviceDescriptor.usage == (int)GenericDesktop.Gamepad)
                 *  baseLayout = "Gamepad";
                 * else if (hidDeviceDescriptor.usage == (int)GenericDesktop.Mouse)
                 *  baseLayout = "Mouse";
                 * else if (hidDeviceDescriptor.usage == (int)GenericDesktop.Pointer)
                 *  baseLayout = "Pointer";
                 * else if (hidDeviceDescriptor.usage == (int)GenericDesktop.Keyboard)
                 *  baseLayout = "Keyboard";
                 */
            }

            ////TODO: match HID layouts by vendor and product ID
            ////REVIEW: this probably works fine for most products out there but I'm not sure it works reliably for all cases
            // Come up with a unique template name. HIDs are required to have product and vendor IDs.
            // We go with the string versions if we have them and with the numeric versions if we don't.
            string layoutName;

            if (!string.IsNullOrEmpty(description.product) && !string.IsNullOrEmpty(description.manufacturer))
            {
                layoutName = string.Format("{0}::{1} {2}", kHIDNamespace, description.manufacturer, description.product);
            }
            else
            {
                // Sanity check to make sure we really have the data we expect.
                if (hidDeviceDescriptor.vendorId == 0)
                {
                    return(null);
                }
                layoutName = string.Format("{0}::{1:X}-{2:X}", kHIDNamespace, hidDeviceDescriptor.vendorId,
                                           hidDeviceDescriptor.productId);
            }

            // Register layout builder that will turn the HID descriptor into an
            // InputControlLayout instance.
            var layout = new HIDLayoutBuilder {
                hidDescriptor = hidDeviceDescriptor
            };

            InputSystem.RegisterControlLayoutBuilder(() => layout.Build(),
                                                     layoutName, baseLayout, InputDeviceMatcher.FromDeviceDescription(description));

            return(layoutName);
        }
Esempio n. 19
0
        public override unsafe bool ScheduleVertexBonesJob(
            VertexInputData weightsInput,
            VertexInputData jointsInput,
            NativeSlice <JobHandle> handles
            )
        {
            Profiler.BeginSample("ScheduleVertexBonesJob");
            Profiler.BeginSample("AllocateNativeArray");
            vData = new NativeArray <VBones>(weightsInput.count, VertexBufferConfigBase.defaultAllocator);
            var vDataPtr = (byte *)NativeArrayUnsafeUtility.GetUnsafeReadOnlyPtr(vData);

            Profiler.EndSample();

            fixed(void *input = &(weightsInput.buffer[weightsInput.startOffset]))
            {
                var h = GetWeightsJob(
                    input,
                    weightsInput.count,
                    weightsInput.type,
                    weightsInput.byteStride,
                    (Vector4 *)vDataPtr,
                    32,
                    weightsInput.normalize
                    );

                if (h.HasValue)
                {
                    handles[0] = h.Value;
                }
                else
                {
                    Profiler.EndSample();
                    return(false);
                }
            }

            fixed(void *input = &(jointsInput.buffer[jointsInput.startOffset]))
            {
                var h = GetJointsJob(
                    input,
                    jointsInput.count,
                    jointsInput.type,
                    jointsInput.byteStride,
                    (uint *)(vDataPtr + 16),
                    32,
                    jointsInput.normalize
                    );

                if (h.HasValue)
                {
                    handles[1] = h.Value;
                }
                else
                {
                    Profiler.EndSample();
                    return(false);
                }
            }

            Profiler.EndSample();
            return(true);
        }
        internal static JobHandle PreparePrefilteredChunkLists(int unfilteredChunkCount, MatchingArchetypeList archetypes, ComponentGroupFilter filter, JobHandle dependsOn, ScheduleMode mode, out NativeArray <byte> prefilterDataArray, out void *deferredCountData)
        {
            // Allocate one buffer for all prefilter data and distribute it
            // We keep the full buffer as a "dummy array" so we can deallocate it later with [DeallocateOnJobCompletion]
            var sizeofChunkArray  = sizeof(ArchetypeChunk) * unfilteredChunkCount;
            var sizeofIndexArray  = sizeof(int) * unfilteredChunkCount;
            var prefilterDataSize = sizeofChunkArray + sizeofIndexArray + sizeof(int);

            var prefilterData = (byte *)UnsafeUtility.Malloc(prefilterDataSize, 64, Allocator.TempJob);

            prefilterDataArray = NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray <byte>(prefilterData, prefilterDataSize, Allocator.TempJob);

#if ENABLE_UNITY_COLLECTIONS_CHECKS
            NativeArrayUnsafeUtility.SetAtomicSafetyHandle(ref prefilterDataArray, AtomicSafetyHandle.Create());
#endif

            JobHandle prefilterHandle = default(JobHandle);

            if (filter.RequiresMatchesFilter)
            {
                var prefilteringJob = new GatherChunksAndOffsetsWithFilteringJob
                {
                    Archetypes           = archetypes,
                    Filter               = filter,
                    PrefilterData        = prefilterData,
                    UnfilteredChunkCount = unfilteredChunkCount
                };
                if (mode == ScheduleMode.Batched)
                {
                    prefilterHandle = prefilteringJob.Schedule(dependsOn);
                }
                else
                {
                    prefilteringJob.Run();
                }
            }
            else
            {
                var gatherJob = new GatherChunksAndOffsetsJob
                {
                    Archetypes           = archetypes,
                    PrefilterData        = prefilterData,
                    UnfilteredChunkCount = unfilteredChunkCount
                };
                if (mode == ScheduleMode.Batched)
                {
                    prefilterHandle = gatherJob.Schedule(dependsOn);
                }
                else
                {
                    gatherJob.Run();
                }
            }

            // ScheduleParallelForDeferArraySize expects a ptr to a structure with a void* and a count.
            // It only uses the count, so this is safe to fudge
            deferredCountData = prefilterData + sizeofChunkArray + sizeofIndexArray;
            deferredCountData = (byte *)deferredCountData - sizeof(void *);

            return(prefilterHandle);
        }
Esempio n. 21
0
 /// <summary>
 /// Does NOT allocate memory, but shares it.
 /// </summary>
 public NativeArray <T> ToNativeArray()
 {
     return(NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray <T> (m_ListData->buffer, m_ListData->length, Collections.Allocator.Invalid));
 }
Esempio n. 22
0
            public unsafe void Execute(ArchetypeChunk chunk, int chunkIndex, int firstEntityIndex)
            {
                var entities         = chunk.GetNativeArray(entityType);
                var rpcInBuffer      = chunk.GetBufferAccessor(inBufferType);
                var rpcOutBuffer     = chunk.GetBufferAccessor(outBufferType);
                var connections      = chunk.GetNativeArray(connectionType);
                var deserializeState = new RpcDeserializerState {
                    ghostMap = ghostMap
                };

                for (int i = 0; i < rpcInBuffer.Length; ++i)
                {
                    if (driver.GetConnectionState(connections[i].Value) != NetworkConnection.State.Connected)
                    {
                        continue;
                    }

                    var dynArray   = rpcInBuffer[i];
                    var parameters = new RpcExecutor.Parameters
                    {
                        Reader        = dynArray.AsDataStreamReader(),
                        CommandBuffer = commandBuffer,
                        State         = (IntPtr)UnsafeUtility.AddressOf(ref deserializeState),
                        Connection    = entities[i],
                        JobIndex      = chunkIndex
                    };
                    int msgHeaderLen = dynamicAssemblyList ? 10 : 4;
                    while (parameters.Reader.GetBytesRead() < parameters.Reader.Length)
                    {
                        int rpcIndex = 0;
                        if (dynamicAssemblyList)
                        {
                            ulong rpcHash = parameters.Reader.ReadULong();
                            if (rpcHash == 0)
                            {
                                rpcIndex = ushort.MaxValue;
                                protocolVersion.RpcCollectionVersion       = 0;
                                protocolVersion.ComponentCollectionVersion = 0;
                            }
                            else if (rpcHash != 0 && !hashToIndex.TryGetValue(rpcHash, out rpcIndex))
                            {
                                errors.Enqueue(new RpcReceiveError
                                {
                                    connection = entities[i],
                                    error      = ErrorCodes.InvalidRpc
                                });
                                break;
                            }
                        }
                        else
                        {
                            rpcIndex = parameters.Reader.ReadUShort();
                        }

                        var rpcSize = parameters.Reader.ReadUShort();
                        if (rpcIndex == ushort.MaxValue)
                        {
                            // Special value for NetworkProtocolVersion
                            var netCodeVersion   = parameters.Reader.ReadInt();
                            var gameVersion      = parameters.Reader.ReadInt();
                            var rpcVersion       = parameters.Reader.ReadULong();
                            var componentVersion = parameters.Reader.ReadULong();
                            if (netCodeVersion != protocolVersion.NetCodeVersion ||
                                gameVersion != protocolVersion.GameVersion ||
                                rpcVersion != protocolVersion.RpcCollectionVersion ||
                                componentVersion != protocolVersion.ComponentCollectionVersion)
                            {
                                errors.Enqueue(new RpcReceiveError
                                {
                                    connection = entities[i],
                                    error      = ErrorCodes.ProtocolMismatch
                                });
                                break;
                            }
                            //The connection has received the version. RpcSystem can't accept any rpc's if the NetworkProtocolVersion
                            //has not been received first.
                            var connection = connections[i];
                            connection.ProtocolVersionReceived = 1;
                            connections[i] = connection;
                        }
                        else if (rpcIndex >= execute.Length)
                        {
                            //If this is the server, we must disconnect the connection
                            errors.Enqueue(new RpcReceiveError
                            {
                                connection = entities[i],
                                error      = ErrorCodes.InvalidRpc
                            });
                            break;
                        }
                        else if (connections[i].ProtocolVersionReceived == 0)
                        {
                            errors.Enqueue(new RpcReceiveError
                            {
                                connection = entities[i],
                                error      = ErrorCodes.VersionNotReceived
                            });
                            break;
                        }
                        else
                        {
                            execute[rpcIndex].Execute.Ptr.Invoke(ref parameters);
                        }
                    }

                    dynArray.Clear();

                    var sendBuffer = rpcOutBuffer[i];
                    while (sendBuffer.Length > 0)
                    {
                        DataStreamWriter tmp = driver.BeginSend(reliablePipeline, connections[i].Value);
                        // If sending failed we stop and wait until next frame
                        if (!tmp.IsCreated)
                        {
                            break;
                        }
                        if (sendBuffer.Length > tmp.Capacity)
                        {
                            var sendArray = NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray <byte>(sendBuffer.GetUnsafePtr(), sendBuffer.Length, Allocator.Invalid);
#if ENABLE_UNITY_COLLECTIONS_CHECKS
                            var safety = NativeArrayUnsafeUtility.GetAtomicSafetyHandle(sendBuffer.AsNativeArray());
                            NativeArrayUnsafeUtility.SetAtomicSafetyHandle(ref sendArray, safety);
#endif
                            var reader = new DataStreamReader(sendArray);
                            reader.ReadByte();
                            reader.ReadUShort();
                            var len = reader.ReadUShort() + msgHeaderLen + 1;
                            if (len > tmp.Capacity)
                            {
                                sendBuffer.Clear();
                                // Could not fit a single message in the packet, this is a serious error
                                throw new InvalidOperationException("An RPC was too big to be sent, reduce the size of your RPCs");
                            }
                            tmp.WriteBytes((byte *)sendBuffer.GetUnsafePtr(), len);
                            // Try to fit a few more messages in this packet
                            while (true)
                            {
                                var subArray = sendArray.GetSubArray(tmp.Length, sendArray.Length - tmp.Length);
                                reader = new DataStreamReader(subArray);
                                reader.ReadUShort();
                                len = reader.ReadUShort() + msgHeaderLen;
                                if (tmp.Length + len > tmp.Capacity)
                                {
                                    break;
                                }
                                tmp.WriteBytes((byte *)subArray.GetUnsafeReadOnlyPtr(), len);
                            }
                        }
                        else
                        {
                            tmp.WriteBytes((byte *)sendBuffer.GetUnsafePtr(), sendBuffer.Length);
                        }
                        // If sending failed we stop and wait until next frame
                        if (driver.EndSend(tmp) <= 0)
                        {
                            break;
                        }
                        if (tmp.Length < sendBuffer.Length)
                        {
                            // Compact the buffer, removing the rpcs we did send
                            for (int cpy = tmp.Length; cpy < sendBuffer.Length; ++cpy)
                            {
                                sendBuffer[1 + cpy - tmp.Length] = sendBuffer[cpy];
                            }
                            // Remove all but the first byte of the data we sent, first byte is identifying the packet as an rpc
                            sendBuffer.ResizeUninitialized(1 + sendBuffer.Length - tmp.Length);
                        }
                        else
                        {
                            sendBuffer.Clear();
                        }
                    }
                }
            }
Esempio n. 23
0
    public unsafe static T UncheckReadArrayElement <T>(NativeArray <T> narr, int idx) where T : struct
    {
        void *ptr = NativeArrayUnsafeUtility.GetUnsafeBufferPointerWithoutChecks <T>(narr);

        return(UnsafeUtility.ReadArrayElement <T>(ptr, idx));
    }
Esempio n. 24
0
 // Uncomment when NativeArrayUnsafeUtility includes these conditional checks
 // [Conditional("ENABLE_UNITY_COLLECTIONS_CHECKS")]
 private void SortedIndicesSetSafetyHandle(ref NativeArray <int> arr)
 {
     NativeArrayUnsafeUtility.SetAtomicSafetyHandle(ref arr,
                                                    NativeArrayUnsafeUtility.GetAtomicSafetyHandle(m_WorkingBuffer));
 }
Esempio n. 25
0
 // Uncomment when NativeArrayUnsafeUtility includes these conditional checks
 // [Conditional("ENABLE_UNITY_COLLECTIONS_CHECKS")]
 private void SharedValueIndicesSetSafetyHandle(ref NativeArray <int> arr)
 {
     NativeArrayUnsafeUtility.SetAtomicSafetyHandle(ref arr,
                                                    NativeArrayUnsafeUtility.GetAtomicSafetyHandle(m_SourceIndexBySortedSourceIndex));
 }
Esempio n. 26
0
 // Uncomment when NativeArrayUnsafeUtility includes these conditional checks
 // [Conditional("ENABLE_UNITY_COLLECTIONS_CHECKS")]
 private void SharedValueIndexCountArraySetSafetyHandle(ref NativeArray <int> arr)
 {
     NativeArrayUnsafeUtility.SetAtomicSafetyHandle(ref arr,
                                                    NativeArrayUnsafeUtility.GetAtomicSafetyHandle(m_WorkingBuffer));
 }
Esempio n. 27
0
 unsafe public static void *ToPtr(NativeArray <byte> data)
 {
     unsafe {
         return(NativeArrayUnsafeUtility.GetUnsafeReadOnlyPtr(data));
     }
 }
Esempio n. 28
0
 // Uncomment when NativeArrayUnsafeUtility includes these conditional checks
 // [Conditional("ENABLE_UNITY_COLLECTIONS_CHECKS")]
 private void SharedValueIndicesSetSafetyHandle(ref NativeArray <int> arr)
 {
     NativeArrayUnsafeUtility.SetAtomicSafetyHandle(ref arr,
                                                    NativeArrayUnsafeUtility.GetAtomicSafetyHandle(m_Buffer));
 }
Esempio n. 29
0
        NativeArray <int3> Constrain(ref int count)
        {
            var cells = GetCells(ref count);
            int nc    = count;

            for (int i = 0; i < nc; ++i)
            {
                int3 c = cells[i];
                int  x = c.x, y = c.y, z = c.z;
                if (y < z)
                {
                    if (y < x)
                    {
                        c.x = y;
                        c.y = z;
                        c.z = x;
                    }
                }
                else if (z < x)
                {
                    c.x = z;
                    c.y = x;
                    c.z = y;
                }

                cells[i] = c;
            }

            unsafe
            {
                ModuleHandle.InsertionSort <int3, TessCellCompare>(
                    NativeArrayUnsafeUtility.GetUnsafeBufferPointerWithoutChecks(cells), 0, m_CellCount - 1,
                    new TessCellCompare());
            }

            // Out
            m_Flags       = new NativeArray <int>(nc, m_Allocator);
            m_Neighbors   = new NativeArray <int>(nc * 3, m_Allocator);
            m_Constraints = new NativeArray <int>(nc * 3, m_Allocator);
            var next   = new NativeArray <int>(nc * 3, m_Allocator);
            var active = new NativeArray <int>(nc * 3, m_Allocator);

            int side = 1, nextCount = 0, activeCount = 0;

            for (int i = 0; i < nc; ++i)
            {
                int3 c = cells[i];
                for (int j = 0; j < 3; ++j)
                {
                    int x = j, y = (j + 1) % 3;
                    x = (x == 0) ? c.x : (j == 1) ? c.y : c.z;
                    y = (y == 0) ? c.x : (y == 1) ? c.y : c.z;

                    int o = OppositeOf(y, x);
                    int a = m_Neighbors[3 * i + j] = FindNeighbor(cells, count, y, x, o);
                    int b = m_Constraints[3 * i + j] = (-1 != FindConstraint(x, y)) ? 1 : 0;
                    if (a < 0)
                    {
                        if (0 != b)
                        {
                            next[nextCount++] = i;
                        }
                        else
                        {
                            active[activeCount++] = i;
                            m_Flags[i]            = 1;
                        }
                    }
                }
            }

            while (activeCount > 0 || nextCount > 0)
            {
                while (activeCount > 0)
                {
                    int t = active[activeCount - 1];
                    activeCount--;
                    if (m_Flags[t] == -side)
                    {
                        continue;
                    }

                    m_Flags[t] = side;
                    int3 c = cells[t];
                    for (int j = 0; j < 3; ++j)
                    {
                        int f = m_Neighbors[3 * t + j];
                        if (f >= 0 && m_Flags[f] == 0)
                        {
                            if (0 != m_Constraints[3 * t + j])
                            {
                                next[nextCount++] = f;
                            }
                            else
                            {
                                active[activeCount++] = f;
                                m_Flags[f]            = side;
                            }
                        }
                    }
                }

                for (int e = 0; e < nextCount; e++)
                {
                    active[e] = next[e];
                }
                activeCount = nextCount;
                nextCount   = 0;
                side        = -side;
            }

            active.Dispose();
            next.Dispose();
            return(cells);
        }
Esempio n. 30
0
 public unsafe ImageFrame(ImageFormat.Types.Format format, int width, int height, int widthStep, NativeArray <byte> pixelData, Deleter deleter)
     : this(format, width, height, widthStep, (IntPtr)NativeArrayUnsafeUtility.GetUnsafeReadOnlyPtr(pixelData), deleter)
 {
 }