Beispiel #1
0
 public void NodeCreated(ValidatedHandle handle)
 {
     Commands.Add(new CommandTuple {
         command = Command.Create, ContainerIndex = CreatedNodes.Count
     });
     CreatedNodes.Add(handle);
 }
Beispiel #2
0
 public void NodeDeleted(ValidatedHandle handle, int definitionIndex)
 {
     Commands.Add(new CommandTuple {
         command = Command.Destroy, ContainerIndex = DeletedNodes.Count
     });
     DeletedNodes.Add(new DeletedTuple {
         Handle = handle, Class = definitionIndex
     });
 }
Beispiel #3
0
        void AddWriter(ComponentType component)
        {
            // TODO: take argument instead. AtomicSafetyManager does not yet support read-only
            // For now, DFG takes write dependency on every type in the graph
            component.AccessModeType = ComponentType.AccessMode.ReadWrite;

            if (!HasReaderOrWriter(component))
            {
                if (component.IsZeroSized)
                {
                    throw new InvalidNodeDefinitionException($"ECS types on ports cannot be zero-sized ({component})");
                }

                HostSystem.AddReaderWriter(component);
                m_ActiveComponentTypes.Add(new AtomicSafetyManager.ECSTypeAndSafety {
                    Type = component
                });
            }
        }
Beispiel #4
0
        /// <summary>
        /// Construct a node set. Remember to dispose it.
        /// <seealso cref="Dispose"/>
        /// </summary>
        public NodeSet()
        {
            m_NodeDefinitions.Add(s_InvalidDefinitionSlot);

            var defaultTraits = LLTraitsHandle.Create();

            // stuff that needs the first slot to be invalid
            defaultTraits.Resolve() = new LowLevelNodeTraits();
            m_Traits.Add(defaultTraits);
            m_ForwardingTable.Allocate();
            m_ArraySizes.Allocate();
            m_ManagedAllocators.Add(new ManagedMemoryAllocator());
            // (we don't need a zeroth invalid index for nodes, because they are versioned)

            RendererModel = RenderExecutionModel.MaximallyParallel;
            m_RenderGraph = new RenderGraph(this);
            NodeSetID     = ++s_NodeSetCounter;

            m_Batches     = new VersionedList <InputBatch>(Allocator.Persistent, NodeSetID);
            m_GraphValues = new VersionedList <DataOutputValue>(Allocator.Persistent, NodeSetID);
        }
        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);
        }