Example #1
0
        protected override JobHandle OnUpdate(JobHandle inputDeps)
        {
            var commandBuffer = _commandBufferSystem.CreateCommandBuffer().ToConcurrent();
            var updateJob     = new UpdateJob
            {
                attackTemplate         = _enemyAttack,
                movementTemplate       = _enemyMovement,
                entityType             = GetArchetypeChunkEntityType(),
                raycastResultStateType = GetArchetypeChunkComponentType <RaycastResultState>(false),
                raycastResultType      = GetArchetypeChunkComponentType <RaycastResult>(true),
                movementType           = GetArchetypeChunkComponentType <Movement>(true),
                attackType             = GetArchetypeChunkComponentType <EnemyAttack>(true),
                targetType             = GetArchetypeChunkComponentType <TargetOwnership>(false),
                commands = commandBuffer
            };

            var cleanupJob = new CleanupJob
            {
                commands = commandBuffer
            };

            inputDeps = updateJob.Schedule(_updateQuery, inputDeps);
            inputDeps = updateJob.Schedule(_updateQueryNoState, inputDeps);
            inputDeps = cleanupJob.Schedule(_cleanupQuery, inputDeps);

            _commandBufferSystem.AddJobHandleForProducer(inputDeps);

            return(inputDeps);
        }
Example #2
0
    protected override JobHandle OnUpdate(JobHandle inputDependencies)
    {
        var commandBuffer = _bufferSystem.CreateCommandBuffer().ToConcurrent();

        //Create New Maps
        var createJob = Entities.WithAll <WorldMapViewData>().WithNone <WorldMapViewSystemData>().ForEach((int nativeThreadIndex, Entity entity) =>
        {
            commandBuffer.AddComponent(nativeThreadIndex, entity, new WorldMapViewSystemData());
        }).Schedule(inputDependencies);

        _bufferSystem.AddJobHandleForProducer(createJob);

        //Clean Up Destroyed Maps
        var destroyJob = Entities.WithAll <WorldMapViewSystemData>().WithNone <WorldMapViewData>().ForEach((int nativeThreadIndex, Entity entity) =>
        {
            //Cleanup Destroyed Maps
            commandBuffer.RemoveComponent <WorldMapViewSystemData>(nativeThreadIndex, entity);
        }).Schedule(createJob);

        _bufferSystem.AddJobHandleForProducer(destroyJob);

        var tileArchetype = _tileArchetype;

        var cleanupJob = new CleanupJob
        {
            commandBuffer = _bufferSystem.CreateCommandBuffer().ToConcurrent(),
            mapViews      = worldMapViewDataQuery.ToComponentDataArray <WorldMapViewData>(Allocator.TempJob)
        };

        var cleanupJobHandle = cleanupJob.Schedule(worldMapTiles, destroyJob);

        _bufferSystem.AddJobHandleForProducer(cleanupJobHandle);

        var spawnJob = new SpawnJob()
        {
            CommandBuffer  = _bufferSystem.CreateCommandBuffer().ToConcurrent(),
            OutOfViewTiles = outOfViewQuery.ToEntityArray(Allocator.TempJob),
            TileArchetype  = tileArchetype
        }.Schedule(viewChangedQuery, cleanupJobHandle);

        _bufferSystem.AddJobHandleForProducer(spawnJob);

        return(spawnJob);
    }
Example #3
0
        protected override JobHandle OnUpdate(JobHandle inputDeps)
        {
            m_SerialSpawnChunks.Clear();
            // Make sure the list of connections and connection state is up to date
            var connections = connectionGroup.ToEntityArray(Allocator.TempJob);
            var existing    = new NativeHashMap <Entity, int>(connections.Length, Allocator.Temp);

            for (int i = 0; i < connections.Length; ++i)
            {
                existing.TryAdd(connections[i], 1);
                int stateIndex;
                if (!m_ConnectionStateLookup.TryGetValue(connections[i], out stateIndex))
                {
                    m_ConnectionStates.Add(new ConnectionStateData
                    {
                        Entity             = connections[i],
                        SerializationState = new NativeHashMap <ArchetypeChunk, SerializationState>(1024, Allocator.Persistent)
                    });
                    m_ConnectionStateLookup.TryAdd(connections[i], m_ConnectionStates.Count - 1);
                }
            }

            connections.Dispose();

            for (int i = 0; i < m_ConnectionStates.Count; ++i)
            {
                int val;
                if (!existing.TryGetValue(m_ConnectionStates[i].Entity, out val))
                {
                    m_ConnectionStateLookup.Remove(m_ConnectionStates[i].Entity);
                    m_ConnectionStates[i].Dispose();
                    if (i != m_ConnectionStates.Count - 1)
                    {
                        m_ConnectionStates[i] = m_ConnectionStates[m_ConnectionStates.Count - 1];
                        m_ConnectionStateLookup.Remove(m_ConnectionStates[i].Entity);
                        m_ConnectionStateLookup.TryAdd(m_ConnectionStates[i].Entity, i);
                    }

                    m_ConnectionStates.RemoveAt(m_ConnectionStates.Count - 1);
                }
            }

            // Find the latest tick which has been acknowledged by all clients and cleanup all ghosts destroyed ebfore that
            uint currentTick = m_ServerSimulation.ServerTick;

            var ackedByAll = new NativeArray <uint>(1, Allocator.TempJob);

            ackedByAll[0] = currentTick;
            var findAckJob = new FindAckedByAllJob
            {
                tick = ackedByAll
            };

            inputDeps = findAckJob.ScheduleSingle(this, inputDeps);

            EntityCommandBuffer commandBuffer = m_Barrier.CreateCommandBuffer();
            var ghostCleanupJob = new CleanupGhostJob
            {
                currentTick    = currentTick,
                tick           = ackedByAll,
                commandBuffer  = commandBuffer.ToConcurrent(),
                freeGhostIds   = m_FreeGhostIds.AsParallelWriter(),
                ghostStateType = ComponentType.ReadWrite <GhostSystemStateComponent>()
            };

            inputDeps = ghostCleanupJob.Schedule(this, inputDeps);


            var entityType           = GetArchetypeChunkEntityType();
            var ghostSystemStateType = GetArchetypeChunkComponentType <GhostSystemStateComponent>();

            serializers.BeginSerialize(this);

            // Extract all newly spawned ghosts and set their ghost ids
            JobHandle spawnChunkHandle;
            var       spawnChunks = ghostSpawnGroup.CreateArchetypeChunkArray(Allocator.TempJob, out spawnChunkHandle);
            var       spawnJob    = new SpawnGhostJob
            {
                spawnChunks       = spawnChunks,
                serialSpawnChunks = m_SerialSpawnChunks,
                entityType        = entityType,
                serializers       = serializers,
                freeGhostIds      = m_FreeGhostIds,
                allocatedGhostIds = m_AllocatedGhostIds,
                commandBuffer     = commandBuffer
            };

            inputDeps = spawnJob.Schedule(JobHandle.CombineDependencies(inputDeps, spawnChunkHandle));
            // This was the last job using the commandBuffer
            m_Barrier.AddJobHandleForProducer(inputDeps);

            JobHandle despawnChunksHandle, ghostChunksHandle;
            var       despawnChunks = ghostDespawnGroup.CreateArchetypeChunkArray(Allocator.TempJob, out despawnChunksHandle);
            var       ghostChunks   = ghostGroup.CreateArchetypeChunkArray(Allocator.TempJob, out ghostChunksHandle);

            inputDeps = JobHandle.CombineDependencies(inputDeps, despawnChunksHandle, ghostChunksHandle);

            var serialDep = new NativeArray <JobHandle>(m_ConnectionStates.Count + 1, Allocator.Temp);

            // In case there are 0 connections
            serialDep[0] = inputDeps;
            for (int con = 0; con < m_ConnectionStates.Count; ++con)
            {
                var connectionEntity       = m_ConnectionStates[con].Entity;
                var chunkSerializationData = m_ConnectionStates[con].SerializationState;
                var serializeJob           = new SerializeJob
                {
                    driver                 = m_ReceiveSystem.ConcurrentDriver,
                    unreliablePipeline     = m_ReceiveSystem.UnreliablePipeline,
                    despawnChunks          = despawnChunks,
                    ghostChunks            = ghostChunks,
                    connectionEntity       = connectionEntity,
                    chunkSerializationData = chunkSerializationData,
                    ackFromEntity          = GetComponentDataFromEntity <NetworkSnapshotAckComponent>(true),
                    connectionFromEntity   = GetComponentDataFromEntity <NetworkStreamConnection>(true),
                    serialSpawnChunks      = m_SerialSpawnChunks,
                    entityType             = entityType,
                    ghostSystemStateType   = ghostSystemStateType,
                    serializers            = serializers,
                    compressionModel       = m_CompressionModel,
                    currentTick            = currentTick,
                    localTime              = NetworkTimeSystem.TimestampMS
                };
                // FIXME: disable safety for BufferFromEntity is not working
                serialDep[con + 1] = serializeJob.Schedule(serialDep[con]);
            }

            inputDeps = JobHandle.CombineDependencies(serialDep);

            var cleanupJob = new CleanupJob
            {
                despawnChunks     = despawnChunks,
                spawnChunks       = spawnChunks,
                ghostChunks       = ghostChunks,
                serialSpawnChunks = m_SerialSpawnChunks
            };

            inputDeps = cleanupJob.Schedule(inputDeps);

            return(inputDeps);
        }
Example #4
0
    protected override JobHandle OnUpdate(JobHandle inputDeps)
    {
        if (units.entities.Length == 0)
        {
            return(inputDeps);
        }
        Profiler.BeginSample("Explosion wait");
        spellSystem.CombinedExplosionHandle.Complete();         // TODO try to remove this
        Profiler.EndSample();
        inputDeps.Complete();
        Profiler.BeginSample("Spawn ");

        if (!deathQueue.IsCreated)
        {
            deathQueue = new NativeQueue <Entity>(Allocator.Persistent);
        }
        if (!createdArrows.IsCreated)
        {
            createdArrows = new NativeQueue <ArrowData>(Allocator.Persistent);
        }

        while (createdArrows.Count > 0)
        {
            var data = createdArrows.Dequeue();
            Spawner.Instance.SpawnArrow(data);
        }

        UpdateInjectedComponentGroups();

        var cleanupJob = new CleanupJob
        {
            deathQueue = deathQueue,
            minionData = units.data,
            entitites  = units.entities
        };

        var moveUnitsJob = new MoveUnitsBelowGround()
        {
            dyingUnitData = dyingUnits.dyingData,
            transforms    = dyingUnits.transforms,
            time          = Time.time
        };

        var cleanupJobFence           = cleanupJob.Schedule(units.Length, SimulationState.BigBatchSize, inputDeps);
        var moveUnitsBelowGroundFence = moveUnitsJob.Schedule(dyingUnits.Length, SimulationState.HugeBatchSize, spellSystem.CombinedExplosionHandle);

        Profiler.EndSample();

        cleanupJobFence.Complete();
        moveUnitsBelowGroundFence.Complete();

        Profiler.BeginSample("LifeCycleManager - Main Thread");

        float time = Time.time;

        if (dyingUnits.Length > 0)
        {
            for (int i = 0; i < dyingUnits.Length; i++)
            {
                if (time > dyingUnits.dyingData[i].TimeAtWhichToExpire)
                {
                    var entityToKill = dyingUnits.entities[i];
                    queueForKillingEntities.Enqueue(entityToKill);
                }
                //else if (time > dyingData[i].TimeAtWhichToExpire - 2f)
                //{
                //	float t = (dyingData[i].TimeAtWhichToExpire - time) / 2f;
                //	var transform = transforms[i];
                //	transform.Position.y = math.lerp(dyingData[i].StartingYCoord, dyingData[i].StartingYCoord - 1f, t);
                //	transforms[i] = transform;
                //}
            }
        }

        if (dyingArrows.Length > 0)
        {
            for (int i = 0; i < dyingArrows.Length; i++)
            {
                if (time > dyingArrows.dyingData[i].TimeAtWhichToExpire)
                {
                    var arrowToKill = dyingArrows.entities[i];
                    queueForKillingEntities.Enqueue(arrowToKill);
                }
            }
        }

        Profiler.EndSample();
        Profiler.BeginSample("Queue processing");

        float timeForUnitExpiring  = Time.time + 5f;
        float timeForArrowExpiring = Time.time + 1f;

        Profiler.BeginSample("Death queue");
        int processed = 0;

        while (deathQueue.Count > 0)
        {
            var entityToKill = deathQueue.Dequeue();
            if (EntityManager.HasComponent <MinionData>(entityToKill))
            {
                EntityManager.RemoveComponent <MinionData>(entityToKill);
                entitiesThatNeedToBeKilled.Enqueue(entityToKill);
            }

            if (EntityManager.HasComponent <ArrowData>(entityToKill))
            {
                EntityManager.AddComponentData(entityToKill, new DyingUnitData(timeForArrowExpiring, 0));
            }
        }
        Profiler.EndSample();

        Profiler.BeginSample("Explosion wait");
        spellSystem.CombinedExplosionHandle.Complete();
        Profiler.EndSample();

        Profiler.BeginSample("Killing minionEntities");
        // TODO try batched replacing
        while (entitiesThatNeedToBeKilled.Count > 0 && processed < MaxDyingUnitsPerFrame)
        {
            processed++;
            var entityToKill = entitiesThatNeedToBeKilled.Dequeue();
            if (EntityManager.HasComponent <MinionTarget>(entityToKill))
            {
                EntityManager.RemoveComponent <MinionTarget>(entityToKill);
                if (EntityManager.HasComponent <AliveMinionData>(entityToKill))
                {
                    EntityManager.RemoveComponent <AliveMinionData>(entityToKill);
                }

                var textureAnimatorData = EntityManager.GetComponentData <TextureAnimatorData>(entityToKill);
                textureAnimatorData.NewAnimationId = AnimationName.Death;
                var transform = EntityManager.GetComponentData <UnitTransformData>(entityToKill);
                EntityManager.AddComponentData(entityToKill, new DyingUnitData(timeForUnitExpiring, transform.Position.y));

                EntityManager.SetComponentData(entityToKill, textureAnimatorData);

                var formations = GetComponentDataFromEntity <FormationData>();
                var formation  = formations[transform.FormationEntity];
                formation.UnitCount--;
                formation.Width = (int)math.ceil((math.sqrt(formation.UnitCount / 2f) * 2f));
                if (formation.UnitCount == 0)
                {
                    formation.FormationState = FormationData.State.AllDead;
                }
                formations[transform.FormationEntity] = formation;
            }
        }
        Profiler.EndSample();

        processed = 0;
        Profiler.BeginSample("Flying queue");
        while (entitiesForFlying.Count > 0 && processed < MaxDyingUnitsPerFrame)
        {
            processed++;
            var entity = entitiesForFlying.Dequeue();
            if (EntityManager.Exists(entity) && !EntityManager.HasComponent <FlyingData>(entity))
            {
                if (EntityManager.HasComponent(entity, typeof(AliveMinionData)))
                {
                    EntityManager.RemoveComponent <AliveMinionData>(entity);
                }
                EntityManager.AddComponentData(entity, new FlyingData());
            }
        }
        Profiler.EndSample();

        Profiler.BeginSample("Destroying entities");
        while (queueForKillingEntities.Count > 0)
        {
            EntityManager.DestroyEntity(queueForKillingEntities.Dequeue());
        }
        Profiler.EndSample();

        Profiler.EndSample();
        return(new JobHandle());
    }