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)); }
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)); }
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; } } }
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)); }
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); }
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); }
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; } }
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)); }
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; }
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; }
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; }
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)); }
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); }
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)); }
// 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); }
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); }
/// <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)); }
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(); } } } }
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)); }
// 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)); }
// 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)); }
// 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)); }
unsafe public static void *ToPtr(NativeArray <byte> data) { unsafe { return(NativeArrayUnsafeUtility.GetUnsafeReadOnlyPtr(data)); } }
// 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)); }
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); }
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) { }