protected override JobHandle OnUpdate(JobHandle inputDependencies)
    {
        //shared ECB between all jobs
        EntityCommandBuffer.Concurrent ecb = endInitECBSystem.CreateCommandBuffer().ToConcurrent();

        //Job 1
        //First we run through all the enemies finding the closest player (generally there's only one).
        //We prepare 2 NativeArrays: a reference to the players, and to their positions. This way enemies can run distance checks and note down which Entity is the closest player.
        NativeArray <Entity>      players         = playersGroup.ToEntityArray(Allocator.TempJob, out JobHandle handle1);
        NativeArray <Translation> playerPositions = playersGroup.ToComponentDataArray <Translation>(Allocator.TempJob, out JobHandle handle2);

        //This code is running on the main thread but the 2 NativeArrays above are fetched in a job.
        //This is why we combine the dependencies and pass them all to the job when we schedule it (see below), to ensure that all the data is ready at the moment the job is launched.
        //For more info: https://gametorrahod.com/minimum-main-thread-block-with-out-jobhandle-overload/ (first section)
        JobHandle newInputDependencies = JobHandle.CombineDependencies(inputDependencies, handle1, handle2);

        var job1 = new FindClosestPlayerJob()
        {
            players   = players,
            positions = playerPositions,
            ECB       = ecb,
        };

        JobHandle job1Handle = job1.Schedule(this, newInputDependencies);

        //Job 2
        //Now iterating through the players (only one) finding the closest enemy.
        //We prepare the NativeArrays like in the job above.
        NativeArray <Entity>      enemies        = enemyGroup.ToEntityArray(Allocator.TempJob, out JobHandle handle3);
        NativeArray <Translation> enemyPositions = enemyGroup.ToComponentDataArray <Translation>(Allocator.TempJob, out JobHandle handle4);

        //Again, we combine dependencies to make sure that job1 is run as well as the fetching of the 2 NativeArrays, before running job2
        JobHandle job1Dependencies = JobHandle.CombineDependencies(job1Handle, handle3, handle4);

        var job2 = new FindClosestEnemyJob()
        {
            enemies   = enemies,
            positions = enemyPositions,
            ECB       = ecb,
        };

        JobHandle job2Handle = job2.Schedule(this, job1Dependencies);

        endInitECBSystem.AddJobHandleForProducer(job2Handle);

        //Job 3
        //All characters already with a Target but not currently dealing an attack, check if the target is still in range or dead.
        var job3 = new CheckIfTargetValidJob()
        {
            ECB = ecb,
            targetTranslations = GetComponentDataFromEntity <Translation>(true),
        };
        JobHandle job3Handle = job3.Schedule(this, job2Handle);

        endInitECBSystem.AddJobHandleForProducer(job3Handle);

        return(job3Handle);
    }
예제 #2
0
        protected override void OnUpdate()
        {
            var ecb = endInitializationEcbSystem.CreateCommandBuffer();

            Entities
            .WithoutBurst()
            .WithNone <Bounds>()
            .ForEach((Entity entity, in Terrain terrain) =>
            {
                var shift = terrain.terrainData.size / 2;

                var bounds = new Bounds
                {
                    Value = new UnityEngine.Bounds
                    {
                        center  = terrain.GetPosition() + shift,
                        extents = terrain.terrainData.size
                    }
                };

                ecb.AddComponent(entity, bounds);
            }).Run();

            endInitializationEcbSystem.AddJobHandleForProducer(this.Dependency);
        }
    protected override JobHandle OnUpdate(JobHandle inputDeps)
    {
        GlobalData gd = util.GetGlobalData();

        if (!gd)
        {
            Debug.LogError("NO GLOBAL DATA");
        }
        else
        {
            throwCurve = gd.armThrowingCurve;
        }

        var handle = inputDeps;

        var job = new ArmAnimationJob()
        {
            worldTime                = Time.time,
            matrixBufferLookup       = GetBufferFromEntity <ArmMatrixBuffer>(),
            armChainsBufferLookup    = GetBufferFromEntity <ArmChainsBuffer>(),
            fingerChainsBufferLookup = GetBufferFromEntity <FingerChainsBuffer>(),
            thumbChainsBufferLookup  = GetBufferFromEntity <ThumbChainsBuffer>(),
            ecb = ecbSystem.CreateCommandBuffer().ToConcurrent()
        };

        handle = job.Schedule(this, inputDeps);
        ecbSystem.AddJobHandleForProducer(handle);
        return(handle);
    }
        protected override JobHandle OnUpdate(JobHandle inputDeps)
        {
            Debug.Log("Remove Octree Instance.");

            // int i_groupLength = group.CalculateLength () ;

            JobHandle removeInstanceJobHandle = new RemoveInstanceJob
            {
                // a_octreeEntities                    = group.GetEntityArray (),

                // Contains a list of instances to add, with its properties.
                // removeInstanceBufferElement         = GetBufferFromEntity <RemoveInstanceBufferElement> (),

                a_rootNodeData = GetComponentDataFromEntity <RootNodeData> (),

                nodeSparesBufferElement          = GetBufferFromEntity <NodeSparesBufferElement> (),
                nodeBufferElement                = GetBufferFromEntity <NodeBufferElement> (),
                nodeInstancesIndexBufferElement  = GetBufferFromEntity <NodeInstancesIndexBufferElement> (),
                nodeChildrenBufferElement        = GetBufferFromEntity <NodeChildrenBufferElement> (),
                instanceBufferElement            = GetBufferFromEntity <InstanceBufferElement> (),
                instancesSpareIndexBufferElement = GetBufferFromEntity <InstancesSpareIndexBufferElement> ()
            }.Schedule(group, inputDeps);



            JobHandle completeRemoveInstanceJobHandle = new CompleteRemoveInstanceJob
            {
                ecb = eiecb.CreateCommandBuffer().ToConcurrent(),
                // a_octreeEntities                 = group.GetEntityArray ()
            }.Schedule(group, removeInstanceJobHandle);

            eiecb.AddJobHandleForProducer(completeRemoveInstanceJobHandle);

            return(completeRemoveInstanceJobHandle);
        }
        protected override JobHandle OnUpdate(JobHandle inputDeps)
        {
            var transforms = m_InitialTransformGroup.GetTransformAccessArray();
            var entities   = m_InitialTransformGroup.ToEntityArray(Allocator.TempJob);

            var transformStashes   = new NativeArray <TransformStash>(transforms.length, Allocator.TempJob);
            var stashTransformsJob = new StashTransforms
            {
                transformStashes = transformStashes
            };

            var stashTransformsJobHandle = stashTransformsJob.Schedule(transforms, inputDeps);

            var copyTransformsJob = new CopyTransforms
            {
                transformStashes = transformStashes,
            };

            var copyTransformsJobHandle = copyTransformsJob.Schedule(m_InitialTransformGroup, stashTransformsJobHandle);

            var removeComponentsJob = new RemoveCopyInitialTransformFromGameObjectComponent
            {
                entities            = entities,
                entityCommandBuffer = m_EntityCommandBufferSystem.CreateCommandBuffer()
            };
            var removeComponentsJobHandle = removeComponentsJob.Schedule(copyTransformsJobHandle);

            m_EntityCommandBufferSystem.AddJobHandleForProducer(removeComponentsJobHandle);
            return(removeComponentsJobHandle);
        }
        protected override void OnUpdate( )
        {
            var commandBuffer = m_barrier.CreateCommandBuffer( );

            var networkId = GetSingleton <NetworkIdComponent>( ).Value;

            Entities.ForEach((Entity ent, ref DynamicBuffer <PhysicsSnapshotBufferElement> snapshots, in SimulationBodyOwner bodyOwner) =>
            {
                var doesClientHaveAuthorityFlagAssignedToEntity = HasComponent <HasAuthorityOverPhysicsBody>(ent);
                var shouldHaveFlagAssigned = bodyOwner.Value == networkId;

                if (shouldHaveFlagAssigned && !doesClientHaveAuthorityFlagAssignedToEntity)
                {
                    commandBuffer.AddComponent <HasAuthorityOverPhysicsBody>(ent);
                }
                if (!shouldHaveFlagAssigned && doesClientHaveAuthorityFlagAssignedToEntity)
                {
                    commandBuffer.RemoveComponent <HasAuthorityOverPhysicsBody>(ent);
                    snapshots.Clear( );
                }
            }).Schedule( );

            commandBuffer.RemoveComponent <HasAuthorityOverPhysicsBody>(m_bodiesWithoutOwnerComponent);

            m_barrier.AddJobHandleForProducer(Dependency);
        }
예제 #7
0
    public override void UpdateSystem()
    {
        Dependency = JobHandle.CombineDependencies(Dependency, m_spawningQueueSystem.spawnQueueDependencies);

        EntityCommandBuffer       ecb        = m_entityCommandBuffer.CreateCommandBuffer();
        NativeQueue <Translation> spawnQueue = m_spawningQueueSystem.spawnQueue;

        Dependency = Entities.ForEach((ref RuntimePrefabData runtimePrefabData) =>
        {
            Translation translation;
            while (spawnQueue.TryDequeue(out translation))
            {
                Rotation rotation = GetComponent <Rotation>(runtimePrefabData.aiDrone);

                Entity e = ecb.Instantiate(runtimePrefabData.aiDrone);

                ecb.SetComponent(e, translation);
                ecb.SetComponent(e, new LocalToWorld {
                    Value = new float4x4(rotation.Value, translation.Value)
                });
            }
        }).Schedule(Dependency);

        m_entityCommandBuffer.AddJobHandleForProducer(Dependency);
    }
예제 #8
0
        protected override JobHandle OnUpdate(JobHandle inputDeps)
        {
            var commandBuffer = _cbSystem.CreateCommandBuffer();
            var job           = new UpdateUIDataJob
            {
                commands = commandBuffer.ToConcurrent()
            };

            inputDeps = job.Schedule(this, inputDeps);
            _cbSystem.AddJobHandleForProducer(inputDeps);

            return(inputDeps);
        }
        protected override void OnUpdate()
        {
            var shader = World.GetExistingSystem <SpriteRendererSubmitSystem>().DefaultShader;

            if (!shader.IsInitialized)
            {
                return;
            }

            var cmd = m_Barrier.CreateCommandBuffer();

            Dependency = Entities
                         .WithName("CreateMesh2D")
                         .WithoutBurst()
                         .WithNone <SpriteMeshBuffers>()
                         .ForEach((Entity entity, in Sprite sprite) =>
            {
                var blob        = sprite.Mesh;
                var indexCount  = blob.Value.Indices.Length;
                var vertexCount = blob.Value.Vertices.Length;

                unsafe
                {
                    cmd.AddComponent(entity, new SpriteMeshBuffers
                    {
                        IndexCount         = indexCount,
                        VertexCount        = vertexCount,
                        VertexLayoutHandle = shader.LayoutHandle,
                        IndexBufferHandle  = bgfx.create_index_buffer(RendererBGFXStatic.CreateMemoryBlock((byte *)blob.Value.Indices.GetUnsafePtr(), indexCount * 2), (ushort)bgfx.BufferFlags.None).idx,
                        VertexBufferHandle = bgfx.create_vertex_buffer(RendererBGFXStatic.CreateMemoryBlock((byte *)blob.Value.Vertices.GetUnsafePtr(), vertexCount * sizeof(SpriteVertex)), (bgfx.VertexLayout *)shader.VertexLayout.GetUnsafeReadOnlyPtr(), (ushort)bgfx.BufferFlags.None).idx
                    });
                }
            }).Schedule(Dependency);

            Dependency = Entities
                         .WithName("RemoveMesh2D")
                         .WithoutBurst()
                         .WithNone <Sprite>()
                         .ForEach((Entity entity, in SpriteMeshBuffers mesh) =>
            {
                bgfx.destroy_index_buffer(new bgfx.IndexBufferHandle {
                    idx = mesh.IndexBufferHandle
                });
                bgfx.destroy_vertex_buffer(new bgfx.VertexBufferHandle {
                    idx = mesh.VertexBufferHandle
                });
                cmd.RemoveComponent(entity, typeof(SpriteMeshBuffers));
            }).Schedule(Dependency);

            m_Barrier.AddJobHandleForProducer(Dependency);
        }
예제 #10
0
    public override void UpdateSystem()
    {
        EntityCommandBuffer.ParallelWriter ecb = m_entityCommandBuffer.CreateCommandBuffer().AsParallelWriter();

        JobHandle freezeRotationJobHandle = Entities.ForEach((Entity entity, int entityInQueryIndex, ref PhysicsMass physicsMass, in FreezeRotation freezeRotation) =>
        {
            physicsMass.InverseInertia[0] = freezeRotation.x ? 0 : physicsMass.InverseInertia[0];
            physicsMass.InverseInertia[1] = freezeRotation.y ? 0 : physicsMass.InverseInertia[1];
            physicsMass.InverseInertia[2] = freezeRotation.z ? 0 : physicsMass.InverseInertia[2];

            ecb.RemoveComponent <FreezeRotation>(entityInQueryIndex, entity);
        }).Schedule(Dependency);

        m_entityCommandBuffer.AddJobHandleForProducer(freezeRotationJobHandle);
        Dependency = freezeRotationJobHandle;
    }
예제 #11
0
        protected override JobHandle OnUpdate(JobHandle jobHandle)
        {
            var random        = Random;
            var commandBuffer = commandBufferSystem.CreateCommandBuffer().ToConcurrent();

            jobHandle = Entities
                        .WithNone <AnimationTimeMutator>()
                        .ForEach((Entity entity, int entityInQueryIndex, ref AnimationTimeMutatorRange range) =>
            {
                commandBuffer.AddComponent(entityInQueryIndex, entity,
                                           new AnimationTimeMutator {
                    Value = random.NextFloat(range.Min, range.Max)
                });
            })
                        .Schedule(jobHandle);
            commandBufferSystem.AddJobHandleForProducer(jobHandle);
            return(jobHandle);
        }
예제 #12
0
    protected override void OnUpdate()
    {
        var buffer = mCommandBufferSystem.CreateCommandBuffer();

        Entities
        .WithAll <TInitRandomizer>()
        .ForEach((Entity e) =>
        {
            var randomizer = new CRandomizer {
                Value = new Unity.Mathematics.Random((uint)UnityEngine.Random.Range(1, int.MaxValue))
            };
            buffer.AddComponent(e, randomizer);
            buffer.RemoveComponent <TInitRandomizer>(e);
        })
        .Run();

        mCommandBufferSystem.AddJobHandleForProducer(Dependency);
    }
예제 #13
0
    protected override void OnUpdate()
    {
        float time = Time.DeltaTime;
        var   ecb  = _entityCommandBufferSystem.CreateCommandBuffer().AsParallelWriter();

        Entities.ForEach((Entity entity, int entityInQueryIndex, ref LifetimeComponent lifetimeComponent) => {
            if (lifetimeComponent.time > 0)
            {
                lifetimeComponent.time -= time;
            }
            else
            {
                ecb.DestroyEntity(entityInQueryIndex, entity);
            }
        }).ScheduleParallel();

        _entityCommandBufferSystem.AddJobHandleForProducer(Dependency);
    }
    protected override JobHandle OnUpdate(JobHandle inputDeps)
    {
        var handle = inputDeps;

        Entities.WithStructuralChanges().WithoutBurst().ForEach((Entity entity, in TerrainGenerator g) =>
        {
            for (int x = 0; x < g.X; x++)
            {
                handle = JobHandle.CombineDependencies(new J {
                    xMax = g.X, yMax = g.Y, Archetype = _archetype, Buffer = _barrier.CreateCommandBuffer().ToConcurrent()
                }.Schedule(g.X * g.Y * g.Z, 128, handle),
                                                       handle);
            }
            EntityManager.DestroyEntity(entity);
        }).Run();
        _barrier.AddJobHandleForProducer(handle);
        return(handle);
    }
예제 #15
0
        protected override JobHandle OnUpdate(JobHandle inputDeps)
        {
            NativeArray <Entity> na_newOctreeEntities = group.ToEntityArray(Allocator.TempJob);

            Debug.Log("Add New Octree System");

            for (int i = 0; i < na_newOctreeEntities.Length; i++)
            {
                Entity e = na_newOctreeEntities [i];

                Debug.Log("#" + i + "; e #" + e.Index);
            }

            na_newOctreeEntities.Dispose();


            int i_groupLength = group.CalculateEntityCount();

            var initialiseOctreeJobHandle = new InitialiseOctreeJob
            {
                // a_newOctreeEntities                 = group.GetEntityArray (),

                // a_addNewOctreeData                  = GetComponentDataFromEntity <AddNewOctreeData> (),
                a_rootNodeData = GetComponentDataFromEntity <RootNodeData> (),

                nodeSparesBufferElement          = GetBufferFromEntity <NodeSparesBufferElement> (),
                nodeBufferElement                = GetBufferFromEntity <NodeBufferElement> (),
                nodeInstancesIndexBufferElement  = GetBufferFromEntity <NodeInstancesIndexBufferElement> (),
                nodeChildrenBufferElement        = GetBufferFromEntity <NodeChildrenBufferElement> (),
                instanceBufferElement            = GetBufferFromEntity <InstanceBufferElement> (),
                instancesSpareIndexBufferElement = GetBufferFromEntity <InstancesSpareIndexBufferElement> ()
            }.Schedule(group, inputDeps);


            var finalizeInitialisationOctreeJobHandle = new FinalizeInitialisationOctreeJob
            {
                ecb = eiecb.CreateCommandBuffer().ToConcurrent(),
                // a_newOctreeEntities                 = group.GetEntityArray ()
            }.Schedule(group, initialiseOctreeJobHandle);

            eiecb.AddJobHandleForProducer(finalizeInitialisationOctreeJobHandle);

            return(finalizeInitialisationOctreeJobHandle);
        }
예제 #16
0
    protected override JobHandle OnUpdate(JobHandle inputDeps)
    {
        //Instead of performing structural changes directly, a Job can add a command to an EntityCommandBuffer to perform such changes on the main thread after the Job has finished.
        //Command buffers allow you to perform any, potentially costly, calculations on a worker thread, while queuing up the actual insertions and deletions for later.

        // Schedule the job that will add Instantiate commands to the EntityCommandBuffer.
        var job = new TileSpawnJob
        {
            CommandBuffer = m_EntityCommandBufferSystem.CreateCommandBuffer()
        }.ScheduleSingle(this, inputDeps);


        // SpawnJob runs in parallel with no sync point until the barrier system executes.
        // When the barrier system executes we want to complete the SpawnJob and then play back the commands (Creating the entities and placing them).
        // We need to tell the barrier system which job it needs to complete before it can play back the commands.
        m_EntityCommandBufferSystem.AddJobHandleForProducer(job);

        return(job);
    }
예제 #17
0
        public unsafe override void UpdateSystem()
        {
            Dependency = JobHandle.CombineDependencies(Dependency, m_spawningQueueSystem.spawnQueueDependencies);

            EntityCommandBuffer        ecb        = m_entityCommandBuffer.CreateCommandBuffer();
            NativeQueue <SpawnCommand> spawnQueue = m_spawningQueueSystem.spawnQueue;
            NativeArray2D <MapNode>    grid       = _mMapManager.map;

            Dependency = Job.WithCode(() =>
            {
                while (spawnQueue.TryDequeue(out SpawnCommand spawnCommand))
                {
                    Entity entity;
                    switch (spawnCommand.spawnCommandType)
                    {
                    case SpawnCommandType.Harvester:
                        HarvesterSpawnData harvesterSpawnData = *spawnCommand.CommandData <HarvesterSpawnData>();

                        entity = ecb.Instantiate(spawnCommand.entity);
                        ecb.SetComponent(entity, harvesterSpawnData.translation);
                        ecb.SetComponent(entity, harvesterSpawnData.localToWorld);
                        ecb.SetComponent(entity, harvesterSpawnData.pathFinding);
                        break;

                    case SpawnCommandType.Projectile:
                        ProjectileSpawnData projectileSpawnData = *spawnCommand.CommandData <ProjectileSpawnData>();
                        entity = ecb.Instantiate(spawnCommand.entity);
                        ecb.SetComponent(entity, projectileSpawnData.translation);
                        ecb.SetComponent(entity, projectileSpawnData.projectile);
                        break;

                    default:
                        Debug.LogError("Invalid spawn command type!");
                        break;
                    }
                }
            }).Schedule(Dependency);

            m_entityCommandBuffer.AddJobHandleForProducer(Dependency);
        }
예제 #18
0
    protected override void OnUpdate()
    {
        var ecb  = _entityCommandBufferSystem.CreateCommandBuffer();
        var time = Time.DeltaTime;

        Entities.WithoutBurst().ForEach((ref AsteroidSpawnerComponent asteroidSpawner) => {
            if (asteroidSpawner.asteroidPrefab != Entity.Null)
            {
                if (asteroidSpawner.cooldown <= 0)
                {
                    var spawnRadius    = _random.NextFloat(asteroidSpawner.spawnRadius.min, asteroidSpawner.spawnRadius.max);
                    var spawnDirection = _random.NextFloat2Direction();
                    var position       = new float3(spawnRadius * spawnDirection.x, spawnRadius * spawnDirection.y, 0f);

                    var instance = ecb.Instantiate(asteroidSpawner.asteroidPrefab);
                    ecb.SetComponent(instance, new Translation()
                    {
                        Value = position
                    });
                    ecb.SetComponent(instance, new ForwardMovementComponent()
                    {
                        speed = _random.NextFloat(2f, 4f), isMoving = true
                    });
                    ecb.SetComponent(instance, new Rotation {
                        Value = quaternion.Euler(0f, 0f, _random.NextFloat(0f, 360f))
                    });

                    asteroidSpawner.cooldown += 1 / asteroidSpawner.spawnRate - time;
                }
                else
                {
                    asteroidSpawner.cooldown -= time;
                }
            }
        }).Run();

        _entityCommandBufferSystem.AddJobHandleForProducer(Dependency);
    }
        protected override void OnUpdate()
        {
            var lookup     = GhostLookup;
            var hashLookup = HashLookup;

            var commandBuffer = m_barrier.CreateCommandBuffer( );

            Entities.WithNone <AddedToLookupTables>( ).ForEach((Entity e, in GhostComponent ghost) =>
            {
                var hash = 13;
                hash     = hash * 7 + ghost.ghostId.GetHashCode( );
                hash     = hash * 7 + ghost.ghostType.GetHashCode( );
                hash     = hash * 7 + ghost.spawnTick.GetHashCode( );

                if (hash == 4459)
                {
                    return;
                }

                lookup.Add(hash, e);
                hashLookup.Add(e, hash);

                commandBuffer.AddComponent <AddedToLookupTables>(e);
            }).Schedule( );

            Entities.WithNone <GhostComponent>( ).WithAll <AddedToLookupTables>().ForEach(( Entity ent ) =>
            {
                var hash = hashLookup[ent];

                lookup.Remove(hash);
                hashLookup.Remove(ent);

                commandBuffer.RemoveComponent <AddedToLookupTables>(ent);
            }).Schedule( );

            m_barrier.AddJobHandleForProducer(Dependency);
        }
예제 #20
0
    protected override JobHandle OnUpdate(JobHandle inputDeps)
    {
        if (Input.GetKeyDown(KeyCode.Space))
        {
            Random random = new Random((uint)(Time.ElapsedTime * 100000));
            EntityCommandBuffer commandBuffer      = beginSimulationEntityCBS.CreateCommandBuffer();
            EntityCommandBuffer.ParallelWriter ecb = commandBuffer.AsParallelWriter();
            inputDeps = Entities.ForEach((int entityInQueryIndex, ref BoidSpawnerComponent prefabComponent) =>
            {
                float3 spawnOffset = prefabComponent.Offsets;
                for (int i = 0; i < prefabComponent.SpawnNumber; i++)
                {
                    float3 offset = new float3(
                        spawnOffset.x * (2 * random.NextFloat() - 1),
                        spawnOffset.y * (2 * random.NextFloat() - 1),
                        spawnOffset.z * (2 * random.NextFloat() - 1)
                        );
                    Entity entity = ecb.Instantiate(entityInQueryIndex, prefabComponent.Entity);
                    //Entity entity = EntityManager.Instantiate(prefabComponent.Entity);

                    float3 position = prefabComponent.Center + offset;
                    ecb.SetComponent(entityInQueryIndex, entity, new Translation {
                        Value = position
                    });
                    ecb.SetComponent(entityInQueryIndex, entity, new Rotation {
                        Value = new quaternion(random.NextFloat(), random.NextFloat(), random.NextFloat(), random.NextFloat())
                    });
                    //EntityManager.AddComponentData(entity, new Translation { Value = position });
                    //EntityManager.AddComponentData(entity, new Rotation { Value = new quaternion(random.NextFloat(), random.NextFloat(), random.NextFloat(), random.NextFloat())});
                }
            }).Schedule(inputDeps);
            //commandBuffer.Playback(EntityManager);
            beginSimulationEntityCBS.AddJobHandleForProducer(inputDeps);
        }
        return(inputDeps);
    }
예제 #21
0
    protected override void OnUpdate()
    {
        var   quadrantMultiHashMap = quadrantMultiHashMap2;
        float deltaTime            = Time.DeltaTime;

        var ecb = m_EndSimulationEcbSystem.CreateCommandBuffer().ToConcurrent();

        NativeArray <long> localInfectedCounter = new NativeArray <long>(1, Allocator.TempJob);

        localInfectedCounter[0] = 0;

        NativeArray <long> localTotalInfectedCounter = new NativeArray <long>(1, Allocator.TempJob);

        localTotalInfectedCounter[0] = 0;

        NativeArray <long> localSymptomaticCounter = new NativeArray <long>(1, Allocator.TempJob);

        localSymptomaticCounter[0] = 0;

        NativeArray <long> localAsymptomaticCounter = new NativeArray <long>(1, Allocator.TempJob);

        localAsymptomaticCounter[0] = 0;

        NativeArray <long> localDeathCounter = new NativeArray <long>(1, Allocator.TempJob);

        localDeathCounter[0] = 0;

        NativeArray <long> localRecoveredCounter = new NativeArray <long>(1, Allocator.TempJob);

        localRecoveredCounter[0] = 0;

        NativeArray <long> localTotalRecoveredCounter = new NativeArray <long>(1, Allocator.TempJob);

        localTotalRecoveredCounter[0] = 0;

        //job -> each element, if not infected, check if there are infected in its same quadrant
        var jobHandle = Entities.ForEach((Entity entity, int nativeThreadIndex, Translation t, ref QuadrantEntity qe, ref HumanComponent humanComponent, ref InfectionComponent ic) => {
            //for non infected entities, a check in the direct neighbours is done for checking the presence of infected
            if (ic.status == Status.susceptible)
            {
                //not infected-> look for infected in same cell
                int hashMapKey = QuadrantSystem.GetPositionHashMapKey(t.Value);
                //Debug.Log("Infected false");
                QuadrantData quadrantData;
                NativeMultiHashMapIterator <int> nativeMultiHashMapIterator;
                if (quadrantMultiHashMap.TryGetFirstValue(hashMapKey, out quadrantData, out nativeMultiHashMapIterator))
                {
                    //cycle through all entries oh hashmap with the same Key
                    do
                    {
                        //Debug.Log(quadrantData.position);
                        if (math.distance(t.Value, quadrantData.position) < 2f)
                        {
                            //TODO consider also social resp other human involved
                            //increment infectionCounter if one/more infected are in close positions (infected at quadrantData.position)
                            //infection counter is determined by time and human responsibility
                            ic.contagionCounter += 1f * deltaTime * (1 - humanComponent.socialResposibility);
                        }
                        //TODO we could add a cap here to speed up the check
                    } while (quadrantMultiHashMap.TryGetNextValue(out quadrantData, ref nativeMultiHashMapIterator));
                }
                else
                {
                    //no infected in same cell -> human is safe
                    ic.contagionCounter = 0f;
                }
            }
            //infection happened
            if (ic.contagionCounter >= contagionThreshold && ic.status == Status.susceptible)
            {
                //human become infected
                unsafe {
                    Interlocked.Increment(ref ((long *)localInfectedCounter.GetUnsafePtr())[0]);
                    Interlocked.Increment(ref ((long *)localTotalInfectedCounter.GetUnsafePtr())[0]);
                }
                qe.typeEnum       = QuadrantEntity.TypeEnum.exposed;
                ic.status         = Status.exposed;
                ic.exposedCounter = 0;
            }

            //Infectious status -> symptoms vs non-symptoms
            if (ic.exposedCounter > ic.exposedThreshold && ic.status == Status.exposed)
            {
                qe.typeEnum = QuadrantEntity.TypeEnum.infectious;
                ic.status   = Status.infectious;
                ic.infected = true;

                if (ic.humanSymptomsProbability > (100 - ic.globalSymptomsProbability))
                {
                    //symptomatic -> lasts between 0.5 and 1.5 day
                    ic.symptomatic = true;
                    unsafe
                    {
                        Interlocked.Increment(ref ((long *)localSymptomaticCounter.GetUnsafePtr())[0]);
                    }
                    ic.infectiousCounter = 0;
                }
                else
                {
                    //asymptomatic
                    ic.symptomatic = false;
                    unsafe
                    {
                        Interlocked.Increment(ref ((long *)localAsymptomaticCounter.GetUnsafePtr())[0]);
                    }
                    ic.infectiousCounter = 0;
                }
            }

            if (ic.infectiousCounter > ic.infectiousThreshold && ic.status == Status.infectious)
            {
                if (ic.humanDeathProbability > (100 - ic.globalDeathProbability))
                {
                    //remove entity
                    unsafe
                    {
                        Interlocked.Increment(ref ((long *)localDeathCounter.GetUnsafePtr())[0]);
                        Interlocked.Decrement(ref ((long *)localInfectedCounter.GetUnsafePtr())[0]);
                    }


                    if (ic.symptomatic)
                    {
                        unsafe
                        {
                            Interlocked.Decrement(ref ((long *)localSymptomaticCounter.GetUnsafePtr())[0]);
                        }
                    }
                    else
                    {
                        unsafe
                        {
                            Interlocked.Decrement(ref ((long *)localAsymptomaticCounter.GetUnsafePtr())[0]);
                        }
                    }
                    ic.status   = Status.removed;
                    qe.typeEnum = QuadrantEntity.TypeEnum.removed;
                    ecb.DestroyEntity(nativeThreadIndex, entity);
                }
                else
                {
                    //recovery time set up
                    unsafe {
                        Interlocked.Decrement(ref ((long *)localInfectedCounter.GetUnsafePtr())[0]);
                        Interlocked.Increment(ref ((long *)localRecoveredCounter.GetUnsafePtr())[0]);
                        Interlocked.Increment(ref ((long *)localTotalRecoveredCounter.GetUnsafePtr())[0]);
                    }
                    if (ic.symptomatic)
                    {
                        unsafe
                        {
                            Interlocked.Decrement(ref ((long *)localSymptomaticCounter.GetUnsafePtr())[0]);
                        }
                    }
                    else
                    {
                        unsafe
                        {
                            Interlocked.Decrement(ref ((long *)localAsymptomaticCounter.GetUnsafePtr())[0]);
                        }
                    }

                    ic.status   = Status.recovered;
                    ic.infected = false;
                    //qe.typeEnum = QuadrantEntity.TypeEnum.recovered;
                    ic.recoveredCounter = 0;
                }
            }

            if (ic.recoveredCounter > ic.recoveredThreshold && ic.status == Status.recovered)
            {
                ic.status   = Status.susceptible;
                qe.typeEnum = QuadrantEntity.TypeEnum.susceptible;
                unsafe {
                    Interlocked.Decrement(ref ((long *)localRecoveredCounter.GetUnsafePtr())[0]);
                }
            }

            if (ic.status == Status.exposed)
            {
                ic.exposedCounter += 1f * deltaTime;
            }
            if (ic.status == Status.infectious)
            {
                ic.infectiousCounter += 1f * deltaTime;
            }
            if (ic.status == Status.recovered)
            {
                ic.recoveredCounter += 1f * deltaTime;
            }
        }).WithReadOnly(quadrantMultiHashMap).ScheduleParallel(Dependency);

        m_EndSimulationEcbSystem.AddJobHandleForProducer(jobHandle);
        this.Dependency = jobHandle;

        jobHandle.Complete();

        unsafe {
            Interlocked.Add(ref infectedCounter, Interlocked.Read(ref ((long *)localInfectedCounter.GetUnsafePtr())[0]));
            Interlocked.Add(ref totalInfectedCounter, Interlocked.Read(ref ((long *)localTotalInfectedCounter.GetUnsafePtr())[0]));
            Interlocked.Add(ref symptomaticCounter, Interlocked.Read(ref ((long *)localSymptomaticCounter.GetUnsafePtr())[0]));
            Interlocked.Add(ref asymptomaticCounter, Interlocked.Read(ref ((long *)localAsymptomaticCounter.GetUnsafePtr())[0]));
            Interlocked.Add(ref recoveredCounter, Interlocked.Read(ref ((long *)localRecoveredCounter.GetUnsafePtr())[0]));
            Interlocked.Add(ref deathCounter, Interlocked.Read(ref ((long *)localDeathCounter.GetUnsafePtr())[0]));
            Interlocked.Add(ref populationCounter, -Interlocked.Read(ref ((long *)localDeathCounter.GetUnsafePtr())[0]));
        }

        //Write some text to the test.txt file
        writer.WriteLine(Interlocked.Read(ref populationCounter) + "\t"
                         + Interlocked.Read(ref infectedCounter) + "\t"
                         + Interlocked.Read(ref totalInfectedCounter) + "\t"
                         + Interlocked.Read(ref symptomaticCounter) + "\t"
                         + Interlocked.Read(ref asymptomaticCounter) + "\t"
                         + Interlocked.Read(ref deathCounter) + "\t"
                         + Interlocked.Read(ref recoveredCounter) + "\t"
                         + Interlocked.Read(ref totalRecoveredCounter) + "\t"
                         + (int)Datetime.total_minutes);

        localInfectedCounter.Dispose();
        localTotalInfectedCounter.Dispose();
        localAsymptomaticCounter.Dispose();
        localSymptomaticCounter.Dispose();
        localRecoveredCounter.Dispose();
        localTotalRecoveredCounter.Dispose();
        localDeathCounter.Dispose();
    }
예제 #22
0
    protected override void OnUpdate()
    {
        var ecb = _ecbSystem.CreateCommandBuffer().AsParallelWriter();

        if (Input.GetMouseButtonDown(0))
        {
            // Deselect everything
            EntityManager.SetSharedComponentData(_unitQuery, new SelectedFormationSharedComponent {
                IsSelected = false
            });
            EntityManager.SetSharedComponentData(_dragIndicatorQuery, new SelectedFormationSharedComponent {
                IsSelected = false
            });

            Entities
            .WithName("Deselect_All_Unit_Indicator_Job")
            .WithAll <SelectedIndicatorTag>()
            .ForEach((Entity unitEntity, int entityInQueryIndex) => {
                ecb.AddComponent <DisableRendering>(entityInQueryIndex, unitEntity);
            }).ScheduleParallel();

            _dragStartPos = Input.mousePosition;
        }

        if (Input.GetMouseButton(0))
        {
            float3 currDragPos = Input.mousePosition;
        }

        if (Input.GetMouseButtonUp(0))
        {
            float3 dragEndPos = Input.mousePosition;

            float2 bottomLeftCornor = new float2(math.min(_dragStartPos.x, dragEndPos.x), math.min(_dragStartPos.y, dragEndPos.y));
            float2 topRightCornor   = new float2(math.max(_dragStartPos.x, dragEndPos.x), math.max(_dragStartPos.y, dragEndPos.y));

            var cameraPos       = _cameraMain.transform.position;
            var cameraTransform = _cameraMain.transform;

            #region Method 1

            // For using static methods below
            var camProjMatrix = _cameraMain.projectionMatrix;
            var camUp         = cameraTransform.up;
            var camRight      = cameraTransform.right;
            var camForward    = cameraTransform.forward;
            var pixelWidth    = Screen.width;
            var pixelHeight   = Screen.height;
            var scaleFactor   = GameController.instance.dragRectCanvas.scaleFactor;

            // TEMP stupid way of "cancelling" this job early when a unit in the same formation has been selected
            // NOTE: due to running on multiple threads, there is a race condition where the job will write to the array multiple times (but no side effects)
            var formationGroups = new List <FormationGroup>();
            EntityManager.GetAllUniqueSharedComponentData(formationGroups);

            var isSelected = new NativeArray <bool>(40, Allocator.TempJob); // TODO capacity should be the number of formations player has
            _unitSelectSystem.SetBuffer(isSelected);

            // Iterate through every formation and check if they're selected
            foreach (var formation in formationGroups)
            {
                Entities
                .WithAll <UnitTag>()
                .WithSharedComponentFilter(formation)
                .ForEach((Entity unitEntity, int entityInQueryIndex, ref Translation translation) => {
                    if (isSelected[formation.ID])
                    {
                        return;
                    }

                    // Convert entity to view space before converting it to frustum space
                    float2 entityPos2D = ConvertWorldToScreenCoordinates(translation.Value, cameraPos, camProjMatrix, camUp, camRight, camForward, pixelWidth, pixelHeight, scaleFactor);

                    if (entityPos2D.x > bottomLeftCornor.x &&
                        entityPos2D.y > bottomLeftCornor.y &&
                        entityPos2D.x < topRightCornor.x &&
                        entityPos2D.y < topRightCornor.y)
                    {
                        isSelected[formation.ID] = true;
                    }
                })
                .WithNativeDisableContainerSafetyRestriction(isSelected)
                .ScheduleParallel();
            }

            #endregion

            #region Method 2

/*            // For all selected units, give them the SelectedFormationTag
 *          var ecb = m_EndSimulationEcbSystem.CreateCommandBuffer().AsParallelWriter();
 *
 *          var pixelWidth = Screen.width;
 *          var pixelHeight = Screen.height;
 *          var fullViewProjMatrix = _cameraMain.projectionMatrix * _cameraMain.transform.localToWorldMatrix;
 *
 *          // TEMP stupid way of "cancelling" this job early when a unit in the same formation has been selected
 *          // NOTE: due to running on multiple threads, there is a race condition where the job will write to the array multiple times (but no side effects)
 *          var formationGroups = new List<FormationGroup>();
 *          EntityManager.GetAllUniqueSharedComponentData(formationGroups);
 *          var isSelected = new NativeArray<bool>(40, Allocator.TempJob); // TODO max of 40 formations
 *
 *          foreach (var formation in formationGroups) {
 *              Entities
 *                  .WithAll<UnitTag>()
 *                  .ForEach((Entity unitEntity, int entityInQueryIndex, ref Translation translation, in LocalToWorld localToWorld) => {
 *
 *                      if (isSelected[formation.ID]) {
 *                          ecb.AddComponent<SelectedFormationTag>(entityInQueryIndex, unitEntity); // TODO replace with chunk component, shared component, or something else
 *                          ecb.DestroyEntity(entityInQueryIndex, unitEntity);
 *                          return;
 *                      }
 *
 *                      // Converting world point to screen point
 *                      var position4 = new float4(translation.Value.x, translation.Value.y, translation.Value.z, 1);
 *                      var viewPos = math.mul(fullViewProjMatrix, position4); // Gets view position
 *                      var viewportPoint = viewPos / -viewPos.w; // Takes away depth? Puts everything in a 2D place?
 *
 *                      var screenCord = new float2(viewportPoint.x, viewportPoint.y) / 2f;
 *                      screenCord.x = screenCord.x * pixelWidth;
 *                      screenCord.y = screenCord.y * pixelHeight;
 *
 *                      if (screenCord.x > bottomLeftCornor.x &&
 *                          screenCord.y > bottomLeftCornor.y &&
 *                          screenCord.x < topRightCornor.x &&
 *                          screenCord.y < topRightCornor.y) {
 *
 *                          isSelected[formation.ID] = true;
 *                          ecb.AddComponent<SelectedFormationTag>(entityInQueryIndex, unitEntity); // TODO replace with chunk component, shared component, or something else
 *                      }
 *
 *                  })
 *                  .WithNativeDisableContainerSafetyRestriction(isSelected)
 *                  .ScheduleParallel();
 *          }
 *
 */
            #endregion
        }

        _ecbSystem.AddJobHandleForProducer(this.Dependency);
    }
예제 #23
0
    protected override void OnUpdate()
    {
        float spawnRadius_ = spawnRadius;  // TODO: find a good pattern for all system configuration variables

        var randomArray = World.GetExistingSystem <RandomSystem>().RandomArray;

        if (templateEntity == Entity.Null)
        {
            EntityQuery templateQuery = GetEntityQuery(ComponentType.ReadOnly <TemplateData>());

            if (!templateQuery.IsEmpty)
            {
                templateEntity = templateQuery.GetSingletonEntity();
                //Debug.Log("templateEntity = " + templateEntity.Index);
                templateData = EntityManager.GetComponentData <TemplateData>(templateEntity);
            }
        }

        Entity cinnamonPrefab = templateData.cinnamonPrefab;
        Entity oreoPrefab     = templateData.oreoPrefab;

        var commandBuffer = m_EntityCommandBufferSystem.CreateCommandBuffer().AsParallelWriter();

        float deltaTime = Time.DeltaTime;

        Entities
        .WithNativeDisableParallelForRestriction(randomArray)
        .ForEach((Entity entity, int entityInQueryIndex, int nativeThreadIndex, ref GestationData gestationData, in Translation translation) =>
        {
            gestationData.timeUntilDelivery -= deltaTime;

            if (gestationData.timeUntilDelivery <= 0)
            {
                var random      = randomArray[nativeThreadIndex];
                Entity instance = Entity.Null;

                for (int i = 0; i < gestationData.litterSize; i++)
                {
                    if (random.NextFloat() > 0.5f)
                    {
                        //Debug.Log("Time to birth a baby Cinnamon!");
                        instance = commandBuffer.Instantiate(entityInQueryIndex, cinnamonPrefab);
                    }
                    else
                    {
                        //Debug.Log("Time to birth a baby Oreo!");
                        instance = commandBuffer.Instantiate(entityInQueryIndex, oreoPrefab);
                    }

                    //float3 offset = new float3(randomPoint.x, 0, randomPoint.y);  // TODO: find threadsafe Random pattern for inside Job
                    float3 offset = new float3(i + 1, 0, 0) * spawnRadius_;

                    commandBuffer.SetComponent(entityInQueryIndex, instance, new Translation
                    {
                        Value = translation.Value + offset
                    });
                }

                commandBuffer.RemoveComponent <GestationData>(entityInQueryIndex, entity);

                randomArray[nativeThreadIndex] = random;     // This is NECESSARY.
            }
        }).ScheduleParallel();

        m_EntityCommandBufferSystem.AddJobHandleForProducer(Dependency);
    }