Beispiel #1
0
        public void ActivateGameStateAsync(GameState state, bool preservePreviousStates = false)
        {
            logger.Debug("Activating new game state {0}", state.Name);

            //_inActivationProcess filter that only one Activation can be requested at a time !
            //state.IsActivationRequested filter the case where the requested state is already on an Activation process (Cannot request it twice)
            if (_inActivationProcess == false || state.IsActivationRequested == false)
            {
                state.WithPreservePreviousStates = preservePreviousStates;
                _inActivationProcess             = true;
                state.IsActivationRequested      = true;

                state.PreviousGameState = _currentState;

#if DEBUG
                logger.Debug("State requested for activation : {0}", state.Name);
#endif

                //If ALL the components inside the states are already initiazed, switch directly the States
                if (state.GameComponents.Count > 0 && state.IsInitialized)
                {
                    SetCurrentState(state);
                    return;
                }

#if DEBUG
                logger.Debug("State Initialization requested in Async Mode : {0}", state.Name);
#endif
                AsyncStateInitResults.Add(ThreadsManager.RunAsync(() => InitializeComponentsAsync(state)));
            }
            else
            {
                logger.Warn("State : '{0}' requested to be activated while another activation requested is in initialization state, the request is dropped", state.Name);
            }
        }
Beispiel #2
0
        public override void FTSUpdate(GameTime timeSpent)
        {
            _brightness = _worldclock.ClockTime.SmartTimeInterpolation(0.2f);

            if ((Math.Abs(_smallOffset.X) > CloudBlockSize || Math.Abs(_smallOffset.Y) > CloudBlockSize) &&
                (_threadState == null || _threadState.IsCompleted) &&
                _newCloudGenerated == false
                )
            {
                // rebuild the grid in thread
                _threadState = ThreadsManager.RunAsync(FormClouds);
            }

            if (_newCloudGenerated)
            {
                if (Math.Abs((int)(_smallOffset.X / CloudBlockSize)) > 0)
                {
                    _smallOffset.X = _smallOffset.X % CloudBlockSize;
                }

                if (Math.Abs((int)(_smallOffset.Y / CloudBlockSize)) > 0)
                {
                    _smallOffset.Y = _smallOffset.Y % CloudBlockSize;
                }

                _instancedBuffer.SetInstancedData(_d3DEngine.Device.ImmediateContext, _clouds.ToArray());
                _cloudBlocksCount = _clouds.Count;
                _clouds.Clear();
                _newCloudGenerated = false;
            }
        }
Beispiel #3
0
        /// <summary>
        /// All Components used by this GameState should be Added in the GameState here
        /// This will be called in a multithreaded way !
        /// </summary>
        public virtual void Initialize(DeviceContext context)
        {
            //Call the Initialized from each Registered component, if needed !
            //Will be thread dispatched !
            List <Task> _startedTask = new List <Task>();

            GameComponents.ForEach(gc =>
            {
                if (gc.IsInitialized == false)
                {
                    //Start the Initialize()
                    _startedTask.Add(ThreadsManager.RunAsync(gc.Initialize));
                }
            });

            Task.WaitAll(_startedTask.ToArray());

            //Call the LoadContents from each Registered component, if needed !
            //!! Those methods are not Thread Safe !! => cannot thread dispatch them, can only run once at a time in this thread context
            foreach (var gc in GameComponents.Where(x => x.IsDefferedLoadContent))
            {
                if (gc.IsInitialized == false)
                {
                    gc.LoadContent(context);
                    gc.IsInitialized = true;
                }
            }

            IsDirty = false;
        }
 public void ProcessMessageEntityIn(ProtocolMessageEventArgs <EntityInMessage> e)
 {
     //Only take into account static entity
     if (e.Message.Link.IsStatic)
     {
         ThreadsManager.RunAsync(() => AddEntity((IStaticEntity)e.Message.Entity, e.Message.SourceEntityId), singleConcurrencyRun: true);
     }
 }
Beispiel #5
0
        public void PrepareStateAsync(GameState state)
        {
#if DEBUG
            logger.Debug("State Initialization requested (by Prepare) : {0}", state.Name);
#endif
            state.PreviousGameState = _currentState;
            AsyncStateInitResults.Add(ThreadsManager.RunAsync(() => InitializeComponentsAsync(state), singleConcurrencyRun: true));
        }
Beispiel #6
0
 public void RefreshWorldListAsync()
 {
     _savedGameList.Items.Clear();
     _savedGameList.SelectItem(-1);
     _savedGameList.Items.Add("Loading...");
     NeedShowResults = false;
     ThreadsManager.RunAsync(RefreshWorldList);
 }
 public void ProcessMessageEntityOut(ProtocolMessageEventArgs <EntityOutMessage> e)
 {
     // Only take into account static entity
     if (e.Message.Link.IsStatic)
     {
         //The server change modification will be queued inside a single concurrency thread pool. (Only one running at the same time)
         ThreadsManager.RunAsync(() => RemoveEntity(e.Message.Link, e.Message.TakerEntityId), singleConcurrencyRun: true);
     }
 }
Beispiel #8
0
        private void LoadMissingModels(WorldConfiguration configuration, VoxelModelManager voxelModelManager)
        {
            ThreadsManager.RunAsync(() => {
                voxelModelManager.Initialize();
                var availableModels = voxelModelManager.Enumerate().Select(m => m.VoxelModel.Name).ToList();
                var neededModels    = configuration.GetUsedModelsNames().Where(m => !availableModels.Contains(m)).ToList();

                foreach (var neededModel in neededModels)
                {
                    voxelModelManager.DownloadModel(neededModel);
                }
            });
        }
Beispiel #9
0
        //The state is enabled, start loading other components in background while the Loading is shown
        public override void OnEnabled(GameState previousState)
        {
            if (PreviousGameState != this)
            {
                ThreadsManager.RunAsync(GameplayInitializeAsync);
            }

            var serverComponent = _ioc.Get <ServerComponent>();

            serverComponent.ConnectionStatusChanged += serverComponent_ConnectionStausChanged;

            base.OnEnabled(previousState);
        }
        public void ReplaceBlocks(Vector3I[] position, byte[] blockId, BlockTag[] tags, bool isNetworkChange)
        {
            //Single block to change =============================================
            if (blockId.Length == 1)
            {
                ThreadsManager.RunAsync(() => ReplaceBlockThreaded(position[0], blockId[0], isNetworkChange, tags != null ? tags[0] : null), singleConcurrencyRun: true);
                return;
            }

            //Multiple blocks to change =============================================
            Dictionary <VisualChunk, List <TerraCubePositionTag> > blockPerChunk = new Dictionary <VisualChunk, List <TerraCubePositionTag> >();
            List <TerraCubePositionTag> blockList;

            //Multiple block to changes at once
            //Split the various blocks by chunks
            for (int i = 0; i < blockId.Length; i++)
            {
                BlockTag    tag = tags != null ? tags[i] : null;
                VisualChunk impactedChunk;
                if (_worldChunks.GetSafeChunk(position[i].X, position[i].Z, out impactedChunk))
                {
                    if (!blockPerChunk.TryGetValue(impactedChunk, out blockList))
                    {
                        blockList = new List <TerraCubePositionTag>();
                        blockPerChunk[impactedChunk] = blockList;
                    }
                    blockList.Add(new TerraCubePositionTag(position[i], blockId[i], tag));
                }
            }

            //Create a thread for working on the update per chunk !
            foreach (var blocks in blockPerChunk)
            {
                ThreadsManager.RunAsync(() => ReplaceChunkBlocksThreaded(blocks.Key, blocks.Value, isNetworkChange), singleConcurrencyRun: true);
            }
        }
        public bool ReplaceBlock(int cubeArrayIndex, ref Vector3I cubeCoordinates, byte replacementCubeId, bool isNetworkChanged, BlockTag blockTag = null)
        {
            VisualChunk impactedChunk = _worldChunks.GetChunk(cubeCoordinates.X, cubeCoordinates.Z);

            if (impactedChunk.State != ChunkState.DisplayInSyncWithMeshes && isNetworkChanged)
            {
                return(false);
            }

            try
            {
                // Check if the cube is not already the same ? ! ?
                var existingCube = _cubesHolder.Cubes[cubeArrayIndex];

                var inChunkPos = BlockHelper.GlobalToInternalChunkPosition(cubeCoordinates);

                if (existingCube.Id == replacementCubeId)
                {
                    // tag change event
                    // some tags changes requires chunk mesh rebuild (LiquidTag), some not (DamageTag)
                    // we will update the mesh only if at least one tag (current or previous) requires mesh update

                    var needChunkMeshUpdate = false;

                    var oldTag = impactedChunk.BlockData.GetTag(inChunkPos);

                    if (oldTag != null && oldTag.RequireChunkMeshUpdate)
                    {
                        needChunkMeshUpdate = true;
                    }

                    if (blockTag != null && blockTag.RequireChunkMeshUpdate)
                    {
                        needChunkMeshUpdate = true;
                    }

                    if (!needChunkMeshUpdate)
                    {
                        impactedChunk.BlockData.SetTag(blockTag, inChunkPos);
                        return(true);
                    }
                }

                // Change the cube in the big array
                impactedChunk.BlockData.SetBlock(inChunkPos, replacementCubeId, blockTag);

                // Start Chunk Visual Impact to decide what needs to be redraw, will be done in async mode,
                // quite heavy, will also restart light computations for the impacted chunk range.
                var cube = new TerraCubeWithPosition(cubeCoordinates, replacementCubeId, _visualWorldParameters.WorldParameters.Configuration.BlockProfiles[replacementCubeId]);

#if PERFTEST
                if (Utopia.Worlds.Chunks.WorldChunks.perf.Actif == false)
                {
                    Utopia.Worlds.Chunks.WorldChunks.perf.Actif         = true;
                    Utopia.Worlds.Chunks.WorldChunks.perf.CollectedData = new List <string>();
                    Utopia.Worlds.Chunks.WorldChunks.perf.AddData("Started New User Action");
                    Utopia.Worlds.Chunks.WorldChunks.perf.sw.Restart();
                }
#endif

                impactedChunk.UpdateOrder = !cube.BlockProfile.IsBlockingLight ? 1 : 2;
                //Compute the Range impacted by the cube change
                var cubeRange = new Range3I
                {
                    Position = new Vector3I(cube.Position.X, 0, cube.Position.Z),
                    Size     = Vector3I.One
                };
                ThreadsManager.RunAsync(() => CheckImpact(impactedChunk, cubeRange), ThreadsManager.ThreadTaskPriority.High);

                // Raise event for sound
                OnBlockReplaced(new LandscapeBlockReplacedEventArgs {
                    IsLocalPLayerAction = !isNetworkChanged,
                    Position            = cubeCoordinates,
                    NewBlockType        = replacementCubeId,
                    PreviousBlock       = existingCube
                });

                return(true);
            }
            finally
            {
                // Save the modified Chunk in local buffer DB
                SendChunkForBuffering(impactedChunk);
            }
        }
        //Multiple blocks replace logic
        public bool ReplaceChunkBlocks(VisualChunk impactedChunk, List <TerraCubePositionTag> blocks, bool isNetworkChanged)
        {
            if (impactedChunk.State != ChunkState.DisplayInSyncWithMeshes && isNetworkChanged)
            {
                return(false);
            }

            Vector2I Min = new Vector2I(int.MaxValue, int.MaxValue);
            Vector2I Max = new Vector2I(int.MinValue, int.MinValue);

            foreach (var block in blocks)
            {
                var existingCube = _cubesHolder.Cubes[_cubesHolder.Index(ref block.Position)];
                var inChunkPos   = BlockHelper.GlobalToInternalChunkPosition(block.Position);

                //Cube not changed - Check Tags
                if (existingCube.Id == block.Cube.Id)
                {
                    var needChunkMeshUpdate = false;
                    var oldTag = impactedChunk.BlockData.GetTag(inChunkPos);
                    if (oldTag != null && oldTag.RequireChunkMeshUpdate)
                    {
                        needChunkMeshUpdate = true;
                    }

                    if (block.Tag != null && block.Tag.RequireChunkMeshUpdate)
                    {
                        needChunkMeshUpdate = true;
                    }

                    if (!needChunkMeshUpdate)
                    {
                        impactedChunk.BlockData.SetTag(block.Tag, inChunkPos);
                        continue;
                    }
                }

                if (Min.X > block.Position.X)
                {
                    Min.X = block.Position.X;
                }
                if (Min.Y > block.Position.Z)
                {
                    Min.Y = block.Position.Z;
                }
                if (Max.X < block.Position.X)
                {
                    Max.X = block.Position.X;
                }
                if (Max.Y < block.Position.Z)
                {
                    Max.Y = block.Position.Z;
                }

                // Change the cube in the big array
                impactedChunk.BlockData.SetBlock(inChunkPos, block.Cube.Id, block.Tag);
            }

            //Compute the Range impacted by the cube change
            var cubeRange = new Range3I
            {
                Position = new Vector3I(Min.X, 0, Min.Y),
                Size     = new Vector3I((Max.X - Min.X) + 1, 0, (Max.Y - Min.Y) + 1)
            };

            impactedChunk.UpdateOrder = 1;
            ThreadsManager.RunAsync(() => CheckImpact(impactedChunk, cubeRange), ThreadsManager.ThreadTaskPriority.High);

            // Save the modified Chunk in local buffer DB
            SendChunkForBuffering(impactedChunk);

            return(true);
        }