Beispiel #1
0
        //public BlitList<> DirtyKernelDatas;
        //public BlitList<> CreatedConnections;
        //public BlitList<> DeletedConnections;

        public GraphDiff(Allocator allocator)
        {
            CreatedNodes                = new BlitList <ValidatedHandle>(0, allocator);
            DeletedNodes                = new BlitList <DeletedTuple>(0, allocator);
            Commands                    = new BlitList <CommandTuple>(0, allocator);
            ResizedDataBuffers          = new BlitList <BufferResizedTuple>(0, allocator);
            ResizedPortArrays           = new BlitList <PortArrayResizedTuple>(0, allocator);
            MessagesArrivingAtDataPorts = new BlitList <DataPortMessageTuple>(0, allocator);
        }
Beispiel #2
0
        /// <summary>
        /// Initializes this <see cref="NodeSet"/> in a mode that's compatible with running together with ECS,
        /// through the use of <see cref="ComponentNode"/>s.
        /// The <paramref name="hostSystem"/> and this instance are tied together from this point, and you must
        /// update this set using the <see cref="Update(JobHandle)"/> function.
        /// See also <seealso cref="NodeSet()"/>.
        /// </summary>
        /// <remarks>
        /// Any instantiated nodes with <see cref="IKernelPortDefinition"/>s containing ECS types will be added
        /// as dependencies to <paramref name="hostSystem"/>.
        /// </remarks>
        /// <exception cref="ArgumentNullException">
        /// Thrown if the <paramref name="hostSystem"/> is null
        /// </exception>
        public NodeSet(JobComponentSystem hostSystem)
            : this()
        {
            if (hostSystem == null)
            {
                // In case of cascading constructors, an object can be partially constructed but still be
                // GC collected and finalized.
                Dispose();
                throw new ArgumentNullException(nameof(hostSystem));
            }

            HostSystem             = hostSystem;
            m_ActiveComponentTypes = new BlitList <AtomicSafetyManager.ECSTypeAndSafety>(0, Allocator.Persistent);
        }
        GenerateDataPortDeclarations(Type definitionType, Type kernelPortType)
        {
            // Offset from the start of the field of the data port to the pointer. A bit of a hack.
            const int k_PtrOffset = 0;

            var inputs              = new BlitList <InputDeclaration>(0);
            var outputs             = new BlitList <OutputDeclaration>(0);
            var outputBufferOffsets = new BlitList <BufferOffset>(0);

            try
            {
                var kernelPortValue = definitionType.GetField("s_KernelPorts", BindingFlags.FlattenHierarchy | BindingFlags.Static | BindingFlags.NonPublic)?.GetValue(null);

                foreach (var potentialPortFieldInfo in kernelPortType.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static))
                {
                    ValidateFieldOnKernelPort(potentialPortFieldInfo);

                    var portType = potentialPortFieldInfo.FieldType;

                    if (!portType.IsConstructedGenericType)
                    {
                        throw new InvalidNodeDefinitionException($"Simulation port definition contains disallowed field {portType}.");
                    }

                    // Acquire the assigned port number of this port declaration
                    var assignedPortNumberField = portType.GetField("Port", BindingFlags.Instance | BindingFlags.NonPublic);

                    var genericPortType = portType.GetGenericTypeDefinition();

                    var genericsForDeclaration = portType.GetGenericArguments();

                    bool isPortArray = genericPortType == typeof(PortArray <>);
                    if (isPortArray)
                    {
                        // Extract the specifics of the port type inside the port array.
                        portType = genericsForDeclaration[0];
                        if (!portType.IsConstructedGenericType)
                        {
                            throw new InvalidNodeDefinitionException($"Simulation port definition contains disallowed field {portType}.");
                        }
                        genericPortType        = portType.GetGenericTypeDefinition();
                        genericsForDeclaration = portType.GetGenericArguments();
                    }

                    if (genericsForDeclaration.Length < 2)
                    {
                        throw new InvalidNodeDefinitionException($"Simulation port definition contains disallowed type {portType}.");
                    }

                    var dataType = genericsForDeclaration[1];

                    ValidateDataPortType(potentialPortFieldInfo, dataType);

                    var offsetOfWholePortDeclaration = UnsafeUtility.GetFieldOffset(potentialPortFieldInfo);

                    var portValue = potentialPortFieldInfo.GetValue(kernelPortValue);

                    if (genericPortType == typeof(DataInput <,>))
                    {
                        if (UnsafeUtility.SizeOf(dataType) > k_MaxInputSize)
                        {
                            throw new InvalidNodeDefinitionException($"Node input data structure types cannot have a sizeof larger than {k_MaxInputSize}");
                        }

                        inputs.Add(
                            new InputDeclaration(
                                new SimpleType(dataType),
                                offsetOfWholePortDeclaration + k_PtrOffset,
                                (InputPortID)assignedPortNumberField.GetValue(portValue),
                                isPortArray
                                )
                            );
                    }
                    else if (genericPortType == typeof(DataOutput <,>))
                    {
                        SimpleType type;

                        if (IsBufferDefinition(dataType))
                        {
                            // Compute the simple type of an element inside a buffer if possible
                            type = new SimpleType(dataType.GetGenericArguments()[0]);
                            outputBufferOffsets.Add(new BufferOffset(offsetOfWholePortDeclaration));
                        }
                        else
                        {
                            // otherwise the entire value (breaks for aggregates)
                            type = new SimpleType(dataType);

                            foreach (var field in WalkTypeInstanceFields(dataType, BindingFlags.Public, IsBufferDefinition))
                            {
                                outputBufferOffsets.Add(new BufferOffset(offsetOfWholePortDeclaration + UnsafeUtility.GetFieldOffset(field)));
                            }
                        }

                        outputs.Add(
                            new OutputDeclaration(
                                type,
                                offsetOfWholePortDeclaration + k_PtrOffset,
                                (OutputPortID)assignedPortNumberField.GetValue(portValue)
                                )
                            );
                    }
                    else
                    {
                        throw new InvalidNodeDefinitionException($"Kernel port definition {kernelPortType} contains other types of fields than DataInput<> and DataOutput<> ({portType})");
                    }
                }
            }
            catch
            {
                inputs.Dispose();
                outputs.Dispose();
                outputBufferOffsets.Dispose();
                throw;
            }
            return(inputs, outputs, outputBufferOffsets);
        }
 public void Create()
 {
     Inputs   = new BlitList <InputToECS>(0, Allocator.Persistent);
     Outputs  = new BlitList <OutputFromECS>(0, Allocator.Persistent);
     JITPorts = new BlitList <JITPort>(0, Allocator.Persistent);
 }