Beispiel #1
0
 public void SetResult(ISerializable serializable)
 {
     using (semaphore.Wait())
     {
         Serializable = serializable;
         manualReset.Set();
         alreadyDeserialized = true;
     }
 }
 public Database <T> GetDatabase <T>(Guid universeGuid, int planetId, bool fixedValueSize) where T : ITag, new()
 {
     (Type, Guid universeGuid, int planetId)key = (typeof(T), universeGuid, planetId);
     using (planetSemaphore.Wait())
     {
         if (planetDatabaseRegister.TryGetValue(key, out Database.Database database))
         {
             return(database as Database <T>);
         }
         else
         {
             Database <T> tmpDatabase = CreateDatabase <T>(Path.Combine(rootPath, universeGuid.ToString(), planetId.ToString()), fixedValueSize);
             try
             {
                 tmpDatabase.Open();
             }
             catch (Exception ex)
             {
                 tmpDatabase.Dispose();
                 logger.Error($"Can not Open Database for [{universeGuid}]{planetId}, {typeof(T).Name}", ex);
                 throw ex;
             }
             planetDatabaseRegister.Add(key, tmpDatabase);
             return(tmpDatabase);
         }
     }
 }
        public Database <T> GetDatabase <T>(bool fixedValueSize) where T : ITag, new()
        {
            Type key = typeof(T);

            using (globalSemaphore.Wait())
            {
                if (globalDatabaseRegister.TryGetValue(key, out Database.Database database))
                {
                    return(database as Database <T>);
                }
                else
                {
                    Database <T> tmpDatabase = CreateDatabase <T>(rootPath, fixedValueSize);

                    try
                    {
                        tmpDatabase.Open();
                    }
                    catch (Exception ex)
                    {
                        tmpDatabase.Dispose();
                        logger.Error($"Can not Open Database for global, {typeof(T).Name}", ex);
                        throw ex;
                    }
                    globalDatabaseRegister.Add(key, tmpDatabase);
                    return(tmpDatabase);
                }
            }
        }
Beispiel #4
0
 public string GetRandomQuote()
 {
     using (semaphoreExtended.Wait())
     {
         Load();
         return(quotes[random.Next(0, quotes.Length)]);
     }
 }
Beispiel #5
0
        public T Get()
        {
            T obj;

            using (semaphoreExtended.Wait())
            {
                if (internalStack.Count > 0)
                {
                    obj = internalStack.Pop();
                }
                else
                {
                    obj = new T();
                }
            }

            obj.Init(this);
            return(obj);
        }
Beispiel #6
0
        public Package Get()
        {
            Package obj;

            using (semaphoreExtended.Wait())
            {
                if (internalStack.Count > 0)
                {
                    obj = internalStack.Pop();
                }
                else
                {
                    obj = new Package();
                }
            }

            obj.Init(this);
            obj.UId = Package.NextUId;
            return(obj);
        }
        /// <summary>
        /// Setzt den Zentrums-Chunk für diesen lokalen Cache.
        /// </summary>
        /// <param name="planet">Der Planet, auf dem sich der Chunk befindet</param>
        /// <param name="index">Die Koordinaten an der sich der Chunk befindet</param>
        /// <param name="successCallback">Routine die Aufgerufen werden soll, falls das setzen erfolgreich war oder nicht</param>
        public bool SetCenter(Index2 index, Action<bool> successCallback = null)
        {
            using (taskSemaphore.Wait())
            {
                var callerName = new StackFrame(1).GetMethod().Name;
                logger.Debug($"Set Center from {callerName}");
                CenterPosition = index;

                if (_loadingTask != null && !_loadingTask.IsCompleted)
                {
                    logger.Debug("Continue with task on index " + index);
                    _loadingTask = _loadingTask.ContinueWith(_ => InternalSetCenter(_cancellationToken.Token, index, successCallback));
                }
                else
                {
                    logger.Debug("New task on index " + index);
                    _cancellationToken?.Cancel();
                    _cancellationToken?.Dispose();
                    _cancellationToken = new CancellationTokenSource();
                    _loadingTask = Task.Run(() => InternalSetCenter(_cancellationToken.Token, index, successCallback));
                }
            }
            return true;
        }
        /// <summary>
        /// Interne Methode, in der der zentrale Chunk gesetzt wird. Die Chunks um den Zentrumschunk werden auch nachgeladen falls nötig
        /// </summary>
        /// <param name="token">Token, um zu prüfen, ob die aktualisierung abgeborchen werden soll</param>
        /// <param name="planet">Der Planet, auf dem die Chunks aktualisiert werden sollen</param>
        /// <param name="index">Der ins Zentrum zu setzende Chunk</param>
        /// <param name="successCallback">Routine die Aufgerufen werden soll, falls das setzen erfolgreich war oder nicht</param>
        private void InternalSetCenter(CancellationToken token, Index2 index, Action<bool> successCallback)
        {
            if (Planet == null)
            {
                successCallback?.Invoke(true);
                return;
            }

            List<Index2> requiredChunkColumns = new List<Index2>();

            for (int x = -range; x <= range; x++)
            {
                for (int y = -range; y <= range; y++)
                {
                    Index2 local = new Index2(index.X + x, index.Y + y);
                    local.NormalizeXY(Planet.Size);
                    requiredChunkColumns.Add(local);
                }
            }

            // Erste Abbruchmöglichkeit
            if (token.IsCancellationRequested)
            {
                successCallback?.Invoke(false);
                return;
            }

            foreach (var chunkColumnIndex in requiredChunkColumns
                                                .OrderBy(c => index.ShortestDistanceXY(c, new Index2(Planet.Size))
                                                .LengthSquared()))
            {
                int localX = chunkColumnIndex.X & mask;
                int localY = chunkColumnIndex.Y & mask;
                int flatIndex = FlatIndex(localX, localY);
                IChunkColumn chunkColumn = chunkColumns[flatIndex];

                // Alten Chunk entfernen, falls notwendig

                using (semaphore.Wait())
                {
                    if (chunkColumn != null && chunkColumn.Index != chunkColumnIndex)
                    {
                        //logger.Debug($"Remove Chunk: {chunkColumn.Index}, new: {chunkColumnIndex}");
                        globalCache.Release(chunkColumn.Index);


                        chunkColumns[flatIndex] = null;
                        chunkColumn = null;
                    }
                }

                // Zweite Abbruchmöglichkeit
                if (token.IsCancellationRequested)
                {
                    successCallback?.Invoke(false);
                    return;
                }

                using (semaphore.Wait())
                {
                    // Neuen Chunk laden
                    if (chunkColumn == null)
                    {
                        chunkColumn = globalCache.Subscribe(new Index2(chunkColumnIndex));

                        if (chunkColumn?.Index != chunkColumnIndex)
                            logger.Error($"Loaded Chunk Index: {chunkColumn?.Index}, wanted: {chunkColumnIndex} ");
                        if (chunkColumns[flatIndex] != null)
                            logger.Error($"Chunk in Array!!: {flatIndex}, on index: {chunkColumns[flatIndex].Index} ");


                        chunkColumns[flatIndex] = chunkColumn;

                        if (chunkColumn == null)
                        {
                            successCallback?.Invoke(false);
                            return;
                        }
                    }
                }

                // Dritte Abbruchmöglichkeit
                if (token.IsCancellationRequested)
                {
                    successCallback?.Invoke(false);
                    return;
                }
            }

            successCallback?.Invoke(true);
        }
 public LockSemaphore.SemaphoreLock Wait()
 => semaphore.Wait();
Beispiel #10
0
        /// <summary>
        /// Serialisiert die Chunksäule in den angegebenen Stream.
        /// </summary>
        /// <param name="writer">Zielschreiber</param>
        /// <param name="definitionManager">Der verwendete DefinitionManager</param>
        public void Serialize(BinaryWriter writer)
        {
            // Definitionen sammeln
            var definitions = new List <IBlockDefinition>();

            for (var c = 0; c < Chunks.Length; c++)
            {
                IChunk chunk = Chunks[c];
                for (var i = 0; i < chunk.Blocks.Length; i++)
                {
                    if (chunk.Blocks[i] != 0)
                    {
                        var definition = (IBlockDefinition)DefinitionManager.GetDefinitionByIndex(chunk.Blocks[i]);
                        if (!definitions.Contains(definition))
                        {
                            definitions.Add(definition);
                        }
                    }
                }
            }

            var longIndex = definitions.Count > 254;

            writer.Write((byte)((longIndex) ? 1 : 0));

            // Schreibe Phase 1 (Column Meta: Heightmap, populated, chunkcount)
            writer.Write((byte)Chunks.Length); // Chunk Count
            writer.Write(Populated);           // Populated
            writer.Write(Index.X);
            writer.Write(Index.Y);
            writer.Write(Planet.Id);

            for (var y = 0; y < Chunk.CHUNKSIZE_Y; y++) // Heightmap
            {
                for (var x = 0; x < Chunk.CHUNKSIZE_X; x++)
                {
                    writer.Write((ushort)Heights[x, y]);
                }
            }

            // Schreibe Phase 2 (Block Definitionen)
            if (longIndex)
            {
                writer.Write((ushort)definitions.Count);
            }
            else
            {
                writer.Write((byte)definitions.Count);
            }

            foreach (IBlockDefinition definition in definitions)
            {
                writer.Write(definition.GetType().FullName);
            }

            // Schreibe Phase 3 (Chunk Infos)
            for (var c = 0; c < Chunks.Length; c++)
            {
                IChunk chunk = Chunks[c];
                for (var i = 0; i < chunk.Blocks.Length; i++)
                {
                    if (chunk.Blocks[i] == 0)
                    {
                        // Definition Index (Air)
                        if (longIndex)
                        {
                            writer.Write((ushort)0);
                        }
                        else
                        {
                            writer.Write((byte)0);
                        }
                    }
                    else
                    {
                        // Definition Index
                        var definition = (IBlockDefinition)DefinitionManager.GetDefinitionByIndex(chunk.Blocks[i]);

                        if (longIndex)
                        {
                            writer.Write((ushort)(definitions.IndexOf(definition) + 1));
                        }
                        else
                        {
                            writer.Write((byte)(definitions.IndexOf(definition) + 1));
                        }

                        // Meta Data
                        if (definition.HasMetaData)
                        {
                            writer.Write(chunk.MetaData[i]);
                        }
                    }
                }
            }
            var resManager = TypeContainer.Get <IResourceManager>();

            using (var lockObj = entitieSemaphore.Wait())
            {
                foreach (var entity in entities)
                {
                    resManager.SaveEntity(entity);
                }
            }
        }