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); } } }
public string GetRandomQuote() { using (semaphoreExtended.Wait()) { Load(); return(quotes[random.Next(0, quotes.Length)]); } }
public T Get() { T obj; using (semaphoreExtended.Wait()) { if (internalStack.Count > 0) { obj = internalStack.Pop(); } else { obj = new T(); } } obj.Init(this); return(obj); }
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();
/// <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); } } }